From caec284d1baab9ac77b4720d2754a681f9010882 Mon Sep 17 00:00:00 2001 From: Octav Sandulescu Date: Wed, 23 May 2018 12:37:46 +0000 Subject: [PATCH] Add a console - show it with `remote.call("prodmon", "console")` - it's a Lua interpreter inside the mod's sandbox, so you can use it to peek and poke as desired - lifted from Factorio-Stdlib and adapted for here --- VERSION | 2 +- gui.lua | 26 +++++++------- remote.lua | 3 +- utils/STDLIB-LICENSE | 13 +++++++ utils/console.lua | 83 ++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 111 insertions(+), 16 deletions(-) create mode 100644 utils/STDLIB-LICENSE create mode 100644 utils/console.lua diff --git a/VERSION b/VERSION index c946ee6..0ea3a94 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.1.6 +0.2.0 diff --git a/gui.lua b/gui.lua index 6cd9acc..be71d46 100644 --- a/gui.lua +++ b/gui.lua @@ -1,6 +1,7 @@ gui = { data_rows = {}, + patterns = {}, -- and functions below } @@ -231,16 +232,6 @@ function gui.update_display_row(player, i, data_row) end -function string.starts_with(haystack, needle) - return string.sub(haystack, 1, string.len(needle)) == needle -end - - -function string.ends_with(haystack, needle) - return string.sub(haystack, -string.len(needle)) == needle -end - - function gui.rename_monitor(player, old_name) local rename_root = player.gui.center.add{ type="frame", direction="vertical", name="prodmon_rename_"..old_name } rename_root.add{ type="label", caption=string.format("Rename the monitor \"%s\" to:", old_name) } @@ -253,11 +244,16 @@ function gui.rename_monitor(player, old_name) end +function gui.register_on_click(pattern, handler) + gui.patterns[pattern] = handler +end + + function gui.on_click(e) - if string.starts_with(e.element.name, "prodmon_rename_ok_") then - gui.on_rename_ok(e) - elseif string.starts_with(e.element.name, "prodmon_rename_cancel_") then - gui.on_rename_cancel(e) + for pattern, handler in pairs(gui.patterns) do + if e.element.name:match(pattern) then + handler(e) + end end end @@ -277,6 +273,7 @@ function gui.on_rename_ok(e) rename_root.destroy() end end +gui.register_on_click("^prodmon_rename_ok_", gui.on_rename_ok) function gui.on_rename_cancel(e) @@ -285,3 +282,4 @@ function gui.on_rename_cancel(e) player.gui.center["prodmon_rename_"..old_name].destroy() end +gui.register_on_click("^prodmon_rename_cancel_", gui.on_rename_cancel) diff --git a/remote.lua b/remote.lua index b3109c5..dcd8bf6 100644 --- a/remote.lua +++ b/remote.lua @@ -1,5 +1,7 @@ interface = {} +interface.console = require("utils.console") + function interface.reset_gui(player) if not player then return end @@ -15,5 +17,4 @@ function interface.on_init() gui.on_init() end - remote.add_interface("prodmon", interface) diff --git a/utils/STDLIB-LICENSE b/utils/STDLIB-LICENSE new file mode 100644 index 0000000..e0f7493 --- /dev/null +++ b/utils/STDLIB-LICENSE @@ -0,0 +1,13 @@ +Copyright (c) 2016, Afforess + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/utils/console.lua b/utils/console.lua new file mode 100644 index 0000000..4023ca5 --- /dev/null +++ b/utils/console.lua @@ -0,0 +1,83 @@ +--- Debug console. +-- Originally from Factorio-stdlib +-- (Copyright (c) 2016 Afforess, licensed under the ISC license -- +-- see STDLIB-LICENSE in this package) +-- +-- Original documentation below: +-- Creates a textfield allowing you to run commands directly in your mod's enviorment. +--

This module requires the use of stdlib's @{Event} module for GUI interactions. +--

This module was originally the ***Console*** code from a modder named ***adil***, which has been modified for use with stdlib. +-- @module Console +-- @usage +-- remote.add_interface("my_interface", {show = require("stdlib/utils/console")}) +-- /c remote.call("my_interface", "show", game.player) +-- --In the window that appears you can run lua code directly on your mod, including globals. +require("gui") + + +--TODO fix for .16 when script.mod_name is implemented +local have_mod_name, mod_name = pcall(function() return script.mod_name end) +local prefix = (have_mod_name and mod_name) or (MOD and MOD.console_prefix) or "console" +local names = { + frame = prefix..'_console', + scroll = prefix..'_console_scroll', + textbox = prefix..'_console_line', + enter = prefix..'_console_enter', + clear = prefix..'_console_clear', + close = prefix..'_console_close', +} + +local function create_gui_player(player) + if player.gui.left[names.frame] then player.gui.left[names.frame].destroy() end + + local c = player.gui.left.add{type='frame', name = names.frame, direction = 'horizontal'} + + local scroll = c.add{type = 'scroll-pane', name = names.scroll} + scroll.style.minimal_width=600 + scroll.style.maximal_width=600 + scroll.style.maximal_height=150 + scroll.style.minimal_height=150 + + local t = scroll.add{type = 'text-box', name = names.textbox} + t.style.minimal_width=600 + t.style.maximal_width=600 + t.style.minimal_height=150 + + c.add{type = 'button', name = names.enter, caption = '<', tooltip = "Run Script"} + c.add{type = 'button', name = names.clear, caption = 'C', tooltip = "Clear Input"} + c.add{type = 'button', name = names.close, caption = "X", tooltip = "Close"} +end + +local function create_gui(player) + --if not sent with a player, then enable for all players? + if not (player and player.valid) then + for _, cur_player in pairs(game.players) do + create_gui_player(cur_player) + end + else + create_gui_player(player) + end +end + +local function enter(event) + local p = game.players[event.player_index] + local s = event.element.parent[names.scroll][names.textbox].text + + local ok, err = pcall(function() return loadstring(s)() end ) + if not ok then p.print(err) end + --pcall(loadstring("return function(a, b, c) ".. chunkstring .. " end")) + game.write_file(prefix..'/console.log', s..'\n', true, p.index) +end +gui.register_on_click('^'..names.enter..'$', enter) + +local function close(event) + event.element.parent.destroy() +end +gui.register_on_click('^'..names.close..'$', close) + +local function clear(event) + event.element.parent[names.scroll][names.textbox].text = "" +end +gui.register_on_click('^'..names.clear..'$', clear) + +return create_gui