world/Reboot refactor (#15268)

* world/Reboot refactor

* Re adds noises

* Im being punished by my own CI!
This commit is contained in:
AffectedArc07
2021-01-15 13:03:08 -05:00
committed by GitHub
parent 56423a0049
commit 2f6b0a9a0f
7 changed files with 104 additions and 49 deletions
+39 -2
View File
@@ -59,6 +59,8 @@ SUBSYSTEM_DEF(ticker)
var/mode_result = "undefined"
/// Server end state (Did we end properly or reboot or nuke or what)
var/end_state = "undefined"
/// Time the real reboot kicks in
var/real_reboot_time = 0
/datum/controller/subsystem/ticker/Initialize()
login_music = pick(\
@@ -128,9 +130,9 @@ SUBSYSTEM_DEF(ticker)
spawn(50)
if(mode.station_was_nuked)
world.Reboot("Station destroyed by Nuclear Device.", "nuke")
reboot_helper("Station destroyed by Nuclear Device.", "nuke")
else
world.Reboot("Round ended.", "proper completion")
reboot_helper("Round ended.", "proper completion")
/datum/controller/subsystem/ticker/proc/setup()
cultdat = setupcult()
@@ -541,3 +543,38 @@ SUBSYSTEM_DEF(ticker)
var/datum/trade_destination/D = new loc_type
GLOB.weighted_randomevent_locations[D] = D.viable_random_events.len
GLOB.weighted_mundaneevent_locations[D] = D.viable_mundane_events.len
// Easy handler to make rebooting the world not a massive sleep in world/Reboot()
/datum/controller/subsystem/ticker/proc/reboot_helper(reason, end_string, delay)
// Admins delayed round end. Just alert and dont bother with anything else.
if(delay_end)
to_chat(world, "<span class='boldannounce'>An admin has delayed the round end.</span>")
return
if(!isnull(delay))
// Delay time was present. Use that.
delay = max(0, delay)
else
// Use default restart timeout
delay = restart_timeout
to_chat(world, "<span class='boldannounce'>Rebooting world in [delay/10] [delay > 10 ? "seconds" : "second"]. [reason]</span>")
real_reboot_time = world.time + delay
UNTIL(world.time > real_reboot_time) // Hold it here
// And if we re-delayed, bail again
if(delay_end)
to_chat(world, "<span class='boldannounce'>Reboot was cancelled by an admin.</span>")
return
if(end_string)
end_state = end_string
// Play a haha funny noise
var/round_end_sound = pick(GLOB.round_end_sounds)
var/sound_length = GLOB.round_end_sounds[round_end_sound]
world << round_end_sound
sleep(sound_length)
world.Reboot()
+1 -1
View File
@@ -180,7 +180,7 @@ SUBSYSTEM_DEF(vote)
if(restart)
world.Reboot("Restart vote successful.", "restart vote")
SSticker.reboot_helper("Restart vote successful.", "restart vote")
return .
+1 -1
View File
@@ -382,7 +382,7 @@ GLOBAL_VAR(bomb_set)
//kinda shit but I couldn't get permission to do what I wanted to do.
if(!SSticker.mode.check_finished())//If the mode does not deal with the nuke going off so just reboot because everyone is stuck as is
world.Reboot("Station destroyed by Nuclear Device.", "nuke - unhandled ending")
SSticker.reboot_helper("Station destroyed by Nuclear Device.", "nuke - unhandled ending")
return
return
+16 -34
View File
@@ -102,9 +102,9 @@ GLOBAL_LIST_EMPTY(world_topic_handlers)
wth = new wth()
return wth.invoke(input)
/world/Reboot(var/reason, end_string, var/time)
/world/Reboot(reason, fast_track = FALSE)
//special reboot, do none of the normal stuff
if(reason == 1) // Do NOT change this to if(reason). You WILL break the entirety of world rebooting
if((reason == 1) || fast_track) // Do NOT change this to if(reason). You WILL break the entirety of world rebooting
if(usr)
if(!check_rights(R_SERVER))
message_admins("[key_name_admin(usr)] attempted to restart the server via the Profiler, without access.")
@@ -112,71 +112,53 @@ GLOBAL_LIST_EMPTY(world_topic_handlers)
return
message_admins("[key_name_admin(usr)] has requested an immediate world restart via client side debugging tools")
log_admin("[key_name(usr)] has requested an immediate world restart via client side debugging tools")
spawn(0)
to_chat(world, "<span class='boldannounce'>Rebooting world immediately due to host request</span>")
rustg_log_close_all() // Past this point, no logging procs can be used, at risk of data loss.
TgsReboot()
// Now handle a reboot
if(config && config.shutdown_on_reboot)
sleep(0)
if(GLOB.shutdown_shell_command)
shell(GLOB.shutdown_shell_command)
del(world)
TgsEndProcess() // We want to shutdown on reboot. That means kill our TGS process "gracefully", instead of the watchdog crying
return
else
TgsReboot() // Tell TGS we did a reboot
return ..(1)
var/delay
if(!isnull(time))
delay = max(0,time)
else
delay = SSticker.restart_timeout
if(SSticker.delay_end)
to_chat(world, "<span class='boldannounce'>An admin has delayed the round end.</span>")
return
to_chat(world, "<span class='boldannounce'>Rebooting world in [delay/10] [delay > 10 ? "seconds" : "second"]. [reason]</span>")
var/round_end_sound = pick(GLOB.round_end_sounds)
var/sound_length = GLOB.round_end_sounds[round_end_sound]
if(delay > sound_length) // If there's time, play the round-end sound before rebooting
spawn(delay - sound_length)
if(!SSticker.delay_end)
world << round_end_sound
sleep(delay)
if(SSticker.delay_end)
to_chat(world, "<span class='boldannounce'>Reboot was cancelled by an admin.</span>")
return
log_game("<span class='boldannounce'>Rebooting world. [reason]</span>")
//kick_clients_in_lobby("<span class='boldannounce'>The round came to an end with you in the lobby.</span>", 1)
if(end_string)
SSticker.end_state = end_string
Master.Shutdown() //run SS shutdowns
rustg_log_close_all() // Past this point, no logging procs can be used, at risk of data loss.
TgsReboot()
// If we got here, we are in a "normal" reboot
Master.Shutdown() // Shutdown subsystems
// If we were running unit tests, finish that run
#ifdef UNIT_TESTS
FinishTestRun()
return
#endif
// If we had an update or pending TM, set a 60 second timeout
var/secs_before_auto_reconnect = 10
if(GLOB.pending_server_update)
secs_before_auto_reconnect = 60
to_chat(world, "<span class='boldannounce'>Reboot will take a little longer, due to pending updates.</span>")
// Send the reboot banner to all players
for(var/client/C in GLOB.clients)
C << output(list2params(list(secs_before_auto_reconnect)), "browseroutput:reboot")
if(config.server) //if you set a server location in config.txt, it sends you there instead of trying to reconnect to the same world address. -- NeoFite
if(config.server) // If you set a server location in config.txt, it sends you there instead of trying to reconnect to the same world address. -- NeoFite
C << link("byond://[config.server]")
// And begin the real shutdown
rustg_log_close_all() // Past this point, no logging procs can be used, at risk of data loss.
if(config && config.shutdown_on_reboot)
sleep(0)
if(GLOB.shutdown_shell_command)
shell(GLOB.shutdown_shell_command)
rustg_log_close_all() // Past this point, no logging procs can be used, at risk of data loss.
del(world)
TgsEndProcess() // We want to shutdown on reboot. That means kill our TGS process "gracefully", instead of the watchdog crying
return
else
TgsReboot() // We did a normal reboot. Tell TGS we did a normal reboot.
..(0)
/world/proc/load_mode()
+44 -10
View File
@@ -363,16 +363,47 @@ GLOBAL_VAR_INIT(nologevent, 0)
if(!check_rights(R_SERVER))
return
var/delay = input("What delay should the restart have (in seconds)?", "Restart Delay", 5) as num|null
if(isnull(delay))
return
else
delay = delay * 10
message_admins("[key_name_admin(usr)] has initiated a server restart with a delay of [delay/10] seconds")
log_admin("[key_name(usr)] has initiated a server restart with a delay of [delay/10] seconds")
SSticker.delay_end = 0
SSblackbox.record_feedback("tally", "admin_verb", 1, "Reboot Server") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
world.Reboot("Initiated by [usr.client.holder.fakekey ? "Admin" : usr.key].", "admin reboot - by [usr.key] [usr.client.holder.fakekey ? "(stealth)" : ""]", delay)
// Give an extra popup if they are rebooting a live server
var/is_live_server = TRUE
if(usr.client.is_connecting_from_localhost())
is_live_server = FALSE
var/list/options = list("Regular Restart", "Hard Restart")
if(world.TgsAvailable()) // TGS lets you kill the process entirely
options += "Terminate Process (Kill and restart DD)"
var/result = input(usr, "Select reboot method", "World Reboot", options[1]) as null|anything in options
if(is_live_server)
if(alert(usr, "WARNING: THIS IS A LIVE SERVER, NOT A LOCAL TEST SERVER. DO YOU STILL WANT TO RESTART","This server is live","Restart","Cancel") != "Restart")
return FALSE
if(result)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Reboot World") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
var/init_by = "Initiated by [usr.client.holder.fakekey ? "Admin" : usr.key]."
switch(result)
if("Regular Restart")
var/delay = input("What delay should the restart have (in seconds)?", "Restart Delay", 5) as num|null
if(!delay)
return FALSE
// These are pasted each time so that they dont false send if reboot is cancelled
message_admins("[key_name_admin(usr)] has initiated a server restart of type [result]")
log_admin("[key_name(usr)] has initiated a server restart of type [result]")
SSticker.delay_end = FALSE // We arent delayed anymore
SSticker.reboot_helper(init_by, "admin reboot - by [usr.key] [usr.client.holder.fakekey ? "(stealth)" : ""]", delay * 10)
if("Hard Restart")
message_admins("[key_name_admin(usr)] has initiated a server restart of type [result]")
log_admin("[key_name(usr)] has initiated a server restart of type [result]")
world.Reboot(fast_track = TRUE)
if("Terminate Process (Kill and restart DD)")
message_admins("[key_name_admin(usr)] has initiated a server restart of type [result]")
log_admin("[key_name(usr)] has initiated a server restart of type [result]")
world.TgsEndProcess() // Just nuke the entire process if we are royally fucked
/datum/admins/proc/end_round()
set category = "Server"
@@ -576,6 +607,8 @@ GLOBAL_VAR_INIT(nologevent, 0)
SSticker.delay_end = !SSticker.delay_end
log_admin("[key_name(usr)] [SSticker.delay_end ? "delayed the round end" : "has made the round end normally"].")
message_admins("[key_name(usr)] [SSticker.delay_end ? "delayed the round end" : "has made the round end normally"].", 1)
if(SSticker.delay_end)
SSticker.real_reboot_time = 0 // Immediately show the "Admin delayed round end" message
return //alert("Round end delayed", null, null, null, null, null)
if(SSticker.ticker_going)
SSticker.ticker_going = FALSE
@@ -883,3 +916,4 @@ GLOBAL_VAR_INIT(gamma_ship_location, 1) // 0 = station , 1 = space
continue
result[1]++
return result
+2
View File
@@ -317,6 +317,8 @@
SSticker.delay_end = !SSticker.delay_end
log_admin("[key_name(usr)] [SSticker.delay_end ? "delayed the round end" : "has made the round end normally"].")
message_admins("<span class='notice'>[key_name_admin(usr)] [SSticker.delay_end ? "delayed the round end" : "has made the round end normally"].</span>", 1)
if(SSticker.delay_end)
SSticker.real_reboot_time = 0 // If they set this at round end, show the "Reboot was cancelled by an admin" message instantly
href_list["secretsadmin"] = "check_antagonist"
else if(href_list["simplemake"])
+1 -1
View File
@@ -70,7 +70,7 @@ GLOBAL_VAR(test_log)
CHECK_TICK
world.Reboot("Unit Test Reboot", "tests ended", 0)
SSticker.reboot_helper("Unit Test Reboot", "tests ended", 0)
// OTHER MISC PROCS RELATED TO UNIT TESTS //