Files
2026-03-31 10:27:04 +03:00

97 lines
3.1 KiB
Lua

-- Garry's Mod Binder - Main Client Logic
include("binder/sh_lang.lua")
include("binder/core/sh_config.lua")
include("binder/vgui/cl_frame.lua")
include("binder/vgui/cl_profiles_tab.lua")
include("binder/vgui/cl_keybind_tab.lua")
include("binder/vgui/cl_radial_tab.lua")
include("binder/vgui/cl_radial_hud.lua")
include("binder/vgui/cl_settings_tab.lua")
Binder = Binder or {}
Binder.Profiles = Binder.Profiles or {}
surface.CreateFont("Binder_Key", {
font = "Roboto",
size = 12,
weight = 700,
extended = true,
})
CreateClientConVar("binder_show_feedback", "1", true, false)
CreateClientConVar("binder_dark_theme", "1", true, false)
CreateClientConVar("binder_radial_key", tostring(Binder.Config.DefaultRadialKey), true, false)
-- Networking
net.Receive("Binder_SyncProfiles", function()
local length = net.ReadUInt(32)
local compressed = net.ReadData(length)
local data = util.Decompress(compressed)
if data then
Binder.Profiles = Binder.SanitizeProfiles(util.JSONToTable(data) or {})
if IsValid(Binder.Frame) then
Binder.Frame:RefreshActiveTab()
end
end
end)
function Binder.SaveToServer()
local data = util.TableToJSON(Binder.Profiles)
local compressed = util.Compress(data)
net.Start("Binder_UpdateProfile")
net.WriteUInt(#compressed, 32)
net.WriteData(compressed, #compressed)
net.SendToServer()
end
-- Input Hook for Binds (Client-side Think for Singleplayer support)
local PrevBindState = {}
hook.Add("Think", "Binder_CheckBindsThink", function()
local activeProfile
for _, p in ipairs(Binder.Profiles or {}) do
if p.Active then activeProfile = p break end
end
if not activeProfile or not activeProfile.Binds then return end
-- Don't trigger new presses if in console, ESC menu, typing in chat, or focused on a VGUI text entry
local blockNewInput = gui.IsConsoleVisible() or gui.IsGameUIVisible() or (vgui.GetKeyboardFocus() ~= nil) or LocalPlayer():IsTyping()
for key, commandStr in pairs(activeProfile.Binds) do
local isDown = input.IsButtonDown(key)
local wasDown = PrevBindState[key] or false
if isDown and not wasDown then
if not blockNewInput then
PrevBindState[key] = true
if string.sub(commandStr, 1, 1) == "/" then
LocalPlayer():ConCommand("say " .. commandStr)
else
LocalPlayer():ConCommand(commandStr)
end
end
elseif not isDown and wasDown then
PrevBindState[key] = false
-- Automatically release + commands
local cmd = string.Explode(" ", commandStr)[1]
if cmd and string.sub(cmd, 1, 1) == "+" then
local minusCmd = "-" .. string.sub(cmd, 2)
LocalPlayer():ConCommand(minusCmd)
end
end
end
end)
concommand.Add("binder_menu", function()
if Binder.Frame and IsValid(Binder.Frame) then
Binder.Frame:Remove()
end
Binder.Frame = vgui.Create("Binder_Frame")
end)