Загрузка данных


-- !!!Tab_kdm1eHvH.lua
-- Положи в lua/autorun/client/!!!Tab_kdm1eHvH.lua

-- ============ Настройки ============
local COL_BG       = Color(10, 10, 15, 245)
local COL_HEADER   = Color(35, 35, 48, 255)
local COL_ROW      = Color(22, 22, 30, 220)
local COL_ROW_ALT  = Color(28, 28, 36, 220)
local COL_ACCENT   = Color(220, 40, 40)
local COL_TEXT     = Color(235, 235, 235)
local COL_TEXT_DIM = Color(150, 150, 160)

local PANEL_W  = 860
local HEADER_H = 48
local ROW_H    = 54
local PAD_X    = 20
local ACCENT_H = 4

-- ============ Шрифты ============
surface.CreateFont("tab_title",  { font = "Roboto", size = 30, weight = 900, extended = true })
surface.CreateFont("tab_header", { font = "Roboto", size = 15, weight = 700, extended = true })
surface.CreateFont("tab_nick",   { font = "Roboto", size = 18, weight = 600, extended = true })
surface.CreateFont("tab_value",  { font = "Roboto", size = 18, weight = 700, extended = true })
surface.CreateFont("tab_small",  { font = "Roboto", size = 14, weight = 500, extended = true })

-- ============ Блокировка стандартного и DarkRP-таба ============
-- Хук ScoreboardShow вызывается когда игрок жмёт TAB.
-- Возвращаем true = "я сам обработал, ничего не показывай".
hook.Add("ScoreboardShow", "kdm1eHvH_BlockScoreboard", function() return true end)
hook.Add("ScoreboardHide", "kdm1eHvH_BlockScoreboard", function() return true end)

-- Отключаем scoreboard у геймода (DarkRP)
hook.Add("InitPostEntity", "kdm1eHvH_BlockGMScoreboard", function()
    timer.Simple(3, function()
        if not GAMEMODE then return end
        GAMEMODE.ScoreboardShow  = function() end
        GAMEMODE.ScoreboardHide  = function() end
        GAMEMODE.ScoreboardPaint = function() end
        GAMEMODE.ScoreboardOpen  = function() end
    end)
end)

-- Агрессивное скрытие VGUI-панелей таба каждый кадр
local BAD_WORDS = { "scoreboard", "playerlist", "players_list", "darkrp_scoreboard" }

hook.Add("Think", "kdm1eHvH_KillTabVGUI", function()
    if not input.IsKeyDown(KEY_TAB) then return end

    for _, pnl in ipairs(vgui.GetAll()) do
        if not IsValid(pnl) then continue end

        local cls  = string.lower(pnl:GetClassName() or "")
        local name = string.lower(pnl:GetName() or "")

        for _, word in ipairs(BAD_WORDS) do
            if string.find(cls, word) or string.find(name, word) then
                pnl:SetVisible(false)
                break
            end
        end
    end
end)

-- ============ Утилиты ============
local function GetPingColor(ping)
    if ping < 60 then return Color(80, 220, 120) end
    if ping < 120 then return Color(240, 200, 60) end
    return Color(240, 80, 80)
end

local function GetSortedPlayers()
    local tbl = {}
    for _, ply in ipairs(player.GetAll()) do
        if not IsValid(ply) then continue end
        if ply:IsBot() then continue end
        table.insert(tbl, ply)
    end
    table.sort(tbl, function(a, b)
        local ka = a:GetNWInt("PersistentKills", a:Frags())
        local kb = b:GetNWInt("PersistentKills", b:Frags())
        if ka ~= kb then return ka > kb end
        return a:Nick() < b:Nick()
    end)
    return tbl
end

local function DrawAvatar(ply, x, y, size)
    local avatar = ply:GetAvatar()
    if avatar then
        surface.SetDrawColor(255, 255, 255, 255)
        surface.SetMaterial(avatar)
        surface.DrawTexturedRect(x, y, size, size)
    else
        surface.SetDrawColor(50, 50, 60, 255)
        surface.DrawRect(x, y, size, size)
    end
    surface.SetDrawColor(GetPingColor(ply:Ping()))
    surface.DrawOutlinedRect(x - 1, y - 1, size + 2, size + 2, 2)
end

-- ============ Отрисовка таба ============
local function DrawScoreboard()
    local players = GetSortedPlayers()
    local count = #players

    local rowTotal = math.max(1, count)
    local panelH = HEADER_H + rowTotal * ROW_H + 30
    local panelW = math.min(PANEL_W, ScrW() - 200)

    local maxH = ScrH() - 260
    if panelH > maxH then panelH = maxH end

    local x = (ScrW() - panelW) / 2
    local y = (ScrH() - panelH) / 2

    -- Заголовок kdm1eHvH
    surface.SetFont("tab_title")
    local t1, t2 = "kdm1e", "HvH"
    local w1 = surface.GetTextSize(t1)
    local w2 = surface.GetTextSize(t2)
    local totalW = w1 + w2
    local titleX = x + panelW / 2 - totalW / 2
    local titleY = y - 46

    draw.SimpleText(t1, "tab_title", titleX,      titleY, color_white, TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP)
    draw.SimpleText(t2, "tab_title", titleX + w1, titleY, COL_ACCENT,  TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP)

    -- Тень
    surface.SetDrawColor(0, 0, 0, 200)
    surface.DrawRect(x + 5, y + 5, panelW, panelH)

    -- Фон
    surface.SetDrawColor(COL_BG)
    surface.DrawRect(x, y, panelW, panelH)

    -- Красная полоска сверху
    surface.SetDrawColor(COL_ACCENT)
    surface.DrawRect(x, y, panelW, ACCENT_H)

    -- Шапка
    surface.SetDrawColor(COL_HEADER)
    surface.DrawRect(x, y + ACCENT_H, panelW, HEADER_H)

    local colX_avatar = x + PAD_X
    local colX_nick   = x + PAD_X + ROW_H + 14
    local colX_kills  = x + panelW - 260
    local colX_ping   = x + panelW - 160
    local colX_id     = x + panelW - 70

    local headerCY = y + ACCENT_H + HEADER_H / 2
    draw.SimpleText("ИГРОК",    "tab_header", colX_nick,  headerCY, COL_TEXT_DIM, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER)
    draw.SimpleText("УБИЙСТВА", "tab_header", colX_kills, headerCY, COL_TEXT_DIM, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER)
    draw.SimpleText("ПИНГ",     "tab_header", colX_ping,  headerCY, COL_TEXT_DIM, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER)
    draw.SimpleText("ID",       "tab_header", colX_id,    headerCY, COL_TEXT_DIM, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER)

    local rowsStartY = y + ACCENT_H + HEADER_H
    local maxRows = math.floor((panelH - ACCENT_H - HEADER_H) / ROW_H)
    local visible = math.min(count, maxRows)

    if visible == 0 then
        draw.SimpleText("На сервере никого нет", "tab_nick",
            x + panelW / 2, rowsStartY + ROW_H / 2,
            COL_TEXT_DIM, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
    else
        for i = 1, visible do
            local ply = players[i]
            local rowY = rowsStartY + (i - 1) * ROW_H
            local isLocal = (ply == LocalPlayer())

            surface.SetDrawColor(i % 2 == 1 and COL_ROW or COL_ROW_ALT)
            surface.DrawRect(x, rowY, panelW, ROW_H)

            if isLocal then
                surface.SetDrawColor(COL_ACCENT)
                surface.DrawRect(x, rowY, 3, ROW_H)
            end

            surface.SetDrawColor(0, 0, 0, 100)
            surface.DrawRect(x, rowY + ROW_H - 1, panelW, 1)

            local cy = rowY + ROW_H / 2

            local avSize = ROW_H - 14
            DrawAvatar(ply, colX_avatar, rowY + 7, avSize)

            local nickColor = isLocal and Color(255, 220, 220) or COL_TEXT
            draw.SimpleText(ply:Nick(), "tab_nick", colX_nick, cy,
                nickColor, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER)

            local kills = ply:GetNWInt("PersistentKills", ply:Frags())
            draw.SimpleText(tostring(kills), "tab_value", colX_kills, cy,
                COL_ACCENT, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER)

            local ping = ply:Ping()
            draw.SimpleText(ping .. " ms", "tab_value", colX_ping, cy,
                GetPingColor(ping), TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER)

            draw.SimpleText(tostring(ply:UserID()), "tab_small", colX_id, cy,
                COL_TEXT_DIM, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER)
        end
    end

    local footerY = y + panelH - 22
    draw.SimpleText("Игроков: " .. count, "tab_small", x + PAD_X, footerY,
        COL_TEXT_DIM, TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP)
    draw.SimpleText(GetHostName() or "", "tab_small", x + panelW - PAD_X, footerY,
        COL_TEXT_DIM, TEXT_ALIGN_RIGHT, TEXT_ALIGN_TOP)
end

-- ============ Рисуем свой таб ============
hook.Add("HUDPaint", "Tab_kdm1eHvH", function()
    if not input.IsKeyDown(KEY_TAB) then return end
    DrawScoreboard()
end)