JS Chat Coding
Key RequiredUniversal

JS Chat Coding

Universal ScriptMediorceExploiterMediorceExploiter 492 views 202 executesUpdated Mar 11, 2026
5.0/ 5(1 votes)
10100% Positive
Lua Script•393 lines (12827 chars)
-- SINGLE-LINE JS INTERPRETER WITH LIVE MODE & CLEARLL (evaluator fix)
local PREFIX = "js:"
local UNLOAD_KEY = Enum.KeyCode.M

local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local UserInputService = game:GetService("UserInputService")
local player = Players.LocalPlayer

-- FULL UNLOAD OLD COPY
if _G.JSInterpreterLoaded then
    if _G.JSUnloadFunc then _G.JSUnloadFunc() end
end
_G.JSInterpreterLoaded = true

-- Interpreter state
local codeBuffer = {}
local variables = {}
local functions = {}
local running = false
local enabled = true
local chatConn, inputConn

-- CONSOLE / CHAT API
local console = {}
local c = console

function console.log(msg)
    print("[JS]", tostring(msg))
end

function console.chat(msg)
    if ReplicatedStorage:FindFirstChild("DefaultChatSystemChatEvents") then
        pcall(function()
            ReplicatedStorage.DefaultChatSystemChatEvents.SayMessageRequest:FireServer(tostring(msg),"All")
        end)
    else
        if player then
            pcall(function() player:Chat(tostring(msg)) end)
        else
            warn("[JS] Cannot chat: player missing")
        end
    end
end

-- Random helper table (use m.r(min, max))
local m = {}

-- Random helper table (use m.r(min, max [, precision]))
local m = {}

-- seed once
if not _G.JSRandomSeeded then
    local seed = (tick and tick() or os.time()) % 1e9
    math.randomseed(seed)
    math.random(); math.random(); math.random()
    _G.JSRandomSeeded = true
end

-- Helper: round to N decimal places
local function roundTo(n, decimals)
    local mult = 10 ^ (decimals or 0)
    return math.floor(n * mult + 0.5) / mult
end

-- m.r(min, max [, precision])
-- - If both min and max are integer-like and precision is nil -> returns integer in [min,max]
-- - If precision is provided (non-negative integer) -> returns a number with that many decimals
--   * If precision == 0 behaves like integer mode
--   * If precision > 0 returns a float with exactly that many decimals (rounded)
-- - If precision is nil and either arg is non-integer -> returns a float with full math.random() precision
function m.r(minv, maxv, precision)
    minv = tonumber(minv) or 0
    maxv = tonumber(maxv) or 1
    if minv > maxv then minv, maxv = maxv, minv end

    -- If precision explicitly provided
    if precision ~= nil then
        precision = tonumber(precision) or 0
        if precision <= 0 then
            -- integer behavior
            local imin = math.ceil(minv)
            local imax = math.floor(maxv)
            if imin > imax then return imin end
            return math.random(imin, imax)
        end
        -- produce float with 'precision' decimal places
        local scale = 10 ^ precision
        -- choose integer in scaled range, but avoid exact endpoints if you want open interval
        local scaledMin = math.ceil(minv * scale)
        local scaledMax = math.floor(maxv * scale)
        if scaledMin > scaledMax then
            -- fallback: produce a single rounded value
            return roundTo(minv, precision)
        end
        local r = math.random(scaledMin, scaledMax) / scale
        return roundTo(r, precision)
    end

    -- No precision provided: previous behavior
    if math.floor(minv) == minv and math.floor(maxv) == maxv then
        return math.random(minv, maxv)
    end

    -- mixed/float args -> return float in [minv, maxv)
    return minv + math.random() * (maxv - minv)
end




-- Strip comments and pasted metadata
local function stripComments(line)
    if not line then return "" end
    line = line:gsub("//.*", "")
    line = line:gsub("#.*", "")
    line = line:gsub("<WebsiteContent_[^>]->", "")
    line = line:gsub("</WebsiteContent_[^>]->", "")
    line = line:gsub("<[^>]->", "")
    return line:match("^%s*(.-)%s*$") or ""
end

-- Enhanced syntax check
local function syntaxValid(line)
    line = stripComments(line)
    if line == "" then return false end
    if line:match("^var%s+[%a_][%w_]*%s*=%s*.+") then return true end
    if line:match("^[%a_][%w_]*%s*=%s*.+") then return true end
    if line:match("^function%s+%w+%s*%((.-)%)%s*{.-}$") then return true end
    if line:match("^console%.") or line:match("^c%.") then return true end
    if line:match("^if%s*%(.+%)%s*{.-}%s*else%s*{.-}$") then return true end
    if line:match("^if%s*%(.+%)%s*{.-}$") then return true end
    if line:match("%f[%w]true%f[%W]") or line:match("%f[%w]false%f[%W]") then return true end
    return false
end

-- Convert JS operators and boolean literals to Lua equivalents
local function convertMath(expr)
    if not expr then return expr end
    -- boolean literals
    expr = expr:gsub("%f[%w]true%f[%W]","true")
    expr = expr:gsub("%f[%w]false%f[%W]","false")
    -- logical operators
    expr = expr:gsub("&&"," and ")
    expr = expr:gsub("%|%|"," or ")
    expr = expr:gsub("!%s*","not ")
    -- inequality
    expr = expr:gsub("!=","~=")
    -- exponent
    expr = expr:gsub("%*%*","^")
    return expr
end

-- Evaluate expression in sandboxed env that resolves names from variables first
local function evaluate(expr)
    if expr == nil then return nil end
    expr = expr:match("^%s*(.-)%s*$")
    -- quoted boolean strings
    local quoted = expr:match('^"(.-)"$') or expr:match("^'(.-)'$")
    if quoted == "true" then return true end
    if quoted == "false" then return false end

    expr = convertMath(expr)

    -- Build sandbox environment that resolves identifiers from variables table
	local env = {}
	env.math = math
	env.string = string
	env.tonumber = tonumber
	env.tostring = tostring
	env.pairs = pairs
	env.ipairs = ipairs
	env.print = print
	env.m = m   -- <--- expose the random helper


    setmetatable(env, {
        __index = function(_, k)
            -- first check interpreter variables
            if variables[k] ~= nil then return variables[k] end
            -- then fallback to global
            return _G[k]
        end
    })

    -- try as expression first
    local chunk, err = loadstring("return "..expr)
    if not chunk then
        -- try as statement
        chunk, err = loadstring(expr)
    end
    if not chunk then
        warn("[JS] Eval compile error:", err, "expr:", expr)
        return nil
    end

    -- set environment and run
    local ok, res
    -- setfenv is available in Roblox Lua (5.1)
    pcall(function() setfenv(chunk, env) end)
    ok, res = pcall(chunk)
    if not ok then
        warn("[JS] Eval runtime error:", res, "expr:", expr)
        return nil
    end
    return res
end

-- Assignment handler (supports "var name = value" and "name = value")
local function handleAssignment(line)
    local name, value = line:match("^var%s+([%a_][%w_]*)%s*=%s*(.+)")
    if not name then
        name, value = line:match("^([%a_][%w_]*)%s*=%s*(.+)")
    end
    if name and value then
        value = stripComments(value):match("^%s*(.-)%s*$")
        local quoted = value:match('^"(.-)"$') or value:match("^'(.-)'$")
        if quoted == "true" then variables[name] = true; return true end
        if quoted == "false" then variables[name] = false; return true end
        local ok, res = pcall(function() return evaluate(value) end)
        if ok then variables[name] = res else warn("[JS] Assignment eval failed for "..name..":", res) end
        return true
    end
    return false
end

-- Run a single line (supports nested single-line if/else)
local function runLine(line)
    line = stripComments(line)
    if line == "" then return end

    -- assignment
    if handleAssignment(line) then return end

    -- function
    if line:match("^function") then
        local fname,args,body = line:match("^function%s+(%w+)%s*%((.-)%)%s*{(.-)}$")
        if fname and args and body then
            functions[fname] = {args=args, body=body}
        end
        return
    end

    -- if/else (supports single-line if without else)
    if line:match("^if%s*%(") then
        local cond, ifbody, elsebody
        cond, ifbody, elsebody = line:match("^if%s*%((.-)%)%s*{(.-)}%s*else%s*{(.-)}")
        if cond then
            if evaluate(cond) then runLine(ifbody) else runLine(elsebody) end
            return
        end
        cond, ifbody = line:match("^if%s*%((.-)%)%s*{(.-)}")
        if cond then
            if evaluate(cond) then runLine(ifbody) end
            return
        end
        warn("[JS] Malformed if statement:", line)
        return
    end

    -- function call resolution for user-defined functions
    -- (simple inline replacement for single-line functions)
    if line:match("(%w+)%s*%(") then
        -- try to detect console calls first
        if line:match("console%.log") or line:match("c%.l") then
            local expr = line:match("console%.log%((.+)%)") or line:match("c%.l%((.+)%)")
            if expr then console.log(evaluate(expr)) end
            return
        end
        if line:match("console%.chat") or line:match("c%.c") then
            local expr = line:match("console%.chat%((.+)%)") or line:match("c%.c%((.+)%)")
            if expr then console.chat(evaluate(expr)) end
            return
        end
    end

    -- fallback: try to evaluate as expression/statement
    local ok, res = pcall(function() return evaluate(line) end)
    if not ok then warn("[JS] RunLine eval failed:", res) end
end

-- Execute program buffer
local function executeBuffer()
    for _,line in ipairs(codeBuffer) do
        local ok, err = pcall(function() runLine(line) end)
        if not ok then warn("[JS] Error executing line:", line, err) end
    end
end

-- Handle chat input
local function handleJSCommand(msg)
    if not enabled then return end
    if msg:sub(1,#PREFIX):lower() ~= PREFIX then return end

    local code = msg:sub(#PREFIX+1):gsub("^%s+","")

    -- COMMANDS
    if code == "print" then
        print("========== JS PROGRAM ==========")
        for _,line in ipairs(codeBuffer) do print(line) end
        print("========== END PROGRAM ==========")
        return
    elseif code == "clip" then
        if setclipboard then
            setclipboard(table.concat(codeBuffer,"\n"))
            print("[JS] Program copied to clipboard!")
        else
            warn("[JS] Clipboard unavailable")
        end
        return
    elseif code == "clear" then
        codeBuffer = {}
        variables = {}
        functions = {}
        print("[JS] Program cleared")
        return
    elseif code == "clearll" then
        local last = table.remove(codeBuffer)
        if last then
            local varName = last:match("^var%s+(%w+)%s*=") or last:match("^([%a_][%w_]*)%s*=")
            if varName then variables[varName] = nil end
            local funcName = last:match("^function%s+(%w+)%s*%(")
            if funcName then functions[funcName] = nil end
            print("[JS] Last line cleared:", last)
        else
            print("[JS] No line to clear")
        end
        return
    elseif code == "run" then
        for _,line in ipairs(codeBuffer) do
            if not syntaxValid(line) then
                warn("[JS] Cannot run: Invalid code in buffer:", line)
                return
            end
        end
        running = true
        executeBuffer()
        print("[JS] Entered running mode — new JS executes instantly!")
        return
    elseif code == "stop" then
        running = false
        print("[JS] Stopped running code")
        return
    end

    -- SINGLE-LINE STRICT CHECK
    if not syntaxValid(code) then
        warn("[JS] Invalid syntax:", code)
        return
    end

    -- Add valid line to buffer
    table.insert(codeBuffer, code)

    -- Instantly execute if running
    if running then
        local ok, err = pcall(function() runLine(code) end)
        if not ok then warn("[JS] Runtime error:", err) end
    end
end

-- CHAT CONNECTION (Unified)
local ChatEvents = game:FindFirstChild("DefaultChatSystemChatEvents", true)
if ChatEvents and ChatEvents:IsA("Folder") and ChatEvents:FindFirstChild("OnMessageDoneFiltering") then
    chatConn = ChatEvents.OnMessageDoneFiltering.OnClientEvent:Connect(function(msgData)
        if msgData.Message and type(msgData.Message)=="string" then
            handleJSCommand(msgData.Message)
        end
    end)
else
    chatConn = player.Chatted:Connect(handleJSCommand)
end

-- UNLOAD
local function fullUnload()
    enabled = false
    codeBuffer = {}
    variables = {}
    functions = {}
    if chatConn then chatConn:Disconnect() end
    if inputConn then inputConn:Disconnect() end
    _G.JSInterpreterLoaded = false
    _G.JSUnloadFunc = nil
    print("[JS] Fully Unloaded")
end

_G.JSUnloadFunc = fullUnload
inputConn = UserInputService.InputBegan:Connect(function(input,gp)
    if gp then return end
    if input.KeyCode == UNLOAD_KEY then fullUnload() end
end)

print("[JS] Loaded (evaluator fixed)")

Features & Information

You can now code with JavaScript in chat because why not. Made with multiple AIs to the point where I forgot their specific models. EX Code: js: c.l(4) prints to console 4 ^
#cool

Community Comments (1)

sawdwad

More Scripts for Universal Scripts