Skip to content

Instantly share code, notes, and snippets.

@Zbizu
Last active November 27, 2021 15:17
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save Zbizu/7ac19d5c468d6c8b081ea1e7a383b427 to your computer and use it in GitHub Desktop.
Lua interpreter in chat channel
<channel id="32" name="Lua" script="luachannel.lua" />
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