Fix: #294 Need to convert the result encoding of IPConverter

This commit is contained in:
yuanyuanxiang
2026-01-27 20:17:57 +01:00
parent e40cb4da92
commit 02ce01d5e7
2 changed files with 63 additions and 4 deletions

View File

@@ -24,6 +24,63 @@
#pragma comment(lib, "wininet.lib") #pragma comment(lib, "wininet.lib")
#pragma comment(lib, "Iphlpapi.lib") #pragma comment(lib, "Iphlpapi.lib")
// UTF-8 转 ANSI当前系统代码页
inline std::string Utf8ToAnsi(const std::string& utf8)
{
if (utf8.empty()) return "";
// UTF-8 -> UTF-16
int wideLen = MultiByteToWideChar(CP_UTF8, 0, utf8.c_str(), -1, NULL, 0);
if (wideLen <= 0) return utf8;
std::wstring wideStr(wideLen, 0);
MultiByteToWideChar(CP_UTF8, 0, utf8.c_str(), -1, &wideStr[0], wideLen);
// UTF-16 -> ANSI
int ansiLen = WideCharToMultiByte(CP_ACP, 0, wideStr.c_str(), -1, NULL, 0, NULL, NULL);
if (ansiLen <= 0) return utf8;
std::string ansiStr(ansiLen, 0);
WideCharToMultiByte(CP_ACP, 0, wideStr.c_str(), -1, &ansiStr[0], ansiLen, NULL, NULL);
// 去掉末尾的 null 字符
if (!ansiStr.empty() && ansiStr.back() == '\0') {
ansiStr.pop_back();
}
return ansiStr;
}
// 检测字符串是否可能是 UTF-8 编码(包含多字节序列)
inline bool IsLikelyUtf8(const std::string& str)
{
for (size_t i = 0; i < str.size(); i++) {
unsigned char c = str[i];
if (c >= 0x80) {
// 2字节序列: 110xxxxx 10xxxxxx
if ((c & 0xE0) == 0xC0 && i + 1 < str.size()) {
if ((str[i+1] & 0xC0) == 0x80) return true;
}
// 3字节序列: 1110xxxx 10xxxxxx 10xxxxxx
else if ((c & 0xF0) == 0xE0 && i + 2 < str.size()) {
if ((str[i+1] & 0xC0) == 0x80 && (str[i+2] & 0xC0) == 0x80) return true;
}
// 4字节序列: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
else if ((c & 0xF8) == 0xF0 && i + 3 < str.size()) {
if ((str[i+1] & 0xC0) == 0x80 && (str[i+2] & 0xC0) == 0x80 && (str[i+3] & 0xC0) == 0x80) return true;
}
}
}
return false;
}
// 安全转换:检测到 UTF-8 才转换,否则原样返回
inline std::string SafeUtf8ToAnsi(const std::string& str)
{
if (str.empty()) return str;
return IsLikelyUtf8(str) ? Utf8ToAnsi(str) : str;
}
inline void splitIpPort(const std::string& input, std::string& ip, std::string& port) inline void splitIpPort(const std::string& input, std::string& ip, std::string& port)
{ {
size_t pos = input.find(':'); size_t pos = input.find(':');
@@ -126,8 +183,8 @@ public:
std::string location; std::string location;
if (jsonReader.parse(readBuffer, jsonData)) { if (jsonReader.parse(readBuffer, jsonData)) {
std::string country = jsonData["country"].asString(); std::string country = Utf8ToAnsi(jsonData["country"].asString());
std::string city = jsonData["city"].asString(); std::string city = Utf8ToAnsi(jsonData["city"].asString());
std::string loc = jsonData["loc"].asString(); // 经纬度信息 std::string loc = jsonData["loc"].asString(); // 经纬度信息
if (city.empty() && country.empty()) { if (city.empty() && country.empty()) {
} else if (city.empty()) { } else if (city.empty()) {

View File

@@ -780,6 +780,8 @@ VOID CMy2015RemoteDlg::AddList(CString strIP, CString strAddr, CString strPCName
loc = cvt.GetGeoLocation(data[ONLINELIST_IP].GetString()).c_str(); loc = cvt.GetGeoLocation(data[ONLINELIST_IP].GetString()).c_str();
} }
} }
// TODO: Remove SafeUtf8ToAnsi after migrating to UTF-8
loc = SafeUtf8ToAnsi(loc.GetString()).c_str();
bool flag = strIP == "127.0.0.1" && !v[RES_CLIENT_PUBIP].empty(); bool flag = strIP == "127.0.0.1" && !v[RES_CLIENT_PUBIP].empty();
data[ONLINELIST_IP] = flag ? v[RES_CLIENT_PUBIP].c_str() : strIP; data[ONLINELIST_IP] = flag ? v[RES_CLIENT_PUBIP].c_str() : strIP;
data[ONLINELIST_LOCATION] = loc; data[ONLINELIST_LOCATION] = loc;
@@ -828,8 +830,8 @@ VOID CMy2015RemoteDlg::AddList(CString strIP, CString strAddr, CString strPCName
CharMsg *title = new CharMsg("主机上线"); CharMsg *title = new CharMsg("主机上线");
CharMsg *text = new CharMsg(strIP + CString(tip.c_str()) + _T(" 主机上线 [") + loc + _T("]")); CharMsg *text = new CharMsg(strIP + CString(tip.c_str()) + _T(" 主机上线 [") + loc + _T("]"));
LeaveCriticalSection(&m_cs); LeaveCriticalSection(&m_cs);
Mprintf("主机[%s]上线: %s\n", v[RES_CLIENT_PUBIP].empty() ? strIP : v[RES_CLIENT_PUBIP].c_str(), Mprintf("主机[%s]上线: %s[%s]\n", v[RES_CLIENT_PUBIP].empty() ? strIP : v[RES_CLIENT_PUBIP].c_str(),
std::to_string(id).c_str()); std::to_string(id).c_str(), loc);
SendMasterSettings(ContextObject); SendMasterSettings(ContextObject);
if (m_needNotify && (GetTickCount() - g_StartTick > 30*1000)) if (m_needNotify && (GetTickCount() - g_StartTick > 30*1000))
PostMessageA(WM_SHOWNOTIFY, WPARAM(title), LPARAM(text)); PostMessageA(WM_SHOWNOTIFY, WPARAM(title), LPARAM(text));