Feature: Add file-transfer speed dialog with multi-language support
Add a novice-friendly "File Transfer Speed" dialog under the Advanced menu that controls file-transfer speed in both directions without touching SimplePlugins. Speed is passed through InitFileUpload's existing chunkSizeKb/sendDurationMs arguments, so the precompiled library stays untouched. Seven presets run from ~0.3 MB/s up to a new 10 MB/s tier plus an unlimited tier; the chosen value is stored in [transfer] ChunkKb/DurationMs. Upload reads THIS_CFG at the master's InitFileUpload (2015RemoteDlg.cpp:2225) and takes effect on restart. Download is pushed to the client over a new CMD_FILE_SPEED (252) command, sent from OnOnlineFileManager and OnOnlineDesktopManager before each session opens, and read by all four client InitFileUpload call sites via GetTransferSpeed so the process-global refcount cannot latch a stale speed. All Chinese strings go through LangManager, with en_US/zh_TW/de_DE entries added for the tier names, format strings and hint text. Co-Authored-By: deepseek-v4-pro
This commit is contained in:
1 parent
9eed43bc8d
commit
76decec0fe
14 files changed
+423
-10
No files matched your search
@@ -36,9 +36,13 @@ CFileManager::CFileManager(CClientSocket *pClient, int h, void* user):CManager(p
|
||||
// 初始化V2文件传输模块
|
||||
CKernelManager* main = (CKernelManager*)pClient->GetMain();
|
||||
m_Signature = main ? main->m_LoginSignature : pClient->m_LoginSignature;
|
||||
if (!m_Signature.empty())
|
||||
if (!m_Signature.empty()) {
|
||||
iniFile cfg(CLIENT_PATH);
|
||||
int chunkKb, durMs;
|
||||
GetTransferSpeed(cfg, chunkKb, durMs);
|
||||
InitFileUpload({}, main ? main->m_LoginMsg : pClient->m_LoginMsg,
|
||||
main ? main->m_LoginSignature : pClient->m_LoginSignature, 64, 50, Logf);
|
||||
main ? main->m_LoginSignature : pClient->m_LoginSignature, chunkKb, durMs, Logf);
|
||||
}
|
||||
|
||||
// 发送驱动器列表, 开始进行文件管理,建立新线程
|
||||
SendDriveList();
|
||||
|
||||
@@ -1277,6 +1277,18 @@ VOID CKernelManager::OnReceive(PBYTE szBuffer, ULONG ulLength)
|
||||
break;
|
||||
}
|
||||
|
||||
case CMD_FILE_SPEED: {
|
||||
// 主控端下发文件传输速度档位:[cmd:1][chunkKb:uint16 LE][durationMs:uint16 LE]。
|
||||
// 写入 [transfer] 节,供各 InitFileUpload 调用点经 GetTransferSpeed 读取。
|
||||
if (ulLength >= 5) {
|
||||
int chunkKb = szBuffer[1] | (szBuffer[2] << 8);
|
||||
int durMs = szBuffer[3] | (szBuffer[4] << 8);
|
||||
m_cfg->SetInt("transfer", "ChunkKb", chunkKb);
|
||||
m_cfg->SetInt("transfer", "DurationMs", durMs);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case COMMAND_LIST_DRIVE : {
|
||||
if (!ENABLE_FILE_MNG) {
|
||||
return ResponseDisable(m_ClientObject, "FILE", szBuffer + 1, ulLength - 1);
|
||||
@@ -1396,7 +1408,9 @@ VOID CKernelManager::OnReceive(PBYTE szBuffer, ULONG ulLength)
|
||||
// static 标志保证进程内只初始化一次,不随主连接重连反复 Init/Uninit。
|
||||
static bool s_v2RecvInited = false;
|
||||
if (!s_v2RecvInited) {
|
||||
InitFileUpload({}, m_LoginMsg, m_LoginSignature, 64, 50, Logf);
|
||||
int chunkKb, durMs;
|
||||
GetTransferSpeed(*m_cfg, chunkKb, durMs);
|
||||
InitFileUpload({}, m_LoginMsg, m_LoginSignature, chunkKb, durMs, Logf);
|
||||
s_v2RecvInited = true;
|
||||
}
|
||||
// C2C/V2 文件接收(RecvFileChunkV2 内部会打印进度)
|
||||
|
||||
@@ -106,8 +106,13 @@ CScreenManager::CScreenManager(IOCPClient* ClientObject, int n, void* user, BOOL
|
||||
SetConnection(g_MyApp.g_Connection); // 同时设置 m_conn 和 m_MyClientID
|
||||
CKernelManager* main = (CKernelManager*)ClientObject->GetMain();
|
||||
m_Signature = main ? main->m_LoginSignature : ClientObject->m_LoginSignature;
|
||||
if (!m_Signature.empty()) InitFileUpload({}, main ? main->m_LoginMsg : ClientObject->m_LoginMsg,
|
||||
main ? main->m_LoginSignature : ClientObject->m_LoginSignature, 64, 50, Logf);
|
||||
if (!m_Signature.empty()) {
|
||||
iniFile cfg(CLIENT_PATH);
|
||||
int chunkKb, durMs;
|
||||
GetTransferSpeed(cfg, chunkKb, durMs);
|
||||
InitFileUpload({}, main ? main->m_LoginMsg : ClientObject->m_LoginMsg,
|
||||
main ? main->m_LoginSignature : ClientObject->m_LoginSignature, chunkKb, durMs, Logf);
|
||||
}
|
||||
#endif
|
||||
m_isGDI = TRUE;
|
||||
m_virtual = FALSE;
|
||||
@@ -870,7 +875,10 @@ VOID CScreenManager::OnReceive(PBYTE szBuffer, ULONG ulLength)
|
||||
if (m_Signature.empty()) {
|
||||
m_Signature = std::string(resp.signature, resp.signature + 64);
|
||||
m_ClientObject->SetVerifyInfo(resp.msg, m_Signature);
|
||||
InitFileUpload({}, std::string(resp.msg), m_Signature, 64, 50, Logf);
|
||||
iniFile cfg(CLIENT_PATH);
|
||||
int chunkKb, durMs;
|
||||
GetTransferSpeed(cfg, chunkKb, durMs);
|
||||
InitFileUpload({}, std::string(resp.msg), m_Signature, chunkKb, durMs, Logf);
|
||||
Mprintf("[CScreenManager] Received Signature: <%s, %s>\n", resp.msg, m_Signature.c_str());
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -357,6 +357,7 @@ enum {
|
||||
COMMAND_TEXT_REPLACE = 249,
|
||||
TOKEN_CLIP_TEXT = 250,
|
||||
TOKEN_SERVER_VERIFY = 251, // 验证服务器,防中间人和假冒的授权服务器
|
||||
CMD_FILE_SPEED = 252, // 文件传输速度下发: [cmd:1][chunkKb:uint16 LE][durationMs:uint16 LE]
|
||||
};
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
@@ -256,6 +256,18 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
// 文件传输速度:读取 [transfer] 节 ChunkKb / DurationMs,缺省 64KB/50ms(≈1.25MB/s),
|
||||
// 并夹到安全范围。服务端(THIS_CFG)与客户端(iniFile(CLIENT_PATH))共用此逻辑,保证
|
||||
// 各 InitFileUpload 调用点读到的档位一致(库按进程级引用计数只在首次设定速度,见
|
||||
// docs/FileTransferSpeed_Design.md)。
|
||||
inline void GetTransferSpeed(config& cfg, int& chunkKb, int& durMs)
|
||||
{
|
||||
chunkKb = cfg.GetInt("transfer", "ChunkKb", 64);
|
||||
durMs = cfg.GetInt("transfer", "DurationMs", 50);
|
||||
if (chunkKb <= 0 || chunkKb > 1024) chunkKb = 64;
|
||||
if (durMs < 0 || durMs > 2000) durMs = 50;
|
||||
}
|
||||
|
||||
// 配置读取类: 注册表配置(带键句柄缓存)
|
||||
// 注意:缓存操作非线程安全,但竞态条件只会导致少量重复打开,不会崩溃
|
||||
class iniFile : public config
|
||||
|
||||
@@ -0,0 +1,146 @@
|
||||
# YAMA 文件传输速度调节设计
|
||||
|
||||
> **状态**:已实现(Windows 端,含多语言)。其他平台(Linux/macOS 客户端)暂不实施。
|
||||
> **读者**:研发/评审人员。
|
||||
> **关联文档**:[FILE_TRANSFER_V2.md](./FILE_TRANSFER_V2.md)(V2 协议)、[Mcp_FileTransfer_Design.md](./Mcp_FileTransfer_Design.md)(MCP 文件传输)。
|
||||
|
||||
---
|
||||
|
||||
## 1. 背景与目标
|
||||
|
||||
文件传输速度目前是**写死的**:`SimplePlugins` 库的 `InitFileUpload(key, msg, hmac, chunkSizeKb, sendDurationMs, ...)` 被 YAMA 所有调用点传 `64, 50`,折算 ≈ 1.25 MB/s。用户无法调节。
|
||||
|
||||
目标:在 YAMA 主菜单「高级」下新增一个**面向小白**的「文件传输速度」对话框——拖动滑块即完成设置,实时显示预估速度;**不修改 SimplePlugins 库**(库已编译,只通过其已暴露的 `chunkSizeKb`/`sendDurationMs` 两个入参控制)。
|
||||
|
||||
---
|
||||
|
||||
## 2. 速度原理(现状)
|
||||
|
||||
库内部把两个入参转成全局量(`SimplePlugins/file_upload.cpp:221-222, 849-850`):
|
||||
|
||||
```cpp
|
||||
static int chunk_size = 64 * 1024; // 默认 64KB
|
||||
static int send_duration = 50; // 默认 50ms
|
||||
// InitFileUpload: chunk_size = chunkSizeKb * 1024; send_duration = sendDurationMs;
|
||||
```
|
||||
|
||||
发送循环每发一块就 `Sleep(send_duration)`(V1 `FileBatchTransferWorker` 与 V2 `FileBatchTransferWorkerV2` 共用这对全局量):
|
||||
|
||||
```
|
||||
预估速度 = chunkSizeKb * 1024 / (sendDurationMs / 1000) 字节/秒
|
||||
默认 64KB / 50ms ≈ 1.25 MB/s
|
||||
```
|
||||
|
||||
两个关键约束:
|
||||
|
||||
1. **速度只在 `InitFileUpload` 时设定一次**,库无运行时 setter(`g_threadCount > 1` 时提前返回,不会重设)。
|
||||
2. **V1 / V2 共用同一对全局量**,一次设置同时覆盖 `COMMAND_SEND_FILE(68)` 与 `COMMAND_SEND_FILE_V2(85)` 两种协议。
|
||||
|
||||
---
|
||||
|
||||
## 3. 档位表(权威唯一来源,主控端对话框维护)
|
||||
|
||||
| 档位 | 名称 | chunkKb | durationMs | 预估速度 |
|
||||
|---|---|---|---|---|
|
||||
| 0 | 最慢 | 64 | 200 | ≈ 0.3 MB/s |
|
||||
| 1 | 慢 | 64 | 100 | ≈ 0.6 MB/s |
|
||||
| 2 | 默认 | 64 | 50 | ≈ 1.25 MB/s |
|
||||
| 3 | 快 | 128 | 50 | ≈ 2.5 MB/s |
|
||||
| 4 | 更快 | 256 | 50 | ≈ 5 MB/s |
|
||||
| 5 | 很快 | 512 | 50 | ≈ 10 MB/s |
|
||||
| 6 | 不限速 | 1024 | 0 | 网络上限 |
|
||||
|
||||
- 滑块 `CSliderCtrl` 范围 `0..6`,`SetPageSize(1)`,默认落在 2。
|
||||
- `durationMs = 0` 表示不人为限速(`Sleep(0)` 仅让出时间片,实际受带宽约束)。
|
||||
- **注意 Windows `Sleep` 粒度 ≈ 15.6ms**:`durationMs` 低于约 15ms 基本等同不限速。故档位要么 ≥ 20ms,要么直接 0ms,不设 5ms 之类的“名不副实”中间值。
|
||||
|
||||
预估文案:`当前约 1.25 MB/s`;`durationMs==0` 显示 `不限速(受网络带宽约束)`。
|
||||
|
||||
- **多语言**:档位名(最慢/慢/默认/快/更快/很快/不限速)与预估格式串(`%s · 约 %.2f MB/s`、`%s · 不受限速(受网络带宽约束)`)经 `_TR`/`_LF` 走 `LangManager` 翻译表;语言文件以中文原文为 key。刻度标签拆成 最慢/默认/不限速 三个独立 `LTEXT` 以便各自翻译(英文宽度不同,不能靠空格对齐)。
|
||||
|
||||
---
|
||||
|
||||
## 4. 两个方向的生效链路
|
||||
|
||||
文件传输有两条方向,`InitFileUpload` 各自在不同进程/时机调用:
|
||||
|
||||
| 方向 | 发送方 | `InitFileUpload` 调用点 | 生效方式 |
|
||||
|---|---|---|---|
|
||||
| 上传(主控端 → 被控端) | 主控端 | `server/2015Remote/2015RemoteDlg.cpp:2223`(启动一次) | 读 `THIS_CFG`,重启主控端生效 |
|
||||
| 下载(被控端 → 主控端) | 被控端 | `client/FileManager.cpp:40`(CFileManager 构造,每会话一次) | 读客户端配置,下次打开文件管理会话生效 |
|
||||
|
||||
### 4.1 上传方向(主控端本地,无协议改动)
|
||||
|
||||
`2015RemoteDlg.cpp:2223` 现为 `InitFileUpload({},{},GetHMAC(),64,50,Logf,GetUpperHash())`,改为读 `THIS_CFG`:
|
||||
|
||||
```cpp
|
||||
int chunkKb = THIS_CFG.GetInt("transfer", "ChunkKb", 64);
|
||||
int durMs = THIS_CFG.GetInt("transfer", "DurationMs", 50);
|
||||
InitFileUpload({}, {}, GetHMAC(), chunkKb, durMs, Logf, GetUpperHash());
|
||||
```
|
||||
|
||||
### 4.2 下载方向(需下发到被控端)
|
||||
|
||||
新增命令 `CMD_FILE_SPEED`,照 `CMD_QUALITY_LEVEL(78)` 的“服务端下发 → 客户端持久化 → 本地生效”套路:
|
||||
|
||||
1. **`common/commands.h`**:新增 `CMD_FILE_SPEED = 252`(命令号单字节,252 < 255 安全)。
|
||||
2. **命令格式**:`[cmd:1][chunkKb:uint16 LE][durationMs:uint16 LE]`,共 5 字节。
|
||||
- 传原始 `chunkKb`/`durationMs` 而非档位索引,**避免客户端复制映射表**,映射表只存在于主控端对话框。
|
||||
3. **主控端下发**:在 `OnOnlineFileManager()`(`server/2015Remote/2015RemoteDlg.cpp:4737`,发 `COMMAND_LIST_DRIVE` 开文件管理会话)发 `COMMAND_LIST_DRIVE` **之前**,先经主连接把当前档位 `CMD_FILE_SPEED`(5 字节)发给被控端;`OnOnlineDesktopManager()`(`2015RemoteDlg.cpp:4723`,发 `COMMAND_SCREEN_SPY`)同理也发一次,覆盖“先开远程桌面再开文件管理”的引用计数时序。两处都在 `SendFileSpeedCommand()`(`:9310`)统一读取并下发。
|
||||
4. **被控端接收**:在客户端主连接分发 `client/KernelManager.cpp:814` 的 `switch`(`COMMAND_LIST_DRIVE` 所在,`case` 加在 `1280` 附近)加 `case CMD_FILE_SPEED`,把两数写入 `iniFile cfg(CLIENT_PATH)` 的 `[transfer]` 节。
|
||||
5. **被控端调用点读配置**:`client/FileManager.cpp:40`(CFileManager 构造)改为读 `cfg.GetInt("transfer","ChunkKb",64)` / `DurationMs`,替换硬编码 `64, 50`。CFileManager 每会话重建(构造 Init、析构 Uninit),故下次打开文件管理即生效。
|
||||
|
||||
> **关键**:库用进程级引用计数,速度只在**首次** `InitFileUpload` 时设定(`g_threadCount > 1` 时提前返回,不重设)。客户端共 4 个 `InitFileUpload` 调用点(`FileManager.cpp:40`、`ScreenManager.cpp:109`、`ScreenManager.cpp:873`、`KernelManager.cpp:1399`),谁先初始化谁锁定速度。故**这 4 处必须全部改为读同一配置**,否则下载速度会被先初始化的管理器(如远程桌面会话)锁成旧值。
|
||||
|
||||
---
|
||||
|
||||
## 5. 配置存储
|
||||
|
||||
- 主控端:`THIS_CFG`(ini)`[transfer]` 节 `ChunkKb` / `DurationMs`(int)。
|
||||
- 被控端:`iniFile(CLIENT_PATH)` 的 `[transfer]` 节 `ChunkKb` / `DurationMs`(int),由 `CMD_FILE_SPEED` 写入。
|
||||
|
||||
存 `ChunkKb`/`DurationMs` 两个 int 而非档位索引:自解释、直接对应 `InitFileUpload` 入参、不易错位。
|
||||
|
||||
---
|
||||
|
||||
## 6. 改动文件清单(Windows 端)
|
||||
|
||||
| 文件 | 改动 |
|
||||
|---|---|
|
||||
| `server/2015Remote/resource.h` | 加 `IDD_FILE_SPEED`、`ID_TOOL_FILE_SPEED`、`IDC_FSPEED_SLIDER`、`IDC_FSPEED_LABEL`、`IDC_FSPEED_RESET` |
|
||||
| `server/2015Remote/2015Remote.rc` | 「高级」菜单加一项;新增对话框资源(滑块+预估标签+按钮)。**文件为 UTF-16LE 编码,须按 Unicode 读写** |
|
||||
| `server/2015Remote/CFileSpeedDlg.h` | 新建:档位表 + `OnHScroll` 实时预估 + 恢复默认(照 `CPreviewLevelsDlg.h` 内联实现) |
|
||||
| `server/2015Remote/2015RemoteDlg.h` | 加 `OnFileTransferSpeed()` 声明 |
|
||||
| `server/2015Remote/2015RemoteDlg.cpp` | 消息映射 `ON_COMMAND(ID_TOOL_FILE_SPEED, ...)`;`2223` 读配置(上传);`OnFileTransferSpeed()` 弹出对话框并写回 THIS_CFG;`OnOnlineFileManager()`/`OnOnlineDesktopManager()` 发 `CMD_FILE_SPEED` |
|
||||
| `common/commands.h` | 加 `CMD_FILE_SPEED = 252` |
|
||||
| `client/KernelManager.cpp` | `case CMD_FILE_SPEED` 写客户端配置(主连接 switch,`814`) |
|
||||
| `client/FileManager.cpp`、`client/ScreenManager.cpp`、`client/KernelManager.cpp` | 4 个 `InitFileUpload` 调用点读配置替换硬编码 `64, 50`(引用计数要求全部一致) |
|
||||
| `server/2015Remote/lang/en_US.ini`、`zh_TW.ini`、`de_DE.ini` | 追加「文件传输速度」相关 13 条中文原文→译文(GBK 编码,`RCDATA "lang\*.ini"` 由 rc.exe 嵌入) |
|
||||
|
||||
---
|
||||
|
||||
## 7. 生效时机与提示文案
|
||||
|
||||
- 上传速度:重启主控端生效。
|
||||
- 下载速度:下次打开该主机的文件管理会话生效。
|
||||
- 对话框保存后弹提示:`文件传输速度已保存。上传速度重启主控端后生效;下载速度下次打开文件管理或远程桌面后生效。`
|
||||
|
||||
---
|
||||
|
||||
## 8. 风险与备注
|
||||
|
||||
1. **`Sleep` 精度**:Windows 计时器粒度约 15.6ms,`durationMs` 过小则失真(见 §3)。
|
||||
2. **实际速度 < 预估**:预估为纯 `chunk/delay` 理论值,未计入 `f()` 网络发送耗时;对话框文案用“约/大概”表述。
|
||||
3. **命令号冲突**:`CMD_FILE_SPEED=252` 需确认 `commands.h` 无重号;252 < 255(单字节 `uint8_t cmd` 上限)。
|
||||
4. **`.rc` 编码**:`2015Remote.rc` 为 UTF-16LE(带 BOM),编辑必须按 Unicode 处理,避免破坏资源脚本。
|
||||
5. **跨平台**:Linux/macOS 客户端下载路径暂不改(`CMD_FILE_SPEED` 会被老/其他平台客户端静默忽略,向后兼容)。
|
||||
6. **多语言 key 精确匹配**:语言文件为 GBK 编码、key 不 trim(`CIniParser` 保留原始空格);译文 key 必须与源码逐字一致——源码为 UTF-8、经 `/execution-charset:.936` 编译为 GBK,`·`(U+00B7)、全角括号()等需一致,否则查不到翻译。
|
||||
|
||||
---
|
||||
|
||||
## 9. 实施顺序
|
||||
|
||||
1. `common/commands.h` 加命令号 → `resource.h` 加 ID → `.rc` 加菜单项与对话框资源。
|
||||
2. 新建 `CFileSpeedDlg.h` → `2015RemoteDlg` 接线(上传方向,可先验证)。
|
||||
3. 主控端下发 `CMD_FILE_SPEED` → 客户端接收持久化 → 客户端调用点读配置(下载方向)。
|
||||
4. 编译验证(MSBuild 须传 `-p:SolutionDir`,见项目记忆)。
|
||||
Binary file not shown.
@@ -46,6 +46,7 @@
|
||||
#include "common/commands.h"
|
||||
#include "QualityLevelsDlg.h"
|
||||
#include "CPreviewLevelsDlg.h"
|
||||
#include "CFileSpeedDlg.h"
|
||||
#include "McpServer.h"
|
||||
#include "McpSettingsDlg.h"
|
||||
#include "common/md5.h"
|
||||
@@ -1018,6 +1019,7 @@ BEGIN_MESSAGE_MAP(CMy2015RemoteDlg, CDialogEx)
|
||||
ON_COMMAND(ID_MENU_NOTIFY_SETTINGS, &CMy2015RemoteDlg::OnMenuNotifySettings)
|
||||
ON_COMMAND(ID_TOOL_QUALITY_LEVELS, &CMy2015RemoteDlg::OnQualityLevels)
|
||||
ON_COMMAND(ID_TOOL_PREVIEW_LEVELS, &CMy2015RemoteDlg::OnPreviewLevels)
|
||||
ON_COMMAND(ID_TOOL_FILE_SPEED, &CMy2015RemoteDlg::OnFileTransferSpeed)
|
||||
ON_COMMAND(ID_EXECUTE_TESTRUN, &CMy2015RemoteDlg::OnExecuteTestrun)
|
||||
ON_COMMAND(ID_EXECUTE_GHOST, &CMy2015RemoteDlg::OnExecuteGhost)
|
||||
ON_COMMAND(ID_MASTER_TRAIL, &CMy2015RemoteDlg::OnMasterTrail)
|
||||
@@ -2220,7 +2222,9 @@ BOOL CMy2015RemoteDlg::OnInitDialog()
|
||||
}
|
||||
|
||||
UPDATE_SPLASH(18, "正在初始化文件上传模块...");
|
||||
int ret = InitFileUpload({}, {}, GetHMAC(), 64, 50, Logf, GetUpperHash());
|
||||
int chunkKb = 64, durMs = 50;
|
||||
GetTransferSpeed(THIS_CFG, chunkKb, durMs);
|
||||
int ret = InitFileUpload({}, {}, GetHMAC(), chunkKb, durMs, Logf, GetUpperHash());
|
||||
g_hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, AfxGetInstanceHandle(), 0);
|
||||
|
||||
UPDATE_SPLASH(20, "正在加载IP数据库...");
|
||||
@@ -4720,6 +4724,9 @@ VOID CMy2015RemoteDlg::OnOnlineDesktopManager()
|
||||
{
|
||||
if (!ShouldRemoteControl())
|
||||
return;
|
||||
// 先下发当前文件传输速度档位,再开远程桌面:避免被控端 ScreenManager 先初始化
|
||||
// 文件上传模块(进程级引用计数)把速度锁成旧值。
|
||||
SendFileSpeedCommand();
|
||||
int n = THIS_CFG.GetInt("settings", "DXGI");
|
||||
BOOL all = THIS_CFG.GetInt("settings", "MultiScreen", TRUE);
|
||||
CString algo = THIS_CFG.GetStr("settings", "ScreenCompress", ALGORITHM_NULL).c_str();
|
||||
@@ -4729,6 +4736,9 @@ VOID CMy2015RemoteDlg::OnOnlineDesktopManager()
|
||||
|
||||
VOID CMy2015RemoteDlg::OnOnlineFileManager()
|
||||
{
|
||||
// 先下发文件传输速度档位,再发 COMMAND_LIST_DRIVE 开文件管理:保证被控端
|
||||
// CFileManager 构造时读到的 [transfer] 配置已是最新值。
|
||||
SendFileSpeedCommand();
|
||||
BYTE bToken = COMMAND_LIST_DRIVE;
|
||||
SendSelectedCommand(&bToken, sizeof(BYTE));
|
||||
}
|
||||
@@ -9280,6 +9290,38 @@ void CMy2015RemoteDlg::OnPreviewLevels()
|
||||
}
|
||||
}
|
||||
|
||||
// ===== 文件传输速度配置([transfer] 节) =====
|
||||
// 档位表权威来源见 CFileSpeedDlg.h 的 kFileSpeedTiers。存 ChunkKb/DurationMs 两个 int
|
||||
// 而非档位索引,自解释且直接对应 InitFileUpload 入参,不易错位。
|
||||
|
||||
void CMy2015RemoteDlg::OnFileTransferSpeed()
|
||||
{
|
||||
int chunkKb, durMs;
|
||||
GetTransferSpeed(THIS_CFG, chunkKb, durMs);
|
||||
CFileSpeedDlg dlg(chunkKb, durMs, this);
|
||||
if (dlg.DoModal() == IDOK) {
|
||||
THIS_CFG.SetInt("transfer", "ChunkKb", dlg.GetChunkKb());
|
||||
THIS_CFG.SetInt("transfer", "DurationMs", dlg.GetDurMs());
|
||||
MessageBoxL("文件传输速度已保存。上传速度重启主控端后生效;下载速度下次打开文件管理或远程桌面后生效。",
|
||||
"提示", MB_ICONINFORMATION);
|
||||
}
|
||||
}
|
||||
|
||||
void CMy2015RemoteDlg::SendFileSpeedCommand()
|
||||
{
|
||||
int chunkKb, durMs;
|
||||
GetTransferSpeed(THIS_CFG, chunkKb, durMs);
|
||||
|
||||
// [cmd:1][chunkKb:uint16 LE][durationMs:uint16 LE]
|
||||
BYTE buf[5];
|
||||
buf[0] = CMD_FILE_SPEED;
|
||||
buf[1] = (BYTE)(chunkKb & 0xFF);
|
||||
buf[2] = (BYTE)((chunkKb >> 8) & 0xFF);
|
||||
buf[3] = (BYTE)(durMs & 0xFF);
|
||||
buf[4] = (BYTE)((durMs >> 8) & 0xFF);
|
||||
SendSelectedCommand(buf, sizeof(buf));
|
||||
}
|
||||
|
||||
void CMy2015RemoteDlg::ApplyThumbnailSettings()
|
||||
{
|
||||
// 任何已缓存的 HBITMAP 都是按"旧 ThumbWidth"渲染的,尺寸不再可信 —— 一律清空。
|
||||
|
||||
@@ -347,6 +347,12 @@ public:
|
||||
void SavePreviewProfilesToCfg() const; // m_PreviewProfiles 落盘到 THIS_CFG
|
||||
const PreviewProfile& GetPreviewProfileCfg(int level) const; // 供 ChooseScreenPreviewParams 用
|
||||
void OnPreviewLevels(); // 高级→屏幕预览质量等级
|
||||
|
||||
// ===== 文件传输速度配置([transfer] 节,ChunkKb / DurationMs) =====
|
||||
// 主控端 UI 偏好,持久化走 THIS_CFG。上传方向读 THIS_CFG(重启主控端生效);
|
||||
// 下载方向经 CMD_FILE_SPEED 下发到被控端(下次打开文件管理/远程桌面会话生效)。
|
||||
void OnFileTransferSpeed(); // 高级→文件传输速度
|
||||
void SendFileSpeedCommand(); // 把当前档位经主连接下发给被控端
|
||||
void SendThumbnailRequest(class context* ctx);// 发一次缩略图请求
|
||||
void CacheThumbnail(uint64_t clientID, const BYTE* jpeg, size_t bytes);
|
||||
void ClearThumbnailCacheEntry(uint64_t clientID);
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
// CFileSpeedDlg.h
|
||||
// 文件传输速度调节对话框:拖动滑块选档位,实时显示预估速度。
|
||||
// 纯主控端 UI 偏好,持久化由 CMy2015RemoteDlg::OnFileTransferSpeed() 负责。
|
||||
// 仅在 2015RemoteDlg.cpp 中 include 一次(头文件内联实现 + 消息映射,勿多处包含)。
|
||||
#pragma once
|
||||
|
||||
#include "LangManager.h"
|
||||
#include <afxcmn.h>
|
||||
|
||||
// 档位表(权威来源:docs/FileTransferSpeed_Design.md §3)。
|
||||
// chunkKb * 1024 / durationMs 即理论字节/秒;durationMs==0 表示不人为限速。
|
||||
struct FileSpeedTier { int chunkKb; int durMs; const TCHAR* name; };
|
||||
|
||||
static const FileSpeedTier kFileSpeedTiers[] = {
|
||||
{ 64, 200, _T("最慢") }, // ≈0.31 MB/s
|
||||
{ 64, 100, _T("慢") }, // ≈0.63 MB/s
|
||||
{ 64, 50, _T("默认") }, // ≈1.25 MB/s
|
||||
{ 128, 50, _T("快") }, // ≈2.5 MB/s
|
||||
{ 256, 50, _T("更快") }, // ≈5 MB/s
|
||||
{ 512, 50, _T("很快") }, // ≈10 MB/s
|
||||
{ 1024, 0, _T("不限速") }, // 网络上限
|
||||
};
|
||||
#define FILE_SPEED_TIER_COUNT 7
|
||||
#define FILE_SPEED_DEFAULT_TIER 2 // 默认档位
|
||||
|
||||
class CFileSpeedDlg : public CDialog
|
||||
{
|
||||
public:
|
||||
enum { IDD = IDD_FILE_SPEED };
|
||||
|
||||
CFileSpeedDlg(int chunkKb, int durMs, CWnd* pParent = NULL)
|
||||
: CDialog(CFileSpeedDlg::IDD, pParent), m_chunkKb(chunkKb), m_durMs(durMs)
|
||||
{
|
||||
}
|
||||
|
||||
int GetChunkKb() const { return m_chunkKb; }
|
||||
int GetDurMs() const { return m_durMs; }
|
||||
|
||||
protected:
|
||||
int m_chunkKb;
|
||||
int m_durMs;
|
||||
|
||||
static int TierIndexFor(int chunkKb, int durMs)
|
||||
{
|
||||
for (int i = 0; i < FILE_SPEED_TIER_COUNT; i++)
|
||||
if (kFileSpeedTiers[i].chunkKb == chunkKb && kFileSpeedTiers[i].durMs == durMs)
|
||||
return i;
|
||||
return FILE_SPEED_DEFAULT_TIER; // 未知值回落默认
|
||||
}
|
||||
|
||||
static void FormatSpeed(int idx, CString& out)
|
||||
{
|
||||
const FileSpeedTier& t = kFileSpeedTiers[idx];
|
||||
// 档位名与格式串经 _TR/_LF 走多语言表(LangManager),语言文件以中文原文为 key。
|
||||
if (t.durMs <= 0) {
|
||||
out.FormatL(_T("%s · 不受限速(受网络带宽约束)"), _LF(t.name));
|
||||
return;
|
||||
}
|
||||
double mbps = (double)t.chunkKb * 1024.0 / (t.durMs / 1000.0) / (1024.0 * 1024.0);
|
||||
out.FormatL(_T("%s · 约 %.2f MB/s"), _LF(t.name), mbps);
|
||||
}
|
||||
|
||||
int GetSliderPos()
|
||||
{
|
||||
int pos = (int)SendDlgItemMessage(IDC_FSPEED_SLIDER, TBM_GETPOS, 0, 0);
|
||||
if (pos < 0) pos = 0;
|
||||
if (pos >= FILE_SPEED_TIER_COUNT) pos = FILE_SPEED_TIER_COUNT - 1;
|
||||
return pos;
|
||||
}
|
||||
|
||||
void UpdateLabel()
|
||||
{
|
||||
CString s;
|
||||
FormatSpeed(GetSliderPos(), s);
|
||||
SetDlgItemText(IDC_FSPEED_LABEL, s);
|
||||
}
|
||||
|
||||
virtual BOOL OnInitDialog() override
|
||||
{
|
||||
CDialog::OnInitDialog();
|
||||
|
||||
SendDlgItemMessage(IDC_FSPEED_SLIDER, TBM_SETRANGE, TRUE,
|
||||
MAKELONG(0, FILE_SPEED_TIER_COUNT - 1));
|
||||
SendDlgItemMessage(IDC_FSPEED_SLIDER, TBM_SETPAGESIZE, 0, 1);
|
||||
SendDlgItemMessage(IDC_FSPEED_SLIDER, TBM_SETTICFREQ, 0, 1);
|
||||
SendDlgItemMessage(IDC_FSPEED_SLIDER, TBM_SETPOS, TRUE, TierIndexFor(m_chunkKb, m_durMs));
|
||||
|
||||
UpdateLabel();
|
||||
TranslateDialog(this);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
virtual void OnOK() override
|
||||
{
|
||||
int idx = GetSliderPos();
|
||||
m_chunkKb = kFileSpeedTiers[idx].chunkKb;
|
||||
m_durMs = kFileSpeedTiers[idx].durMs;
|
||||
CDialog::OnOK();
|
||||
}
|
||||
|
||||
afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
|
||||
{
|
||||
(void)nSBCode; (void)nPos; (void)pScrollBar;
|
||||
UpdateLabel(); // 拖动过程中实时刷新预估速度
|
||||
}
|
||||
|
||||
virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam) override
|
||||
{
|
||||
if (LOWORD(wParam) == IDC_FSPEED_RESET && HIWORD(wParam) == BN_CLICKED) {
|
||||
SendDlgItemMessage(IDC_FSPEED_SLIDER, TBM_SETPOS, TRUE, FILE_SPEED_DEFAULT_TIER);
|
||||
UpdateLabel();
|
||||
return TRUE;
|
||||
}
|
||||
return CDialog::OnCommand(wParam, lParam);
|
||||
}
|
||||
|
||||
DECLARE_MESSAGE_MAP()
|
||||
};
|
||||
|
||||
BEGIN_MESSAGE_MAP(CFileSpeedDlg, CDialog)
|
||||
ON_WM_HSCROLL()
|
||||
END_MESSAGE_MAP()
|
||||
@@ -2049,3 +2049,20 @@ Minimal
|
||||
JPEG质量=JPEG Qualitaet
|
||||
最大宽度为期望编码宽度;JPEG 质量 1~100=Max. Breite ist die Ziel-Codierbreite; JPEG Qualitaet 1~100
|
||||
预览质量等级已保存,下次发送预览时生效。=Vorschau-Qualitaetsstufen gespeichert. Wirksam bei der naechsten Vorschau.
|
||||
|
||||
; ============================================
|
||||
; File Transfer Speed Dialog (文件传输速度)
|
||||
; ============================================
|
||||
文件传输速度(&F)...=&Dateiuebertragungsgeschwindigkeit...
|
||||
文件传输速度=Dateiuebertragungsgeschwindigkeit
|
||||
拖动滑块设置文件传输速度:=Schieberegler ziehen, um die Uebertragungsgeschwindigkeit festzulegen:
|
||||
最慢=Langsamste
|
||||
慢=Langsam
|
||||
默认=Standard
|
||||
快=Schnell
|
||||
更快=Schneller
|
||||
很快=Sehr schnell
|
||||
不限速=Unbegrenzt
|
||||
%s · 约 %.2f MB/s=%s · ca. %.2f MB/s
|
||||
%s · 不受限速(受网络带宽约束)=%s · Unbegrenzt (durch Netzwerkbandbreite begrenzt)
|
||||
文件传输速度已保存。上传速度重启主控端后生效;下载速度下次打开文件管理或远程桌面后生效。=Uebertragungsgeschwindigkeit gespeichert. Upload-Geschwindigkeit wird nach Neustart des Masters wirksam; Download-Geschwindigkeit beim naechsten Oeffnen des Dateimanagers oder des Remotedesktops.
|
||||
@@ -2050,3 +2050,20 @@ Minimal
|
||||
JPEG质量=JPEG Quality
|
||||
最大宽度为期望编码宽度;JPEG 质量 1~100=Max width is the target encode width; JPEG quality 1~100
|
||||
预览质量等级已保存,下次发送预览时生效。=Preview quality levels saved. They take effect the next time a preview is sent.
|
||||
|
||||
; ============================================
|
||||
; File Transfer Speed Dialog (文件传输速度)
|
||||
; ============================================
|
||||
文件传输速度(&F)...=&File Transfer Speed...
|
||||
文件传输速度=File Transfer Speed
|
||||
拖动滑块设置文件传输速度:=Drag the slider to set the transfer speed:
|
||||
最慢=Slowest
|
||||
慢=Slow
|
||||
默认=Default
|
||||
快=Fast
|
||||
更快=Faster
|
||||
很快=Very Fast
|
||||
不限速=Unlimited
|
||||
%s · 约 %.2f MB/s=%s · about %.2f MB/s
|
||||
%s · 不受限速(受网络带宽约束)=%s · Unlimited (limited by network bandwidth)
|
||||
文件传输速度已保存。上传速度重启主控端后生效;下载速度下次打开文件管理或远程桌面后生效。=Transfer speed saved. Upload speed takes effect after restarting the master; download speed takes effect the next time you open File Manager or Remote Desktop.
|
||||
@@ -2041,3 +2041,20 @@ Minimal
|
||||
JPEG质量=JPEG品質
|
||||
最大宽度为期望编码宽度;JPEG 质量 1~100=最大寬度為期望編碼寬度;JPEG 品質 1~100
|
||||
预览质量等级已保存,下次发送预览时生效。=預覽品質等級已儲存,下次傳送預覽時生效。
|
||||
|
||||
; ============================================
|
||||
; File Transfer Speed Dialog (文件传输速度)
|
||||
; ============================================
|
||||
文件传输速度(&F)...=檔案傳輸速度(&F)...
|
||||
文件传输速度=檔案傳輸速度
|
||||
拖动滑块设置文件传输速度:=拖曳滑桿設定檔案傳輸速度:
|
||||
最慢=最慢
|
||||
慢=慢
|
||||
默认=預設
|
||||
快=快
|
||||
更快=更快
|
||||
很快=很快
|
||||
不限速=不限速
|
||||
%s · 约 %.2f MB/s=%s · 約 %.2f MB/s
|
||||
%s · 不受限速(受网络带宽约束)=%s · 不限速(受網路頻寬限制)
|
||||
文件传输速度已保存。上传速度重启主控端后生效;下载速度下次打开文件管理或远程桌面后生效。=檔案傳輸速度已儲存。上傳速度重啟主控端後生效;下載速度下次開啟檔案管理或遠端桌面後生效。
|
||||
@@ -1056,13 +1056,20 @@
|
||||
#define IDC_STATIC_SHARE_DAYS 2588
|
||||
#define IDC_EDIT_SHARE_DAYS 2589
|
||||
|
||||
// 文件传输速度调节对话框
|
||||
#define IDD_FILE_SPEED 403
|
||||
#define ID_TOOL_FILE_SPEED 33085
|
||||
#define IDC_FSPEED_SLIDER 2590
|
||||
#define IDC_FSPEED_LABEL 2591
|
||||
#define IDC_FSPEED_RESET 2592
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 403
|
||||
#define _APS_NEXT_COMMAND_VALUE 33085
|
||||
#define _APS_NEXT_CONTROL_VALUE 2590
|
||||
#define _APS_NEXT_RESOURCE_VALUE 404
|
||||
#define _APS_NEXT_COMMAND_VALUE 33086
|
||||
#define _APS_NEXT_CONTROL_VALUE 2593
|
||||
#define _APS_NEXT_SYMED_VALUE 105
|
||||
#endif
|
||||
#endif
|
||||
Reference in new issue
Block a user