Fix: Linux client UTF-8 path/active-window garbled on server
This commit is contained in:
@@ -1170,7 +1170,11 @@ int main(int argc, char* argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 构造并发送心跳包(与 Windows 端 KernelManager::SendHeartbeat 格式一致)
|
// 构造并发送心跳包(与 Windows 端 KernelManager::SendHeartbeat 格式一致)
|
||||||
std::string activity = utf8ToGbk(activityChecker.Check());
|
// ActiveWnd 直接发 UTF-8——与 LOGIN_INFOR.moduleVersion 中声明的
|
||||||
|
// CLIENT_CAP_UTF8 一致;服务端按 cap 位用 CP_UTF8 解码。早期为兼容
|
||||||
|
// MBCS 老服务端做过 utf8ToGbk 转换,但现在新版 Linux 客户端经
|
||||||
|
// libsign 网关只能连新版服务端,无需再转。
|
||||||
|
std::string activity = activityChecker.Check();
|
||||||
|
|
||||||
Heartbeat hb;
|
Heartbeat hb;
|
||||||
hb.Time = GetUnixMs();
|
hb.Time = GetUnixMs();
|
||||||
|
|||||||
@@ -178,15 +178,25 @@ bool SupportsFileTransferV2(context* ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 获取客户端协议字符串编码:优先看自身能力位,若是子连接(CAPABILITIES 为空)
|
// 获取客户端协议字符串编码:优先看自身能力位,若是子连接(CAPABILITIES 为空)
|
||||||
// 则通过 peer IP 查主连接。找不到则默认 CP936。
|
// 则通过 peer IP 查主连接。Linux/macOS 客户端文件系统路径与 locale 现代发行版
|
||||||
|
// 默认就是 UTF-8——即便客户端二进制是早于 CLIENT_CAP_UTF8 引入(commit 0aa7588)
|
||||||
|
// 之前编译的,没声明 cap 位,事实上仍发 UTF-8 字节,按 client type 兜底走 UTF-8。
|
||||||
|
// 找不到则默认 CP936。
|
||||||
UINT GetClientEncoding(context* ctx) {
|
UINT GetClientEncoding(context* ctx) {
|
||||||
if (!ctx) return 936;
|
if (!ctx) return 936;
|
||||||
// 主连接情形:CAPABILITIES 已由 LOGIN_INFOR 处理流程填好
|
// 主连接情形:CAPABILITIES 已由 LOGIN_INFOR 处理流程填好
|
||||||
if (ctx->SupportsUtf8()) return CP_UTF8;
|
if (ctx->SupportsUtf8()) return CP_UTF8;
|
||||||
|
// 客户端类型兜底:LNX / MAC 默认 UTF-8(兼容老二进制无 UTF-8 cap 位的情形)
|
||||||
|
CString clientType = ctx->GetAdditionalData(RES_CLIENT_TYPE);
|
||||||
|
if (clientType == "LNX" || clientType == "MAC") return CP_UTF8;
|
||||||
// 子连接情形:CAPABILITIES 为空 -> 通过 IP 找主连接
|
// 子连接情形:CAPABILITIES 为空 -> 通过 IP 找主连接
|
||||||
if (g_2015RemoteDlg) {
|
if (g_2015RemoteDlg) {
|
||||||
context* mainCtx = g_2015RemoteDlg->FindHostByIP(ctx->GetPeerName());
|
context* mainCtx = g_2015RemoteDlg->FindHostByIP(ctx->GetPeerName());
|
||||||
if (mainCtx && mainCtx->SupportsUtf8()) return CP_UTF8;
|
if (mainCtx) {
|
||||||
|
if (mainCtx->SupportsUtf8()) return CP_UTF8;
|
||||||
|
CString mainType = mainCtx->GetAdditionalData(RES_CLIENT_TYPE);
|
||||||
|
if (mainType == "LNX" || mainType == "MAC") return CP_UTF8;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 936;
|
return 936;
|
||||||
}
|
}
|
||||||
@@ -7550,6 +7560,28 @@ void CMy2015RemoteDlg::OnListClick(NMHDR* pNMHDR, LRESULT* pResult)
|
|||||||
CString res[RES_MAX];
|
CString res[RES_MAX];
|
||||||
CString startTime = ctx->GetClientData(ONLINELIST_STARTTIME);
|
CString startTime = ctx->GetClientData(ONLINELIST_STARTTIME);
|
||||||
ctx->GetAdditionalData(res);
|
ctx->GetAdditionalData(res);
|
||||||
|
// 客户端 RES_* 字符串编码取决于客户端能力位:UTF-8 客户端(Linux/macOS/新 Win)
|
||||||
|
// 发的是 UTF-8 字节,老客户端是 CP_ACP。这里统一规整到 CP_ACP,让下游 FormatL
|
||||||
|
// 与既有 ANSI 字符串拼接以及最终 CP_ACP→wide 的浮窗渲染都能正确识别。
|
||||||
|
// 若服务端运行系统的 ANSI 代码页不能容纳客户端字符(如德语服务端遇到中文路径),
|
||||||
|
// 不可表示的字符会变 '?' —— 与项目其它路径的既有限制一致,不在本次修复范围。
|
||||||
|
UINT cp = GetClientEncoding(ctx);
|
||||||
|
if (cp != CP_ACP) {
|
||||||
|
for (int i = 0; i < RES_MAX; i++) {
|
||||||
|
if (res[i].IsEmpty()) continue;
|
||||||
|
int wlen = MultiByteToWideChar(cp, 0, res[i].GetString(), -1, NULL, 0);
|
||||||
|
if (wlen <= 1) continue;
|
||||||
|
std::wstring wbuf(wlen - 1, L'\0');
|
||||||
|
MultiByteToWideChar(cp, 0, res[i].GetString(), -1, &wbuf[0], wlen);
|
||||||
|
int alen = WideCharToMultiByte(CP_ACP, 0, wbuf.c_str(), -1, NULL, 0, NULL, NULL);
|
||||||
|
if (alen <= 1) continue;
|
||||||
|
CString out;
|
||||||
|
WideCharToMultiByte(CP_ACP, 0, wbuf.c_str(), -1,
|
||||||
|
out.GetBufferSetLength(alen - 1), alen, NULL, NULL);
|
||||||
|
out.ReleaseBuffer(alen - 1);
|
||||||
|
res[i] = out;
|
||||||
|
}
|
||||||
|
}
|
||||||
FlagType type = ctx->GetFlagType();
|
FlagType type = ctx->GetFlagType();
|
||||||
static std::map<FlagType, std::string> typMap = {
|
static std::map<FlagType, std::string> typMap = {
|
||||||
{FLAG_WINOS, "WinOS"}, {FLAG_UNKNOWN, "Unknown"}, {FLAG_SHINE, "Shine"},
|
{FLAG_WINOS, "WinOS"}, {FLAG_UNKNOWN, "Unknown"}, {FLAG_SHINE, "Shine"},
|
||||||
|
|||||||
Reference in New Issue
Block a user