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);