Improve: Add adaptive screen algorithm option and set to default

Fix: send Windows client path/username as UTF-8 (consistent with CLIENT_CAP_UTF8), keep client ID stable across upgrade
This commit is contained in:
yuanyuanxiang
2026-05-09 22:25:20 +02:00
parent a354f1ed86
commit 70354e244c
7 changed files with 61 additions and 20 deletions

View File

@@ -11,6 +11,8 @@
// ScreenType enum (USING_GDI, USING_DXGI, USING_VIRTUAL) 已移至 common/commands.h
#define ALGORITHM_NULL "-1"
#define ALGORITHM_NUL -1
#define ALGORITHM_GRAY 0
#define ALGORITHM_DIFF 1
#define ALGORITHM_DEFAULT 1

View File

@@ -213,14 +213,18 @@ std::string GetCurrentExeVersion()
std::string GetCurrentUserNameA()
{
char username[256];
DWORD size = sizeof(username);
if (GetUserNameA(username, &size)) {
return std::string(username);
} else {
// 用 W 接口取宽字符再转 UTF-8避免依赖系统 ANSI 代码页(中文账号名在英语系统上
// 用 GetUserNameA 取出来是 '?',与 LOGIN_INFOR 的 CLIENT_CAP_UTF8 声明也不一致)。
wchar_t wname[256] = {};
DWORD wsize = _countof(wname);
if (!GetUserNameW(wname, &wsize)) {
return "Unknown";
}
char buf[256 * 3] = {};
if (WideCharToMultiByte(CP_UTF8, 0, wname, -1, buf, sizeof(buf), NULL, NULL) <= 0) {
return "Unknown";
}
return std::string(buf);
}
#define XXH_INLINE_ALL
@@ -341,9 +345,18 @@ LOGIN_INFOR GetLoginInfo(DWORD dwSpeed, CONNECT_ADDRESS& conn, const std::string
LoginInfor.AddReserved(getOSBits()); // 系统位数
LoginInfor.AddReserved(GetCPUCores()); // CPU核数
LoginInfor.AddReserved(GetMemorySizeGB()); // 系统内存
// 路径分两份处理:
// - buf (CP_ACP): 保留给 CalcalateIDv2 / 老 CalculateID 用,保证升级后 client ID
// 不变(老版客户端用的是 GetModuleFileNameA 的 CP_ACP 字节,
// 若改成 UTF-8 同一物理路径会算出不同 ID丢授权/备注)。
// - utf8Path: 发给服务端的 RES_FILE_PATH与 CLIENT_CAP_UTF8 一致。
char buf[_MAX_PATH] = {};
GetModuleFileNameA(NULL, buf, sizeof(buf));
LoginInfor.AddReserved(buf); // 文件路径
GetModuleFileNameA(NULL, buf, sizeof(buf)); // CP_ACP, 留给 ID 计算用
wchar_t wbuf[_MAX_PATH] = {};
GetModuleFileNameW(NULL, wbuf, _MAX_PATH);
char utf8Path[_MAX_PATH * 3] = {}; // UTF-8 最多 3 字节/中文,给足
WideCharToMultiByte(CP_UTF8, 0, wbuf, -1, utf8Path, sizeof(utf8Path), NULL, NULL);
LoginInfor.AddReserved(utf8Path); // 文件路径 (UTF-8 发给服务端显示)
LoginInfor.AddReserved("?"); // test
std::string installTime = cfg.GetStr("settings", "install_time");
if (installTime.empty()) {
@@ -355,7 +368,7 @@ LOGIN_INFOR GetLoginInfo(DWORD dwSpeed, CONNECT_ADDRESS& conn, const std::string
LoginInfor.AddReserved(sizeof(void*)==4 ? 32 : 64); // 程序位数
std::string masterHash(skCrypt(MASTER_HASH));
WIN32_FILE_ATTRIBUTE_DATA fileInfo;
GetFileAttributesExA(buf, GetFileExInfoStandard, &fileInfo);
GetFileAttributesExW(wbuf, GetFileExInfoStandard, &fileInfo);
LoginInfor.AddReserved(str.c_str()); // 授权信息
bool isDefault = strlen(conn.szFlag) == 0 || strcmp(conn.szFlag, skCrypt(FLAG_GHOST)) == 0 ||
strcmp(conn.szFlag, skCrypt("Happy New Year!")) == 0;

View File

@@ -137,7 +137,11 @@ CScreenManager::CScreenManager(IOCPClient* ClientObject, int n, void* user, BOOL
}
}
BOOL fixedQuality = all || algo == ALGORITHM_H264;
int quality = cfg.GetInt("settings", "QualityLevel", QUALITY_GOOD);
if (algo != (BYTE)ALGORITHM_NUL)
quality = QUALITY_DISABLED;
Mprintf("图像传输算法: %d, 多显示器支持是否启用: %d, 屏幕质量等级: %d\n", (int)algo, all, quality);
m_ScreenSettings.MaxFPS = m_nMaxFPS;
m_ScreenSettings.CompressThread = threadNum;
m_ScreenSettings.ScreenStrategy = cfg.GetInt("settings", "ScreenStrategy", 0);
@@ -146,7 +150,7 @@ CScreenManager::CScreenManager(IOCPClient* ClientObject, int n, void* user, BOOL
m_ScreenSettings.FullScreen = cfg.GetInt("settings", "FullScreen", priv);
m_ScreenSettings.RemoteCursor = cfg.GetInt("settings", "RemoteCursor", 0);
m_ScreenSettings.ScrollDetectInterval = cfg.GetInt("settings", "ScrollDetectInterval", 2); // 默认每2帧
m_ScreenSettings.QualityLevel = cfg.GetInt("settings", "QualityLevel", fixedQuality ? QUALITY_GOOD : QUALITY_ADAPTIVE);
m_ScreenSettings.QualityLevel = cfg.GetInt("settings", "QualityLevel", quality);
m_ScreenSettings.CpuSpeedup = cfg.GetInt("settings", "CpuSpeedup", 0);
m_ScreenSettings.AudioEnabled = cfg.GetInt("settings", "AudioEnabled", 0); // 默认禁用音频

View File

@@ -3902,7 +3902,23 @@ void CMy2015RemoteDlg::OnOnlineUpdate()
return;
DWORD dwFileSize = 0;
BOOL is64bit = "64" == ContextObject->GetAdditionalData(RES_PROGRAM_BITS);
std::filesystem::path path = ContextObject->GetAdditionalData(RES_FILE_PATH).GetString();
// 客户端 RES_FILE_PATH 编码取决于其能力位(新 Win/Linux/macOS 是 UTF-8
// std::filesystem::path 的 std::string 构造器把字节当本机 ANSI 解读——
// 直接用 UTF-8 字节会被 CP936 误解为乱码,进而 stem() / parent_path() 提取错误。
// 走 cap 位 → wide → wstring 构造路径,规避编码假设。
CString pathRaw = ContextObject->GetAdditionalData(RES_FILE_PATH);
std::filesystem::path path;
{
UINT cp = GetClientEncoding(ContextObject);
int wlen = MultiByteToWideChar(cp, 0, pathRaw, -1, NULL, 0);
if (wlen > 1) {
std::wstring wpath(wlen - 1, L'\0');
MultiByteToWideChar(cp, 0, pathRaw, -1, &wpath[0], wlen);
path = std::filesystem::path(wpath);
} else {
path = std::filesystem::path(pathRaw.GetString());
}
}
std::string stem = path.stem().string();
std::string dirName = path.parent_path().filename().string();
const char* resName = dlg.m_nSelected
@@ -4046,7 +4062,7 @@ VOID CMy2015RemoteDlg::OnOnlineDesktopManager()
return;
int n = THIS_CFG.GetInt("settings", "DXGI");
BOOL all = THIS_CFG.GetInt("settings", "MultiScreen", TRUE);
CString algo = THIS_CFG.GetStr("settings", "ScreenCompress", "").c_str();
CString algo = THIS_CFG.GetStr("settings", "ScreenCompress", ALGORITHM_NULL).c_str();
BYTE bToken[32] = { COMMAND_SCREEN_SPY, n, algo.IsEmpty() ? ALGORITHM_RGB565 : atoi(algo.GetString()), all};
SendSelectedCommand(bToken, sizeof(bToken), screenParamModifier, bToken);
}

View File

@@ -17,7 +17,7 @@ CSettingDlg::CSettingDlg(CMy2015RemoteDlg* pParent)
, m_nListenPort("6543")
, m_nMax_Connect(0)
, m_sScreenCapture(_T("GDI"))
, m_sScreenCompress(_T("RGBA->RGB565"))
, m_sScreenCompress(_T("算法自适应"))
, m_nReportInterval(5)
, m_sSoftwareDetect(_T("摄像头"))
, m_sPublicIP(_T(""))
@@ -154,12 +154,15 @@ BOOL CSettingDlg::OnInitDialog()
int DXGI = THIS_CFG.GetInt("settings", "DXGI");
CString algo = THIS_CFG.GetStr("settings", "ScreenCompress", "").c_str();
CString algo = THIS_CFG.GetStr("settings", "ScreenCompress", ALGORITHM_NULL).c_str();
m_nListenPort = nPort.c_str();
int n = algo.IsEmpty() ? ALGORITHM_DIFF : atoi(algo.GetString());
switch (n) {
case ALGORITHM_NUL:
m_sScreenCompress = _L(_T("算法自适应"));
break;
case ALGORITHM_GRAY:
m_sScreenCompress = _L(_T("灰度图像传输"));
break;
@@ -175,10 +178,11 @@ BOOL CSettingDlg::OnInitDialog()
default:
break;
}
m_ComboScreenCompress.InsertStringL(ALGORITHM_GRAY, "灰度图像传输");
m_ComboScreenCompress.InsertStringL(ALGORITHM_DIFF, "屏幕差异算法");
m_ComboScreenCompress.InsertStringL(ALGORITHM_H264, "H264压缩算法");
m_ComboScreenCompress.InsertStringL(ALGORITHM_RGB565, "RGBA->RGB565");
m_ComboScreenCompress.InsertStringL(1+ALGORITHM_NUL, "算法自适应");
m_ComboScreenCompress.InsertStringL(1+ALGORITHM_GRAY, "灰度图像传输");
m_ComboScreenCompress.InsertStringL(1+ALGORITHM_DIFF, "屏幕差异算法");
m_ComboScreenCompress.InsertStringL(1+ALGORITHM_H264, "H264压缩算法");
m_ComboScreenCompress.InsertStringL(1+ALGORITHM_RGB565, "RGBA->RGB565");
m_ComboScreenCapture.InsertStringL(0, "GDI");
m_ComboScreenCapture.InsertStringL(1, "DXGI");
@@ -245,7 +249,7 @@ void CSettingDlg::OnBnClickedButtonSettingapply()
int n = m_ComboScreenCapture.GetCurSel();
THIS_CFG.SetInt("settings", "DXGI", n);
n = m_ComboScreenCompress.GetCurSel();
n = m_ComboScreenCompress.GetCurSel() - 1;
THIS_CFG.SetInt("settings", "ScreenCompress", n);
THIS_CFG.SetInt("settings", "ReportInterval", m_nReportInterval);

View File

@@ -1823,3 +1823,4 @@ IOCP
历史目录不存在: %s=History folder not exist: %s
无法识别远程主机=Unknown remote machine
没有远程历史记录=No remote history
算法自适应=Algorithm Adaptive

View File

@@ -1814,3 +1814,4 @@ IOCP
历史目录不存在: %s=历史目录不存在: %s
无法识别远程主机=无法识别远程主机
没有远程历史记录=没有远程历史记录
算法自适应=算法自适应