У меня стоит onex scoreboard, я добавил колонку “Звания” и по стандарту там стоит нет, но есть кнопка “Добавить звание/убрать” и при нажатии на добавить, вылезет список званий, при нажатии на любое будет выдавать ошибку в консоли, а в табе все так же будет текст в звании “Нет”
Ошибка:
[onyx_scoreboard] lua/includes/extensions/net.lua:234: net.ReadType: Couldn't read type 55
1. error - [C]:-1
2. ReadType - lua/includes/extensions/net.lua:234
3. ReadTable - lua/includes/extensions/net.lua:170
4. func - addons/onyx_scoreboard/lua/onyx/modules/scoreboard/cfg/sh_columns.lua:90
5. unknown - lua/includes/extensions/net.lua:34
Код кнопки:
onyx.scoreboard:RegisterButton('manage_rank', {
callback = function(ply)
-- Создаем меню управления званиями
local frame = vgui.Create("DFrame")
frame:SetTitle("Управление званиями - " .. ply:Nick())
frame:SetSize(300, 400)
frame:Center()
frame:MakePopup()
local currentRank = GetClientPlayerRank and GetClientPlayerRank(ply:SteamID64()) or ""
-- Текущее звание
local currentLabel = vgui.Create("DLabel", frame)
currentLabel:SetPos(10, 30)
currentLabel:SetText("Текущее звание: " .. (currentRank ~= "" and currentRank or "Нет"))
currentLabel:SizeToContents()
-- Список званий
local rankList = vgui.Create("DListView", frame)
rankList:SetPos(10, 60)
rankList:SetSize(280, 250)
rankList:SetMultiSelect(false)
rankList:AddColumn("Звания")
-- Список доступных званий
local ranks = {
"Рядовой", "Ефрейтор", "Младший сержант", "Сержант", "Старший сержант",
"Старшина", "Прапорщик", "Старший прапорщик", "Младший лейтенант", "Лейтенант",
"Старший лейтенант", "Капитан", "Майор", "Подполковник", "Полковник",
"Генерал-майор", "Генерал-лейтенант", "Генерал-полковник"
}
for _, rank in ipairs(ranks) do
rankList:AddLine(rank)
end
-- Кнопки управления
local giveButton = vgui.Create("DButton", frame)
giveButton:SetPos(10, 320)
giveButton:SetSize(135, 30)
giveButton:SetText("Выдать звание")
giveButton.DoClick = function()
local selectedLine = rankList:GetSelectedLine()
if not selectedLine then return end
local selectedRank = rankList:GetLine(selectedLine):GetColumnText(1)
net.Start("Onyx_SetPlayerRank")
net.WriteString(ply:SteamID64())
net.WriteString(selectedRank)
net.SendToServer()
-- Локальное обновление
if GetClientPlayerRank then
playerRanks[ply:SteamID64()] = selectedRank
end
frame:Close()
end
local removeButton = vgui.Create("DButton", frame)
removeButton:SetPos(155, 320)
removeButton:SetSize(135, 30)
removeButton:SetText("Снять звание")
removeButton.DoClick = function()
net.Start("Onyx_SetPlayerRank")
net.WriteString(ply:SteamID64())
net.WriteString("")
net.SendToServer()
-- Локальное обновление
if GetClientPlayerRank then
playerRanks[ply:SteamID64()] = ""
end
frame:Close()
end
-- Подсветка текущего звания в списке
if currentRank ~= "" then
for i, rank in ipairs(ranks) do
if rank == currentRank then
rankList:SelectItem(rankList:GetLine(i))
break
end
end
end
end,
getVisible = function(client)
-- Проверяем права доступа для редактирования
return LocalPlayer():IsUserGroup("ROOT") or
LocalPlayer():IsUserGroup("Chiref Curator") or
LocalPlayer():IsUserGroup("Deputy Curator") or
LocalPlayer():IsUserGroup("admin") or
LocalPlayer():IsUserGroup("superadmin")
end
})
Код колонки:
-- Функции для работы с званиями
if SERVER then
util.AddNetworkString("Onyx_SetPlayerRank")
util.AddNetworkString("Onyx_RequestRankData")
util.AddNetworkString("Onyx_SendRankData")
-- Файл для хранения всех званий
local RANK_FILE = "player_ranks.json"
-- Загрузка данных о званиях
local function LoadRankData()
if not file.Exists(RANK_FILE, "DATA") then
return {}
end
return util.JSONToTable(file.Read(RANK_FILE, "DATA")) or {}
end
-- Сохранение данных о званиях
local function SaveRankData(data)
file.Write(RANK_FILE, util.TableToJSON(data, true))
end
-- Получение звания игрока (серверная версия)
local function GetPlayerRank(steamID64)
local data = LoadRankData()
return data[steamID64] or ""
end
-- Установка звания игрока
local function SetPlayerRank(steamID64, rank)
local data = LoadRankData()
data[steamID64] = rank
SaveRankData(data)
-- Уведомляем всех клиентов об обновлении
net.Start("Onyx_SendRankData")
net.WriteString(steamID64)
net.WriteString(rank)
net.Broadcast()
return true
end
-- Обработка установки звания из клиента
net.Receive("Onyx_SetPlayerRank", function(len, ply)
-- Проверяем права доступа
if not (ply:IsUserGroup("ROOT") or ply:IsUserGroup("Chiref Curator") or ply:IsUserGroup("Deputy Curator") or ply:IsUserGroup("admin") or ply:IsUserGroup("superadmin")) then
return
end
local targetSteamID = net.ReadString()
local rank = net.ReadString()
SetPlayerRank(targetSteamID, rank)
end)
-- Отправка данных о званиях при запросе
net.Receive("Onyx_RequestRankData", function(len, ply)
local data = LoadRankData()
net.Start("Onyx_SendRankData")
net.WriteTable(data)
net.Send(ply)
end)
-- Автоматическая отправка данных новым игрокам
hook.Add("PlayerInitialSpawn", "Onyx_SendRankDataOnSpawn", function(ply)
timer.Simple(5, function()
if IsValid(ply) then
local data = LoadRankData()
net.Start("Onyx_SendRankData")
net.WriteTable(data)
net.Send(ply)
end
end)
end)
else -- CLIENT
local playerRanks = {}
-- Запрос данных о званиях при загрузке клиента
hook.Add("InitPostEntity", "Onyx_RequestRankData", function()
net.Start("Onyx_RequestRankData")
net.SendToServer()
end)
-- Получение данных о званиях
net.Receive("Onyx_SendRankData", function()
local data = net.ReadTable()
playerRanks = data
end)
-- Получение звания игрока на клиенте (клиентская версия)
local function GetClientPlayerRank(steamID64)
return playerRanks[steamID64] or ""
end
end