mirror of
https://github.com/PHIDIAS0303/ExpCluster.git
synced 2025-12-31 21:01:39 +09:00
Added Redmew Debugger and Debugged Checkboxs
This commit is contained in:
@@ -32,6 +32,8 @@ return {
|
|||||||
'modules.addons.scorched-earth',
|
'modules.addons.scorched-earth',
|
||||||
'modules.addons.pollution-grading',
|
'modules.addons.pollution-grading',
|
||||||
'modules.addons.random-player-colours',
|
'modules.addons.random-player-colours',
|
||||||
|
-- GUI
|
||||||
|
'modules.commands.debug',
|
||||||
-- Config Files
|
-- Config Files
|
||||||
'config.command_auth_admin', -- commands tagged with admin_only are blocked for non admins
|
'config.command_auth_admin', -- commands tagged with admin_only are blocked for non admins
|
||||||
'config.command_auth_roles', -- commands must be allowed via the role config
|
'config.command_auth_roles', -- commands must be allowed via the role config
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ Roles.new_role('Senior Administrator','SAdmin')
|
|||||||
:set_parent('Administrator')
|
:set_parent('Administrator')
|
||||||
:allow{
|
:allow{
|
||||||
'command/interface',
|
'command/interface',
|
||||||
|
'command/debug',
|
||||||
'command/toggle-cheat-mode'
|
'command/toggle-cheat-mode'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,12 +23,13 @@ function Button.new_button(name)
|
|||||||
local uid = Gui.uid_name()
|
local uid = Gui.uid_name()
|
||||||
local self = setmetatable({
|
local self = setmetatable({
|
||||||
name=uid,
|
name=uid,
|
||||||
clean_name=name
|
clean_name=name,
|
||||||
|
_draw={
|
||||||
|
name=uid,
|
||||||
|
style=mod_gui.button_style,
|
||||||
|
type='button'
|
||||||
|
}
|
||||||
},{__index=Button._prototype})
|
},{__index=Button._prototype})
|
||||||
|
|
||||||
self._draw.name = uid
|
|
||||||
self._draw.style = mod_gui.button_style
|
|
||||||
self._draw.type = 'button'
|
|
||||||
Button.config[uid] = self
|
Button.config[uid] = self
|
||||||
|
|
||||||
if name then
|
if name then
|
||||||
|
|||||||
@@ -30,9 +30,10 @@ end
|
|||||||
|
|
||||||
local function get_instances(checkbox,category)
|
local function get_instances(checkbox,category)
|
||||||
if not Checkbox.instances[checkbox.name] then return end
|
if not Checkbox.instances[checkbox.name] then return end
|
||||||
local instances = Checkbox.instances
|
local instances = Checkbox.instances[checkbox.name]
|
||||||
if checkbox.categorize then
|
if checkbox.categorize then
|
||||||
instances = instances[category]
|
if not instances[category] then instances[category] = {} end
|
||||||
|
return instances[category]
|
||||||
end
|
end
|
||||||
return instances
|
return instances
|
||||||
end
|
end
|
||||||
@@ -43,9 +44,12 @@ function Checkbox.new_checkbox(name)
|
|||||||
local self = setmetatable({
|
local self = setmetatable({
|
||||||
name=uid,
|
name=uid,
|
||||||
clean_name=name,
|
clean_name=name,
|
||||||
|
_draw={
|
||||||
|
name=uid,
|
||||||
|
type='checkbox',
|
||||||
|
state=false
|
||||||
|
}
|
||||||
},{__index=Checkbox._prototype_checkbox})
|
},{__index=Checkbox._prototype_checkbox})
|
||||||
self._draw.name = uid
|
|
||||||
self._draw.type = 'checkbox'
|
|
||||||
|
|
||||||
self._post_draw = function(element)
|
self._post_draw = function(element)
|
||||||
local category = self.categorize and self.categorize(element) or nil
|
local category = self.categorize and self.categorize(element) or nil
|
||||||
@@ -53,6 +57,8 @@ function Checkbox.new_checkbox(name)
|
|||||||
if instances then
|
if instances then
|
||||||
table.insert(instances,element)
|
table.insert(instances,element)
|
||||||
end
|
end
|
||||||
|
local state = self:get_store_state(category)
|
||||||
|
if state then element.state = true end
|
||||||
end
|
end
|
||||||
|
|
||||||
Checkbox.config[uid] = self
|
Checkbox.config[uid] = self
|
||||||
@@ -66,7 +72,7 @@ function Checkbox.new_checkbox(name)
|
|||||||
local element = event.element
|
local element = event.element
|
||||||
if self.store then
|
if self.store then
|
||||||
if self.categorize then
|
if self.categorize then
|
||||||
Store.set_chlid(self.store,self.categorize(element),element.state)
|
Store.set_child(self.store,self.categorize(element),element.state)
|
||||||
else
|
else
|
||||||
Store.set(self.store,element.state)
|
Store.set(self.store,element.state)
|
||||||
end
|
end
|
||||||
@@ -87,11 +93,12 @@ function Checkbox._prototype_checkbox:add_store(categorize)
|
|||||||
if self.store then return end
|
if self.store then return end
|
||||||
self.store = get_store_location(self)
|
self.store = get_store_location(self)
|
||||||
self.categorize = categorize
|
self.categorize = categorize
|
||||||
|
Checkbox.instances[self.name]={}
|
||||||
Store.register(self.store,function(value,category)
|
Store.register(self.store,function(value,category)
|
||||||
local instances = get_instances(self,category)
|
local instances = get_instances(self,category)
|
||||||
if instances then
|
if instances then
|
||||||
for k,element in pairs(instances) do
|
for k,element in pairs(instances) do
|
||||||
if element.valid then
|
if element and element.valid then
|
||||||
element.state = value
|
element.state = value
|
||||||
if self._on_state_change then
|
if self._on_state_change then
|
||||||
local player = Game.get_player_by_index(element.player_index)
|
local player = Game.get_player_by_index(element.player_index)
|
||||||
@@ -109,7 +116,7 @@ end
|
|||||||
function Checkbox._prototype_checkbox:get_store_state(category)
|
function Checkbox._prototype_checkbox:get_store_state(category)
|
||||||
if not self.store then return end
|
if not self.store then return end
|
||||||
if self.categorize then
|
if self.categorize then
|
||||||
return Store.get_chlid(self.store,category)
|
return Store.get_child(self.store,category)
|
||||||
else
|
else
|
||||||
return Store.get(self.store)
|
return Store.get(self.store)
|
||||||
end
|
end
|
||||||
@@ -119,9 +126,9 @@ function Checkbox._prototype_checkbox:set_store_state(category,state)
|
|||||||
if not self.store then return end
|
if not self.store then return end
|
||||||
state = not not state
|
state = not not state
|
||||||
if self.categorize then
|
if self.categorize then
|
||||||
return Store.set_chlid(self.store,category,state)
|
return Store.set_child(self.store,category,state)
|
||||||
else
|
else
|
||||||
return Store.set(self.store,state)
|
return Store.set(self.store,category)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -151,11 +158,11 @@ function Checkbox._prototype_radiobutton:add_store(categorize)
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function Checkbox._prototype_radiobutton:get_store_value(category)
|
function Checkbox._prototype_radiobutton:get_store_state(category)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function Checkbox._prototype_radiobutton:set_store_value(category,value)
|
function Checkbox._prototype_radiobutton:set_store_state(category,value)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -171,12 +178,14 @@ function Checkbox._prototype_radiobutton:on_state_change(callback)
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function Checkbox.get_stored_value(name,category)
|
function Checkbox.get_stored_state(name,category)
|
||||||
|
local checkbox = get_config(name)
|
||||||
|
return checkbox:get_store_state(category)
|
||||||
end
|
end
|
||||||
|
|
||||||
function Checkbox.set_stored_value(name,category,value)
|
function Checkbox.set_stored_state(name,category,value)
|
||||||
|
local checkbox = get_config(name)
|
||||||
|
return checkbox:set_store_state(category,value)
|
||||||
end
|
end
|
||||||
|
|
||||||
return Checkbox
|
return Checkbox
|
||||||
@@ -1,26 +1,27 @@
|
|||||||
local Gui = require 'utils.gui'
|
local Gui = require 'utils.gui'
|
||||||
|
local Game = require 'utils.game'
|
||||||
|
|
||||||
Gui._prototype = {_draw={}}
|
Gui._prototype = {}
|
||||||
Gui.inputs = {}
|
Gui.inputs = {}
|
||||||
Gui.structure = {}
|
Gui.structure = {}
|
||||||
Gui.outputs = {}
|
Gui.outputs = {}
|
||||||
|
|
||||||
function Gui._extend_prototype(tbl)
|
function Gui._extend_prototype(tbl)
|
||||||
for k,v in pairs(Gui._prototype) do
|
for k,v in pairs(Gui._prototype) do
|
||||||
if not tbl[k] then tbl[k] = table.deep_copy(v) end
|
if not tbl[k] then tbl[k] = v end
|
||||||
end
|
end
|
||||||
return tbl
|
return tbl
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Sets the caption for the element config
|
--- Sets the caption for the element config
|
||||||
function Gui._prototype:set_caption(caption)
|
function Gui._prototype:set_caption(caption)
|
||||||
self.caption = caption
|
self._draw.caption = caption
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Sets the tooltip for the element config
|
--- Sets the tooltip for the element config
|
||||||
function Gui._prototype:set_tooltip(tooltip)
|
function Gui._prototype:set_tooltip(tooltip)
|
||||||
self.tooltip = tooltip
|
self._draw.tooltip = tooltip
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -44,13 +45,14 @@ end
|
|||||||
|
|
||||||
--- Draws the element using what is in the _draw table, allows use of authenticator if present
|
--- Draws the element using what is in the _draw table, allows use of authenticator if present
|
||||||
function Gui._prototype:draw_to(element)
|
function Gui._prototype:draw_to(element)
|
||||||
if element.children[self.name] then return end
|
if element[self.name] then return end
|
||||||
|
local player = Game.get_player_by_index(element.player_index)
|
||||||
if self.pre_authenticator then
|
if self.pre_authenticator then
|
||||||
if not self.pre_authenticator(element.player,self.clean_name or self.name) then return end
|
if not self.pre_authenticator(player,self.clean_name or self.name) then return end
|
||||||
end
|
end
|
||||||
local _element = element.add(self._draw)
|
local _element = element.add(self._draw)
|
||||||
if self.authenticator then
|
if self.authenticator then
|
||||||
_element.enabled = not not self.authenticator(element.player,self.clean_name or self.name)
|
_element.enabled = not not self.authenticator(player,self.clean_name or self.name)
|
||||||
end
|
end
|
||||||
if self._post_draw then self._post_draw(_element) end
|
if self._post_draw then self._post_draw(_element) end
|
||||||
return _element
|
return _element
|
||||||
|
|||||||
@@ -1,4 +1,10 @@
|
|||||||
local Gui = require 'expcore.gui'
|
local Gui = require 'expcore.gui'
|
||||||
|
local format_chat_colour = ext_require('expcore.common','format_chat_colour')
|
||||||
|
local Colors = require 'resources.color_presets'
|
||||||
|
local Game = require 'utils.game'
|
||||||
|
local clean_stack_trace = ext_require('modules.commands.interface','clean_stack_trace')
|
||||||
|
|
||||||
|
local tests = {}
|
||||||
|
|
||||||
Gui.new_toolbar_button('click-1')
|
Gui.new_toolbar_button('click-1')
|
||||||
:set_authenticator(function(player,button_name)
|
:set_authenticator(function(player,button_name)
|
||||||
@@ -25,3 +31,82 @@ end)
|
|||||||
:on_click(function(player,element,event)
|
:on_click(function(player,element,event)
|
||||||
player.print('CLICK 3')
|
player.print('CLICK 3')
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
Gui.new_toolbar_button('gui-test-open')
|
||||||
|
:set_caption('Open Test Gui')
|
||||||
|
:set_authenticator(function(player,button_name)
|
||||||
|
return global.show_test_gui
|
||||||
|
end)
|
||||||
|
:on_click(function(player,_element,event)
|
||||||
|
if player.gui.center.TestGui then player.gui.center.TestGui.destroy() return end
|
||||||
|
local frame = player.gui.center.add{type='frame',caption='Gui Test',name='TestGui'}
|
||||||
|
frame = frame.add{type='table',column_count=5}
|
||||||
|
for key,element in pairs(tests) do
|
||||||
|
local success,err = pcall(element.draw_to,element,frame)
|
||||||
|
if success then
|
||||||
|
player.print('Drawing: '..key..format_chat_colour(' SUCCESS',Colors.green))
|
||||||
|
else
|
||||||
|
player.print('Drawing: '..key..format_chat_colour(' FAIL',Colors.red)..' '..clean_stack_trace(err))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
tests['Button no display'] = Gui.new_button('test button no display')
|
||||||
|
:on_click(function(player,element,event)
|
||||||
|
player.print('Button no display')
|
||||||
|
global.test_auth_button = not global.test_auth_button
|
||||||
|
player.print('Auth Button auth state: '..tostring(global.test_auth_button))
|
||||||
|
end)
|
||||||
|
|
||||||
|
tests['Button caption'] = Gui.new_button('test button caption')
|
||||||
|
:set_caption('Button Caption')
|
||||||
|
:on_click(function(player,element,event)
|
||||||
|
player.print('Button caption')
|
||||||
|
end)
|
||||||
|
|
||||||
|
tests['Button icon'] = Gui.new_button('test Bbutton icon')
|
||||||
|
:set_sprites('utility/warning_icon','utility/warning','utility/warning_white')
|
||||||
|
:on_click(function(player,element,event)
|
||||||
|
player.print('Button icon')
|
||||||
|
end)
|
||||||
|
|
||||||
|
tests['Button auth'] = Gui.new_button('test button auth')
|
||||||
|
:set_authenticator(function(player,button_name)
|
||||||
|
return global.test_auth_button
|
||||||
|
end)
|
||||||
|
:on_click(function(player,element,event)
|
||||||
|
player.print('Button auth')
|
||||||
|
end)
|
||||||
|
|
||||||
|
tests['Checkbox local'] = Gui.new_checkbox('test checkbox local')
|
||||||
|
:set_caption('Checkbox Local')
|
||||||
|
:on_state_change(function(player,element)
|
||||||
|
player.print('Checkbox local: '..tostring(element.state))
|
||||||
|
end)
|
||||||
|
|
||||||
|
tests['Checkbox store game'] = Gui.new_checkbox('test checkbox store game')
|
||||||
|
:set_caption('Checkbox Store Game')
|
||||||
|
:add_store()
|
||||||
|
:on_state_change(function(player,element)
|
||||||
|
player.print('Checkbox store game: '..tostring(element.state))
|
||||||
|
end)
|
||||||
|
|
||||||
|
tests['Checkbox store player'] = Gui.new_checkbox('test checkbox store player')
|
||||||
|
:set_caption('Checkbox Store Player')
|
||||||
|
:add_store(function(element)
|
||||||
|
local player = Game.get_player_by_index(element.player_index)
|
||||||
|
return player.name
|
||||||
|
end)
|
||||||
|
:on_state_change(function(player,element)
|
||||||
|
player.print('Checkbox store player: '..tostring(element.state))
|
||||||
|
end)
|
||||||
|
|
||||||
|
tests['Checkbox store force'] = Gui.new_checkbox('test checkbox store force')
|
||||||
|
:set_caption('Checkbox Store Force')
|
||||||
|
:add_store(function(element)
|
||||||
|
local player = Game.get_player_by_index(element.player_index)
|
||||||
|
return player.force.name
|
||||||
|
end)
|
||||||
|
:on_state_change(function(player,element)
|
||||||
|
player.print('Checkbox store force: '..tostring(element.state))
|
||||||
|
end)
|
||||||
@@ -1,6 +1,4 @@
|
|||||||
-- This file is used to require all the different elements of the gui module
|
-- This file is used to require all the different elements of the gui module
|
||||||
local opt_require = ext_require('expcore.common','opt_require')
|
|
||||||
|
|
||||||
local Gui = require('./gui/core')
|
local Gui = require('./gui/core')
|
||||||
|
|
||||||
local Buttons = require('./gui/buttons')
|
local Buttons = require('./gui/buttons')
|
||||||
@@ -12,13 +10,8 @@ Gui.new_toolbar_button = Toolbar.new_button
|
|||||||
Gui.add_button_to_toolbar = Toolbar.add_button
|
Gui.add_button_to_toolbar = Toolbar.add_button
|
||||||
Gui.structure.toolbar = Toolbar
|
Gui.structure.toolbar = Toolbar
|
||||||
|
|
||||||
--[[local Checkboxs = opt_require('./gui/checkboxs')
|
local Checkboxs = require('./gui/checkboxs')
|
||||||
Gui.new_checkbox = Checkboxs.new_checkbox
|
Gui.new_checkbox = Checkboxs.new_checkbox
|
||||||
Gui.new_radiobutton = Checkboxs.new_radiobutton
|
|
||||||
Gui.inputs.checkboxs = Checkboxs
|
Gui.inputs.checkboxs = Checkboxs
|
||||||
|
|
||||||
local TextEntry = opt_require('./gui/text')
|
|
||||||
Gui.new_text_entry = TextEntry.new_text_entry
|
|
||||||
Gui.inputs.text_entrys = TextEntry
|
|
||||||
]]
|
|
||||||
return Gui
|
return Gui
|
||||||
@@ -25,3 +25,8 @@ game-message-assign=__1__ has been assigned to __2__ by __3__
|
|||||||
game-message-unassign=__1__ has been unassigned from __2__ by __3__
|
game-message-unassign=__1__ has been unassigned from __2__ by __3__
|
||||||
reject-role=Invalid Role Name.
|
reject-role=Invalid Role Name.
|
||||||
reject-player-role=Player has a higher role.
|
reject-player-role=Player has a higher role.
|
||||||
|
|
||||||
|
[gui_util]
|
||||||
|
button_tooltip=Shows / hides the Toolbar Gui buttons.
|
||||||
|
|
||||||
|
[expcore-gui]
|
||||||
|
|||||||
@@ -76,8 +76,8 @@
|
|||||||
end)
|
end)
|
||||||
]]
|
]]
|
||||||
|
|
||||||
local Global = require 'util.global'
|
local Global = require 'utils.global'
|
||||||
local Event = require 'util.event'
|
local Event = require 'utils.event'
|
||||||
local write_json = ext_require('expcore.common','write_json','table_keys')
|
local write_json = ext_require('expcore.common','write_json','table_keys')
|
||||||
|
|
||||||
local Store = {
|
local Store = {
|
||||||
@@ -169,7 +169,7 @@ end
|
|||||||
-- @tparam value any the new value to set at the location, value may be reverted if there is a watch callback
|
-- @tparam value any the new value to set at the location, value may be reverted if there is a watch callback
|
||||||
-- @treturn boolean true if it was successful
|
-- @treturn boolean true if it was successful
|
||||||
function Store.set(location,value)
|
function Store.set(location,value)
|
||||||
if not Store.callbacks[location] and not no_error then
|
if not Store.callbacks[location] then
|
||||||
return error('Location is not registered', 2)
|
return error('Location is not registered', 2)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -193,7 +193,7 @@ end
|
|||||||
function Store.get_children(location)
|
function Store.get_children(location)
|
||||||
local store = Store.get(location)
|
local store = Store.get(location)
|
||||||
|
|
||||||
if type(store) ~= 'table' and table ~= nil then
|
if type(store) ~= 'table' and store ~= nil then
|
||||||
return error('Location has a non table value', 2)
|
return error('Location has a non table value', 2)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -207,11 +207,11 @@ end
|
|||||||
function Store.get_child(location,child)
|
function Store.get_child(location,child)
|
||||||
local store = Store.get(location)
|
local store = Store.get(location)
|
||||||
|
|
||||||
if type(store) ~= 'table' and table ~= nil then
|
if type(store) ~= 'table' and store ~= nil then
|
||||||
return error('Location has a non table value', 2)
|
return error('Location has a non table value', 2)
|
||||||
end
|
end
|
||||||
|
|
||||||
return store[child]
|
return store and store[child]
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Sets the value of the chlid to a location, children can be added and removed during runtime
|
--- Sets the value of the chlid to a location, children can be added and removed during runtime
|
||||||
@@ -224,7 +224,7 @@ end
|
|||||||
function Store.set_child(location,child,value)
|
function Store.set_child(location,child,value)
|
||||||
local store = Store.get(location)
|
local store = Store.get(location)
|
||||||
|
|
||||||
if type(store) ~= 'table' and table ~= nil then
|
if type(store) ~= 'table' and store ~= nil then
|
||||||
return error('Location has a non table value', 2)
|
return error('Location has a non table value', 2)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -257,14 +257,18 @@ Event.add(defines.events.on_tick,function()
|
|||||||
if not success then
|
if not success then
|
||||||
table.insert(errors,store_new)
|
table.insert(errors,store_new)
|
||||||
else
|
else
|
||||||
if store_old ~= store_new then
|
if type(store_old) ~= type(store_new)
|
||||||
|
or type(store_old) == 'table' and not table.compare(store_new,store_new)
|
||||||
|
or store_old ~= store_new then
|
||||||
Store.data[location] = store_new
|
Store.data[location] = store_new
|
||||||
Store.callbacks[location](store_new)
|
Store.callbacks[location](store_new)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
error(errors)
|
if #errors > 0 then
|
||||||
|
error(table.concat(errors,'; '))
|
||||||
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
return Store
|
return Store
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
time-symbol-days-short=__1__d
|
time-symbol-days-short=__1__d
|
||||||
color-tag=[color=__1__]__2__[/color]
|
|
||||||
|
|
||||||
[expcore-commands]
|
[expcore-commands]
|
||||||
unauthorized=Unauthorized, Access is denied due to invalid credentials
|
unauthorized=Unauthorized, Access is denied due to invalid credentials
|
||||||
@@ -26,3 +25,8 @@ game-message-assign=__1__ has been assigned to __2__ by __3__
|
|||||||
game-message-unassign=__1__ has been unassigned from __2__ by __3__
|
game-message-unassign=__1__ has been unassigned from __2__ by __3__
|
||||||
reject-role=Invalid Role Name.
|
reject-role=Invalid Role Name.
|
||||||
reject-player-role=Player has a higher role.
|
reject-player-role=Player has a higher role.
|
||||||
|
|
||||||
|
[gui_util]
|
||||||
|
button_tooltip=Shows / hides the Toolbar Gui buttons.
|
||||||
|
|
||||||
|
[expcore-gui]
|
||||||
|
|||||||
7
modules/commands/debug.lua
Normal file
7
modules/commands/debug.lua
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
local DebugView = require 'modules.gui.debug.main_view'
|
||||||
|
local Commands = require 'expcore.commands'
|
||||||
|
|
||||||
|
Commands.new_command('debug','Opens the debug pannel for viewing tables.')
|
||||||
|
:register(function(player,raw)
|
||||||
|
DebugView.open_dubug(player)
|
||||||
|
end)
|
||||||
@@ -96,5 +96,6 @@ add_interface_callback('tile',function(player) return player.surface.get_tile(pl
|
|||||||
return {
|
return {
|
||||||
add_interface_callback=add_interface_callback,
|
add_interface_callback=add_interface_callback,
|
||||||
interface_env=interface_env,
|
interface_env=interface_env,
|
||||||
interface_callbacks=interface_callbacks
|
interface_callbacks=interface_callbacks,
|
||||||
|
clean_stack_trace=function(str) return str:gsub('%.%.%..-/temp/currently%-playing','') end
|
||||||
}
|
}
|
||||||
114
modules/gui/debug/_g_view.lua
Normal file
114
modules/gui/debug/_g_view.lua
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
local Gui = require 'utils.gui'
|
||||||
|
local Model = require 'modules.gui.debug.model'
|
||||||
|
local Color = require 'resources.color_presets'
|
||||||
|
|
||||||
|
local dump = Model.dump
|
||||||
|
|
||||||
|
local Public = {}
|
||||||
|
|
||||||
|
local ignore = {
|
||||||
|
_G = true,
|
||||||
|
assert = true,
|
||||||
|
collectgarbage = true,
|
||||||
|
error = true,
|
||||||
|
getmetatable = true,
|
||||||
|
ipairs = true,
|
||||||
|
load = true,
|
||||||
|
loadstring = true,
|
||||||
|
next = true,
|
||||||
|
pairs = true,
|
||||||
|
pcall = true,
|
||||||
|
print = true,
|
||||||
|
rawequal = true,
|
||||||
|
rawlen = true,
|
||||||
|
rawget = true,
|
||||||
|
rawset = true,
|
||||||
|
select = true,
|
||||||
|
setmetatable = true,
|
||||||
|
tonumber = true,
|
||||||
|
tostring = true,
|
||||||
|
type = true,
|
||||||
|
xpcall = true,
|
||||||
|
_VERSION = true,
|
||||||
|
module = true,
|
||||||
|
require = true,
|
||||||
|
package = true,
|
||||||
|
unpack = true,
|
||||||
|
table = true,
|
||||||
|
string = true,
|
||||||
|
bit32 = true,
|
||||||
|
math = true,
|
||||||
|
debug = true,
|
||||||
|
serpent = true,
|
||||||
|
log = true,
|
||||||
|
table_size = true,
|
||||||
|
global = true,
|
||||||
|
remote = true,
|
||||||
|
commands = true,
|
||||||
|
settings = true,
|
||||||
|
rcon = true,
|
||||||
|
script = true,
|
||||||
|
util = true,
|
||||||
|
mod_gui = true,
|
||||||
|
game = true,
|
||||||
|
rendering = true
|
||||||
|
}
|
||||||
|
|
||||||
|
local header_name = Gui.uid_name()
|
||||||
|
local left_panel_name = Gui.uid_name()
|
||||||
|
local right_panel_name = Gui.uid_name()
|
||||||
|
|
||||||
|
Public.name = '_G'
|
||||||
|
|
||||||
|
function Public.show(container)
|
||||||
|
local main_flow = container.add {type = 'flow', direction = 'horizontal'}
|
||||||
|
|
||||||
|
local left_panel = main_flow.add {type = 'scroll-pane', name = left_panel_name}
|
||||||
|
local left_panel_style = left_panel.style
|
||||||
|
left_panel_style.width = 300
|
||||||
|
|
||||||
|
for key, value in pairs(_G) do
|
||||||
|
if not ignore[key] then
|
||||||
|
local header =
|
||||||
|
left_panel.add({type = 'flow'}).add {type = 'label', name = header_name, caption = tostring(key)}
|
||||||
|
Gui.set_data(header, value)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local right_panel = main_flow.add {type = 'text-box', name = right_panel_name}
|
||||||
|
right_panel.read_only = true
|
||||||
|
right_panel.selectable = true
|
||||||
|
|
||||||
|
local right_panel_style = right_panel.style
|
||||||
|
right_panel_style.vertically_stretchable = true
|
||||||
|
right_panel_style.horizontally_stretchable = true
|
||||||
|
right_panel_style.maximal_width = 1000
|
||||||
|
right_panel_style.maximal_height = 1000
|
||||||
|
|
||||||
|
Gui.set_data(left_panel, {right_panel = right_panel, selected_header = nil})
|
||||||
|
end
|
||||||
|
|
||||||
|
Gui.on_click(
|
||||||
|
header_name,
|
||||||
|
function(event)
|
||||||
|
local element = event.element
|
||||||
|
local value = Gui.get_data(element)
|
||||||
|
|
||||||
|
local left_panel = element.parent.parent
|
||||||
|
local left_panel_data = Gui.get_data(left_panel)
|
||||||
|
local right_panel = left_panel_data.right_panel
|
||||||
|
local selected_header = left_panel_data.selected_header
|
||||||
|
|
||||||
|
if selected_header then
|
||||||
|
selected_header.style.font_color = Color.white
|
||||||
|
end
|
||||||
|
|
||||||
|
element.style.font_color = Color.orange
|
||||||
|
left_panel_data.selected_header = element
|
||||||
|
|
||||||
|
local content = dump(value)
|
||||||
|
right_panel.text = content
|
||||||
|
end
|
||||||
|
)
|
||||||
|
|
||||||
|
return Public
|
||||||
117
modules/gui/debug/event_view.lua
Normal file
117
modules/gui/debug/event_view.lua
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
local Event = require 'utils.event'
|
||||||
|
local table = require 'utils.table'
|
||||||
|
local Gui = require 'utils.gui'
|
||||||
|
local Model = require 'modules.gui.debug.model'
|
||||||
|
|
||||||
|
local format = string.format
|
||||||
|
local insert = table.insert
|
||||||
|
|
||||||
|
local events = defines.events
|
||||||
|
|
||||||
|
-- Constants
|
||||||
|
local events_to_keep = 10
|
||||||
|
|
||||||
|
-- Local vars
|
||||||
|
local Public = {
|
||||||
|
name = 'Events'
|
||||||
|
}
|
||||||
|
local name_lookup = {}
|
||||||
|
|
||||||
|
-- GUI names
|
||||||
|
local checkbox_name = Gui.uid_name()
|
||||||
|
|
||||||
|
-- global tables
|
||||||
|
local enabled = {}
|
||||||
|
local last_events = {}
|
||||||
|
global.debug_event_view = {
|
||||||
|
enabled = enabled,
|
||||||
|
last_events = last_events
|
||||||
|
}
|
||||||
|
|
||||||
|
function Public.on_open_debug()
|
||||||
|
local tbl = global.debug_event_view
|
||||||
|
if tbl then
|
||||||
|
enabled = tbl.enabled
|
||||||
|
last_events = tbl.last_events
|
||||||
|
else
|
||||||
|
enabled = {}
|
||||||
|
last_events = {}
|
||||||
|
|
||||||
|
global.debug_event_view = {
|
||||||
|
enabled = enabled,
|
||||||
|
last_events = last_events
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
Public.on_open_debug = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Local functions
|
||||||
|
local function event_callback(event)
|
||||||
|
local id = event.name
|
||||||
|
if not enabled[id] then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local name = name_lookup[id]
|
||||||
|
|
||||||
|
if not last_events[name] then
|
||||||
|
last_events[name] = {}
|
||||||
|
end
|
||||||
|
|
||||||
|
insert(last_events[name], 1, event)
|
||||||
|
last_events[name][events_to_keep + 1] = nil
|
||||||
|
event.name = nil
|
||||||
|
|
||||||
|
local str = format('%s (id = %s): %s', name, id, Model.dump(event))
|
||||||
|
game.print(str)
|
||||||
|
log(str)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function on_gui_checked_state_changed(event)
|
||||||
|
local element = event.element
|
||||||
|
local name = element.caption
|
||||||
|
local id = events[name]
|
||||||
|
local state = element.state and true or false
|
||||||
|
element.state = state
|
||||||
|
if state then
|
||||||
|
enabled[id] = true
|
||||||
|
else
|
||||||
|
enabled[id] = false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- GUI
|
||||||
|
|
||||||
|
-- Create a table with events sorted by their names
|
||||||
|
local grid_builder = {}
|
||||||
|
for name, _ in pairs(events) do
|
||||||
|
grid_builder[#grid_builder + 1] = name
|
||||||
|
end
|
||||||
|
|
||||||
|
table.sort(grid_builder)
|
||||||
|
|
||||||
|
function Public.show(container)
|
||||||
|
local main_frame_flow = container.add({type = 'flow', direction = 'vertical'})
|
||||||
|
local scroll_pane = main_frame_flow.add({type = 'scroll-pane'})
|
||||||
|
local gui_table = scroll_pane.add({type = 'table', column_count = 3, draw_horizontal_lines = true})
|
||||||
|
|
||||||
|
for _, event_name in pairs(grid_builder) do
|
||||||
|
local index = events[event_name]
|
||||||
|
gui_table.add({type = 'flow'}).add {
|
||||||
|
name = checkbox_name,
|
||||||
|
type = 'checkbox',
|
||||||
|
state = enabled[index] or false,
|
||||||
|
caption = event_name
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Gui.on_checked_state_changed(checkbox_name, on_gui_checked_state_changed)
|
||||||
|
|
||||||
|
-- Event registers (TODO: turn to removable hooks.. maybe)
|
||||||
|
for name, id in pairs(events) do
|
||||||
|
name_lookup[id] = name
|
||||||
|
Event.add(id, event_callback)
|
||||||
|
end
|
||||||
|
|
||||||
|
return Public
|
||||||
133
modules/gui/debug/global_view.lua
Normal file
133
modules/gui/debug/global_view.lua
Normal file
@@ -0,0 +1,133 @@
|
|||||||
|
local Gui = require 'utils.gui'
|
||||||
|
local Model = require 'modules.gui.debug.model'
|
||||||
|
local Color = require 'resources.color_presets'
|
||||||
|
|
||||||
|
local dump = Model.dump
|
||||||
|
local dump_text = Model.dump_text
|
||||||
|
local concat = table.concat
|
||||||
|
|
||||||
|
local Public = {}
|
||||||
|
|
||||||
|
local ignore = {tokens = true}
|
||||||
|
|
||||||
|
local header_name = Gui.uid_name()
|
||||||
|
local left_panel_name = Gui.uid_name()
|
||||||
|
local right_panel_name = Gui.uid_name()
|
||||||
|
local input_text_box_name = Gui.uid_name()
|
||||||
|
local refresh_name = Gui.uid_name()
|
||||||
|
|
||||||
|
Public.name = 'global'
|
||||||
|
|
||||||
|
function Public.show(container)
|
||||||
|
local main_flow = container.add {type = 'flow', direction = 'horizontal'}
|
||||||
|
|
||||||
|
local left_panel = main_flow.add {type = 'scroll-pane', name = left_panel_name}
|
||||||
|
local left_panel_style = left_panel.style
|
||||||
|
left_panel_style.width = 300
|
||||||
|
|
||||||
|
for key, _ in pairs(global) do
|
||||||
|
if not ignore[key] then
|
||||||
|
local header =
|
||||||
|
left_panel.add({type = 'flow'}).add {type = 'label', name = header_name, caption = tostring(key)}
|
||||||
|
Gui.set_data(header, key)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local right_flow = main_flow.add {type = 'flow', direction = 'vertical'}
|
||||||
|
|
||||||
|
local right_top_flow = right_flow.add {type = 'flow', direction = 'horizontal'}
|
||||||
|
|
||||||
|
local input_text_box = right_top_flow.add {type = 'text-box', name = input_text_box_name}
|
||||||
|
local input_text_box_style = input_text_box.style
|
||||||
|
input_text_box_style.horizontally_stretchable = true
|
||||||
|
input_text_box_style.height = 32
|
||||||
|
input_text_box_style.maximal_width = 1000
|
||||||
|
|
||||||
|
local refresh_button =
|
||||||
|
right_top_flow.add {type = 'sprite-button', name = refresh_name, sprite = 'utility/reset', tooltip = 'refresh'}
|
||||||
|
local refresh_button_style = refresh_button.style
|
||||||
|
refresh_button_style.width = 32
|
||||||
|
refresh_button_style.height = 32
|
||||||
|
|
||||||
|
local right_panel = right_flow.add {type = 'text-box', name = right_panel_name}
|
||||||
|
right_panel.read_only = true
|
||||||
|
right_panel.selectable = true
|
||||||
|
|
||||||
|
local right_panel_style = right_panel.style
|
||||||
|
right_panel_style.vertically_stretchable = true
|
||||||
|
right_panel_style.horizontally_stretchable = true
|
||||||
|
right_panel_style.maximal_width = 1000
|
||||||
|
right_panel_style.maximal_height = 1000
|
||||||
|
|
||||||
|
local data = {
|
||||||
|
right_panel = right_panel,
|
||||||
|
input_text_box = input_text_box,
|
||||||
|
selected_header = nil,
|
||||||
|
selected_token_id = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
Gui.set_data(input_text_box, data)
|
||||||
|
Gui.set_data(left_panel, data)
|
||||||
|
Gui.set_data(refresh_button, data)
|
||||||
|
end
|
||||||
|
|
||||||
|
Gui.on_click(
|
||||||
|
header_name,
|
||||||
|
function(event)
|
||||||
|
local element = event.element
|
||||||
|
local key = Gui.get_data(element)
|
||||||
|
|
||||||
|
local left_panel = element.parent.parent
|
||||||
|
local data = Gui.get_data(left_panel)
|
||||||
|
local right_panel = data.right_panel
|
||||||
|
local selected_header = data.selected_header
|
||||||
|
local input_text_box = data.input_text_box
|
||||||
|
|
||||||
|
if selected_header then
|
||||||
|
selected_header.style.font_color = Color.white
|
||||||
|
end
|
||||||
|
|
||||||
|
element.style.font_color = Color.orange
|
||||||
|
data.selected_header = element
|
||||||
|
|
||||||
|
input_text_box.text = concat {"global['", key, "']"}
|
||||||
|
input_text_box.style.font_color = Color.black
|
||||||
|
|
||||||
|
local content = dump(global[key]) or 'nil'
|
||||||
|
right_panel.text = content
|
||||||
|
end
|
||||||
|
)
|
||||||
|
|
||||||
|
local function update_dump(text_input, data, player)
|
||||||
|
local suc, ouput = dump_text(text_input.text, player)
|
||||||
|
if not suc then
|
||||||
|
text_input.style.font_color = Color.red
|
||||||
|
else
|
||||||
|
text_input.style.font_color = Color.black
|
||||||
|
data.right_panel.text = ouput
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Gui.on_text_changed(
|
||||||
|
input_text_box_name,
|
||||||
|
function(event)
|
||||||
|
local element = event.element
|
||||||
|
local data = Gui.get_data(element)
|
||||||
|
|
||||||
|
update_dump(element, data, event.player)
|
||||||
|
end
|
||||||
|
)
|
||||||
|
|
||||||
|
Gui.on_click(
|
||||||
|
refresh_name,
|
||||||
|
function(event)
|
||||||
|
local element = event.element
|
||||||
|
local data = Gui.get_data(element)
|
||||||
|
|
||||||
|
local input_text_box = data.input_text_box
|
||||||
|
|
||||||
|
update_dump(input_text_box, data, event.player)
|
||||||
|
end
|
||||||
|
)
|
||||||
|
|
||||||
|
return Public
|
||||||
103
modules/gui/debug/main_view.lua
Normal file
103
modules/gui/debug/main_view.lua
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
local Gui = require 'utils.gui'
|
||||||
|
local Color = require 'resources.color_presets'
|
||||||
|
|
||||||
|
local Public = {}
|
||||||
|
|
||||||
|
local pages = {
|
||||||
|
require 'modules.gui.debug.redmew_global_view',
|
||||||
|
require 'modules.gui.debug.global_view',
|
||||||
|
require 'modules.gui.debug.package_view',
|
||||||
|
require 'modules.gui.debug._g_view',
|
||||||
|
require 'modules.gui.debug.event_view'
|
||||||
|
}
|
||||||
|
|
||||||
|
local main_frame_name = Gui.uid_name()
|
||||||
|
local close_name = Gui.uid_name()
|
||||||
|
local tab_name = Gui.uid_name()
|
||||||
|
|
||||||
|
function Public.open_dubug(player)
|
||||||
|
for i = 1, #pages do
|
||||||
|
local page = pages[i]
|
||||||
|
local callback = page.on_open_debug
|
||||||
|
if callback then
|
||||||
|
callback()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local center = player.gui.center
|
||||||
|
local frame = center[main_frame_name]
|
||||||
|
if frame then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
frame = center.add {type = 'frame', name = main_frame_name, caption = 'Debuggertron 3001', direction = 'vertical'}
|
||||||
|
local frame_style = frame.style
|
||||||
|
frame_style.height = 600
|
||||||
|
frame_style.width = 900
|
||||||
|
|
||||||
|
local tab_flow = frame.add {type = 'flow', direction = 'horizontal'}
|
||||||
|
local container = frame.add {type = 'flow'}
|
||||||
|
container.style.vertically_stretchable = true
|
||||||
|
|
||||||
|
local data = {}
|
||||||
|
|
||||||
|
for i = 1, #pages do
|
||||||
|
local page = pages[i]
|
||||||
|
local tab_button = tab_flow.add({type = 'flow'}).add {type = 'button', name = tab_name, caption = page.name}
|
||||||
|
local tab_button_style = tab_button.style
|
||||||
|
|
||||||
|
Gui.set_data(tab_button, {index = i, frame_data = data})
|
||||||
|
|
||||||
|
if i == 1 then
|
||||||
|
tab_button_style.font_color = Color.orange
|
||||||
|
|
||||||
|
data.selected_index = i
|
||||||
|
data.selected_tab_button = tab_button
|
||||||
|
data.container = container
|
||||||
|
|
||||||
|
Gui.set_data(frame, data)
|
||||||
|
page.show(container)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
frame.add {type = 'button', name = close_name, caption = 'Close'}
|
||||||
|
end
|
||||||
|
|
||||||
|
Gui.on_click(
|
||||||
|
tab_name,
|
||||||
|
function(event)
|
||||||
|
local element = event.element
|
||||||
|
local data = Gui.get_data(element)
|
||||||
|
|
||||||
|
local index = data.index
|
||||||
|
local frame_data = data.frame_data
|
||||||
|
local selected_index = frame_data.selected_index
|
||||||
|
|
||||||
|
if selected_index == index then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local selected_tab_button = frame_data.selected_tab_button
|
||||||
|
selected_tab_button.style.font_color = Color.black
|
||||||
|
|
||||||
|
frame_data.selected_tab_button = element
|
||||||
|
frame_data.selected_index = index
|
||||||
|
element.style.font_color = Color.orange
|
||||||
|
|
||||||
|
local container = frame_data.container
|
||||||
|
Gui.clear(container)
|
||||||
|
pages[index].show(container)
|
||||||
|
end
|
||||||
|
)
|
||||||
|
|
||||||
|
Gui.on_click(
|
||||||
|
close_name,
|
||||||
|
function(event)
|
||||||
|
local frame = event.player.gui.center[main_frame_name]
|
||||||
|
if frame then
|
||||||
|
Gui.destroy(frame)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
)
|
||||||
|
|
||||||
|
return Public
|
||||||
147
modules/gui/debug/model.lua
Normal file
147
modules/gui/debug/model.lua
Normal file
@@ -0,0 +1,147 @@
|
|||||||
|
local Gui = require 'utils.gui'
|
||||||
|
local table = require 'utils.table'
|
||||||
|
|
||||||
|
local gui_names = Gui.names
|
||||||
|
local type = type
|
||||||
|
local concat = table.concat
|
||||||
|
local inspect = table.inspect
|
||||||
|
local pcall = pcall
|
||||||
|
local loadstring = loadstring
|
||||||
|
local rawset = rawset
|
||||||
|
|
||||||
|
local Public = {}
|
||||||
|
|
||||||
|
local luaObject = {'{', nil, ", name = '", nil, "'}"}
|
||||||
|
local luaPlayer = {"{LuaPlayer, name = '", nil, "', index = ", nil, '}'}
|
||||||
|
local luaEntity = {"{LuaEntity, name = '", nil, "', unit_number = ", nil, '}'}
|
||||||
|
local luaGuiElement = {"{LuaGuiElement, name = '", nil, "'}"}
|
||||||
|
|
||||||
|
local function get(obj, prop)
|
||||||
|
return obj[prop]
|
||||||
|
end
|
||||||
|
|
||||||
|
local function get_name_safe(obj)
|
||||||
|
local s, r = pcall(get, obj, 'name')
|
||||||
|
if not s then
|
||||||
|
return 'nil'
|
||||||
|
else
|
||||||
|
return r or 'nil'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function get_lua_object_type_safe(obj)
|
||||||
|
local s, r = pcall(get, obj, 'help')
|
||||||
|
|
||||||
|
if not s then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
return r():match('Lua%a+')
|
||||||
|
end
|
||||||
|
|
||||||
|
local function inspect_process(item)
|
||||||
|
if type(item) ~= 'table' or type(item.__self) ~= 'userdata' then
|
||||||
|
return item
|
||||||
|
end
|
||||||
|
|
||||||
|
local suc, valid = pcall(get, item, 'valid')
|
||||||
|
if not suc then
|
||||||
|
-- no 'valid' property
|
||||||
|
return get_lua_object_type_safe(item) or '{NoHelp LuaObject}'
|
||||||
|
end
|
||||||
|
|
||||||
|
if not valid then
|
||||||
|
return '{Invalid LuaObject}'
|
||||||
|
end
|
||||||
|
|
||||||
|
local obj_type = get_lua_object_type_safe(item)
|
||||||
|
if not obj_type then
|
||||||
|
return '{NoHelp LuaObject}'
|
||||||
|
end
|
||||||
|
|
||||||
|
if obj_type == 'LuaPlayer' then
|
||||||
|
luaPlayer[2] = item.name or 'nil'
|
||||||
|
luaPlayer[4] = item.index or 'nil'
|
||||||
|
|
||||||
|
return concat(luaPlayer)
|
||||||
|
elseif obj_type == 'LuaEntity' then
|
||||||
|
luaEntity[2] = item.name or 'nil'
|
||||||
|
luaEntity[4] = item.unit_number or 'nil'
|
||||||
|
|
||||||
|
return concat(luaEntity)
|
||||||
|
elseif obj_type == 'LuaGuiElement' then
|
||||||
|
local name = item.name
|
||||||
|
luaGuiElement[2] = gui_names and gui_names[name] or name or 'nil'
|
||||||
|
|
||||||
|
return concat(luaGuiElement)
|
||||||
|
else
|
||||||
|
luaObject[2] = obj_type
|
||||||
|
luaObject[4] = get_name_safe(item)
|
||||||
|
|
||||||
|
return concat(luaObject)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local inspect_options = {process = inspect_process}
|
||||||
|
function Public.dump(data)
|
||||||
|
return inspect(data, inspect_options)
|
||||||
|
end
|
||||||
|
local dump = Public.dump
|
||||||
|
|
||||||
|
function Public.dump_ignore_builder(ignore)
|
||||||
|
local function process(item)
|
||||||
|
if ignore[item] then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
return inspect_process(item)
|
||||||
|
end
|
||||||
|
|
||||||
|
local options = {process = process}
|
||||||
|
return function(data)
|
||||||
|
return inspect(data, options)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function Public.dump_function(func)
|
||||||
|
local res = {'upvalues:\n'}
|
||||||
|
|
||||||
|
local i = 1
|
||||||
|
while true do
|
||||||
|
local n, v = debug.getupvalue(func, i)
|
||||||
|
|
||||||
|
if n == nil then
|
||||||
|
break
|
||||||
|
elseif n ~= '_ENV' then
|
||||||
|
res[#res + 1] = n
|
||||||
|
res[#res + 1] = ' = '
|
||||||
|
res[#res + 1] = dump(v)
|
||||||
|
res[#res + 1] = '\n'
|
||||||
|
end
|
||||||
|
|
||||||
|
i = i + 1
|
||||||
|
end
|
||||||
|
|
||||||
|
return concat(res)
|
||||||
|
end
|
||||||
|
|
||||||
|
function Public.dump_text(text, player)
|
||||||
|
local func = loadstring('return ' .. text)
|
||||||
|
if not func then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
rawset(game, 'player', player)
|
||||||
|
|
||||||
|
local suc, var = pcall(func)
|
||||||
|
|
||||||
|
rawset(game, 'player', nil)
|
||||||
|
|
||||||
|
if not suc then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
return true, dump(var)
|
||||||
|
end
|
||||||
|
|
||||||
|
return Public
|
||||||
161
modules/gui/debug/package_view.lua
Normal file
161
modules/gui/debug/package_view.lua
Normal file
@@ -0,0 +1,161 @@
|
|||||||
|
local Gui = require 'utils.gui'
|
||||||
|
local Color = require 'resources.color_presets'
|
||||||
|
local Model = require 'modules.gui.debug.model'
|
||||||
|
|
||||||
|
local dump_function = Model.dump_function
|
||||||
|
local loaded = _G.package.loaded
|
||||||
|
|
||||||
|
local Public = {}
|
||||||
|
|
||||||
|
local ignore = {
|
||||||
|
_G = true,
|
||||||
|
package = true,
|
||||||
|
coroutine = true,
|
||||||
|
table = true,
|
||||||
|
string = true,
|
||||||
|
bit32 = true,
|
||||||
|
math = true,
|
||||||
|
debug = true,
|
||||||
|
serpent = true,
|
||||||
|
['utils.math'] = true,
|
||||||
|
util = true,
|
||||||
|
['utils.inspect'] = true,
|
||||||
|
['mod-gui'] = true
|
||||||
|
}
|
||||||
|
|
||||||
|
local file_label_name = Gui.uid_name()
|
||||||
|
local left_panel_name = Gui.uid_name()
|
||||||
|
local breadcrumbs_name = Gui.uid_name()
|
||||||
|
local top_panel_name = Gui.uid_name()
|
||||||
|
local variable_label_name = Gui.uid_name()
|
||||||
|
local text_box_name = Gui.uid_name()
|
||||||
|
|
||||||
|
Public.name = 'package'
|
||||||
|
|
||||||
|
function Public.show(container)
|
||||||
|
local main_flow = container.add {type = 'flow', direction = 'horizontal'}
|
||||||
|
|
||||||
|
local left_panel = main_flow.add {type = 'scroll-pane', name = left_panel_name}
|
||||||
|
local left_panel_style = left_panel.style
|
||||||
|
left_panel_style.width = 300
|
||||||
|
|
||||||
|
for name, file in pairs(loaded) do
|
||||||
|
if not ignore[name] then
|
||||||
|
local file_label =
|
||||||
|
left_panel.add({type = 'flow'}).add {type = 'label', name = file_label_name, caption = name}
|
||||||
|
Gui.set_data(file_label, file)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local right_flow = main_flow.add {type = 'flow', direction = 'vertical'}
|
||||||
|
|
||||||
|
local breadcrumbs = right_flow.add {type = 'label', name = breadcrumbs_name}
|
||||||
|
|
||||||
|
local top_panel = right_flow.add {type = 'scroll-pane', name = top_panel_name}
|
||||||
|
local top_panel_style = top_panel.style
|
||||||
|
top_panel_style.height = 200
|
||||||
|
top_panel_style.maximal_width = 1000
|
||||||
|
top_panel_style.horizontally_stretchable = true
|
||||||
|
|
||||||
|
local text_box = right_flow.add {type = 'text-box', name = text_box_name}
|
||||||
|
text_box.read_only = true
|
||||||
|
text_box.selectable = true
|
||||||
|
|
||||||
|
local text_box_style = text_box.style
|
||||||
|
text_box_style.vertically_stretchable = true
|
||||||
|
text_box_style.horizontally_stretchable = true
|
||||||
|
text_box_style.maximal_width = 1000
|
||||||
|
text_box_style.maximal_height = 1000
|
||||||
|
|
||||||
|
local data = {
|
||||||
|
left_panel = left_panel,
|
||||||
|
breadcrumbs = breadcrumbs,
|
||||||
|
top_panel = top_panel,
|
||||||
|
text_box = text_box,
|
||||||
|
selected_file_label = nil,
|
||||||
|
selected_variable_label = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
Gui.set_data(left_panel, data)
|
||||||
|
Gui.set_data(top_panel, data)
|
||||||
|
end
|
||||||
|
|
||||||
|
Gui.on_click(
|
||||||
|
file_label_name,
|
||||||
|
function(event)
|
||||||
|
local element = event.element
|
||||||
|
local file = Gui.get_data(element)
|
||||||
|
|
||||||
|
local left_panel = element.parent.parent
|
||||||
|
local data = Gui.get_data(left_panel)
|
||||||
|
|
||||||
|
local selected_file_label = data.selected_file_label
|
||||||
|
|
||||||
|
if selected_file_label then
|
||||||
|
selected_file_label.style.font_color = Color.white
|
||||||
|
end
|
||||||
|
|
||||||
|
element.style.font_color = Color.orange
|
||||||
|
data.selected_file_label = element
|
||||||
|
|
||||||
|
local top_panel = data.top_panel
|
||||||
|
local text_box = data.text_box
|
||||||
|
|
||||||
|
Gui.clear(top_panel)
|
||||||
|
|
||||||
|
local file_type = type(file)
|
||||||
|
|
||||||
|
if file_type == 'table' then
|
||||||
|
for k, v in pairs(file) do
|
||||||
|
local label =
|
||||||
|
top_panel.add({type = 'flow'}).add {type = 'label', name = variable_label_name, caption = k}
|
||||||
|
Gui.set_data(label, v)
|
||||||
|
end
|
||||||
|
elseif file_type == 'function' then
|
||||||
|
text_box.text = dump_function(file)
|
||||||
|
else
|
||||||
|
text_box.text = tostring(file)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
)
|
||||||
|
|
||||||
|
Gui.on_click(
|
||||||
|
variable_label_name,
|
||||||
|
function(event)
|
||||||
|
local element = event.element
|
||||||
|
local variable = Gui.get_data(element)
|
||||||
|
|
||||||
|
local top_panel = element.parent.parent
|
||||||
|
local data = Gui.get_data(top_panel)
|
||||||
|
local text_box = data.text_box
|
||||||
|
|
||||||
|
local variable_type = type(variable)
|
||||||
|
|
||||||
|
if variable_type == 'table' then
|
||||||
|
Gui.clear(top_panel)
|
||||||
|
for k, v in pairs(variable) do
|
||||||
|
local label =
|
||||||
|
top_panel.add({type = 'flow'}).add {type = 'label', name = variable_label_name, caption = k}
|
||||||
|
Gui.set_data(label, v)
|
||||||
|
end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local selected_label = data.selected_variable_label
|
||||||
|
|
||||||
|
if selected_label and selected_label.valid then
|
||||||
|
selected_label.style.font_color = Color.white
|
||||||
|
end
|
||||||
|
|
||||||
|
element.style.font_color = Color.orange
|
||||||
|
data.selected_variable_label = element
|
||||||
|
|
||||||
|
if variable_type == 'function' then
|
||||||
|
text_box.text = dump_function(variable)
|
||||||
|
else
|
||||||
|
text_box.text = tostring(variable)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
)
|
||||||
|
|
||||||
|
return Public
|
||||||
129
modules/gui/debug/redmew_global_view.lua
Normal file
129
modules/gui/debug/redmew_global_view.lua
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
local Gui = require 'utils.gui'
|
||||||
|
local Global = require 'utils.global'
|
||||||
|
local Token = require 'utils.token'
|
||||||
|
local Color = require 'resources.color_presets'
|
||||||
|
local Model = require 'modules.gui.debug.model'
|
||||||
|
|
||||||
|
local dump = Model.dump
|
||||||
|
local dump_text = Model.dump_text
|
||||||
|
local concat = table.concat
|
||||||
|
|
||||||
|
local Public = {}
|
||||||
|
|
||||||
|
local header_name = Gui.uid_name()
|
||||||
|
local left_panel_name = Gui.uid_name()
|
||||||
|
local right_panel_name = Gui.uid_name()
|
||||||
|
local input_text_box_name = Gui.uid_name()
|
||||||
|
local refresh_name = Gui.uid_name()
|
||||||
|
|
||||||
|
Public.name = 'Global'
|
||||||
|
|
||||||
|
function Public.show(container)
|
||||||
|
local main_flow = container.add {type = 'flow', direction = 'horizontal'}
|
||||||
|
|
||||||
|
local left_panel = main_flow.add {type = 'scroll-pane', name = left_panel_name}
|
||||||
|
local left_panel_style = left_panel.style
|
||||||
|
left_panel_style.width = 300
|
||||||
|
|
||||||
|
for token_id, token_name in pairs(Global.names) do
|
||||||
|
local header = left_panel.add({type = 'flow'}).add {type = 'label', name = header_name, caption = token_name}
|
||||||
|
Gui.set_data(header, token_id)
|
||||||
|
end
|
||||||
|
|
||||||
|
local right_flow = main_flow.add {type = 'flow', direction = 'vertical'}
|
||||||
|
|
||||||
|
local right_top_flow = right_flow.add {type = 'flow', direction = 'horizontal'}
|
||||||
|
|
||||||
|
local input_text_box = right_top_flow.add {type = 'text-box', name = input_text_box_name}
|
||||||
|
local input_text_box_style = input_text_box.style
|
||||||
|
input_text_box_style.horizontally_stretchable = true
|
||||||
|
input_text_box_style.height = 32
|
||||||
|
input_text_box_style.maximal_width = 1000
|
||||||
|
|
||||||
|
local refresh_button =
|
||||||
|
right_top_flow.add {type = 'sprite-button', name = refresh_name, sprite = 'utility/reset', tooltip = 'refresh'}
|
||||||
|
local refresh_button_style = refresh_button.style
|
||||||
|
refresh_button_style.width = 32
|
||||||
|
refresh_button_style.height = 32
|
||||||
|
|
||||||
|
local right_panel = right_flow.add {type = 'text-box', name = right_panel_name}
|
||||||
|
right_panel.read_only = true
|
||||||
|
right_panel.selectable = true
|
||||||
|
|
||||||
|
local right_panel_style = right_panel.style
|
||||||
|
right_panel_style.vertically_stretchable = true
|
||||||
|
right_panel_style.horizontally_stretchable = true
|
||||||
|
right_panel_style.maximal_width = 1000
|
||||||
|
right_panel_style.maximal_height = 1000
|
||||||
|
|
||||||
|
local data = {
|
||||||
|
right_panel = right_panel,
|
||||||
|
input_text_box = input_text_box,
|
||||||
|
selected_header = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
Gui.set_data(input_text_box, data)
|
||||||
|
Gui.set_data(left_panel, data)
|
||||||
|
Gui.set_data(refresh_button, data)
|
||||||
|
end
|
||||||
|
|
||||||
|
Gui.on_click(
|
||||||
|
header_name,
|
||||||
|
function(event)
|
||||||
|
local element = event.element
|
||||||
|
local token_id = Gui.get_data(element)
|
||||||
|
|
||||||
|
local left_panel = element.parent.parent
|
||||||
|
local data = Gui.get_data(left_panel)
|
||||||
|
local right_panel = data.right_panel
|
||||||
|
local selected_header = data.selected_header
|
||||||
|
local input_text_box = data.input_text_box
|
||||||
|
|
||||||
|
if selected_header then
|
||||||
|
selected_header.style.font_color = Color.white
|
||||||
|
end
|
||||||
|
|
||||||
|
element.style.font_color = Color.orange
|
||||||
|
data.selected_header = element
|
||||||
|
|
||||||
|
input_text_box.text = concat {'global.tokens[', token_id, ']'}
|
||||||
|
input_text_box.style.font_color = Color.black
|
||||||
|
|
||||||
|
local content = dump(Token.get_global(token_id)) or 'nil'
|
||||||
|
right_panel.text = content
|
||||||
|
end
|
||||||
|
)
|
||||||
|
|
||||||
|
local function update_dump(text_input, data, player)
|
||||||
|
local suc, ouput = dump_text(text_input.text, player)
|
||||||
|
if not suc then
|
||||||
|
text_input.style.font_color = Color.red
|
||||||
|
else
|
||||||
|
text_input.style.font_color = Color.black
|
||||||
|
data.right_panel.text = ouput
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Gui.on_text_changed(
|
||||||
|
input_text_box_name,
|
||||||
|
function(event)
|
||||||
|
local element = event.element
|
||||||
|
local data = Gui.get_data(element)
|
||||||
|
|
||||||
|
update_dump(element, data, event.player)
|
||||||
|
end
|
||||||
|
)
|
||||||
|
|
||||||
|
Gui.on_click(
|
||||||
|
refresh_name,
|
||||||
|
function(event)
|
||||||
|
local element = event.element
|
||||||
|
local data = Gui.get_data(element)
|
||||||
|
|
||||||
|
local input_text_box = data.input_text_box
|
||||||
|
|
||||||
|
update_dump(input_text_box, data, event.player)
|
||||||
|
end
|
||||||
|
)
|
||||||
|
|
||||||
|
return Public
|
||||||
@@ -3,13 +3,11 @@
|
|||||||
-- Dependencies
|
-- Dependencies
|
||||||
local Game = require 'utils.game'
|
local Game = require 'utils.game'
|
||||||
local Color = require 'resources.color_presets'
|
local Color = require 'resources.color_presets'
|
||||||
local Server = require 'features.server'
|
|
||||||
|
|
||||||
-- localized functions
|
-- localized functions
|
||||||
local random = math.random
|
local random = math.random
|
||||||
local sqrt = math.sqrt
|
local sqrt = math.sqrt
|
||||||
local floor = math.floor
|
local floor = math.floor
|
||||||
local format = string.format
|
|
||||||
local match = string.match
|
local match = string.match
|
||||||
local insert = table.insert
|
local insert = table.insert
|
||||||
local concat = table.concat
|
local concat = table.concat
|
||||||
@@ -201,27 +199,6 @@ function Module.set_and_return(tbl, key, value)
|
|||||||
return value
|
return value
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Takes msg and prints it to all players. Also prints to the log and discord
|
|
||||||
-- @param msg <string> The message to print
|
|
||||||
-- @param warning_prefix <string> The name of the module/warning
|
|
||||||
function Module.action_warning(warning_prefix, msg)
|
|
||||||
game.print(prefix .. msg, Color.yellow)
|
|
||||||
msg = format('%s %s', warning_prefix, msg)
|
|
||||||
log(msg)
|
|
||||||
Server.to_discord_bold(msg)
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Takes msg and prints it to all players except provided player. Also prints to the log and discord
|
|
||||||
-- @param msg <string> The message to print
|
|
||||||
-- @param warning_prefix <string> The name of the module/warning
|
|
||||||
-- @param player <LuaPlayer> the player not to send the message to
|
|
||||||
function Module.silent_action_warning(warning_prefix, msg, player)
|
|
||||||
Module.print_except(prefix .. msg, player, Color.yellow)
|
|
||||||
msg = format('%s %s', warning_prefix, msg)
|
|
||||||
log(msg)
|
|
||||||
Server.to_discord_bold(msg)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- add utility functions that exist in base factorio/util
|
-- add utility functions that exist in base factorio/util
|
||||||
require 'util'
|
require 'util'
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ function Global.register_init(tbl, init_handler, callback)
|
|||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
if _DEBUG then
|
if _DEBUG or true then
|
||||||
local concat = table.concat
|
local concat = table.concat
|
||||||
|
|
||||||
local names = {}
|
local names = {}
|
||||||
|
|||||||
Reference in New Issue
Block a user