mirror of
https://github.com/PHIDIAS0303/ExpCluster.git
synced 2025-12-27 03:25:23 +09:00
484 lines
21 KiB
Lua
484 lines
21 KiB
Lua
--[[-- Gui Module - Readme
|
|
- Adds a main gui that contains lots of important information about our server
|
|
@gui Readme
|
|
@alias readme
|
|
]]
|
|
|
|
local ExpUtil = require("modules/exp_util")
|
|
local Gui = require("modules/exp_gui")
|
|
local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event
|
|
local Roles = require("modules.exp_legacy.expcore.roles") --- @dep expcore.roles
|
|
local Commands = require("modules/exp_commands") --- @dep expcore.commands
|
|
local PlayerData = require("modules.exp_legacy.expcore.player_data") --- @dep expcore.player_data
|
|
local External = require("modules.exp_legacy.expcore.external") --- @dep expcore.external
|
|
local format_number = require("util").format_number --- @dep util
|
|
|
|
local tabs = {}
|
|
local function define_tab(caption, tooltip, element_define)
|
|
tabs[#tabs + 1] = { caption, tooltip, element_define }
|
|
end
|
|
|
|
local frame_width = 595 -- controls width of top descriptions
|
|
local title_width = 270 -- controls the centering of the titles
|
|
local scroll_height = 275 -- controls the height of the scrolls
|
|
|
|
--- Sub content area used within the content areas
|
|
local sub_content = Gui.define("readme_sub_content")
|
|
:draw{
|
|
type = "frame",
|
|
direction = "vertical",
|
|
style = "inside_deep_frame",
|
|
}
|
|
:style{
|
|
horizontally_stretchable = true,
|
|
horizontal_align = "center",
|
|
padding = { 2, 2 },
|
|
top_margin = 2,
|
|
}
|
|
|
|
--- Table which has a title above it above it
|
|
local title_table = Gui.define("readme_title_table")
|
|
:draw(function(_, parent, bar_size, caption, column_count)
|
|
Gui.elements.title_label(parent, bar_size, caption)
|
|
|
|
return parent.add{
|
|
type = "table",
|
|
column_count = column_count,
|
|
style = "bordered_table",
|
|
}
|
|
end)
|
|
:style{
|
|
padding = 0,
|
|
cell_padding = 0,
|
|
vertical_align = "center",
|
|
horizontally_stretchable = true,
|
|
}
|
|
|
|
--- Scroll to be used with Gui.elements.title_label tables
|
|
local title_table_scroll = Gui.define("readme_title_table_scroll")
|
|
:draw{
|
|
type = "scroll-pane",
|
|
direction = "vertical",
|
|
horizontal_scroll_policy = "never",
|
|
vertical_scroll_policy = "auto",
|
|
style = "scroll_pane_under_subheader",
|
|
}
|
|
:style{
|
|
padding = { 1, 3 },
|
|
maximal_height = scroll_height,
|
|
horizontally_stretchable = true,
|
|
}
|
|
|
|
--- Used to connect to servers in server list
|
|
local join_server = Gui.define("readme_join_server")
|
|
:draw(function(_, parent, server_id, wrong_version)
|
|
local status = External.get_server_status(server_id) or "Offline"
|
|
if wrong_version then status = "Version" end
|
|
local flow = parent.add{ name = server_id, type = "flow" }
|
|
local button = flow.add{
|
|
type = "sprite-button",
|
|
sprite = "utility/circuit_network_panel",
|
|
hovered_sprite = "utility/circuit_network_panel",
|
|
tooltip = { "readme.servers-connect-" .. status, wrong_version },
|
|
style = "frame_action_button",
|
|
}
|
|
|
|
if status == "Offline" or status == "Current" then
|
|
button.enabled = false
|
|
button.sprite = "utility/circuit_network_panel"
|
|
elseif status == "Version" then
|
|
button.enabled = false
|
|
button.sprite = "utility/shuffle"
|
|
elseif status == "Password" then
|
|
button.sprite = "utility/warning_white"
|
|
button.hovered_sprite = "utility/warning"
|
|
elseif status == "Modded" then
|
|
button.sprite = "utility/downloading_white"
|
|
button.hovered_sprite = "utility/downloading"
|
|
end
|
|
|
|
return button
|
|
end)
|
|
:style{
|
|
size = 20,
|
|
padding = -1,
|
|
}
|
|
:on_click(function(def, player, element)
|
|
local server_id = element.parent.name
|
|
External.request_connection(player, server_id, true)
|
|
end)
|
|
|
|
local welcome_time_format = ExpUtil.format_time_factory_locale{ format = "long", days = true, hours = true, minutes = true }
|
|
|
|
--- Content area for the welcome tab
|
|
define_tab({ "readme.welcome-tab" }, { "readme.welcome-tooltip" }, Gui.define("readme_welcome")
|
|
:draw(function(_, parent)
|
|
local server_details = { name = "APERX S0 - Local", welcome = "Failed to load description: disconnected from external api.", reset_time = "Non Set", branch = "Unknown" }
|
|
if External.valid() then server_details = External.get_current_server() end
|
|
local container = parent.add{ type = "flow", direction = "vertical" }
|
|
local player = Gui.get_player(parent)
|
|
|
|
-- Set up the top flow with logos
|
|
local top_flow = container.add{ type = "flow" }
|
|
top_flow.add{ type = "sprite", sprite = "file/modules/exp_legacy/modules/gui/logo.png" }
|
|
local top_vertical_flow = top_flow.add{ type = "flow", direction = "vertical" }
|
|
top_flow.add{ type = "sprite", sprite = "file/modules/exp_legacy/modules/gui/logo.png" }
|
|
top_vertical_flow.style.horizontal_align = "center"
|
|
|
|
-- Add the title and description to the top flow
|
|
Gui.elements.title_label(top_vertical_flow, 62, "Welcome to " .. server_details.name)
|
|
Gui.elements.centered_label(top_vertical_flow, 380, server_details.welcome)
|
|
Gui.elements.bar(container)
|
|
|
|
-- Get the names of the roles the player has
|
|
local player_roles = Roles.get_player_roles(player)
|
|
local role_names = {}
|
|
for i, role in ipairs(player_roles) do
|
|
role_names[i] = role.name
|
|
end
|
|
|
|
-- Add the other information to the gui
|
|
container.add{ type = "flow" }.style.height = 4
|
|
local online_time = welcome_time_format(game.tick)
|
|
Gui.elements.centered_label(sub_content(container), frame_width, { "readme.welcome-general", server_details.reset_time, online_time })
|
|
Gui.elements.centered_label(sub_content(container), frame_width, { "readme.welcome-roles", table.concat(role_names, ", ") })
|
|
Gui.elements.centered_label(sub_content(container), frame_width, { "readme.welcome-chat" })
|
|
|
|
return container
|
|
end))
|
|
|
|
--- Content area for the rules tab
|
|
define_tab({ "readme.rules-tab" }, { "readme.rules-tooltip" }, Gui.define("readme_rules")
|
|
:draw(function(_, parent)
|
|
local container = parent.add{ type = "flow", direction = "vertical" }
|
|
|
|
-- Add the title and description to the content
|
|
Gui.elements.title_label(container, title_width - 3, { "readme.rules-tab" })
|
|
Gui.elements.centered_label(container, frame_width, { "readme.rules-general" })
|
|
Gui.elements.bar(container)
|
|
container.add{ type = "flow" }
|
|
|
|
-- Add a table for the rules
|
|
local rules = Gui.elements.scroll_table(container, scroll_height, 1) --[[@as LuaGuiElement]]
|
|
rules.style = "bordered_table"
|
|
rules.style.cell_padding = 4
|
|
|
|
-- Add the rules to the table
|
|
for i = 1, 15 do
|
|
Gui.elements.centered_label(rules, 565, { "readme.rules-" .. i })
|
|
end
|
|
|
|
return container
|
|
end))
|
|
|
|
--- Content area for the commands tab
|
|
define_tab({ "readme.commands-tab" }, { "readme.commands-tooltip" }, Gui.define("readme_commands")
|
|
:draw(function(_, parent)
|
|
local container = parent.add{ type = "flow", direction = "vertical" }
|
|
local player = Gui.get_player(parent)
|
|
|
|
-- Add the title and description to the content
|
|
Gui.elements.title_label(container, title_width - 20, { "readme.commands-tab" })
|
|
Gui.elements.centered_label(container, frame_width, { "readme.commands-general" })
|
|
Gui.elements.bar(container)
|
|
container.add{ type = "flow" }
|
|
|
|
-- Add a table for the commands
|
|
local commands = Gui.elements.scroll_table(container, scroll_height, 2) --[[@as LuaGuiElement]]
|
|
commands.style = "bordered_table"
|
|
commands.style.cell_padding = 0
|
|
|
|
-- Add the rules to the table
|
|
for name, command in pairs(Commands.list_for_player(player)) do
|
|
Gui.elements.centered_label(commands, 120, name)
|
|
Gui.elements.centered_label(commands, 450, command.description)
|
|
end
|
|
|
|
return container
|
|
end))
|
|
|
|
--- Content area for the servers tab
|
|
define_tab({ "readme.servers-tab" }, { "readme.servers-tooltip" }, Gui.define("readme_servers")
|
|
:draw(function(_, parent)
|
|
local container = parent.add{ type = "flow", direction = "vertical" }
|
|
|
|
-- Add the title and description to the content
|
|
Gui.elements.title_label(container, title_width - 10, { "readme.servers-tab" })
|
|
Gui.elements.centered_label(container, frame_width, { "readme.servers-general" })
|
|
Gui.elements.bar(container)
|
|
container.add{ type = "flow" }
|
|
|
|
-- Draw the scroll
|
|
local scroll_pane = title_table_scroll(container)
|
|
scroll_pane.style.maximal_height = scroll_height + 20 -- the text is a bit shorter
|
|
|
|
-- Add the factorio servers
|
|
if External.valid() then
|
|
local factorio_servers = title_table(scroll_pane, 225, { "readme.servers-factorio" }, 3)
|
|
local current_version = External.get_current_server().version
|
|
for server_id, server in pairs(External.get_servers()) do
|
|
Gui.elements.centered_label(factorio_servers, 110, server.short_name)
|
|
Gui.elements.centered_label(factorio_servers, 436, server.description)
|
|
join_server(factorio_servers, server_id, current_version ~= server.version and server.version)
|
|
end
|
|
else
|
|
local factorio_servers = title_table(scroll_pane, 225, { "readme.servers-factorio" }, 2)
|
|
for _, i in pairs{ 1, 2, 3, 5, 6, 8 } do
|
|
Gui.elements.centered_label(factorio_servers, 110, { "readme.servers-" .. i })
|
|
Gui.elements.centered_label(factorio_servers, 460, { "readme.servers-d" .. i })
|
|
end
|
|
end
|
|
|
|
-- Add the external links
|
|
local external_links = title_table(scroll_pane, 235, { "readme.servers-external" }, 2)
|
|
for _, key in ipairs{ "website", "github" } do
|
|
local upper_key = key:gsub("^%l", string.upper)
|
|
Gui.elements.centered_label(external_links, 110, upper_key)
|
|
Gui.elements.centered_label(external_links, 460, { "links." .. key }, { "readme.servers-open-in-browser" })
|
|
end
|
|
|
|
return container
|
|
end))
|
|
|
|
--- Content area for the servers tab
|
|
define_tab({ "readme.backers-tab" }, { "readme.backers-tooltip" }, Gui.define("readme_backers")
|
|
:draw(function(_, parent)
|
|
local container = parent.add{ type = "flow", direction = "vertical" }
|
|
|
|
-- Add the title and description to the content
|
|
Gui.elements.title_label(container, title_width - 10, { "readme.backers-tab" })
|
|
Gui.elements.centered_label(container, frame_width, { "readme.backers-general" })
|
|
Gui.elements.bar(container)
|
|
container.add{ type = "flow" }
|
|
|
|
-- Find which players will go where
|
|
local done = {}
|
|
local groups = {
|
|
{ _roles = { "Senior Administrator", "Administrator" }, _title = { "readme.backers-management" }, _width = 230 },
|
|
{ _roles = { "Senior Moderator", "Moderator", "Trainee Moderator" }, _title = { "readme.backers-staff" }, _width = 230 },
|
|
{ _roles = { "Board Member", "Supporter", "Partner" }, _title = { "readme.backers-backers" }, _width = 230 }, -- change role to board
|
|
{ _roles = { "Veteran" }, _title = { "readme.backers-active" }, _width = 230 },
|
|
-- _time = 3 * 3600 * 60
|
|
}
|
|
|
|
-- Fill by player roles
|
|
for player_name, player_roles in pairs(Roles.config.players) do
|
|
for _, players in ipairs(groups) do
|
|
for _, role_name in pairs(players._roles) do
|
|
if table.contains(player_roles, role_name) then
|
|
done[player_name] = true
|
|
table.insert(players, player_name)
|
|
break
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
-- Fill by active times
|
|
for _, player in pairs(game.players) do
|
|
if not done[player.name] then
|
|
for _, players in ipairs(groups) do
|
|
if players._time and player.online_time > players._time then
|
|
table.insert(players, player.name)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
-- Add the different tables
|
|
local scroll_pane = title_table_scroll(container)
|
|
for _, players in ipairs(groups) do
|
|
local table = title_table(scroll_pane, players._width, players._title, 4)
|
|
for _, player_name in ipairs(players) do
|
|
Gui.elements.centered_label(table, 140, player_name)
|
|
end
|
|
|
|
if #players < 4 then
|
|
for i = 1, 4 - #players do
|
|
Gui.elements.centered_label(table, 140)
|
|
end
|
|
end
|
|
end
|
|
|
|
return container
|
|
end))
|
|
|
|
--- Content area for the player data tab
|
|
define_tab({ "readme.data-tab" }, { "readme.data-tooltip" }, Gui.define("readme_data")
|
|
:draw(function(_, parent)
|
|
local container = parent.add{ type = "flow", direction = "vertical" }
|
|
local player = Gui.get_player(parent)
|
|
local player_name = player.name
|
|
|
|
local enum = PlayerData.PreferenceEnum
|
|
local preference = PlayerData.DataSavingPreference:get(player_name)
|
|
local preference_meta = PlayerData.DataSavingPreference.metadata
|
|
preference = enum[preference]
|
|
|
|
-- Add the title and description to the content
|
|
Gui.elements.title_label(container, title_width, { "readme.data-tab" })
|
|
Gui.elements.centered_label(container, frame_width, { "readme.data-general" })
|
|
Gui.elements.bar(container)
|
|
container.add{ type = "flow" }
|
|
local scroll_pane = title_table_scroll(container)
|
|
|
|
-- Add the required area
|
|
local required = title_table(scroll_pane, 250, { "readme.data-required" }, 2)
|
|
Gui.elements.centered_label(required, 150, preference_meta.name, preference_meta.tooltip)
|
|
Gui.elements.centered_label(required, 420, { "expcore-data.preference-" .. enum[preference] }, preference_meta.value_tooltip)
|
|
|
|
for name, child in pairs(PlayerData.Required.children) do
|
|
local metadata = child.metadata
|
|
local value = child:get(player_name)
|
|
if value ~= nil or metadata.show_always then
|
|
if metadata.stringify then value = metadata.stringify(value) end
|
|
Gui.elements.centered_label(required, 150, metadata.name or { "exp-required." .. name }, metadata.tooltip or { "exp-required." .. name .. "-tooltip" })
|
|
Gui.elements.centered_label(required, 420, tostring(value), metadata.value_tooltip or { "exp-required." .. name .. "-value-tooltip" })
|
|
end
|
|
end
|
|
|
|
-- Add the settings area
|
|
if preference <= enum.Settings then
|
|
local settings = title_table(scroll_pane, 255, { "readme.data-settings" }, 2)
|
|
for name, child in pairs(PlayerData.Settings.children) do
|
|
local metadata = child.metadata
|
|
local value = child:get(player_name)
|
|
if not metadata.permission or Roles.player_allowed(player, metadata.permission) then
|
|
if metadata.stringify then value = metadata.stringify(value) end
|
|
if value == nil then value = "None set" end
|
|
Gui.elements.centered_label(settings, 150, metadata.name or { "exp-settings." .. name }, metadata.tooltip or { "exp-settings." .. name .. "-tooltip" })
|
|
Gui.elements.centered_label(settings, 420, tostring(value), metadata.value_tooltip or { "exp-settings." .. name .. "-value-tooltip" })
|
|
end
|
|
end
|
|
end
|
|
|
|
-- Add the statistics area
|
|
if preference <= enum.Statistics then
|
|
local count = 4
|
|
local statistics = title_table(scroll_pane, 250, { "readme.data-statistics" }, 4)
|
|
for _, name in pairs(PlayerData.Statistics.metadata.display_order) do
|
|
local child = PlayerData.Statistics[name]
|
|
local metadata = child.metadata
|
|
local value = child:get(player_name)
|
|
if value ~= nil or metadata.show_always then
|
|
count = count - 2
|
|
if metadata.stringify then
|
|
value = metadata.stringify(value)
|
|
else
|
|
value = format_number(value or 0, false)
|
|
end
|
|
Gui.elements.centered_label(statistics, 150, metadata.name or { "exp-statistics." .. name }, metadata.tooltip or { "exp-statistics." .. name .. "-tooltip" })
|
|
Gui.elements.centered_label(statistics, 130, { "readme.data-format", value, metadata.unit or "" }, metadata.value_tooltip or { "exp-statistics." .. name .. "-tooltip" })
|
|
end
|
|
end
|
|
|
|
if count > 0 then for i = 1, count do Gui.elements.centered_label(statistics, 140) end end
|
|
end
|
|
|
|
-- Add the misc area
|
|
local skip = { DataSavingPreference = true, Settings = true, Statistics = true, Required = true }
|
|
local count = 0; for _ in pairs(PlayerData.All.children) do count = count + 1 end
|
|
|
|
if preference <= enum.All and count > 4 then
|
|
local misc = title_table(scroll_pane, 232, { "readme.data-misc" }, 2)
|
|
for name, child in pairs(PlayerData.All.children) do
|
|
if not skip[name] then
|
|
local metadata = child.metadata
|
|
local value = child:get(player_name)
|
|
if value ~= nil or metadata.show_always then
|
|
if metadata.stringify then value = metadata.stringify(value) end
|
|
Gui.elements.centered_label(misc, 150, metadata.name or name, metadata.tooltip)
|
|
Gui.elements.centered_label(misc, 420, tostring(value), metadata.value_tooltip)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
return container
|
|
end))
|
|
|
|
--- Main readme container for the center flow
|
|
local readme_toggle
|
|
local readme = Gui.define("readme")
|
|
:draw(function(def, parent)
|
|
local container = parent.add{
|
|
name = def.name,
|
|
type = "frame",
|
|
style = "invisible_frame",
|
|
}
|
|
|
|
-- Add the left hand side of the frame back, removed because of frame_tabbed_pane style
|
|
local left_alignment = Gui.elements.aligned_flow(container, { vertical_align = "bottom" })
|
|
left_alignment.style.padding = { 32, 0, 0, 0 }
|
|
|
|
local left_side =
|
|
left_alignment.add{
|
|
type = "frame",
|
|
style = "character_gui_left_side",
|
|
}
|
|
left_side.style.vertically_stretchable = true
|
|
left_side.style.padding = 0
|
|
left_side.style.width = 5
|
|
|
|
-- Add the tab pane
|
|
local tab_pane = container.add{
|
|
name = "pane",
|
|
type = "tabbed-pane",
|
|
style = "frame_tabbed_pane",
|
|
}
|
|
|
|
-- Add the different content areas
|
|
for _, tab_details in ipairs(tabs) do
|
|
local tab = tab_pane.add{ type = "tab", style = "frame_tab", caption = tab_details[1], tooltip = tab_details[2] }
|
|
tab_pane.add_tab(tab, tab_details[3](tab_pane))
|
|
end
|
|
|
|
return container
|
|
end)
|
|
:on_opened(function(def, player, element)
|
|
Gui.toolbar.set_button_toggled_state(readme_toggle, player, true)
|
|
end)
|
|
:on_closed(function(def, player, element)
|
|
Gui.toolbar.set_button_toggled_state(readme_toggle, player, false)
|
|
Gui.destroy_if_valid(element)
|
|
end)
|
|
|
|
--- Toggle button for the readme gui
|
|
readme_toggle =
|
|
Gui.toolbar.create_button{
|
|
name = "readme_toggle",
|
|
auto_toggle = true,
|
|
sprite = "virtual-signal/signal-info",
|
|
tooltip = { "readme.main-tooltip" },
|
|
visible = function(player, element)
|
|
return Roles.player_allowed(player, "gui/readme")
|
|
end
|
|
}
|
|
:on_click(function(def, player, element)
|
|
local center = player.gui.center
|
|
if center[readme.name] then
|
|
player.opened = nil
|
|
else
|
|
player.opened = readme(center)
|
|
end
|
|
end)
|
|
|
|
--- When a player joins the game for the first time show this gui
|
|
Event.add(defines.events.on_player_created, function(event)
|
|
local player = game.players[event.player_index]
|
|
local element = readme(player.gui.center)
|
|
element.pane.selected_tab_index = 1
|
|
player.opened = element
|
|
end)
|
|
|
|
local function clear_readme(event)
|
|
local player = game.players[event.player_index]
|
|
if not player.opened then
|
|
Gui.destroy_if_valid(player.gui.center[readme.name])
|
|
end
|
|
end
|
|
|
|
--- When a player joins or respawns, clear center unless the player has something open
|
|
Event.add(defines.events.on_player_joined_game, clear_readme)
|
|
Event.add(defines.events.on_player_respawned, clear_readme)
|