Feature: Add "Unban IP" to log message context menu in main dialog
- Add "Unban IP" menu item to the log message list (m_CList_Message)
right-click context menu, performing two actions on the extracted IP:
1. Remove the IP from the IPBlacklist singleton and persist to config
2. Scan the entire history host list (m_ClientMap->GetAll()) for all
clients matching the IP with AUTH_FORBIDDEN status, and restore
them to UNAUTHORIZED (0) — requiring re-authorization for safety
- Reuses ExtractFirstIPFromMessage() for dependency-free IPv4 parsing
- Handles the case where an IP is not in the blacklist and has no
matching forbidden clients with a clear "no action needed" message
- 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:
@@ -944,6 +944,7 @@ BEGIN_MESSAGE_MAP(CMy2015RemoteDlg, CDialogEx)
|
|||||||
ON_COMMAND(ID_MSGLOG_SEARCH, &CMy2015RemoteDlg::OnMsglogSearch)
|
ON_COMMAND(ID_MSGLOG_SEARCH, &CMy2015RemoteDlg::OnMsglogSearch)
|
||||||
ON_COMMAND(ID_MSGLOG_LOGIN_NOTIFY, &CMy2015RemoteDlg::OnMsglogLoginNotify)
|
ON_COMMAND(ID_MSGLOG_LOGIN_NOTIFY, &CMy2015RemoteDlg::OnMsglogLoginNotify)
|
||||||
ON_COMMAND(ID_MSGLOG_BAN_IP, &CMy2015RemoteDlg::OnMsglogBanIP)
|
ON_COMMAND(ID_MSGLOG_BAN_IP, &CMy2015RemoteDlg::OnMsglogBanIP)
|
||||||
|
ON_COMMAND(ID_MSGLOG_UNBAN_IP, &CMy2015RemoteDlg::OnMsglogUnbanIP)
|
||||||
ON_COMMAND(ID_ONLINE_ADD_WATCH, &CMy2015RemoteDlg::OnOnlineAddWatch)
|
ON_COMMAND(ID_ONLINE_ADD_WATCH, &CMy2015RemoteDlg::OnOnlineAddWatch)
|
||||||
ON_COMMAND(ID_ONLINE_LOGIN_NOTIFY, &CMy2015RemoteDlg::OnOnlineLoginNotify)
|
ON_COMMAND(ID_ONLINE_LOGIN_NOTIFY, &CMy2015RemoteDlg::OnOnlineLoginNotify)
|
||||||
ON_NOTIFY(NM_CUSTOMDRAW, IDC_ONLINE, &CMy2015RemoteDlg::OnNMCustomdrawOnline)
|
ON_NOTIFY(NM_CUSTOMDRAW, IDC_ONLINE, &CMy2015RemoteDlg::OnNMCustomdrawOnline)
|
||||||
@@ -9308,13 +9309,15 @@ void CMy2015RemoteDlg::OnRClickMessage(NMHDR* pNMHDR, LRESULT* pResult)
|
|||||||
menu.AppendMenu(MF_SEPARATOR);
|
menu.AppendMenu(MF_SEPARATOR);
|
||||||
menu.AppendMenu(MF_STRING, ID_MSGLOG_LOGIN_NOTIFY, _TR("上线提醒"));
|
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_BAN_IP, _TR("封禁IP"));
|
||||||
|
menu.AppendMenu(MF_STRING, ID_MSGLOG_UNBAN_IP, _TR("解除封禁"));
|
||||||
|
|
||||||
// 没有选中项时禁用"删除选中"、"复制选中"、"上线提醒"和"封禁IP"
|
// 没有选中项时禁用"删除选中"、"复制选中"、"上线提醒"、"封禁IP"和"解除封禁"
|
||||||
if (m_CList_Message.GetSelectedCount() == 0) {
|
if (m_CList_Message.GetSelectedCount() == 0) {
|
||||||
menu.EnableMenuItem(ID_MSGLOG_DELETE, MF_GRAYED);
|
menu.EnableMenuItem(ID_MSGLOG_DELETE, MF_GRAYED);
|
||||||
menu.EnableMenuItem(ID_MSGLOG_COPY, MF_GRAYED);
|
menu.EnableMenuItem(ID_MSGLOG_COPY, MF_GRAYED);
|
||||||
menu.EnableMenuItem(ID_MSGLOG_LOGIN_NOTIFY, MF_GRAYED);
|
menu.EnableMenuItem(ID_MSGLOG_LOGIN_NOTIFY, MF_GRAYED);
|
||||||
menu.EnableMenuItem(ID_MSGLOG_BAN_IP, MF_GRAYED);
|
menu.EnableMenuItem(ID_MSGLOG_BAN_IP, MF_GRAYED);
|
||||||
|
menu.EnableMenuItem(ID_MSGLOG_UNBAN_IP, MF_GRAYED);
|
||||||
}
|
}
|
||||||
// PowerShell不可用时禁用"上线提醒"
|
// PowerShell不可用时禁用"上线提醒"
|
||||||
if (!GetNotifyManager().IsPowerShellAvailable()) {
|
if (!GetNotifyManager().IsPowerShellAvailable()) {
|
||||||
@@ -9623,6 +9626,73 @@ void CMy2015RemoteDlg::OnMsglogBanIP()
|
|||||||
MessageBoxL(details, _TR("封禁IP"), MB_ICONINFORMATION);
|
MessageBoxL(details, _TR("封禁IP"), MB_ICONINFORMATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CMy2015RemoteDlg::OnMsglogUnbanIP()
|
||||||
|
{
|
||||||
|
// Get selected log messages and extract IP addresses from them
|
||||||
|
std::vector<std::string> ipsToProcess;
|
||||||
|
|
||||||
|
POSITION pos = m_CList_Message.GetFirstSelectedItemPosition();
|
||||||
|
while (pos) {
|
||||||
|
int row = m_CList_Message.GetNextSelectedItem(pos);
|
||||||
|
CString msgText = m_CList_Message.GetItemText(row, 2);
|
||||||
|
|
||||||
|
CString extractedIP;
|
||||||
|
if (ExtractFirstIPFromMessage(msgText, extractedIP)) {
|
||||||
|
std::string ipUtf8 = CT2A(extractedIP, CP_UTF8);
|
||||||
|
ipsToProcess.push_back(ipUtf8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ipsToProcess.empty()) {
|
||||||
|
MessageBoxL("所选日志消息中未检测到有效的 IP 地址", "提示", MB_ICONINFORMATION);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int unblacklistedCount = 0;
|
||||||
|
int clientRestoredCount = 0;
|
||||||
|
|
||||||
|
for (const auto& ip : ipsToProcess) {
|
||||||
|
// 1. Remove from IP blacklist
|
||||||
|
if (IPBlacklist::getInstance().IsBlacklisted(ip)) {
|
||||||
|
IPBlacklist::getInstance().RemoveIP(ip);
|
||||||
|
unblacklistedCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Find all clients matching this IP and restore AUTH_FORBIDDEN to UNAUTHORIZED
|
||||||
|
for (const auto& kv : m_ClientMap->GetAll()) {
|
||||||
|
if (strcmp(kv.second.IP, ip.c_str()) == 0
|
||||||
|
&& kv.second.Authorized == AUTH_FORBIDDEN) {
|
||||||
|
m_ClientMap->SetClientMapInteger(kv.first, MAP_AUTH, UNAUTHORIZED);
|
||||||
|
clientRestoredCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Persist
|
||||||
|
if (unblacklistedCount > 0) {
|
||||||
|
std::string blacklistStr = IPBlacklist::getInstance().Export();
|
||||||
|
THIS_CFG.SetStr("settings", "IPBlacklist", blacklistStr.c_str());
|
||||||
|
}
|
||||||
|
if (clientRestoredCount > 0) {
|
||||||
|
m_ClientMap->SaveToFile(GetDbPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build result message
|
||||||
|
CString details;
|
||||||
|
if (unblacklistedCount > 0) {
|
||||||
|
details.AppendFormat(_TR("已将 %d 个 IP 从黑名单移除"), unblacklistedCount);
|
||||||
|
}
|
||||||
|
if (clientRestoredCount > 0) {
|
||||||
|
if (!details.IsEmpty()) details += _T("\n");
|
||||||
|
details.AppendFormat(_TR("已恢复 %d 个客户端的授权状态"), clientRestoredCount);
|
||||||
|
}
|
||||||
|
if (unblacklistedCount == 0 && clientRestoredCount == 0) {
|
||||||
|
details = _TR("未找到需要解除封禁的 IP");
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageBoxL(details, _TR("解除封禁"), MB_ICONINFORMATION);
|
||||||
|
}
|
||||||
|
|
||||||
void CMy2015RemoteDlg::OnOnlineAddWatch()
|
void CMy2015RemoteDlg::OnOnlineAddWatch()
|
||||||
{
|
{
|
||||||
EnterCriticalSection(&m_cs);
|
EnterCriticalSection(&m_cs);
|
||||||
|
|||||||
@@ -566,6 +566,7 @@ public:
|
|||||||
afx_msg void OnMsglogSearch();
|
afx_msg void OnMsglogSearch();
|
||||||
afx_msg void OnMsglogLoginNotify();
|
afx_msg void OnMsglogLoginNotify();
|
||||||
afx_msg void OnMsglogBanIP();
|
afx_msg void OnMsglogBanIP();
|
||||||
|
afx_msg void OnMsglogUnbanIP();
|
||||||
afx_msg void OnOnlineAddWatch();
|
afx_msg void OnOnlineAddWatch();
|
||||||
afx_msg void OnNMCustomdrawOnline(NMHDR* pNMHDR, LRESULT* pResult);
|
afx_msg void OnNMCustomdrawOnline(NMHDR* pNMHDR, LRESULT* pResult);
|
||||||
afx_msg void OnOnlineRunAsAdmin();
|
afx_msg void OnOnlineRunAsAdmin();
|
||||||
|
|||||||
@@ -1973,3 +1973,7 @@ FRPC Զ
|
|||||||
%d 个 IP 已在黑名单中=%d IP(s) already in blacklist
|
%d 个 IP 已在黑名单中=%d IP(s) already in blacklist
|
||||||
%d 个 IP 在白名单中,已跳过=%d IP(s) in whitelist, skipped
|
%d 个 IP 在白名单中,已跳过=%d IP(s) in whitelist, skipped
|
||||||
未执行任何操作=No action taken
|
未执行任何操作=No action taken
|
||||||
|
解除封禁=Unban IP
|
||||||
|
已将 %d 个 IP 从黑名单移除=Removed %d IP(s) from blacklist
|
||||||
|
已恢复 %d 个客户端的授权状态=Restored authorization for %d client(s)
|
||||||
|
未找到需要解除封禁的 IP=No IPs found that need unbanning
|
||||||
|
|||||||
@@ -1964,3 +1964,7 @@ FRPC Զ
|
|||||||
%d 个 IP 已在黑名单中=%d 個 IP 已在黑名單中
|
%d 个 IP 已在黑名单中=%d 個 IP 已在黑名單中
|
||||||
%d 个 IP 在白名单中,已跳过=%d 個 IP 在白名單中,已跳過
|
%d 个 IP 在白名单中,已跳过=%d 個 IP 在白名單中,已跳過
|
||||||
未执行任何操作=未執行任何操作
|
未执行任何操作=未執行任何操作
|
||||||
|
解除封禁=解除封禁
|
||||||
|
已将 %d 个 IP 从黑名单移除=已將 %d 個 IP 從黑名單移除
|
||||||
|
已恢复 %d 个客户端的授权状态=已恢復 %d 個客戶端的授權狀態
|
||||||
|
未找到需要解除封禁的 IP=未找到需要解除封禁的 IP
|
||||||
|
|||||||
@@ -993,6 +993,7 @@
|
|||||||
#define ID_MSGLOG_SEARCH 33078
|
#define ID_MSGLOG_SEARCH 33078
|
||||||
#define ID_MSGLOG_LOGIN_NOTIFY 33079
|
#define ID_MSGLOG_LOGIN_NOTIFY 33079
|
||||||
#define ID_MSGLOG_BAN_IP 33080
|
#define ID_MSGLOG_BAN_IP 33080
|
||||||
|
#define ID_MSGLOG_UNBAN_IP 33081
|
||||||
#define ID_WEB_REMOTE_CONTROL 33044
|
#define ID_WEB_REMOTE_CONTROL 33044
|
||||||
#define ID_TOOL_PLUGIN_SETTINGS 33045
|
#define ID_TOOL_PLUGIN_SETTINGS 33045
|
||||||
#define ID_33046 33046
|
#define ID_33046 33046
|
||||||
@@ -1034,7 +1035,7 @@
|
|||||||
#ifdef APSTUDIO_INVOKED
|
#ifdef APSTUDIO_INVOKED
|
||||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||||
#define _APS_NEXT_RESOURCE_VALUE 398
|
#define _APS_NEXT_RESOURCE_VALUE 398
|
||||||
#define _APS_NEXT_COMMAND_VALUE 33081
|
#define _APS_NEXT_COMMAND_VALUE 33082
|
||||||
#define _APS_NEXT_CONTROL_VALUE 2542
|
#define _APS_NEXT_CONTROL_VALUE 2542
|
||||||
#define _APS_NEXT_SYMED_VALUE 105
|
#define _APS_NEXT_SYMED_VALUE 105
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user