local AUTH_URL = "https://vantarmor.up.railway.app/scripts/hosted/packet-45a2c1/auth" local PAYLOAD_URL = "https://vantarmor.up.railway.app/scripts/hosted/packet-45a2c1/payload" local FFA = false local SECURE = false local HEAD = "[ VANTARMOR ]\n" local MSG = { KEY_REQUIRED = HEAD .. "A valid key is required.", KEY_INVALID = HEAD .. "The key is not valid.", KEY_EXPIRED = HEAD .. "Your key has expired.", NOT_AUTHORIZED = HEAD .. "You are not authorized to run this script.", HWID_MISMATCH = HEAD .. "This key is linked to another device.", VERIFY_FAILED = HEAD .. "Verification failed. Please rejoin.", CONNECTION_FAILED = HEAD .. "Connection failed. Please try again.", TAMPERING = HEAD .. "Tampering detected.", SCRIPT_NOT_FOUND = HEAD .. "Script not found.", SCRIPT_DELETED = HEAD .. "This script was deleted by its owner.", REAUTH = HEAD .. "Please re-authenticate.", BLACKLISTED = HEAD .. "Access denied.", MAINTENANCE = HEAD .. "This script is under maintenance.\nPlease try again in a few minutes.", MAINTENANCE_ALL = HEAD .. "Vantarmor is under maintenance.\nPlease try again in a few minutes.", SERVER_UNREACHABLE = HEAD .. "Server unreachable. Please try later.", PAYLOAD_LOAD_FAILED = HEAD .. "The script could not be loaded by your executor.\nPlease contact the script owner.", TOKEN_INVALID = HEAD .. "Your session expired. Please rejoin.", FORBIDDEN = HEAD .. "Access denied.", } local Players = game:GetService("Players") local function kick(code) local msg = MSG[code] or MSG.VERIFY_FAILED local lp = Players.LocalPlayer if lp then lp:Kick(msg) end error(msg, 0) end -- Si loadstring fue reemplazado por una función de Lua (un volcador que intercepta el código), se corta local function nativeFn(f) if type(f) ~= "function" then return false end local okI, info = pcall(function() return debug.getinfo(f, "S") end) return not (okI and type(info) == "table" and info.what ~= "C") end local function loaderTampered() -- loadstring es la vía del payload; load también puede usarse para volcar, así que se revisan los dos if not nativeFn(loadstring) then return true end if type(load) == "function" and not nativeFn(load) then return true end return false end local key = "" -- script_key puede venir como global normal, en _G, o en getgenv() (depende del executor) local _rawKey = (getgenv and rawget(getgenv(), "script_key")) or (type(script_key) == "string" and script_key) or (_G and type(rawget(_G, "script_key")) == "string" and rawget(_G, "script_key")) or "" if type(_rawKey) == "string" then key = (_rawKey:gsub("^%s+", ""):gsub("%s+$", "")) end if key == "" and not FFA then kick("KEY_REQUIRED") end local function enc(s) return (s:gsub("[^%w%-_%.~]", function(c) return string.format("%%%02X", string.byte(c)) end)) end local hwid = "" local okh, h = pcall(function() return game:GetService("RbxAnalyticsService"):GetClientId() end) if okh and type(h) == "string" and #h >= 8 then hwid = h end local rbxid = "" local okr, rid = pcall(function() return tostring(Players.LocalPlayer.UserId) end) if okr and rid then rbxid = rid end -- Detector de dump: solo verifica que el Heartbeat responda (reloj completamente congelado = volcado) local detections = 0 pcall(function() local hits = 0 local conn = game:GetService("RunService").Heartbeat:Connect(function() hits += 1 end) local t0 = os.clock() repeat task.wait() until hits >= 2 or os.clock() - t0 > 2 conn:Disconnect() if hits < 2 then detections += 1 end end) -- Si el propio detector falla no se castiga al jugador (evita falsos positivos) local function _clearKey() pcall(function() if type(getgenv) == "function" then local _g = getgenv(); if _g then _g.script_key = nil end end end) if type(_G) == "table" then pcall(function() _G.script_key = nil end) end pcall(function() script_key = nil end) end if detections > 0 then pcall(function() game:HttpGet(AUTH_URL .. "?key=" .. enc(key) .. "&hwid=" .. enc(hwid) .. "&rbxid=" .. enc(rbxid) .. "&tamper=1") end) _clearKey() kick("TAMPERING") end -- Detector de entorno: solo reporta si encuentra funciones de hook activas (hookfunction, etc.) -- Las comprobaciones de Tween/FPS se eliminaron porque fallaban en ejecutores legítimos y causaban -- kicks falsos. Solo se castiga si se detectan hooks explícitos que indican volcado activo. local function envProbeRun() local _hookFound = false pcall(function() local _rg = rawget local _okE, _f = pcall(function() return getfenv and getfenv(0) or getgenv and getgenv() or {} end) if _okE and type(_f) == "table" then for _, _nm in ipairs({ "hookfunction", "hookmetamethod", "hookm", "replaceclosure" }) do if _rg(_f, _nm) ~= nil then _hookFound = true end end end end) return _hookFound end local hookDetected = envProbeRun() if hookDetected then pcall(function() game:HttpGet(AUTH_URL .. "?key=" .. enc(key) .. "&hwid=" .. enc(hwid) .. "&rbxid=" .. enc(rbxid) .. "&tamper=1") end) _clearKey() kick("TAMPERING") end -- Si loadstring fue interceptado: se avisa al servidor (dueño) y se corta antes de validar la key if loaderTampered() then pcall(function() game:HttpGet(AUTH_URL .. "?key=" .. enc(key) .. "&hwid=" .. enc(hwid) .. "&rbxid=" .. enc(rbxid) .. "&tamper=1") end) _clearKey() kick("TAMPERING") end -- Contactar el servidor con hasta 3 reintentos (Railway puede tardar al arrancar) local ok, body = false, "" local _url = AUTH_URL .. "?key=" .. enc(key) .. "&hwid=" .. enc(hwid) .. "&rbxid=" .. enc(rbxid) for _attempt = 1, 3 do ok, body = pcall(function() return game:HttpGet(_url) end) if ok and type(body) == "string" then break end if _attempt < 3 then task.wait(1) end end script_key = nil -- Limpiar script_key de todos los entornos para que el payload no la lea (ya fue consumida) pcall(function() if getgenv then rawset(getgenv(), "script_key", nil) end end) pcall(function() script_key = nil end) pcall(function() if _G then rawset(_G, "script_key", nil) end end) if not ok or type(body) ~= "string" then kick("SERVER_UNREACHABLE") end -- Entrega en dos pasos (solo scripts con secure_fetch): /auth dio un token; el código sale de /payload por POST -- La respuesta del servidor decide el flujo (no la marca SECURE del bootstrap): así un loader viejo o cacheado no se rechaza local _tp = "!VANTARMOR:TOKEN\n" if body:sub(1, #_tp) == _tp then local _token = (body:sub(#_tp + 1):gsub("%s+$", "")) local _post = (type(request) == "function" and request) or (type(http_request) == "function" and http_request) or (type(syn) == "table" and type(syn.request) == "function" and syn.request) or nil if not _post then kick("EXECUTOR_NO_POST") end local _okp, _resp = pcall(function() return _post({ Url = PAYLOAD_URL, Method = "POST", Headers = { ["Content-Type"] = "text/plain" }, Body = _token }) end) if not _okp or type(_resp) ~= "table" or type(_resp.Body) ~= "string" then kick("SERVER_UNREACHABLE") end body = _resp.Body end -- El servidor responde "!VANTARMOR:CODIGO" (error) o "!VANTARMOR:CODE" seguido del script (éxito). -- Se usa string.sub en lugar de match para soportar scripts multilínea -- (el patrón (.*) no captura saltos de línea en Lua, y el $ tampoco funciona bien con salto final). -- Los códigos de error toleran CR-LF o LF al final (algunos proxies / ejecutores los agregan). local errCode = body:match("^!VANTARMOR:([%u_]+)[\r\n]*$") if errCode then kick(errCode) end local _prefix = "!VANTARMOR:CODE\n" local payload = (body:sub(1, #_prefix) == _prefix and #body > #_prefix) and body:sub(#_prefix + 1) or nil if not payload then kick("VERIFY_FAILED") end if loaderTampered() then kick("TAMPERING") end local fn, cerr = loadstring(payload) -- El error exacto de compilación queda en la consola del executor (para diagnosticar el script) if not fn then warn("[VANTARMOR] No se pudo compilar el script: " .. tostring(cerr)) kick("PAYLOAD_LOAD_FAILED") end -- task.spawn: ejecuta el script del usuario en un hilo separado. -- Si el script del usuario tiene un error, no mata el bootstrap y el error -- aparece con el nombre real del script (no "LocalScript"). task.spawn(fn)