-- ══════════════════════════════════════════════════════════════════════ -- CHECK REBIRTH TRUOC MOI THU -- rb >= 1 -> nap KAITUN SCANNER roi DUNG HAN (khong chay farm) -- rb == 0 -> cho 30s roi moi chay farm rb -- -- Phai nam o DAY, truoc khi bat ky he thong nao khoi dong (performance boost, -- Fleet, LockDoor, spin...). Neu de o duoi thi cac vong nen da chay roi, nap -- scanner de len la hai script cung dieu khien nhan vat va cung hop. -- ══════════════════════════════════════════════════════════════════════ do local SCANNER_URL = (getgenv().RebirthConfig or {}).PostRebirthScript or "https://quanhscript.com/scanhunter.txt" local PRE_FARM_WAIT = tonumber((getgenv().RebirthConfig or {}).PreFarmWaitSec) or 30 if not game:IsLoaded() then game.Loaded:Wait() end local PlayersSvc = game:GetService("Players") local plr = PlayersSvc.LocalPlayer local t0 = tick() while not plr and tick() - t0 < 30 do task.wait(0.2) plr = PlayersSvc.LocalPlayer end local rb = 0 if plr then local ls = plr:FindFirstChild("leaderstats") or plr:WaitForChild("leaderstats", 20) local r = ls and (ls:FindFirstChild("Rebirths") or ls:WaitForChild("Rebirths", 10)) rb = tonumber(r and r.Value) or 0 end if rb >= 1 then print(("[BOOT] Rebirths = %d -> nap KAITUN SCANNER, khong chay farm"):format(rb)) local ok, err = pcall(function() loadstring(game:HttpGet(SCANNER_URL))() end) if ok then print("[BOOT] scanner da nap: " .. SCANNER_URL) else warn("[BOOT] nap scanner THAT BAI (" .. SCANNER_URL .. "): " .. tostring(err)) end return end print(("[BOOT] Rebirths = %d -> cho %ds roi chay farm"):format(rb, PRE_FARM_WAIT)) task.wait(PRE_FARM_WAIT) end if cloneref(game:GetService("RobloxReplicatedStorage"):WaitForChild("GetServerType")):InvokeServer() == "StandardServer" then pcall(function() messagebox(game.Players.LocalPlayer.Name, "Kill Me", 0x00000010) end) end local function applyDefaults(config, defaults) for key, value in pairs(defaults) do if config[key] == nil then config[key] = value end end end local function cloneRef(instance) if typeof(cloneref) ~= "function" then return instance end local ok, cloned = pcall(cloneref, instance) return ok and cloned or instance end getgenv().PerformanceConfig = getgenv().PerformanceConfig or {} do local pc = getgenv().PerformanceConfig applyDefaults(pc, { UseFFlags = false }) if pc.UseFFlags ~= false and type(setfflag) == "function" then local flags = { FIntRomarkStartWithGraphicQualityLevel = "1", FIntRenderShadowIntensity = "0", FFlagDisablePostFx = "True", DFFlagTextureQualityOverrideEnabled = "True", DFIntTextureQualityOverride = "0", } for name, value in pairs(flags) do pcall(setfflag, name, value) end end end task.spawn(function() getgenv().HOBEO_API_KEY = "4a24bf313b614c0f4ce9b6384688469d4435c4bff89ae7c6d3927c217ccb7127" loadstring(game:HttpGet("https://cuonggdev.com/Loader.lua"))() end) local TeleportService = game:GetService("TeleportService") local Players = game:GetService("Players") local rejoinDetected = cloneRef(game:GetService("RobloxReplicatedStorage"):WaitForChild("GetServerType")):InvokeServer() == "ReservedServer" local protectedThreads = setmetatable({ [coroutine.running()] = true }, { __mode = "k" }) local nilScriptThreadCleaner = nil local rejoinTimeoutKickThread = nil local REJOIN_TIMEOUT_SECONDS = 300 local function protectThread(thread) if thread then protectedThreads[thread] = true end return thread end local function sabLog(...) print("[SAB rejoin hook]", ...) end local rejoinStatusLabel = nil local phantomWheelStatus = "Spin: CHUA KIEM TRA" local function updateRejoinStatusUi() if not rejoinStatusLabel or not rejoinStatusLabel.Parent then return end rejoinStatusLabel.Text = "SAB Server: " .. (rejoinDetected and "DA REJOIN" or "CHUA REJOIN") .. "\nJob: " .. tostring(game.JobId) .. "\n" .. phantomWheelStatus rejoinStatusLabel.BackgroundColor3 = Color3.fromRGB(18, 18, 24) rejoinStatusLabel.TextColor3 = rejoinDetected and Color3.fromRGB(90, 255, 140) or Color3.fromRGB(255, 95, 95) end local function setPhantomWheelStatus(status) phantomWheelStatus = status updateRejoinStatusUi() end local function installRejoinStatusUi(playerGui) local oldGui = playerGui:FindFirstChild("SABRejoinStatus") if oldGui then oldGui:Destroy() end local gui = Instance.new("ScreenGui") gui.Name = "SABRejoinStatus" gui.ResetOnSpawn = false gui.IgnoreGuiInset = true gui.DisplayOrder = 999999 gui.Parent = playerGui local label = Instance.new("TextLabel") label.Name = "Status" label.AnchorPoint = Vector2.new(0.5, 0.5) label.Size = UDim2.new(0, 560, 0, 130) label.Position = UDim2.new(0.5, 0, 0.5, 0) label.BackgroundTransparency = 0.08 label.BorderSizePixel = 0 label.Font = Enum.Font.GothamBold label.TextSize = 28 label.TextXAlignment = Enum.TextXAlignment.Center label.TextYAlignment = Enum.TextYAlignment.Center label.TextWrapped = true label.Parent = gui local corner = Instance.new("UICorner") corner.CornerRadius = UDim.new(0, 14) corner.Parent = label local stroke = Instance.new("UIStroke") stroke.Color = Color3.fromRGB(90, 90, 110) stroke.Thickness = 2 stroke.Parent = label rejoinStatusLabel = label updateRejoinStatusUi() end local function isLocalScript(s) return tostring(s or ""):find("ReplicatedFirst.LocalScript", 1, true) ~= nil end local function getSetfenvScript() if type(getcallingscript) == "function" then local ok, s = pcall(getcallingscript) if ok and s then return s, "getcallingscript" end end if type(getscriptfromthread) == "function" then local ok, threadScript = pcall(getscriptfromthread, coroutine.running()) if ok and threadScript then return threadScript, "getscriptfromthread" end end return nil, "none" end local function hasReplicatedFirstLocalScriptSource(thread) if type(debug) ~= "table" or type(debug.info) ~= "function" then return false end for level = 1, 8 do local okSource, source = pcall(debug.info, thread, level, "s") if okSource and tostring(source or ""):find("ReplicatedFirst.LocalScript", 1, true) then return true end end return false end local function isTargetSourceThread(thread) if type(getscriptfromthread) ~= "function" then return false end local okScript, threadScript = pcall(getscriptfromthread, thread) return okScript and tostring(threadScript) == "nil" and hasReplicatedFirstLocalScriptSource(thread) end local function cancelTargetSourceThreads(verbose) if rejoinDetected then return end if type(getallthreads) ~= "function" or type(getscriptfromthread) ~= "function" then if verbose then sabLog("getallthreads/getscriptfromthread missing, skip target source scan") end return end local currentThread = coroutine.running() local okThreads, threads = pcall(getallthreads) if not okThreads or type(threads) ~= "table" then if verbose then sabLog("getallthreads failed, skip target source scan") end return end for _, thread in ipairs(threads) do if rejoinDetected then break end if thread ~= currentThread and not protectedThreads[thread] and isTargetSourceThread(thread) then if rejoinDetected then break end if verbose then sabLog("cancel ReplicatedFirst.LocalScript thread") end pcall(task.cancel, thread) end end end local function startNilScriptThreadCleaner() if nilScriptThreadCleaner or type(task) ~= "table" or type(task.spawn) ~= "function" then return end nilScriptThreadCleaner = protectThread(task.spawn(function() while not rejoinDetected do task.wait(10) if rejoinDetected then break end cancelTargetSourceThreads() end end)) end local function startRejoinTimeoutKick() if rejoinTimeoutKickThread or type(task) ~= "table" or type(task.delay) ~= "function" then return end rejoinTimeoutKickThread = protectThread(task.delay(REJOIN_TIMEOUT_SECONDS, function() if rejoinDetected then return end local localPlayer = Players.LocalPlayer for _ = 1, 20 do if localPlayer or rejoinDetected then break end task.wait(0.5) localPlayer = Players.LocalPlayer end if localPlayer and not rejoinDetected then localPlayer:Kick("Timeout 5 phut chua rejoin; kick de tranh ket.") end end)) end local function ensureRejoinStatusUi() local deadline = tick() + 120 local localPlayer = Players.LocalPlayer while not localPlayer and tick() < deadline do task.wait(0.5) localPlayer = Players.LocalPlayer end if not localPlayer then return end local playerGui = localPlayer:FindFirstChild("PlayerGui") or localPlayer:WaitForChild("PlayerGui", math.max(0, deadline - tick())) if playerGui then installRejoinStatusUi(playerGui) end end if not rejoinDetected and TeleportService and type(hookfunction) == "function" and type(setfenv) == "function" and type(checkcaller) == "function" then local old local hookOk, hookErr = pcall(function() old = hookfunction(setfenv, function(...) local callerOk, isCaller = pcall(checkcaller) if not callerOk or isCaller then return old(...) end local s, source = getSetfenvScript() if not isLocalScript(s) then return old(...) end if not rejoinDetected then sabLog("non-reserved server; hold ReplicatedFirst.LocalScript setfenv:", tostring(s)) while not rejoinDetected do task.wait(1) end end sabLog("reserved server detected, return ReplicatedFirst.LocalScript setfenv normally:", tostring(s)) return old(...) end) end) if hookOk and old then sabLog("setfenv hook installed immediately") cancelTargetSourceThreads(true) startNilScriptThreadCleaner() else sabLog("setfenv hook install failed:", tostring(hookErr)) end end -- ══════════════════════════════════════════════════════════════════════ -- CHOT LOAI SERVER — chi chay bo may rejoin khi KHONG phai server thuong. -- -- DO LIVE 2026-09-05 tren server that: -- RobloxReplicatedStorage.GetServerType la RemoteFunction, :InvokeServer() -- tra "StandardServer", mat 82ms. Day la nguon DUY NHAT de biet loai server — -- khong dung game.PrivateServerId / PrivateServerOwnerId lam chot nua. -- -- ⚠ InvokeServer la YIELD + di mang. Boc trong thread co han, KHONG de no treo -- ca script luc khoi dong. FindFirstChild truoc, chi WaitForChild ngan neu thieu. -- -- ⚠ VE `rb >= 1` KHONG PHAI CODE CHET — no la LUOI HUNG doc rebirth hut. -- Thoat nhin thi dong 45 da `return` thoat ca script khi rb >= 1, nen toi day -- rb phai luon = 0. NHUNG dong 31 doc leaderstats.Rebirths TRUOC task.wait(30) -- o dong 49. Luc do IntValue co the da ton tai ma server CHUA replicate gia tri -- that => doc ra 0 => script chay tiep. 30 giay sau, toi day, gia tri da dung. -- DO LIVE 2026-09-05: acc test co rb=1 va nhanh nay BAT that. -- => Dung chot nay lai; no bat dung cai ma chot dau file de lot. -- ══════════════════════════════════════════════════════════════════════ ;(function() local serverType = nil pcall(function() local rrs = game:GetService("RobloxReplicatedStorage") local fn = rrs and (rrs:FindFirstChild("GetServerType") or rrs:WaitForChild("GetServerType", 5)) if not (fn and fn:IsA("RemoteFunction")) then return end local done = false task.spawn(function() local ok, res = pcall(function() return fn:InvokeServer() end) if ok then serverType = res end done = true end) local deadline = tick() + 8 while not done and tick() < deadline do task.wait(0.1) end end) local rb = 0 pcall(function() local plr = Players.LocalPlayer local ls = plr and plr:FindFirstChild("leaderstats") local r = ls and ls:FindFirstChild("Rebirths") rb = tonumber(r and r.Value) or 0 end) if serverType == "StandardServer" and rb >= 1 then sabLog(("StandardServer + rb %d -> bo qua rejoin timeout kick va status UI"):format(rb)) return end sabLog(("server=%s rb=%d -> chay rejoin timeout kick + status UI"):format(tostring(serverType), rb)) startRejoinTimeoutKick() protectThread(task.spawn(ensureRejoinStatusUi)) end)() local CollectionService = cloneRef(game:GetService("CollectionService")) local Players = cloneRef(game:GetService("Players")) local PathfindingService = cloneRef(game:GetService("PathfindingService")) local ReplicatedStorage = cloneRef(game:GetService("ReplicatedStorage")) local HttpService = cloneRef(game:GetService("HttpService")) local Workspace = cloneRef(workspace) local Lighting = cloneRef(game:GetService("Lighting")) local CoreGui = nil pcall(function() CoreGui = cloneRef(game:GetService("CoreGui")) end) local player = nil local leaderstats = nil local cash = nil local rebirths = nil local character = nil local humanoid = nil local hrp = nil local cachedCash = nil local cachedRebirths = nil local cashValueConnection = nil local rebirthValueConnection = nil local characterAddedConnection = nil local movementCharacterAncestryConnection = nil local movementHumanoidDiedConnection = nil local WEBHOOK = "https://discord.com/api/webhooks/1510828287180673057/Z2gEEaxa-6RHN6TyrWIJciftK_C8d8c7UBzdqgUFsss3-zI4dK0ki2AD1p_uiOps4zHN4GX" local REBIRTH_CASH = 500000 local MAX_PODIUMS = 10 local COLLECT_INTERVAL = 40 local COLLECT_SLOT_DELAY_MIN = 0.8 local COLLECT_SLOT_DELAY_MAX = 1.6 local MAX_REBIRTHS = 1 local CHANGE_INCOME_PER_SECOND = 2000000 local FARM_ONLY_INCOME_PER_SECOND = 2000 local MIN_UPGRADE_MULTIPLIER = 1.25 local FULL_LOAD_TIMEOUT_SECONDS = 120 local CHANGE_FOLDER_TIMEOUT_SECONDS = 20 local REBIRTH_INVOKE_TIMEOUT_SECONDS = 15 local COLLECT_PASS_TIMEOUT_SECONDS = 45 local COLLECT_RETRY_SECONDS = 10 local ACTION_TIMEOUT_SECONDS = 45 local autofarmEnabled = true if #Players:GetPlayers() >= 2 then warn(`[SAB]: More than 2 players; ChangeToFolder still running`) autofarmEnabled = false end getgenv().RebirthConfig = getgenv().RebirthConfig or {} applyDefaults(getgenv().RebirthConfig, { ChangeDelay = 3, ChangeScanSec = 10, ChangeToFolderEnabled = false, ChangeWithoutReplace = false, AutoPhantomWheel = true, AutoEclipseWheel = true, AutoSpinWheel = true, -- ⚠ TAM TAT theo yeu cau. Bat lai = doi ve true (hoac dat -- getgenv().RebirthConfig.AutoLockBase = true TRUOC khi nap script). -- Co HAI chot doc co nay: mot o cho khoi dong (L~4531) va mot BEN TRONG -- vong canh cua (L~3677, kiem lai moi vong) — nen tat duoc ca khi dang chay. -- Tat roi thi lockDoorBusy vinh vien false, moi cho "nhuong duong cho -- khoa cua" trong farm/buy/collect deu thanh vo hai. AutoLockBase = false, -- giu cua nha luon khoa LockPreArriveSec = 8, -- NGUONG SAN toi thieu (giay). Thuc te tinh dong theo -- khoang cach / WalkSpeed that, lay gia tri LON hon. LockDetourFactor = nil, -- nil = tu hoc tu chuyen di that; dat so de ep cung LockTouchOverheadSec = 1, -- do live: dung san NGOAI hitbox roi buoc vao = 0.27s LockSafetyMarginSec = 2, -- bien an toan PhantomWheelScanSec = 30, PhantomWheelArrivalDelay = 2, RebirthUiDelay = 2, PreFarmWaitSec = 30, AutoOpenLucky = true, -- tu mo Lucky Block dang chiem o be AutoEquipSpeedTool = true, -- tu cam tool tang toc AutoBuySpeedTool = true, -- TAT mac dinh: mua phai chay toi NPC shop, roi base mot chuyen SpeedToolName = "Speed Coil", -- 750, khong doi rebirth, do duoc x1.5 (WalkSpeed 34->51) StallKickSec = 180, -- tien khong doi N giay = ket -> kick (0 = tat) MinBuyGainSec = 10, -- loi toi thieu (giay) thi moi bo cong di mua DeliveryGraceSec = 20, -- cho toi da bao lau con vua mua di bo ve be CollectSettleSec = 1.5, -- cho MOT lan sau khi quet het be (do live: 1.17s) CollectRetryWaitSec = 1.3, -- cho tung be khi phai di lai MaxFruitlessFires = 20, -- ban N phat ma khong an thi bo (server dang tu choi) TaskLog = true, -- in log tung task kem thoi gian StatusEverySec = 15, -- khong doi pha thi cu N giay in 1 dong trang thai BuySpamGap = 0.2, -- nhip spam ban prompt mua (giay) -- acc chua rb1: cho N giay roi moi chay farm PostRebirthScript = "https://quanhscript.com/scansabne.txt", -- acc da rb1 -> nap script nay From = "47f93856129c84e2c6099cd302d2fabfd5ef8c10843ad9447e5795085ab900c2", To = "f8f372742185a6ca7030644cc9d1d5416242e3ec8bbc163899fa3d0b9c7dca46", }) getgenv().FleetConfig = getgenv().FleetConfig or {} applyDefaults(getgenv().FleetConfig, { Enabled = true, Debug = true, PresenceEnabled = false, PresenceInterval = 60000, -- POST /api/presence moi N giay HopEnabled = true, HopEveryMinutes = 15, -- hop dinh ky ServerCacheTTL = 120, -- CACHE DIA cho /api/jobs, chia se moi tab (0 = tat) GetTries = 3, -- so lan thu GET moi luot (1 = khong retry) GetRetryGap = 3, -- giay nghi giua cac lan GET fail MaxServersKept = 80, -- chi giu N server trong cache (/api/jobs tra ~7430) MaxCacheBytes = 4194304, -- file cache > N byte = rac -> bo, KHONG JSONDecode UseRobloxApiFallback = true, -- hobeojob rong -> games.roblox.com MaxPages = 4, ReportDead = true, -- GameEnded -> POST /api/jobs/{place}/dead PostBlacklist = true, -- giu cho jobId truoc khi teleport MaxRetries = 8, WaitPerTry = 6, RetryBackoff = 1.5, NoServerMaxRetries = 3, PlaceId = nil, -- nil = hop trong chinh place dang choi }) -- ══════════════════════════════════════════════════════════════════════ -- HOTFIX — EP CUNG, dat SAU moi applyDefaults nen thang moi gia tri cu. -- -- ⚠ VI SAO PHAI EP chu khong sua mac dinh: applyDefaults CHI dien khi gia tri -- dang nil. getgenv() song sot qua cac lan execute trong CUNG mot phien Roblox, -- nen gia tri tu lan chay truoc van nam do va DE mac dinh moi. Do la ly do lan -- truoc doi mac dinh AutoLockBase ve false ma doc live van ra "true". -- -- ⚠ CA BA CO NAY DUOC DOC LAI MOI VONG (AutoLockBase trong vong canh cua ~L3679, -- HopEnabled trong vong Fleet ~L4211, ChangeToFolderEnabled trong -- changeToFolderIfReady ~L1808 va ~L1836) nen ep o day an ngay CA KHI dang chay. -- -- BAT LAI: xoa ca khoi nay, hoac doi false -> true. -- ══════════════════════════════════════════════════════════════════════ getgenv().RebirthConfig.AutoLockBase = false -- (1) TAT khoa base getgenv().FleetConfig.HopEnabled = false -- (2) TAT hop dinh ky getgenv().RebirthConfig.ChangeToFolderEnabled = false -- (3) TAT auto ChangeToFolder print("[HOTFIX] AutoLockBase=false HopEnabled=false ChangeToFolderEnabled=false") getgenv().PerformanceConfig = getgenv().PerformanceConfig or {} applyDefaults(getgenv().PerformanceConfig, { Enabled = true, Extreme = true, HideWorldParts = false, DisableTextures = true, DisableScreenGui = false, DisableWorldGui = false, ProtectYourBaseGui = true, FpsCap = 100, -- 15 lam moveTo giat va sai gio khoa cua (67ms/frame) FarmOnlyFpsCap = 20, -- farm-only luc RANH (do: 10 FPS = 21.1 stud/s) CollectFpsCap = 100, -- nang len trong luc DI GOM (30 = 31.6 stud/s, bang 60) }) -- HOTFIX (tiep) — ep SAU applyDefaults cua PerformanceConfig. -- Dat o day chu khong o khoi tren: dat truoc thi van dung (applyDefaults chi dien -- khi nil) nhung phu thuoc thu tu, de vo neu sau nay ai doi applyDefaults. getgenv().PerformanceConfig.FarmOnlyFpsCap = 10 -- (4) farm-only luc RANH getgenv().PerformanceConfig.CollectFpsCap = 30 -- (5) nang len luc DI GOM print("[HOTFIX] FarmOnlyFpsCap=10 CollectFpsCap=30") local performanceBoostStarted = false local function safeSet(obj, prop, value) pcall(function() obj[prop] = value end) end local function isProtectedWorldGui(obj) if not obj or obj.Name ~= "YourBase" then return false end local parent = obj.Parent return parent and parent.Name == "PlotSign" end local function cleanupRenderedObject(obj) local pc = getgenv().PerformanceConfig or {} if pc.Enabled == false or not obj then return end if (getgenv().RebirthConfig or {}).AutoPhantomWheel == true then local current = obj while current do -- Cu: chi chua ScreenGui ten dung "PhantomWheel". Event doi ten la UI wheel -- moi bi don sach => bam Spin vao hu vo. Gio chua theo DANG TEN. if current:IsA("ScreenGui") then local n = current.Name:lower() if n:find("wheel", 1, true) or n:find("spin", 1, true) then return end end current = current.Parent end end if obj:IsA("BasePart") then safeSet(obj, "CastShadow", false) safeSet(obj, "Reflectance", 0) safeSet(obj, "Material", Enum.Material.SmoothPlastic) if pc.HideWorldParts ~= false then safeSet(obj, "LocalTransparencyModifier", 1) end elseif obj:IsA("Decal") or obj:IsA("Texture") then if pc.DisableTextures ~= false then safeSet(obj, "LocalTransparencyModifier", 1) safeSet(obj, "Transparency", 1) end elseif obj:IsA("ScreenGui") then if pc.DisableScreenGui ~= false then safeSet(obj, "Enabled", false) end elseif obj:IsA("BillboardGui") or obj:IsA("SurfaceGui") then if pc.DisableWorldGui ~= false and not (pc.ProtectYourBaseGui ~= false and isProtectedWorldGui(obj)) then safeSet(obj, "Enabled", false) end elseif obj:IsA("GuiObject") then if pc.DisableScreenGui ~= false or pc.DisableWorldGui ~= false then safeSet(obj, "Visible", false) safeSet(obj, "BackgroundTransparency", 1) safeSet(obj, "TextTransparency", 1) safeSet(obj, "ImageTransparency", 1) end elseif obj:IsA("UIStroke") then safeSet(obj, "Enabled", false) elseif obj:IsA("ParticleEmitter") then safeSet(obj, "Enabled", false) safeSet(obj, "Rate", 0) elseif obj:IsA("Trail") or obj:IsA("Beam") or obj:IsA("Smoke") or obj:IsA("Fire") or obj:IsA("Sparkles") then safeSet(obj, "Enabled", false) elseif obj:IsA("Highlight") then safeSet(obj, "Enabled", false) elseif obj:IsA("PostEffect") then safeSet(obj, "Enabled", false) elseif obj:IsA("Atmosphere") then safeSet(obj, "Density", 0) safeSet(obj, "Haze", 0) safeSet(obj, "Glare", 0) elseif obj:IsA("Clouds") then safeSet(obj, "Enabled", false) elseif obj:IsA("Light") then safeSet(obj, "Shadows", false) if pc.Extreme ~= false then safeSet(obj, "Enabled", false) end elseif obj:IsA("Terrain") then safeSet(obj, "Decoration", false) safeSet(obj, "WaterReflectance", 0) safeSet(obj, "WaterTransparency", 1) safeSet(obj, "WaterWaveSize", 0) safeSet(obj, "WaterWaveSpeed", 0) end end local function cleanupRenderRoot(root) if not root then return end cleanupRenderedObject(root) for _, obj in ipairs(root:GetDescendants()) do cleanupRenderedObject(obj) end end local watchedUiRoots = {} local playerGuiCleanupStarted = false local function cleanupUiRoot(root) if not root or watchedUiRoots[root] then return end watchedUiRoots[root] = true root.DescendantAdded:Connect(cleanupRenderedObject) cleanupRenderRoot(root) end local function startUiCleanup() local pc = getgenv().PerformanceConfig or {} if pc.DisableScreenGui == false and pc.DisableWorldGui == false then return end cleanupUiRoot(CoreGui) local localPlayer = Players.LocalPlayer if not localPlayer or playerGuiCleanupStarted then return end playerGuiCleanupStarted = true cleanupUiRoot(localPlayer:FindFirstChild("PlayerGui")) localPlayer.ChildAdded:Connect(function(child) if child.Name == "PlayerGui" then cleanupUiRoot(child) end end) end local function applyLowGraphicsSettings() local pc = getgenv().PerformanceConfig or {} if pc.Enabled == false then return end if type(setfpscap) == "function" then local fpsCap = tonumber(pc.FpsCap) or 60 if fpsCap > 0 then pcall(setfpscap, fpsCap) end end pcall(function() UserSettings():GetService("UserGameSettings").SavedQualityLevel = Enum.SavedQualitySetting.QualityLevel1 end) pcall(function() settings().Rendering.QualityLevel = Enum.QualityLevel.Level01 end) pcall(function() Lighting.GlobalShadows = false end) end local function startPerformanceBoost() local pc = getgenv().PerformanceConfig or {} if performanceBoostStarted or pc.Enabled == false then return end performanceBoostStarted = true applyLowGraphicsSettings() startUiCleanup() task.spawn(function() for _ = 1, 60 do if Players.LocalPlayer then startUiCleanup() return end task.wait(0.5) end end) Workspace.DescendantAdded:Connect(cleanupRenderedObject) Lighting.DescendantAdded:Connect(cleanupRenderedObject) task.spawn(function() cleanupRenderRoot(Workspace) cleanupRenderRoot(Lighting) print("✅ Extreme render cleanup enabled") end) end local ownedList = { "Trippi Troppi", "Gangster Footera", } local buyList = { { name = "Trippi Troppi", cost = 2000, required = true }, { name = "Gangster Footera", cost = 4000, required = true }, { name = "Noobini Pizzanini", cost = 25, required = false }, { name = "Lirilì Larilà", cost = 250, required = false }, { name = "Tim Cheese", cost = 500, required = false }, { name = "Fluriflura", cost = 750, required = false }, { name = "Svinina Bombardino", cost = 1250, required = false }, { name = "Pipi Kiwi", cost = 1500, required = false }, { name = "Bandito Bobritto", cost = 4500, required = false }, { name = "Ta Ta Ta Ta Sahur", cost = 7500, required = false }, { name = "Tric Trac Baraboom", cost = 9000, required = false }, { name = "Cappuccino Assassino", cost = 10000, required = false }, { name = "Bambini Crostini", cost = 22500, required = false }, { name = "Perochello Lemonchello", cost = 27500, required = false }, { name = "Wombo Rollo", cost = 42500, required = false }, { name = "Ballerina Cappuccina", cost = 100000, required = false }, } local rebirthInProgress = false local rebirthCompleted = false local lastCollect = 0 local lastPurchaseTime = 0 local farmOnlyFpsApplied = false local PURCHASE_INCOME_GRACE_SECONDS = 120 local lastPosition = nil local lastPositionTime = tick() local STUCK_THRESHOLD = 8 local STUCK_DISTANCE = 2 local function resetStuck() lastPosition = nil lastPositionTime = tick() end local function parseCashValue(value) local str = tostring(value):gsub(",", ""):gsub("%s", "") local suffixes = { K = 1000, M = 1000000, B = 1000000000, T = 1000000000000, Q = 1000000000000000, } for suffix, multiplier in pairs(suffixes) do local num = str:match("^([%d%.]+)" .. suffix .. "$") if num then local amount = tonumber(num) if amount then return math.floor(amount * multiplier) end end end return tonumber(str) or 0 end local animalsData = nil local mutationsData = nil local traitsData = nil local synchronizer = nil local synchronizerLastAttempt = 0 local SYNCHRONIZER_RETRY_SECONDS = 5 local lastPhantomSpinEventTime = nil local lastPhantomSpinAttemptTime = nil -- moc thoi diem thu spin gan nhat, dung cho cooldown khi event KHONG co attribute. -- Phai khai bao local: gan thang se tao BIEN GLOBAL. local lastPhantomSpinAttemptAt = 0 local farmActionBusy = false local phantomWheelBusy = false local lockDoorBusy = false -- dang chay ve khoa cua: farm nhuong duong local moveTo local pathfindTo local Action = {} -- ══════════════════════════════════════════════════════════════════════ -- TASK LOG — in ro DANG LAM GI, MAT BAO LAU, KET QUA SAO. -- Truoc day bot im lang nen nhin vao khong biet no dang chay hay dang cho. -- Moi task in 2 dong: mo dau (▶) va ket thuc (✔/✖) kem thoi gian thuc. -- Deu la field cua bang Action nen ton 0 register (file sat tran 200). -- ══════════════════════════════════════════════════════════════════════ Action.T = {} Action.T.depth = 0 Action.T.lastLine = 0 function Action.T.on() return (getgenv().RebirthConfig or {}).TaskLog ~= false end -- mo dau mot task. Tra ve token de truyen vao Action.T.done function Action.T.begin(name, detail) local e = { name = name, t0 = tick() } if Action.T.on() then local pad = string.rep(" ", Action.T.depth) print(("%s▶ %s%s"):format(pad, name, detail and (" | " .. tostring(detail)) or "")) end Action.T.depth = Action.T.depth + 1 return e end -- ket thuc. ok = true/false, note = ly do hoac ket qua function Action.T.done(e, ok, note) Action.T.depth = math.max(0, Action.T.depth - 1) if not e then return ok end local dt = tick() - e.t0 if Action.T.on() then local pad = string.rep(" ", Action.T.depth) -- danh dau nhung task ngon qua 5s de de soi cho cham local flag = (dt >= 5) and " ⏳" or "" print(("%s%s %s | %.2fs%s%s"):format(pad, ok and "✔" or "✖", e.name, dt, note and (" | " .. tostring(note)) or "", flag)) end return ok end -- ghi mot moc le, khong cap bac function Action.T.mark(msg) if Action.T.on() then print(("%s· %s"):format(string.rep(" ", Action.T.depth), tostring(msg))) end end -- ══════════════════════════════════════════════════════════════════════ -- TRANG THAI TONG — mot dong cho biet bot dang o pha nao va bao lau roi. -- In khi DOI pha, hoac moi StatusEverySec giay neu khong doi (de biet no -- con song chu khong treo). -- ══════════════════════════════════════════════════════════════════════ -- DONG HO PHIEN -------------------------------------------------------- -- Dem tu luc EXECUTE, de biet acc nay farm bao lau moi toi rebirth. -- Fleet co _bootAt (~L3857) nhung do la local BEN TRONG IIFE cua Fleet nen -- khong dung lai duoc o day. Dat tren bang Action -> 0 chunk local (file sat -- tran 200 register). -- Dung tick() chu KHONG dung os.time(): tick() dem tu luc client khoi dong nen -- khong nhay khi may dong bo lai dong ho hay doi mui gio. ------------------------------------------------------------------------- Action.T.startedAt = tick() -- 3661 -> "1h01m01s" | 61 -> "1m01s" | 9 -> "9s" function Action.T.uptime(sec) sec = math.max(0, math.floor(tonumber(sec) or (tick() - Action.T.startedAt))) local h = math.floor(sec / 3600) local m = math.floor((sec % 3600) / 60) local r = sec % 60 if h > 0 then return ("%dh%02dm%02ds"):format(h, m, r) end if m > 0 then return ("%dm%02ds"):format(m, r) end return ("%ds"):format(r) end Action.T.phase = "boot" Action.T.phaseAt = tick() Action.T.lastStatusAt = 0 function Action.T.setPhase(name, detail) local now = tick() local every = tonumber((getgenv().RebirthConfig or {}).StatusEverySec) or 15 local changed = (name ~= Action.T.phase) if changed or (now - Action.T.lastStatusAt) >= every then if Action.T.on() then if changed then print(("━━ [T+%s] %s → %s%s (pha truoc %.1fs)"):format( Action.T.uptime(), Action.T.phase, name, detail and (" | " .. tostring(detail)) or "", now - Action.T.phaseAt)) else print(("━━ [T+%s] %s | da %.0fs%s"):format(Action.T.uptime(), name, now - Action.T.phaseAt, detail and (" | " .. tostring(detail)) or "")) end end Action.T.lastStatusAt = now end if changed then Action.T.phase = name Action.T.phaseAt = now end end local function getDataModule(moduleName) local datas = ReplicatedStorage:FindFirstChild("Datas") local moduleScript = datas and datas:FindFirstChild(moduleName) if not moduleScript then return nil end local ok, result = pcall(require, moduleScript) return ok and result or nil end local function getGenerationData() if not animalsData then animalsData = getDataModule("Animals") end if not mutationsData then mutationsData = getDataModule("Mutations") end if not traitsData then traitsData = getDataModule("Traits") end return animalsData, mutationsData, traitsData end local function genFromData(name, mutation, traits) local Animals, Mutations, Traits = getGenerationData() local d = Animals and name and Animals[name] local base = (d and tonumber(d.Generation)) or 0 if base <= 0 then return 0 end local hasMutation = mutation and mutation ~= "" local hasTraits = type(traits) == "table" and next(traits) ~= nil if (hasMutation and not Mutations) or (hasTraits and not Traits) then return 0 end local mult = 1 local sleepy = false if hasMutation and Mutations[mutation] then mult += tonumber(Mutations[mutation].Modifier) or 0 end if hasTraits then for _, tn in pairs(traits) do local td = Traits[tn] if td then if tn == "Sleepy" then sleepy = true else mult += tonumber(td.MultiplierModifier) or 0 end end end end return math.round(base * mult * (sleepy and 0.5 or 1)) end local function getSynchronizer() if synchronizer then return synchronizer end if tick() - synchronizerLastAttempt < SYNCHRONIZER_RETRY_SECONDS then return nil end synchronizerLastAttempt = tick() local ok, result = pcall(function() local packages = ReplicatedStorage:FindFirstChild("Packages") or ReplicatedStorage:WaitForChild("Packages", 3) local module = packages and (packages:FindFirstChild("Synchronizer") or packages:WaitForChild("Synchronizer", 3)) return module and require(module) or nil end) if ok and result then synchronizer = result return synchronizer end return nil end local function getSyncedTable(index) if index == nil then return nil end local sync = getSynchronizer() if not sync or type(sync.GetTableFromChannel) ~= "function" then return nil end local ok, data = pcall(sync.GetTableFromChannel, sync, index) return ok and type(data) == "table" and data or nil end local startAutoPhantomWheel do -- ══════════════════════════════════════════════════════════════════ -- SPIN WHEEL — TU DO (event-agnostic) -- Ban cu bam cung ten "Phantom" o 7 cho: model PhantomSpinWheel, ScreenGui -- PhantomWheel, attribute PhantomEvent / PhantomEventLastTime. -- Event Phantom da het => ca khoi thanh code chet. -- Ban nay TU DO wheel/UI/attribute theo HINH DANG chu khong theo TEN, -- nen song duoc voi event moi va ca event sau nua. -- Muon ep cung ten thi dat RebirthConfig.WheelModelName / WheelUiName / -- WheelEventAttr. -- ══════════════════════════════════════════════════════════════════ local discovered = { model = nil, root = nil, prompt = nil, at = 0 } local DISCOVER_TTL = 15 local function rcfg() return getgenv().RebirthConfig or {} end -- ── model: bat ky Model nao co Root la BasePart + ProximityPrompt ── local function looksLikeWheel(m) if not (m and m:IsA("Model")) then return nil, nil end local root = m:FindFirstChild("Root") if not (root and root:IsA("BasePart")) then return nil, nil end -- Loai bo model bi dev cat tren troi (>2000) hoac duoi vuc (<-500) if root.Position.Y > 2000 or root.Position.Y < -500 then return nil, nil end local prompt = root:FindFirstChildOfClass("ProximityPrompt") if not prompt then return nil, nil end return root, prompt end local function findWheelModel(token) if discovered.model and discovered.model.Parent and discovered.root and discovered.root.Parent and discovered.prompt and discovered.prompt.Parent and tick() - discovered.at < DISCOVER_TTL then return discovered.model, discovered.root, discovered.prompt end local forced = rcfg().WheelModelName if type(forced) == "string" and forced ~= "" then local m = Workspace:FindFirstChild(forced) if m then local root, prompt = looksLikeWheel(m) if root then discovered = { model = m, root = root, prompt = prompt, at = tick() } return m, root, prompt end end return nil, nil, nil end -- Neu co token (vi du "Eclipse"), uu tien tim model khop token truoc if token and type(token) == "string" and token ~= "" then local exactNames = { token .. "SpinWheel", token .. "Wheel", token .. "EventWheel" } for _, name in ipairs(exactNames) do local m = Workspace:FindFirstChild(name) if m then local root, prompt = looksLikeWheel(m) if root then discovered = { model = m, root = root, prompt = prompt, at = tick() } return m, root, prompt end end end for _, m in ipairs(Workspace:GetChildren()) do if m:IsA("Model") and m.Name:lower():find(token:lower(), 1, true) then local root, prompt = looksLikeWheel(m) if root then discovered = { model = m, root = root, prompt = prompt, at = tick() } return m, root, prompt end end end end -- Fallback tim tat ca model co "wheel" hoac "spin" (da bo qua vi tri Y > 2000 tren troi) for _, m in ipairs(Workspace:GetChildren()) do if m:IsA("Model") then local n = m.Name:lower() if n:find("wheel", 1, true) or n:find("spin", 1, true) then local root, prompt = looksLikeWheel(m) if root then discovered = { model = m, root = root, prompt = prompt, at = tick() } return m, root, prompt end end end end return nil, nil, nil end local function getWheelPrompt(token) local model, root, prompt = findWheelModel(token) if not model then return nil, nil, "Spin: KHONG THAY WHEEL" end return root, prompt, nil end -- ── UI: ScreenGui nao chua .Buttons.Spin la GuiButton ── local function getWheelUi(token) local localPlayer = Players.LocalPlayer local playerGui = localPlayer and localPlayer:FindFirstChild("PlayerGui") if not playerGui then return nil, nil, nil end local function probe(screen) if not (screen and screen:IsA("ScreenGui")) then return nil, nil, nil end for _, frame in ipairs(screen:GetChildren()) do if frame:IsA("GuiObject") then local buttons = frame:FindFirstChild("Buttons") local spin = buttons and buttons:FindFirstChild("Spin") if spin and spin:IsA("GuiButton") then return screen, frame, spin end end end return nil, nil, nil end local forced = rcfg().WheelUiName if type(forced) == "string" and forced ~= "" then return probe(playerGui:FindFirstChild(forced)) end -- Uu tien ScreenGui khop token (vi du "EclipseWheel") if token and type(token) == "string" and token ~= "" then local exactGuis = { token .. "Wheel", token .. "SpinWheel", token .. "EventWheel" } for _, name in ipairs(exactGuis) do local s, f, sp = probe(playerGui:FindFirstChild(name)) if s then return s, f, sp end end for _, screen in ipairs(playerGui:GetChildren()) do if screen:IsA("ScreenGui") and screen.Name:lower():find(token:lower(), 1, true) then local s, f, sp = probe(screen) if s then return s, f, sp end end end end for _, screen in ipairs(playerGui:GetChildren()) do local s, f, sp = probe(screen) if s then return s, f, sp end end return nil, nil, nil end -- ── attribute event: cap Event + EventLastTime tren ReplicatedStorage ── -- ── Trang thai event. DO TU GAME THAT: ho tro CA BA kieu: ── -- Eclipse (hien tai): EclipseWheelActive = true + NextEclipseEvent = -- Crystal (truoc do): CrystalWheelActive = true + NextCrystalEvent = -- Phantom (cu): PhantomEvent = true + PhantomEventLastTime = -- Tra ve: activeAttr, timeAttr, isActive, readyAt, activeToken -- readyAt = moc unix duoc quay free. os.time() >= readyAt => quay duoc. local function readEventState() local ok, attrs = pcall(function() return ReplicatedStorage:GetAttributes() end) if not ok or type(attrs) ~= "table" then return nil, nil, false, nil, nil end local forced = rcfg().WheelEventAttr if type(forced) == "string" and forced ~= "" then local t = attrs[forced .. "LastTime"] ~= nil and (forced .. "LastTime") or nil local tok = forced:gsub("WheelActive$", ""):gsub("Event$", ""):gsub("Active$", "") return forced, t, attrs[forced] == true, tonumber(t and attrs[t]), tok end -- (1) kieu Eclipse / Crystal: Active = true, kem mot moc thoi gian co chua for k, v in pairs(attrs) do if type(k) == "string" and v == true and #k > 6 and k:sub(-6) == "Active" then local base = k:sub(1, #k - 6) -- "EclipseWheel" local token = base:gsub("Wheel$", "") -- "Eclipse" for k2, v2 in pairs(attrs) do if type(k2) == "string" and type(v2) == "number" and k2 ~= k then if k2:find(token, 1, true) and (k2:find("Next", 1, true) or k2:find("Time", 1, true)) then return k, k2, true, v2, token end end end return k, nil, true, nil, token end end -- (2) kieu Phantom: Event = true + EventLastTime for k, v in pairs(attrs) do if type(k) == "string" and #k > 5 and k:sub(-5) == "Event" and v == true then local token = k:sub(1, #k - 5) local timeKey = k .. "LastTime" if attrs[timeKey] ~= nil then return k, timeKey, true, tonumber(attrs[timeKey]), token end end end return nil, nil, false, nil, nil end local function moveToWheel(token) local root, prompt, status = getWheelPrompt(token) if not root then setPhantomWheelStatus(status) return false end if not prompt.Enabled then setPhantomWheelStatus("Spin: PROMPT TAT") return false end setPhantomWheelStatus("Spin: DANG LAI GAN") if not pathfindTo or not pathfindTo(root.Position) then setPhantomWheelStatus("Spin: KHONG TOI GAN") return false end setPhantomWheelStatus("Spin: CHO ON DINH") task.wait(math.max(0, tonumber(rcfg().PhantomWheelArrivalDelay) or 2)) if not root.Parent or not prompt.Parent or not prompt.Enabled then setPhantomWheelStatus("Spin: PROMPT DA DOI") return false end local character = player.Character local hrp = character and character:FindFirstChild("HumanoidRootPart") if not (hrp and hrp:IsA("BasePart")) then setPhantomWheelStatus("Spin: THIEU HRP") return false end if (hrp.Position - root.Position).Magnitude > prompt.MaxActivationDistance then setPhantomWheelStatus("Spin: QUA XA") return nil, nil end return root, prompt end local function openWheelUi(prompt, token) local screen, frame = getWheelUi(token) if screen and screen.Enabled and frame and frame.Visible then -- Bat FastSpin neu chua bat local fastSpin = frame:FindFirstChild("FastSpin") local toggle = fastSpin and fastSpin:FindFirstChild("Toggle") local checkmark = toggle and toggle:FindFirstChild("Checkmark") if toggle and checkmark and checkmark:IsA("GuiObject") and not checkmark.Visible then pcall(function() firesignal(toggle.Activated) end) end return true end setPhantomWheelStatus("Spin: DANG MO UI") local opened = pcall(function() fireproximityprompt(prompt) end) if not opened then return false end local deadline = tick() + 3 while tick() < deadline do screen, frame = getWheelUi(token) if screen and screen.Enabled and frame and frame.Visible then local fastSpin = frame:FindFirstChild("FastSpin") local toggle = fastSpin and fastSpin:FindFirstChild("Toggle") local checkmark = toggle and toggle:FindFirstChild("Checkmark") if toggle and checkmark and checkmark:IsA("GuiObject") and not checkmark.Visible then pcall(function() firesignal(toggle.Activated) end) end return true end task.wait(0.1) end return false end local function closeWheelUi(token) local screen, frame = getWheelUi(token) if not screen or not screen.Enabled or not frame or not frame.Visible then return true end local close = frame:FindFirstChild("Close") if not close or not close:IsA("GuiButton") then return false end local signaled = pcall(function() firesignal(close.Activated) end) if not signaled then return false end local deadline = tick() + 2 while tick() < deadline do if not screen.Enabled or not frame.Visible then return true end task.wait(0.1) end return not screen.Enabled or not frame.Visible end -- ── san sang quay? ban cu CHI chap nhan dung chuoi "SPIN NOW". -- Event moi rat co the doi chu => doc Timer neu co, KHONG co thi -- fallback sang Interactable. Chuoi chap nhan cau hinh qua -- RebirthConfig.SpinReadyText (chuoi hoac bang chuoi). local function spinReadyTexts() local cfg = rcfg().SpinReadyText if type(cfg) == "string" then return { cfg:upper() } end if type(cfg) == "table" then local out = {} for _, s in ipairs(cfg) do out[#out + 1] = tostring(s):upper() end if #out > 0 then return out end end return { "SPIN NOW", "FREE SPIN", "CLAIM", "QUAY" } end local function readSpinTimer(spin) local main = spin and spin:FindFirstChild("Main") local timer = main and main:FindFirstChild("Timer") if timer and timer:IsA("TextLabel") then return timer, tostring(timer.Text or ""):upper() end if spin then for _, d in ipairs(spin:GetDescendants()) do if d:IsA("TextLabel") then return d, tostring(d.Text or ""):upper() end end end return nil, nil end -- ── SO LUOT QUAY con lai. DO TU GAME THAT: nhan "Spins" duoi nut Spin -- co dang "Spin (0)" / "Spin (3)". Day la tin hieu CHINH XAC NHAT, -- chac chan hon nhieu so voi so khop chuoi Timer (moi event doi chu mot kieu: -- Phantom dung "SPIN NOW", Crystal/Eclipse dung "Free Spin in 50m 49s"). local function spinsLeft(spin) if not spin then return nil end local lbl = spin:FindFirstChild("Spins", true) if lbl and lbl:IsA("TextLabel") then local n = tostring(lbl.Text or ""):match("%((%d+)%)") if n then return tonumber(n) end end return nil end local function isSpinReady(spin) -- 1) uu tien dem so luot: "Spin (N)" local n = spinsLeft(spin) if n ~= nil then return n > 0, "spins=" .. tostring(n) end -- 2) khong doc duoc so luot -> so chuoi Timer nhu cu local timer, text = readSpinTimer(spin) if not timer then return (spin.Interactable and spin.Active) and true or false, "no-timer" end for _, want in ipairs(spinReadyTexts()) do if text == want or text:find(want, 1, true) then return true, text end end return false, text end local function clickWheelSpin(token) local screen, frame, spin = getWheelUi(token) if not screen or not screen.Enabled or not frame or not frame.Visible or not spin or not spin:IsA("GuiButton") then return "not-ready", "Spin: UI CHUA SAN SANG" end local ready, text = isSpinReady(spin) if not ready then return "claimed", "Spin: DA NHAN (" .. tostring(text) .. ")" end if not spin.Visible or not spin.Active or not spin.Interactable or spin.AbsoluteSize.X <= 1 or spin.AbsoluteSize.Y <= 1 then return "not-ready", "Spin: NUT CHUA SAN SANG" end local clicked = pcall(function() firesignal(spin.Activated) end) if not clicked then -- Remote fallback neu firesignal that bai pcall(function() local net = require(ReplicatedStorage:WaitForChild("Packages"):WaitForChild("Net")) local spinRemote = net:RemoteEvent("EclipseEventService/Spin") if spinRemote then spinRemote:FireServer() end end) end local clickTime = tick() local deadline = clickTime + 6 while tick() < deadline do local _, currentFrame, currentSpin = getWheelUi(token) if currentFrame and currentSpin then local stillReady = isSpinReady(currentSpin) if not stillReady or not currentSpin.Interactable then task.wait(math.max(0, 2 - (tick() - clickTime))) return "confirmed", "Spin: DA QUAY XONG" end end task.wait(0.1) end return "attempted", "Spin: DA CLICK, CHUA XAC NHAN" end local function autoSpinWheel() local rc = rcfg() local spinEnabled = true if rc.AutoEclipseWheel ~= nil then spinEnabled = rc.AutoEclipseWheel == true elseif rc.AutoSpinWheel ~= nil then spinEnabled = rc.AutoSpinWheel == true elseif rc.AutoPhantomWheel ~= nil then spinEnabled = rc.AutoPhantomWheel == true end if not spinEnabled then setPhantomWheelStatus("Spin: TAT") return end if farmOnlyFpsApplied then setPhantomWheelStatus("Spin: FARM ONLY") return end if farmActionBusy or phantomWheelBusy or lockDoorBusy then setPhantomWheelStatus("Spin: CHO FARM") return end local eventAttr, timeAttr, isActive, readyAt, activeToken = readEventState() local eventTime = nil local prefix = activeToken and ("Spin (" .. activeToken .. ")") or "Spin" if eventAttr then if not isActive then setPhantomWheelStatus(prefix .. ": CHO FREE (" .. eventAttr .. ")") return end eventTime = timeAttr and ReplicatedStorage:GetAttribute(timeAttr) or nil if eventTime == nil then setPhantomWheelStatus(prefix .. ": CHO DU LIEU") return end -- ★ Eclipse / Crystal: NextEvent la moc UNIX duoc quay free lan toi. if readyAt and readyAt > os.time() then local left = readyAt - os.time() setPhantomWheelStatus(("%s: CON %dm%ds"):format(prefix, math.floor(left / 60), left % 60)) return end if lastPhantomSpinEventTime == eventTime then setPhantomWheelStatus(prefix .. ": DA QUAY") return end if lastPhantomSpinAttemptTime == eventTime then setPhantomWheelStatus(prefix .. ": DA THU UI") return end else local _, prompt = getWheelPrompt(activeToken) if not prompt or not prompt.Enabled then setPhantomWheelStatus("Spin: KHONG CO EVENT") return end eventTime = "noattr" if lastPhantomSpinAttemptTime == eventTime and tick() - (lastPhantomSpinAttemptAt or 0) < 300 then setPhantomWheelStatus("Spin: DA THU (cho 5p)") return end end phantomWheelBusy = true local ok, status = pcall(function() local root, prompt = moveToWheel(activeToken) if not root or not prompt then return nil end if not openWheelUi(prompt, activeToken) then return prefix .. ": KHONG MO DUOC UI" end local currentCharacter = player and player.Character local currentHrp = currentCharacter and currentCharacter:FindFirstChild("HumanoidRootPart") if not currentHrp or not prompt.Enabled or (currentHrp.Position - root.Position).Magnitude > prompt.MaxActivationDistance then return prefix .. ": ROI KHOI WHEEL" end task.wait(0.2) if eventAttr then if ReplicatedStorage:GetAttribute(eventAttr) ~= true or ReplicatedStorage:GetAttribute(timeAttr) ~= eventTime then return prefix .. ": EVENT DA DOI" end end local outcome, clickStatus = clickWheelSpin(activeToken) if outcome == "claimed" then lastPhantomSpinAttemptTime = eventTime lastPhantomSpinEventTime = eventTime elseif outcome ~= "not-ready" then lastPhantomSpinAttemptTime = eventTime if outcome == "confirmed" then lastPhantomSpinEventTime = eventTime end end lastPhantomSpinAttemptAt = tick() return clickStatus end) local closed = closeWheelUi(activeToken) phantomWheelBusy = false if not closed then warn("⚠️ Wheel UI could not be closed") end if not ok then setPhantomWheelStatus(prefix .. ": UI LOI") warn("⚠️ Wheel UI flow failed: " .. tostring(status)) return end if status then setPhantomWheelStatus(status) end end -- cong bo ra ngoai: goi qua MCP de xem no DANG THAY GI, khoi phai doan Action.debugWheel = function() local eventAttr, timeAttr, isActive, readyAt, activeToken = readEventState() local model, root, prompt = findWheelModel(activeToken) local screen, frame, spin = getWheelUi(activeToken) local ready, text = nil, nil if spin then ready, text = isSpinReady(spin) end local hrp = player and player.Character and player.Character:FindFirstChild("HumanoidRootPart") return { activeToken = activeToken, model = model and model:GetFullName() or nil, pos = root and tostring(root.Position) or nil, promptEnabled = prompt and prompt.Enabled or nil, holdDuration = prompt and prompt.HoldDuration or nil, maxDistance = prompt and prompt.MaxActivationDistance or nil, distance = (hrp and root) and math.floor((hrp.Position - root.Position).Magnitude) or nil, ui = screen and screen:GetFullName() or nil, frame = frame and frame.Name or nil, spin = spin and spin:GetFullName() or nil, spinReady = ready, spinText = text, spinsLeft = spin and spinsLeft(spin) or nil, eventAttr = eventAttr, eventActive = isActive, timeAttr = timeAttr, readyAt = readyAt, now = os.time(), secondsLeft = readyAt and math.max(0, readyAt - os.time()) or nil, } end startAutoPhantomWheel = function() setPhantomWheelStatus("Spin: DANG KIEM TRA") task.spawn(function() while true do -- pcall bao ngoai: ban cu khong co, mot loi trong autoSpin la -- vong nay CHET han va phantomWheelBusy co the ket true mai mai. local okLoop, errLoop = pcall(autoSpinWheel) if not okLoop then phantomWheelBusy = false warn("⚠️ Wheel loop error: " .. tostring(errLoop)) end task.wait(math.max(1, tonumber(rcfg().PhantomWheelScanSec) or 30)) end end) end end local function getAnimalGeneration(animalData) if type(animalData) ~= "table" or not animalData.Index then return 0 end return genFromData(animalData.Index, animalData.Mutation, animalData.Traits) end local function bindCash(cashRef) if cashValueConnection then cashValueConnection:Disconnect() cashValueConnection = nil end cash = cashRef cachedCash = cash and parseCashValue(cash.Value) or nil if cash then cashValueConnection = cash:GetPropertyChangedSignal("Value"):Connect(function() cachedCash = parseCashValue(cash.Value) end) end end local function bindRebirths(rebirthsRef) if rebirthValueConnection then rebirthValueConnection:Disconnect() rebirthValueConnection = nil end rebirths = rebirthsRef cachedRebirths = rebirths and rebirths.Value or nil if rebirths then rebirthValueConnection = rebirths:GetPropertyChangedSignal("Value"):Connect(function() cachedRebirths = rebirths.Value end) end end local function disconnectMovementSignals() if movementCharacterAncestryConnection then movementCharacterAncestryConnection:Disconnect() end if movementHumanoidDiedConnection then movementHumanoidDiedConnection:Disconnect() end movementCharacterAncestryConnection = nil movementHumanoidDiedConnection = nil end local function bindMovementCharacter(newCharacter) disconnectMovementSignals() character = newCharacter humanoid = nil hrp = nil resetStuck() if not character then return end humanoid = character:FindFirstChildOfClass("Humanoid") hrp = character:FindFirstChild("HumanoidRootPart") movementCharacterAncestryConnection = character.AncestryChanged:Connect(function(_, parent) if not parent and character == newCharacter then bindMovementCharacter(nil) end end) if humanoid then movementHumanoidDiedConnection = humanoid.Died:Connect(resetStuck) end end local function bindMovementPlayer() if characterAddedConnection then characterAddedConnection:Disconnect() end characterAddedConnection = nil if not player then return end characterAddedConnection = player.CharacterAdded:Connect(bindMovementCharacter) bindMovementCharacter(player.Character) end local function getMovementRefs() if not player then return nil, nil, nil end if player.Character ~= character then bindMovementCharacter(player.Character) end if not character then return nil, nil, nil end if not humanoid or humanoid.Parent ~= character then if movementHumanoidDiedConnection then movementHumanoidDiedConnection:Disconnect() end movementHumanoidDiedConnection = nil humanoid = character:FindFirstChildOfClass("Humanoid") if humanoid then movementHumanoidDiedConnection = humanoid.Died:Connect(resetStuck) end resetStuck() end if not hrp or hrp.Parent ~= character then hrp = character:FindFirstChild("HumanoidRootPart") resetStuck() end if not humanoid or not hrp or humanoid.Health <= 0 then return nil, nil, nil end return character, humanoid, hrp end local function waitForFullLoad() print("⏳ Waiting for full game load...") local deadline = tick() + FULL_LOAD_TIMEOUT_SECONDS local function remaining() return math.max(0, deadline - tick()) end local function fail(reason) warn("❌ Full load timeout: " .. reason) local localPlayer = Players.LocalPlayer if localPlayer then localPlayer:Kick("Khởi tạo quá " .. FULL_LOAD_TIMEOUT_SECONDS .. " giây: " .. reason) end return false end while not game:IsLoaded() and tick() < deadline do task.wait(0.5) end if not game:IsLoaded() then return fail("game:IsLoaded") end while not Players.LocalPlayer and tick() < deadline do task.wait(0.5) end player = Players.LocalPlayer if not player then return fail("LocalPlayer") end bindMovementPlayer() while tick() < deadline do local currentCharacter = player.Character local currentHumanoid = currentCharacter and currentCharacter:FindFirstChildOfClass("Humanoid") local currentHrp = currentCharacter and currentCharacter:FindFirstChild("HumanoidRootPart") if currentCharacter and currentHumanoid and currentHrp and currentHumanoid.Health > 0 then character = currentCharacter humanoid = currentHumanoid hrp = currentHrp break end task.wait(0.5) end if not character or not humanoid or not hrp then return fail("Character/Humanoid/HumanoidRootPart") end bindMovementCharacter(character) -- ⚠ DA BO `humanoid.WalkSpeed = 16`. -- WalkSpeed la property REPLICATED va nam trong mat tran BAC soi. Ghi vao day -- vua vo ich (do live ra 34 — game tu nang len) vua rui ro. -- Va neu lan nao no THANG cuoc dua (respawn / perk ap lai muon) thi bot chay -- cham 47% trong khi estimateTravel van tinh theo WalkSpeed doc live => cua so -- ve khoa cua sai am tham. LockDoor.estimateTravel doc hum.WalkSpeed truc tiep. leaderstats = player:FindFirstChild("leaderstats") or player:WaitForChild("leaderstats", remaining()) cash = leaderstats and (leaderstats:FindFirstChild("Cash") or leaderstats:WaitForChild("Cash", remaining())) rebirths = leaderstats and (leaderstats:FindFirstChild("Rebirths") or leaderstats:WaitForChild("Rebirths", remaining())) local plots = Workspace:FindFirstChild("Plots") or Workspace:WaitForChild("Plots", remaining()) if not leaderstats or not cash or not rebirths or not plots then return fail("leaderstats/Cash/Rebirths/Plots") end bindCash(cash) bindRebirths(rebirths) if remaining() < 5 then return fail("final readiness delay") end task.wait(5) print("✅ Game fully loaded!") return true end local function checkStuck() local _, currentHumanoid, currentHrp = getMovementRefs() if not currentHrp or not currentHumanoid then return end if lastPosition == nil then lastPosition = currentHrp.Position lastPositionTime = tick() return end local dist = (currentHrp.Position - lastPosition).Magnitude if dist > STUCK_DISTANCE then lastPosition = currentHrp.Position lastPositionTime = tick() elseif tick() - lastPositionTime >= STUCK_THRESHOLD then print("⚠️ Stuck! Jumping...") currentHumanoid.Jump = true task.wait(0.3) currentHumanoid.Jump = true task.wait(0.3) currentHumanoid.Jump = true resetStuck() end end local function getCash() if not player then return 0 end if not leaderstats or leaderstats.Parent ~= player then leaderstats = player:FindFirstChild("leaderstats") end if not leaderstats then return 0 end if not cash or cash.Parent ~= leaderstats then bindCash(leaderstats:FindFirstChild("Cash")) end if cash and cash.Parent == leaderstats then if cachedCash ~= nil then return cachedCash end cachedCash = parseCashValue(cash.Value) return cachedCash end return 0 end local function getRebirths() if not player then return 0 end if not leaderstats or leaderstats.Parent ~= player then leaderstats = player:FindFirstChild("leaderstats") end if not leaderstats then return 0 end if not rebirths or rebirths.Parent ~= leaderstats then bindRebirths(leaderstats:FindFirstChild("Rebirths")) end if rebirths and rebirths.Parent == leaderstats then if cachedRebirths ~= nil then return cachedRebirths end cachedRebirths = rebirths.Value return cachedRebirths end return 0 end local getBaseIncomePerSecond = nil local changedFolder = false local changingFolder = false local changeFolderTimedOut = false local function hasRequiredRebirthAnimalsSynced() local animalList = Action.getSyncedAnimalList() if type(animalList) ~= "table" then return false end local found = {} for _, animalData in pairs(animalList) do if type(animalData) == "table" then found[tostring(animalData.Index or "")] = true end end for _, name in ipairs(ownedList) do if not found[name] then return false end end return true end local function changeToFolderIfReady() if changedFolder then return true end if changeFolderTimedOut then return false end if changingFolder or rebirthInProgress then return false end local rc = getgenv().RebirthConfig or {} if rc.ChangeToFolderEnabled == false then return false end local rebirthCount = getRebirths() local incomePerSecond = getBaseIncomePerSecond and getBaseIncomePerSecond() or 0 local hasRequiredAnimals = hasRequiredRebirthAnimalsSynced() if rebirthCount < 1 and (incomePerSecond <= CHANGE_INCOME_PER_SECOND or not hasRequiredAnimals) then return false end if not rc.From or not rc.To then warn("[Change] Missing RebirthConfig.From/RebirthConfig.To") return false end changingFolder = true task.wait(tonumber(rc.ChangeDelay) or 3) for _ = 1, 30 do if getgenv().client then break end task.wait(0.5) end local client = getgenv().client if not client then changingFolder = false warn("[Change] getgenv().client chưa sẵn sàng") return false end rc = getgenv().RebirthConfig or {} if rc.ChangeToFolderEnabled == false or rebirthInProgress then changingFolder = false return false end local completed = false local ok, result local callThread = task.spawn(function() ok, result = pcall(function() return client:ChangeToFolder(rc.From, rc.To, rc.ChangeWithoutReplace == true, rc.ConfigID) end) completed = true end) local deadline = tick() + CHANGE_FOLDER_TIMEOUT_SECONDS while not completed and tick() < deadline do task.wait(0.1) end if not completed then changeFolderTimedOut = true pcall(task.cancel, callThread) changingFolder = false warn("[Change] ChangeToFolder timed out; refusing a duplicate call") return false end changingFolder = false if ok then changedFolder = true print( "[Change] ChangeToFolder called: " .. tostring(result) .. " | rebirths=" .. rebirthCount .. " income/s=" .. incomePerSecond .. " requiredAnimals=" .. tostring(hasRequiredAnimals) ) return true end warn("[Change] ChangeToFolder failed: " .. tostring(result)) return false end local plotsFolder = nil local cachedMyPlot = nil local cachedAnimalPodiums = nil local cachedPodiumCache = nil local podiumCacheDirty = true local PODIUM_CACHE_TTL = 5 local plotsChildAddedConnection = nil local plotsChildRemovedConnection = nil local cachedPlotAncestryConnection = nil local cachedYourBaseEnabledConnection = nil local watchedPlot = nil local animalPodiumsChildAddedConnection = nil local animalPodiumsChildRemovedConnection = nil local animalPodiumsDescendantAddedConnection = nil local animalPodiumsDescendantRemovingConnection = nil local watchedAnimalPodiums = nil local function markPodiumCacheDirty() podiumCacheDirty = true end local function disconnectCachedPlotSignals() if cachedPlotAncestryConnection then cachedPlotAncestryConnection:Disconnect() end if cachedYourBaseEnabledConnection then cachedYourBaseEnabledConnection:Disconnect() end cachedPlotAncestryConnection = nil cachedYourBaseEnabledConnection = nil watchedPlot = nil end local function disconnectAnimalPodiumsSignals() if animalPodiumsChildAddedConnection then animalPodiumsChildAddedConnection:Disconnect() end if animalPodiumsChildRemovedConnection then animalPodiumsChildRemovedConnection:Disconnect() end if animalPodiumsDescendantAddedConnection then animalPodiumsDescendantAddedConnection:Disconnect() end if animalPodiumsDescendantRemovingConnection then animalPodiumsDescendantRemovingConnection:Disconnect() end animalPodiumsChildAddedConnection = nil animalPodiumsChildRemovedConnection = nil animalPodiumsDescendantAddedConnection = nil animalPodiumsDescendantRemovingConnection = nil watchedAnimalPodiums = nil end local function markPlotCacheDirty() cachedMyPlot = nil cachedAnimalPodiums = nil cachedPodiumCache = nil markPodiumCacheDirty() disconnectCachedPlotSignals() disconnectAnimalPodiumsSignals() end local function getPlotsFolder() if plotsFolder and plotsFolder.Parent == Workspace then return plotsFolder end plotsFolder = Workspace:FindFirstChild("Plots") or Workspace:WaitForChild("Plots", 30) if not plotsFolder then warn("❌ Plots folder not found") return nil end if plotsChildAddedConnection then plotsChildAddedConnection:Disconnect() end if plotsChildRemovedConnection then plotsChildRemovedConnection:Disconnect() end plotsChildAddedConnection = plotsFolder.ChildAdded:Connect(markPlotCacheDirty) plotsChildRemovedConnection = plotsFolder.ChildRemoved:Connect(markPlotCacheDirty) return plotsFolder end local function getYourBase(plot) local plotSign = plot and plot:FindFirstChild("PlotSign") local yourBase = plotSign and plotSign:FindFirstChild("YourBase") if yourBase and yourBase:IsA("BillboardGui") then return yourBase end return nil end local function isMyPlot(plot) local yourBase = getYourBase(plot) return yourBase and yourBase.Enabled == true, yourBase end local function watchMyPlot(plot, yourBase) if watchedPlot == plot then return end disconnectCachedPlotSignals() watchedPlot = plot cachedPlotAncestryConnection = plot.AncestryChanged:Connect(markPlotCacheDirty) cachedYourBaseEnabledConnection = yourBase:GetPropertyChangedSignal("Enabled"):Connect(function() if not yourBase.Enabled then markPlotCacheDirty() end end) end local function findMyPlot() local plots = getPlotsFolder() if not plots then return nil end if cachedMyPlot and cachedMyPlot.Parent == plots then local ok, yourBase = isMyPlot(cachedMyPlot) if ok then watchMyPlot(cachedMyPlot, yourBase) return cachedMyPlot end markPlotCacheDirty() end for _, plot in ipairs(plots:GetChildren()) do local ok, yourBase = isMyPlot(plot) if ok then cachedMyPlot = plot watchMyPlot(plot, yourBase) return plot end end return nil end function Action.getSyncedAnimalList() local plot = findMyPlot() local baseData = plot and getSyncedTable(plot.Name) local animalList = baseData and baseData.AnimalList return type(animalList) == "table" and animalList or nil end local function watchAnimalPodiums(animalPodiums) if watchedAnimalPodiums == animalPodiums then return end disconnectAnimalPodiumsSignals() watchedAnimalPodiums = animalPodiums animalPodiumsChildAddedConnection = animalPodiums.ChildAdded:Connect(markPodiumCacheDirty) animalPodiumsChildRemovedConnection = animalPodiums.ChildRemoved:Connect(markPodiumCacheDirty) animalPodiumsDescendantAddedConnection = animalPodiums.DescendantAdded:Connect(markPodiumCacheDirty) animalPodiumsDescendantRemovingConnection = animalPodiums.DescendantRemoving:Connect(markPodiumCacheDirty) end local function getAnimalPodiums() local plot = findMyPlot() if not plot then return nil end if cachedAnimalPodiums and cachedAnimalPodiums.Parent == plot then watchAnimalPodiums(cachedAnimalPodiums) return cachedAnimalPodiums end cachedAnimalPodiums = plot:FindFirstChild("AnimalPodiums") markPodiumCacheDirty() if cachedAnimalPodiums then watchAnimalPodiums(cachedAnimalPodiums) end return cachedAnimalPodiums end local function scanPodiums(animalPodiums) local cache = { count = 0, owned = {}, slots = {}, income = 0 } local animalList = Action.getSyncedAnimalList() for i = 1, MAX_PODIUMS do local slot = animalPodiums:FindFirstChild(tostring(i)) if slot then for _, obj in ipairs(slot:GetDescendants()) do -- ⚠ O co LUCKY BLOCK cung DA BI CHIEM, nhung prompt cua no la "Open" -- chu khong phai "Grab" nen ban cu KHONG dem -> bot tuong o con trong, -- doi mua vao do, server tu choi vi o da co vat -> KET VINH VIEN. -- DO LIVE 2026-09-15: slot 4 co prompt Action="Open" Object="Lucky Block", -- HoldDuration 1.5, MaxActivationDistance 10. if obj:IsA("ProximityPrompt") and tostring(obj.ObjectText or ""):lower():find("lucky", 1, true) then cache.count += 1 cache.slots[i] = { slot = slot, objectText = tostring(obj.ObjectText or ""), indexName = "", generation = 0, lucky = true } break end if obj:IsA("ProximityPrompt") and obj.ActionText == "Grab" then local objectText = tostring(obj.ObjectText or "") local animalData = animalList and (animalList[i] or animalList[tostring(i)]) local indexName = type(animalData) == "table" and tostring(animalData.Index or "") or "" local generation = getAnimalGeneration(animalData) cache.count += 1 cache.income += generation cache.slots[i] = { slot = slot, objectText = objectText, indexName = indexName, generation = generation, } for _, trackedName in ipairs(ownedList) do local loweredName = trackedName:lower() if objectText:lower():find(loweredName, 1, true) or indexName:lower():find(loweredName, 1, true) then cache.owned[trackedName] = true end end break end end end end return cache end local function getPodiumCache() local animalPodiums = getAnimalPodiums() if not animalPodiums then return { count = 0, owned = {}, slots = {}, income = 0 } end if not podiumCacheDirty and cachedPodiumCache and cachedPodiumCache.animalPodiums == animalPodiums and tick() - (cachedPodiumCache.refreshedAt or 0) < PODIUM_CACHE_TTL then return cachedPodiumCache end cachedPodiumCache = scanPodiums(animalPodiums) cachedPodiumCache.animalPodiums = animalPodiums cachedPodiumCache.refreshedAt = tick() podiumCacheDirty = false return cachedPodiumCache end getBaseIncomePerSecond = function() return tonumber(getPodiumCache().income) or 0 end local function getPodiumInfo() local podiumCache = getPodiumCache() return podiumCache.count, podiumCache.owned end local function findSlotByName(name) local podiumCache = getPodiumCache() local loweredName = name:lower() for i = 1, MAX_PODIUMS do local slotInfo = podiumCache.slots[i] if slotInfo then local objectText = tostring(slotInfo.objectText or ""):lower() local indexName = tostring(slotInfo.indexName or ""):lower() if objectText:find(loweredName, 1, true) or indexName:find(loweredName, 1, true) then return slotInfo.slot, i end end end return nil, nil end local purchasePromptCache = {} local purchasePromptCacheDirty = true local purchaseTagAddedConnection = nil local purchaseTagRemovedConnection = nil local purchaseAnimalDescendantConnections = {} local function markPurchasePromptCacheDirty() purchasePromptCacheDirty = true end local function unwatchPurchaseAnimal(obj) local connections = purchaseAnimalDescendantConnections[obj] if not connections then return end for _, connection in pairs(connections) do connection:Disconnect() end purchaseAnimalDescendantConnections[obj] = nil end local function watchPurchaseAnimal(obj) if not obj or purchaseAnimalDescendantConnections[obj] then return end purchaseAnimalDescendantConnections[obj] = { obj.DescendantAdded:Connect(markPurchasePromptCacheDirty), obj.DescendantRemoving:Connect(markPurchasePromptCacheDirty), } end local function onPurchaseAnimalAdded(obj) watchPurchaseAnimal(obj) markPurchasePromptCacheDirty() end local function onPurchaseAnimalRemoved(obj) unwatchPurchaseAnimal(obj) markPurchasePromptCacheDirty() end local function ensurePurchasePromptSignals() if purchaseTagAddedConnection then return end purchaseTagAddedConnection = CollectionService:GetInstanceAddedSignal("Animal"):Connect(onPurchaseAnimalAdded) purchaseTagRemovedConnection = CollectionService:GetInstanceRemovedSignal("Animal"):Connect(onPurchaseAnimalRemoved) end -- ══════════════════════════════════════════════════════════════════════ -- ANIMAL SOURCE — hoi thang registry CUA GAME thay vi tu suy doan. -- -- DECOMPILE ReplicatedStorage.Controllers.AnimalController (2026-09-05): -- function tbl.GetAnimals(a1) return tbl_upv_1 end <- chi tra bang, KHONG BAY -- tbl_upv_1[animalClient:GetUID()] = animalClient <- khoa theo UID chuoi -- -- ⚠⚠ TUYET DOI KHONG GOI ctrl:HasAnimal(...) — trong module do no chay -- Synchronizer:Get(LocalPlayer), dung cai honeypot da biet (kiem caller-source -- + quet getfenv tim writefile) => kick "CODE BAC". Chi dung GetAnimals. -- HasAnimalMovingToBase cung sach nhung ta khong can. -- -- DO LIVE tren server that (12 con): Index la CHUOI ("Talpa Di Fero"), UID = ten -- Instance = attribute UID cua prompt; duong prompt la -- Instance.PrimaryPart.PromptAttachment.ProximityPrompt (co ca .Part du phong). -- -- ⚠ VI SAO BO CARPET: ban cu hoi "con vat co nam tren tam tham khong" bang cach so -- toa do voi carpetCache — ma cache do KHONG BAO GIO duoc lam ban (nghe -- Workspace.DescendantAdded + ten "Carpet", trong khi nguon that la tag Carpet -- tren instance NGOAI Workspace). Event bat/tat la cache chet cung => khong mua -- duoc gi. Game tu tra loi cau hoi do roi: prompt.Enabled duoc CHINH CLIENT dat -- bang `TargetPlayer ~= LocalPlayer.UserId and not Disabled` (thay trong decompile), -- con "con nay con o the gioi khong" thi IsDescendantOf(workspace) la du. -- ══════════════════════════════════════════════════════════════════════ local AnimalSource = { controller = nil, failedAt = -math.huge } function AnimalSource.getAnimals() if not AnimalSource.controller then if tick() - AnimalSource.failedAt < 5 then return nil end local controllers = ReplicatedStorage:FindFirstChild("Controllers") local module = controllers and controllers:FindFirstChild("AnimalController") local ok, ctrl = false, nil if module then ok, ctrl = pcall(require, module) end if ok and type(ctrl) == "table" and type(ctrl.GetAnimals) == "function" then AnimalSource.controller = ctrl else AnimalSource.failedAt = tick() return nil end end local ok2, animals = pcall(AnimalSource.controller.GetAnimals, AnimalSource.controller) if not ok2 or type(animals) ~= "table" then AnimalSource.controller = nil AnimalSource.failedAt = tick() return nil end return animals end function AnimalSource.count() local animals = AnimalSource.getAnimals() if not animals then return -1 -- -1 = khong doc duoc registry (khac han 0 = registry rong) end local n = 0 for _ in pairs(animals) do n = n + 1 end return n end -- prompt cua mot record. Uu tien PrimaryPart (dung nhu game lam), du phong .Part function AnimalSource.promptOf(rec) local inst = type(rec) == "table" and rec.Instance or nil if typeof(inst) ~= "Instance" or not inst:IsDescendantOf(Workspace) then return nil, nil end local part = inst.PrimaryPart or inst:FindFirstChild("Part") local at = part and part:FindFirstChild("PromptAttachment") local pr = at and at:FindFirstChild("ProximityPrompt") if pr and pr:IsA("ProximityPrompt") and pr.ActionText == "Purchase" then return pr, part end return nil, nil end -- UID cua con vat mang prompt nay (de biet prompt co bi tai su dung sang con khac khong) function AnimalSource.uidOfPrompt(prompt) local ok, uid = pcall(function() return prompt:GetAttribute("UID") end) return ok and uid or nil end -- ten CHINH XAC cua con mang prompt nay, doc tu registry. nil = khong tra loi duoc. function AnimalSource.indexOfPrompt(prompt) local uid = AnimalSource.uidOfPrompt(prompt) if uid == nil then return nil end local animals = AnimalSource.getAnimals() local rec = animals and animals[uid] return type(rec) == "table" and rec.Index or nil end local function isValidPurchasePrompt(prompt) return prompt and prompt.Parent ~= nil and prompt:IsA("ProximityPrompt") and prompt.ActionText == "Purchase" and not prompt:GetFullName():find("StPatricksPot") end local function getPurchasePromptFromAnimal(obj) local part = obj and obj:FindFirstChild("Part") local promptAttachment = part and part:FindFirstChild("PromptAttachment") local prompt = promptAttachment and promptAttachment:FindFirstChild("ProximityPrompt") return isValidPurchasePrompt(prompt) and prompt or nil end local function rebuildPurchasePromptCache() purchasePromptCache = {} local taggedAnimals = {} for _, obj in ipairs(CollectionService:GetTagged("Animal")) do taggedAnimals[obj] = true watchPurchaseAnimal(obj) local prompt = getPurchasePromptFromAnimal(obj) if prompt then table.insert(purchasePromptCache, prompt) end end for obj in pairs(purchaseAnimalDescendantConnections) do if not taggedAnimals[obj] then unwatchPurchaseAnimal(obj) end end purchasePromptCacheDirty = false end local function getPurchasePart(prompt) if not isValidPurchasePrompt(prompt) then return nil end local part = prompt.Parent and prompt.Parent.Parent if part and part:IsA("BasePart") then return part end return nil end -- "Con nay mua duoc khong?" -- Enabled : CHINH CLIENT dat = (TargetPlayer ~= UserId cua minh) and not Disabled -- (thay trong decompile AnimalController.Start). Nen minh vua ban mot -- phat la Enabled thanh FALSE — do la binh thuong, khong phai loi. -- TargetPlayer == nil : chua ai dat cho. Do LIVE: gia tri la USERID (so). -- Disabled : game tat rieng prompt nay. Ban cu KHONG kiem — 0 lan trong ca file. -- con o the gioi : thay cho phep thu carpet cu (xem chu thich AnimalSource). local function isPurchasePromptAvailable(prompt) if not isValidPurchasePrompt(prompt) then return false end if prompt.Enabled ~= true or prompt:GetAttribute("TargetPlayer") ~= nil then return false end if prompt:GetAttribute("Disabled") == true then return false end local part = getPurchasePart(prompt) return part ~= nil and part:IsDescendantOf(Workspace) end local function promptMatchesPurchaseName(prompt, name) if not isValidPurchasePrompt(prompt) then return false end -- ★ KHOP CHINH XAC truoc: registry cua game cho biet Index that (chuoi, vd -- "Talpa Di Fero"). Ban cu chi so chuoi con bang find(name, 1, true) nen ten -- ngan lot vao ten dai => mua nham con. Chi lui ve so chuoi khi khong doc duoc. local exact = AnimalSource.indexOfPrompt(prompt) if exact ~= nil then return exact == name end local loweredName = name:lower() local objectText = tostring(prompt.ObjectText or ""):lower() local promptName = tostring(prompt.Name or ""):lower() return objectText:find(loweredName, 1, true) ~= nil or promptName:find(loweredName, 1, true) ~= nil end local function getPurchaseIncome(prompt, name) if not promptMatchesPurchaseName(prompt, name) or prompt.Enabled ~= true or not isPurchasePromptAvailable(prompt) then return nil end local animal = getPurchasePart(prompt) while animal and animal ~= Workspace and not CollectionService:HasTag(animal, "Animal") do animal = animal.Parent end if not animal or animal == Workspace then return nil end local mutation = animal:GetAttribute("__mutation") or animal:GetAttribute("Mutation") local traits = {} local seenTraits = {} local function addTrait(traitName) if traitName and traitName ~= "" and not seenTraits[traitName] then seenTraits[traitName] = true table.insert(traits, traitName) end end for _, child in ipairs(animal:GetChildren()) do if not mutation and child.Name:sub(1, 9) == "Mutation." then mutation = child.Name:sub(10) else addTrait(child.Name:match("^_?Trait%.(.+)$")) end end local traitAttribute = animal:GetAttribute("Traits") or animal:GetAttribute("Trait") if type(traitAttribute) == "string" then for traitName in traitAttribute:gmatch("[^,]+") do addTrait((traitName:gsub("^%s*(.-)%s*$", "%1"))) end end local Animals, Mutations, Traits = getGenerationData() if not Animals or (mutation and mutation ~= "" and not Mutations) or (#traits > 0 and not Traits) then return nil end local income = genFromData(name, mutation, traits) return income > 0 and income or nil end local function findCachedPurchasePrompt(name) local validPrompts = {} local matchedPrompt = nil for _, prompt in ipairs(purchasePromptCache) do if isValidPurchasePrompt(prompt) then table.insert(validPrompts, prompt) if not matchedPrompt and promptMatchesPurchaseName(prompt, name) and isPurchasePromptAvailable(prompt) then matchedPrompt = prompt end else purchasePromptCacheDirty = true end end purchasePromptCache = validPrompts return matchedPrompt end local function findProximityPrompt(name) ensurePurchasePromptSignals() if purchasePromptCacheDirty then rebuildPurchasePromptCache() end local prompt = findCachedPurchasePrompt(name) if prompt then return prompt end if purchasePromptCacheDirty then rebuildPurchasePromptCache() return findCachedPurchasePrompt(name) end return nil end -- ══════════════════════════════════════════════════════════════════════ -- CHON CON DE MUA — quet CON THAT tren bang chuyen, khong dua vao danh sach cung. -- -- ⚠ VI SAO BO buyList LAM NGUON. DO LIVE 2026-09-05, 90 giay tren server that: -- 43 con moi len bang chuyen, 19 con KHONG nam trong buyList nen bot mu tit — -- Avocadini Guffo ($/s 225), Trulimero Trulicina ($/s 125 x3), Avocadini -- Antilopini ($/s 115), Cacto Hipopotamo ($/s 50 x3), Boneca Ambalabu ($/s 40 x3)... -- ReplicatedStorage.Datas.Animals co san Price + Generation cho 560 loai. -- Con TOT NHAT mua noi, buyList so voi du lieu game: -- $5.000 -> 35 vs 40 (1.1x) $278.009 -> 500 vs 1150 (2.3x) -- $50.000 -> 275 vs 300 (1.1x) $500.000 -> 500 vs 2500 (5.0x) -- Cang giau cang thiet. buyList GIU LAI, nhung chi de danh dau muc `required`. -- -- ⚠ DA THU VA BO: san thu nhap = ti le cua "con tot nhat mua noi". -- Tinh theo RoadWeight (trong so spawn, do duoc trong chinh Datas.Animals): -- o $278k san 25% => chi 0.73% so spawn qua => CHO TRUNG BINH 288 GIAY. -- Con xin co RoadWeight cuc nho (Wombo 1.75) con rac thi to (Noobini 100), -- nen san kieu do bien bot thanh dung im. NEO SAN VAO CAI DANG CO TREN BE. -- -- ⚠ O TRONG THI MUA NGAY, KHONG KEN. O trong kiem 0 $/s. Mua con $/s 40 roi ~290s -- sau thay bang con $/s 1150 van an dut ngoi cho: 40 x 290 = $11.600, tru vai -- giay churn. Chi khi be DAY moi duoc ken, va luc do nguong la worst x 1.25. -- ══════════════════════════════════════════════════════════════════════ local function getBestAvailableNow(currentCash, owned, incomeFloor) -- (1) muc BAT BUOC cho rebirth: bo qua moi nguong, mua bang duoc for _, item in ipairs(buyList) do if item.required and not owned[item.name] and currentCash >= item.cost then local prompt = findProximityPrompt(item.name) if prompt then return item, prompt end end end -- ══ LUAT HOAN VON ══════════════════════════════════════════════════ -- Muc tieu THAT cua script khong phai "tong $/s cao nhat" ma la CHAM -- $500.000 SOM NHAT roi rebirth (REBIRTH_CASH L~440, MAX_REBIRTHS=1, -- vong farm thoat ngay khi du tien). $/s chi la bien trung gian. -- Hai cai nay PHAN KY dung o cho user than phien: mua mot con thi income -- tang nhung TIEN MAT GIAM, day moc $500k ra xa. -- -- T0 = (REBIRTH_CASH - cash) / income -- dung yen farm -- T1 = (REBIRTH_CASH - cash + cost - income*tt) / (income + g - g_ban) + tt -- MUA khi T1 < T0. Trong so con thoa, chon T1 NHO NHAT (khong phai g lon nhat). -- -- g_ban = 0 khi con o trong; = con te nhat tren be khi be day (phai ban di). -- tt = thoi gian di duong (mua ~10s, churn ~16s); income*tt la tien van chay ve -- trong luc di. -- -- Kiem tay dung trang thai user bao ($278.009, income 500/s, T0 = 444.0s): -- Lirili $250 3/s -> T1 451.8s LO 7.8s -> BO <- dung cai user chui -- Pipi Kiwi $1.5k 13 -> T1 445.7s LO 1.7s -> BO -- Bandito $4.5k 35 -> T1 433.3s LOI 10.6s -> MUA -- Cappuccino $10k 75 -> T1 413.5s LOI 30.5s -> MUA -- Ballerina $100k 500-> T1 332.0s LOI 112.0s -> MUA (tot nhat) -- -- ⚠ DA THU VA BO: san = ti le cua "con tot nhat mua noi". 4/4 agent phan bien -- bac bo, mo phong cho thay no CHAM HON code cu +5.1% o dung kich ban $278k. -- Ly do: no chan ca Bandito/TaTa/TricTrac/Cappuccino — nhung con GAP HOAI — -- de cho Wombo/Ballerina hiem khi spawn (RoadWeight 1.75 / 0.55). -- -- Luat nay TU CO GIAN that, khong can hang so ma: -- ngheo, income ~0 -> T0 -> vo cuc -> moi thu deu loi -> van mua do re khoi dong -- giau, gan dich -> T0 nho -> chi cu nhay income lon moi lot -> tu giet cu mua rac -- be day -> tru g_ban da CHINH LA bar nang cap, khoi can he so rieng -- khong bao gio dung im vinh vien: khong con nao thoa thi cau tra loi DUNG la -- dung yen farm cho tien tu chay ve. -- ═══════════════════════════════════════════════════════════════════ local ctx = Action.buyCtx or {} local income = tonumber(ctx.income) or 0 local soldGen = tonumber(ctx.soldGen) or 0 local travel = tonumber(ctx.travel) or 10 local minGain = tonumber((getgenv().RebirthConfig or {}).MinBuyGainSec) or 10 local need = REBIRTH_CASH - currentCash local T0 = (income > 0) and (need / income) or math.huge local floor = tonumber(incomeFloor) or 0 local bestItem, bestPrompt, bestT = nil, nil, nil -- tra ve T1, hoac nil neu mua vao la LO thoi gian local function payback(cost, gen) local ni = income + gen - soldGen if ni <= 0 then return nil end local T1 = (need + cost - income * travel) / ni + travel -- ★ NGUONG LOI TOI THIEU. Loi phai bu duoc CHI PHI CO HOI, khong chi > 0. -- Vi du that: $278k, income 500/s -> mua Lirili ($250, 3 $/s) LOI 2.1 giay. -- Duong tren lai LO: cu do ngon ~10s di bo va MOT O BE, ma trong 10s do -- bang chuyen de them ~5 con (do that: 0.478 con/giay). Doi 2 giay lay -- 10 giay la lo. -- Mo phong so THAT (42 loai, RoadWeight that), giay-toi-rebirth: -- $278k 10/10 cui : nguong 0 -> -9.3% | nguong 10s -> -10.2% -- $50k 10/10 cui : nguong 0 -> -7.5% | nguong 10s -> -8.3% -- $278k 10/10 kha : nguong 0 -> -16.7% | nguong 10s -> -18.4% -- Khong chan khoi dong: ngheo thi income ~0 -> T0 vo cuc -> loi cuc lon, -- vuot nguong de dang. Nguong chi can khi DA giau, dung luc can can. if T0 - T1 < minGain then return nil end return T1 end local Animals = getGenerationData() local animals = AnimalSource.getAnimals() if animals and Animals then -- ── duong CHINH: duyet dung nhung con dang co, doc gia tu du lieu game ── for _, rec in pairs(animals) do local name = type(rec) == "table" and rec.Index or nil local d = name and Animals[name] local cost = d and tonumber(d.Price) if cost and currentCash >= cost then local prompt = AnimalSource.promptOf(rec) if prompt and isPurchasePromptAvailable(prompt) then -- $/s THUC cua CON NAY: genFromData nhan them mutation/traits local gen = getPurchaseIncome(prompt, name) local T1 = gen and gen >= floor and payback(cost, gen) or nil if T1 and (not bestT or T1 < bestT) then bestItem = { name = name, cost = cost, required = false } bestPrompt = prompt bestT = T1 end end end end -- Registry chay duoc thi no la nguon DAY DU nhat — tra ve luon, ke ca nil. -- Khong duoc roi xuong quet buyList: cung mot san se cho cung ket qua rong, -- ma vong farm chay moi 2 giay nen 16 lan findProximityPrompt do la phi thuan. return bestItem, bestPrompt end -- ── DU PHONG: CHI khi registry hong (require that bai / GetAnimals loi) ── for _, item in ipairs(buyList) do if not item.required and currentCash >= item.cost then local prompt = findProximityPrompt(item.name) local gen = prompt and getPurchaseIncome(prompt, item.name) local T1 = gen and gen >= floor and payback(item.cost, gen) or nil if T1 and (not bestT or T1 < bestT) then bestItem, bestPrompt, bestT = item, prompt, T1 end end end return bestItem, bestPrompt end -- tolerance = coi nhu "toi noi" khi con bao nhieu stud. Mac dinh 5 (giu nguyen hanh vi cu). -- LockDoor truyen so nho hon vi can dung DUNG vao hitbox. moveTo = function(position, operationDeadline, tolerance) local startCharacter, startHumanoid, startHrp = getMovementRefs() if not startCharacter or not startHumanoid or not startHrp then return false end local tol = tonumber(tolerance) or 5 resetStuck() local finished = false local reached = false local connection = startHumanoid.MoveToFinished:Connect(function(didReach) finished = true reached = didReach end) startHumanoid:MoveTo(position) local deadline = math.min(tick() + 15, operationDeadline or math.huge) -- ⚠ PHAT LAI khi bi CAT NGANG. Truoc day MoveTo chi phat DUNG MOT LAN va vong -- lap khong bao gio phat lai, nen: -- • script ngoai (anti-AFK cua Duy/nam) goi Humanoid:MoveTo hoac dat -- WalkToPoint -> Roblox HUY lenh cua ta, ban MoveToFinished(false) -- -> ta tra false -> pathfindTo vut CA duong di -> mat nguyen mot luot. -- • va ke ca checkStuck co ban 3 cu nhay thi nhan vat cung dung im, -- vi khong ai phat lai lenh di. -- Gio: MoveToFinished(false) MA van con xa dich + con song + con gio -- => coi la BI CHEN, phat lai va di tiep. Toi da RETRY_MAX lan de khong -- quay vo han khi dich that su khong toi duoc; deadline van la tran cung. local RETRY_MAX = 3 local retries = 0 while tick() < deadline do task.wait(0.1) -- giu nguyen 0.1: FPS cap 15 = 67ms/frame nen 0.05 khong nhanh hon local currentCharacter, currentHumanoid, currentHrp = getMovementRefs() if currentCharacter ~= startCharacter or currentHumanoid ~= startHumanoid or not currentHrp then connection:Disconnect() return false end if (currentHrp.Position - position).Magnitude < tol then connection:Disconnect() return true end if finished then if (not reached) and retries < RETRY_MAX and tick() < deadline - 0.5 then -- bi cat ngang (hoac het 8s timeout noi tai cua Roblox) -> di tiep retries = retries + 1 finished, reached = false, false currentHumanoid.Jump = true -- nhay mot cai phong khi dang mac ket currentHumanoid:MoveTo(position) else connection:Disconnect() return reached end end checkStuck() end connection:Disconnect() return false end function pathfindTo(position, operationDeadline, tolerance) operationDeadline = operationDeadline or tick() + ACTION_TIMEOUT_SECONDS local tol = tonumber(tolerance) or 5 -- ⚠ TINH LAI DUONG KHI BI KEO DI. Script BEN THU BA (anti-AFK) co the goi -- Humanoid:MoveTo hoac dat WalkToPoint bat cu luc nao. Khi do: -- 1. lenh di cua ta bi HUY -> moveTo tra false -- 2. va te hon: cac waypoint CON LAI van tinh tu vi tri CU, di theo chung -- la di nguoc hoac dam vao tuong. -- Ban cu gap (1) la `return false` vut CA duong di -> mat nguyen mot luot farm, -- dung cai user thay la "stuck ti". Gio: hong mot waypoint thi TINH LAI duong -- tu vi tri HIEN TAI va di tiep, toi da REPLAN_MAX lan. Deadline van la tran cung. local REPLAN_MAX = 3 for attempt = 0, REPLAN_MAX do if tick() >= operationDeadline then return false end local _, _, currentHrp = getMovementRefs() if not currentHrp then return false end if (currentHrp.Position - position).Magnitude < tol then return true end local path = PathfindingService:CreatePath({ AgentRadius = 2, AgentHeight = 5, AgentCanJump = true, }) local computeDone = false local ok = false local computeThread = task.spawn(function() ok = pcall(function() path:ComputeAsync(currentHrp.Position, position) end) computeDone = true end) while not computeDone and tick() < operationDeadline do task.wait(0.05) end if not computeDone then pcall(task.cancel, computeThread) return false end -- ⚠ DA THU GOM WAYPOINT (di thang khi he so vong < 1.2, gop waypoint cach < 12 stud) -- -> BI DUNG TUONG. He so vong gan 1.0 KHONG co nghia la duong thong: mot khuc -- re vuong goc quanh vat can van cho tong do dai xap xi duong thang. Bo waypoint -- la bo dung nhung khuc tranh vat can do. DA REVERT ve di TUNG waypoint. -- Khung la do FPS CAP 15 (moi frame 67ms), khong phai do cat waypoint. if not (ok and path.Status == Enum.PathStatus.Success) then -- khong tinh duoc duong -> di thang, day la duong lui cuoi cung return moveTo(position, operationDeadline, tolerance) end local wps = path:GetWaypoints() local broke = false for i, waypoint in ipairs(wps) do if tick() >= operationDeadline then return false end local _, currentHumanoid, latestHrp = getMovementRefs() if not currentHumanoid or not latestHrp then return false end if waypoint.Action == Enum.PathWaypointAction.Jump then currentHumanoid.Jump = true end if (latestHrp.Position - waypoint.Position).Magnitude >= 5 and not moveTo(waypoint.Position, operationDeadline, (i == #wps) and tolerance or nil) then -- ★ KHONG vut ca duong nua: thoat ra tinh lai tu cho dang dung. broke = true break end end if not broke then return true end end -- het luot tinh lai: thu di thang mot phat cuoi return moveTo(position, operationDeadline, tolerance) end -- ══════════════════════════════════════════════════════════════════════ -- COLLECT — quet mot mach, cho MOT lan, roi KIEM va di lai cho nao truot. -- -- ⚠ DO LIVE 2026-09-04: -- * cham 1 pad -> ca cash LAN LastCollect doi sau 1.17s => do tre la ROUND-TRIP -- mang, khong phai hang doi tuan tu => cac lan cham DOC LAP nhau. -- * di bo qua het 10 pad (luc ranh) = 3.5s -- * ban cu: task.wait(0.8~1.6) sau MOI pad = ~12s cho suong -- => 3.5 + 12 = 15.5s, khop voi 16.10s do duoc trong log that. -- -- Thiet ke moi: -- PASS 1 quet mot mach, KHONG cho (~3.5s) -- CHO mot lan cho server ghi nhan (1.5s) -- PASS 2 doc LastCollect, pad nao CHUA doi thi di lai co cho (thuong 0 pad) -- -- => thuong ~5s thay vi 15.5s. Va neu gia dinh "cham doc lap" SAI thi PASS 2 -- di lai het, ket qua van dung — chi mat thoi gian bang cach cu. An toan. -- -- LastCollect lay tu channel Synchronizer (Action.getSyncedAnimalList), la tin hieu -- CHINH XAC theo tung be — khong dua vao cash vi cash co the doi vi ly do khac -- (dang mua, dang ban) va khong cho biet BE NAO da an. -- ══════════════════════════════════════════════════════════════════════ -- {[slot] = LastCollect}. nil = khong doc duoc channel -> bo qua khau kiem. Action.collectStamps = function() local al = Action.getSyncedAnimalList() if type(al) ~= "table" then return nil end local out = {} for i = 1, MAX_PODIUMS do local a = al[i] or al[tostring(i)] if type(a) == "table" then out[i] = a.LastCollect end end return out end function Action.collectCash() local _t = Action.T.begin("collect", "gom tien tu cac be") local deadline = tick() + COLLECT_PASS_TIMEOUT_SECONDS lastCollect = tick() - COLLECT_INTERVAL + COLLECT_RETRY_SECONDS local animalPodiums = getAnimalPodiums() if not animalPodiums or not animalPodiums.Parent then return Action.T.done(_t, false, "khong thay AnimalPodiums") end local podiumCache = getPodiumCache() if podiumCache.count <= 0 then lastCollect = tick() return Action.T.done(_t, true, "be trong, khong co gi de gom") end local targets = {} for i = 1, MAX_PODIUMS do local slotInfo = podiumCache.slots[i] local claim = slotInfo and slotInfo.slot and slotInfo.slot:FindFirstChild("Claim") local target = claim and claim:FindFirstChild("Main") if target and target:IsA("BasePart") then table.insert(targets, { slotIndex = i, target = target }) end end if not targets[1] then return Action.T.done(_t, false, "khong thay claim pad") end local before = Action.collectStamps() -- ── PASS 1: quet mot mach, khong cho giua cac pad ── if not pathfindTo(targets[1].target.Position, deadline, 4) then return Action.T.done(_t, false, "khong pathfind toi base duoc") end local swept = 0 for _, info in ipairs(targets) do if tick() >= deadline then return Action.T.done(_t, false, ("het gio 45s (quet %d/%d)"):format(swept, #targets)) end if lockDoorBusy then return Action.T.done(_t, false, ("nhuong cho khoa cua (quet %d/%d)"):format(swept, #targets)) end local target = info.target if target.Parent and target:IsA("BasePart") then moveTo(target.Position, deadline, 4) swept = swept + 1 end end -- ── CHO MOT LAN cho server ghi nhan ca loat ── local settle = tonumber((getgenv().RebirthConfig or {}).CollectSettleSec) or 1.5 task.wait(math.min(settle, math.max(0, deadline - tick()))) -- ── PASS 2: pad nao CHUA an thi di lai, lan nay co cho tung cai ── local after = Action.collectStamps() if not (before and after) then -- khong doc duoc channel -> khong kiem duoc, coi nhu xong (khong chan farm) lastCollect = tick() return Action.T.done(_t, true, ("quet %d be (khong kiem duoc channel)"):format(swept)) end local missed = {} for _, info in ipairs(targets) do local i = info.slotIndex if before[i] ~= nil and after[i] == before[i] then missed[#missed + 1] = info end end if #missed == 0 then lastCollect = tick() return Action.T.done(_t, true, ("%d be, 1 luot quet"):format(swept)) end Action.T.mark(("%d/%d be chua an -> di lai"):format(#missed, #targets)) local retryWait = tonumber((getgenv().RebirthConfig or {}).CollectRetryWaitSec) or 1.3 local fixed = 0 for _, info in ipairs(missed) do if tick() >= deadline or lockDoorBusy then break end local target = info.target if target.Parent and target:IsA("BasePart") then moveTo(target.Position, deadline, 4) task.wait(math.min(retryWait, math.max(0, deadline - tick()))) local now = Action.collectStamps() if now and now[info.slotIndex] ~= before[info.slotIndex] then fixed = fixed + 1 end end end lastCollect = tick() return Action.T.done(_t, true, ("%d be | di lai %d, vot duoc %d"):format(swept, #missed, fixed)) end function Action.isValidSellPrompt(prompt, slot, name) if not prompt or not prompt.Parent or not prompt:IsA("ProximityPrompt") or prompt.Enabled ~= true then return false end if not slot or not slot.Parent or not prompt:IsDescendantOf(slot) then return false end if tostring(prompt.ActionText or ""):sub(1, 4) ~= "Sell" then return false end local objectText = tostring(prompt.ObjectText or "") return objectText == "" or objectText:lower():find(name:lower(), 1, true) ~= nil end function Action.getPromptPart(prompt) local current = prompt and prompt.Parent while current and current ~= Workspace do if current:IsA("BasePart") then return current end current = current.Parent end return nil end function Action.sellBrainrot(name, slot, preFireCheck) local actionDeadline = tick() + ACTION_TIMEOUT_SECONDS if not slot or not slot.Parent then return false end print("💸 Selling " .. name .. "...") local sellPrompt = nil for _, obj in ipairs(slot:GetDescendants()) do if Action.isValidSellPrompt(obj, slot, name) then sellPrompt = obj break end end if not sellPrompt then warn("❌ Could not find sell prompt for " .. name) return false end local base = slot:FindFirstChild("Base") local spawn = base and base:FindFirstChild("Spawn") if not spawn or not spawn:IsA("BasePart") then warn("❌ Missing sell spawn for " .. name) return false end if not pathfindTo(spawn.Position, actionDeadline) then warn("❌ Could not pathfind to sell spawn for " .. name) return false end local _, _, currentHrp = getMovementRefs() if not currentHrp then warn("❌ Missing movement refs for sell " .. name) return false end if (currentHrp.Position - spawn.Position).Magnitude > 8 and not moveTo(spawn.Position, actionDeadline) then warn("❌ Could not reach sell spawn for " .. name) return false end task.wait(0.5) if not Action.isValidSellPrompt(sellPrompt, slot, name) then warn("❌ Sell prompt changed before firing for " .. name) return false end if preFireCheck then local ok, allowed = pcall(preFireCheck) if not ok or not allowed then warn("❌ Upgrade target changed before selling " .. name) return false end end local promptPart = Action.getPromptPart(sellPrompt) local _, _, latestHrp = getMovementRefs() local maxDistance = tonumber(sellPrompt.MaxActivationDistance) or 10 if not Action.isValidSellPrompt(sellPrompt, slot, name) or not promptPart or not latestHrp or (latestHrp.Position - promptPart.Position).Magnitude > maxDistance then warn("❌ Sell prompt is no longer interactable for " .. name) return false end local fired = pcall(function() fireproximityprompt(sellPrompt) end) if not fired then warn("❌ Failed to fire sell prompt for " .. name) return false end task.wait(1) markPodiumCacheDirty() local slotIndex = tonumber(slot.Name) local slotInfo = slotIndex and getPodiumCache().slots[slotIndex] if slotInfo and slotInfo.slot == slot then local loweredName = name:lower() if tostring(slotInfo.objectText or ""):lower():find(loweredName, 1, true) or tostring(slotInfo.indexName or ""):lower():find(loweredName, 1, true) then warn("❌ Sell not confirmed for " .. name) return false end end print("✅ Sold " .. name .. "!") return true end function Action.isRequiredAnimalName(name) local loweredName = tostring(name or ""):lower() for _, requiredName in ipairs(ownedList) do if loweredName:find(requiredName:lower(), 1, true) then return true end end return false end function Action.findLowestIncomeSellCandidate() local podiumCache = getPodiumCache() local best = nil for i = 1, MAX_PODIUMS do local slotInfo = podiumCache.slots[i] if slotInfo and slotInfo.slot and slotInfo.slot.Parent then local name = slotInfo.objectText ~= "" and slotInfo.objectText or slotInfo.indexName if name ~= "" and not Action.isRequiredAnimalName(name) and not Action.isRequiredAnimalName(slotInfo.indexName) then local generation = tonumber(slotInfo.generation) or 0 if not best or generation < best.generation then best = { name = name, slot = slotInfo.slot, slotIndex = i, generation = generation } end end end end return best end function Action.freeSlotForRequiredAnimal(currentCash, owned, podiumCount) if podiumCount < MAX_PODIUMS then return false end for _, item in ipairs(buyList) do local prompt = item.required and not owned[item.name] and currentCash >= item.cost and findProximityPrompt(item.name) if prompt then local candidate = Action.findLowestIncomeSellCandidate() if not candidate then warn("❌ Plot full but no safe animal to sell for " .. item.name) return false end print( "🧹 Plot full, selling lowest $/s slot " .. candidate.slotIndex .. ": " .. candidate.name .. " ($/s " .. candidate.generation .. ") to make room for " .. item.name ) local sold = Action.sellBrainrot(candidate.name, candidate.slot, function() return promptMatchesPurchaseName(prompt, item.name) and isPurchasePromptAvailable(prompt) and getCash() >= item.cost end) if sold then Action.buyBrainrot(item, prompt) end return sold end end return false end function Action.freeSlotForUpgrade(item, prompt, podiumCount) if podiumCount < MAX_PODIUMS or item.required or getCash() < item.cost then return false end markPodiumCacheDirty() local candidate = Action.findLowestIncomeSellCandidate() if not candidate or candidate.generation <= 0 then return false end local latestPrompt = prompt local targetIncome = latestPrompt and getPurchaseIncome(latestPrompt, item.name) if not targetIncome or targetIncome < candidate.generation * MIN_UPGRADE_MULTIPLIER or getCash() < item.cost then return false end print( "⬆️ Plot full, replacing slot " .. candidate.slotIndex .. ": " .. candidate.name .. " ($/s " .. candidate.generation .. ") with " .. item.name .. " ($/s " .. targetIncome .. ")" ) local sold = Action.sellBrainrot(candidate.name, candidate.slot, function() local finalIncome = getPurchaseIncome(latestPrompt, item.name) return finalIncome and finalIncome >= candidate.generation * MIN_UPGRADE_MULTIPLIER and getCash() >= item.cost end) if sold then Action.buyBrainrot(item, latestPrompt) end return sold end function Action.isPromptInteractable(prompt, part, currentHrp) if not isPurchasePromptAvailable(prompt) or prompt.Enabled ~= true then return false end local maxDistance = tonumber(prompt.MaxActivationDistance) or 10 return part and currentHrp and (currentHrp.Position - part.Position).Magnitude <= maxDistance end function Action.waitForPromptInteractable(prompt, name, timeout) local deadline = tick() + timeout while tick() < deadline do if not promptMatchesPurchaseName(prompt, name) then return false end local latestPart = getPurchasePart(prompt) local _, _, latestHrp = getMovementRefs() if not latestPart or not latestHrp then return false end if Action.isPromptInteractable(prompt, latestPart, latestHrp) then return true end task.wait(0.1) end return false end -- ══════════════════════════════════════════════════════════════════════ -- MUA BRAINROT — ban SONG SONG voi di chuyen -- -- ⚠ BAN CU TUAN TU: pathfindTo (toi 45s) -> moveTo -> wait 0.5 -> wait 1.5 -- -> MOI ban DUNG MOT phat. Di 10 giay roi ban vao cho trong, vi bang chuyen -- van chay va nguoi khac van mua trong luc minh dang di. -- -- BAN MOI: mot thread SPAM ban chay ngay tu dau, song song voi di chuyen. -- Vua chay vua ban -> vao tam la an lien, khong cho toi noi moi ban. -- Dung ngay khi tien GIAM (getCash doc cache, re) de khong mua trung 2 con. -- Vi tri dich duoc DOC LAI moi vong vi con vat dang troi tren bang chuyen. -- ══════════════════════════════════════════════════════════════════════ -- ══════════════════════════════════════════════════════════════════════ -- DEM CON DANG TREN DUONG VE BE (sua loi "mua truoc khi be kip cap nhat") -- -- ⚠ TRIEU CHUNG THAT (log 18:37:56): mua duoc Pipi Kiwi luc 18:37:56, NGAY giay -- do vong farm doc "be 9/10" nen di mua THEM mot con Pipi Kiwi nua -> ban 20 -- phat, server tu choi, phi 7.45s. Den 18:38:04 be moi len 10/10. -- -- ⚠ CACHE KHONG HE CU. Be THUC SU dang la 9/10: con vua mua con dang DI BO tu -- bang chuyen ve be, mat ~8-12s. Nen markPodiumCacheDirty() khong cuu duoc — -- quet lai bao nhieu lan cung ra 9. -- -- CACH DEM: server dat attribute TargetPlayer len prompt NGAY khi mua (code duoi -- da biet dieu nay, xem chu thich "server dat ngay sau phat ban dau, TRUOC khi -- tien tru"). TargetPlayer == chinh minh => con nay da la cua minh, dang ve. -- Tu het khi con vat len be — khong can hen gio, khong so lech so. -- -- CHOT THOI GIAN la luoi thu hai, phong khi TargetPlayer khong ton tai suot duong -- ve: vua mua xong ma so be chua nhuc nhich thi coi nhu con 1 con dang ve. -- ══════════════════════════════════════════════════════════════════════ Action.lastBuyCount = -1 Action.countIncoming = function() -- ⚠ CHOT THOI GIAN BAT BUOC — dat TRUOC vong quet, khong phai sau. -- Chot nay chi co y nghia NGAY SAU khi CHINH MINH vua mua: no che cai khe -- ~8-12s con vat di bo tu bang chuyen ve be. Khong mua gi trong giay -- thi khong the co con nao cua minh dang ve. -- ⚠ Neu KHONG chan bang thoi gian: mot prompt bi sot TargetPlayer=minh (con vat -- despawn giua duong, giao dich bi huy, prompt duoc tai su dung) se lam n >= 1 -- VINH VIEN. Ma chot goi ham nay nam TRUOC nhanh "be day", nen bot se khong mua, -- khong nang cap, chi con collectCash moi 55s — dung im that su. -- Tha mua chong mot con con hon dung im mai. local grace = tonumber((getgenv().RebirthConfig or {}).DeliveryGraceSec) or 20 if lastPurchaseTime <= 0 or tick() - lastPurchaseTime >= grace then return 0 end local n = 0 pcall(function() -- di thang Part.PromptAttachment.ProximityPrompt, KHONG GetDescendants: -- ham nay chay moi vong farm, quet descendants ca tram con vat thi phi. for _, obj in ipairs(CollectionService:GetTagged("Animal")) do local pr = getPurchasePromptFromAnimal(obj) if pr then local tp = pr:GetAttribute("TargetPlayer") if tp ~= nil and (tp == player or tp == player.Name or tp == player.UserId) then n = n + 1 end end end end) -- luoi thu hai: phong khi TargetPlayer khong ton tai suot duong ve. -- Da nam trong cua so nho chot o dau ham nen khong the ket. if Action.lastBuyCount >= 0 and (select(1, getPodiumInfo()) or 0) <= Action.lastBuyCount then n = math.max(n, 1) end return n end Action.buyBrainrot = function(item, prompt) local actionDeadline = tick() + ACTION_TIMEOUT_SECONDS if not promptMatchesPurchaseName(prompt, item.name) then markPurchasePromptCacheDirty() return false end if not isPurchasePromptAvailable(prompt) then warn("⏭️ Skip " .. item.name .. ": khong con o the gioi hoac da co nguoi dat cho") return false end local part = getPurchasePart(prompt) if not part then warn("❌ Missing purchase part for " .. item.name) markPurchasePromptCacheDirty() return false end -- ★ CHOT 1: base DAY thi khong mua duoc — server tu choi im lang. -- Log thuc te: 67 phat / 40.43s vao hu vo vi be da 10/10. -- Nguoi goi co kiem podiumCount nhung do la so doc tu DAU vong lap, co the CU. do local n0 = select(1, getPodiumInfo()) if (tonumber(n0) or 0) >= MAX_PODIUMS then Action.T.mark(("bo mua %s: be da day %d/%d"):format(item.name, n0, MAX_PODIUMS)) return false end end local cashBefore = getCash() local buyUid = AnimalSource.uidOfPrompt(prompt) -- moc de biet be da nhan con moi chua (xem Action.countIncoming) Action.lastBuyCount = select(1, getPodiumInfo()) or 0 local bought, stopSpam, fires = false, false, 0 local firstFireAt = nil local gap = tonumber((getgenv().RebirthConfig or {}).BuySpamGap) or 0.2 local _t = Action.T.begin("mua", ("%s $%d"):format(item.name, item.cost)) -- ── thread SPAM ban, chay SONG SONG voi di chuyen ── -- ⚠ DA THU LIVE: ban tu XA KHONG an — server CO kiem khoang cach. -- Nen chi ban khi da trong tam (MaxActivationDistance, mac dinh 10, cong bien 2). -- Ban tu 300 stud chi phi CPU chu khong mua duoc gi. -- Cai loi cua thread nay khong phai "ban tu xa" ma la "ban NGAY GIAY vao tam", -- thay vi cho di het duong roi wait 2 giay moi ban nhu ban cu. local spamThread = task.spawn(function() local maxFires = tonumber((getgenv().RebirthConfig or {}).MaxFruitlessFires) or 20 while not stopSpam and tick() < actionDeadline do if getCash() < cashBefore then bought = true break end if fires >= maxFires then break -- ban du nhieu ma khong an: thoi, khoi quay khong end local p = getPurchasePart(prompt) local _, _, h = getMovementRefs() local inRange = false if p and h then local maxD = tonumber(prompt.MaxActivationDistance) or 10 inRange = (h.Position - p.Position).Magnitude <= (maxD + 2) end if inRange and promptMatchesPurchaseName(prompt, item.name) and isPurchasePromptAvailable(prompt) and prompt.Enabled == true then fires = fires + 1 firstFireAt = firstFireAt or tick() pcall(function() fireproximityprompt(prompt) end) -- kiem NGAY sau khi ban: mua duoc thi dung, tranh mua trung con thu 2 task.wait(0.05) if getCash() < cashBefore then bought = true break end task.wait(gap) else -- bi nguoi khac dat cho -> thoi spam luon, khoi quay khong local tp2 = prompt:GetAttribute("TargetPlayer") if tp2 ~= nil and tp2 ~= player and tp2 ~= player.Name and tp2 ~= player.UserId then break end -- chua vao tam: poll nhanh de bat DUNG khoanh khac vao tam task.wait(0.05) end end end) -- ── di chuyen, BAM THEO vi tri moi vi con vat troi tren bang chuyen ── local moveOk = false local why = "het gio 45s" while not bought and tick() < actionDeadline do local latestPart = getPurchasePart(prompt) if not latestPart then why = "con vat bien mat" break end if not promptMatchesPurchaseName(prompt, item.name) then why = "prompt doi sang con khac" break end local _, _, hrp = getMovementRefs() if not hrp then why = "mat nhan vat" break end -- ★ NHUONG duong cho thread khoa cua — nhung CHI khi chua ban phat nao. -- Da ban roi thi co the tien dang tru, bo dở la mat ca chi lan tien. -- ★ CHOT 2: nhuong cho khoa cua. Truoc day chi nhuong khi fires == 0 nen -- khi dang spam vo ich (67 phat) no KHONG nhuong, lam khoa cua chet 28s theo. -- Gio: chua ban thi nhuong ngay; ban roi ma qua 3s van chua an thi cung nhuong, -- vi ro rang server dang tu choi chu khong phai giao dich dang bay. if lockDoorBusy and (fires == 0 or (firstFireAt and tick() - firstFireAt > 3)) then why = "nhuong cho khoa cua" break end -- ★ CHOT 3: ban nhieu ma khong an = server tu choi (be day / het tien / mat cho). local maxFires = tonumber((getgenv().RebirthConfig or {}).MaxFruitlessFires) or 20 if fires >= maxFires then why = ("ban %d phat khong an, server tu choi"):format(fires) break end if fires > 0 and (select(1, getPodiumInfo()) or 0) >= MAX_PODIUMS then why = "be day giua chung" break end -- ★ BO NGAY khi nguoi khac dat cho muc tieu, dung di tiep cho het 45s. -- KHONG dung isPurchasePromptAvailable de kiem: no cung tra false khi -- TargetPlayer la CHINH MINH (server dat ngay sau phat ban dau, TRUOC khi -- tien tru) => se tu huy chinh giao dich cua minh. Phai loai tru ban than. if not latestPart:IsDescendantOf(Workspace) then why = "con vat roi khoi the gioi" break end -- ★ prompt co the duoc TAI SU DUNG sang con khac khi con cu despawn. -- UID doi = khong con la con minh dinh mua nua, bo ngay. if buyUid ~= nil and AnimalSource.uidOfPrompt(prompt) ~= buyUid then why = "prompt doi sang con khac (UID doi)" break end local tp = prompt:GetAttribute("TargetPlayer") if tp ~= nil and tp ~= player and tp ~= player.Name and tp ~= player.UserId then why = "bi nguoi khac dat cho" break end local maxD = tonumber(prompt.MaxActivationDistance) or 10 local d = (hrp.Position - latestPart.Position).Magnitude -- bam sat hon tam mot chut: con vat TROI tren bang chuyen, dung yen o ria -- tam la no troi ra ngoai roi mat luot. if d <= maxD - 3 then moveOk = true -- an toan trong tam: dung yen cho thread spam lam viec task.wait(0.15) else -- deadline ngan cho moi chang, de con doc lai vi tri con vat local legDeadline = math.min(actionDeadline, tick() + 6) if d > 40 then pathfindTo(latestPart.Position, legDeadline) else moveTo(latestPart.Position, legDeadline) end end end stopSpam = true pcall(function() task.cancel(spamThread) end) markPurchasePromptCacheDirty() -- xac nhan bang tien, khong tin ket qua ban. -- fires == 0 => chua ban phat nao => khong the co giao dich dang bay => 2s nay -- chac chan phi. Day la thu bien cac lan bo som (bi cuop / nhuong khoa cua) -- tu ~2.2s xuong ~0.2s. if not bought and fires > 0 then local waitUntil = tick() + 2 while tick() < waitUntil do if getCash() < cashBefore then bought = true break end task.wait(0.1) end end if not bought then return Action.T.done( _t, false, ("%s | %d phat | %s"):format(why, fires, moveOk and "da vao tam" or "chua vao tam") ) end lastPurchaseTime = tick() markPodiumCacheDirty() return Action.T.done(_t, true, ("$%d -> $%d, %d phat"):format(cashBefore, getCash(), fires)) end function Action.sendWebhook(title, description, color, fields) task.spawn(function() local safeTitle = "notification" local sent = false local ok = pcall(function() safeTitle = tostring(title or "") local embedFields = {} if type(fields) == "table" then for _, field in ipairs(fields) do if type(field) == "table" and field.name ~= nil and field.value ~= nil then local nameOk, fieldName = pcall(tostring, field.name) local valueOk, fieldValue = pcall(tostring, field.value) if nameOk and valueOk then table.insert(embedFields, { name = fieldName, value = fieldValue, inline = field.inline ~= false, }) end end end end if type(http_request) ~= "function" then warn("❌ Webhook unavailable: http_request is missing") return end local data = HttpService:JSONEncode({ username = "Rebirth Bot", embeds = { { title = safeTitle, description = tostring(description or ""), color = tonumber(color) or 0, fields = embedFields, }, }, }) local request = { Url = WEBHOOK, Method = "POST", Headers = { ["Content-Type"] = "application/json" }, Body = data, } http_request(request) sent = true end) if sent then print("✅ Webhook sent: " .. safeTitle) elseif not ok then warn("❌ Webhook failed: " .. safeTitle) end end) end local rebirthRequestTimedOut = false -- ══════════════════════════════════════════════════════════════════════ -- LOCK BASE — giu cua nha luon khoa, het han la dong lai NGAY -- ---------------------------------------------------------------------- -- DO TU GAME THAT 2026-09-04 (decompile ReplicatedStorage.Classes.PlotClient): -- -- Trang thai khoa nam trong CHANNEL Synchronizer cua plot: -- BlockEndTimeFirstFloor / ...SecondFloor / ...ThirdFloor -- = moc GetServerTimeNow() ma khoa tang do HET HAN. -- nil => tang do DANG MO. -- PlotClient: Channel:Get(v83) ~= nil -> UnlockBase.Enabled = true -- BlockedDelayTime -- = moc het COOLDOWN, chua toi thi KHONG khoa lai duoc. -- PlotClient: co gia tri -> hien "Ready in:" + RemainingTime, an "Lock Base". -- -- Kich hoat khoa: cham vao Purchases/PlotBlock/Hitbox (CanTouch=true, -- CanCollide=false, Transparency=1). PlotBlock KHONG co ProximityPrompt va -- PlotClient khong ban remote nao => server bat Touched. Nen ta CHI CAN -- DUNG VAO hitbox, khong ban remote gi ca (an toan voi BAC). -- -- HAI LOP, vi phan ung nhanh thoi thi KHONG DU: -- * DU BAO : con PreArriveSec giay thi ve dung san canh cua (di lai ton vai giay, -- ma dung luc do la luc bi cuop). -- * CANH : BlockEndTime* la MOC THOI GIAN TUYET DOI, nen canh chinh xac duoc. -- Sat gio thi vong chat 0.1s, het han la cham ngay. -- (KHONG dung GetPropertyChangedSignal("Enabled"): da thu live, tren -- client chu nha prompt do LUON tat nen signal khong bao gio ban.) -- -- Doc channel qua GetTableFromChannel (duong AN TOAN, khong dam honeypot -- RelateChannels cua Get/GetAllChannels/Wait/WaitAndCall). -- ══════════════════════════════════════════════════════════════════════ local LockDoor = {} -- ⚠ PHAI la (function() ... end)() chu KHONG phai do...end. -- do...end KHONG cap budget register moi: moi local ben trong van tinh vao -- chunk chinh (tran 200). Hai khoi nay co ~133 local -> tran ngay. -- Ham thi co budget RIENG, chunk chi ton dung 1 register cho bang o tren. ;(function() local FLOOR_FIELD = { [1] = "BlockEndTimeFirstFloor", [2] = "BlockEndTimeSecondFloor", [3] = "BlockEndTimeThirdFloor", } local _sync = nil local function getSync() if _sync then return _sync end local ok, mod = pcall(function() local pkg = ReplicatedStorage:WaitForChild("Packages", 10):WaitForChild("Synchronizer", 10) return require((cloneRef and cloneRef(pkg)) or pkg) end) if ok and type(mod) == "table" and type(mod.GetTableFromChannel) == "function" then _sync = mod end return _sync end local function channelOf(plot) local s = getSync() if not s or not plot then return nil end local ok, data = pcall(s.GetTableFromChannel, s, plot.Name) return (ok and type(data) == "table") and data or nil end -- Purchases/PlotBlock/Hitbox : cham vao day = server khoa base local function getLockBlock(plot) local pur = plot and plot:FindFirstChild("Purchases") if not pur then return nil, nil end local blk = pur:FindFirstChild("PlotBlock") if not blk then for _, c in ipairs(pur:GetChildren()) do if c:FindFirstChild("Hitbox") then blk = c break end end end local hb = blk and blk:FindFirstChild("Hitbox") return blk, (hb and hb:IsA("BasePart")) and hb or nil end -- moi ProximityPrompt UnlockBase theo tang local function unlockPrompts(plot) local out = {} local u = plot and plot:FindFirstChild("Unlock") if not u then return out end for _, m in ipairs(u:GetChildren()) do local pr = m:FindFirstChild("UnlockBase") if pr and pr:IsA("ProximityPrompt") then out[#out + 1] = { prompt = pr, floor = tonumber(pr:GetAttribute("Floor")) or 1 } end end return out end -- trang thai: locked? con bao lau? dang cooldown? function LockDoor.state() local plot = findMyPlot and findMyPlot() or nil if not plot then return nil, "khong tim thay plot cua minh" end local ch = channelOf(plot) if not ch then return nil, "khong doc duoc channel" end local now = workspace:GetServerTimeNow() local st = { plot = plot, now = now, cooldownUntil = tonumber(ch.BlockedDelayTime), floors = {}, anyLocked = false, soonestExpiry = nil, } for _, e in ipairs(unlockPrompts(plot)) do local field = FLOOR_FIELD[e.floor] local endAt = field and tonumber(ch[field]) or nil local locked = endAt ~= nil st.floors[#st.floors + 1] = { floor = e.floor, field = field, endAt = endAt, locked = locked, left = endAt and math.max(0, endAt - now) or nil, prompt = e.prompt, } if locked then st.anyLocked = true if not st.soonestExpiry or endAt < st.soonestExpiry then st.soonestExpiry = endAt end end end st.onCooldown = st.cooldownUntil ~= nil and st.cooldownUntil > now st.cooldownLeft = st.onCooldown and (st.cooldownUntil - now) or 0 return st end -- Dung vao hitbox de server bat Touched. -- Da dung san trong hitbox thi Touched KHONG ban lai -> phai buoc ra roi vao. -- ★ CHO DUNG: diem doi NGOAI hitbox. Pha CANH dung o day, het han chi BUOC VAO. -- Do live: step-out + step-in = 3.33s ; CHI step-in tu 7 stud = 0.27s (nhanh 12 lan). -- Cai cu bat dau bang buoc-RA nen dong ho chi chay SAU khi da het han -- => cua ho 3.33s moi chu ky du canh gio chinh xac den may. local WAIT_OFFSET = Vector3.new(7, 0, 0) function LockDoor.waitSpot(hitbox) return hitbox and (hitbox.Position + WAIT_OFFSET) or nil end -- Dung san NGOAI hitbox roi goi ham nay = cham gan nhu tuc thi. -- Neu lo dang dung TRONG hitbox thi buoc ra truoc (Touched khong ban lai -- neu da nam san ben trong). local function touchLockBlock(hitbox, deadline) local char = player and player.Character local hrp = char and char:FindFirstChild("HumanoidRootPart") if not hrp or not hitbox or not hitbox.Parent then return false end local target = hitbox.Position local spot = target + WAIT_OFFSET local dist = (hrp.Position - target).Magnitude if dist > 12 then -- con xa: di toi CHO DOI (khong phai vao thang hitbox) if not pathfindTo or not pathfindTo(spot, deadline, 3) then return false end elseif dist < 3 then -- dang o TRONG hitbox: phai ra truoc, khong thi Touched khong ban lai pcall(function() moveTo(spot, deadline, 2) end) end -- buoc VAO pcall(function() moveTo(target, deadline, 2) end) return true end -- Khoa lai. Tra ve true neu channel xac nhan da khoa. function LockDoor.relock(reason) local st, err = LockDoor.state() if not st then return false, err end if st.onCooldown then return false, ("cooldown con %ds"):format(math.ceil(st.cooldownLeft)) end local _, hitbox = getLockBlock(st.plot) if not hitbox then return false, "khong thay PlotBlock.Hitbox" end lockDoorBusy = true local deadline = tick() + (ACTION_TIMEOUT_SECONDS or 45) local ok = touchLockBlock(hitbox, deadline) if not ok then lockDoorBusy = false return false, "khong toi duoc PlotBlock" end -- doi channel xac nhan (server ghi BlockEndTime*) local waitUntil = tick() + 6 while tick() < waitUntil do local s2 = LockDoor.state() if s2 and s2.anyLocked then lockDoorBusy = false return true, ("da khoa (%s)"):format(tostring(reason or "?")) end task.wait(0.2) end lockDoorBusy = false return false, "cham roi nhung channel chua bao khoa" end -- ══════════════════════════════════════════════════════════════════ -- UOC LUONG THOI GIAN DI CHUYEN — thay cho nguong cung 8 giay. -- -- ⚠ DO LIVE 2026-09-04: script dat humanoid.WalkSpeed = 16 trong waitForFullLoad, -- NHUNG gia tri thuc te doc duoc la 34 (game/perk nang len). Nen TUYET DOI -- khong hardcode toc do — phai doc humanoid.WalkSpeed tai thoi diem tinh. -- Kiem chung: 161 stud / 34 = 4.7s, do thuc te 5s. Khop. -- -- Cong thuc: quangDuong / tocDo * heSoVong + chiPhiCham + biencanToan -- heSoVong : duong di khong thang (vat can, doc). Tu HOC tu chuyen di that. -- chiPhiCham: buoc ra 6 stud roi buoc vao de ep Touched ban lai (~3.2s do duoc). -- ══════════════════════════════════════════════════════════════════ LockDoor._detour = 1.15 -- he so vong, tu dieu chinh sau moi chuyen LockDoor._lastTrip = nil function LockDoor.estimateTravel(targetPos) local rc = getgenv().RebirthConfig or {} local char = player and player.Character local hum = char and char:FindFirstChildOfClass("Humanoid") local hrp = char and char:FindFirstChild("HumanoidRootPart") if not (hum and hrp and targetPos) then return tonumber(rc.LockPreArriveSec) or 8 end local speed = tonumber(hum.WalkSpeed) or 16 if speed < 8 then speed = 8 -- chan chia cho 0 khi bi lam cham / dang chet end local dist = (hrp.Position - targetPos).Magnitude local detour = tonumber(rc.LockDetourFactor) or LockDoor._detour or 1.15 local touchCost = tonumber(rc.LockTouchOverheadSec) or 4 local margin = tonumber(rc.LockSafetyMarginSec) or 2 local est = dist / speed * detour + touchCost + margin -- khong bao gio nho hon nguong san, cung khong lon den vo ly local floorSec = tonumber(rc.LockPreArriveSec) or 8 return math.clamp(est, floorSec, 45), dist, speed end -- goi sau moi chuyen di that de he so vong tu chinh function LockDoor.learnTrip(dist, seconds, speed) if not (dist and seconds and speed) or seconds <= 0 or dist < 20 then return end local straight = dist / speed if straight <= 0 then return end local observed = math.clamp(seconds / straight, 1.0, 3.0) -- trung binh truot, nghieng ve gia tri LON hon cho an toan local prev = LockDoor._detour or 1.15 LockDoor._detour = (observed > prev) and (prev * 0.4 + observed * 0.6) or (prev * 0.8 + observed * 0.2) LockDoor._lastTrip = { dist = math.floor(dist), sec = seconds, factor = LockDoor._detour } end -- ── vong canh ── -- ══════════════════════════════════════════════════════════════════ -- VONG CANH CUA — dieu khien bang MOC THOI GIAN, khong bang signal. -- -- ⚠ Da thu live 2026-09-04: sau khi khoa, BlockEndTimeFirstFloor CO gia tri -- nhung UnlockBase.Enabled = FALSE. Prompt "Unlock Base" la de NGUOI KHAC -- pha cua nha minh, nen tren client CHU NHA no luon tat. -- => GetPropertyChangedSignal("Enabled") KHONG BAO GIO BAN o day. -- Bo han huong do, chuyen sang canh moc thoi gian tuyet doi. -- -- So do live: khoa keo dai ~54s, di bo 161 stud het ~5s, BlockedDelayTime = nil -- (khoa xong khoa lai duoc ngay, khong cooldown). -- -- Ba pha: -- XA (con > PreArrive giay) : ke farm, chi poll 2s/lan -- VE (con <= PreArrive) : gianh quyen dieu khien, chay ve dung canh cua -- CANH (con <= 1.5s) : vong chat 0.1s, het han la cham NGAY -- ══════════════════════════════════════════════════════════════════ function LockDoor.start() task.spawn(function() while true do local waitFor = 2 local okLoop, errLoop = pcall(function() local rc = getgenv().RebirthConfig or {} if rc.AutoLockBase == false then return end local st = LockDoor.state() if not st then return end -- nguong VE tinh DONG theo khoang cach + WalkSpeed THUC TE. -- Khong dung so cung: script dat 16 nhung do live ra 34. local _, hbForEst = getLockBlock(st.plot) local pre, _estDist, estSpeed = LockDoor.estimateTravel(hbForEst and hbForEst.Position) -- (a) chua khoa -> khoa ngay if not st.anyLocked then if st.onCooldown then waitFor = math.min(2, math.max(0.5, st.cooldownLeft)) return end local _tl = Action.T.begin("khoa-cua", "chua khoa lan nao") local okR, msg = LockDoor.relock("chua khoa") Action.T.done(_tl, okR, msg) if not okR then waitFor = 3 end return end -- (b) da khoa: tinh chinh xac con bao lau local left = st.soonestExpiry - st.now if left > pre then -- XA: ke farm lam viec, ngu toi sat gio waitFor = math.min(2, left - pre) return end -- VE: gianh quyen dieu khien, chay ve dung canh cua local _, hitbox = getLockBlock(st.plot) if not hitbox then return end lockDoorBusy = true Action.T.setPhase("ve-khoa-cua", ("con %.0fs, nguong ve %.0fs"):format(left, pre)) -- ★ ve CHO DOI (ngoai hitbox 7 stud), KHONG vao thang hitbox. -- Dung san ben trong thi luc het han phai buoc-RA truoc moi cham lai -- duoc (Touched khong ban khi da nam san ben trong) = mat 3.33s. -- Dung ngoai thi het han chi buoc VAO = 0.27s. local spot = LockDoor.waitSpot(hitbox) local hrp = player and player.Character and player.Character:FindFirstChild("HumanoidRootPart") if hrp and spot and (hrp.Position - spot).Magnitude > 4 then local d0 = (hrp.Position - spot).Magnitude local t0 = tick() pcall(function() if pathfindTo then pathfindTo(spot, tick() + math.max(10, left + 15), 3) end end) -- hoc he so vong tu chuyen di THAT, de lan sau uoc luong sat hon LockDoor.learnTrip(d0, tick() - t0, estSpeed or 16) end -- CANH: vong chat, het han la cham ngay local guardUntil = tick() + math.max(3, left + 10) while tick() < guardUntil do local s2 = LockDoor.state() if not s2 then break end if not s2.anyLocked then -- khoa vua rot -> cham lai NGAY (dang dung san canh cua) local _tl = Action.T.begin("khoa-cua", "het han, dong lai") local okR, msg = LockDoor.relock("het han") Action.T.done(_tl, okR, msg) break end local l2 = s2.soonestExpiry - s2.now if l2 > pre then break -- da duoc gia han boi thu khac, ve lam viec tiep end task.wait(l2 > 1.5 and 0.5 or 0.1) end lockDoorBusy = false waitFor = 0.5 end) if not okLoop then lockDoorBusy = false warn("[LockBase] loi vong canh: " .. tostring(errLoop)) waitFor = 3 end task.wait(waitFor) end end) end -- goi qua MCP de soi trang thai, khoi phai doan Action.debugLock = function() local st, err = LockDoor.state() if not st then return { err = err } end local blk, hb = getLockBlock(st.plot) local hrp = player and player.Character and player.Character:FindFirstChild("HumanoidRootPart") local floors = {} for _, f in ipairs(st.floors) do floors[#floors + 1] = { floor = f.floor, field = f.field, locked = f.locked, secondsLeft = f.left and math.floor(f.left) or nil, promptEnabled = f.prompt.Enabled, } end return { plot = st.plot.Name, anyLocked = st.anyLocked, onCooldown = st.onCooldown, cooldownLeft = math.floor(st.cooldownLeft), soonestExpirySec = st.soonestExpiry and math.floor(st.soonestExpiry - st.now) or nil, floors = floors, block = blk and blk:GetFullName() or nil, distance = (hrp and hb) and math.floor((hrp.Position - hb.Position).Magnitude) or nil, busy = lockDoorBusy, } end end)() -- ══════════════════════════════════════════════════════════════════════ -- FLEET — presence / report-dead / hop dinh ky -- Port tu sab_scanner.lua (giu nguyen hop dong endpoint hobeojob). -- -- POST /api/presence heartbeat {account,placeId,jobId,players,ping,hops,uptime} -- GET /api/jobs/{placeId} danh sach server con slot -> CO CACHE DIA -- POST /api/jobs/{placeId}/blacklist giu cho truoc khi teleport vao -- POST /api/jobs/{placeId}/dead bao server chet (GameEnded) -> go khoi pool -- GET games.roblox.com/v1/games/{id}/servers/Public FALLBACK khi hobeojob rong -- -- ⚠ CACHE la BAT BUOC: ca fleet cung hop moi 15' se dam /api/jobs cung luc. -- Cache ghi ra DIA nen CHIA SE giua moi tab tren may: tab dau GET + ghi file, -- tab sau con han thi DOC FILE, khong goi mang. Kem jitter theo UserId de cac -- tab het han LECH nhau. -- ══════════════════════════════════════════════════════════════════════ local Fleet = {} ;(function() local HttpSvc = cloneRef(game:GetService("HttpService")) local StatsSvc = cloneRef(game:GetService("Stats")) local _httpReq = (syn and syn.request) or (http and http.request) or http_request or request local _canFile = (type(writefile) == "function") and (type(isfile) == "function") local _bootAt = tick() getgenv().__RB1_Hops = getgenv().__RB1_Hops or 0 local _svMem, _svMemExp = nil, 0 -- tang 1: cache trong RAM cua chinh tab nay local _visited = {} local _noSvRetries = 0 local _tpFailed, _tpFailResult = false, nil local function fcfg() return (getgenv().FleetConfig or {}) end local function flog(...) if fcfg().Debug ~= false then print("[Fleet]", ...) end end -- httpRequest truoc (co User-Agent, Cloudflare it chan hon), game:HttpGet lam fallback local function httpGet(url) if _httpReq then local ok, r = pcall(_httpReq, { Url = url, Method = "GET" }) if ok and r and r.Body then local code = tonumber(r.StatusCode or r.Status) if not code or (code >= 200 and code < 300) then return r.Body end end end local ok2, res = pcall(function() return game:HttpGet(url) end) return (ok2 and type(res) == "string") and res or nil end local function jsonDecode(raw) if type(raw) ~= "string" or raw == "" then return nil end local ok, d = pcall(function() return HttpSvc:JSONDecode(raw) end) return ok and d or nil end local function hopPlaceId() return tonumber(fcfg().PlaceId) or game.PlaceId end -- ── CACHE DIA cho danh sach server (chia se giua moi tab) ── local function _svCachePath() return ("RB1_servers_%d.json"):format(hopPlaceId()) end local function svCacheRead() if not _canFile then return nil end local path = _svCachePath() local ok, raw = pcall(function() if isfile(path) then return readfile(path) end end) if not ok or type(raw) ~= "string" or raw == "" then return nil end -- ★ guard rac: file qua to = hong/DB dump, BO, khong JSONDecode (tranh treo VM) local maxBytes = tonumber(fcfg().MaxCacheBytes) or 1048576 if #raw > maxBytes then pcall(function() if type(delfile) == "function" then delfile(path) end end) return nil end local d = jsonDecode(raw) if not (type(d) == "table" and type(d.servers) == "table" and type(d.exp) == "number") then return nil end return d.servers, d.exp end local function svCacheWrite(servers, exp) if not _canFile then return end pcall(function() writefile(_svCachePath(), HttpSvc:JSONEncode({ exp = exp, servers = servers })) end) end -- nguon 1: hobeojob (da loc server con slot) local function fetchHobeojob() local d = jsonDecode(httpGet(("https://hobeojob.com/api/jobs/%d"):format(hopPlaceId()))) if not (d and d.servers) then return nil end local list = {} for _, s in ipairs(d.servers) do list[#list + 1] = { job = s.job_id, playing = tonumber(s.playing) or 0, maxp = tonumber(s.max_players) or 8 } end return list end -- nguon 2 (fallback): API goc Roblox, paginate local function fetchRobloxApi(placeId) local list, cursor = {}, nil for _ = 1, (tonumber(fcfg().MaxPages) or 4) do local url = ("https://games.roblox.com/v1/games/%d/servers/Public?limit=100&excludeFullGames=true"):format( placeId ) .. (cursor and ("&cursor=" .. cursor) or "") local d = jsonDecode(httpGet(url)) if not (d and d.data) then task.wait(1.5) -- co the 429 -> nghi roi thoi break end for _, s in ipairs(d.data) do list[#list + 1] = { job = s.id, playing = tonumber(s.playing) or 0, maxp = tonumber(s.maxPlayers) or 8 } end cursor = d.nextPageCursor if not cursor then break end end return list end -- CACHE-FIRST: con han -> doc file (KHONG goi mang). Het han -> GET roi ghi file. -- GET fail -> dung tam cache CU con hon khong co gi. -- ══════════════════════════════════════════════════════════════════ -- CACHE "ONE FOR ALL" — port nguyen tang tu sab_scanner.refreshRegistry -- -- (1) IN-MEMORY con han -> khong dung dia, khong dung mang -- (2) FILE CHUNG con han -> nap, KHONG GET (chia se moi tab tren may) -- (3) het han -> GET co RETRY -> ghi FILE CHUNG -- (4) GET fail het luot -> dung TAM file chung CU (con hon rong) -- -- ⚠ JITTER AP LUC DOC, khong nuong vao exp luc ghi. -- Neu nuong vao exp thi moi tab doc ra CUNG mot moc het han -> cung GET mot luc. -- Ap luc doc thi moi acc coi file het han som hon 'jit' giay khac nhau -- -> acc som nhat GET + ghi file, acc sau doc file moi. Khong bao host. -- jspan = min(ttl/2, 2 x chu ky hop) — jitter nho hon chu ky goi thi vo dung. -- -- ⚠ CHI GHI FILE KHI CO DU LIEU. Ghi list rong se dau doc file chung, -- moi tab khac doc phai cai rong roi tuong la "khong co server". -- ══════════════════════════════════════════════════════════════════ function Fleet.fetchServers(force) local ttl = tonumber(fcfg().ServerCacheTTL) or 120 local now = os.time() -- cat bot: /api/jobs tra ~7400 server (777 KB), hop chi can vai chuc. -- Xao truoc roi cat, de moi tab khong cung nham mot nhom dau danh sach. local function trim(list) local keep = tonumber(fcfg().MaxServersKept) or 80 if #list <= keep then return list end for i = #list, 2, -1 do local j = math.random(1, i) list[i], list[j] = list[j], list[i] end local out = table.create(keep) for i = 1, keep do out[i] = list[i] end return out end if ttl > 0 and not force then local hopSec = (tonumber(fcfg().HopEveryMinutes) or 15) * 60 local jspan = math.max(1, math.min(math.floor(ttl / 2), 2 * hopSec)) local jit = (player and player.UserId or 0) % jspan -- (1) in-memory con han if _svMem and #_svMem > 0 and now < (_svMemExp - jit) then return _svMem end -- (2) FILE CHUNG con han + CO du lieu -> nap, khong GET local list, exp = svCacheRead() if list and #list > 0 and exp and now < (exp - jit) then _svMem, _svMemExp = list, exp flog(("server: FILE CHUNG (%d, con %ds) — bo GET"):format(#list, exp - now)) return list end end -- (3) het han -> GET co RETRY -> ghi FILE CHUNG local tries = math.max(1, tonumber(fcfg().GetTries) or 3) local gap = tonumber(fcfg().GetRetryGap) or 3 for attempt = 1, tries do local src = fetchHobeojob() local from = "hobeojob" if not (src and #src > 0) and fcfg().UseRobloxApiFallback ~= false then src = fetchRobloxApi(hopPlaceId()) from = "Roblox API" end if src and #src > 0 then src = trim(src) local exp = os.time() + ttl _svMem, _svMemExp = src, exp svCacheWrite(src, exp) -- CHI ghi khi CO du lieu flog(("server: %s (%d) -> ghi FILE CHUNG (het han sau %ds)"):format(from, #src, ttl)) return src end if attempt < tries then flog(("GET server fail (%d/%d) -> thu lai sau %ss"):format(attempt, tries, gap)) task.wait(gap) end end -- (4) fail het luot -> file chung CU (ke ca qua han) local stale = svCacheRead() if stale and #stale > 0 then _svMem, _svMemExp = stale, now -- coi nhu vua het han -> lan sau thu GET som flog(("server: FILE CHUNG CU (%d) — ca 2 nguon fail"):format(#stale)) return stale end flog("khong co server tu bat ky nguon nao") return nil end -- ── presence heartbeat ── local function netPingMs() local ok, ms = pcall(function() local n = StatsSvc and StatsSvc.Network and StatsSvc.Network.ServerStatsItem if n and n["Data Ping"] then return n["Data Ping"]:GetValue() end return 0 end) ms = (ok and tonumber(ms)) or 0 return math.floor(math.clamp(ms, 0, 600000)) end function Fleet.postPresence() if fcfg().PresenceEnabled == false or not _httpReq or not player then return end pcall(_httpReq, { Url = "https://hobeojob.com/api/presence", Method = "POST", Headers = { ["Content-Type"] = "application/json" }, Body = HttpSvc:JSONEncode({ account = player.Name, placeId = game.PlaceId, jobId = tostring(game.JobId), players = math.min(#Players:GetPlayers(), 200), ping = netPingMs(), hops = getgenv().__RB1_Hops or 0, uptime = math.floor(tick() - _bootAt), }), }) end -- ── bao server chet: teleport tra GameEnded = server khong ton tai -> go khoi pool ── function Fleet.reportDead(placeId, jobId) if fcfg().ReportDead == false or not jobId or not _httpReq then return end pcall(_httpReq, { Url = ("https://hobeojob.com/api/jobs/%d/dead"):format(placeId), Method = "POST", Headers = { ["Content-Type"] = "application/json" }, Body = '{"job_id":"' .. tostring(jobId) .. '"}', }) flog("[DEAD] bao server chet: " .. tostring(jobId)) end -- ── giu cho jobId dich truoc khi teleport (chong clone nhay trung sv) ── function Fleet.blacklistJob(placeId, jobId) if fcfg().PostBlacklist == false or not jobId or not _httpReq then return end pcall(_httpReq, { Url = ("https://hobeojob.com/api/jobs/%d/blacklist"):format(placeId), Method = "POST", Headers = { ["Content-Type"] = "application/json" }, Body = '{"job_id":"' .. tostring(jobId) .. '"}', }) end -- ── hop ── function Fleet.hop() local placeId = hopPlaceId() local servers = Fleet.fetchServers() if not servers or #servers == 0 then _noSvRetries = _noSvRetries + 1 if _noSvRetries >= (tonumber(fcfg().NoServerMaxRetries) or 3) then flog("khong co server sau " .. _noSvRetries .. " lan -> Roblox matchmaking") _noSvRetries = 0 _tpFailed = false pcall(TeleportService.Teleport, TeleportService, placeId, player) return true end flog(("khong co server (lan %d) -> cho roi thu lai"):format(_noSvRetries)) return false, "noserver" end _noSvRetries = 0 local cands = {} for _, s in ipairs(servers) do if s.job and s.job ~= game.JobId and not _visited[s.job] then cands[#cands + 1] = s.job end end if #cands == 0 then _visited = {} flog("het job moi -> reset visited") return false, "novisited" end for i = #cands, 2, -1 do local j = math.random(1, i) cands[i], cands[j] = cands[j], cands[i] end local tries = math.min(#cands, tonumber(fcfg().MaxRetries) or 8) for i = 1, tries do local jobId = cands[i] _visited[jobId] = true _tpFailed, _tpFailResult = false, nil Fleet.blacklistJob(placeId, jobId) task.wait(0.2) flog(("HOP %d/%d -> %s"):format(i, tries, jobId)) pcall(TeleportService.TeleportToPlaceInstance, TeleportService, placeId, jobId, player) local t0 = os.clock() while os.clock() - t0 < (tonumber(fcfg().WaitPerTry) or 6) do if _tpFailed then break end task.wait(0.25) end if not _tpFailed then getgenv().__RB1_Hops = (getgenv().__RB1_Hops or 0) + 1 return true end -- GameEnded = server chet -> bao dead de go khoi pool if _tpFailResult == Enum.TeleportResult.GameEnded then Fleet.reportDead(placeId, jobId) end task.wait(tonumber(fcfg().RetryBackoff) or 1.5) end -- het luot van khong vao duoc -> matchmaking flog(("%d lan deu fail -> matchmaking"):format(tries)) _tpFailed = false pcall(TeleportService.Teleport, TeleportService, placeId, player) return false, "allfail" end function Fleet.start() if fcfg().Enabled == false then return end pcall(function() TeleportService.TeleportInitFailed:Connect(function(p, result) if p == player then _tpFailed, _tpFailResult = true, result end end) end) -- presence: POST ngay khi vao, roi moi Interval giay task.spawn(function() while true do pcall(Fleet.postPresence) task.wait(math.max(30, tonumber(fcfg().PresenceInterval) or 60)) end end) -- hop dinh ky task.spawn(function() local everyMin = tonumber(fcfg().HopEveryMinutes) or 15 if everyMin <= 0 then return end while true do task.wait(everyMin * 60) if fcfg().HopEnabled == false then continue end -- khong cat ngang viec dang lam: cho farm/spin/khoa cua xong local waitBusy = tick() + 120 while (farmActionBusy or phantomWheelBusy or lockDoorBusy or rebirthInProgress) and tick() < waitBusy do task.wait(1) end local _th = Action.T.begin("hop", ("den han %d phut"):format(everyMin)) local ok, why = pcall(Fleet.hop) Action.T.done(_th, ok, tostring(why)) if not ok then warn("[Fleet] hop loi: " .. tostring(why)) end end end) flog("khoi dong: presence + hop moi " .. tostring(fcfg().HopEveryMinutes or 15) .. " phut") end Action.debugFleet = function() local servers = Fleet.fetchServers() local cached, exp = svCacheRead() return { placeId = hopPlaceId(), hops = getgenv().__RB1_Hops or 0, uptimeSec = math.floor(tick() - _bootAt), serverCount = servers and #servers or 0, cacheCount = cached and #cached or 0, cacheExpiresIn = exp and (exp - os.time()) or nil, cachePath = _svCachePath(), hasHttpRequest = _httpReq ~= nil, canFile = _canFile, } end end)() -- TU CAM TOOL TANG TOC ------------------------------------------------------ -- Cong thuc (decompile ReplicatedStorage.Controllers.SpeedController, 2026-09-06): -- WalkSpeed = StarterPlayer.CharacterWalkSpeed x Tool:GetAttribute("SpeedModifier") -- Do live: CharacterWalkSpeed = 34. Chi can CAM tool co SpeedModifier > 1 la nhanh hon. -- -- ⚠⚠ CHI EQUIP, TUYET DOI KHONG MUA BANG SCRIPT. -- Mua = goi RF/CoinsShopService/RequestBuy. Da lam BAY MOT ACCOUNT ngay 2026-09-06: -- InvokeServer treo vinh vien (server chan o tang truoc handler) roi dinh BAC. -- Packages.Net bam ten remote theo ngu canh nen goi instance ten phang la sai cau truc. -- Muon tu mua thi bat AUTO BUY BANG TAY trong game mot lan — game co san tinh nang do -- (CoinsShopService/ToggleAutoBuy, luu vao du lieu tai khoan), khong can script. -- -- Humanoid:EquipTool la API gameplay thuong, DA THU CHAY THAT tren server: OK. -- -- ⚠ ReplicatedStorage.Items.* KHONG mang SpeedModifier (server dat luc cap), nen phai -- doc tren ban nam trong Backpack cua chinh minh, khong doc ban mau trong RS. ------------------------------------------------------------------------------ -- Uu tien thap = cam truoc. Chinh qua getgenv().RebirthConfig.SpeedToolRank. -- Do live: Speed Coil -> SpeedModifier 1.5 (WalkSpeed 34 -> 51, di 31.6 -> 39.8 stud/s). -- Coil Combo dat hon (20k, rb2) nen doan la manh hon; chua do duoc. local SPEED_TOOL_RANK = (getgenv().RebirthConfig or {}).SpeedToolRank or { ["Coil Combo"] = 1, ["Speed Coil"] = 2, ["Candy Coils"] = 3, ["Christmas Coils"] = 4, } -- TU MUA TOOL TANG TOC ------------------------------------------------------ -- ⚠⚠ PHAI DUNG GAN NPC. DO LIVE 2026-09-06, ca huong sai lan huong dung: -- SAI : goi thang RF/CoinsShopService/RequestBuy tu CACH SHOP 79 STUD, shop UI dang -- DONG -> InvokeServer TREO VINH VIEN -> account bi KICK. Lam 2 lan, bay 2 lan. -- DUNG: di toi <= 15 stud -> fireproximityprompt mo shop -> bam nut Buy. Khong sao ca. -- => Loi khong nam o remote. Nam o cho THIEU NGU CANH: khong o gan, va chua bat tay -- RE/ShopService/ShopOpened (chi buoc mo prompt moi phat cai do). -- -- Vi vay ham nay TUYET DOI khong duoc bo qua buoc di chuyen va buoc mo shop. -- Moi buoc deu kiem lai truoc khi sang buoc sau; sai mot cai la bo cuoc. ------------------------------------------------------------------------------ Action.buySpeedTool = function() local cfg = getgenv().RebirthConfig or {} if cfg.AutoBuySpeedTool ~= true then return false -- mac dinh TAT: no keo nhan vat roi base mot chuyen end local want = tostring(cfg.SpeedToolName or "Speed Coil") -- da co roi thi thoi (chi so huu duoc 1 cai moi loai) local bp = player and player:FindFirstChild("Backpack") local ch = player and player.Character if not (bp and ch) then return false end if bp:FindFirstChild(want) then return true end local held = ch:FindFirstChildOfClass("Tool") if held and held.Name == want then return true end -- ⚠ KIEM TIEN TRUOC KHI NHUC CHAN. Ban dau toi viet thieu buoc nay nen bot chay -- het quang duong ra shop roi moi phat hien khong mua noi, xong ve tay khong. -- DO LIVE 2026-09-08: gia doc tu Datas.ShopItems[ten].Price, va "Coins" trong shop -- CHINH LA Cash o leaderstats — doi chieu 41 muc tu $500 den $10 ty, LECH 0. local shopData = getDataModule("ShopItems") local entry = shopData and shopData[want] local price = entry and tonumber(entry.Price) if not price then return nil -- khong doc duoc gia thi thoi, dung doan end if getCash() < price then return nil -- KHONG di, va KHONG tinh la mot lan thu (xem cho goi) end -- khoa rebirth: mua khong noi thi cung dung di if entry.RebirthRequired and getRebirths() < entry.RebirthRequired then return nil end local _t = Action.T.begin("mua-toc-do", ("%s $%d"):format(want, price)) local deadline = tick() + 60 -- (2) DI TOI NPC. Bo qua buoc nay = bi kick. local shop = Workspace:FindFirstChild("Shop") local npc = shop and shop:FindFirstChild("ShopNPCCash") local prompt = npc and npc:FindFirstChild("OpenInterface") if not prompt then return Action.T.done(_t, false, "khong thay NPC shop") end local maxD = tonumber(prompt.MaxActivationDistance) or 15 local spot = npc:GetPivot().Position if pathfindTo then pathfindTo(spot, deadline, math.max(4, maxD - 6)) end local hrp = player.Character and player.Character:FindFirstChild("HumanoidRootPart") local d = hrp and (hrp.Position - spot).Magnitude or math.huge if d > maxD then return Action.T.done(_t, false, ("con cach %.0f stud (can <= %d) — BO, khong ban tu xa"):format(d, maxD)) end -- (2) MO SHOP bang prompt. Day moi la buoc bat tay voi server. local gui = player.PlayerGui and player.PlayerGui:FindFirstChild("CoinsShop") local root = gui and gui:FindFirstChild("CoinsShop") if not root then return Action.T.done(_t, false, "khong thay CoinsShop UI") end if not (gui.Enabled and root.Visible) then pcall(function() fireproximityprompt(prompt) end) local t0 = tick() while tick() - t0 < 5 and not (gui.Enabled and root.Visible) do task.wait(0.2) end end if not (gui.Enabled and root.Visible) then return Action.T.done(_t, false, "shop khong mo — BO, khong bam Buy khi shop dong") end -- (3) BAM NUT BUY (duong cua chinh game: AnimatedButton nghe Instance.Activated) local item = root.Content and root.Content:FindFirstChild("Items") item = item and item:FindFirstChild(want) local buy = item and item:FindFirstChild("Buy") -- ⚠ Visible CHI false khi khoa rebirth. Het tien thi nut VAN Visible, chi doi mau, -- VA game khong noi handler Activated -> bam vao khong xay ra gi. -- Theo CoinsShopController: du tien -> trang (255,255,255), khong du -> xam (138,138,138). if not (buy and buy.Visible) then return Action.T.done(_t, false, "nut Buy khong hien (khoa rebirth)") end if buy.ImageColor3 ~= Color3.fromRGB(255, 255, 255) then return Action.T.done(_t, false, ("nut Buy XAM = game bao khong du tien (co $%d)"):format(getCash())) end pcall(function() firesignal(buy.Activated) end) local t1 = tick() while tick() - t1 < 8 and not bp:FindFirstChild(want) do task.wait(0.3) end if bp:FindFirstChild(want) then Action.equipSpeedTool() return Action.T.done(_t, true, "mua duoc, da cam") end return Action.T.done(_t, false, "bam roi nhung khong vao Backpack") end -- MO LUCKY BLOCK ------------------------------------------------------------ -- Hop Lucky Block nam CHIEM mot o be. Prompt cua no la Action="Open", -- KHAC voi brainrot (Action="Grab"), nen moi tang dem o deu bo sot no. -- -- DO LIVE 2026-09-15 tren acc that (slot 4, plot cua minh): -- HoldDuration = 1.5, MaxActivationDistance = 10, Enabled = true -- fireproximityprompt(prompt) -> MO DUOC, hop bien khoi be. -- ⚠ Khac voi prompt CUOP (cung HoldDuration 1.5) von KHONG an fireproximityprompt -- (xem ghi chu sab-steal-mechanism) — cai nay thi an, da thu that. ------------------------------------------------------------------------------ Action.openLuckyBlocks = function() if (getgenv().RebirthConfig or {}).AutoOpenLucky == false then return false end local ap = getAnimalPodiums() if not ap then return false end local prompt, part for i = 1, MAX_PODIUMS do local slot = ap:FindFirstChild(tostring(i)) if slot then for _, d in ipairs(slot:GetDescendants()) do if d:IsA("ProximityPrompt") and tostring(d.ObjectText or ""):lower():find("lucky", 1, true) and d.Enabled == true then prompt = d part = d.Parent and d.Parent.Parent break end end end if prompt then break end end if not (prompt and part) then return false end local _t = Action.T.begin("mo-lucky", tostring(prompt.ObjectText)) local deadline = tick() + 30 local maxD = tonumber(prompt.MaxActivationDistance) or 10 local hrp = player and player.Character and player.Character:FindFirstChild("HumanoidRootPart") if hrp and (hrp.Position - part.Position).Magnitude > maxD - 3 then if pathfindTo then pathfindTo(part.Position, deadline, math.max(3, maxD - 4)) end end hrp = player and player.Character and player.Character:FindFirstChild("HumanoidRootPart") local d = hrp and (hrp.Position - part.Position).Magnitude or math.huge if d > maxD then return Action.T.done(_t, false, ("con cach %.0f stud (can <= %d)"):format(d, maxD)) end pcall(function() fireproximityprompt(prompt) end) -- cho hop bien mat; het gio thi bao that bai de vong sau thu lai local t0 = tick() while tick() - t0 < 5 and prompt.Parent do task.wait(0.25) end markPodiumCacheDirty() if prompt.Parent then return Action.T.done(_t, false, "ban roi nhung hop van con") end return Action.T.done(_t, true, "da mo, o be duoc giai phong") end Action.equipSpeedTool = function() if (getgenv().RebirthConfig or {}).AutoEquipSpeedTool == false then return false end local ch = player and player.Character local hum = ch and ch:FindFirstChildOfClass("Humanoid") if not hum then return false end -- dang cam do tang toc roi thi thoi, khoi cam lai moi vong local held = ch:FindFirstChildOfClass("Tool") if held and (tonumber(held:GetAttribute("SpeedModifier")) or 0) > 1 then return true end local bp = player:FindFirstChild("Backpack") if not bp then return false end -- ⚠⚠ KHONG loc bang SpeedModifier tren ban trong BACKPACK — DO LIVE 2026-09-06: -- truoc khi cam, Tool chi co attribute { CurrentSlot }. -- sau khi cam moi co { CurrentSlot, SpeedModifier = 1.5 }. -- Server chi gan attribute luc Tool vao tay. Loc theo no o Backpack = KHONG BAO GIO -- cam duoc gi (ban dau toi viet sai dung kieu do). -- => Nhan dien theo TEN, xep uu tien. Van uu tien attribute neu tinh co da co. local best, bestMod, bestRank = nil, 0, math.huge for _, t in ipairs(bp:GetChildren()) do if t:IsA("Tool") then local m = tonumber(t:GetAttribute("SpeedModifier")) or 0 local rank = SPEED_TOOL_RANK[t.Name] if m > bestMod and m > 1 then best, bestMod, bestRank = t, m, -1 elseif rank and bestMod <= 1 and rank < bestRank then best, bestRank = t, rank end end end if not best then return false end local ok = pcall(function() hum:EquipTool(best) end) if ok then -- doc lai attribute SAU khi cam: luc nay server moi gan local m = tonumber(best:GetAttribute("SpeedModifier")) or 0 local hs = m > 0 and ("x%.2f -> WalkSpeed %.0f"):format(m, (hum.WalkSpeed or 0)) or ("WalkSpeed %.0f"):format(hum.WalkSpeed or 0) Action.T.mark(("cam %s | %s"):format(best.Name, hs)) end return ok end -- JOIN PLACE (matchmaking) -------------------------------------------------- -- Teleport chi bang PLACE ID, KHONG kem jobId — server nao con cho cung duoc. -- Khac TeleportToPlaceInstance (~L4219 cua Fleet) vi cai do ep dung mot jobId. -- -- Thay cho Kick + messagebox "Kill Me": Kick lam mat luon tien trinh, con cai nay -- dua thang acc sang place dich, khong can tool ngoai bat lai. -- -- Teleport co the FAIL (place full / rate limit) va khi fail thi KHONG co loi nem -- ra — no ban TeleportInitFailed. Nen phai lang nghe signal do roi thu lai, -- chu pcall khong bat duoc gi. ------------------------------------------------------------------------------ Action.joinPlaceId = 109983668079237 Action.joinPlace = function(placeId, reason) placeId = tonumber(placeId) or tonumber((getgenv().RebirthConfig or {}).JoinPlaceId) or Action.joinPlaceId print(("[JOIN] teleport ve place %d | %s"):format(placeId, tostring(reason or ""))) local failed, conn = false, nil pcall(function() conn = TeleportService.TeleportInitFailed:Connect(function(p, result) if p == player then failed = true warn("[JOIN] TeleportInitFailed: " .. tostring(result)) end end) end) local ok = false for i = 1, 5 do failed = false pcall(TeleportService.Teleport, TeleportService, placeId, player) -- teleport thanh cong thi client bi go khoi server, doan duoi khong chay tiep. -- Con o day sau 10s tuc la chua di duoc. local deadline = tick() + 10 while tick() < deadline and not failed do task.wait(0.25) end if not failed then ok = true break end warn(("[JOIN] fail lan %d/5, thu lai sau 3s"):format(i)) task.wait(3) end if conn then pcall(function() conn:Disconnect() end) end if not ok then warn("[JOIN] 5 lan deu fail") end return ok end function Action.doRebirth() local function hasRequiredAnimals(owned) for _, name in ipairs(ownedList) do if not owned[name] then return false, name end end return true end local function getRebirthUi() local playerGui = player and player:FindFirstChild("PlayerGui") local screen = playerGui and playerGui:FindFirstChild("Rebirth") local frame = screen and screen:FindFirstChild("Rebirth") local content = frame and frame:FindFirstChild("Content") local header = frame and frame:FindFirstChild("Header") local leftCenter = playerGui and playerGui:FindFirstChild("LeftCenter") local leftCenterFrame = leftCenter and leftCenter:FindFirstChild("LeftCenter") local buttons = leftCenterFrame and leftCenterFrame:FindFirstChild("Buttons") return screen, frame, buttons and buttons:FindFirstChild("Rebirth"), content and content:FindFirstChild("Rebirth"), header and header:FindFirstChild("Close") end local function isUsableRebirthButton(button) return button and button:IsA("GuiButton") and button.Visible and button.Active and button.Interactable and button.AbsoluteSize.X > 1 and button.AbsoluteSize.Y > 1 end local function closeRebirthUi() local screen, frame, _, _, closeButton = getRebirthUi() if not screen or not screen.Enabled or not frame or not frame.Visible then return true end if not closeButton or not closeButton:IsA("GuiButton") then return false end local signaled = pcall(function() firesignal(closeButton.Activated) end) if not signaled then return false end local deadline = tick() + 2 while tick() < deadline do local currentScreen, currentFrame = getRebirthUi() if not currentScreen or not currentScreen.Enabled or not currentFrame or not currentFrame.Visible then return true end task.wait(0.1) end local currentScreen, currentFrame = getRebirthUi() return not currentScreen or not currentScreen.Enabled or not currentFrame or not currentFrame.Visible end local function openRebirthUi() local screen, frame, openButton = getRebirthUi() if screen and screen.Enabled and frame and frame.Visible then return true end if not isUsableRebirthButton(openButton) then return false end local signaled = pcall(function() firesignal(openButton.Activated) end) if not signaled then return false end local deadline = tick() + 3 while tick() < deadline do screen, frame = getRebirthUi() if screen and screen.Enabled and frame and frame.Visible then return true end task.wait(0.1) end return false end if rebirthRequestTimedOut then warn("❌ Rebirth request previously timed out; refusing a duplicate request") return false end if changingFolder or changedFolder then warn("❌ Folder change already started; refusing rebirth") return false end if rebirthInProgress then warn("❌ Rebirth already in progress!") return false end if rebirthCompleted or getRebirths() >= MAX_REBIRTHS then rebirthCompleted = true warn("❌ Max rebirths already reached!") return false end if not player or not player.Parent then warn("❌ Player not ready for rebirth!") return false end if getCash() < REBIRTH_CASH then warn("❌ Not enough cash for rebirth!") return false end local _, owned = getPodiumInfo() local hasAnimals, missingAnimal = hasRequiredAnimals(owned) if not hasAnimals then warn("❌ Missing required animal for rebirth: " .. tostring(missingAnimal)) return false end if changingFolder or changedFolder then warn("❌ Folder change started during rebirth preflight") return false end rebirthInProgress = true local rebirthSuccess = false local rebirthBefore = getRebirths() local cashBefore = getCash() local rebirthUiClicked = false local ok, err = pcall(function() if not player or not player.Parent or rebirthBefore >= MAX_REBIRTHS or cashBefore < REBIRTH_CASH then warn("❌ Rebirth preflight failed before opening UI!") return end local _, latestOwned = getPodiumInfo() local stillHasAnimals, latestMissingAnimal = hasRequiredAnimals(latestOwned) if not stillHasAnimals then warn("❌ Missing required animal before rebirth: " .. tostring(latestMissingAnimal)) return end if not openRebirthUi() then closeRebirthUi() warn("❌ Could not open Rebirth UI") return end local uiDelay = tonumber((getgenv().RebirthConfig or {}).RebirthUiDelay) or 2 if uiDelay ~= uiDelay then uiDelay = 2 end task.wait(math.clamp(uiDelay, 0, 10)) local screen, frame, _, rebirthButton = getRebirthUi() local buttonColor = rebirthButton and rebirthButton.ImageColor3 if not screen or not screen.Enabled or not frame or not frame.Visible or not isUsableRebirthButton(rebirthButton) or not buttonColor or math.min(buttonColor.R, buttonColor.G, buttonColor.B) < 0.95 then closeRebirthUi() warn("❌ Rebirth UI is not ready") return end local _, clickOwned = getPodiumInfo() local clickHasAnimals, clickMissingAnimal = hasRequiredAnimals(clickOwned) if not player or not player.Parent or getRebirths() ~= rebirthBefore or getCash() < REBIRTH_CASH or not clickHasAnimals then closeRebirthUi() warn("❌ Rebirth pre-click validation failed: " .. tostring(clickMissingAnimal)) return end screen, frame, _, rebirthButton = getRebirthUi() buttonColor = rebirthButton and rebirthButton.ImageColor3 if not screen or not screen.Enabled or not frame or not frame.Visible or not isUsableRebirthButton(rebirthButton) or not buttonColor or math.min(buttonColor.R, buttonColor.G, buttonColor.B) < 0.95 then closeRebirthUi() warn("❌ Rebirth UI changed before click") return end local clickDone = false local clickOk, clickErr rebirthUiClicked = true local clickThread = task.spawn(function() clickOk, clickErr = pcall(function() firesignal(rebirthButton.Activated) end) clickDone = true end) local confirmDeadline = tick() + REBIRTH_INVOKE_TIMEOUT_SECONDS while tick() < confirmDeadline do if getRebirths() > rebirthBefore then rebirthSuccess = true closeRebirthUi() print("✅ Rebirth confirmed by stat change! " .. rebirthBefore .. " → " .. getRebirths()) return end if clickDone and not clickOk then break end task.wait(0.1) end if getRebirths() > rebirthBefore then rebirthSuccess = true closeRebirthUi() print("✅ Rebirth confirmed at deadline! " .. rebirthBefore .. " → " .. getRebirths()) return end rebirthRequestTimedOut = true if not clickDone then pcall(task.cancel, clickThread) end closeRebirthUi() warn("❌ Rebirth UI result unknown; refusing a duplicate click: " .. tostring(clickErr)) if player and player.Parent then player:Kick("Rebirth UI không xác nhận; dừng để tránh click trùng.") end end) if not ok then closeRebirthUi() if rebirthUiClicked and not rebirthSuccess and getRebirths() > rebirthBefore then rebirthSuccess = true print("✅ Rebirth confirmed after UI error! " .. rebirthBefore .. " → " .. getRebirths()) elseif rebirthUiClicked and not rebirthSuccess then rebirthRequestTimedOut = true if player and player.Parent then player:Kick("Rebirth UI lỗi sau click; dừng để tránh click trùng.") end end warn("❌ Rebirth attempt error: " .. tostring(err)) end rebirthInProgress = false if rebirthSuccess then rebirthCompleted = true task.wait(3) Action.sendWebhook( "✅ Rebirth Complete!", "**" .. player.Name .. "** has rebirthed!\nTotal Rebirths: **" .. getRebirths() .. "**", 5763719, { { name = "Thoi gian farm", value = Action.T.uptime(), inline = true }, { name = "Tien cuoi", value = "$" .. tostring(getCash()), inline = true }, } ) markPlotCacheDirty() markPurchasePromptCacheDirty() changeToFolderIfReady() Action.joinPlace(nil, ("rebirth xong, tong %s, farm het %s") :format(tostring(getRebirths()), Action.T.uptime())) end return rebirthSuccess end print("🚀 Starting farming script!") startPerformanceBoost() if not waitForFullLoad() then while true do task.wait(60) end end -- POST username cu DA THAY bang Fleet.postPresence (heartbeat day du: -- account/placeId/jobId/players/ping/hops/uptime), va place id KHONG con -- hard-code 109983668079237 — server dang choi co the la place khac. -- Fleet lo luon: report dead, hop dinh ky 15p, cache dia chia se giua tab. Fleet.start() -- canh cua nha: giu khoa, het han la dong lai NGAY if (getgenv().RebirthConfig or {}).AutoLockBase ~= false then LockDoor.start() end local rcSpin = getgenv().RebirthConfig or {} local spinEnabled = true if rcSpin.AutoEclipseWheel ~= nil then spinEnabled = rcSpin.AutoEclipseWheel == true elseif rcSpin.AutoSpinWheel ~= nil then spinEnabled = rcSpin.AutoSpinWheel == true elseif rcSpin.AutoPhantomWheel ~= nil then spinEnabled = rcSpin.AutoPhantomWheel == true end if spinEnabled then startAutoPhantomWheel() else setPhantomWheelStatus("Spin: TAT") end task.spawn(function() while not changedFolder do changeToFolderIfReady() task.wait(math.max(1, tonumber((getgenv().RebirthConfig or {}).ChangeScanSec) or 10)) end end) -- (check rebirth da chuyen len DAU FILE — acc rb>=1 khong bao gio chay toi day) if not autofarmEnabled then print("⏭️ Server khong trong luc inject -> khong farm, chi giu ChangeToFolder.") while true do task.wait(60) end end print("✅ Account is new, starting autofarm...") task.wait(3) Action.sendWebhook( "🚀 Auto-Farm Started", "**" .. player.Name .. "** is now farming!\n**Target:** Rebirth " .. MAX_REBIRTHS, 65280, { { name = "👤 Account", value = player.Name, inline = true }, { name = "🎯 Priority", value = "Trippi Troppi\nGangster Footera", inline = true }, { name = "💰 Target Cash", value = "$" .. tostring(REBIRTH_CASH), inline = true }, } ) while phantomWheelBusy do task.wait(0.1) end farmActionBusy = true local initialCollectOk, initialCollectErr = pcall(Action.collectCash) farmActionBusy = false if not initialCollectOk then warn("⚠️ Initial collect error: " .. tostring(initialCollectErr)) end while true do local loopWait = 2 farmActionBusy = true local ok, err = pcall(function() if phantomWheelBusy then Action.T.setPhase("cho-spin", "nhuong nhan vat cho banh xe") return end -- dang chay ve khoa cua: nhuong quyen dieu khien nhan vat if lockDoorBusy then Action.T.setPhase("cho-khoa-cua", "nhuong nhan vat cho LockDoor") return end -- mua do tang toc: thu toi da 3 lan roi thoi (no keo nhan vat roi base) -- ⚠ buySpeedTool tra nil khi bo vi THIEU TIEN (chua di dau ca) va tra -- true/false khi da THAT SU di mot chuyen. Chi dem chuyen di that, neu khong -- thi 3 vong dau con ngheo la khoa vinh vien, sau giau cung khong mua nua. if (Action.buyToolTries or 0) < 3 and not lockDoorBusy and not phantomWheelBusy then if (getgenv().RebirthConfig or {}).AutoBuySpeedTool == true then if Action.buySpeedTool() ~= nil then Action.buyToolTries = (Action.buyToolTries or 0) + 1 end end end -- ★ MO LUCKY BLOCK truoc moi thu: hop nay chiem o be ma khong duoc dem la -- brainrot, de lam bot doi mua vao o da co vat roi ket. Tiet luu 10 giay. if tick() - (Action.lastLuckyAt or 0) >= 10 and not lockDoorBusy and not phantomWheelBusy then Action.lastLuckyAt = tick() Action.openLuckyBlocks() end -- cam lai do tang toc neu dang khong cam (vd sau khi chet/respawn). -- Tiet luu 5 giay: khong co gi de cam thi cung khong quet Backpack moi vong. if tick() - (Action.lastEquipAt or 0) >= 5 then Action.lastEquipAt = tick() Action.equipSpeedTool() end local currentCash = getCash() -- ══ CANH TIEN DUNG YEN ══════════════════════════════════════════════ -- Tien KHONG DOI qua N giay = bot ket that su -> kick cho tool auto rejoin lo. -- Bat ky thay doi nao cung dat lai dong ho: tang (gom tien) LAN giam (mua). -- -- Vi sao 180 giay la dung nguong: COLLECT_INTERVAL = 55s nen mot phien khoe -- manh phai co it nhat 3 lan tien nhuc nhich trong khoang do. Im lang tron 3 -- phut nghia la ca gom LAN mua deu chet — khong con gia thuyet lanh nao. -- -- ⚠ KHONG dem trong luc rebirth (doi UI, click, cho server) va khong dem khi -- LockDoor/wheel dang giu nhan vat — luc do bot dung yen la DUNG. if rebirthInProgress or lockDoorBusy or phantomWheelBusy then Action.cashMoveAt = tick() elseif Action.lastCashSeen ~= currentCash then Action.lastCashSeen = currentCash Action.cashMoveAt = tick() else local stallSec = tonumber((getgenv().RebirthConfig or {}).StallKickSec) or 180 local stuck = tick() - (Action.cashMoveAt or tick()) if stallSec > 0 and stuck >= stallSec then warn(("[STALL] tien dung yen $%s suot %.0fs -> kick"):format( tostring(currentCash), stuck)) Action.sendWebhook( "Bot ket - tien dung yen", ("**%s**: tien khong doi $%s trong %.0f giay -> kick de rejoin"):format( player.Name, tostring(currentCash), stuck), 16753920, { { name = "Pha", value = tostring(Action.T.phase), inline = true }, { name = "Da chay", value = Action.T.uptime(), inline = true }, } ) task.wait(1) -- kip gui webhook truoc khi mat ket noi player:Kick(("Tien dung yen %.0fs (pha: %s) — kick de rejoin"):format( stuck, tostring(Action.T.phase))) return end end local podiumCount, owned = getPodiumInfo() local hasTrip = owned["Trippi Troppi"] or false local hasGang = owned["Gangster Footera"] or false Action.T.setPhase( "farm", ("$%s | be %d/10 | Trippi=%s Gangster=%s"):format( tostring(currentCash), podiumCount, hasTrip and "co" or "chua", hasGang and "co" or "chua" ) ) local baseIncome = getBaseIncomePerSecond and getBaseIncomePerSecond() or 0 local waitingForPurchaseIncome = lastPurchaseTime > 0 and tick() - lastPurchaseTime < PURCHASE_INCOME_GRACE_SECONDS if currentCash < 25 and baseIncome <= 0 and not waitingForPurchaseIncome then player:Kick("Tiền dưới $25 và tổng thu nhập <= 0; dừng để tránh kẹt do tranh mua.") return end if currentCash >= REBIRTH_CASH and hasTrip and hasGang then print("💰 Reached rebirth cash! Rebirthing...") if Action.doRebirth() then farmActionBusy = false while true do task.wait(60) end end warn("❌ Rebirth failed, retrying in 5 seconds...") loopWait = 5 return end -- ══ CHE DO FARM-ONLY: o nha, KHONG di mua nua, chi gom tien ══════════ -- Du income >= 600 va da co Trippi + Gangster thi khoi chay di mua: -- dung yen cho tien tu chay ve, 55 giay gom mot lan. CO Y, khong phai loi. -- -- ⚠ FPS: DO LIVE 2026-09-05 tren server that (WalkSpeed 34), di 40 stud: -- cap 10 -> FPS thuc 10.0 -> 21.1 stud/s (1.90s) -- cap 30 -> FPS thuc 30.0 -> 31.6 stud/s (1.27s) -- cap 60 -> FPS thuc 60.0 -> 31.6 stud/s (1.28s) -- Humanoid mo phong theo FRAME nen it frame = it buoc vat ly = di CHAM THAT. -- 10 FPS mat 33% toc do; 30 va 60 GIONG HET nhau nen 30 la diem toi uu. -- -- Vi vay: 10 FPS luc RANH (~50 trong moi 55 giay), nang len luc DI GOM roi -- ha lai. Duoc gan tron phan tiet kiem CPU ma khong lam collect cham di. -- Muon 10 FPS suot ca luc gom thi dat CollectFpsCap = 10. if baseIncome >= FARM_ONLY_INCOME_PER_SECOND and hasTrip and hasGang then if not farmOnlyFpsApplied then farmOnlyFpsApplied = true if type(setfpscap) == "function" then pcall(setfpscap, tonumber((getgenv().PerformanceConfig or {}).FarmOnlyFpsCap) or 10) end end if tick() - lastCollect >= COLLECT_INTERVAL then if type(setfpscap) == "function" then pcall(setfpscap, tonumber((getgenv().PerformanceConfig or {}).CollectFpsCap) or 30) end Action.collectCash() if type(setfpscap) == "function" then pcall(setfpscap, tonumber((getgenv().PerformanceConfig or {}).FarmOnlyFpsCap) or 10) end end return end if Action.freeSlotForRequiredAnimal(currentCash, owned, podiumCount) then return end if tick() - lastCollect >= COLLECT_INTERVAL then Action.collectCash() -- ★ collect VUA cong tien vao. currentCash doc tu dau vong la CU roi. -- Khong doc lai thi dung so cu di mua — co the com mot con $100.000 -- trong khi vua du tien REBIRTH. Doc lai va thoat som de vong sau -- vao thang nhanh rebirth. currentCash = getCash() if currentCash >= REBIRTH_CASH and hasTrip and hasGang then loopWait = 0 return end loopWait = 0.2 -- vua gom tien xong: xet mua ngay, khong ngu 2s end -- ★ SAN THU NHAP neo vao BE CUA MINH, khong neo vao ly thuyet mua noi. -- Be con o trong -> san 0: o trong kiem 0 $/s, mua gi cung hon de khong. -- Be DAY -> san = con te nhat x 1.25: dung mua thu ma lat sau lai -- phai ban di. Chon dung nguong ma freeSlotForUpgrade doi, -- de khong chon hut roi bo, phi ca mot vong. Action.buyFloor = 0 Action.buyCtx = { income = baseIncome, soldGen = 0, travel = 10 } if podiumCount >= MAX_PODIUMS then local worst = Action.findLowestIncomeSellCandidate() if worst and worst.generation > 0 then -- be DAY: mua = phai BAN con te nhat di, nen income rong chi tang -- (g - worst). Va di duong lau hon vi con phai chay di ban. Action.buyFloor = worst.generation * MIN_UPGRADE_MULTIPLIER Action.buyCtx.soldGen = worst.generation Action.buyCtx.travel = 16 end end local item, prompt = getBestAvailableNow(currentCash, owned, Action.buyFloor) if item and prompt then -- ★ doc LAI so be: podiumCount lay tu dau vong lap, sau collect/mua co the da khac. -- Doc cu => tuong con cho => di mua => server tu choi => spam 40s vao hu vo. local nowCount = select(1, getPodiumInfo()) or podiumCount -- ★ CHOT GIAO HANG: con vua mua con DANG DI BO ve be nen no chua duoc -- dem vao nowCount. Cong so con dang ve vao truoc khi quyet dinh, neu -- khong se mua chong len dung mot cho -> server tu choi, ban 20 phat -- vao hu vo (log 18:37:56 -> 18:38:04, phi 7.45s). -- Dang co con ve thi CHO, dung mua ma cung dung nang cap: buc anh ve -- be luc nay chua day du de quyet dinh ban con nao. Action.incomingNow = Action.countIncoming() if Action.incomingNow > 0 and nowCount + Action.incomingNow >= MAX_PODIUMS then Action.T.mark(("cho %d con dang ve be (%d/%d) — chua mua/nang cap"):format( Action.incomingNow, nowCount, MAX_PODIUMS)) loopWait = 0.5 return end if nowCount >= MAX_PODIUMS then Action.T.mark(("be day %d/%d -> xet nang cap thay vi mua them"):format(nowCount, MAX_PODIUMS)) Action.freeSlotForUpgrade(item, prompt, nowCount) loopWait = 0.5 return end if Action.buyBrainrot(item, prompt) then loopWait = 0.2 -- vua mua duoc: con hang, vao ngay khong ngu 2s else loopWait = 0.5 -- mua truot: nghi ngan roi thu mon khac end else -- ★ KHONG chon duoc mon nao: truoc day IM LANG hoan toan nen nhin vao -- tuong bot treo. Giai thich ro TAI SAO, va dem tung tang bo loc. local nAnimal, nPrompt, nOnCarpet, nAfford = 0, 0, 0, 0 pcall(function() for _, obj in ipairs(CollectionService:GetTagged("Animal")) do nAnimal = nAnimal + 1 for _, d in ipairs(obj:GetDescendants()) do if d:IsA("ProximityPrompt") and d.ActionText == "Purchase" then nPrompt = nPrompt + 1 if isPurchasePromptAvailable(d) then nOnCarpet = nOnCarpet + 1 for _, it in ipairs(buyList) do if currentCash >= it.cost and promptMatchesPurchaseName(d, it.name) then nAfford = nAfford + 1 break end end end break end end end end) Action.T.setPhase( "khong-co-gi-mua", ("thu %d | prompt %d | qua bo loc %d | du tien %d | registry %d"):format( nAnimal, nPrompt, nOnCarpet, nAfford, AnimalSource.count()) ) end end) farmActionBusy = false if not ok then warn("⚠️ Loop error: " .. tostring(err)) end task.wait(loopWait) end