[MIRROR] Drastic Lag Mitigation Subsystem: SSlag_switch (#6786)

* Drastic Lag Mitigation Subsystem: SSlag_switch (#59717)

Requested by oranges and inspired by the upcoming event. A new subsyetem, non-processing (for now), aimed at providing some toggle switches that can be flipped as a last ditch effort to save some CPU cycles by sacrificing some non-critical mechanics. Below you can see each individual toggle.

Screenshot of the admin panel:
image
Surely there are more opportunities for toggles I missed, but adding new ones is not very difficult at all.
Why It's Good For The Game

Better performance during extreme pop, I hope.
Changelog

cl
code: Introduces the Lag Switch subsystem for when a smoother experience is worth trading a few bells and whistles for. Performance enhancement measures can be togged by admins with the Show Lag Switches admin verb or enabled automatically at a pop amount set via config.
config: Added a new config var: number/auto_lag_switch_pop

* Drastic Lag Mitigation Subsystem: SSlag_switch

* mirrored the changes to the modular file

Co-authored-by: Wayland-Smithy <64715958+Wayland-Smithy@users.noreply.github.com>
Co-authored-by: Useroth <37159550+Useroth@users.noreply.github.com>
This commit is contained in:
SkyratBot
2021-07-08 02:24:16 +01:00
committed by GitHub
parent 694032f53f
commit df651808d4
29 changed files with 315 additions and 29 deletions
+37 -9
View File
@@ -590,15 +590,12 @@
set category = "Server"
set desc="People can't enter"
set name="Toggle Entering"
GLOB.enter_allowed = !( GLOB.enter_allowed )
if (!( GLOB.enter_allowed ))
to_chat(world, "<B>New players may no longer enter the game.</B>", confidential = TRUE)
else
to_chat(world, "<B>New players may now enter the game.</B>", confidential = TRUE)
log_admin("[key_name(usr)] toggled new player game entering.")
message_admins(span_adminnotice("[key_name_admin(usr)] toggled new player game entering."))
world.update_status()
SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle Entering", "[GLOB.enter_allowed ? "Enabled" : "Disabled"]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
if(!SSlag_switch.initialized)
return
SSlag_switch.set_measure(DISABLE_NON_OBSJOBS, !SSlag_switch.measures[DISABLE_NON_OBSJOBS])
log_admin("[key_name(usr)] toggled new player game entering. Lag Switch at index ([DISABLE_NON_OBSJOBS])")
message_admins("[key_name_admin(usr)] toggled new player game entering [SSlag_switch.measures[DISABLE_NON_OBSJOBS] ? "OFF" : "ON"].")
SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle Entering", "[!SSlag_switch.measures[DISABLE_NON_OBSJOBS] ? "Enabled" : "Disabled"]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/datum/admins/proc/toggleAI()
set category = "Server"
@@ -828,6 +825,9 @@
tgui_alert(usr, "You cannot manage jobs before the job subsystem is initialized!")
return
if(SSlag_switch.measures[DISABLE_NON_OBSJOBS])
dat += "<div class='notice red' style='font-size: 125%'>Lag Switch \"Disable non-observer late joining\" is ON. Only Observers may join!</div>"
dat += "<table>"
for(var/j in SSjob.occupations)
@@ -960,3 +960,31 @@
"Admin login: [key_name(src)]")
if(string)
message_admins("[string]")
/datum/admins/proc/show_lag_switch_panel()
set category = "Admin.Game"
set name = "Show Lag Switches"
set desc="Display the controls for drastic lag mitigation measures."
if(!SSlag_switch.initialized)
to_chat(usr, span_notice("The Lag Switch subsystem has not yet been initialized."))
return
if(!check_rights())
return
var/list/dat = list("<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'><title>Lag Switches</title></head><body><h2><B>Lag (Reduction) Switches</B></h2>")
dat += "Automatic Trigger: <a href='?_src_=holder;[HrefToken()];change_lag_switch_option=TOGGLE_AUTO'><b>[SSlag_switch.auto_switch ? "On" : "Off"]</b></a><br/>"
dat += "Population Threshold: <a href='?_src_=holder;[HrefToken()];change_lag_switch_option=NUM'><b>[SSlag_switch.trigger_pop]</b></a><br/>"
dat += "Slowmode Cooldown (toggle On/Off below): <a href='?_src_=holder;[HrefToken()];change_lag_switch_option=SLOWCOOL'><b>[SSlag_switch.slowmode_cooldown/10] seconds</b></a><br/>"
dat += "<br/><b>SET ALL MEASURES: <a href='?_src_=holder;[HrefToken()];change_lag_switch=ALL_ON'>ON</a> | <a href='?_src_=holder;[HrefToken()];change_lag_switch=ALL_OFF'>OFF</a></b><br/>"
dat += "<br/>Disable ghosts zoom and t-ray verbs (except staff): <a href='?_src_=holder;[HrefToken()];change_lag_switch=[DISABLE_GHOST_ZOOM_TRAY]'><b>[SSlag_switch.measures[DISABLE_GHOST_ZOOM_TRAY] ? "On" : "Off"]</b></a><br/>"
dat += "Disable late joining: <a href='?_src_=holder;[HrefToken()];change_lag_switch=[DISABLE_NON_OBSJOBS]'><b>[SSlag_switch.measures[DISABLE_NON_OBSJOBS] ? "On" : "Off"]</b></a><br/>"
dat += "<br/>============! MAD GHOSTS ZONE !============<br/>"
dat += "Disable deadmob keyLoop (except staff, informs dchat): <a href='?_src_=holder;[HrefToken()];change_lag_switch=[DISABLE_DEAD_KEYLOOP]'><b>[SSlag_switch.measures[DISABLE_DEAD_KEYLOOP] ? "On" : "Off"]</b></a><br/>"
dat += "==========================================<br/>"
dat += "<br/><b>Measures below can be bypassed with a <abbr title='TRAIT_BYPASS_MEASURES'><u>special trait</u></abbr></b><br/>"
dat += "Slowmode say verb (informs world): <a href='?_src_=holder;[HrefToken()];change_lag_switch=[SLOWMODE_SAY]'><b>[SSlag_switch.measures[SLOWMODE_SAY] ? "On" : "Off"]</b></a><br/>"
dat += "Disable runechat: <a href='?_src_=holder;[HrefToken()];change_lag_switch=[DISABLE_RUNECHAT]'><b>[SSlag_switch.measures[DISABLE_RUNECHAT] ? "On" : "Off"]</b></a> - <span style='font-size:80%'>trait applies to speaker</span><br/>"
dat += "Disable examine icons: <a href='?_src_=holder;[HrefToken()];change_lag_switch=[DISABLE_USR_ICON2HTML]'><b>[SSlag_switch.measures[DISABLE_USR_ICON2HTML] ? "On" : "Off"]</b></a> - <span style='font-size:80%'>trait applies to examiner</span><br/>"
dat += "</body></html>"
usr << browse(dat.Join(), "window=lag_switch_panel;size=420x420")
+1
View File
@@ -31,6 +31,7 @@ GLOBAL_PROTECT(admin_verbs_admin)
return list(
/client/proc/invisimin, /*allows our mob to go invisible/visible*/
// /datum/admins/proc/show_traitor_panel, /*interface which shows a mob's mind*/ -Removed due to rare practical use. Moved to debug verbs ~Errorage
/datum/admins/proc/show_lag_switch_panel,
/datum/admins/proc/show_player_panel, /*shows an interface for individual players, with various links (links require additional flags*/
/datum/verbs/menu/Admin/verb/playerpanel,
/client/proc/game_panel, /*game panel, allows to change game-mode etc*/
+52
View File
@@ -1721,6 +1721,58 @@
GLOB.station_goals += G
modify_goals()
else if(href_list["change_lag_switch"])
if(!check_rights(R_ADMIN))
return
switch(href_list["change_lag_switch"])
if("ALL_ON")
SSlag_switch.set_all_measures(TRUE)
log_admin("[key_name(usr)] turned all Lag Switch measures ON.")
message_admins("[key_name_admin(usr)] turned all Lag Switch measures ON.")
if("ALL_OFF")
SSlag_switch.set_all_measures(FALSE)
log_admin("[key_name(usr)] turned all Lag Switch measures OFF.")
message_admins("[key_name_admin(usr)] turned all Lag Switch measures OFF.")
else
var/switch_index = text2num(href_list["change_lag_switch"])
if(!SSlag_switch.set_measure(switch_index, !LAZYACCESS(SSlag_switch.measures, switch_index)))
to_chat(src, span_danger("Something went wrong when trying to toggle that Lag Switch. Check runtimes for more info."), confidential = TRUE)
else
log_admin("[key_name(usr)] turned a Lag Switch measure at index ([switch_index]) [LAZYACCESS(SSlag_switch.measures, switch_index) ? "ON" : "OFF"]")
message_admins("[key_name_admin(usr)] turned a Lag Switch measure [LAZYACCESS(SSlag_switch.measures, switch_index) ? "ON" : "OFF"]")
src.show_lag_switch_panel()
else if(href_list["change_lag_switch_option"])
if(!check_rights(R_ADMIN))
return
switch(href_list["change_lag_switch_option"])
if("CANCEL")
if(SSlag_switch.cancel_auto_enable_in_progress())
log_admin("[key_name(usr)] canceled the automatic Lag Switch activation in progress.")
message_admins("[key_name_admin(usr)] canceled the automatic Lag Switch activation in progress.")
return // return here to avoid (re)rendering the panel for this case
if("TOGGLE_AUTO")
SSlag_switch.toggle_auto_enable()
log_admin("[key_name(usr)] toggled automatic Lag Switch activation [SSlag_switch.auto_switch ? "ON" : "OFF"].")
message_admins("[key_name_admin(usr)] toggled automatic Lag Switch activation [SSlag_switch.auto_switch ? "ON" : "OFF"].")
if("NUM")
var/new_num = input("Enter new threshold value:", "Num") as null|num
if(!isnull(new_num))
SSlag_switch.trigger_pop = new_num
log_admin("[key_name(usr)] set the Lag Switch automatic trigger pop to [new_num].")
message_admins("[key_name_admin(usr)] set the Lag Switch automatic trigger pop to [new_num].")
if("SLOWCOOL")
var/new_num = input("Enter new cooldown in seconds:", "Num") as null|num
if(!isnull(new_num))
SSlag_switch.change_slowmode_cooldown(new_num)
log_admin("[key_name(usr)] set the Lag Switch slowmode cooldown to [new_num] seconds.")
message_admins("[key_name_admin(usr)] set the Lag Switch slowmode cooldown to [new_num] seconds.")
src.show_lag_switch_panel()
else if(href_list["viewruntime"])
var/datum/error_viewer/error_viewer = locate(href_list["viewruntime"])
if(!istype(error_viewer))
@@ -475,7 +475,7 @@ GLOBAL_VAR(station_nuke_source)
SSticker.roundend_check_paused = FALSE
return
GLOB.enter_allowed = FALSE
SSlag_switch.set_measure(DISABLE_NON_OBSJOBS, TRUE)
var/off_station = 0
var/turf/bomb_location = get_turf(src)
+2
View File
@@ -32,6 +32,8 @@
var/externalreplyamount = 0
///When was the last time we warned them about not cryoing without an ahelp, set to -5 minutes so that rounstart cryo still warns
COOLDOWN_DECLARE(cryo_warned)
///Tracks say() usage for ic/dchat while slowmode is enabled
COOLDOWN_DECLARE(say_slowmode)
/////////
//OTHER//
/////////
+1
View File
@@ -452,6 +452,7 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
view_size.setZoomMode()
fit_viewport()
Master.UpdateTickRate()
SEND_GLOBAL_SIGNAL(COMSIG_GLOB_CLIENT_CONNECT, src)
//////////////
//DISCONNECT//
@@ -182,7 +182,7 @@
to_chat(usr, span_danger("The round is either not ready, or has already finished..."))
return
if(!GLOB.enter_allowed)
if(SSlag_switch.measures[DISABLE_NON_OBSJOBS])
to_chat(usr, span_notice("There is an administrative lock on entering the game!"))
return
@@ -215,7 +215,10 @@
ready = PLAYER_NOT_READY
return FALSE
var/this_is_like_playing_right = tgui_alert(usr, "Are you sure you wish to observe? You will not be able to play this round!","Player Setup",list("Yes","No"))
var/less_input_message
if(SSlag_switch.measures[DISABLE_DEAD_KEYLOOP])
less_input_message = " - Notice: Observer freelook is currently disabled."
var/this_is_like_playing_right = tgui_alert(usr, "Are you sure you wish to observe? You will not be able to play this round![less_input_message]","Player Setup",list("Yes","No"))
if(QDELETED(src) || !src.client || this_is_like_playing_right != "Yes")
ready = PLAYER_NOT_READY
@@ -296,10 +299,6 @@
tgui_alert(usr, get_job_unavailable_error_message(error, rank))
return FALSE
if(SSticker.late_join_disabled)
tgui_alert(usr, "An administrator has disabled late join spawning.")
return FALSE
var/arrivals_docked = TRUE
if(SSshuttle.arrivals)
close_spawn_windows() //In case we get held up
@@ -389,7 +388,10 @@
/mob/dead/new_player/proc/LateChoices()
var/list/dat = list("<div class='notice'>Round Duration: [DisplayTimeText(world.time - SSticker.round_start_time)]</div>")
var/list/dat = list()
if(SSlag_switch.measures[DISABLE_NON_OBSJOBS])
dat += "<div class='notice red' style='font-size: 125%'>Only Observers may join at this time.</div><br>"
dat += "<div class='notice'>Round Duration: [DisplayTimeText(world.time - SSticker.round_start_time)]</div>"
if(SSshuttle.emergency)
switch(SSshuttle.emergency.mode)
if(SHUTTLE_ESCAPE)
@@ -370,6 +370,8 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
return
client.view_size.setDefault(getScreenSize(client.prefs.widescreenpref))//Let's reset so people can't become allseeing gods
SStgui.on_transfer(src, mind.current) // Transfer NanoUIs.
if(mind.current.stat == DEAD && SSlag_switch.measures[DISABLE_DEAD_KEYLOOP])
to_chat(src, span_warning("To leave your body again use the Ghost verb."))
mind.current.key = key
mind.current.client.init_verbs()
return TRUE
@@ -525,6 +527,10 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
set name = "View Range"
set desc = "Change your view range."
if(SSlag_switch.measures[DISABLE_GHOST_ZOOM_TRAY] && !client?.holder)
to_chat(usr, span_notice("That verb is currently globally disabled."))
return
var/max_view = client.prefs.unlock_content ? GHOST_MAX_VIEW_RANGE_MEMBER : GHOST_MAX_VIEW_RANGE_DEFAULT
if(client.view_size.getView() == client.view_size.default)
var/list/views = list()
@@ -539,6 +545,11 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
/mob/dead/observer/verb/add_view_range(input as num)
set name = "Add View Range"
set hidden = TRUE
if(SSlag_switch.measures[DISABLE_GHOST_ZOOM_TRAY] && !client?.holder)
to_chat(usr, span_notice("That verb is currently globally disabled."))
return
var/max_view = client.prefs.unlock_content ? GHOST_MAX_VIEW_RANGE_MEMBER : GHOST_MAX_VIEW_RANGE_DEFAULT
if(input)
client.rescale_view(input, 0, ((max_view*2)+1) - 15)
@@ -959,6 +970,9 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
set desc = "Toggles a view of sub-floor objects"
var/static/t_ray_view = FALSE
if(SSlag_switch.measures[DISABLE_GHOST_ZOOM_TRAY] && !client?.holder && !t_ray_view)
to_chat(usr, span_notice("That verb is currently globally disabled."))
return
t_ray_view = !t_ray_view
var/list/t_ray_images = list()
+3
View File
@@ -76,6 +76,9 @@
var/turf/T = get_turf(src)
if(mind && mind.name && mind.active && !istype(T.loc, /area/ctf))
deadchat_broadcast(" has died at <b>[get_area_name(T)]</b>.", "<b>[mind.name]</b>", follow_target = src, turf_target = T, message_type=DEADCHAT_DEATHRATTLE)
if(SSlag_switch.measures[DISABLE_DEAD_KEYLOOP] && !client?.holder)
to_chat(src, span_deadsay(span_big("Observer freelook is disabled.\nPlease use Orbit, Teleport, and Jump to look around.")))
ghostize(TRUE)
if(mind)
mind.store_memory("Time of death: [tod]", 0)
set_drugginess(0)
+7 -1
View File
@@ -152,6 +152,12 @@ GLOBAL_LIST_INIT(message_modes_stat_limits, list(
say_dead(original_message)
return
if(client && SSlag_switch.measures[SLOWMODE_SAY] && !HAS_TRAIT(src, TRAIT_BYPASS_MEASURES) && !forced && src == usr)
if(!COOLDOWN_FINISHED(client, say_slowmode))
to_chat(src, span_warning("Message not sent due to slowmode. Please wait [SSlag_switch.slowmode_cooldown/10] seconds between messages.\n\"[message]\""))
return
COOLDOWN_START(client, say_slowmode, SSlag_switch.slowmode_cooldown)
if(!can_speak_basic(original_message, ignore_spam, forced))
return
@@ -349,7 +355,7 @@ GLOBAL_LIST_INIT(message_modes_stat_limits, list(
//speech bubble
var/list/speech_bubble_recipients = list()
for(var/mob/M in listening)
if(M.client && !M.client.prefs.chat_on_map)
if(M.client && (!M.client.prefs.chat_on_map || (SSlag_switch.measures[DISABLE_RUNECHAT] && !HAS_TRAIT(src, TRAIT_BYPASS_MEASURES))))
speech_bubble_recipients.Add(M.client)
var/image/I = image('icons/mob/talk.dmi', src, "[bubble_type][say_test(message)]", FLY_LAYER)
I.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA
+5
View File
@@ -49,6 +49,10 @@
/mob/proc/add_to_player_list()
SHOULD_CALL_PARENT(TRUE)
GLOB.player_list |= src
if(client.holder)
GLOB.keyloop_list |= src
else if(stat != DEAD || !SSlag_switch?.measures[DISABLE_DEAD_KEYLOOP])
GLOB.keyloop_list |= src
if(!SSticker?.mode)
return
if(stat == DEAD)
@@ -60,6 +64,7 @@
/mob/proc/remove_from_player_list()
SHOULD_CALL_PARENT(TRUE)
GLOB.player_list -= src
GLOB.keyloop_list -= src
if(!SSticker?.mode)
return
if(stat == DEAD)
+6
View File
@@ -77,6 +77,12 @@
to_chat(src, span_danger("You cannot talk in deadchat (muted)."))
return
if(SSlag_switch.measures[SLOWMODE_SAY] && !HAS_TRAIT(src, TRAIT_BYPASS_MEASURES) && src == usr)
if(!COOLDOWN_FINISHED(client, say_slowmode))
to_chat(src, span_warning("Message not sent due to slowmode. Please wait [SSlag_switch.slowmode_cooldown/10] seconds between messages.\n\"[message]\""))
return
COOLDOWN_START(client, say_slowmode, SSlag_switch.slowmode_cooldown)
if(src.client.handle_spam_prevention(message,MUTE_DEADCHAT))
return