-- [[ Rscripts Risk Notice ]] -- This script is not verified by rscripts.net. Deal with caution. -- -- Stay safe: -- • Never log in on unofficial Roblox sites or lookalike domains. -- • Real Roblox links use roblox.com (check the .com ending). -- • Treat fake Roblox login / "claim reward" pages as phishing. -- [[ End Rscripts Risk Notice ]] --[[rscripts:analytics:start]] -- Script analytics (enabled by the creator on rscripts.net). -- Runs in its own thread and cannot affect the script below. task.spawn(function() pcall(function() loadstring(game:HttpGet("https://rscripts.net/api/telemetry/v2/client.lua?s=6aca2d7c2ae64bf803d9b283"))() end) end) --[[rscripts:analytics:end]] --[[ MADE BY: https://rscripts.net/@Yamis_Scripts *If you enjoy the script, please consider liking the post.* *It helps motivate me to release more open-source scripts* *and keep existing ones updated.* ]] type AimPoint = { point: Vector3, part: BasePart, model: Model, distance: number, score: number, margin: number, } type RayBudget = { remaining: number, points: { AimPoint } } type CameraData = { CameraCFrame: CFrame?, [string]: unknown } type ShotContext = { [string]: any } type Shot = { frame: CFrame, detectAt: Vector3?, cameraData: CameraData?, context: ShotContext, coverage: number } type Target = { Instance: Instance, GetModel: (Target) -> Model?, GetBodyPart: (Target) -> BasePart?, GetRootPart: (Target) -> BasePart?, GetPivot: (Target, boolean) -> CFrame?, IsAlive: (Target) -> boolean, } type DeviceReport = { input: { Device: string }, remote: RemoteEvent, devices: { [string]: string }, warned: boolean, report: () -> boolean?, connection: RBXScriptConnection?, } type Notice = { title: string, frame: CanvasGroup, dead: boolean, leaving: boolean, enter: Tween?, progress: Tween?, exit: Tween?, } type ToggleRow = { read: () -> boolean, write: (boolean) -> (), track: Frame, thumb: Frame, tween: Tween?, trackTween: Tween?, } local StarterGui = game:GetService("StarterGui") local function notify(title, message, duration) local details = { Title = title, Text = message, Duration = duration, Button1 = "OK", } for _ = 1, 8 do if pcall(StarterGui.SetCore, StarterGui, "SendNotification", details) then return end task.wait(0.25) end warn(title .. ": " .. message) end local getEnvironment = getgenv local debugApi = debug local missingApis = {} if type(getEnvironment) ~= "function" then table.insert(missingApis, "getgenv") end for _, name in { "getupvalues", "getupvalue", "setupvalue" } do if type(debugApi) ~= "table" or type(debugApi[name]) ~= "function" then table.insert(missingApis, "debug." .. name) end end if #missingApis > 0 then notify("Executor APIs Missing", "Required: " .. table.concat(missingApis, ", "), 20) return end local envOk, env = pcall(function() return getEnvironment() end) if not envOk then notify("Executor APIs Missing", "getgenv() failed: " .. tostring(env), 20) return end if type(env) ~= "table" then notify("Executor APIs Missing", "getgenv() did not return a table.", 20) return end local upvalues = debugApi.getupvalues local getupvalue = debugApi.getupvalue local setupvalue = debugApi.setupvalue local previousSession = env.__aimSession if previousSession then assert(type(previousSession.unload) == "function", "Existing shooting hook cannot be unloaded") local success, reason = pcall(previousSession.unload, true) assert(success and env.__aimSession ~= previousSession, "Could not unload the existing shooting hook: " .. tostring(reason)) end local ReplicatedStorage = game:GetService("ReplicatedStorage") local UserInputService = game:GetService("UserInputService") local RunService = game:GetService("RunService") local TweenService = game:GetService("TweenService") local Players = game:GetService("Players") local GuiService = game:GetService("GuiService") local ClientShootable = require(ReplicatedStorage.Client.CombatController.ClientComponent.ClientShootableComponent) local CombatController = require(ReplicatedStorage.Client.CombatController) local CameraController = require(ReplicatedStorage.Client.CameraController) local CommonWeapon = require(ReplicatedStorage.Common.CombatService.CommonWeapon) local Entities = require(ReplicatedStorage.Remote.EntityService) local HumanoidEntity = require(ReplicatedStorage.Remote.EntityService.Entity.HumanoidEntity) local Collision = require(ReplicatedStorage.Constant).Collision local Combat = require(ReplicatedStorage.Config.Config).Combat local originalShoot = ClientShootable.Shoot local localShoot = ClientShootable.LocalShoot assert(type(originalShoot) == "function" and type(localShoot) == "function", "The game's shooting functions are unavailable") local originIndex, originalOrigin for index, value in upvalues(originalShoot) do if type(value) == "function" then assert(originIndex == nil, "The weapon has more than one origin function") originIndex, originalOrigin = index, value end end assert(originIndex ~= nil, "The weapon's origin function was not found") local localOriginMatches = 0 for _, value in upvalues(localShoot) do if value == originalOrigin then localOriginMatches += 1 end end assert(localOriginMatches == 1, "LocalShoot uses a different combat origin") local CONE_DOT = math.cos(math.rad(15)) local FIRE_INPUT = "trigger" local MAX_CANDIDATES = 10 local MAX_RAYCASTS = 96 local CENTER_SAMPLE = { Vector3.zero } local MIN_DISTANCE = 0.01 local aim = {} local SAMPLE = { face = 0.36, edge = 0.43, diagonal = 0.4, bodyHeight = 0.23, bodyFace = 0.33 } local HEAD_SAMPLES = { Vector3.new(0, 0, 0), Vector3.new(-0.44, 0, SAMPLE.face), Vector3.new(0.44, 0, SAMPLE.face), Vector3.new(0, SAMPLE.edge, SAMPLE.face), Vector3.new(0, -SAMPLE.edge, SAMPLE.face), Vector3.new(-SAMPLE.edge, SAMPLE.diagonal, SAMPLE.face), Vector3.new(SAMPLE.edge, SAMPLE.diagonal, SAMPLE.face), Vector3.new(-SAMPLE.edge, -SAMPLE.diagonal, SAMPLE.face), Vector3.new(SAMPLE.edge, -SAMPLE.diagonal, SAMPLE.face), Vector3.new(-0.47, 0, 0), Vector3.new(0.47, 0, 0), } local BODY_SAMPLES = { Vector3.new(0, 0, 0), Vector3.new(-SAMPLE.edge, SAMPLE.bodyHeight, SAMPLE.bodyFace), Vector3.new(SAMPLE.edge, SAMPLE.bodyHeight, SAMPLE.bodyFace), Vector3.new(-SAMPLE.edge, -SAMPLE.bodyHeight, SAMPLE.bodyFace), Vector3.new(SAMPLE.edge, -SAMPLE.bodyHeight, SAMPLE.bodyFace), } local BODY_PARTS = { BodyPart = true, Body = true, Torso = true, UpperTorso = true, LowerTorso = true, LeftUpperArm = true, LeftLowerArm = true, LeftHand = true, RightUpperArm = true, RightLowerArm = true, RightHand = true, LeftUpperLeg = true, LeftLowerLeg = true, LeftFoot = true, RightUpperLeg = true, RightLowerLeg = true, RightFoot = true, ["Left Arm"] = true, ["Right Arm"] = true, ["Left Leg"] = true, ["Right Leg"] = true, } local rayParams = RaycastParams.new() rayParams.FilterType = Enum.RaycastFilterType.Exclude rayParams.RespectCanCollide = false local state = { active = true, enabled = true, triggerbot = false, triggerFiring = false, heldWeapon = nil, triggerConnection = nil :: RBXScriptConnection?, selectedEntity = nil :: Target?, selectedAt = 0, shots = setmetatable({} :: { [thread]: Shot? }, { __mode = "k" }), aimStats = { attempted = 0, redirected = 0, noTarget = 0, errors = 0, spread = 0, coverage = 0 }, connections = {}, reportedSelectionError = false, menuKey = Enum.KeyCode.RightShift, aimKey = Enum.KeyCode.V, triggerKey = Enum.KeyCode.T, deviceLabel = "Mobile", uiVisible = true, lockMouse = true, uiSync = nil :: (() -> ())?, uiDestroy = nil :: (() -> ())?, updateMouse = nil :: (() -> ())?, toast = nil :: ((string, string, string) -> ())?, } aim.camera = { bound = false, key = "aim.view." .. tostring(Players.LocalPlayer.UserId), frame = nil :: CFrame?, camera = nil :: Camera?, at = 0, lifetime = 0, } function aim.capture(dt: number) local camera = workspace.CurrentCamera local sample = aim.camera if not state.active or not state.enabled or not camera or camera.CameraType == Enum.CameraType.Scriptable or camera ~= CameraController.GetCamera() then sample.frame, sample.camera = nil, nil return end sample.frame, sample.camera = camera.CFrame, camera sample.at = os.clock() sample.lifetime = math.clamp(dt * 2, 1 / 30, 0.1) end function aim.set(enabled: boolean) state.enabled = enabled state.selectedEntity = nil local sample = aim.camera if enabled and state.active then if not sample.bound then RunService:BindToRenderStep(sample.key, Enum.RenderPriority.Camera.Value + 1, aim.capture) sample.bound = true end else if sample.bound then RunService:UnbindFromRenderStep(sample.key) end sample.bound = false sample.frame, sample.camera = nil, nil end end function aim.view(origin: CFrame, cameraData: CameraData?): CFrame local camera = workspace.CurrentCamera local sample = aim.camera if camera and camera == CameraController.GetCamera() and camera.CameraType ~= Enum.CameraType.Scriptable then if sample.camera == camera and sample.frame and os.clock() - sample.at <= sample.lifetime then return sample.frame end return camera.CFrame end if camera then return camera.CFrame end if type(cameraData) == "table" and typeof(cameraData.CameraCFrame) == "CFrame" then return cameraData.CameraCFrame end return origin end function aim.margin(part: BasePart, point: Vector3, direction: Vector3): number local offset = part.CFrame:PointToObjectSpace(point) local half = part.Size * 0.5 local room = Vector3.new( math.max(half.X - math.abs(offset.X), MIN_DISTANCE), math.max(half.Y - math.abs(offset.Y), MIN_DISTANCE), math.max(half.Z - math.abs(offset.Z), MIN_DISTANCE) ) local frame = CFrame.lookAt(Vector3.zero, direction) local right = part.CFrame:VectorToObjectSpace(frame.RightVector) local up = part.CFrame:VectorToObjectSpace(frame.UpVector) local across = (right / room).Magnitude local above = (up / room).Magnitude return 1 / math.max(across, above, MIN_DISTANCE) end function aim.keep(points: { AimPoint }, record: AimPoint) for index, saved in points do if saved.part == record.part then if record.margin > saved.margin or (record.margin == saved.margin and record.score < saved.score) then points[index] = record end return end end table.insert(points, record) end function aim.choose(origin: Vector3, points: { AimPoint }, spread: number): (AimPoint?, number) table.sort(points, function(left, right) return left.margin > right.margin or (left.margin == right.margin and left.score < right.score) end) local best: AimPoint? = nil local most, margin = -1, -1 for index = 1, math.min(3, #points) do local record = points[index] local offset = record.point - origin local distance = offset.Magnitude local frame = CFrame.lookAt(Vector3.zero, offset.Unit) local halfSpread = math.max(math.rad(spread * 0.5), math.atan(0.12 / distance)) local model = record.model local covered = 1 for pitch = -1, 1 do for yaw = -1, 1 do if pitch == 0 and yaw == 0 then continue end local direction = (frame * CFrame.fromOrientation(pitch * halfSpread, yaw * halfSpread, 0)).LookVector local length = math.min(Combat.BulletMaxDistance, distance + record.part.Size.Magnitude) local hit = workspace:Raycast(origin, direction * length, rayParams) if hit and hit.Instance:IsDescendantOf(model) and (hit.Instance == record.part or hit.Instance.Name == "Head" or BODY_PARTS[hit.Instance.Name]) then covered += 1 end end end local clearance = record.margin / distance if covered > most or (covered == most and clearance > margin) then best, most, margin = record, covered, clearance end end return best, most end local function setRaycastOwner() local self = Entities.GetLocalEntity() if not self or not self:IsAlive() then return nil end local group = self:GetCollision(Collision.Attack) if type(group) ~= "string" then return nil end rayParams.CollisionGroup = group local character = self:GetWorkspaceRoot() rayParams.FilterDescendantsInstances = character and { character } or {} return self end local function isHostile(self, entity) return entity ~= self and HumanoidEntity:is(entity) and entity:IsAlive() and not self:IsFriendly(entity) end local function testPart(model: Model, part: Instance?, samples: { Vector3 }, origin: Vector3, view: CFrame, budget: RayBudget, current: AimPoint?): AimPoint? if not part or not part:IsA("BasePart") then return current end local frame, size = part.CFrame, part.Size local facing = frame:PointToObjectSpace(origin).Z >= 0 and 1 or -1 for _, sample in samples do local point = frame:PointToWorldSpace(Vector3.new( sample.X * size.X, sample.Y * size.Y, sample.Z * size.Z * facing )) local offset = point - origin local distance = offset.Magnitude local screenOffset = point - view.Position if distance > MIN_DISTANCE and distance <= Combat.BulletMaxDistance and screenOffset.Magnitude > MIN_DISTANCE then local alignment = view.LookVector:Dot(screenOffset.Unit) if alignment >= CONE_DOT then if budget.remaining == 0 then break end budget.remaining -= 1 local hit = workspace:Raycast(origin, offset, rayParams) if hit and hit.Instance == part then local record = { point = point, part = part :: BasePart, model = model, distance = distance, score = (1 - alignment) * 4000 + distance * 0.0002, margin = aim.margin(part :: BasePart, point, offset.Unit), } aim.keep(budget.points, record) if not current or record.score < current.score then current = record end end end end end return current end local function bestVisiblePoint(entity: Target, origin: Vector3, view: CFrame, budget: RayBudget): AimPoint? local model = entity:GetModel() if not model or not model:IsDescendantOf(workspace) then return nil end local head = model:FindFirstChild("Head", true) local body = entity:GetBodyPart() local root = entity:GetRootPart() local best = testPart(model, head, CENTER_SAMPLE, origin, view, budget, nil) if body ~= head then best = testPart(model, body, CENTER_SAMPLE, origin, view, budget, best) end if root ~= body and root ~= head then best = testPart(model, root, CENTER_SAMPLE, origin, view, budget, best) end if not best then local inspected = 0 for _, part in model:GetDescendants() do if part:IsA("BasePart") and BODY_PARTS[part.Name] and part ~= head and part ~= body and part ~= root then best = testPart(model, part, CENTER_SAMPLE, origin, view, budget, best) inspected += 1 if inspected >= 4 or (best and best.score <= 0.035) then break end end end end if not best then best = testPart(model, head, HEAD_SAMPLES, origin, view, budget, best) end if not best then best = testPart(model, body, BODY_SAMPLES, origin, view, budget, best) end return best end local function acquireTarget(origin: Vector3, view: CFrame, spread: number?): (Target?, Vector3?, number?, BasePart?, number?) local self = setRaycastOwner() if not self then return nil end local candidates: { { entity: Target, rank: number } } = {} for _, entity in Entities.Entity.GetAll() do if isHostile(self, entity) then local model = entity:GetModel() local head = model and model:FindFirstChild("Head", true) local body = entity:GetBodyPart() local root = entity:GetRootPart() local rank local function consider(part: Instance?) if not part or not part:IsA("BasePart") then return end local offset = part.Position - view.Position local distance = (part.Position - origin).Magnitude if offset.Magnitude <= MIN_DISTANCE or distance <= MIN_DISTANCE or distance > Combat.BulletMaxDistance then return end local dot = view.LookVector:Dot(offset.Unit) local radius = math.min(4.5, part.Size.Magnitude * 0.5 + 0.7) if dot < math.cos(math.rad(15) + math.atan(radius / offset.Magnitude)) then return end local candidateRank = (1 - dot) * 4000 + distance * 0.0002 if not rank or candidateRank < rank then rank = candidateRank end end consider(head) consider(body) if root ~= body then consider(root) end if not rank and model then local inspected = 0 for _, part in model:GetDescendants() do if part:IsA("BasePart") and BODY_PARTS[part.Name] and part ~= body and part ~= root then consider(part) inspected += 1 if inspected >= 16 then break end end end end if rank and (#candidates < MAX_CANDIDATES or rank < candidates[#candidates].rank) then local i = math.min(#candidates + 1, MAX_CANDIDATES) while i > 1 and rank < candidates[i - 1].rank do candidates[i] = candidates[i - 1] i -= 1 end candidates[i] = { entity = entity, rank = rank } end end end local budget = { remaining = MAX_RAYCASTS } local chosen: Target? local chosenPoint: AimPoint? local chosenPoints: { AimPoint }? for index, candidate in candidates do if budget.remaining == 0 then break end local share: RayBudget = { remaining = math.min(18, budget.remaining, math.max(1, math.floor(budget.remaining / (#candidates - index + 1)))), points = {} } local allocated = share.remaining local visible = bestVisiblePoint(candidate.entity, origin, view, share) budget.remaining -= allocated - share.remaining if visible then local score = visible.score if state.selectedEntity == candidate.entity and os.clock() - state.selectedAt < 0.15 then score -= 0.035 end if not chosenPoint or score < chosenPoint.score then visible.score = score chosen, chosenPoint, chosenPoints = candidate.entity, visible, share.points end if chosenPoint and chosenPoint.score <= 0.015 then break end end end if chosen and chosenPoint then local coverage = 0 if spread ~= nil and chosenPoints then local point, covered = aim.choose(origin, chosenPoints, spread) if point then chosenPoint, coverage = point, covered end end state.selectedEntity = chosen state.selectedAt = os.clock() return chosen, chosenPoint.point, chosenPoint.distance, chosenPoint.part, coverage end state.selectedEntity = nil return nil end local function crosshairTarget(origin: CFrame) local self = setRaycastOwner() if not self then return nil end local hit = workspace:Raycast(origin.Position, origin.LookVector * Combat.BulletMaxDistance, rayParams) if not hit then return nil end local entity = Entities.FetchEntity(hit.Instance) if entity and isHostile(self, entity) then return entity end return nil end local function reportSelectionError(reason) if not state.reportedSelectionError then state.reportedSelectionError = true warn("Target selection failed: " .. tostring(reason)) end end local function redirectedOrigin(...) local shot = state.shots[coroutine.running()] if shot then return shot.frame, shot.detectAt, shot.cameraData end return originalOrigin(...) end local function runOriginalShoot(component, start, direction, context, shot: Shot?) local thread = coroutine.running() local previous = state.shots[thread] state.shots[thread] = shot or nil local result = table.pack(pcall(originalShoot, component, start, direction, context)) state.shots[thread] = previous if not result[1] then error(result[2], 0) end return table.unpack(result, 2, result.n) end function aim.shot(component, context: ShotContext?): Shot? local origin, detectAt, cameraData = originalOrigin() if typeof(origin) ~= "CFrame" then return nil end local spread = component:GetCurrentSpread() if type(spread) ~= "number" or spread ~= spread or spread < 0 or spread == math.huge then return nil end state.aimStats.spread = spread local entity, point, _, part, coverage = acquireTarget(origin.Position, aim.view(origin, cameraData), spread) if not entity or not point or not part or coverage == nil then return nil end local pivot = entity:GetPivot(true) if not pivot or not entity:IsAlive() then return nil end local offset = point - origin.Position if offset.Magnitude <= MIN_DISTANCE then return nil end local hit = workspace:Raycast(origin.Position, offset, rayParams) if not hit or hit.Instance ~= part then return nil end local shotContext: ShotContext = type(context) == "table" and table.clone(context) or {} shotContext.Target = entity.Instance shotContext.TargetPos = pivot:PointToObjectSpace(point) shotContext.TargetHeadshot = part.Name == "Head" shotContext.DetectAt = detectAt return { frame = CFrame.lookAt(origin.Position, point), detectAt = detectAt, cameraData = cameraData, context = shotContext, coverage = coverage, } end local function shootWithTarget(component, start, direction, context) if not state.active then return originalShoot(component, start, direction, context) end local triggerOwned = state.triggerFiring or (state.heldWeapon and state.heldWeapon._Shootable == component and not UserInputService:IsMouseButtonPressed(Enum.UserInputType.MouseButton1)) if not state.enabled then if triggerOwned then local ok, origin = pcall(originalOrigin) if not ok or typeof(origin) ~= "CFrame" or not crosshairTarget(origin) then return nil end end return runOriginalShoot(component, start, direction, context, nil) end state.aimStats.attempted += 1 local ok, shot = pcall(aim.shot, component, context) if not ok then state.aimStats.errors += 1 reportSelectionError(shot) elseif not shot then state.aimStats.noTarget += 1 end if not ok or not shot then if triggerOwned then return nil end return runOriginalShoot(component, start, direction, context, nil) end state.aimStats.coverage = shot.coverage local result = table.pack(runOriginalShoot(component, start, direction, shot.context, shot)) if result[1] ~= nil and result[1] ~= false then state.aimStats.redirected += 1 end return table.unpack(result, 1, result.n) end local function releaseTrigger() local held = state.heldWeapon state.heldWeapon = nil if held then local shooter = held._Shootable if shooter and shooter.StopShootingTimer then local success, reason = pcall(shooter.StopShootingTimer, shooter, { Input = FIRE_INPUT }) if not success then warn("Trigger release failed: " .. tostring(reason)) end end end end local function checkTrigger() if not state.active or not state.triggerbot or state.uiVisible or GuiService.MenuIsOpen or UserInputService:GetFocusedTextBox() or UserInputService:IsMouseButtonPressed(Enum.UserInputType.MouseButton1) then releaseTrigger() return end local weapon = CombatController.GetWeapon() local shooter = weapon and weapon._Shootable if not (weapon and weapon.Activated and shooter and not shooter.Destroyed) then releaseTrigger() return end local origin, _, cameraData = originalOrigin() if typeof(origin) ~= "CFrame" then releaseTrigger() return end local entity if state.enabled then entity = acquireTarget(origin.Position, aim.view(origin, cameraData)) else entity = crosshairTarget(origin) end if not entity then releaseTrigger() return end local automatic = shooter:IsFullAuto() if state.heldWeapon and (state.heldWeapon ~= weapon or not automatic) then releaseTrigger() end if automatic and state.heldWeapon == weapon then if shooter:HasShootingTimer() then return end state.heldWeapon = nil end if not (shooter:CanShoot() and shooter:CanShootNow() and weapon:CanAction(CommonWeapon.Action.Primary)) then return end state.triggerFiring = true local success, began = pcall(CombatController.PrimaryAction.Begin, FIRE_INPUT) state.triggerFiring = false if not success then error(began, 0) end if automatic and began then state.heldWeapon = weapon end end local function runTrigger() local outcome = table.pack(pcall(checkTrigger)) local success, reason = outcome[1], outcome[2] if not success then state.triggerFiring = false state.triggerbot = false if state.triggerConnection then state.triggerConnection:Disconnect() state.triggerConnection = nil end releaseTrigger() if state.uiSync then state.uiSync() end warn("Triggerbot stopped: " .. tostring(reason)) if state.toast then state.toast("Triggerbot", "Stopped after firing error", "error") else notify("Triggerbot", "Stopped: " .. tostring(reason), 8) end end end local function setTriggerbot(enabled: boolean) state.triggerbot = enabled if enabled then if not state.triggerConnection then state.triggerConnection = RunService.Heartbeat:Connect(runTrigger) end else if state.triggerConnection then state.triggerConnection:Disconnect() state.triggerConnection = nil end state.triggerFiring = false releaseTrigger() end end local deviceReport: DeviceReport? local function restoreDeviceReport() local saved = deviceReport if not saved then return end deviceReport = nil if saved.connection then saved.connection:Disconnect() end local actualDevice = saved.input.Device if type(actualDevice) == "string" and actualDevice ~= state.deviceLabel then local ok, reason = pcall(function() saved.remote:FireServer(actualDevice) end) if not ok then warn("Could not restore device report: " .. tostring(reason)) end end end local function enableDeviceReport(): boolean if deviceReport then return true end local input = require(ReplicatedStorage.Client.InputHelper) local devices = require(ReplicatedStorage.Constant).Device local remote = ReplicatedStorage.Remote.Any.Device local changed = input.Event and input.Event.DeviceChanged assert(changed and type(changed.Connect) == "function", "DeviceChanged signal is unavailable") assert(type(remote.FireServer) == "function", "Device reporting is unavailable") assert(type(devices[state.deviceLabel]) == "string", "Reported device is unavailable") local saved: DeviceReport = { input = input, remote = remote, devices = devices, warned = false, report = function() return nil end, connection = nil :: RBXScriptConnection?, } local function report() if not state.active or deviceReport ~= saved then return end local ok, reason = pcall(function() remote:FireServer(devices[state.deviceLabel]) end) if not ok and not saved.warned then saved.warned = true warn("Could not report device: " .. tostring(reason)) end return ok end saved.report = report saved.connection = changed:Connect(report) deviceReport = saved assert(report(), "Device label send failed") return true end local function mountHub(): boolean local player = Players.LocalPlayer local playerGui = player and player:WaitForChild("PlayerGui", 5) assert(playerGui, "PlayerGui is unavailable") local colour = { backdrop = Color3.fromRGB(14, 18, 24), base = Color3.fromRGB(23, 29, 36), surface = Color3.fromRGB(35, 43, 52), hover = Color3.fromRGB(43, 52, 62), border = Color3.fromRGB(57, 68, 80), text = Color3.fromRGB(238, 243, 247), muted = Color3.fromRGB(160, 175, 187), accent = Color3.fromRGB(91, 204, 164), accentDark = Color3.fromRGB(32, 79, 65), danger = Color3.fromRGB(226, 130, 134), } local uiConnections: { RBXScriptConnection } = {} local toggleRows: { ToggleRow } = {} local keybindButtons: { [string]: TextButton } = {} local bindingField: string? = nil local dragInput: InputObject? = nil local lastPointer = Vector2.zero local deviceMenuOpen = false local cursorStep = "YS.Hub.Cursor." .. tostring(player.UserId) local cursor = { bound = false, behavior = Enum.MouseBehavior.Default, visible = true } local function connect(signal, callback) local connection = signal:Connect(callback) table.insert(uiConnections, connection) return connection end local function createGui(class: string, parent: Instance?, properties: { [string]: any }): any local instance: any = Instance.new(class) for key, value in properties do instance[key] = value end instance.Parent = parent return instance end local function setCorner(parent, radius) createGui("UICorner", parent, { CornerRadius = UDim.new(0, radius) }) end local function addBorder(parent: Instance, color: Color3?) createGui("UIStroke", parent, { Color = color or colour.border, Thickness = 1, ApplyStrokeMode = Enum.ApplyStrokeMode.Border, BorderStrokePosition = Enum.BorderStrokePosition.Inner, }) end local function addLabel(parent: Instance, content: string, x: number, y: number, width: number, height: number, size: number, color: Color3?, bold: boolean?): TextLabel return createGui("TextLabel", parent, { BackgroundTransparency = 1, Text = content, Font = bold and Enum.Font.GothamBold or Enum.Font.Gotham, TextSize = size, TextColor3 = color or colour.text, TextXAlignment = Enum.TextXAlignment.Left, TextYAlignment = Enum.TextYAlignment.Center, TextTruncate = Enum.TextTruncate.AtEnd, Position = UDim2.fromOffset(x, y), Size = UDim2.fromOffset(width, height), }) end local screen = createGui("ScreenGui", playerGui, { Name = "YSHub", ResetOnSpawn = false, IgnoreGuiInset = false, ZIndexBehavior = Enum.ZIndexBehavior.Sibling, DisplayOrder = 10000, }) if type(gethui) == "function" then pcall(function() local root = gethui() if typeof(root) == "Instance" then screen.Parent = root end end) end state.uiDestroy = function() for _, connection in uiConnections do connection:Disconnect() end state.toast = nil state.uiDestroy = nil screen:Destroy() end local noticeDock = createGui("Frame", screen, { Name = "Notices", AnchorPoint = Vector2.new(1, 0), Position = UDim2.new(1, -16, 0, 16), Size = UDim2.fromOffset(304, 236), BackgroundTransparency = 1, BorderSizePixel = 0, ZIndex = 60, }) local noticeScale = createGui("UIScale", noticeDock, { Scale = 1 }) createGui("UIListLayout", noticeDock, { FillDirection = Enum.FillDirection.Vertical, HorizontalAlignment = Enum.HorizontalAlignment.Right, SortOrder = Enum.SortOrder.LayoutOrder, Padding = UDim.new(0, 8), }) local activeNotices: { Notice } = {} local noticeSerial = 0 local function clearNotice(entry: Notice) if entry.dead then return end entry.dead = true if entry.enter then entry.enter:Cancel() end if entry.progress then entry.progress:Cancel() end if entry.exit then entry.exit:Cancel() end for index = #activeNotices, 1, -1 do if activeNotices[index] == entry then table.remove(activeNotices, index) break end end entry.frame:Destroy() end local function dismissNotice(entry: Notice) if entry.dead or entry.leaving then return end entry.leaving = true local fade = TweenService:Create(entry.frame, TweenInfo.new(0.18, Enum.EasingStyle.Quad, Enum.EasingDirection.In), { GroupTransparency = 1 }) entry.exit = fade fade.Completed:Once(function() clearNotice(entry) end) fade:Play() end local function pushNotice(title, detail, kind) if not state.active then return end for index = #activeNotices, 1, -1 do if activeNotices[index].title == title then clearNotice(activeNotices[index]) end end if #activeNotices >= 3 then clearNotice(activeNotices[1]) end noticeSerial += 1 local frame = createGui("CanvasGroup", noticeDock, { Name = "Notice", Size = UDim2.fromOffset(304, 70), BackgroundColor3 = colour.base, BackgroundTransparency = 0, BorderSizePixel = 0, ClipsDescendants = true, GroupTransparency = 1, LayoutOrder = noticeSerial, ZIndex = 61, }) setCorner(frame, 8) addBorder(frame) local tint = kind == "error" and colour.danger or (kind == "off" and colour.muted or colour.accent) local status = createGui("Frame", frame, { BackgroundColor3 = tint, BorderSizePixel = 0, Position = UDim2.fromOffset(14, 25), Size = UDim2.fromOffset(7, 7), ZIndex = 62, }) setCorner(status, 3) addLabel(frame, title, 31, 9, 259, 23, 14, colour.text, true).ZIndex = 62 addLabel(frame, detail, 31, 32, 260, 19, 12, colour.muted).ZIndex = 62 local track = createGui("Frame", frame, { BackgroundColor3 = colour.border, BorderSizePixel = 0, Position = UDim2.fromOffset(14, 61), Size = UDim2.fromOffset(276, 3), ZIndex = 62, }) setCorner(track, 2) local bar = createGui("Frame", track, { BackgroundColor3 = tint, BorderSizePixel = 0, Size = UDim2.fromScale(0, 1), ZIndex = 63, }) local entry: Notice = { title = title, frame = frame, dead = false, leaving = false, enter = nil, progress = nil, exit = nil } table.insert(activeNotices, entry) local enter = TweenService:Create(frame, TweenInfo.new(0.16, Enum.EasingStyle.Quad, Enum.EasingDirection.Out), { GroupTransparency = 0 }) entry.enter = enter enter:Play() task.delay(0.16, function() if entry.dead or not state.active then return end local lifetime = kind == "error" and 3.8 or 3 local progress = TweenService:Create(bar, TweenInfo.new(lifetime, Enum.EasingStyle.Linear, Enum.EasingDirection.Out), { Size = UDim2.fromScale(1, 1) }) entry.progress = progress progress:Play() task.delay(lifetime, function() if entry.dead or not state.active then return end dismissNotice(entry) end) end) end state.toast = pushNotice local modal = createGui("TextButton", screen, { Name = "MouseInput", Text = "", Active = true, Modal = true, BackgroundTransparency = 1, AutoButtonColor = false, Size = UDim2.fromScale(1, 1), Visible = false, }) local window = createGui("Frame", screen, { Name = "Window", AnchorPoint = Vector2.new(0.5, 0.5), Position = UDim2.fromScale(0.5, 0.5), Size = UDim2.fromOffset(400, 520), BackgroundColor3 = colour.backdrop, BorderSizePixel = 0, Active = true, }) setCorner(window, 10) addBorder(window) local scaler = createGui("UIScale", window, { Scale = 1 }) local function fitViewport() local camera = workspace.CurrentCamera local view = camera and camera.ViewportSize or Vector2.new(1280, 720) scaler.Scale = math.min(1, (view.X - 24) / 400, (view.Y - 24) / 520) noticeScale.Scale = math.min(1, (view.X - 24) / 304) end local cameraConnection local function bindViewport() if cameraConnection then cameraConnection:Disconnect() end local camera = workspace.CurrentCamera if camera then cameraConnection = connect(camera:GetPropertyChangedSignal("ViewportSize"), fitViewport) end fitViewport() end connect(workspace:GetPropertyChangedSignal("CurrentCamera"), bindViewport) bindViewport() local header = createGui("Frame", window, { BackgroundTransparency = 1, Size = UDim2.fromOffset(400, 70), Active = true, }) addLabel(header, "YS HUB", 20, 16, 275, 34, 22, colour.text, true) local minimise = createGui("TextButton", header, { Name = "Minimise", Text = "", AutoButtonColor = false, BackgroundTransparency = 1, BorderSizePixel = 0, Position = UDim2.fromOffset(336, 13), Size = UDim2.fromOffset(44, 44), }) createGui("Frame", minimise, { BackgroundColor3 = colour.text, BorderSizePixel = 0, Position = UDim2.fromOffset(15, 21), Size = UDim2.fromOffset(14, 2), }) createGui("Frame", window, { BackgroundColor3 = colour.border, BorderSizePixel = 0, Position = UDim2.fromOffset(20, 69), Size = UDim2.fromOffset(360, 1), }) local navRail = createGui("Frame", window, { Name = "Navigation", BackgroundTransparency = 1, BorderSizePixel = 0, Position = UDim2.fromOffset(20, 80), Size = UDim2.fromOffset(360, 46), }) local tabPages = {} local tabButtons = {} local currentTab = 1 for index, name in { "Main", "Settings" } do local button = createGui("TextButton", navRail, { Name = name .. "Tab", Text = name, AutoButtonColor = false, Font = Enum.Font.GothamBold, TextSize = 13, TextColor3 = colour.muted, TextXAlignment = Enum.TextXAlignment.Center, BackgroundTransparency = 1, BorderSizePixel = 0, Position = UDim2.fromOffset(5 + (index - 1) * 177, 5), Size = UDim2.fromOffset(173, 36), }) local underline = createGui("Frame", button, { Name = "Selection", BackgroundColor3 = colour.accent, BorderSizePixel = 0, Position = UDim2.new(0, 12, 1, -2), Size = UDim2.new(1, -24, 0, 2), Visible = index == 1, }) local tab = { button = button, underline = underline, hovered = false, focused = false } tabButtons[index] = tab tabPages[index] = createGui("Frame", window, { Name = name .. "Page", BackgroundTransparency = 1, Position = UDim2.fromOffset(0, 136), Size = UDim2.fromOffset(400, 332), Visible = index == 1, }) end local deviceMenu = createGui("Frame", window, { Name = "DeviceOptions", BackgroundColor3 = colour.surface, BorderSizePixel = 0, Position = UDim2.fromOffset(20, 228), Size = UDim2.fromOffset(360, 186), Visible = false, ZIndex = 30, }) setCorner(deviceMenu, 7) addBorder(deviceMenu) local deviceChevron local function closeDeviceMenu() deviceMenuOpen = false deviceMenu.Visible = false if deviceChevron then deviceChevron.Rotation = 0 end end local function renderToggle(control: ToggleRow, immediate: boolean) local enabled = control.read() if control.tween then control.tween:Cancel() end if control.trackTween then control.trackTween:Cancel() end local thumbPosition = UDim2.fromOffset(enabled and 25 or 4, 4) local fill = enabled and colour.accentDark or colour.border if immediate then control.thumb.Position = thumbPosition control.track.BackgroundColor3 = fill else local thumbTween = TweenService:Create(control.thumb, TweenInfo.new(0.13, Enum.EasingStyle.Quad, Enum.EasingDirection.Out), { Position = thumbPosition }) local trackTween = TweenService:Create(control.track, TweenInfo.new(0.13, Enum.EasingStyle.Quad, Enum.EasingDirection.Out), { BackgroundColor3 = fill }) control.tween, control.trackTween = thumbTween, trackTween thumbTween:Play() trackTween:Play() end end local function addToggleRow(page: GuiObject, y: number, heading: string, description: string, read: () -> boolean, write: (boolean) -> ()) local button = createGui("TextButton", page, { Name = heading .. "Toggle", Text = "", AutoButtonColor = false, BackgroundColor3 = colour.hover, BackgroundTransparency = 1, BorderSizePixel = 0, Position = UDim2.fromOffset(20, y), Size = UDim2.fromOffset(360, 63), }) setCorner(button, 5) connect(button.MouseEnter, function() if state.active then button.BackgroundTransparency = 0 end end) connect(button.MouseLeave, function() button.BackgroundTransparency = 1 end) addLabel(button, heading, 14, 10, 266, 24, 13, colour.text, true) addLabel(button, description, 14, 34, 277, 18, 12, colour.muted) local track = createGui("Frame", button, { BackgroundColor3 = colour.border, BorderSizePixel = 0, Position = UDim2.fromOffset(300, 19), Size = UDim2.fromOffset(47, 26), }) setCorner(track, 13) local thumb = createGui("Frame", track, { BackgroundColor3 = colour.text, BorderSizePixel = 0, Position = UDim2.fromOffset(4, 4), Size = UDim2.fromOffset(18, 18), }) setCorner(thumb, 9) local control: ToggleRow = { read = read, write = write, track = track, thumb = thumb, tween = nil, trackTween = nil } table.insert(toggleRows, control) connect(button.Activated, function() if not state.active then return end write(not read()) for _, item in toggleRows do renderToggle(item, false) end end) renderToggle(control, true) end local renderKeybinds local function renderTab(index) local tab = tabButtons[index] local selected = index == currentTab local button = tab.button button.BackgroundTransparency = 1 button.TextColor3 = selected and colour.text or ((tab.hovered or tab.focused) and colour.text or colour.muted) button.Font = selected and Enum.Font.GothamBold or Enum.Font.GothamMedium tab.underline.Visible = selected tab.underline.BackgroundColor3 = tab.focused and colour.text or colour.accent end local function selectTab(index) currentTab = index closeDeviceMenu() bindingField = nil if renderKeybinds then renderKeybinds() end for i in tabButtons do tabPages[i].Visible = i == index renderTab(i) end end for index, tab in tabButtons do connect(tab.button.Activated, function() selectTab(index) end) connect(tab.button.MouseEnter, function() tab.hovered = true renderTab(index) end) connect(tab.button.MouseLeave, function() tab.hovered = false renderTab(index) end) connect(tab.button.SelectionGained, function() tab.focused = true renderTab(index) end) connect(tab.button.SelectionLost, function() tab.focused = false renderTab(index) end) end selectTab(1) local main = tabPages[1] addLabel(main, "Targeting", 22, 3, 276, 20, 12, colour.muted, true) local aimGroup = createGui("Frame", main, { Name = "TargetSettings", BackgroundColor3 = colour.base, BorderSizePixel = 0, Position = UDim2.fromOffset(20, 31), Size = UDim2.fromOffset(360, 134), }) setCorner(aimGroup, 8) createGui("Frame", aimGroup, { BackgroundColor3 = colour.border, BorderSizePixel = 0, Position = UDim2.fromOffset(14, 67), Size = UDim2.fromOffset(332, 1), }) addToggleRow(main, 32, "Silent Aim", "Prioritises targets in sight", function() return state.enabled end, function(enabled) aim.set(enabled) pushNotice("Silent Aim", enabled and "Enabled" or "Disabled", enabled and "on" or "off") end) addToggleRow(main, 100, "Triggerbot", "Fires at targets with panel hidden", function() return state.triggerbot end, function(enabled) setTriggerbot(enabled) pushNotice("Triggerbot", enabled and "Enabled" or "Disabled", enabled and "on" or "off") end) addLabel(main, "Device", 22, 179, 280, 20, 12, colour.muted, true) local deviceGroup = createGui("Frame", main, { Name = "DeviceSettings", BackgroundColor3 = colour.base, BorderSizePixel = 0, Position = UDim2.fromOffset(20, 204), Size = UDim2.fromOffset(360, 126), }) setCorner(deviceGroup, 8) createGui("Frame", deviceGroup, { BackgroundColor3 = colour.border, BorderSizePixel = 0, Position = UDim2.fromOffset(14, 65), Size = UDim2.fromOffset(332, 1), }) addToggleRow(main, 205, "Device Spoofer", "Reports a chosen input device", function() return deviceReport ~= nil end, function(enabled) if enabled then local sent, err = pcall(enableDeviceReport) if not sent then restoreDeviceReport() warn("Device report failed: " .. tostring(err)) pushNotice("Device Spoofer", "Could not send device", "error") else pushNotice("Device Spoofer", "Spoofed to: " .. state.deviceLabel, "on") end else restoreDeviceReport() pushNotice("Device Spoofer", "Disabled", "off") end end) local deviceButton = createGui("TextButton", main, { Name = "ReportedDevice", Text = "", AutoButtonColor = false, BackgroundColor3 = colour.surface, BorderSizePixel = 0, Position = UDim2.fromOffset(28, 278), Size = UDim2.fromOffset(344, 44), }) setCorner(deviceButton, 5) connect(deviceButton.MouseEnter, function() deviceButton.BackgroundColor3 = colour.hover end) connect(deviceButton.MouseLeave, function() deviceButton.BackgroundColor3 = colour.surface end) addLabel(deviceButton, "Report as", 14, 2, 268, 17, 12, colour.muted) local deviceChoice = addLabel(deviceButton, "", 14, 18, 270, 21, 14, colour.text, true) deviceChevron = createGui("ImageLabel", deviceButton, { Name = "DeviceChevron", BackgroundTransparency = 1, Image = "rbxassetid://71457658246709", ImageColor3 = colour.muted, ScaleType = Enum.ScaleType.Fit, AnchorPoint = Vector2.new(0.5, 0.5), Position = UDim2.fromOffset(321, 22), Size = UDim2.fromOffset(18, 18), }) local deviceOptions: { [string]: { button: TextButton, dot: Frame } } = {} local function renderDeviceChoices() deviceChoice.Text = state.deviceLabel for name, row in deviceOptions do local selected = name == state.deviceLabel row.button.BackgroundColor3 = selected and colour.accentDark or colour.surface row.dot.Visible = selected end end for index, name in { "Mobile", "Tablet", "Desktop", "Gamepad" } do local button = createGui("TextButton", deviceMenu, { Name = name, Text = name, Font = Enum.Font.Gotham, TextSize = 13, TextColor3 = colour.text, TextXAlignment = Enum.TextXAlignment.Left, AutoButtonColor = false, BackgroundColor3 = colour.surface, BorderSizePixel = 0, Position = UDim2.fromOffset(6, 5 + (index - 1) * 44), Size = UDim2.fromOffset(348, 43), ZIndex = 31, }) createGui("UIPadding", button, { PaddingLeft = UDim.new(0, 14) }) setCorner(button, 5) local dot = createGui("Frame", button, { BackgroundColor3 = colour.accent, BorderSizePixel = 0, Position = UDim2.fromOffset(312, 17), Size = UDim2.fromOffset(8, 8), Visible = false, ZIndex = 32, }) setCorner(dot, 4) deviceOptions[name] = { button = button, dot = dot } connect(button.Activated, function() state.deviceLabel = name local reported = not deviceReport or deviceReport.report() renderDeviceChoices() closeDeviceMenu() if not reported then pushNotice("Device Spoofer", "Could not send device", "error") elseif deviceReport then pushNotice("Device Spoofer", "Spoofed to: " .. name, "on") else pushNotice("Device Spoofer", "Selected: " .. name, "off") end end) end renderDeviceChoices() connect(deviceButton.Activated, function() deviceMenuOpen = not deviceMenuOpen deviceMenu.Visible = deviceMenuOpen deviceChevron.Rotation = deviceMenuOpen and 180 or 0 end) local settings = tabPages[2] addLabel(settings, "Keybinds", 22, 3, 250, 20, 12, colour.muted, true) local keyGroup = createGui("Frame", settings, { Name = "KeybindSettings", BackgroundColor3 = colour.base, BorderSizePixel = 0, Position = UDim2.fromOffset(20, 30), Size = UDim2.fromOffset(360, 143), }) setCorner(keyGroup, 8) for index = 1, 2 do createGui("Frame", keyGroup, { BackgroundColor3 = colour.border, BorderSizePixel = 0, Position = UDim2.fromOffset(14, index * 47), Size = UDim2.fromOffset(332, 1), }) end local bindingHint = addLabel(settings, "Esc cancels. End unloads.", 22, 178, 350, 18, 12, colour.muted) local function boundKey(field) return state[field] end renderKeybinds = function() for field, button in keybindButtons do local key = boundKey(field) button.Text = bindingField == field and "Press key" or key.Name button.BackgroundColor3 = bindingField == field and colour.accentDark or colour.surface end end for index, info in { { "menuKey", "Window", "Show or hide the panel" }, { "aimKey", "Silent Aim", "Toggle silent aim" }, { "triggerKey", "Triggerbot", "Toggle automatic firing" }, } do local y = 31 + (index - 1) * 47 addLabel(settings, info[2], 32, y, 225, 23, 13, colour.text, true) addLabel(settings, info[3], 32, y + 22, 225, 18, 12, colour.muted) local button = createGui("TextButton", settings, { Name = info[1], Text = "", Font = Enum.Font.GothamBold, TextSize = 12, TextColor3 = colour.text, BackgroundColor3 = colour.surface, BorderSizePixel = 0, AutoButtonColor = false, Position = UDim2.fromOffset(263, y + 4), Size = UDim2.fromOffset(105, 40), }) setCorner(button, 5) keybindButtons[info[1]] = button connect(button.Activated, function() bindingField = info[1] bindingHint.Text = "Press a key. Esc cancels." bindingHint.TextColor3 = colour.muted renderKeybinds() end) end addLabel(settings, "Mouse", 22, 206, 225, 20, 12, colour.muted, true) local mouseGroup = createGui("Frame", settings, { Name = "MouseSettings", BackgroundColor3 = colour.base, BorderSizePixel = 0, Position = UDim2.fromOffset(20, 227), Size = UDim2.fromOffset(360, 63), }) setCorner(mouseGroup, 8) addToggleRow(settings, 227, "Lock Mouse", "Free cursor while the panel is open", function() return state.lockMouse end, function(enabled) state.lockMouse = enabled if state.updateMouse then state.updateMouse() end pushNotice("Lock Mouse", enabled and "Enabled" or "Disabled", enabled and "on" or "off") end) local unload = createGui("TextButton", settings, { Name = "Unload", Text = "Unload script", AutoButtonColor = false, Font = Enum.Font.GothamBold, TextSize = 13, TextColor3 = colour.danger, BackgroundColor3 = colour.backdrop, BorderSizePixel = 0, Position = UDim2.fromOffset(20, 296), Size = UDim2.fromOffset(360, 36), }) setCorner(unload, 7) connect(unload.Activated, function() state.unload() end) renderKeybinds() createGui("Frame", window, { BackgroundColor3 = colour.border, BorderSizePixel = 0, Position = UDim2.fromOffset(20, 478), Size = UDim2.fromOffset(360, 1), }) local footer = addLabel(window, "", 20, 486, 360, 24, 12, colour.muted) local function renderFooter() footer.Text = state.menuKey.Name .. " - hide/show ui End - unload" end renderFooter() local reopen = createGui("TextButton", screen, { Name = "Open", Text = "YS", Font = Enum.Font.GothamBold, TextSize = 14, TextColor3 = colour.accent, AutoButtonColor = false, BackgroundColor3 = colour.base, BorderSizePixel = 0, Position = UDim2.new(0, 14, 0.5, -22), Size = UDim2.fromOffset(52, 44), Visible = false, }) setCorner(reopen, 8) addBorder(reopen) local function restoreCursor() modal.Visible = false if not cursor.bound then return end RunService:UnbindFromRenderStep(cursorStep) cursor.bound = false if not GuiService.MenuIsOpen then if UserInputService.MouseBehavior == Enum.MouseBehavior.Default then UserInputService.MouseBehavior = cursor.behavior end UserInputService.MouseIconEnabled = cursor.visible end end local function syncCursor() local useCursor = state.active and state.uiVisible and state.lockMouse and not GuiService.MenuIsOpen if not useCursor then restoreCursor() return end modal.Visible = true if cursor.bound then return end cursor.behavior = UserInputService.MouseBehavior cursor.visible = UserInputService.MouseIconEnabled cursor.bound = true RunService:BindToRenderStep(cursorStep, Enum.RenderPriority.Last.Value + 1, function() if state.active and state.uiVisible and state.lockMouse and not GuiService.MenuIsOpen then UserInputService.MouseBehavior = Enum.MouseBehavior.Default UserInputService.MouseIconEnabled = true end end) UserInputService.MouseBehavior = Enum.MouseBehavior.Default UserInputService.MouseIconEnabled = true end state.updateMouse = syncCursor local function setWindowVisible(visible) if visible then releaseTrigger() end state.uiVisible = visible window.Visible = visible reopen.Visible = not visible if not visible then closeDeviceMenu() bindingField = nil dragInput = nil renderKeybinds() end syncCursor() end connect(minimise.Activated, function() setWindowVisible(false) end) connect(reopen.Activated, function() setWindowVisible(true) end) state.uiSync = function() for _, control in toggleRows do renderToggle(control, false) end end state.uiDestroy = function() restoreCursor() for index = #activeNotices, 1, -1 do clearNotice(activeNotices[index]) end for _, connection in uiConnections do connection:Disconnect() end for _, control in toggleRows do if control.tween then control.tween:Cancel() end if control.trackTween then control.trackTween:Cancel() end end state.updateMouse = nil state.uiSync = nil state.toast = nil state.uiDestroy = nil screen:Destroy() end local function containsPoint(object: GuiObject, position: Vector2) local p, size = object.AbsolutePosition, object.AbsoluteSize return position.X >= p.X and position.X <= p.X + size.X and position.Y >= p.Y and position.Y <= p.Y + size.Y end connect(UserInputService.InputBegan, function(input, processed) local kind = input.UserInputType if deviceMenuOpen and (kind == Enum.UserInputType.MouseButton1 or kind == Enum.UserInputType.Touch) then local position = Vector2.new(input.Position.X, input.Position.Y) if not containsPoint(deviceMenu, position) and not containsPoint(deviceButton, position) then closeDeviceMenu() end end if kind ~= Enum.UserInputType.Keyboard then return end local key = input.KeyCode if bindingField then if key == Enum.KeyCode.Escape then bindingField = nil bindingHint.Text = "Esc cancels. End unloads." bindingHint.TextColor3 = colour.muted elseif key == Enum.KeyCode.End or key.Name == "Unknown" then bindingHint.Text = "That key is reserved." bindingHint.TextColor3 = colour.danger else local conflict = false for _, field in { "menuKey", "aimKey", "triggerKey" } do if field ~= bindingField and state[field] == key then conflict = true break end end if conflict then bindingHint.Text = "That key is already assigned." bindingHint.TextColor3 = colour.danger else state[bindingField] = key bindingField = nil bindingHint.Text = "Esc cancels. End unloads." bindingHint.TextColor3 = colour.muted renderFooter() end end renderKeybinds() return end if processed or UserInputService:GetFocusedTextBox() then return end if key == state.menuKey then setWindowVisible(not state.uiVisible) elseif key == state.aimKey then aim.set(not state.enabled) if state.uiSync then state.uiSync() end pushNotice("Silent Aim", state.enabled and "Enabled" or "Disabled", state.enabled and "on" or "off") elseif key == state.triggerKey then setTriggerbot(not state.triggerbot) if state.uiSync then state.uiSync() end pushNotice("Triggerbot", state.triggerbot and "Enabled" or "Disabled", state.triggerbot and "on" or "off") elseif key == Enum.KeyCode.End then state.unload() end end) connect(UserInputService.InputChanged, function(input) if not dragInput or not state.uiVisible then return end local touch = dragInput.UserInputType == Enum.UserInputType.Touch if (touch and input ~= dragInput) or (not touch and input.UserInputType ~= Enum.UserInputType.MouseMovement) then return end local camera = workspace.CurrentCamera if not camera then return end local position = Vector2.new(input.Position.X, input.Position.Y) local delta = position - lastPointer local size = window.AbsoluteSize local centre = window.AbsolutePosition + size * 0.5 + delta local view = camera.ViewportSize window.Position = UDim2.fromOffset( math.clamp(centre.X, size.X * 0.5, math.max(size.X * 0.5, view.X - size.X * 0.5)), math.clamp(centre.Y, size.Y * 0.5, math.max(size.Y * 0.5, view.Y - size.Y * 0.5)) ) lastPointer = position end) connect(UserInputService.InputEnded, function(input) if dragInput and (dragInput == input or (dragInput.UserInputType == Enum.UserInputType.MouseButton1 and input.UserInputType == Enum.UserInputType.MouseButton1)) then dragInput = nil end end) connect(header.InputBegan, function(input) if (input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch) and input.Position.X < minimise.AbsolutePosition.X then dragInput = input lastPointer = Vector2.new(input.Position.X, input.Position.Y) end end) connect(GuiService.MenuOpened, syncCursor) connect(GuiService.MenuClosed, syncCursor) connect(UserInputService.WindowFocused, syncCursor) connect(UserInputService.WindowFocusReleased, function() restoreCursor() dragInput = nil closeDeviceMenu() bindingField = nil bindingHint.Text = "Esc cancels. End unloads." bindingHint.TextColor3 = colour.muted renderKeybinds() end) setWindowVisible(true) return true end function state.unload(_silent: boolean?) if not state.active then return end state.active = false aim.set(false) setTriggerbot(false) local destroy = state.uiDestroy if destroy then destroy() end for index = #state.connections, 1, -1 do state.connections[index]:Disconnect() state.connections[index] = nil end restoreDeviceReport() if ClientShootable.Shoot == shootWithTarget then ClientShootable.Shoot = originalShoot else warn("Shoot belongs to another owner") end if getupvalue(originalShoot, originIndex) == redirectedOrigin then setupvalue(originalShoot, originIndex, originalOrigin) else warn("Combat origin belongs to another owner") end if env.__aimSession == state then env.__aimSession = nil end end setupvalue(originalShoot, originIndex, redirectedOrigin) assert(getupvalue(originalShoot, originIndex) == redirectedOrigin, "Could not install the combat origin redirect") ClientShootable.Shoot = shootWithTarget env.__aimSession = state local taken = {} local function savedKey(field, fallback) local candidate = previousSession and previousSession[field] if typeof(candidate) ~= "EnumItem" or tostring(candidate.EnumType) ~= "Enum.KeyCode" or candidate.Name == "Unknown" or candidate.Name == "End" or candidate.Name == "Escape" or taken[candidate.Name] then candidate = fallback end if field == "aimKey" and candidate.Name == "F6" then candidate = Enum.KeyCode.V end if taken[candidate.Name] then for _, option in { Enum.KeyCode.RightShift, Enum.KeyCode.V, Enum.KeyCode.T, Enum.KeyCode.B } do if not taken[option.Name] then candidate = option break end end end taken[candidate.Name] = true return candidate end state.menuKey = savedKey("menuKey", Enum.KeyCode.RightShift) state.aimKey = savedKey("aimKey", Enum.KeyCode.V) state.triggerKey = savedKey("triggerKey", Enum.KeyCode.T) local priorDevice = previousSession and previousSession.deviceLabel if priorDevice == "Mobile" or priorDevice == "Tablet" or priorDevice == "Desktop" or priorDevice == "Gamepad" then state.deviceLabel = priorDevice end state.uiVisible = true if previousSession and type(previousSession.lockMouse) == "boolean" then state.lockMouse = previousSession.lockMouse end aim.set(state.enabled) setTriggerbot(true) local deviceReportStarted, deviceReportError = pcall(enableDeviceReport) if not deviceReportStarted then restoreDeviceReport() warn("Device report unavailable: " .. tostring(deviceReportError)) end local mounted, mountError = pcall(mountHub) if not mounted then state.unload(true) warn("YS HUB window failed: " .. tostring(mountError)) notify("YS HUB", "Window could not open: " .. tostring(mountError), 10) return end