summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcheapie <no-email-for-you@example.com>2022-01-02 13:48:45 -0600
committercheapie <no-email-for-you@example.com>2022-01-02 13:48:45 -0600
commit2ad8e91d9fd3f968106b52f7fcaf2710587974b5 (patch)
tree83269700ada305b4735ba716fb50d579460e58a5
parenta98cf4b03d42d3836148da590bb0cde9f689037f (diff)
downloadmesecons-2ad8e91d9fd3f968106b52f7fcaf2710587974b5.tar
mesecons-2ad8e91d9fd3f968106b52f7fcaf2710587974b5.tar.gz
mesecons-2ad8e91d9fd3f968106b52f7fcaf2710587974b5.tar.bz2
mesecons-2ad8e91d9fd3f968106b52f7fcaf2710587974b5.tar.xz
mesecons-2ad8e91d9fd3f968106b52f7fcaf2710587974b5.zip
Add Luacontroller terminal
This adds a "terminal" tab to the Luacontroller, which: * Shows errors, warnings, and print() output (fixing upstream #388) * Allows text to be entered, which is sent as event.text with an event.type of "terminal" The Luacontroller formspec has also been converted to version 4 in the process.
-rw-r--r--mesecons_luacontroller/init.lua166
1 files changed, 122 insertions, 44 deletions
diff --git a/mesecons_luacontroller/init.lua b/mesecons_luacontroller/init.lua
index 04438e9..669bacb 100644
--- a/mesecons_luacontroller/init.lua
+++ b/mesecons_luacontroller/init.lua
@@ -211,16 +211,81 @@ local function ignore_event(event, meta)
end
end
+-----------------------
+-- Formspec creation --
+-----------------------
+
+local function update_formspec(pos)
+ local meta = minetest.get_meta(pos)
+ local code = minetest.formspec_escape(meta:get_string("code"))
+ local errmsg = minetest.formspec_escape(meta:get_string("errmsg"))
+ local tab = meta:get_int("tab")
+ if tab < 1 or tab > 2 then tab = 1 end
+
+ --Default theme settings
+ local textcolor = "#ffffff"
+ local bg_img = "jeija_luac_background.png"
+ local run_img = "jeija_luac_runbutton.png"
+ local close_img = "jeija_close_window.png"
+
+ --If Dreambuilder's theming engine is in use, then override those
+ if minetest.global_exists("dreambuilder_theme") then
+ textcolor = dreambuilder_theme.editor_text_color
+ bg_img = dreambuilder_theme.name.."_jeija_luac_background.png"
+ run_img = dreambuilder_theme.name.."_jeija_luac_runbutton.png"
+ close_img = dreambuilder_theme.name.."_jeija_close_window.png"
+ end
+
+ local fs = "formspec_version[4]"
+ .."size[15,12]"
+ .."style_type[label,textarea,field;font=mono]"
+ .."style_type[textarea;textcolor="..textcolor.."]"
+ .."background[0,0;15,12;"..bg_img.."]"
+ .."tabheader[0,0;tab;Code,Terminal;"..tab.."]"
+ .."image_button_exit[14.5,0;0.425,0.4;"..close_img..";exit;]"
+
+ if tab == 1 then
+ --Code tab
+ fs = fs.."label[0.1,10;"..errmsg.."]"
+ .."textarea[0.25,0.6;14.5,9.05;code;;"..code.."]"
+ .."image_button[6.25,10.25;2.5,1;"..run_img..";program;]"
+ elseif tab == 2 then
+ --Terminal tab
+ local termtext = minetest.formspec_escape(meta:get_string("terminal_text"))
+ fs = fs.."textarea[0.25,0.6;14.5,9.05;;;"..termtext.."]"
+ .."field[0.25,9.85;12.5,1;terminal_input;;]"
+ .."button[12.75,9.85;2,1;terminal_send;Send]"
+ .."button[12.75,10.85;2,1;terminal_clear;Clear]"
+ .."field_close_on_enter[terminal_input;false]"
+ end
+
+ meta:set_string("formspec",fs)
+end
+
-------------------------
-- Parsing and running --
-------------------------
-local function safe_print(param)
- local string_meta = getmetatable("")
- local sandbox = string_meta.__index
- string_meta.__index = string -- Leave string sandbox temporarily
- print(dump(param))
- string_meta.__index = sandbox -- Restore string sandbox
+local function terminal_write(pos,text)
+ local meta = minetest.get_meta(pos)
+ local oldtext = meta:get_string("terminal_text")
+ local delim = string.len(oldtext) > 0 and "\n" or ""
+ local newtext = string.sub(oldtext..delim..text,-100000,-1)
+ meta:set_string("terminal_text",newtext)
+end
+
+local function get_safe_print(pos)
+ return function (param)
+ local string_meta = getmetatable("")
+ local sandbox = string_meta.__index
+ string_meta.__index = string -- Leave string sandbox temporarily
+ if type(param) == "string" then
+ terminal_write(pos,param)
+ else
+ terminal_write(pos,dump(param))
+ end
+ string_meta.__index = sandbox -- Restore string sandbox
+ end
end
local function safe_date()
@@ -549,7 +614,7 @@ local function create_environment(pos, mem, event, itbl, send_warning)
mem = mem,
heat = mesecon.get_heat(pos),
heat_max = mesecon.setting("overheat_max", 20),
- print = safe_print,
+ print = get_safe_print(pos),
interrupt = get_interrupt(pos, itbl, send_warning),
digiline_send = get_digiline_send(pos, itbl, send_warning),
string = {
@@ -690,6 +755,7 @@ local function run_inner(pos, code, event)
local warning = ""
local function send_warning(str)
warning = "Warning: " .. str
+ terminal_write(pos,"[WARNING] "..str)
end
-- Create environment
@@ -728,36 +794,17 @@ local function run_inner(pos, code, event)
return true, warning
end
-local function reset_formspec(meta, code, errmsg)
+local function reset_formspec(pos, meta, code, errmsg)
meta:set_string("code", code)
meta:mark_as_private("code")
- code = minetest.formspec_escape(code or "")
- errmsg = minetest.formspec_escape(tostring(errmsg or ""))
- if minetest.get_modpath("dreambuilder_theme_settings") then
- meta:set_string("formspec", "size[12,10]"
- .."style_type[label,textarea;font=mono]"
- .."style_type[textarea;textcolor="..dreambuilder_theme.editor_text_color.."]"
- .."background[-0.2,-0.25;12.4,10.75;"..dreambuilder_theme.name.."_jeija_luac_background.png]"
- .."label[0.1,8.3;"..errmsg.."]"
- .."textarea[0.2,0.2;12.2,9.5;code;;"..code.."]"
- .."image_button[4.75,8.75;2.5,1;"..dreambuilder_theme.name.."_jeija_luac_runbutton.png;program;]"
- .."image_button_exit[11.72,-0.25;0.425,0.4;"..dreambuilder_theme.name.."_jeija_close_window.png;exit;]"
- )
- else
- meta:set_string("formspec", "size[12,10]"
- .."style_type[label,textarea;font=mono]"
- .."background[-0.2,-0.25;12.4,10.75;jeija_luac_background.png]"
- .."label[0.1,8.3;"..errmsg.."]"
- .."textarea[0.2,0.2;12.2,9.5;code;;"..code.."]"
- .."image_button[4.75,8.75;2.5,1;jeija_luac_runbutton.png;program;]"
- .."image_button_exit[11.72,-0.25;0.425,0.4;jeija_close_window.png;exit;]"
- )
- end
+ meta:set_string("errmsg",tostring(errmsg or ""))
+ meta:mark_as_private("errmsg")
+ update_formspec(pos)
end
local function reset_meta(pos, code, errmsg)
local meta = minetest.get_meta(pos)
- reset_formspec(meta, code, errmsg)
+ reset_formspec(pos, meta, code, errmsg)
meta:set_int("luac_id", math.random(1, 65535))
end
@@ -770,9 +817,10 @@ local function run(pos, event)
local code = meta:get_string("code")
local ok, errmsg = run_inner(pos, code, event)
if not ok then
+ terminal_write(pos,"[ERROR] "..errmsg)
reset_meta(pos, code, errmsg)
else
- reset_formspec(meta, code, errmsg)
+ reset_formspec(pos, meta, code, errmsg)
end
return ok, errmsg
end
@@ -879,18 +927,48 @@ local function set_program(pos, code)
end
local function on_receive_fields(pos, form_name, fields, sender)
- if not fields.program then
- return
- end
- local name = sender:get_player_name()
- if minetest.is_protected(pos, name) and not minetest.check_player_privs(name, {protection_bypass=true}) then
- minetest.record_protection_violation(pos, name)
- return
- end
- local ok, err = set_program(pos, fields.code)
- if not ok then
- -- it's not an error from the server perspective
- minetest.log("action", "Lua controller programming error: " .. tostring(err))
+ local meta = minetest.get_meta(pos)
+ if fields.tab then
+ local name = sender:get_player_name()
+ if minetest.is_protected(pos, name) and not minetest.check_player_privs(name, {protection_bypass=true}) then
+ minetest.record_protection_violation(pos, name)
+ return
+ end
+ meta:set_int("tab",fields.tab)
+ update_formspec(pos)
+ else
+ local tab = meta:get_int("tab")
+ if tab == 1 then
+ --Code tab
+ if not fields.program then
+ return
+ end
+ local name = sender:get_player_name()
+ if minetest.is_protected(pos, name) and not minetest.check_player_privs(name, {protection_bypass=true}) then
+ minetest.record_protection_violation(pos, name)
+ return
+ end
+ meta:set_string("terminal_text","")
+ local ok, err = set_program(pos, fields.code)
+ if not ok then
+ -- it's not an error from the server perspective
+ minetest.log("action", "Lua controller programming error: " .. tostring(err))
+ end
+ elseif tab == 2 then
+ --Terminal tab
+ if fields.exit or fields.quit then return end
+ local name = sender:get_player_name()
+ if minetest.is_protected(pos, name) and not minetest.check_player_privs(name, {protection_bypass=true}) then
+ minetest.record_protection_violation(pos, name)
+ return
+ end
+ if fields.terminal_clear then
+ meta:set_string("terminal_text","")
+ update_formspec(pos)
+ return
+ end
+ run(pos,{type="terminal",text=fields.terminal_input})
+ end
end
end