Feat: Add whitelist action to log-list right-click menu

Adds a "白名单" item after "解除封禁" in the message-log context menu.
It extracts the IP from each selected log entry, asks for confirmation,
then adds it to the shared IPWhitelist singleton — which IOCPServer and
the DLL rate limiter already consult live — so the entry takes effect on
new connections immediately, without a restart. The whitelist is
persisted to settings\IPWhitelist the same way the Network dialog does.

- An IP already in the whitelist is reported as such and skipped.
- An IP in the IP blacklist (banned) is reported as banned and skipped,
  rather than silently removed from the blacklist.
- Menu item, confirmation, and result strings are added to the
  en_US/zh_TW/de_DE language files.

Co-Authored-By: deepseek-v4-pro
This commit is contained in:
yuanyuanxianganddeepseek-v4-pro committed 2026-10-16 13:16:33 +02:00
1 parent c85039ea0a
commit d7b49a3d06
6 files changed
+98 -2

No files matched your search

+80 -1
View File
@@ -1036,6 +1036,7 @@ BEGIN_MESSAGE_MAP(CMy2015RemoteDlg, CDialogEx)
ON_COMMAND(ID_MSGLOG_LOGIN_NOTIFY, &CMy2015RemoteDlg::OnMsglogLoginNotify)
ON_COMMAND(ID_MSGLOG_BAN_IP, &CMy2015RemoteDlg::OnMsglogBanIP)
ON_COMMAND(ID_MSGLOG_UNBAN_IP, &CMy2015RemoteDlg::OnMsglogUnbanIP)
ON_COMMAND(ID_MSGLOG_WHITELIST_IP, &CMy2015RemoteDlg::OnMsglogWhitelistIP)
ON_COMMAND(ID_ONLINE_ADD_WATCH, &CMy2015RemoteDlg::OnOnlineAddWatch)
ON_COMMAND(ID_ONLINE_LOGIN_NOTIFY, &CMy2015RemoteDlg::OnOnlineLoginNotify)
ON_NOTIFY(NM_CUSTOMDRAW, IDC_ONLINE, &CMy2015RemoteDlg::OnNMCustomdrawOnline)
@@ -10236,14 +10237,16 @@ void CMy2015RemoteDlg::OnRClickMessage(NMHDR* pNMHDR, LRESULT* pResult)
menu.AppendMenu(MF_STRING, ID_MSGLOG_LOGIN_NOTIFY, _TR("上线提醒"));
menu.AppendMenu(MF_STRING, ID_MSGLOG_BAN_IP, _TR("封禁IP"));
menu.AppendMenu(MF_STRING, ID_MSGLOG_UNBAN_IP, _TR("解除封禁"));
menu.AppendMenu(MF_STRING, ID_MSGLOG_WHITELIST_IP, _TR("白名单"));
// 没有选中项时禁用"删除选中"、"复制选中"、"上线提醒"、"封禁IP"和"解除封禁"
// 没有选中项时禁用"删除选中"、"复制选中"、"上线提醒"、"封禁IP"、"解除封禁"和"白名单"
if (m_CList_Message.GetSelectedCount() == 0) {
menu.EnableMenuItem(ID_MSGLOG_DELETE, MF_GRAYED);
menu.EnableMenuItem(ID_MSGLOG_COPY, MF_GRAYED);
menu.EnableMenuItem(ID_MSGLOG_LOGIN_NOTIFY, MF_GRAYED);
menu.EnableMenuItem(ID_MSGLOG_BAN_IP, MF_GRAYED);
menu.EnableMenuItem(ID_MSGLOG_UNBAN_IP, MF_GRAYED);
menu.EnableMenuItem(ID_MSGLOG_WHITELIST_IP, MF_GRAYED);
}
// PowerShell不可用时禁用"上线提醒"
if (!GetNotifyManager().IsPowerShellAvailable()) {
@@ -10630,6 +10633,82 @@ void CMy2015RemoteDlg::OnMsglogUnbanIP()
MessageBoxL(details, _TR("解除封禁"), MB_ICONINFORMATION);
}
void CMy2015RemoteDlg::OnMsglogWhitelistIP()
{
// Get selected log messages and extract IP addresses from them
std::vector<std::string> ipsToAdd;
POSITION pos = m_CList_Message.GetFirstSelectedItemPosition();
while (pos) {
int row = m_CList_Message.GetNextSelectedItem(pos);
// Column 2 is the message content ("信息内容")
CString msgText = m_CList_Message.GetItemText(row, 2);
CString extractedIP;
if (ExtractFirstIPFromMessage(msgText, extractedIP)) {
std::string ipUtf8 = CT2A(extractedIP, CP_UTF8);
ipsToAdd.push_back(ipUtf8);
}
}
if (ipsToAdd.empty()) {
MessageBoxL(_TR("所选日志消息中未检测到有效的 IP 地址"), _TR("提示"), MB_ICONINFORMATION);
return;
}
// 二次确认
if (IDYES != MessageBoxL(_TR("确定将选中日志中的 IP 加入白名单吗?"), _TR("提示"), MB_ICONQUESTION | MB_YESNO)) {
return;
}
// Process each extracted IP
int addedCount = 0;
int alreadyCount = 0;
int bannedCount = 0;
for (const auto& ip : ipsToAdd) {
// Already whitelisted
if (IPWhitelist::getInstance().IsWhitelisted(ip)) {
alreadyCount++;
continue;
}
// Banned IPs cannot be whitelisted
if (IPBlacklist::getInstance().IsBlacklisted(ip)) {
bannedCount++;
continue;
}
IPWhitelist::getInstance().AddIP(ip);
addedCount++;
}
// Persist to config
if (addedCount > 0) {
std::string whitelistStr = IPWhitelist::getInstance().Export();
THIS_CFG.SetStr("settings", "IPWhitelist", whitelistStr.c_str());
}
// Build result message
CString details;
if (addedCount > 0) {
details.AppendFormat(_TR("已将 %d 个 IP 加入白名单"), addedCount);
}
if (alreadyCount > 0) {
if (!details.IsEmpty()) details += _T("\n");
details.AppendFormat(_TR("%d 个 IP 已在白名单中"), alreadyCount);
}
if (bannedCount > 0) {
if (!details.IsEmpty()) details += _T("\n");
details.AppendFormat(_TR("%d 个 IP 已封禁,无法加入白名单"), bannedCount);
}
if (details.IsEmpty()) {
details = _TR("未执行任何操作");
}
MessageBoxL(details, _TR("白名单"), MB_ICONINFORMATION);
}
void CMy2015RemoteDlg::OnOnlineAddWatch()
{
EnterCriticalSection(&m_cs);
+1
View File
@@ -630,6 +630,7 @@ public:
afx_msg void OnMsglogLoginNotify();
afx_msg void OnMsglogBanIP();
afx_msg void OnMsglogUnbanIP();
afx_msg void OnMsglogWhitelistIP();
afx_msg void OnOnlineAddWatch();
afx_msg void OnNMCustomdrawOnline(NMHDR* pNMHDR, LRESULT* pResult);
afx_msg void OnOnlineRunAsAdmin();
+5
View File
@@ -2087,3 +2087,8 @@ TLS
确定取消选中主机的 TLS 传输吗?(客户端下次启动生效)=TLS-Transport fuer die ausgewaehlten Hosts deaktivieren? (wirkt nach Client-Neustart)
服务端未启用 TLS 证书,无法切换客户端 TLS 传输=Server-TLS-Zertifikat ist nicht aktiviert; TLS-Transport der Clients kann nicht umgeschaltet werden
读取服务端 TLS 证书失败,无法下发=Server-TLS-Zertifikat konnte nicht gelesen werden; Verteilung nicht moeglich
白名单=Whitelist
确定将选中日志中的 IP 加入白名单吗?=IP aus den ausgewaehlten Log-Eintraegen zur Whitelist hinzufuegen?
已将 %d 个 IP 加入白名单=%d IP(s) zur Whitelist hinzugefuegt
%d 个 IP 已在白名单中=%d IP(s) bereits in der Whitelist
%d 个 IP 已封禁,无法加入白名单=%d IP(s) sind gesperrt und koennen nicht zur Whitelist hinzugefuegt werden
+5
View File
@@ -2102,3 +2102,8 @@ TLS
确定取消选中主机的 TLS 传输吗?(客户端下次启动生效)=Disable TLS transport for the selected host? (takes effect after the client restarts)
服务端未启用 TLS 证书,无法切换客户端 TLS 传输=Server TLS certificate is not enabled; cannot toggle client TLS transport
读取服务端 TLS 证书失败,无法下发=Failed to read the server TLS certificate; cannot distribute
白名单=Whitelist
确定将选中日志中的 IP 加入白名单吗?=Add the IP from the selected log entries to the whitelist?
已将 %d 个 IP 加入白名单=Added %d IP(s) to the whitelist
%d 个 IP 已在白名单中=%d IP(s) already in the whitelist
%d 个 IP 已封禁,无法加入白名单=%d IP(s) are banned and cannot be added to the whitelist
+5
View File
@@ -2093,3 +2093,8 @@ TLS
确定取消选中主机的 TLS 传输吗?(客户端下次启动生效)=確定取消選取主機的 TLS 傳輸嗎?(用戶端下次啟動生效)
服务端未启用 TLS 证书,无法切换客户端 TLS 传输=伺服器未啟用 TLS 憑證,無法切換用戶端 TLS 傳輸
读取服务端 TLS 证书失败,无法下发=讀取伺服器 TLS 憑證失敗,無法下發
白名单=白名單
确定将选中日志中的 IP 加入白名单吗?=確定將選取日誌中的 IP 加入白名單嗎?
已将 %d 个 IP 加入白名单=已將 %d 個 IP 加入白名單
%d 个 IP 已在白名单中=%d 個 IP 已在白名單中
%d 个 IP 已封禁,无法加入白名单=%d 個 IP 已封禁,無法加入白名單
+2 -1
View File
@@ -1010,6 +1010,7 @@
#define ID_MSGLOG_LOGIN_NOTIFY 33079
#define ID_MSGLOG_BAN_IP 33080
#define ID_MSGLOG_UNBAN_IP 33081
#define ID_MSGLOG_WHITELIST_IP 33096
#define ID_WEB_REMOTE_CONTROL 33044
#define ID_TOOL_PLUGIN_SETTINGS 33045
#define ID_MCP_SETTINGS 33077
@@ -1120,7 +1121,7 @@
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 412
#define _APS_NEXT_COMMAND_VALUE 33096
#define _APS_NEXT_COMMAND_VALUE 33097
#define _APS_NEXT_CONTROL_VALUE 2620
#define _APS_NEXT_SYMED_VALUE 105
#endif