Feature: Add "Ban IP" to log message context menu in main dialog

- Add "Ban IP" menu item to the log message list (m_CList_Message)
  right-click context menu, allowing users to extract IPv4 addresses from
  selected log entries and add them directly to the IP blacklist
- Reuses ExtractFirstIPFromMessage() from the previous commit for
  dependency-free IPv4 parsing with per-segment 0-255 validation
- Checks against whitelist before banning (whitelisted IPs cannot be
  banned) and skips IPs already in blacklist with clear feedback
- Immediately persists via THIS_CFG.SetStr to the config ini file;
  IPBlacklist singleton takes effect instantly — subsequent connections
  from banned IPs are rejected in IOCPServer::OnAccept() which already
  calls IsIPBlacklisted() on every new connection
- Menu item is grayed out when no log entry is selected
- Sync en_US / zh_TW language files with new translation strings

Co-Authored-By: DeepSeek V4 Pro
This commit is contained in:
yuanyuanxiang
2026-08-06 20:44:33 +02:00
parent eeacbe5d61
commit 7bbc47a0ee
5 changed files with 88 additions and 2 deletions

View File

@@ -943,6 +943,7 @@ BEGIN_MESSAGE_MAP(CMy2015RemoteDlg, CDialogEx)
ON_COMMAND(ID_MSGLOG_CLEAR, &CMy2015RemoteDlg::OnMsglogClear)
ON_COMMAND(ID_MSGLOG_SEARCH, &CMy2015RemoteDlg::OnMsglogSearch)
ON_COMMAND(ID_MSGLOG_LOGIN_NOTIFY, &CMy2015RemoteDlg::OnMsglogLoginNotify)
ON_COMMAND(ID_MSGLOG_BAN_IP, &CMy2015RemoteDlg::OnMsglogBanIP)
ON_COMMAND(ID_ONLINE_ADD_WATCH, &CMy2015RemoteDlg::OnOnlineAddWatch)
ON_COMMAND(ID_ONLINE_LOGIN_NOTIFY, &CMy2015RemoteDlg::OnOnlineLoginNotify)
ON_NOTIFY(NM_CUSTOMDRAW, IDC_ONLINE, &CMy2015RemoteDlg::OnNMCustomdrawOnline)
@@ -9306,12 +9307,14 @@ void CMy2015RemoteDlg::OnRClickMessage(NMHDR* pNMHDR, LRESULT* pResult)
m_bLogSearchVisible ? _TR("隐藏搜索") : _TR("搜索日志"));
menu.AppendMenu(MF_SEPARATOR);
menu.AppendMenu(MF_STRING, ID_MSGLOG_LOGIN_NOTIFY, _TR("上线提醒"));
menu.AppendMenu(MF_STRING, ID_MSGLOG_BAN_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);
}
// PowerShell不可用时禁用"上线提醒"
if (!GetNotifyManager().IsPowerShellAvailable()) {
@@ -9549,6 +9552,77 @@ void CMy2015RemoteDlg::OnMsglogLoginNotify()
MessageBoxL(msg, _TR("上线提醒"), MB_ICONINFORMATION);
}
void CMy2015RemoteDlg::OnMsglogBanIP()
{
// 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("所选日志消息中未检测到有效的 IP 地址", "提示", MB_ICONINFORMATION);
return;
}
// Process each extracted IP
int bannedCount = 0;
int alreadyCount = 0;
int whitelistCount = 0;
for (const auto& ip : ipsToAdd) {
// Cannot ban whitelisted IPs
if (IPWhitelist::getInstance().IsWhitelisted(ip)) {
whitelistCount++;
continue;
}
// Already in blacklist
if (IPBlacklist::getInstance().IsBlacklisted(ip)) {
alreadyCount++;
continue;
}
IPBlacklist::getInstance().AddIP(ip);
bannedCount++;
}
// Persist to config
if (bannedCount > 0) {
std::string blacklistStr = IPBlacklist::getInstance().Export();
THIS_CFG.SetStr("settings", "IPBlacklist", blacklistStr.c_str());
}
// Build result message
CString details;
if (bannedCount > 0) {
details.AppendFormat(_TR("已封禁 %d 个 IP"), bannedCount);
}
if (alreadyCount > 0) {
if (!details.IsEmpty()) details += _T("\n");
details.AppendFormat(_TR("%d 个 IP 已在黑名单中"), alreadyCount);
}
if (whitelistCount > 0) {
if (!details.IsEmpty()) details += _T("\n");
details.AppendFormat(_TR("%d 个 IP 在白名单中,已跳过"), whitelistCount);
}
if (details.IsEmpty()) {
details = _TR("未执行任何操作");
}
MessageBoxL(details, _TR("封禁IP"), MB_ICONINFORMATION);
}
void CMy2015RemoteDlg::OnOnlineAddWatch()
{
EnterCriticalSection(&m_cs);