[Q-Menu] Скрыть владки и инструменты от игроков

Данный код написан не мной и зависит от библиотеки CST и SAM . Позволяет блокировать пользователям вкладки в q меню и инструменты. И да это SH часть.



local BLOCKED = {
    '#spawnmenu.category.your_spawnlists'
}

if (CLIENT) then
    hook.Add('ChatText', 'cst', function(index, name, text, type)
        if (type == 'joinleave') then
            return true
        end
    end)
end

hook.Add('ContextMenuShowTool', 'cst', function()
    -- return false
end)

if (CLIENT) then
    favoriteCache = favoriteCache or {}

    local function saveFavorites()
        local encoded = pon.encode(favoriteCache)
        file.Write('cst_prop_favorites.dat', encoded)
    end

    local function loadFavorites()
        local name = 'cst_prop_favorites.dat'
        if (file.Exists(name, 'DATA')) then
            local encoded = file.Read(name, 'DATA')
            local decoded = pon.decode(encoded)
            favoriteCache = decoded
        end
    end

    local function addFavorite(model)
        favoriteCache[model] = true
        saveFavorites()

        if (IsValid(favoriteSpawnmenuLayout)) then
            for _, child in ipairs(favoriteSpawnmenuLayout:GetChildren()) do
                child:Remove()
            end

            favoriteSpawnmenuLayout:Build()
        end
    end

    local function deleteFavorite(model)
        favoriteCache[model] = nil
        saveFavorites()

        if (IsValid(favoriteSpawnmenuLayout)) then
            for _, child in ipairs(favoriteSpawnmenuLayout:GetChildren()) do
                child:Remove()
            end

            favoriteSpawnmenuLayout:Build()
        end
    end

    local function isFavorite(model)
        return favoriteCache[model]
    end

    hook.Add('gP:PostAddedDMenuOption', 'test', function(state, menu, name)
        local hovered = vgui.GetHoveredPanel()
        local data = IsValid(hovered) and hovered:GetTable() or {}
        local model = data and data.m_strModelName
        if (name == '#spawnmenu.menu.copy' and state == 'post' and model) then
            menu:AddOption('Избранное', function()
                addFavorite(model)
            end):SetIcon('icon16/star.png')
        end
    end)


    -- spawnmenu.AddCreationTab( 'Избранное', function()
    --     local size = cst.util.Tall(64)

    --     local scrollList = vgui.Create( 'DScrollPanel' )

    --     local lblTitle = scrollList:Add('DLabel')
    --     lblTitle:SetFont(cst.Font('Overpass@48'))
    --     lblTitle:SetExpensiveShadow(2, color_black)
    --     lblTitle:Dock(TOP)
    --     lblTitle:SetText('Избранные пропы')
    --     lblTitle:SizeToContentsY()
    --     lblTitle:SetTextColor(color_white)

    --     loadFavorites()
    --     local layout = scrollList:Add('DIconLayout')
    --     layout:Dock(FILL)
    --     layout.Build = function(panel)
    --         for model in pairs(favoriteCache) do
    --             local icon = panel:Add('SpawnIcon')
    --             icon:SetModel(model)
    --             icon:SetSize(size, size)
    --             icon.DoClick = function()
    --                 RunConsoleCommand('gm_spawn', model)
    --                 surface.PlaySound( "ui/buttonclickrelease.wav" )
    --             end
    --             icon.DoRightClick = function()
    --                 local dmenu = DermaMenu()
    --                     dmenu:AddOption('Удалить избранное', function()
    --                         deleteFavorite(model)
    --                     end):SetIcon('icon16/delete.png')
    --                 dmenu:Open()
    --             end
    --         end
    --         panel:InvalidateParent(true)
    --         panel:Layout()
    --     end

    --     favoriteSpawnmenuLayout = layout

    --     layout:Build()

    --     return scrollList

    -- end, 'icon16/star.png', 200 )
end

if (CLIENT) then
    historyCache = historyCache or {}

    hook.Add( 'PopulateHistory', 'AddEntityContent', function( pnlContent )
        local size = cst.util.Tall(64)

        local lblTitle = pnlContent:Add('DLabel')
        lblTitle:SetFont(cst.Font('Overpass@48'))
        lblTitle:SetExpensiveShadow(2, color_black)
        lblTitle:Dock(TOP)
        lblTitle:SetText('Последние использованные пропы')
        lblTitle:SizeToContentsY()
        lblTitle:SetTextColor(color_white)

        local layout = pnlContent:Add('DIconLayout')
        layout:Dock(FILL)
        layout.Build = function(panel)
            for model in pairs(historyCache) do
                local icon = panel:Add('SpawnIcon')
                icon:SetModel(model)
                icon:SetSize(size, size)
                icon.DoClick = function()
                    RunConsoleCommand('gm_spawn', model)
                    surface.PlaySound( "ui/buttonclickrelease.wav" )
                end
            end
            panel:InvalidateParent(true)
            panel:Layout()
        end

        historySpawnmenuLayout = layout

        layout:Build()
    end )

    net.Receive('cst.SendPropHistory', function(len)
        local model = net.ReadString()
        if (not historyCache[model]) then
            historyCache[model] = true

            if (IsValid(historySpawnmenuLayout)) then
                for _, child in ipairs(historySpawnmenuLayout:GetChildren()) do
                    child:Remove()
                end
                historySpawnmenuLayout:Build()
            end
        end
    end)

    -- spawnmenu.AddCreationTab( 'История', function()

    --     ctrl = vgui.Create( 'DScrollPanel' );
    --     hook.Run('PopulateHistory', ctrl)

    --     return ctrl

    -- end, 'icon16/control_repeat_blue.png', 200 )
else
    util.AddNetworkString('cst.SendPropHistory')
    hook.Add('PlayerSpawnedProp', 'prop.history', function(ply, model)
        -- net.Start('cst.SendPropHistory')
        --     net.WriteString(model)
        -- net.Send(ply)
    end)
end

if (CLIENT) then
    local permissions = {
        ['#spawnmenu.category.weapons'] = 'weapons',
        ['#spawnmenu.category.npcs'] = 'npcs',
        ['#spawnmenu.category.entities'] = 'entities'
    }

    local super = {
        ['GuthSCP'] = true,
        ['DrGBase'] = true,
        ['#spawnmenu.category.vehicles'] = true,
    }

    local function modifyCreationMenu()
        cst.util.FindPanel('CreationMenu', function(panel)
            for _, tab in ipairs(panel:GetItems()) do
                local name = tab.Name
                local pnl = tab.Tab
                local isDisabled = {
    ["#spawnmenu.category.dupes"] = true,
    ["#spawnmenu.category.saves"] = true,
    -- ["#spawnmenu.category.npcs"] = true,
    -- ["#spawnmenu.category.vehicles"] = true,
    ["#spawnmenu.category.postprocess"] = true
}

                pnl:SetVisible(true)

                if (permissions[name] and not LocalPlayer():HasPermission(permissions[name])) then
                    pnl:SetVisible(false)
                end

                if isDisabled[name] then
                    pnl:SetVisible(false)
                end

                if (super[name] and not LocalPlayer():IsSuperAdmin()) then
                    pnl:SetVisible(false)
                end

                panel.tabScroller:InvalidateLayout()
            end
        end)
    end

    local function modifyTools()
        local client = LocalPlayer()
        cst.util.FindPanel('ToolPanel', function(panel)
            for _, tab in ipairs(panel.List.pnlCanvas:GetChildren()) do
                local count = 0

                -- Remove tools
                for _, child in ipairs(tab:GetChildren()) do
                    if child.ClassName == 'DButton' then
                        local toolID = child.Name
                        local isSuperadmin = {
                            ['physprop'] = true,
                        }
local disabletool = {
    ["dynamite"] = false,
    ["motor"] = false,
    ["finger"] = false,
    ["trails"] = false,
    ["balloon"] = false,
    ["hoverball"] = false,
    ["thruster"] = false,
    ["inflator"] = false,
    ["eyeposer"] = false,
    ["faceposer"] = false,
    ["paint"] = false,
    -- ["duplicator"] = false,
    ["emitter"] = false,
    -- ["wheel"] = false,
    ["weld"] = false
}
                        if (
                            disabletool[toolID] 
                             or (not client:HasPermission(toolID))
                            or (isSuperadmin[toolID] and not client:IsSuperAdmin())
                        ) then
                            child:SetVisible(false)
                        else
                            child:SetVisible(true)
                        end
                    end
                end

                -- Count how many tools remained in category
                for _, child in ipairs(tab:GetChildren()) do
                    if child.ClassName == 'DButton' and child:IsVisible() then
                        count = count + 1
                    end
                end

                -- Delete category if there's no tools
                if count == 0 then
                    tab:SetVisible(false)
                else
                    tab:SetVisible(true)
                end
            end

            panel.List.pnlCanvas:InvalidateLayout()
        end)
    end

    local cvShowProps = CreateClientConVar('cl_cst_show_default_props', '0', true, false)
    local function modifySpawnmenu()
        cst.util.FindPanel('SpawnmenuContentPanel', function(panel)
            local navbar = panel.ContentNavBar
            local tree = navbar.Tree
            local node = tree.RootNode

            for _, child in pairs(node:GetChildren()) do
                if child.ClassName == 'DListLayout' then
                    for _, tab in pairs(child:GetChildren()) do
                        local text = tab:GetText()

                        if text == language.GetPhrase('#spawnmenu.category.your_spawnlists') then
                            tab:SetVisible(cvShowProps:GetBool())
                        elseif (text == language.GetPhrase('#spawnmenu.category.addon_spawnlists')) then
                            local children = tab.ChildNodes:GetChildren()
                            local tab1 = children[1]
                            if (IsValid(tab1) and not panel.switchedToFirst) then
                                tab1:InternalDoClick()
                                panel.switchedToFirst = true
                            end
                        end
                    end

                    child:InvalidateLayout()
                end
            end
        end)
    end

    hook.Add('SpawnMenuOpened', 'cst.spawnmenu', function()
        modifyCreationMenu()
        modifyTools()
        modifySpawnmenu()
    end)
end

Результат :