Last active
November 27, 2021 15:17
-
-
Save Zbizu/7ac19d5c468d6c8b081ea1e7a383b427 to your computer and use it in GitHub Desktop.
Lua interpreter in chat channel
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<channel id="32" name="Lua" script="luachannel.lua" /> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local CHAT_ID = 32 | |
function canJoin(player) | |
return player:getAccountType() >= ACCOUNT_TYPE_GOD | |
end | |
local function InteractiveConsole(env) | |
return coroutine.wrap(function(inp, out, err) | |
local sandbox = setmetatable({ }, | |
{ | |
__index = function(t, index) | |
return rawget(t, index) or env[index] or _G[index] | |
end | |
} | |
) | |
sandbox._G = sandbox | |
sandbox.os = { | |
time = function() return os.time() end, | |
date = function(...) return os.date(...) end, | |
-- execute = function(...) return os.execute(...) end | |
} | |
sandbox.io = { } | |
sandbox.pcall = { } | |
sandbox.loadstring = { } | |
sandbox.debug = { } | |
sandbox.error = err | |
sandbox.print = function(...) | |
local r = {} | |
for _, v in ipairs({...}) do | |
table.insert(r, tostring(v)) | |
end | |
local s = table.concat(r, string.rep(' ', 4)) | |
return out(#s > 0 and s or 'nil') | |
end | |
local chunks = {} | |
local level = 1 | |
while true do | |
table.insert(chunks, coroutine.yield()) | |
local func, e = loadstring(table.concat(chunks, ' '), 'console') | |
if func then | |
setfenv(func, sandbox) | |
inp(string.rep('>', level) .. ' ' .. chunks[#chunks]) | |
local s, e = pcall(func) | |
-- | |
-- if glitchy replace all with "if not s then err(e) end" | |
if e then | |
local et = type(e) | |
local msg = "" | |
if et == "string" or et == "number" then | |
msg = e | |
elseif et == "boolean" then | |
if e then | |
msg = "true" | |
else | |
msg = "false" | |
end | |
else | |
msg = type(e) | |
end | |
err(msg) | |
end | |
-- | |
chunks = { } | |
level = 1 | |
else | |
if not e:find('near \'<eof>\'$') then | |
inp(string.rep('>', level) .. ' ' .. chunks[#chunks]) | |
chunks = { } | |
level = 1 | |
err(e) | |
else | |
inp(string.rep('>', level) .. ' ' .. chunks[#chunks]) | |
level = 2 | |
end | |
end | |
end | |
end) | |
end | |
local consoles = { } | |
function onSpeak(player, type, message) | |
if player:getAccountType() < ACCOUNT_TYPE_GOD then | |
return false | |
end | |
local pid = player:getId() | |
local console = consoles[pid] | |
if not console then | |
console = InteractiveConsole {} | |
console( | |
function(inp) | |
local player = Player(pid) | |
if player then | |
player:sendChannelMessage(nil, inp, TALKTYPE_CHANNEL_Y, CHAT_ID) | |
end | |
end, | |
function(s) | |
local player = Player(pid) | |
if player then | |
player:sendChannelMessage(nil, s, TALKTYPE_CHANNEL_O, CHAT_ID) | |
end | |
end, | |
function(e) | |
local player = Player(pid) | |
if player then | |
player:sendChannelMessage(nil, e, TALKTYPE_CHANNEL_R1, CHAT_ID) | |
end | |
end | |
) | |
consoles[pid] = console | |
end | |
console(message) | |
return false | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment