292 lines
9.1 KiB
Lua
292 lines
9.1 KiB
Lua
local PLUGIN = PLUGIN
|
||
|
||
util.AddNetworkString("ixAdminShopOpen")
|
||
util.AddNetworkString("ixAdminShopBuy")
|
||
util.AddNetworkString("ixAdminShopRetrieve")
|
||
util.AddNetworkString("ixAdminShopAdminSync")
|
||
util.AddNetworkString("ixAdminShopAdminAction")
|
||
util.AddNetworkString("ixAdminShopPanelOpen")
|
||
util.AddNetworkString("ixAdminShopPanelData")
|
||
util.AddNetworkString("ixAdminShopPanelGivePoints")
|
||
util.AddNetworkString("ixAdminShopPanelTakePoints")
|
||
|
||
local adminRanks = {
|
||
["super admin"] = true,
|
||
["superadmin"] = true,
|
||
["projectteam"] = true,
|
||
["teh.admin"] = true,
|
||
["curator"] = true,
|
||
["sudo-curator"] = true,
|
||
["asist-sudo"] = true,
|
||
["admin"] = true,
|
||
["st.admin"] = true,
|
||
["ivent"] = true,
|
||
["st.event"] = true,
|
||
["event"] = true,
|
||
["disp"] = true,
|
||
["assistant"] = true,
|
||
["prem"] = true,
|
||
["dsmoder"] = true
|
||
}
|
||
|
||
local function IsAdminRank(rank)
|
||
if not rank or rank == "user" then return false end
|
||
|
||
local lowerRank = string.lower(rank)
|
||
|
||
-- Check exact match in the provided list
|
||
if adminRanks[lowerRank] then return true end
|
||
|
||
-- Keep generic string searches just in case
|
||
if lowerRank == "founder" or lowerRank == "owner" or lowerRank == "manager" then return true end
|
||
|
||
return false
|
||
end
|
||
|
||
PLUGIN.IsAdminRank = IsAdminRank
|
||
|
||
function PLUGIN:Initialize()
|
||
self.shopData = ix.data.Get("adminShop", {})
|
||
end
|
||
|
||
function PLUGIN:SaveShopData()
|
||
ix.data.Set("adminShop", self.shopData)
|
||
end
|
||
|
||
function PLUGIN:PlayerLoaded(client)
|
||
local steamID = client:SteamID()
|
||
self.shopData[steamID] = self.shopData[steamID] or {points = 0, inventory = {}}
|
||
|
||
client:SetNetVar("adminPoints", self.shopData[steamID].points)
|
||
client:SetNetVar("adminInventory", self.shopData[steamID].inventory)
|
||
end
|
||
|
||
local playerMeta = debug.getregistry().Player
|
||
|
||
function playerMeta:SetAdminPoints(amount)
|
||
amount = math.max(0, amount)
|
||
self:SetNetVar("adminPoints", amount)
|
||
|
||
local steamID = self:SteamID()
|
||
PLUGIN.shopData[steamID] = PLUGIN.shopData[steamID] or {points = 0, inventory = {}}
|
||
PLUGIN.shopData[steamID].points = amount
|
||
PLUGIN:SaveShopData()
|
||
end
|
||
|
||
function playerMeta:GiveAdminPoints(amount)
|
||
self:SetAdminPoints(self:GetAdminPoints() + amount)
|
||
end
|
||
|
||
function playerMeta:TakeAdminPoints(amount)
|
||
self:SetAdminPoints(self:GetAdminPoints() - amount)
|
||
end
|
||
|
||
function playerMeta:SetAdminInventory(data)
|
||
self:SetNetVar("adminInventory", data)
|
||
|
||
local steamID = self:SteamID()
|
||
PLUGIN.shopData[steamID] = PLUGIN.shopData[steamID] or {points = 0, inventory = {}}
|
||
PLUGIN.shopData[steamID].inventory = data
|
||
PLUGIN:SaveShopData()
|
||
end
|
||
|
||
ix.command.Add("AdminShop", {
|
||
description = "Открыть магазин администратора.",
|
||
OnRun = function(self, client)
|
||
if (!client:IsAdmin() and !client:IsSuperAdmin() and !IsAdminRank(client:GetUserGroup())) then
|
||
client:Notify("Эта команда доступна только администраторам.")
|
||
return
|
||
end
|
||
net.Start("ixAdminShopOpen")
|
||
net.Send(client)
|
||
end
|
||
})
|
||
|
||
net.Receive("ixAdminShopBuy", function(len, client)
|
||
local itemID = net.ReadString()
|
||
local item = PLUGIN.Items[itemID]
|
||
|
||
if (!item) then return end
|
||
|
||
local points = client:GetAdminPoints()
|
||
if (points < item.price) then
|
||
client:Notify("У вас недостаточно очков!")
|
||
return
|
||
end
|
||
|
||
if (itemID == "remove_warn") then
|
||
local warnPlugin = ix.plugin.Get("warn")
|
||
if (warnPlugin) then
|
||
local steamID = client:SteamID()
|
||
local warns = ix.data.Get("warns", {})
|
||
local targetData = warns[steamID]
|
||
|
||
if (targetData and targetData.count > 0) then
|
||
targetData.count = targetData.count - 1
|
||
table.insert(targetData.history, {
|
||
admin = "Admin Shop",
|
||
adminSteamID = "STEAM_0:0:0",
|
||
reason = "Покупка в магазине",
|
||
time = os.time(),
|
||
type = "remove"
|
||
})
|
||
ix.data.Set("warns", warns)
|
||
warnPlugin.warns = warns
|
||
client:TakeAdminPoints(item.price)
|
||
client:Notify("Вы успешно сняли выговор!")
|
||
else
|
||
client:Notify("У вас нет активных выговоров для снятия!")
|
||
end
|
||
else
|
||
client:Notify("Система выговоров не найдена!")
|
||
end
|
||
else
|
||
-- Immediate delivery if class exists
|
||
if (item.class) then
|
||
client:GiveItem(item.class)
|
||
client:TakeAdminPoints(item.price)
|
||
client:Notify("Вы купили " .. item.name .. ". Предмет выдан!")
|
||
else
|
||
-- Fallback to inventory just in case (hidden)
|
||
local inv = client:GetAdminInventory()
|
||
local expireTime = 0
|
||
if (item.duration) then
|
||
expireTime = os.time() + (item.duration * 24 * 60 * 60)
|
||
end
|
||
|
||
table.insert(inv, {
|
||
id = itemID,
|
||
buyTime = os.time(),
|
||
expireTime = expireTime,
|
||
name = item.name,
|
||
class = item.class
|
||
})
|
||
|
||
client:SetAdminInventory(inv)
|
||
client:TakeAdminPoints(item.price)
|
||
client:Notify("Вы купили " .. item.name .. ". Предмет добавлен в инвентарь (скрыто).")
|
||
end
|
||
end
|
||
end)
|
||
|
||
net.Receive("ixAdminShopRetrieve", function(len, client)
|
||
local index = net.ReadUInt(16)
|
||
local inv = client:GetAdminInventory()
|
||
local itemData = inv[index]
|
||
|
||
if (!itemData) then return end
|
||
|
||
if (itemData.expireTime > 0 and os.time() > itemData.expireTime) then
|
||
client:Notify("Срок действия предмета истек!")
|
||
table.remove(inv, index)
|
||
client:SetAdminInventory(inv)
|
||
return
|
||
end
|
||
|
||
if (itemData.class) then
|
||
client:GiveItem(itemData.class)
|
||
client:Notify("Вы получили: " .. itemData.name)
|
||
end
|
||
end)
|
||
|
||
-- Сбор данных игроков с доступом к магазину
|
||
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)
|