1
This commit is contained in:
@@ -339,5 +339,45 @@ function PLUGIN:UpdateLogsList()
|
||||
-- Сообщение
|
||||
draw.SimpleText(log.message, "ixSmallFont", 15, 43, COLOR_TEXT_PRIMARY, TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP)
|
||||
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
|
||||
|
||||
@@ -99,6 +99,10 @@ PLUGIN.LOG_TYPES = {
|
||||
CHARACTER_CREATE = {category = "CHARACTER", description = "Создание персонажа"},
|
||||
CHARACTER_DELETE = {category = "CHARACTER", description = "Удаление персонажа"},
|
||||
CHARACTER_SWITCH = {category = "CHARACTER", description = "Смена персонажа"},
|
||||
CHARACTER_WHITELIST = {category = "CHARACTER", description = "Изменение вайтлиста/статистики"},
|
||||
|
||||
-- Команды
|
||||
COMMAND_RUN = {category = "ADMIN", description = "Выполнена админ-команда"},
|
||||
|
||||
-- Захват точек
|
||||
CAPTURE_START = {category = "COMBAT", description = "Начало захвата точки"},
|
||||
|
||||
@@ -16,18 +16,81 @@ function PLUGIN:InitializeLogSystem()
|
||||
self.logFile = nil
|
||||
|
||||
-- Создаем папку для логов
|
||||
if ix.config.Get("logSaveToFile", true) then
|
||||
local logPath = ix.config.Get("logFilePath", "helix_logs")
|
||||
if not file.Exists(logPath, "DATA") then
|
||||
file.CreateDir(logPath)
|
||||
end
|
||||
local logPath = ix.config.Get("logFilePath", "helix_logs")
|
||||
if not file.Exists(logPath, "DATA") then
|
||||
file.CreateDir(logPath)
|
||||
end
|
||||
|
||||
if ix.config.Get("logSaveToFile", true) then
|
||||
-- Создаем файл для текущей сессии
|
||||
local date = os.date("%Y-%m-%d_%H-%M-%S")
|
||||
self.logFile = logPath .. "/log_" .. date .. ".txt"
|
||||
|
||||
file.Write(self.logFile, "=== Server Logs Started: " .. os.date("%Y-%m-%d %H:%M:%S") .. " ===\n")
|
||||
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
|
||||
|
||||
-- Добавление лога
|
||||
@@ -154,14 +217,58 @@ net.Receive("ixServerLogs_Request", function(len, client)
|
||||
end
|
||||
end)
|
||||
|
||||
-- Очистка логов
|
||||
net.Receive("ixServerLogs_Clear", function(len, client)
|
||||
if not client:IsSuperAdmin() then return end
|
||||
|
||||
PLUGIN.logs = {}
|
||||
PLUGIN:AddLog("ADMIN_COMMAND", client:Nick() .. " очистил логи сервера", client)
|
||||
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
|
||||
|
||||
-- ======================
|
||||
-- ХУКИ ДЛЯ ЛОГИРОВАНИЯ
|
||||
-- ======================
|
||||
|
||||
@@ -102,4 +102,24 @@ net.Receive("ixWhitelistMenuApply", function(_, client)
|
||||
|
||||
client:Notify("Роль назначена: " .. target:Name())
|
||||
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)
|
||||
|
||||
Reference in New Issue
Block a user