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)
|
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
|
||||||
|
|||||||
@@ -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 = "Начало захвата точки"},
|
||||||
|
|||||||
@@ -16,18 +16,81 @@ function PLUGIN:InitializeLogSystem()
|
|||||||
self.logFile = nil
|
self.logFile = nil
|
||||||
|
|
||||||
-- Создаем папку для логов
|
-- Создаем папку для логов
|
||||||
|
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
|
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 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
|
||||||
|
|
||||||
-- ======================
|
-- ======================
|
||||||
-- ХУКИ ДЛЯ ЛОГИРОВАНИЯ
|
-- ХУКИ ДЛЯ ЛОГИРОВАНИЯ
|
||||||
-- ======================
|
-- ======================
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user