From 09c209c99de3e5b94aaedceba0b9dba69deb9abf Mon Sep 17 00:00:00 2001 From: bugor Date: Tue, 31 Mar 2026 23:24:49 +0300 Subject: [PATCH] add --- .../plugins/admin_magaz/cl_plugin.lua | 166 +++++++++++++++++- .../plugins/admin_magaz/sv_plugin.lua | 107 +++++++++++ 2 files changed, 270 insertions(+), 3 deletions(-) diff --git a/garrysmod/gamemodes/militaryrp/plugins/admin_magaz/cl_plugin.lua b/garrysmod/gamemodes/militaryrp/plugins/admin_magaz/cl_plugin.lua index e899242..99f8269 100644 --- a/garrysmod/gamemodes/militaryrp/plugins/admin_magaz/cl_plugin.lua +++ b/garrysmod/gamemodes/militaryrp/plugins/admin_magaz/cl_plugin.lua @@ -7,6 +7,8 @@ surface.CreateFont("ixAdminShopDesc", { font = "Montserrat", size = 14, weight = surface.CreateFont("ixAdminShopPrice", { font = "Montserrat", size = 18, weight = 900, antialias = true }) surface.CreateFont("ixAdminShopSmall", { font = "Montserrat", size = 14, weight = 600, antialias = true }) surface.CreateFont("ixAdminShopBold", { font = "Montserrat", size = 16, weight = 800, antialias = true }) +surface.CreateFont("ixAdminShopTableHeader", { font = "Montserrat", size = 15, weight = 800, antialias = true }) +surface.CreateFont("ixAdminShopTableCell", { font = "Montserrat", size = 14, weight = 500, antialias = true }) -- Modern Color Palette #00431c local COLOR_BASE = Color(0, 67, 28) @@ -37,7 +39,7 @@ function PLUGIN:WrapText(text, width, font) end end - if currentLine != "" then + if currentLine ~= "" then table.insert(lines, currentLine) end @@ -117,6 +119,10 @@ function PANEL:Init() CreateNavBtn("Магазин", "shop", 0, COLOR_BASE) + if LocalPlayer():IsSuperAdmin() then + CreateNavBtn("Панель", "panel", 160, Color(120, 0, 180)) + end + self.content = self:Add("DScrollPanel") self.content:Dock(FILL) self.content:DockMargin(40, 100, 40, 40) @@ -137,7 +143,7 @@ end function PANEL:Refresh() self.content:Clear() - if (self.currentView == "shop") then + if self.currentView == "shop" then local layout = self.content:Add("DIconLayout") layout:Dock(TOP) layout:SetSpaceX(20) @@ -156,7 +162,7 @@ function PANEL:Refresh() local descLines = PLUGIN:WrapText(item.desc, w - 30, "ixAdminShopDesc") for i, line in ipairs(descLines) do - if (i > 4) then break end + if i > 4 then break end draw.SimpleText(line, "ixAdminShopDesc", w/2, 185 + (i-1)*18, COLOR_TEXT_DIM, TEXT_ALIGN_CENTER) end end @@ -186,11 +192,165 @@ function PANEL:Refresh() net.SendToServer() end end + elseif self.currentView == "panel" then + -- Запрос данных с сервера + net.Start("ixAdminShopPanelOpen") + net.SendToServer() + + -- Заголовок панели + local headerPanel = self.content:Add("DPanel") + headerPanel:Dock(TOP) + headerPanel:SetTall(50) + headerPanel.Paint = function(s, w, h) + draw.SimpleText("Управление очками администраторов", "ixAdminShopBold", 10, h/2, COLOR_TEXT, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER) + end + + -- Таблица + self.panelTable = self.content:Add("DListView") + self.panelTable:Dock(TOP) + self.panelTable:SetTall(400) + self.panelTable:DockMargin(0, 10, 0, 10) + self.panelTable:SetMultiSelect(false) + self.panelTable.Paint = function(s, w, h) + draw.RoundedBox(6, 0, 0, w, h, COLOR_CARD) + end + + local col1 = self.panelTable:AddColumn("Игрок") + local col2 = self.panelTable:AddColumn("SteamID") + local col3 = self.panelTable:AddColumn("Ранг") + local col4 = self.panelTable:AddColumn("Очки") + + col1:SetWidth(160) + col2:SetWidth(140) + col3:SetWidth(100) + col4:SetWidth(80) + + -- Настройка заголовков таблицы + for _, col in ipairs(self.panelTable.Columns) do + col.Header:SetFont("ixAdminShopTableHeader") + col.Header:SetTextColor(COLOR_TEXT) + col.Header.Paint = function(s, w, h) + draw.RoundedBox(0, 0, 0, w, h, COLOR_BASE) + end + end + + -- Панель управления + local controlPanel = self.content:Add("DPanel") + controlPanel:Dock(TOP) + controlPanel:SetTall(120) + controlPanel.Paint = function(s, w, h) + draw.RoundedBox(6, 0, 0, w, h, COLOR_CARD) + end + + local selectedSID = nil + + -- Поле ввода количества очков + local amountEntry = controlPanel:Add("DTextEntry") + amountEntry:SetSize(200, 40) + amountEntry:SetPos(10, 10) + amountEntry:SetPlaceholderText("Количество очков...") + amountEntry:SetNumeric(true) + amountEntry:SetFont("ixAdminShopBold") + + -- Кнопка выдачи очков + local giveBtn = controlPanel:Add("DButton") + giveBtn:SetSize(180, 40) + giveBtn:SetPos(220, 10) + giveBtn:SetText("Выдать очки") + giveBtn:SetFont("ixAdminShopBold") + giveBtn:SetTextColor(COLOR_TEXT) + giveBtn.Paint = function(s, w, h) + draw.RoundedBox(6, 0, 0, w, h, s:IsHovered() and Color(0, 180, 80) or COLOR_ACCENT) + end + giveBtn.DoClick = function() + if not selectedSID then + surface.PlaySound("buttons/button10.wav") + return + end + local amount = tonumber(amountEntry:GetValue()) or 0 + if amount < 1 then + surface.PlaySound("buttons/button10.wav") + return + end + surface.PlaySound("ui/buttonclick.wav") + net.Start("ixAdminShopPanelGivePoints") + net.WriteString(selectedSID) + net.WriteUInt(amount, 32) + net.SendToServer() + amountEntry:SetValue("") + end + + -- Кнопка забирания очков + local takeBtn = controlPanel:Add("DButton") + takeBtn:SetSize(180, 40) + takeBtn:SetPos(410, 10) + takeBtn:SetText("Забрать очки") + takeBtn:SetFont("ixAdminShopBold") + takeBtn:SetTextColor(COLOR_TEXT) + takeBtn.Paint = function(s, w, h) + draw.RoundedBox(6, 0, 0, w, h, s:IsHovered() and Color(230, 60, 60) or COLOR_DANGER) + end + takeBtn.DoClick = function() + if not selectedSID then + surface.PlaySound("buttons/button10.wav") + return + end + local amount = tonumber(amountEntry:GetValue()) or 0 + if amount < 1 then + surface.PlaySound("buttons/button10.wav") + return + end + surface.PlaySound("ui/buttonclick.wav") + net.Start("ixAdminShopPanelTakePoints") + net.WriteString(selectedSID) + net.WriteUInt(amount, 32) + net.SendToServer() + amountEntry:SetValue("") + end + + -- Информация о выбранном игроке + local infoLabel = controlPanel:Add("DLabel") + infoLabel:SetSize(400, 30) + infoLabel:SetPos(10, 55) + infoLabel:SetFont("ixAdminShopSmall") + infoLabel:SetTextColor(COLOR_TEXT_DIM) + infoLabel:SetText("Выберите игрока из таблицы") + + -- Подсказка + local hintLabel = controlPanel:Add("DLabel") + hintLabel:SetSize(500, 25) + hintLabel:SetPos(10, 85) + hintLabel:SetFont("ixAdminShopSmall") + hintLabel:SetTextColor(COLOR_WARN) + hintLabel:SetText("Вводите только положительные числа. Нажмите строку в таблице для выбора.") + + -- Обработчик выбора строки + self.panelTable.OnRowSelected = function(tbl, rowIndex, row) + local data = self.panelPlayers and self.panelPlayers[rowIndex] + if data then + selectedSID = data.steamID + infoLabel:SetText("Выбран: " .. data.name .. " (" .. data.steamID .. ") — Очков: " .. data.points) + end + end end end vgui.Register("ixAdminShop", PANEL, "DFrame") +net.Receive("ixAdminShopPanelData", function() + local data = net.ReadTable() + + if IsValid(ixAdminShop) and ixAdminShop.panelTable then + ixAdminShop.panelTable:Clear() + ixAdminShop.panelPlayers = {} + + for i, plyData in ipairs(data) do + ixAdminShop.panelTable:AddLine(plyData.name, plyData.steamID, plyData.rank, plyData.points) + ixAdminShop.panelPlayers[i] = plyData + end + end +end) + net.Receive("ixAdminShopOpen", function() if (IsValid(ixAdminShop)) then ixAdminShop:Close() diff --git a/garrysmod/gamemodes/militaryrp/plugins/admin_magaz/sv_plugin.lua b/garrysmod/gamemodes/militaryrp/plugins/admin_magaz/sv_plugin.lua index ad4ee33..e9bd29e 100644 --- a/garrysmod/gamemodes/militaryrp/plugins/admin_magaz/sv_plugin.lua +++ b/garrysmod/gamemodes/militaryrp/plugins/admin_magaz/sv_plugin.lua @@ -5,6 +5,10 @@ util.AddNetworkString("ixAdminShopBuy") util.AddNetworkString("ixAdminShopRetrieve") util.AddNetworkString("ixAdminShopAdminSync") util.AddNetworkString("ixAdminShopAdminAction") +util.AddNetworkString("ixAdminShopPanelOpen") +util.AddNetworkString("ixAdminShopPanelData") +util.AddNetworkString("ixAdminShopPanelGivePoints") +util.AddNetworkString("ixAdminShopPanelTakePoints") function PLUGIN:Initialize() self.shopData = ix.data.Get("adminShop", {}) @@ -182,3 +186,106 @@ local function IsAdminRank(rank) return false end + +PLUGIN.IsAdminRank = IsAdminRank + +-- Сбор данных игроков с доступом к магазину +function PLUGIN:CollectPanelData() + local playersData = {} + + for _, ply in ipairs(player.GetAll()) do + local rank = ply:GetUserGroup() + if IsAdminRank(rank) then + table.insert(playersData, { + name = ply:Nick(), + steamID = ply:SteamID(), + rank = rank, + points = ply:GetAdminPoints() + }) + end + end + + return playersData +end + +-- Открытие панели (только superadmin) +net.Receive("ixAdminShopPanelOpen", function(len, client) + if not client:IsSuperAdmin() then + client:Notify("Доступ к панели только у суперадминистраторов!") + return + end + + local data = PLUGIN:CollectPanelData() + + net.Start("ixAdminShopPanelData") + net.WriteTable(data) + net.Send(client) +end) + +-- Выдача очков (только superadmin) +net.Receive("ixAdminShopPanelGivePoints", function(len, client) + if not client:IsSuperAdmin() then + client:Notify("Доступ только у суперадминистраторов!") + return + end + + local targetSID = net.ReadString() + local amount = net.ReadUInt(32) + + local target = player.GetBySteamID(targetSID) + if not IsValid(target) then + client:Notify("Игрок не найден на сервере!") + return + end + + if amount < 1 then + client:Notify("Некорректная сумма!") + return + end + + target:GiveAdminPoints(amount) + client:Notify("Выдано " .. amount .. " очков игроку " .. target:Nick()) + + -- Обновить панель + local data = PLUGIN:CollectPanelData() + net.Start("ixAdminShopPanelData") + net.WriteTable(data) + net.Send(client) +end) + +-- Забрать очки (только superadmin) +net.Receive("ixAdminShopPanelTakePoints", function(len, client) + if not client:IsSuperAdmin() then + client:Notify("Доступ только у суперадминистраторов!") + return + end + + local targetSID = net.ReadString() + local amount = net.ReadUInt(32) + + local target = player.GetBySteamID(targetSID) + if not IsValid(target) then + client:Notify("Игрок не найден на сервере!") + return + end + + if amount < 1 then + client:Notify("Некорректная сумма!") + return + end + + local current = target:GetAdminPoints() + if current < amount then + client:Notify("У игрока недостаточно очков! (Текущий баланс: " .. current .. ")") + return + end + + target:TakeAdminPoints(amount) + client:Notify("Забрано " .. amount .. " очков у игрока " .. target:Nick()) + + -- Обновить панель + local data = PLUGIN:CollectPanelData() + net.Start("ixAdminShopPanelData") + net.WriteTable(data) + net.Send(client) +end)