Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add admin panel #1432

Merged
merged 14 commits into from
Sep 2, 2024
1 change: 1 addition & 0 deletions .luacheckrc
Original file line number Diff line number Diff line change
Expand Up @@ -1052,6 +1052,7 @@ stds.factorio_defines = {
'on_gui_elem_changed',
'on_gui_opened',
'on_gui_selection_state_changed',
'on_gui_switch_state_changed',
'on_gui_text_changed',
'on_gui_value_changed',
'on_land_mine_armed',
Expand Down
3 changes: 3 additions & 0 deletions config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,9 @@ global.config = {
clear_corpses = true,
battery_charge = true,
}
},
admin_panel = {
enabled = true,
}
}

Expand Down
5 changes: 5 additions & 0 deletions control.lua
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,11 @@ if config.map_info.enabled then
require 'features.gui.info'
require 'features.gui.description_generator'
end
if config.admin_panel.enabled then
require 'features.gui.admin_panel.player_manager'
require 'features.gui.admin_panel.map_manager'
require 'features.gui.admin_panel.lua_console'
end
if config.player_list.enabled then
require 'features.gui.player_list'
end
Expand Down
24 changes: 20 additions & 4 deletions features/admin_commands.lua
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ end
local function add_regular(args)
local target_name = args.player
local maybe_target_player = game.get_player(target_name)
local actor = Utils.get_actor()
local actor = args.actor or Utils.get_actor()

if not maybe_target_player and not know_player_or_rerun(target_name, actor, 'regular') then
return
Expand All @@ -90,7 +90,7 @@ end
local function remove_regular(args)
local target_name = args.player
local maybe_target_player = game.get_player(target_name)
local actor = Utils.get_actor()
local actor = args.actor or Utils.get_actor()

if not maybe_target_player and not know_player_or_rerun(target_name, actor, 'regular-remove') then
return
Expand All @@ -112,7 +112,7 @@ end
local function probation_add(args)
local target_name = args.player
local maybe_target_player = game.get_player(target_name)
local actor = Utils.get_actor()
local actor = args.actor or Utils.get_actor()

if not maybe_target_player and not know_player_or_rerun(target_name, actor, 'probation') then
return
Expand Down Expand Up @@ -141,7 +141,7 @@ end
local function probation_remove(args)
local target_name = args.player
local maybe_target_player = game.get_player(target_name)
local actor = Utils.get_actor()
local actor = args.actor or Utils.get_actor()

if not maybe_target_player and not know_player_or_rerun(target_name, actor, 'probation-remove') then
return
Expand Down Expand Up @@ -472,3 +472,19 @@ Command.add(
},
destroy_selected
)

return {
create_pool = pool,
destroy_selected = destroy_selected,
invoke_player = invoke,
jail_player = jail_player,
probation_add = probation_add,
probation_remove = probation_remove,
regular_add = add_regular,
regular_remove = remove_regular,
revive_ghosts = revive_ghosts,
show_reports = show_reports,
teleport_command = teleport_command,
toggle_cheat_mode = toggle_cheat_mode,
unjail_player = unjail_player,
}
202 changes: 202 additions & 0 deletions features/gui/admin_panel/core.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
local Event = require 'utils.event'
local Gui = require 'utils.gui'
local Global = require 'utils.global'
local Config = require 'config'.admin_panel

local main_button_name = Gui.uid_name()
local main_frame_name = Gui.uid_name()
local close_button_name = Gui.uid_name()

local pages = {
--[[
{
type = 'sprite-button',
sprite = 'item/programmable-speaker',
tooltip = 'First page',
},
{
type = 'sprite-button',
sprite = 'utility/spawn_flag',
tooltip = 'Second page',
},
{
type = 'sprite-button',
sprite = 'utility/scripting_editor_icon',
tooltip = 'Third page',
},
{
type = 'sprite-button',
sprite = 'utility/surface_editor_icon',
tooltip = 'Fourth page',
},
]]
}

Global.register(pages, function(tbl) pages = tbl end)

local Public = {}

function Public.get_pages()
return pages
end

function Public.get_canvas(player)
return Gui.get_data(Public.get_main_frame(player)).right
end

function Public.get_main_frame(player)
local frame = player.gui.screen[main_frame_name]
if frame and frame.valid then
return frame
end

frame = player.gui.screen.add {
type = 'frame',
name = main_frame_name,
direction = 'vertical',
style = 'frame',
}
frame.auto_center = true
player.opened = frame
Gui.set_style(frame, {
horizontally_stretchable = true,
vertically_stretchable = true,
natural_width = 400,
natural_height = 400,
top_padding = 8,
bottom_padding = 8,
})

local data = {}

do -- title
local flow = frame.add { type = 'flow', direction = 'horizontal' }
Gui.set_style(flow, { horizontal_spacing = 8, vertical_align = 'center', bottom_padding = 4 })

local label = flow.add { type = 'label', caption = 'Admin panel', style = 'heading_1_label' }
label.drag_target = frame

local dragger = flow.add { type = 'empty-widget', style = 'draggable_space_header' }
dragger.drag_target = frame
Gui.set_style(dragger, { height = 24, horizontally_stretchable = true })

flow.add {
type = 'sprite-button',
name = close_button_name,
sprite = 'utility/close_white',
clicked_sprite = 'utility/close_black',
style = 'close_button',
tooltip = {'gui.close-instruction'}
}
end

local main_flow = frame.add { type = 'flow', name = 'flow', direction = 'horizontal' }
Gui.set_style(main_flow, { horizontal_spacing = 12 })

do -- left
local left = main_flow
.add { type = 'flow', name = 'left', direction = 'vertical' }
.add { type = 'frame', direction = 'vertical', style = 'inside_deep_frame' }
.add { type = 'flow', direction = 'vertical' }
Gui.set_style(left, {
vertically_stretchable = true,
horizontal_align = 'center',
padding = 10,
vertical_spacing = 10,
})

for _, page in pairs(pages) do
left.add(page)
end
data.left = left
end

do -- right
local right = main_flow
.add { type = 'frame', name = 'right', style = 'inside_shallow_frame_with_padding' }
.add { type = 'flow', name = 'flow', direction = 'vertical' }
Gui.set_style(right, {
minimal_width = 300,
minimal_height = 300,
vertically_stretchable = true,
horizontally_stretchable = true,
})
data.right = right
end

Gui.set_data(frame, data)
end

function Public.update_top_button(player)
if not Config.enabled then
return
end

local button = Gui.add_top_element(player, {
type = 'sprite-button',
name = main_button_name,
sprite = 'item/power-armor-mk2',
tooltip = {'admin_panel.info_tooltip'},
})
button.visible = player.admin
end

function Public.toggle_main_button(player)
local main_frame = player.gui.screen[main_frame_name]
if main_frame then
Gui.destroy(main_frame)
else
Public.get_main_frame(player)
end
end

function Public.close_all_pages(player)
local frame = player.gui.screen[main_frame_name]
if not (frame and frame.valid) then
return
end

for _, button in pairs(Gui.get_data(frame).left.children) do
button.toggled = false
end
end

Event.add(defines.events.on_player_created, function(event)
local player = game.get_player(event.player_index)
if not (player and player.valid) then
return
end
Public.update_top_button(player)
end)

Event.add(defines.events.on_gui_closed, function(event)
local element = event.element
if not (element and element.valid) then
return
end

local player = game.get_player(event.player_index)
if not (player and player.valid) then
return
end

if element.name == main_frame_name then
Public.toggle_main_button(player)
end
end)

Gui.allow_player_to_toggle_top_element_visibility(main_button_name)

Gui.on_click(main_button_name, function(event)
Public.toggle_main_button(event.player)
end)

Gui.on_click(close_button_name, function(event)
Public.toggle_main_button(event.player)
end)

Gui.on_player_show_top(main_button_name, function(event)
Public.update_top_button(event.player)
end)

return Public
Loading
Loading