SSinstancing (I need to test this with 2 machines)

This commit is contained in:
AffectedArc07
2021-08-17 14:05:46 +01:00
parent 583dffcad4
commit e19a83f9be
9 changed files with 186 additions and 26 deletions
@@ -24,6 +24,8 @@ GLOBAL_DATUM_INIT(configuration, /datum/server_configuration, new())
var/datum/configuration_section/gateway_configuration/gateway
/// Holder for the general configuration datum
var/datum/configuration_section/general_configuration/general
/// Holder for the instancing configuration datum
var/datum/configuration_section/instancing_configuration/instancing
/// Holder for the IPIntel configuration datum
var/datum/configuration_section/ipintel_configuration/ipintel
/// Holder for the job configuration datum
@@ -79,6 +81,7 @@ GLOBAL_DATUM_INIT(configuration, /datum/server_configuration, new())
gamemode = new()
gateway = new()
general = new()
instancing = new()
ipintel = new()
jobs = new()
logging = new()
@@ -98,6 +101,15 @@ GLOBAL_DATUM_INIT(configuration, /datum/server_configuration, new())
raw_data = json_decode(raw_json)
// Now pass through all our stuff
load_all_sections()
// Clear our list to save RAM
raw_data = list()
// And report the load
DIRECT_OUTPUT(world.log, "Config loaded in [stop_watch(start)]s")
/datum/server_configuration/proc/load_all_sections()
safe_load(admin, "admin_configuration")
safe_load(afk, "afk_configuration")
safe_load(custom_sprites, "custom_sprites_configuration")
@@ -107,6 +119,7 @@ GLOBAL_DATUM_INIT(configuration, /datum/server_configuration, new())
safe_load(gamemode, "gamemode_configuration")
safe_load(gateway, "gateway_configuration")
safe_load(general, "general_configuration")
safe_load(instancing, "instancing_configuration")
safe_load(ipintel, "ipintel_configuration")
safe_load(jobs, "job_configuration")
safe_load(logging, "logging_configuration")
@@ -118,12 +131,6 @@ GLOBAL_DATUM_INIT(configuration, /datum/server_configuration, new())
safe_load(url, "url_configuration")
safe_load(vote, "voting_configuration")
// Clear our list to save RAM
raw_data = list()
// And report the load
DIRECT_OUTPUT(world.log, "Config loaded in [stop_watch(start)]s")
// Proc to load up instance-specific overrides
/datum/server_configuration/proc/load_overrides()
var/override_file = "config/overrides_[world.port].toml"
@@ -140,25 +147,7 @@ GLOBAL_DATUM_INIT(configuration, /datum/server_configuration, new())
// Now safely load our overrides.
// Due to the nature of config wrappers, only vars that exist in the config file are applied to the config datums.
// This means that an override missing a key doesnt null it out from the main server
safe_load(admin, "admin_configuration")
safe_load(afk, "afk_configuration")
safe_load(custom_sprites, "custom_sprites_configuration")
safe_load(database, "database_configuration")
safe_load(discord, "discord_configuration")
safe_load(event, "event_configuration")
safe_load(gamemode, "gamemode_configuration")
safe_load(gateway, "gateway_configuration")
safe_load(general, "general_configuration")
safe_load(ipintel, "ipintel_configuration")
safe_load(jobs, "job_configuration")
safe_load(logging, "logging_configuration")
safe_load(mc, "mc_configuration")
safe_load(movement, "movement_configuration")
safe_load(overflow, "overflow_configuration")
safe_load(ruins, "ruin_configuration")
safe_load(system, "system_configuration")
safe_load(url, "url_configuration")
safe_load(vote, "voting_configuration")
load_all_sections()
// Clear our list to save RAM
raw_data = list()
@@ -0,0 +1,20 @@
/// Config holder for stuff relating to multi-server instances
/datum/configuration_section/instancing_configuration
/// ID of this specific server
var/server_id = "paradise_main"
/// List of all peer servers
var/list/datum/peer_server/peers = list()
/datum/configuration_section/instancing_configuration/load_data(list/data)
// Use the load wrappers here. That way the default isnt made 'null' if you comment out the config line
CONFIG_LOAD_STR(server_id, data["server_id"])
if(islist(data["peer_servers"]))
for(var/list/server in data["peer_servers"])
if(server["server_port"] == world.port) // Skip our own instance
continue
var/datum/peer_server/PS = new()
PS.internal_ip = server["internal_ip"]
PS.server_port = server["server_port"]
PS.commskey = server["commskey"]
peers.Add(PS)
+63
View File
@@ -0,0 +1,63 @@
SUBSYSTEM_DEF(instancing)
name = "Instancing"
runlevels = RUNLEVEL_INIT | RUNLEVEL_LOBBY | RUNLEVEL_SETUP | RUNLEVEL_GAME | RUNLEVEL_POSTGAME
/// Have we announced startup yet
var/startup_announced = FALSE
/// Is a check currently running?
var/check_running = FALSE
/datum/controller/subsystem/instancing/Initialize(start_timeofday)
// Do an initial peer check
check_peers()
return ..()
/datum/controller/subsystem/instancing/fire(resumed)
check_peers()
/**
* Refreshes all peers on the server
*
* Called periodically during fire() as well as when a new peer reports itself as online
* Only one instance of this proc may run at a time
*
*/
/datum/controller/subsystem/instancing/proc/check_peers()
set waitfor = FALSE // This has sleeps if it cant topic so we dont want to bog things down
if(check_running)
return
check_running = TRUE // Dont allow multiple of these
// A NOTE TO ANYONE ELSE WHO LOOKS AT THIS
// THESE TIMINGS ARE A FUCKING NIGHTMARE AND YOU WILL NEED DEBUG LOGGING TO TEST THEM
// DO NOT FUCK WITH THE TIMINGS -aa
for(var/datum/peer_server/PS in GLOB.configuration.instancing.peers)
// If the server hasnt been discovered and its been more than 5 minutes
if((!PS.discovered && PS.last_operation_time + 5 MINUTES > world.time))
continue
if(PS.last_operation_time + 1 MINUTES > world.time)
continue // Only run main operations once every minute anyway
var/peer_response = world.Export("byond://[PS.internal_ip]:[PS.server_port]?server_discovery&key=[PS.commskey]")
if(!peer_response)
PS.online = FALSE // Peer is offline
PS.last_operation_time = world.time
continue
// We got a response
PS.discovered = TRUE
PS.online = TRUE
var/list/peer_data = json_decode(peer_response)
PS.external_ip = peer_data["external_ip"]
PS.server_id = peer_data["server_id"]
PS.server_name = peer_data["server_name"]
PS.playercount = peer_data["playercount"]
PS.last_operation_time = world.time
check_running = FALSE
/datum/controller/subsystem/instancing/proc/message_all_peers(include_offline = FALSE)
return