mirror of
https://github.com/PHIDIAS0303/ExpCluster.git
synced 2025-12-29 20:16:38 +09:00
Refactor of commands
This commit is contained in:
338
old/modules/ExpGamingCore/Sync/control.lua
Normal file
338
old/modules/ExpGamingCore/Sync/control.lua
Normal file
@@ -0,0 +1,338 @@
|
||||
--- Allows syncing with an outside server and info panel.
|
||||
-- @module ExpGamingCore.Sync
|
||||
-- @alias Sync
|
||||
-- @author Cooldude2606
|
||||
-- @license https://github.com/explosivegaming/scenario/blob/master/LICENSE
|
||||
|
||||
local Game = require('FactorioStdLib.Game')
|
||||
local Color = require('FactorioStdLib.Color')
|
||||
|
||||
local Sync = {}
|
||||
local Sync_updates = {}
|
||||
local module_verbose = false --true|false
|
||||
|
||||
--- Global Table
|
||||
-- @table global
|
||||
-- @field server_name the server name
|
||||
-- @field server_description a short description of the server
|
||||
-- @field reset_time the reset time of the server
|
||||
-- @field time the last known irl time
|
||||
-- @field time_set the last in game time that the time was set
|
||||
-- @field last_update the last time that this info was updated
|
||||
-- @field time_period how often this information is updated
|
||||
-- @field players a list of different player related states
|
||||
-- @field ranks a list of player ranks
|
||||
-- @field rockets the number of rockets launched
|
||||
-- @field mods the mods which are loaded
|
||||
local global = {
|
||||
server_name='Factorio Server',
|
||||
server_description='A factorio server for everyone',
|
||||
reset_time='On Demand',
|
||||
time='Day Mth 00 00:00:00 UTC Year',
|
||||
date='0000/00/00',
|
||||
time_set={0,'0.00M'},
|
||||
last_update={0,'0.00M'},
|
||||
time_period={18000,'5.00M'},
|
||||
game_speed=1.0,
|
||||
players={
|
||||
online={},
|
||||
n_online=0,
|
||||
all={},
|
||||
n_all=0,
|
||||
admins_online=0,
|
||||
afk_players={},
|
||||
times={}
|
||||
},
|
||||
roles={admin={online={},players={},n_online=0,n_players=0},user={online={},players={},n_online=0,n_players=0}},
|
||||
rockets=0,
|
||||
mods={'Offline'}
|
||||
}
|
||||
Global.register(global,function(tbl) global = tbl end)
|
||||
|
||||
--- Player sub-table
|
||||
-- @table global.players
|
||||
-- @field online list of all players online
|
||||
-- @field n_online the number of players online
|
||||
-- @field all list of all player on or offline
|
||||
-- @field n_all the number of players who have joined the server
|
||||
-- @field admins_online the number of admins online
|
||||
-- @field afk_players the number of afk players
|
||||
-- @field times the play times of every player
|
||||
|
||||
--- Used to standardise the tick format for any sync info
|
||||
-- @usage Sync.tick_format(60) -- return {60,'1.00M'}
|
||||
-- @treturn {number,string} table containing both the raw number and clean version of a time
|
||||
function Sync.tick_format(tick)
|
||||
if not is_type(tick,'number') then error('Tick was not given to Sync.tick_format',2) end
|
||||
return {tick,tick_to_display_format(tick)}
|
||||
end
|
||||
|
||||
--- Prints to chat as if it were a player
|
||||
-- @usage Sync.print('Test','Cooldude2606')
|
||||
-- @tparam string player_message the message to be printed in chat
|
||||
-- @tparam string player_name the name of the player sending the message
|
||||
-- @tparam[opt] string player_tag the tag applied to the player's name
|
||||
-- @tparam[opt] string player_colour the colour of the message, either hex or named colour
|
||||
-- @tparam[opt] string prefix add a prefix before the chat eg [IRC]
|
||||
function Sync.print(player_message,player_name,player_tag,player_colour,prefix)
|
||||
if not player_message then error('No message given to Sync.print',2) end
|
||||
local player = game.player or game.players[player_name]
|
||||
local tag = player_tag and player_tag ~= '' and ' '..player_tag or ''
|
||||
local colour = type(player_colour) == 'string' and player_colour or '#FFFFFF'
|
||||
prefix = prefix and prefix..' ' or ''
|
||||
-- if it is an in game player it will over ride the given params
|
||||
if player then
|
||||
tag = ' '..player.tag
|
||||
colour = player.chat_color
|
||||
player_name = player.name
|
||||
else
|
||||
-- converts colour into the accepted factorio version
|
||||
if colour:find('#') then colour = Color.from_hex(colour)
|
||||
else colour = defines.color[player_colour] end
|
||||
end
|
||||
game.print(prefix..player_name..tag..': '..player_message,colour)
|
||||
end
|
||||
|
||||
--- Outline of the parameters accepted by Sync.emit_embedded
|
||||
-- @table EmitEmbededParamaters
|
||||
-- @field title the tile of the embed
|
||||
-- @field color the color given in hex you can use Color.to_hex{r=0,g=0,b=0}
|
||||
-- @field description the description of the embed
|
||||
-- @field server_detail sting to add onto the pre-set server detail
|
||||
-- @field fieldone the filed to add to the embed (key is name) (value is text) (start value with <<inline>> to make inline)
|
||||
-- @field fieldtwo the filed to add to the embed (key is name) (value is text) (start value with <<inline>> to make inline)
|
||||
|
||||
--- Logs an embed to the json.data we use a js script to add things we cant here
|
||||
-- @usage Sync.emit_embedded{title='BAN',color='0x0',description='A player was banned' ... }
|
||||
-- @tparam table args a table which contains everything that the embedded will use
|
||||
-- @see EmitEmbededParamaters
|
||||
function Sync.emit_embedded(args)
|
||||
if not is_type(args,'table') then error('Args table not given to Sync.emit_embedded',2) end
|
||||
if not game then error('Game has not loaded',2) end
|
||||
local title = is_type(args.title,'string') and args.title or ''
|
||||
local color = is_type(args.color,'string') and args.color:find("0x") and args.color or '0x0'
|
||||
local description = is_type(args.description,'string') and args.description or ''
|
||||
local server_detail = is_type(args.server_detail,'string') and args.server_detail or ''
|
||||
local mods_online = 'Mods Online: '..Sync.info.players.admins_online
|
||||
-- creates the first field given for every emit
|
||||
local done, fields = {title=true,color=true,description=true,server_detail=true}, {{
|
||||
name='Server Details',
|
||||
value='Server Name: ${serverName} Online Players: '..#game.connected_players..' '..mods_online..' Server Time: '..tick_to_display_format(game.tick)..' '..server_detail
|
||||
}}
|
||||
-- for each value given in args it will create a new field for the embed
|
||||
for key, value in pairs(args) do
|
||||
if not done[key] then
|
||||
done[key] = true
|
||||
local f = {name=key,value='',inline=false}
|
||||
-- if <<inline>> is present then it will cause the field to be inline if the previous
|
||||
local value, inline = value:gsub("<<inline>>",'',1)
|
||||
if inline > 0 then f.inline = true end
|
||||
f.value = value
|
||||
table.insert(fields,f)
|
||||
end
|
||||
end
|
||||
-- forms the data that will be emitted to the file
|
||||
local log_data = {
|
||||
title=title,
|
||||
description=description,
|
||||
color=color,
|
||||
fields=fields
|
||||
}
|
||||
game.write_file('embedded.json',table.json(log_data)..'\n',true,0)
|
||||
end
|
||||
|
||||
--- The error handle setup by sync to emit a discord embed for any errors
|
||||
-- @local here
|
||||
-- @function errorHandler
|
||||
-- @tparam string err the error passed by the err control
|
||||
error.addHandler('Discord Emit',function(err)
|
||||
if not game then return error(error()) end
|
||||
local color = Color and Color.to_hex(defines.textcolor.bg) or '0x0'
|
||||
Sync.emit_embedded{title='SCRIPT ERROR',color=color,description='There was an error in the script @Developers ',Error=err}
|
||||
end)
|
||||
|
||||
--- Used to get the number of admins currently online
|
||||
-- @usage Sync.count_admins() -- returns number
|
||||
-- @treturn number the number of admins online
|
||||
function Sync.count_admins()
|
||||
-- game check
|
||||
if not game then return 0 end
|
||||
local _count = 0
|
||||
for _,player in pairs(game.connected_players) do
|
||||
if player.admin then _count=_count+1 end
|
||||
end
|
||||
return _count
|
||||
end
|
||||
|
||||
--- Used to get the number of afk players defined by 2 min by default
|
||||
-- @usage Sync.count_afk_times()
|
||||
-- @tparam[opt=7200] int time in ticks that a player is called afk
|
||||
-- @treturn number the number of afk players
|
||||
function Sync.count_afk_times(time)
|
||||
if not game then return 0 end
|
||||
time = time or 7200
|
||||
local rtn = {}
|
||||
for _,player in pairs(game.connected_players) do
|
||||
if player.afk_time > time then rtn[player.name] = Sync.tick_format(player.afk_time) end
|
||||
end
|
||||
return rtn
|
||||
end
|
||||
|
||||
--- Used to get the number of players in each rank and currently online
|
||||
-- @usage Sync.count_roles()
|
||||
-- @treturn table contains the ranks and the players in that rank
|
||||
function Sync.count_roles()
|
||||
if not game then return {'Offline'} end
|
||||
local _rtn = {admin={online={},players={}},user={online={},players={}}}
|
||||
for index,player in pairs(game.players) do
|
||||
if player.admin then
|
||||
table.insert(_rtn.admin.players,player.name)
|
||||
if player.connected then table.insert(_rtn.admin.online,player.name) end
|
||||
else
|
||||
table.insert(_rtn.user.players,player.name)
|
||||
if player.connected then table.insert(_rtn.user.online,player.name) end
|
||||
end
|
||||
end
|
||||
_rtn.admin.n_players,_rtn.admin.n_online=#_rtn.admin.players,#_rtn.admin.online
|
||||
_rtn.user.n_players,_rtn.user.n_online=#_rtn.user.players,#_rtn.user.online
|
||||
return _rtn
|
||||
end
|
||||
|
||||
--- Used to get a list of every player name with the option to limit to only online players
|
||||
-- @usage Sync.count_players()
|
||||
-- @tparam boolean online true will get only the online players
|
||||
-- @treturn table table of player names
|
||||
function Sync.count_players(online)
|
||||
if not game then return {'Offline'} end
|
||||
local _players = {}
|
||||
local players = {}
|
||||
if online then _players = game.connected_players else _players = game.players end
|
||||
for k,player in pairs(_players) do table.insert(players,player.name) end
|
||||
return players
|
||||
end
|
||||
|
||||
--- Used to get a list of every player name with the amount of time they have played for
|
||||
-- @usage Sync.count_player_times()
|
||||
-- @treturn table table indexed by player name, each value contains the raw tick and then the clean string
|
||||
function Sync.count_player_times()
|
||||
if not game then return {'Offline'} end
|
||||
local _players = {}
|
||||
for index,player in pairs(game.players) do
|
||||
_players[player.name] = Sync.tick_format(player.online_time)
|
||||
end
|
||||
return _players
|
||||
end
|
||||
|
||||
--- used to get the global list that has been defined, also used to set that list
|
||||
-- @usage Sync.info{server_name='Factorio Server 2'} -- returns true
|
||||
-- @usage Sync.info -- table of info
|
||||
-- @tparam[opt=nil] table set keys to be replaced in the server info
|
||||
-- @treturn boolean success was the data set
|
||||
Sync.info = setmetatable({},{
|
||||
__index=global,
|
||||
__newindex=global,
|
||||
__call=function(tbl,set)
|
||||
if not is_type(set,'table') then return false end
|
||||
for key,value in pairs(set) do global[key] = value end
|
||||
return true
|
||||
end,
|
||||
__pairs=function(tbl)
|
||||
tbl = global
|
||||
local function next_pair(tbl,key)
|
||||
local k, v = next(tbl, key)
|
||||
if type(v) ~= nil then return k,v end
|
||||
end
|
||||
return next_pair, tbl, nil
|
||||
end,
|
||||
__ipairs=function(tbl)
|
||||
tbl = global
|
||||
local function next_pair(tbl, i)
|
||||
i = i + 1
|
||||
local v = tbl[i]
|
||||
if v then return i, v end
|
||||
end
|
||||
return next_pair, tbl, 0
|
||||
end
|
||||
})
|
||||
|
||||
--- Called to update values inside of the info
|
||||
-- @usage Sync.update()
|
||||
-- @return all of the new info
|
||||
function Sync.update()
|
||||
local info = Sync.info
|
||||
info.time_period[2] = tick_to_display_format(info.time_period[1])
|
||||
info.last_update[1] = game.tick
|
||||
info.last_update[2] = tick_to_display_format(game.tick)
|
||||
info.game_speed = game.speed
|
||||
info.players={
|
||||
online=Sync.count_players(true),
|
||||
n_online=#game.connected_players,
|
||||
all=Sync.count_players(),
|
||||
n_all=#game.players,
|
||||
admins_online=Sync.count_admins(),
|
||||
afk_players=Sync.count_afk_times(),
|
||||
times=Sync.count_player_times()
|
||||
}
|
||||
info.roles = Sync.count_roles()
|
||||
info.rockets = game.forces['player'].get_item_launched('satellite')
|
||||
for key,callback in pairs(Sync_updates) do info[key] = callback() end
|
||||
return info
|
||||
end
|
||||
|
||||
--- Adds a callback to be called when the info is updated
|
||||
-- @usage Sync.add_update('players',function() return #game.players end)
|
||||
-- @tparam string key the key that the value will be stored in
|
||||
-- @tparam function callback the function which will return this value
|
||||
function Sync.add_update(key,callback)
|
||||
if game then return end
|
||||
if not is_type(callback,'function') then return end
|
||||
Sync_updates[key] = callback
|
||||
end
|
||||
|
||||
--- Outputs the curent server info into a file
|
||||
-- @usage Sync.emit_data()
|
||||
function Sync.emit_data()
|
||||
local info = Sync.info
|
||||
game.write_file('server-info.json',table.json(info),false,0)
|
||||
end
|
||||
|
||||
--- Updates the info and emits the data to a file
|
||||
-- @usage Sync.emit_update()
|
||||
function Sync.emit_update()
|
||||
Sync.update() Sync.emit_data()
|
||||
end
|
||||
|
||||
--- Used to return and set the current IRL time; not very good need a better way to do this
|
||||
-- @usage Sync.time('Sun Apr 1 18:44:30 UTC 2018')
|
||||
-- @usage Sync.time -- string
|
||||
-- @tparam[opt=nil] string set the date time to be set
|
||||
-- @treturn boolean if the date time set was successful
|
||||
Sync.time=add_metatable({},function(full,date)
|
||||
local info = Sync.info
|
||||
if not is_type(full,'string') then return false end
|
||||
info.time = full
|
||||
info.date = date
|
||||
info.time_set[1] = Sync.tick_format(game.tick)
|
||||
return true
|
||||
end,function() local info = Sync.info return info.time..' (+'..(game.tick-info.time_set[1])..' Ticks)' end)
|
||||
|
||||
-- will auto replace the file every 5 min by default
|
||||
Event.add('on_tick',function(event)
|
||||
local time = Sync.info.time_period[1]
|
||||
if (event.tick%time)==0 then Sync.emit_update() end
|
||||
end)
|
||||
|
||||
Event.add('on_player_joined_game',Sync.emit_update)
|
||||
Event.add('on_pre_player_left_game',Sync.emit_update)
|
||||
Event.add('on_rocket_launched',Sync.emit_update)
|
||||
|
||||
function Sync:on_init()
|
||||
if loaded_modules['ExpGamingCore.Gui'] then verbose('ExpGamingCore.Gui is installed; Loading gui src') require(module_path..'/src/gui',{Sync=Sync,module_path=module_path}) end
|
||||
if loaded_modules['ExpGamingCore.Server'] then require('ExpGamingCore.Server').add_module_to_interface('Sync','ExpGamingCore.Sync') end
|
||||
end
|
||||
|
||||
function Sync:on_post()
|
||||
Sync.info{mods=table.keys(loaded_modules)}
|
||||
end
|
||||
|
||||
return Sync
|
||||
27
old/modules/ExpGamingCore/Sync/softmod.json
Normal file
27
old/modules/ExpGamingCore/Sync/softmod.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"name": "ExpGamingCore.Sync",
|
||||
"version": "4.0.0",
|
||||
"description": "Allows syncing with an outside server and info panle.",
|
||||
"location": "FSM_ARCHIVE",
|
||||
"keywords": [
|
||||
"Library",
|
||||
"Lib",
|
||||
"ExpGaming",
|
||||
"Core",
|
||||
"Info",
|
||||
"Sync",
|
||||
"External",
|
||||
"Discord"
|
||||
],
|
||||
"dependencies": {
|
||||
"ExpGamingLib": "^4.0.0",
|
||||
"FactorioStdLib.Color": "^0.8.0",
|
||||
"FactorioStdLib.Game": "^0.8.0",
|
||||
"FactorioStdLib.Table": "^0.8.0",
|
||||
"ExpGamingCore.Role": "?^4.0.0",
|
||||
"ExpGamingCore.Gui": "?^4.0.0",
|
||||
"ExpGamingCore.Server": "?^4.0.0"
|
||||
},
|
||||
"collection": "ExpGamingCore@4.0.0",
|
||||
"submodules": {}
|
||||
}
|
||||
106
old/modules/ExpGamingCore/Sync/src/gui.lua
Normal file
106
old/modules/ExpGamingCore/Sync/src/gui.lua
Normal file
@@ -0,0 +1,106 @@
|
||||
--- Allows syncing with an outside server and info panel.
|
||||
-- @submodule ExpGamingCore.Sync
|
||||
-- @alias Sync
|
||||
-- @author Cooldude2606
|
||||
-- @license https://github.com/explosivegaming/scenario/blob/master/LICENSE
|
||||
|
||||
--- This file will be loaded when ExpGamingCore.Gui is present
|
||||
-- @function _comment
|
||||
|
||||
local Gui = require('ExpGamingCore.Gui')
|
||||
local Sync = Sync -- this is to force sync to remain in the ENV
|
||||
|
||||
local Sync_gui_functions = {}
|
||||
local logo_sprite_path = 'file'..string.sub(module_path,2)..'/src/logo.png'
|
||||
|
||||
--- Adds a element to the sever info gui
|
||||
-- @usage Sync.add_to_gui('string') -- return true
|
||||
-- @param element see examples before for what can be used, it can also be a return from Gui.inputs.add
|
||||
-- @treturn boolean based on weather it was successful or not
|
||||
function Sync.add_to_gui(element,...)
|
||||
if game then return false end
|
||||
if is_type(element,'function') then
|
||||
table.insert(Sync_gui_functions,{'function',element,...})
|
||||
elseif is_type(element,'table') then
|
||||
if element.draw then table.insert(Sync_gui_functions,{'gui',element})
|
||||
else table.insert(Sync_gui_functions,{'table',element}) end
|
||||
else table.insert(Sync_gui_functions,{'string',element}) end
|
||||
return true
|
||||
end
|
||||
|
||||
Sync.add_to_gui('Welcome to the Explosive Gaming community! This is one of many servers which we host.')
|
||||
Sync.add_to_gui(function(player,frame) return 'This server\'s next reset: '..Sync.info.reset_time end)
|
||||
|
||||
--- Formats a label to be a certain format
|
||||
-- @local label_format
|
||||
local function label_format(label,width)
|
||||
label.style.width = width
|
||||
label.style.align = 'center'
|
||||
label.style.single_line = false
|
||||
end
|
||||
|
||||
--- Creates a center gui that will appear on join
|
||||
-- @gui server-info
|
||||
Sync.info_gui = Gui.center{
|
||||
name='server-info',
|
||||
caption=logo_sprite_path,
|
||||
tooltip='Basic info about the current server',
|
||||
draw=function(self,frame)
|
||||
frame.caption = ''
|
||||
local info = Sync.info
|
||||
frame = frame.add{type='flow',direction='vertical'}
|
||||
local h_flow = frame.add{type='flow'}
|
||||
h_flow.add{type='sprite',sprite=logo_sprite_path}
|
||||
local v_flow = h_flow.add{type='flow',direction='vertical'}
|
||||
h_flow.add{type='sprite',sprite=logo_sprite_path}
|
||||
local _flow = v_flow.add{type='flow'}
|
||||
label_format(v_flow.add{
|
||||
type='label',
|
||||
caption=info.server_description,style='description_label'
|
||||
},412)
|
||||
Gui.bar(_flow,110)
|
||||
label_format(_flow.add{
|
||||
type='label',
|
||||
caption='Welcome To '..info.server_name,
|
||||
style='caption_label'
|
||||
},180)
|
||||
Gui.bar(_flow,110)
|
||||
Gui.bar(frame,600)
|
||||
local _frame = frame
|
||||
frame = frame.add{
|
||||
type='frame',
|
||||
direction='vertical',
|
||||
style='image_frame'
|
||||
}
|
||||
frame.style.width = 600
|
||||
local text_flow = frame.add{type='flow',direction='vertical'}
|
||||
local button_flow = frame.add{type='table',column_count=3}
|
||||
for _,element in pairs(table.deepcopy(Sync_gui_functions)) do
|
||||
local _type = table.remove(element,1)
|
||||
if _type == 'function' then
|
||||
local success, err = pcall(table.remove(element,1),frame.player_index,frame,unpack(element))
|
||||
if not success then error(err) else
|
||||
if is_type(err,'table') then
|
||||
if element.draw then element:draw(button_flow).style.width = 195
|
||||
else label_format(text_flow.add{type='label',caption=err},585) end
|
||||
else label_format(text_flow.add{type='label',caption=tostring(err)},585) end
|
||||
end
|
||||
elseif _type == 'gui' then element[1]:draw(button_flow).style.width = 195
|
||||
elseif _type == 'string' then label_format(text_flow.add{type='label',caption=tostring(element[1])},585)
|
||||
elseif _type == 'table' then label_format(text_flow.add{type='label',caption=element[1]},585) end
|
||||
end
|
||||
_frame.add{
|
||||
type='label',
|
||||
caption='Press Ecs or E to close; this is only visible once!',
|
||||
style='fake_disabled_label'
|
||||
}.style.font='default-small'
|
||||
end}
|
||||
|
||||
Event.add(defines.events.on_gui_click,function(event)
|
||||
local element = event.element
|
||||
if element and element.valid and element.caption and element.caption == 'Press Ecs or E to close; this is only visible once!' then
|
||||
Gui.center.clear(event)
|
||||
end
|
||||
end)
|
||||
|
||||
Event.add(defines.events.on_player_joined_game,function(event) Sync.info_gui(event) end)
|
||||
BIN
old/modules/ExpGamingCore/Sync/src/logo.png
Normal file
BIN
old/modules/ExpGamingCore/Sync/src/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 16 KiB |
Reference in New Issue
Block a user