add sborka

This commit is contained in:
2026-03-31 10:27:04 +03:00
commit f5e5f56c84
2345 changed files with 382127 additions and 0 deletions

View File

@@ -0,0 +1,343 @@
local PLUGIN = PLUGIN
-- Цветовая схема
local COLOR_BG_DARK = Color(3, 5, 4)
local COLOR_BG_MEDIUM = Color(8, 12, 10)
local COLOR_BG_LIGHT = Color(12, 18, 14)
local COLOR_PRIMARY = Color(27, 94, 32)
local COLOR_PRIMARY_DARK = Color(15, 60, 18)
local COLOR_ACCENT = Color(56, 102, 35)
local COLOR_TEXT_PRIMARY = Color(165, 214, 167)
local COLOR_TEXT_SECONDARY = Color(102, 187, 106)
local COLOR_BORDER = Color(15, 60, 18, 60)
-- Локальное хранилище логов
local clientLogs = {}
local isLoadingLogs = false
-- Сетевой получатель для открытия меню (из команды Helix)
net.Receive("ixServerLogs_OpenMenu", function()
PLUGIN:OpenLogsMenu()
end)
-- Получение логов с сервера
function PLUGIN:RequestLogs(filters)
if isLoadingLogs then return end
isLoadingLogs = true
clientLogs = {}
net.Start("ixServerLogs_Request")
net.WriteTable(filters or {})
net.SendToServer()
end
-- Получение ответа с логами
net.Receive("ixServerLogs_Response", function()
local isFirst = net.ReadUInt(2) == 1
local logs = net.ReadTable()
if isFirst then
clientLogs = {}
end
for _, log in ipairs(logs) do
table.insert(clientLogs, log)
end
isLoadingLogs = false
-- Обновляем UI если открыто
if IsValid(PLUGIN.logsFrame) and IsValid(PLUGIN.logsList) then
PLUGIN:UpdateLogsList()
end
end)
-- Главное меню логов
function PLUGIN:OpenLogsMenu()
if IsValid(self.logsFrame) then
self.logsFrame:Remove()
end
local scrW, scrH = ScrW(), ScrH()
local frame = vgui.Create("DFrame")
frame:SetSize(scrW * 0.9, scrH * 0.85)
frame:Center()
frame:SetTitle("")
frame:SetDraggable(true)
frame:ShowCloseButton(false)
frame:MakePopup()
frame.Paint = function(s, w, h)
-- Основной фон
draw.RoundedBox(8, 0, 0, w, h, COLOR_BG_DARK)
-- Верхняя панель
draw.RoundedBoxEx(8, 0, 0, w, 60, COLOR_BG_MEDIUM, true, true, false, false)
-- Акцентная линия
surface.SetDrawColor(COLOR_PRIMARY)
surface.DrawRect(0, 60, w, 3)
-- Заголовок
draw.SimpleText("◆ ЛОГИ СЕРВЕРА", "ixMenuButtonFont", w/2, 20, COLOR_ACCENT, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
draw.SimpleText("СИСТЕМА МОНИТОРИНГА СОБЫТИЙ", "ixSmallFont", w/2, 43, COLOR_TEXT_SECONDARY, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
-- Рамка
surface.SetDrawColor(COLOR_BORDER)
surface.DrawOutlinedRect(0, 0, w, h, 2)
end
-- Кнопка закрытия
local closeBtn = vgui.Create("DButton", frame)
closeBtn:SetSize(40, 40)
closeBtn:SetPos(frame:GetWide() - 50, 10)
closeBtn:SetText("")
closeBtn.Paint = function(s, w, h)
local col = s:IsHovered() and Color(200, 50, 50) or Color(150, 50, 50)
draw.RoundedBox(4, 0, 0, w, h, col)
surface.SetDrawColor(255, 255, 255)
surface.DrawLine(w*0.3, h*0.3, w*0.7, h*0.7)
surface.DrawLine(w*0.7, h*0.3, w*0.3, h*0.7)
end
closeBtn.DoClick = function()
frame:Close()
end
-- Панель фильтров
local filterPanel = vgui.Create("DPanel", frame)
filterPanel:SetSize(250, frame:GetTall() - 80)
filterPanel:SetPos(10, 70)
filterPanel.Paint = function(s, w, h)
draw.RoundedBox(6, 0, 0, w, h, COLOR_BG_MEDIUM)
surface.SetDrawColor(COLOR_BORDER)
surface.DrawOutlinedRect(0, 0, w, h, 1)
end
-- Заголовок фильтров
local filterHeader = vgui.Create("DLabel", filterPanel)
filterHeader:SetPos(10, 10)
filterHeader:SetFont("ixSmallFont")
filterHeader:SetText("⚙ ФИЛЬТРЫ")
filterHeader:SetTextColor(COLOR_TEXT_PRIMARY)
filterHeader:SizeToContents()
-- Категории
local categoryLabel = vgui.Create("DLabel", filterPanel)
categoryLabel:SetPos(10, 40)
categoryLabel:SetFont("DermaDefault")
categoryLabel:SetText("Категория:")
categoryLabel:SetTextColor(COLOR_TEXT_SECONDARY)
categoryLabel:SizeToContents()
local categoryBox = vgui.Create("DComboBox", filterPanel)
categoryBox:SetPos(10, 60)
categoryBox:SetSize(230, 30)
categoryBox:SetValue("Все категории")
categoryBox:AddChoice("Все категории")
for catID, cat in SortedPairs(self.LOG_CATEGORIES) do
categoryBox:AddChoice(cat.icon .. " " .. cat.name, catID)
end
categoryBox.Paint = function(s, w, h)
draw.RoundedBox(4, 0, 0, w, h, COLOR_BG_LIGHT)
surface.SetDrawColor(COLOR_PRIMARY)
surface.DrawOutlinedRect(0, 0, w, h, 1)
end
-- Поиск
local searchLabel = vgui.Create("DLabel", filterPanel)
searchLabel:SetPos(10, 100)
searchLabel:SetFont("DermaDefault")
searchLabel:SetText("Поиск:")
searchLabel:SetTextColor(COLOR_TEXT_SECONDARY)
searchLabel:SizeToContents()
local searchBox = vgui.Create("DTextEntry", filterPanel)
searchBox:SetPos(10, 120)
searchBox:SetSize(230, 30)
searchBox:SetPlaceholderText("Введите текст для поиска...")
searchBox.Paint = function(s, w, h)
draw.RoundedBox(4, 0, 0, w, h, COLOR_BG_LIGHT)
surface.SetDrawColor(COLOR_PRIMARY)
surface.DrawOutlinedRect(0, 0, w, h, 1)
s:DrawTextEntryText(COLOR_TEXT_PRIMARY, COLOR_ACCENT, COLOR_TEXT_PRIMARY)
end
-- Лимит
local limitLabel = vgui.Create("DLabel", filterPanel)
limitLabel:SetPos(10, 160)
limitLabel:SetFont("DermaDefault")
limitLabel:SetText("Количество записей:")
limitLabel:SetTextColor(COLOR_TEXT_SECONDARY)
limitLabel:SizeToContents()
local limitSlider = vgui.Create("DNumSlider", filterPanel)
limitSlider:SetPos(10, 180)
limitSlider:SetSize(230, 30)
limitSlider:SetMin(10)
limitSlider:SetMax(500)
limitSlider:SetDecimals(0)
limitSlider:SetValue(100)
limitSlider:SetText("")
-- Кнопка применить фильтры
local applyBtn = vgui.Create("DButton", filterPanel)
applyBtn:SetPos(10, 230)
applyBtn:SetSize(230, 40)
applyBtn:SetText("")
applyBtn.Paint = function(s, w, h)
local col = s:IsHovered() and COLOR_ACCENT or COLOR_PRIMARY
draw.RoundedBox(4, 0, 0, w, h, col)
surface.SetDrawColor(COLOR_BORDER)
surface.DrawOutlinedRect(0, 0, w, h, 1)
draw.SimpleText("🔍 ПРИМЕНИТЬ", "ixSmallFont", w/2, h/2, COLOR_TEXT_PRIMARY, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
end
applyBtn.DoClick = function()
local filters = {
limit = limitSlider:GetValue()
}
local _, catID = categoryBox:GetSelected()
if catID then
filters.category = catID
end
local searchText = searchBox:GetValue()
if searchText and searchText ~= "" then
filters.search = searchText
end
self:RequestLogs(filters)
end
-- Кнопка очистить логи
local clearBtn = vgui.Create("DButton", filterPanel)
clearBtn:SetPos(10, 280)
clearBtn:SetSize(230, 40)
clearBtn:SetText("")
clearBtn.Paint = function(s, w, h)
local col = s:IsHovered() and Color(200, 50, 50) or Color(150, 50, 50)
draw.RoundedBox(4, 0, 0, w, h, col)
surface.SetDrawColor(COLOR_BORDER)
surface.DrawOutlinedRect(0, 0, w, h, 1)
draw.SimpleText("🗑 ОЧИСТИТЬ ЛОГИ", "ixSmallFont", w/2, h/2, COLOR_TEXT_PRIMARY, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
end
clearBtn.DoClick = function()
Derma_Query(
"Вы уверены что хотите очистить все логи?",
"Подтверждение",
"Да",
function()
net.Start("ixServerLogs_Clear")
net.SendToServer()
clientLogs = {}
self:UpdateLogsList()
end,
"Нет"
)
end
-- Панель логов
local logsPanel = vgui.Create("DPanel", frame)
logsPanel:SetSize(frame:GetWide() - 280, frame:GetTall() - 80)
logsPanel:SetPos(270, 70)
logsPanel.Paint = function(s, w, h)
draw.RoundedBox(6, 0, 0, w, h, COLOR_BG_MEDIUM)
surface.SetDrawColor(COLOR_BORDER)
surface.DrawOutlinedRect(0, 0, w, h, 1)
end
-- Заголовок логов
local logsHeader = vgui.Create("DPanel", logsPanel)
logsHeader:SetSize(logsPanel:GetWide(), 40)
logsHeader:Dock(TOP)
logsHeader.Paint = function(s, w, h)
draw.RoundedBoxEx(6, 0, 0, w, h, COLOR_PRIMARY_DARK, true, true, false, false)
draw.SimpleText("📋 ЗАПИСИ ЛОГОВ", "ixSmallFont", 10, h/2, COLOR_TEXT_PRIMARY, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER)
draw.SimpleText("Всего: " .. #clientLogs, "DermaDefault", w - 10, h/2, COLOR_TEXT_SECONDARY, TEXT_ALIGN_RIGHT, TEXT_ALIGN_CENTER)
end
-- Список логов
local logsList = vgui.Create("DScrollPanel", logsPanel)
logsList:Dock(FILL)
logsList:DockMargin(5, 5, 5, 5)
local sbar = logsList:GetVBar()
sbar:SetHideButtons(true)
function sbar:Paint(w, h)
draw.RoundedBox(4, 0, 0, w, h, COLOR_BG_DARK)
end
function sbar.btnGrip:Paint(w, h)
draw.RoundedBox(4, 0, 0, w, h, COLOR_PRIMARY)
end
self.logsFrame = frame
self.logsList = logsList
self.logsHeader = logsHeader
-- Загружаем логи
self:RequestLogs({limit = 100})
end
-- Обновление списка логов
function PLUGIN:UpdateLogsList()
if not IsValid(self.logsList) then return end
self.logsList:Clear()
if #clientLogs == 0 then
local noLogs = vgui.Create("DLabel", self.logsList)
noLogs:SetText("Логи не найдены")
noLogs:SetFont("ixSmallFont")
noLogs:SetTextColor(COLOR_TEXT_SECONDARY)
noLogs:SizeToContents()
noLogs:Dock(TOP)
noLogs:DockMargin(10, 10, 10, 0)
return
end
-- Обновляем заголовок
if IsValid(self.logsHeader) then
self.logsHeader.Paint = function(s, w, h)
draw.RoundedBoxEx(6, 0, 0, w, h, COLOR_PRIMARY_DARK, true, true, false, false)
draw.SimpleText("📋 ЗАПИСИ ЛОГОВ", "ixSmallFont", 10, h/2, COLOR_TEXT_PRIMARY, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER)
draw.SimpleText("Всего: " .. #clientLogs, "DermaDefault", w - 10, h/2, COLOR_TEXT_SECONDARY, TEXT_ALIGN_RIGHT, TEXT_ALIGN_CENTER)
end
end
for _, log in ipairs(clientLogs) do
local logEntry = vgui.Create("DPanel", self.logsList)
logEntry:SetTall(60)
logEntry:Dock(TOP)
logEntry:DockMargin(5, 5, 5, 0)
local category = self.LOG_CATEGORIES[log.category]
local categoryColor = category and category.color or color_white
logEntry.Paint = function(s, w, h)
draw.RoundedBox(4, 0, 0, w, h, COLOR_BG_LIGHT)
-- Боковая полоска категории
draw.RoundedBoxEx(4, 0, 0, 5, h, categoryColor, true, false, true, false)
-- Рамка
surface.SetDrawColor(COLOR_BORDER)
surface.DrawOutlinedRect(0, 0, w, h, 1)
-- Время
draw.SimpleText(log.timeString, "DermaDefault", 15, 8, COLOR_TEXT_SECONDARY, TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP)
-- Категория
local catText = category and (category.icon .. " " .. category.name) or log.category
draw.SimpleText(catText, "DermaDefault", 15, 25, categoryColor, TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP)
-- Сообщение
draw.SimpleText(log.message, "ixSmallFont", 15, 43, COLOR_TEXT_PRIMARY, TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP)
end
end
end