loadstringScriptChecker (discontinued but working)
Key RequiredUniversal

loadstringScriptChecker (discontinued but working)

Universal Script5teve3019D5teve3019D 2.2K views 180 executesUpdated Oct 3, 2025
Unrated
00
Lua Script•445 lines (17053 chars)
-- WARNING: HOLY AI💀🙏

-- loadstringChecker_full.lua
-- Full output-only loadstring inspector (no GUI). Designed for executor use.
-- Features:
--  - Prints up to SHOW_LINES_LIMIT lines of the remote script (streamed with task.wait(0)) to avoid locking.
--  - Performs static analysis: counts local declarations/variables, functions, Instance.new usage, token/API counts.
--  - Attempts to detect compile-time errors and runtime traceback (if you enable execution).
--  - Shows context around an error line and gives suggestions to fix common issues.
--  - Calculates a heuristic "danger score" and maps to levels: [ Peaceful ], [ Low ], [ Mid ], [ High ], [ Insane ], [ Danger ].
--      If level is High or above, it refuses to run the remote code.
--  - Reports elapsed time for different phases and a final "Completed Time" in seconds.
--
-- USAGE:
--  - Set url to the raw file URL you want to inspect.
--  - Configure flags below (PREVIEW, SHOW_LINES_LIMIT, AUTO_EXECUTE).
--  - Run as a LocalScript in your executor. All output is printed to Output (print/warn).
--  - By default AUTO_EXECUTE = false (script will NOT execute remote code).
--
-- WARNING:
--  - Printing up to 40,000 lines will produce very large Output. Use with caution.
--  - This tool is heuristic-based. It gives guidance but not perfect proof of maliciousness.
--  - Do NOT enable AUTO_EXECUTE unless you trust the source and threat level is low/peaceful.

-- ========== CONFIG ==========
local url = "" -- <<< PUT RAW FILE URL HERE (required)

local PREVIEW = false               -- if true, only scan a head portion first (see PREVIEW_LINES)
local PREVIEW_LINES = 5000           -- number of lines to analyze in preview mode (PLEASE PUT THE NUMBER LINE AT THE END OF SCRIPT IN YOU RAW FOR MORE DETECTION ACCURACY | Ex. Your script has 482 line then put the line in the nill)
local RUN_FULL_AFTER_PREVIEW = false -- if true, after preview the script will continue to full scan
local SHOW_LINES_LIMIT = 40000      -- how many lines to print (user wanted 40000 limit)
local AUTO_EXECUTE = false          -- if true and threat level allows, it will run the chunk (CAUTION)
local CONTEXT_LINES = 8             -- context lines to show around reported error
local PROGRESS_INTERVAL = 1000      -- emit progress every N lines during full scan
local YIELD_PER_LINE = true         -- yield (task.wait(0)) per line while printing to avoid locking; set false to be faster (may lock)
-- ============================

-- simple print wrappers
local function info(...)
    pcall(print, "[CHECKER]", table.concat({...}, " "))
end
local function warnInfo(...)
    pcall(warn, "[CHECKER]", table.concat({...}, " "))
end

local t0_total = tick()
info("Starting loadstringChecker_full. url=", url)
if not url or url == "" then
    warnInfo("ERROR: url is empty. Set url to the raw file you want to inspect.")
    return
end

-- download
local ok, body_or_err = pcall(function() return game:HttpGet(url) end)
if not ok then
    warnInfo("HttpGet failed:", tostring(body_or_err))
    return
end
local src = tostring(body_or_err)
if not src or #src == 0 then
    warnInfo("Downloaded source is empty.")
    return
end
info("Downloaded bytes:", #src)

-- split into lines array
local lines = {}
for ln in src:gmatch("([^\n]*)\n?") do table.insert(lines, ln) end
local totalLines = #lines
info("Total lines in remote script:", totalLines)

-- decide scan range
local scanFrom, scanTo = 1, totalLines
if PREVIEW then
    scanTo = math.min(PREVIEW_LINES, totalLines)
    info("Preview mode: scanning lines 1.." .. tostring(scanTo))
end

-- helpers for analysis
local function stripInlineComments(line)
    -- very simple: remove trailing -- comments; does NOT handle block comments robustly
    return line:gsub("%-%-.*$", "")
end

local function countLocalVars(decl)
    local left = decl:match("^%s*local%s+(.+)$") or ""
    left = left:match("^(.-)%s*=") or left
    left = left:gsub("%b()", "") -- strip parentheses
    local cnt = 0
    for v in left:gmatch("[^,]+") do
        if v:match("%S") then cnt = cnt + 1 end
    end
    return cnt
end

-- data collectors
local tokenPatterns = {
    loadstring = "%f[%w]loadstring%f[%W]",
    load = "%f[%w]load%f[%W]",
    dofile = "%f[%w]dofile%f[%W]",
    require = "%f[%w]require%f[%W]",
    HttpGet = "HttpGet%s*%(",
    gameHttpGet = "game%s*:%s*HttpGet",
    xpcall = "%f[%w]xpcall%f[%W]",
    pcall = "%f[%w]pcall%f[%W]",
    coroutine = "%f[%w]coroutine%f[%W]",
    task_spawn = "%f[%w]task%.spawn%f[%W]",
    spawn = "%f[%w]spawn%f[%W]",
    setmetatable = "%f[%w]setmetatable%f[%W]",
    getfenv = "%f[%w]getfenv%f[%W]",
    debug = "%f[%w]debug%f[%W]",
    XMLHttp = "XMLHttpRequest",
    Instance_new = "Instance%.new%s*%(",
    SetParent = "%:SetParent%(",
    ParentAssign = "%.%s*Parent%s*=",
    HttpService = "HttpService",
    CoreGui = "CoreGui",
    GetService = "GetService",
}

local counts = {}
local totalLocalDeclLines = 0
local totalLocalVars = 0
local totalFunctionDefs = 0
local topFunctions = {}  -- frames: {name, startLine, endLine, locals, localDeclLines}
local funcStack = {}
local inBlockComment = false
local instanceTypes = {} -- map classname -> count
local instancesCount = 0

-- helpers for function frames
local function pushFunc(name, ln)
    totalFunctionDefs = totalFunctionDefs + 1
    local f = { name = name or ("<anon@"..ln..">"), startLine = ln, endLine = nil, locals = 0, localDeclLines = 0 }
    table.insert(funcStack, f)
    return f
end
local function popFunc(ln)
    local f = table.remove(funcStack)
    if not f then return end
    f.endLine = ln
    table.insert(topFunctions, f)
    return f
end

local function addToken(k, n)
    counts[k] = (counts[k] or 0) + (n or 1)
end

-- function name extractor (best-effort)
local function extractFunctionName(line)
    local name = line:match("^%s*local%s+function%s+([%w_%.:]+)")
    if name then return name end
    name = line:match("^%s*function%s+([%w_%.:]+)%s*%(")
    if name then return name end
    name = line:match("^%s*local%s+([%w_]+)%s*=%s*function%s*%(")
    if name then return name end
    return nil
end

-- scanning loop (streamed) for the selected range
local t0_scan = tick()
info("Beginning scan of lines", scanFrom, "to", scanTo)
for i = scanFrom, scanTo do
    if YIELD_PER_LINE then task.wait(0) end
    local raw = lines[i] or ""
    local line = raw

    -- handle block comments rudimentarily
    if inBlockComment then
        local s, e = line:find("%]%]")
        if s then
            line = line:sub(e+1)
            inBlockComment = false
        else
            line = "" -- skip
        end
    end
    local startBlock = line:find("%-%-%[%[")
    if startBlock then
        -- If block ends on same line, remove it; else cut and mark inBlockComment true
        local s,e = line:find("%]%]", startBlock+4)
        if s then
            line = line:sub(1, startBlock-1) .. (line:sub(e+1) or "")
        else
            line = line:sub(1, startBlock-1)
            inBlockComment = true
        end
    end

    -- strip inline comments
    line = stripInlineComments(line)

    -- token counts
    for k, pat in pairs(tokenPatterns) do
        if line:find(pat) then addToken(k) end
    end

    -- Instance.new("ClassName") detection
    for cls in line:gmatch('Instance%.new%s*%(%s*["\']([%w_%:%.%-]+)["\']%s*%)') do
        instancesCount = instancesCount + 1
        instanceTypes[cls] = (instanceTypes[cls] or 0) + 1
    end
    if line:find("Instance%.new") then
        -- count generic occurrence as well
        instancesCount = instancesCount + 0
    end

    -- function detection
    if line:find("%f[%w]function%f[%W]") then
        local fname = extractFunctionName(line)
        pushFunc(fname, i)
        totalFunctionDefs = totalFunctionDefs + 0 -- already incremented inside pushFunc
    end

    -- local declarations
    if line:find("^%s*local%s+") then
        local vars = countLocalVars(line)
        totalLocalDeclLines = totalLocalDeclLines + 1
        totalLocalVars = totalLocalVars + vars
        if #funcStack > 0 then
            local top = funcStack[#funcStack]
            top.locals = top.locals + vars
            top.localDeclLines = top.localDeclLines + 1
        end
    end

    -- balance ends (basic)
    local ends = 0
    for _ in line:gmatch("%f[%w]end%f[%W]") do ends = ends + 1 end
    for _ = 1, ends do
        if #funcStack > 0 then popFunc(i) end
    end
end
local t1_scan = tick()
info("Scan phase completed in", string.format("%.3f", t1_scan - t0_scan), "seconds")

-- If PREVIEW mode and we should skip the rest:
if PREVIEW and not RUN_FULL_AFTER_PREVIEW then
    info("Preview-only run requested. The preview scan has completed and summary will be shown. Full scan skipped.")
end

-- Print the script content up to SHOW_LINES_LIMIT (streamed)
local printLimit = math.min(totalLines, SHOW_LINES_LIMIT)
info(("Printing script lines 1..%d (limit=%d). This may produce a lot of Output."):format(printLimit, SHOW_LINES_LIMIT))
local t0_print = tick()
for i = 1, printLimit do
    if YIELD_PER_LINE then task.wait(0) end
    pcall(print, string.format("%6d: %s", i, lines[i] or ""))
end
local t1_print = tick()
local printElapsed = t1_print - t0_print
info("Printing phase completed in", string.format("%.3f", printElapsed), "seconds")

-- Collate summary
local summary = {
    total_lines = totalLines,
    scanned_lines = (scanTo - scanFrom + 1),
    local_decl_lines = totalLocalDeclLines,
    local_variables = totalLocalVars,
    function_defs = #topFunctions,
    instance_new_literal_types = instanceTypes,
    instance_new_total_literals = 0,
    token_counts = counts,
    scan_time = t1_scan - t0_scan,
    print_time = printElapsed,
}
for k,v in pairs(instanceTypes) do summary.instance_new_total_literals = summary.instance_new_total_literals + v end

-- Top functions by locals
table.sort(topFunctions, function(a,b)
    if a.locals == b.locals then return (a.endLine - a.startLine) > (b.endLine - b.startLine) end
    return a.locals > b.locals
end)

-- Print summary
info("=== Analysis Summary ===")
info("Total lines:", summary.total_lines)
info("Scanned lines:", summary.scanned_lines)
info("Local declaration lines:", summary.local_decl_lines)
info("Total local variables (approx):", summary.local_variables)
info("Functions detected (approx):", summary.function_defs)
info("Instance.new(\"Class\") literal types detected (top):")
local ct = 0
for cls,c in pairs(summary.instance_new_literal_types) do
    ct = ct + 1
    info(string.format("  %s : %d", tostring(cls), c))
    if ct >= 30 then break end
end
info("Token/API counts (top):")
local toklist = {}
for k,v in pairs(summary.token_counts) do table.insert(toklist, {k=k,v=v}) end
table.sort(toklist, function(a,b) return a.v > b.v end)
for _,t in ipairs(toklist) do info(string.format("  %-18s : %d", t.k, t.v)) end

info("Top functions by local variable count (approx):")
for i=1, math.min(12, #topFunctions) do
    local f = topFunctions[i]
    info(string.format(" %2d) %s  locals=%d  localDeclLines=%d  range=%d-%d",
        i, tostring(f.name), f.locals, f.localDeclLines, f.startLine, f.endLine))
end

-- Heuristic danger scoring
local score = 0
-- weights (tunable)
local weights = {
    loadstring = 35,
    gameHttpGet = 20,
    HttpGet = 10,
    require = 8,
    xpcall = 6,
    pcall = 2,
    debug = 25,
    getfenv = 30,
    setmetatable = 6,
    XMLHttp = 40,
    coroutine = 4,
    task_spawn = 3,
    spawn = 6,
    Instance_new = 1,
    Instance_risky_classes = 5, -- e.g., Sound/Image with remote ids (not deeply detected here)
}

-- accumulate token-based score
for k,v in pairs(counts) do
    local w = weights[k] or 1
    score = score + (w * v)
end

-- big local counts or giant top function locals add risk of 'Out of local registers'
if summary.local_variables > 400 then score = score + 40 end
for _,f in ipairs(topFunctions) do
    if f.locals >= 150 then score = score + 50 end
end

-- map score to level
local level = "[ Peaceful ]"
local level_key = "peaceful"
if score < 20 then level = "[ Peaceful ]"; level_key = "peaceful"
elseif score < 60 then level = "[ Low ]"; level_key = "low"
elseif score < 150 then level = "[ Mid ]"; level_key = "mid"
elseif score < 300 then level = "[ High ]"; level_key = "high"
elseif score < 600 then level = "[ Insane ]"; level_key = "insane"
else level = "[ Danger ]"; level_key = "danger"
end

info("Danger heuristic score:", score, "Level:", level)

-- Suggest whether it's safe to run
local canRun = true
if level_key == "high" or level_key == "insane" or level_key == "danger" then
    canRun = false
    warnInfo("AUTORUN DENIED: Threat level is", level, " - DO NOT EXECUTE this script automatically.")
else
    info("Threat level", level, "- script may be executed if you trust the source and manual review passed.")
end

-- Attempt compilation to detect parse errors and report context & suggestions
local t0_compile = tick()
local chunk, compileErr = loadstring(src)
local t1_compile = tick()
info("Compile attempt time:", string.format("%.3f", t1_compile - t0_compile), "seconds")
if not chunk then
    warnInfo("Compile error detected:", tostring(compileErr))
    -- try to extract line number
    local lineno = tonumber(compileErr:match("%[string \"[^\"]*\"%]:(%d+):")) or tonumber(compileErr:match(":(%d+):"))
    if lineno then
        warnInfo("Compile error appears at line", lineno, "- showing context +/-", CONTEXT_LINES)
        local startL = math.max(1, lineno - CONTEXT_LINES)
        local endL = math.min(totalLines, lineno + CONTEXT_LINES)
        for j = startL, endL do
            local mark = (j == lineno) and ">>" or "  "
            pcall(print, string.format("%s %6d: %s", mark, j, lines[j] or ""))
        end
        -- Suggest fixes (basic)
        warnInfo("Suggested fixes:")
        if compileErr:find("unexpected symbol") or compileErr:find("near") then
            warnInfo("  - Check for missing or extra symbols (commas, parentheses, 'end').")
        end
        if compileErr:find("unfinished long string") or compileErr:find("unfinished long comment") then
            warnInfo("  - Check multi-line strings/comments (look for matching [[ and ]]).")
        end
        if compileErr:find("function arguments expected") or compileErr:find("malformed") then
            warnInfo("  - Check function declaration syntax around the marked lines.")
        end
    else
        warnInfo("Could not extract line number from compile error. Full error:")
        pcall(print, compileErr)
    end
else
    info("No compile-time parse errors detected.")
end

-- If AUTO_EXECUTE requested and allowed by threat level, run the chunk under xpcall
if AUTO_EXECUTE and chunk then
    if not canRun then
        warnInfo("AUTO_EXECUTE requested but threat level", level, "prohibits automatic execution.")
    else
        info("AUTO_EXECUTE true and threat level acceptable -> executing chunk under xpcall")
        local t0_run = tick()
        local function onErr(err)
            local tb = (debug and debug.traceback) and debug.traceback(err, 2) or tostring(err)
            warnInfo("Runtime error (traceback):")
            pcall(print, tb)
            -- try to find first occurrence of line reference into the chunk
            local lineno = tonumber(tb:match("%[string \"[^\"]*\"%]:(%d+):")) or tonumber(tb:match(":(%d+):"))
            if lineno and lineno >= 1 and lineno <= totalLines then
                warnInfo("Runtime error reported at line", lineno, "- showing context +/-", CONTEXT_LINES)
                local startL = math.max(1, lineno - CONTEXT_LINES)
                local endL = math.min(totalLines, lineno + CONTEXT_LINES)
                for j = startL, endL do
                    local mark = (j == lineno) and ">>" or "  "
                    pcall(print, string.format("%s %6d: %s", mark, j, lines[j] or ""))
                end
                warnInfo("Suggestion: Inspect the code around the reported line. Common runtime causes: nil indexing, calling missing functions, invalid arguments or mismatched types.")
            end
            return err
        end
        local ok2, res = xpcall(chunk, onErr)
        local t1_run = tick()
        info("Execution finished. success:", ok2, "time:", string.format("%.3f", t1_run - t0_run), "seconds")
    end
end

-- final completed time
local t_end = tick()
local total_elapsed = t_end - t0_total
info("Completed Time (total):", string.format("%.3f", total_elapsed), "seconds")

-- Export results for programmatic consumption
_G.LastLoadstringCheckFull = {
    url = url,
    summary = summary,
    top_functions = topFunctions,
    score = score,
    level = level,
    canRun = canRun,
    compile_error = compileErr,
    scanned_range = { from = scanFrom, to = scanTo },
    printed_lines = printLimit,
    timings = { scan = t1_scan - t0_scan, print = printElapsed, compile = t1_compile - t0_compile, total = total_elapsed },
}

info("Results stored in _G.LastLoadstringCheckFull")
-- End of script

Features & Information

To check your script or others to find an error if you use loadstring and error said: “attempt to call a nill value” you can find error if you use “loadstringScriptChecker” also it script only show in “Output console” SAFETY WARN: if you don't trust it's ok! Be careful if you using unverified script. (I'm not verified user auGHHh *dies*) Note: • Threat levels may not 100% for trust script and another script. • It will not check your executor; it only check your raw website you put in it called [ url = "" -- <<< PUT RAW FILE URL HERE ] • If script has an error, an error will show a warn() and tell where the an error at ~~~~~~~~~~~~~~~~~~~~~~~~~~~ • Update 📌: New update for 1K visit - Increase the accuracy of error detection. - multi errors detection. • Back Up: Uhm sorry, but old script is better. ~~~~~~~~~~~~~~~~~~~~~~~~~~~ Create by: 5teve3019D × Copilot
#Debug#Output#Error Finder#Url#Tools

Community Comments (2)

deaggilisspeesdeaggilisspeesOct 3, 2025

We yes We are NOT using tss very dtcc 2/10

SP_HubSP_HubOct 3, 2025

so this script will check if my executer can run script or not? and he will give me what should i edit in my code for works or what?

More Scripts for Universal Scripts