From aac2ba82e6b0fadbdd9b56a008b21ccd1335dccc Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Wed, 6 Mar 2019 23:17:52 +0000 Subject: [PATCH] Added /cheat-mode and /interface --- control.lua | 2 + locale/en/commands-local.cfg | 2 +- modules/commands/cheat-mode.lua | 12 ++++ modules/commands/commands-local.cfg | 2 +- modules/commands/interface.lua | 89 +++++++++++++++++++++++++++++ 5 files changed, 105 insertions(+), 2 deletions(-) create mode 100644 modules/commands/cheat-mode.lua create mode 100644 modules/commands/interface.lua diff --git a/control.lua b/control.lua index 1d810817..160eabee 100644 --- a/control.lua +++ b/control.lua @@ -21,6 +21,8 @@ local files = { 'modules.commands.admin-chat', 'modules.commands.tag', 'modules.commands.teleport', + 'modules.commands.cheat-mode', + 'modules.commands.interface', } -- Loads all files in array above and logs progress diff --git a/locale/en/commands-local.cfg b/locale/en/commands-local.cfg index dae5141f..3e5abe44 100644 --- a/locale/en/commands-local.cfg +++ b/locale/en/commands-local.cfg @@ -2,4 +2,4 @@ kill-already-dead=You are already dead. admin-chat-format=[Admin Chat] [color=__3__]__1__: __2__ tp-no-position-found=No position to teleport to was found, please try again later. -tp-to-self=Player can not be teleported to them selfs. \ No newline at end of file +tp-to-self=Player can not be teleported to themselves. \ No newline at end of file diff --git a/modules/commands/cheat-mode.lua b/modules/commands/cheat-mode.lua new file mode 100644 index 00000000..565060e9 --- /dev/null +++ b/modules/commands/cheat-mode.lua @@ -0,0 +1,12 @@ +local Commands = require 'expcore.commands' +require 'expcore.common_parse' + +Commands.new_command('toggle-cheat-mode','Toggles cheat mode for your player, or another player.') +:add_param('player',true,'player') -- player to toggle chest mode of, can be nil for self +:add_defaults{player=function(player) + return player -- default is the user using the command +end} +:add_tag('admin_only',true) +:register(function(player,action_player,raw) + action_player.cheat_mode = not action_player.cheat_mode +end) \ No newline at end of file diff --git a/modules/commands/commands-local.cfg b/modules/commands/commands-local.cfg index dae5141f..3e5abe44 100644 --- a/modules/commands/commands-local.cfg +++ b/modules/commands/commands-local.cfg @@ -2,4 +2,4 @@ kill-already-dead=You are already dead. admin-chat-format=[Admin Chat] [color=__3__]__1__: __2__ tp-no-position-found=No position to teleport to was found, please try again later. -tp-to-self=Player can not be teleported to them selfs. \ No newline at end of file +tp-to-self=Player can not be teleported to themselves. \ No newline at end of file diff --git a/modules/commands/interface.lua b/modules/commands/interface.lua new file mode 100644 index 00000000..91bc7b60 --- /dev/null +++ b/modules/commands/interface.lua @@ -0,0 +1,89 @@ +local Commands = require 'expcore.commands' +local Global = require 'utils.global' +local Common = require 'expcore.common' + +-- modules that are loaded into the interface env to be accessed +local interface_modules = { + ['Game']='utils.game', + ['Commands']=Commands, + ['output']=Common.player_return +} + +-- loads all the modules given in the above table +for key,value in pairs(interface_modules) do + if type(value) == 'string' then + interface_modules[key] = require(value) + end +end + +local interface_env = {} -- used as a persistent sandbox for interface commands +local interface_callbacks = {} -- saves callbacks which can load new values per use +Global.register({interface_env,interface_callbacks},function(tbl) + interface_env = tbl[1] + interface_callbacks = tbl[2] +end) + +--- Adds a callback function when the interface command is used +-- nb: returned value is saved in the env that the interface uses +-- @tparam name string the name that the value is loaded under, cant use upvalues +-- @tparam callback function the function that will run whent he command is used +-- callback param - player: LuaPlayer - the player who used the command +local function add_interface_callback(name,callback) + if type(callback) == 'function' then + interface_callbacks[name] = callback + end +end + +-- this is a meta function for __index when self[key] is nil +local function get_index(self,key) + if interface_env[key] then + return interface_env[key] + elseif interface_modules[key] then + return interface_modules[key] + end +end + +Commands.new_command('interface','Sends an innovation to be ran and returns the result.') +:add_param('innovation',false) -- the message to send in the admin chat +:enable_auto_concat() +:add_tag('admin_only',true) +:register(function(player,innovation,raw) + if not innovation:find('%s') and not innovation:find('return') then + -- if there are no spaces and return is not present then return is appended to the start + innovation='return '..innovation + end + -- temp_env will index to interface_env and interface_modules if value not found + local temp_env = setmetatable({},{__index=get_index}) + for name,callback in pairs(interface_callbacks) do + -- loops over callbacks and loads the values returned + local success, rtn = pcall(callback,player) + temp_env[name]=rtn + end + -- sets the global metatable to prevent new values being made + -- global will index to temp_env and new indexs saved to interface_sandbox + local old_mt = getmetatable(_G) + setmetatable(_G,{__index=temp_env,__newindex=interface_env}) + -- runs the innovation and returns values to the player + innovation = loadstring(innovation) + local success, rtn = pcall(innovation) + setmetatable(_G,old_mt) + if not success then + if type(rtn) == 'string' then + -- there may be stack trace that must be removed to avoid desyncs + rtn = rtn:gsub('%.%.%..-/temp/currently%-playing','') + end + return Commands.error(rtn) + else + return Commands.success(rtn) + end +end) + +-- adds some basic callbacks for the interface +add_interface_callback('player',function(player) return player end) +add_interface_callback('surface',function(player) return player.surface end) +add_interface_callback('force',function(player) return player.force end) +add_interface_callback('position',function(player) return player.position end) +add_interface_callback('entity',function(player) return player.selected end) +add_interface_callback('tile',function(player) return player.surface.get_tile(player.position) end) + +return add_interface_callback \ No newline at end of file