Commit 6d0b1bb (Feat: Add privilege column) inserted ONLINELIST_PRIVILEGE
at enum value 9, shifting INSTALLTIME from 9→10 and PATH from 12→13.
However, FileUpload_Lib (SimplePlugins) is compiled against a separate
copy of context.h that still uses the old enum values. Since
HostInfo.cpp's SaveClientMapData uses OLD enum values to read
sClientInfo[], it was reading privilegeStr for InstallTime and client
type for ProgramPath — corrupting the history host database.
Fix: move ONLINELIST_PRIVILEGE to value 16 (just before MAX), restoring
all original enum values (INSTALLTIME=9, PATH=12, etc.) so the
pre-built library can continue reading correct data without recompilation.
The 'permission' column now appears as the rightmost column in the
online host list instead of between 'version' and 'install time'.
Co-Authored-By: DeepSeek V4 Pro
129 lines
3.7 KiB
C++
129 lines
3.7 KiB
C++
#pragma once
|
|
|
|
#include <string>
|
|
#include <vector>
|
|
#include <unordered_map>
|
|
#include <ctime>
|
|
|
|
// Notification cooldown period (minutes)
|
|
// Same host will only trigger one notification within this period
|
|
#define NOTIFY_COOLDOWN_MINUTES 60
|
|
|
|
// Notification trigger types
|
|
enum NotifyTriggerType {
|
|
NOTIFY_TRIGGER_NONE = 0,
|
|
NOTIFY_TRIGGER_HOST_ONLINE = 1, // Host comes online
|
|
// Future extensions:
|
|
// NOTIFY_TRIGGER_HOST_OFFLINE = 2,
|
|
// NOTIFY_TRIGGER_FILE_TRANSFER = 3,
|
|
};
|
|
|
|
// Single notification rule
|
|
struct NotifyRule {
|
|
bool enabled; // Whether this rule is enabled
|
|
NotifyTriggerType triggerType; // Trigger type
|
|
int columnIndex; // Column index (0-based)
|
|
std::string matchPattern; // Match pattern (semicolon-separated keywords)
|
|
|
|
NotifyRule()
|
|
: enabled(false)
|
|
, triggerType(NOTIFY_TRIGGER_NONE)
|
|
, columnIndex(0)
|
|
{}
|
|
};
|
|
|
|
// SMTP configuration
|
|
struct SmtpConfig {
|
|
std::string server; // smtp.gmail.com
|
|
int port; // 587
|
|
bool useSSL; // true for TLS
|
|
std::string username; // sender email
|
|
std::string password; // app-specific password (encrypted in storage)
|
|
std::string recipient; // recipient email
|
|
|
|
SmtpConfig()
|
|
: port(587)
|
|
, useSSL(true)
|
|
{}
|
|
|
|
bool IsValid() const {
|
|
return !server.empty() && port > 0 && !username.empty() && !password.empty();
|
|
}
|
|
|
|
// Get effective recipient (fallback to username if empty)
|
|
std::string GetRecipient() const {
|
|
return recipient.empty() ? username : recipient;
|
|
}
|
|
};
|
|
|
|
// Complete notification configuration
|
|
struct NotifyConfig {
|
|
SmtpConfig smtp;
|
|
std::vector<NotifyRule> rules; // Rule list (supports multiple rules in future)
|
|
|
|
// Frequency control: record last notification time for each host
|
|
// key = clientID, value = last notification timestamp
|
|
std::unordered_map<uint64_t, time_t> lastNotifyTime;
|
|
|
|
NotifyConfig() {
|
|
// Initialize with one default rule
|
|
rules.push_back(NotifyRule());
|
|
}
|
|
|
|
// Get the first (and currently only) rule
|
|
NotifyRule& GetRule() {
|
|
if (rules.empty()) {
|
|
rules.push_back(NotifyRule());
|
|
}
|
|
return rules[0];
|
|
}
|
|
|
|
const NotifyRule& GetRule() const {
|
|
static NotifyRule emptyRule;
|
|
return rules.empty() ? emptyRule : rules[0];
|
|
}
|
|
|
|
// Check if any rule is enabled
|
|
bool HasEnabledRule() const {
|
|
for (const auto& rule : rules) {
|
|
if (rule.enabled) return true;
|
|
}
|
|
return false;
|
|
}
|
|
};
|
|
|
|
// Column name mapping for UI
|
|
inline const char* GetColumnName(int index) {
|
|
static const char* names[] = {
|
|
"IP", // 0
|
|
"Address", // 1
|
|
"Location", // 2
|
|
"ComputerName", // 3
|
|
"OS", // 4
|
|
"CPU", // 5
|
|
"Camera", // 6
|
|
"RTT", // 7
|
|
"Version", // 8
|
|
"InstallTime", // 9 ONLINELIST_INSTALLTIME
|
|
"ActiveWindow", // 10 ONLINELIST_LOGINTIME
|
|
"ClientType", // 11 ONLINELIST_CLIENTTYPE
|
|
"Path", // 12 ONLINELIST_PATH
|
|
"PublicIP", // 13 ONLINELIST_PUBIP
|
|
"StartTime", // 14 ONLINELIST_STARTTIME
|
|
"Capabilities", // 15 ONLINELIST_CAPABILITIES
|
|
"Privilege", // 16 ONLINELIST_PRIVILEGE
|
|
};
|
|
if (index >= 0 && index < sizeof(names)/sizeof(names[0])) {
|
|
return names[index];
|
|
}
|
|
return "Unknown";
|
|
}
|
|
|
|
// Trigger type name mapping for UI
|
|
inline const char* GetTriggerTypeName(NotifyTriggerType type) {
|
|
switch (type) {
|
|
case NOTIFY_TRIGGER_HOST_ONLINE: return "Host Online";
|
|
default: return "None";
|
|
}
|
|
}
|