This commit is contained in:
2026-03-31 10:59:30 +03:00
parent 0301242716
commit f457aa2a11
4 changed files with 180 additions and 9 deletions

View File

@@ -339,5 +339,45 @@ function PLUGIN:UpdateLogsList()
-- Сообщение -- Сообщение
draw.SimpleText(log.message, "ixSmallFont", 15, 43, COLOR_TEXT_PRIMARY, TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP) draw.SimpleText(log.message, "ixSmallFont", 15, 43, COLOR_TEXT_PRIMARY, TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP)
end end
-- Контекстное меню
logEntry.OnMousePressed = function(s, btn)
if btn == MOUSE_RIGHT then
local menu = DermaMenu()
menu:AddOption("Копировать сообщение", function()
SetClipboardText(log.message)
ix.util.Notify("Сообщение скопировано")
end):SetIcon("icon16/page_copy.png")
if log.target and log.target.steamid and log.target.steamid ~= "N/A" then
menu:AddOption("Копировать SteamID (" .. log.target.name .. ")", function()
SetClipboardText(log.target.steamid)
ix.util.Notify("SteamID скопирован: " .. log.target.steamid)
end):SetIcon("icon16/user_edit.png")
end
if log.data and log.data.attacker and log.data.attacker ~= "world" then
menu:AddOption("Копировать SteamID Атакующего", function()
SetClipboardText(log.data.attacker)
ix.util.Notify("SteamID атакующего скопирован: " .. log.data.attacker)
end):SetIcon("icon16/user_delete.png")
end
menu:AddSpacer()
menu:AddOption("Копировать время (" .. log.timeString .. ")", function()
SetClipboardText(log.timeString)
end):SetIcon("icon16/time.png")
menu:AddOption("Копировать полную строку", function()
local fullLog = string.format("[%s][%s] %s", log.timeString, category and category.name or log.category, log.message)
SetClipboardText(fullLog)
ix.util.Notify("Полная строка скопирована")
end):SetIcon("icon16/page_white_copy.png")
menu:Open()
end
end
end end
end end

View File

@@ -99,6 +99,10 @@ PLUGIN.LOG_TYPES = {
CHARACTER_CREATE = {category = "CHARACTER", description = "Создание персонажа"}, CHARACTER_CREATE = {category = "CHARACTER", description = "Создание персонажа"},
CHARACTER_DELETE = {category = "CHARACTER", description = "Удаление персонажа"}, CHARACTER_DELETE = {category = "CHARACTER", description = "Удаление персонажа"},
CHARACTER_SWITCH = {category = "CHARACTER", description = "Смена персонажа"}, CHARACTER_SWITCH = {category = "CHARACTER", description = "Смена персонажа"},
CHARACTER_WHITELIST = {category = "CHARACTER", description = "Изменение вайтлиста/статистики"},
-- Команды
COMMAND_RUN = {category = "ADMIN", description = "Выполнена админ-команда"},
-- Захват точек -- Захват точек
CAPTURE_START = {category = "COMBAT", description = "Начало захвата точки"}, CAPTURE_START = {category = "COMBAT", description = "Начало захвата точки"},

View File

@@ -16,18 +16,81 @@ function PLUGIN:InitializeLogSystem()
self.logFile = nil self.logFile = nil
-- Создаем папку для логов -- Создаем папку для логов
if ix.config.Get("logSaveToFile", true) then
local logPath = ix.config.Get("logFilePath", "helix_logs") local logPath = ix.config.Get("logFilePath", "helix_logs")
if not file.Exists(logPath, "DATA") then if not file.Exists(logPath, "DATA") then
file.CreateDir(logPath) file.CreateDir(logPath)
end end
if ix.config.Get("logSaveToFile", true) then
-- Создаем файл для текущей сессии -- Создаем файл для текущей сессии
local date = os.date("%Y-%m-%d_%H-%M-%S") local date = os.date("%Y-%m-%d_%H-%M-%S")
self.logFile = logPath .. "/log_" .. date .. ".txt" self.logFile = logPath .. "/log_" .. date .. ".txt"
file.Write(self.logFile, "=== Server Logs Started: " .. os.date("%Y-%m-%d %H:%M:%S") .. " ===\n") file.Write(self.logFile, "=== Server Logs Started: " .. os.date("%Y-%m-%d %H:%M:%S") .. " ===\n")
end end
-- Загружаем логи из предыдущей сессии
self:LoadPersistentLogs()
end
-- Загрузка логов из файлов
function PLUGIN:LoadPersistentLogs()
local logPath = ix.config.Get("logFilePath", "helix_logs")
local files, _ = file.Find(logPath .. "/log_*.txt", "DATA")
if #files == 0 then return end
-- Сортируем файлы по дате (в обратном порядке)
table.sort(files, function(a, b) return a > b end)
local logsToLoad = {}
local maxToLoad = 500 -- Лимит загрузки для производительности
for _, fileName in ipairs(files) do
if #logsToLoad >= maxToLoad then break end
local content = file.Read(logPath .. "/" .. fileName, "DATA")
if not content then continue end
local lines = string.Split(content, "\n")
-- Читаем с конца
for i = #lines, 1, -1 do
local line = lines[i]
if not line or line == "" or string.StartWith(line, "===") then continue end
-- Пример лога: [10:38:40][Боевые действия] Игрок умер
-- Нам нужно распарсить это обратно в таблицу
local timeStr, categoryName, msg = string.match(line, "%[(%d%d:%d%d:%d%d)%]%[(.-)%] (.*)")
if timeStr and categoryName and msg then
-- Находим ID категории по имени
local categoryID = "ADMIN"
for catID, cat in pairs(self.LOG_CATEGORIES) do
if cat.name == categoryName then
categoryID = catID
break
end
end
table.insert(logsToLoad, {
id = #logsToLoad + 1,
type = "LOADED", -- Специальный тип для загруженных
category = categoryID,
message = "[АРХИВ] " .. msg,
timestamp = 0, -- Мы не знаем точную дату, только время
timeString = timeStr,
isPersistent = true
})
if #logsToLoad >= maxToLoad then break end
end
end
end
-- Переворачиваем чтобы были по хронологии и добавляем в начало текущих логов
for i = #logsToLoad, 1, -1 do
table.insert(self.logs, logsToLoad[i])
end
end end
-- Добавление лога -- Добавление лога
@@ -154,14 +217,58 @@ net.Receive("ixServerLogs_Request", function(len, client)
end end
end) end)
-- Очистка логов
net.Receive("ixServerLogs_Clear", function(len, client)
if not client:IsSuperAdmin() then return end
PLUGIN.logs = {} PLUGIN.logs = {}
PLUGIN:AddLog("ADMIN_COMMAND", client:Nick() .. " очистил логи сервера", client) PLUGIN:AddLog("ADMIN_COMMAND", client:Nick() .. " очистил логи сервера", client)
end) end)
-- Выполнение админ-команд
function PLUGIN:OnCommandRun(client, command, arguments)
if not IsValid(client) then return end
local cmdObj = ix.command.list[string.lower(command)]
if not cmdObj then return end
-- Логируем только если команда админская или важная
if cmdObj.adminOnly or cmdObj.superAdminOnly or cmdObj.privilege then
local argsStr = table.concat(arguments, " ")
local message = string.format("%s выполнил команду: /%s %s", client:Nick(), command, argsStr)
self:AddLog("COMMAND_RUN", message, client, {
command = command,
args = arguments
})
end
end
-- Самоубийство
function PLUGIN:CanPlayerSuicide(client)
self:AddLog("PLAYER_DEATH", client:Nick() .. " пытается совершить самоубийство", client)
end
-- Поднятие предмета
function PLUGIN:PlayerPickupItem(client, item)
if not IsValid(client) or not item then return end
local itemName = item.GetName and item:GetName() or item.name or "Предмет"
local message = string.format("%s поднял предмет: %s", client:Nick(), itemName)
self:AddLog("ITEM_PICKUP", message, client, {
item = itemName
})
end
-- Выбрасывание предмета
function PLUGIN:PlayerDroppedItem(client, item)
if not IsValid(client) or not item then return end
local itemName = item.GetName and item:GetName() or item.name or "Предмет"
local message = string.format("%s выбросил предмет: %s", client:Nick(), itemName)
self:AddLog("ITEM_DROP", message, client, {
item = itemName
})
end
-- ====================== -- ======================
-- ХУКИ ДЛЯ ЛОГИРОВАНИЯ -- ХУКИ ДЛЯ ЛОГИРОВАНИЯ
-- ====================== -- ======================

View File

@@ -102,4 +102,24 @@ net.Receive("ixWhitelistMenuApply", function(_, client)
client:Notify("Роль назначена: " .. target:Name()) client:Notify("Роль назначена: " .. target:Name())
target:Notify("Вам назначена новая роль!") target:Notify("Вам назначена новая роль!")
-- Логирование в систему серверных логов
local serverlogs = ix.plugin.list["serverlogs"]
if serverlogs then
local factionName = faction.name or "Неизвестно"
local podrName = faction.Podr[podrID] and faction.Podr[podrID].name or tostring(podrID)
local specName = faction.Spec[specID] and faction.Spec[specID].name or tostring(specID)
local rankName = targetRanks[rankID] and targetRanks[rankID].name or tostring(rankID)
local message = string.format("%s изменил роль игроку %s: Фракция: %s, Подразделение: %s, Спец: %s, Ранг: %s",
client:Nick(), target:Nick(), factionName, podrName, specName, rankName)
serverlogs:AddLog("CHARACTER_WHITELIST", message, target, {
admin = client:SteamID(),
faction = factionName,
podr = podrName,
spec = specName,
rank = rankName
})
end
end) end)