Skip to content
This repository was archived by the owner on Sep 8, 2022. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions code/__DEFINES/MC.dm
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,17 @@
}\
/datum/controller/subsystem/timer/##X

<<<<<<< HEAD
=======
#define MOVEMENT_SUBSYSTEM_DEF(X) GLOBAL_REAL(SS##X, /datum/controller/subsystem/movement/##X);\
/datum/controller/subsystem/movement/##X/New(){\
NEW_SS_GLOBAL(SS##X);\
PreInit();\
ss_id="movement_[#X]";\
}\
/datum/controller/subsystem/movement/##X

>>>>>>> bdeb199b49... Revert "Brings our MC up to date with TG (#7285)" (#7597)
#define PROCESSING_SUBSYSTEM_DEF(X) GLOBAL_REAL(SS##X, /datum/controller/subsystem/processing/##X);\
/datum/controller/subsystem/processing/##X/New(){\
NEW_SS_GLOBAL(SS##X);\
Expand Down
55 changes: 55 additions & 0 deletions code/controllers/failsafe.dm
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,61 @@ GLOBAL_REAL(Failsafe, /datum/controller/failsafe)
defcon = 5
sleep(initial(processing_interval))

<<<<<<< HEAD
=======
//Emergency loop used when Master got deleted or the main loop exited while Defcon == 0
//Loop is driven externally so runtimes only cancel the current recovery attempt
/datum/controller/failsafe/proc/emergency_loop()
//The code in this proc should be kept as simple as possible, anything complicated like to_chat might rely on master existing and runtime
//The goal should always be to get a new Master up and running before anything else
. = -1
switch (defcon) //The lower defcon goes the harder we try to fix the MC
if (2 to 3) //Try to normally recreate the MC two times
. = Recreate_MC()
if (1) //Delete the old MC first so we don't transfer any info, in case that caused any issues
del(Master)
. = Recreate_MC()

if (. == 1) //We were able to create a new master
to_chat_immediate(world, "<span class='boldannounce'>Master Controller failure detected. Attempting recovery.</span>\n<span class='danger'>Things may freeze up for a minute or two (or break entirely).</span>")
master_iteration = 0
SSticker.Recover() //Recover the ticket system so the Masters runlevel gets set
Master.Initialize(10, FALSE, TRUE) //Need to manually start the MC, normally world.new would do this
to_chat(GLOB.admins, "<span class='adminnotice'>Failsafe recovered MC while in emergency state [defcon_pretty()]</span>")
else
log_game("FailSafe: Failsafe in emergency state and was unable to recreate MC while in defcon state [defcon_pretty()].")
message_admins("<span class='boldannounce'>Failsafe in emergency state and master down, trying to recreate MC while in defcon level [defcon_pretty()] failed.</span>")

///Recreate all SSs which will still cause data survive due to Recover(), the new Master will then find and take them from global.vars
/proc/recover_all_SS_and_recreate_master()
del(Master)
var/list/subsytem_types = subtypesof(/datum/controller/subsystem)
sortTim(subsytem_types, /proc/cmp_subsystem_init)
for(var/I in subsytem_types)
new I
. = Recreate_MC()
if (. == 1) //We were able to create a new master
SSticker.Recover() //Recover the ticket system so the Masters runlevel gets set
Master.Initialize(10, FALSE, TRUE) //Need to manually start the MC, normally world.new would do this
to_chat(GLOB.admins, "<span class='adminnotice'>MC successfully recreated after recovering all subsystems!</span>")
else
message_admins("<span class='boldannounce'>Failed to create new MC!</span>")

///Delete all existing SS to basically start over
/proc/delete_all_SS_and_recreate_master()
del(Master)
for(var/global_var in global.vars)
if (istype(global.vars[global_var], /datum/controller/subsystem))
del(global.vars[global_var])
. = Recreate_MC()
if (. == 1) //We were able to create a new master
SSticker.Recover() //Recover the ticket system so the Masters runlevel gets set
Master.Initialize(10, FALSE, TRUE) //Need to manually start the MC, normally world.new would do this
to_chat(GLOB.admins, "<span class='adminnotice'>MC successfully recreated after deleting and recreating all subsystems!</span>")
else
message_admins("<span class='boldannounce'>Failed to create new MC!</span>")

>>>>>>> bdeb199b49... Revert "Brings our MC up to date with TG (#7285)" (#7597)
/datum/controller/failsafe/proc/defcon_pretty()
return defcon

Expand Down
6 changes: 6 additions & 0 deletions code/controllers/globals.dm
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,14 @@ GLOBAL_REAL(GLOB, /datum/controller/global_vars)

Initialize()

<<<<<<< HEAD
/datum/controller/global_vars/Destroy()
//fuck off kevinz
=======
/datum/controller/global_vars/Destroy(force)
// This is done to prevent an exploit where admins can get around protected vars
SHOULD_CALL_PARENT(0)
>>>>>>> bdeb199b49... Revert "Brings our MC up to date with TG (#7285)" (#7597)
return QDEL_HINT_IWILLGC

/datum/controller/global_vars/stat_entry()
Expand Down
23 changes: 23 additions & 0 deletions code/controllers/master.dm
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,30 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
Recover()
qdel(Master)
else
<<<<<<< HEAD
var/list/subsytem_types = subtypesof(/datum/controller/subsystem)
sortTim(subsytem_types, /proc/cmp_subsystem_init)
for(var/I in subsytem_types)
_subsystems += new I
Master = src
=======
//Code used for first master on game boot or if existing master got deleted
Master = src
var/list/subsystem_types = subtypesof(/datum/controller/subsystem)
sortTim(subsystem_types, /proc/cmp_subsystem_init)
//Find any abandoned subsystem from the previous master (if there was any)
var/list/existing_subsystems = list()
for(var/global_var in global.vars)
if (istype(global.vars[global_var], /datum/controller/subsystem))
existing_subsystems += global.vars[global_var]
//Either init a new SS or if an existing one was found use that
for(var/I in subsystem_types)
var/ss_idx = existing_subsystems.Find(I)
if (ss_idx)
_subsystems += existing_subsystems[ss_idx]
else
_subsystems += new I
>>>>>>> bdeb199b49... Revert "Brings our MC up to date with TG (#7285)" (#7597)

if(!GLOB)
new /datum/controller/global_vars
Expand Down Expand Up @@ -192,7 +211,11 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
// Initialize subsystems.
current_ticklimit = CONFIG_GET(number/tick_limit_mc_init)
for (var/datum/controller/subsystem/SS in subsystems)
<<<<<<< HEAD
if (SS.flags & SS_NO_INIT)
=======
if (SS.flags & SS_NO_INIT || SS.initialized) //Don't init SSs with the correspondig flag or if they already are initialzized
>>>>>>> bdeb199b49... Revert "Brings our MC up to date with TG (#7285)" (#7597)
continue
SS.Initialize(REALTIMEOFDAY)
CHECK_TICK
Expand Down
5 changes: 5 additions & 0 deletions code/controllers/subsystem.dm
Original file line number Diff line number Diff line change
Expand Up @@ -222,8 +222,13 @@
//this is so the subsystem doesn't rapid fire to make up missed ticks causing more lag
if (var_value)
next_fire = world.time + wait
<<<<<<< HEAD
if ("queued_priority") //editing this breaks things.
return 0
=======
if (NAMEOF(src, queued_priority)) //editing this breaks things.
return FALSE
>>>>>>> bdeb199b49... Revert "Brings our MC up to date with TG (#7285)" (#7597)
. = ..()


Expand Down
4 changes: 4 additions & 0 deletions code/game/objects/structures/traps.dm
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,11 @@
// Makes the trap visible, and starts the cooldown until it's
// able to be triggered again.
visible_message(flare_message)
<<<<<<< HEAD
if(sparks)
=======
if(sparks && Master.current_runlevel)
>>>>>>> bdeb199b49... Revert "Brings our MC up to date with TG (#7285)" (#7597)
spark_system.start()
alpha = 200
last_trigger = world.time
Expand Down
8 changes: 8 additions & 0 deletions code/modules/power/lighting.dm
Original file line number Diff line number Diff line change
Expand Up @@ -422,7 +422,11 @@
update()

/obj/machinery/light/proc/broken_sparks(start_only=FALSE)
<<<<<<< HEAD
if(!QDELETED(src) && status == LIGHT_BROKEN && has_power())
=======
if(!QDELETED(src) && status == LIGHT_BROKEN && has_power() && Master.current_runlevel)
>>>>>>> bdeb199b49... Revert "Brings our MC up to date with TG (#7285)" (#7597)
if(!start_only)
do_sparks(3, TRUE, src)
var/delay = rand(BROKEN_SPARKS_MIN, BROKEN_SPARKS_MAX)
Expand Down Expand Up @@ -754,7 +758,11 @@
if(status == LIGHT_EMPTY || status == LIGHT_BROKEN)
return

<<<<<<< HEAD
if(!skip_sound_and_sparks)
=======
if(!skip_sound_and_sparks && Master.current_runlevel) //not completly sure disabling this during initialize is needed but then again there are broken lights after initialize
>>>>>>> bdeb199b49... Revert "Brings our MC up to date with TG (#7285)" (#7597)
if(status == LIGHT_OK || status == LIGHT_BURNED)
playsound(src.loc, 'sound/effects/glasshit.ogg', 75, 1)
if(on)
Expand Down
4 changes: 4 additions & 0 deletions code/modules/tgchat/to_chat.dm
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,11 @@
// FIXME: These flags are now pointless and have no effect
handle_whitespace = TRUE,
trailing_newline = TRUE)
<<<<<<< HEAD
if(Master.current_runlevel == RUNLEVEL_INIT || !SSchat?.initialized)
=======
if(isnull(Master) || Master.current_runlevel == RUNLEVEL_INIT || !SSchat?.initialized)
>>>>>>> bdeb199b49... Revert "Brings our MC up to date with TG (#7285)" (#7597)
to_chat_immediate(target, html, type, text)
return
if(!target || (!html && !text))
Expand Down