258 lines
7.9 KiB
Lua
258 lines
7.9 KiB
Lua
--
|
|
-- Snippet console - Allows players to create and edit persistent snippets
|
|
--
|
|
|
|
local forms = {}
|
|
|
|
minetest.register_on_leaveplayer(function(player)
|
|
forms[player:get_player_name()] = nil
|
|
end)
|
|
|
|
local callback
|
|
function snippets.update_console(name)
|
|
if not minetest.check_player_privs(name, 'server') then return end
|
|
|
|
if not forms[name] then
|
|
forms[name] = snippets.Form(name)
|
|
forms[name]:add_callback(callback)
|
|
forms[name].context.code = ''
|
|
end
|
|
local form = forms[name]
|
|
if not form:is_open() then form.context.text = nil end
|
|
|
|
local formspec = 'size[14,10]' ..
|
|
'label[0,0;My snippets]' ..
|
|
'textlist[0,0.5;3.5,7.4;snippetlist;#aaaaaaNew snippet'
|
|
|
|
local snippet_list = {}
|
|
form.context.snippet_list = snippet_list
|
|
for k, v in pairs(snippets.registered_snippets) do
|
|
if v.persistent then
|
|
table.insert(snippet_list, k)
|
|
end
|
|
end
|
|
table.sort(snippet_list)
|
|
|
|
local selected, unaved = 0, false
|
|
local selected_snippet = form.context.selected_snippet
|
|
for id, snippet in ipairs(snippet_list) do
|
|
formspec = formspec .. ',##' .. minetest.formspec_escape(snippet)
|
|
if snippet == selected_snippet then
|
|
selected = id
|
|
local def = snippets.registered_snippets[snippet]
|
|
if (def and def.code or '') ~= form.context.code then
|
|
formspec = formspec .. ' (unsaved)'
|
|
end
|
|
end
|
|
end
|
|
|
|
formspec = formspec .. ';' .. tostring(selected + 1) .. ']' ..
|
|
'button[0,8.1;3.7,0.75;save;Save]' ..
|
|
'button[0,8.85;3.7,0.75;save_as;Save as]' ..
|
|
'button_exit[0,9.6;3.7,0.75;quit;Quit]'
|
|
|
|
formspec = formspec ..
|
|
'textlist[3.9,6.01;10,4.04;ignore;'
|
|
if form.context.text then
|
|
local console_text = form.context.text
|
|
if #console_text > 0 then
|
|
for id, msg in ipairs(console_text) do
|
|
if id > 1 then formspec = formspec .. ',' end
|
|
formspec = formspec .. minetest.formspec_escape(msg)
|
|
end
|
|
formspec = formspec .. ',;' .. (#console_text + 1)
|
|
else
|
|
formspec = formspec .. ';1'
|
|
end
|
|
formspec = formspec ..
|
|
']button[3.9,5.14;10.21,0.81;reset;Reset]' ..
|
|
'box[3.9,0.4;10,4.5;#ffffff]'
|
|
else
|
|
formspec = formspec .. ';1]' ..
|
|
'button[3.9,5.14;10.21,0.81;run;Run]'
|
|
end
|
|
|
|
if not form.context.code then form.context.code = '' end
|
|
local code = minetest.formspec_escape(form.context.code)
|
|
if code == '' and form.context.text then code = '(no code)' end
|
|
|
|
local snippet, owner
|
|
if selected_snippet then
|
|
snippet = minetest.colorize('#aaa', selected_snippet)
|
|
else
|
|
snippet = minetest.colorize('#888', 'New snippet')
|
|
end
|
|
|
|
local def = snippets.registered_snippets[selected_snippet]
|
|
if def and def.owner then
|
|
owner = minetest.colorize('#aaa', def.owner)
|
|
elseif selected_snippet then
|
|
owner = minetest.colorize('#888', 'none')
|
|
else
|
|
owner = minetest.colorize('#aaa', name)
|
|
end
|
|
|
|
formspec = formspec .. ']textarea[4.2,0.4;10.2,5.31;' ..
|
|
(form.context.text and '' or 'code') .. ';Snippet: ' ..
|
|
minetest.formspec_escape(snippet .. ', owner: ' .. owner) .. ';' ..
|
|
code .. ']'
|
|
|
|
form:set_formspec(formspec)
|
|
end
|
|
|
|
function snippets.show_console(name)
|
|
snippets.update_console(name)
|
|
local form = forms[name]
|
|
if form then form:show() end
|
|
end
|
|
|
|
function snippets.push_console_msg(name, msg, col)
|
|
if not col or col:sub(1, 1) ~= '#' or #col ~= 7 then
|
|
col = '##'
|
|
end
|
|
|
|
local text = forms[name] and forms[name].context.text
|
|
if not text then return end
|
|
|
|
msg = tostring(msg)
|
|
for _, line in ipairs(msg:split('\n', true)) do
|
|
text[#text + 1] = col .. line
|
|
if #text > 501 then
|
|
text[1] = '#aaaaaaSnippets only stores 500 lines of scrollback.'
|
|
table.remove(text, 2)
|
|
end
|
|
end
|
|
snippets.update_console(name)
|
|
end
|
|
|
|
snippets.register_on_log(function(snippet, level, msg)
|
|
local owner = snippets.registered_snippets[snippet].owner
|
|
local form = forms[owner]
|
|
if not owner or not form or not form.context.text or
|
|
not form:is_open() then
|
|
return
|
|
end
|
|
if level ~= 'none' then
|
|
msg = level:sub(1, 1):upper() .. level:sub(2) .. ': ' .. msg
|
|
end
|
|
|
|
local col
|
|
if level == 'warning' then
|
|
col = '#FFFF00'
|
|
elseif level == 'error' then
|
|
col = '#FF0000'
|
|
elseif level == 'debug' then
|
|
col = '#888888'
|
|
end
|
|
|
|
local p = snippet:sub(1, 16) == 'snippets:player_'
|
|
if not p then msg = 'From snippet "' .. snippet .. '": ' .. msg end
|
|
|
|
snippets.push_console_msg(owner, msg, col)
|
|
|
|
if p then return true end
|
|
end)
|
|
|
|
minetest.register_chatcommand('snippets', {
|
|
description = 'Opens the snippets console.',
|
|
privs = {server=true},
|
|
func = function(name, param)
|
|
snippets.show_console(name)
|
|
return true, 'Opened the snippets console.'
|
|
end,
|
|
})
|
|
|
|
local function saveform_callback(saveform, fields)
|
|
local name = saveform.pname
|
|
local form = forms[name]
|
|
saveform:close()
|
|
|
|
-- Sanity check
|
|
if not minetest.check_player_privs(name, 'server') or not form then
|
|
forms[name] = nil
|
|
return
|
|
end
|
|
|
|
if not fields.filename or fields.filename == '' then
|
|
minetest.chat_send_player(name, 'Save operation cancelled.')
|
|
snippets.show_console(name)
|
|
return
|
|
end
|
|
|
|
-- Don't overwrite non-persistent snippets
|
|
local filename = fields.filename:gsub(':', '/')
|
|
while snippets.registered_snippets[filename] and
|
|
not snippets.registered_snippets[filename].persistent do
|
|
filename = filename .. '_'
|
|
end
|
|
|
|
-- Actually save it
|
|
snippets.register_snippet(filename, {
|
|
owner = name,
|
|
code = form.context.code,
|
|
persistent = true,
|
|
})
|
|
|
|
form.context.selected_snippet = filename
|
|
snippets.show_console(name)
|
|
end
|
|
|
|
function callback(form, fields)
|
|
local name = form.pname
|
|
if not minetest.check_player_privs(name, 'server') then
|
|
forms[name] = nil
|
|
form:close()
|
|
end
|
|
|
|
if fields.code then
|
|
form.context.code = fields.code
|
|
end
|
|
|
|
if fields.ignore then
|
|
return
|
|
elseif fields.run then
|
|
local code = fields.code
|
|
form.context.text = {}
|
|
snippets.show_console(name)
|
|
if not code or code == '' then return end
|
|
local res = snippets.exec_as_player(name, code)
|
|
if res ~= nil then
|
|
snippets.push_console_msg(name, res)
|
|
end
|
|
elseif fields.reset then
|
|
form.context.text = nil
|
|
snippets.update_console(name)
|
|
elseif fields.snippetlist and form.context.snippet_list then
|
|
local event = minetest.explode_textlist_event(fields.snippetlist)
|
|
local selected = form.context.snippet_list[event.index - 1]
|
|
if form.context.selected_snippet == selected then return end
|
|
form.context.selected_snippet = selected
|
|
form.context.text = nil
|
|
local def = snippets.registered_snippets[selected]
|
|
form.context.code = def and def.code or ''
|
|
snippets.update_console(name)
|
|
elseif fields.save and form.context.selected_snippet then
|
|
if form.context.code == '' then
|
|
snippets.unregister_snippet(form.context.selected_snippet)
|
|
form.context.selected_snippet = nil
|
|
else
|
|
snippets.register_snippet(form.context.selected_snippet, {
|
|
owner = name,
|
|
code = form.context.code,
|
|
persistent = true,
|
|
})
|
|
end
|
|
snippets.show_console(name)
|
|
elseif fields.save or fields.save_as and form.context.code ~= '' then
|
|
form.context.text = nil
|
|
|
|
local saveform = snippets.Form(name)
|
|
saveform:set_formspec(
|
|
'field[filename;Please enter a new snippet name.;]')
|
|
saveform:add_callback(saveform_callback)
|
|
saveform:show()
|
|
elseif fields.quit then
|
|
form.text = nil
|
|
end
|
|
end
|