mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-09 16:05:07 +00:00
[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:
@@ -40,6 +40,8 @@
|
||||
#define LINKED_UP (1<<0)
|
||||
/// an obj/item is created! (obj/item/created_item)
|
||||
#define COMSIG_GLOB_NEW_ITEM "!new_item"
|
||||
/// a client (re)connected, after all /client/New() checks have passed : (client/connected_client)
|
||||
#define COMSIG_GLOB_CLIENT_CONNECT "!client_connect"
|
||||
/// a weather event of some kind occured
|
||||
#define COMSIG_WEATHER_TELEGRAPH(event_type) "!weather_telegraph [event_type]"
|
||||
#define COMSIG_WEATHER_START(event_type) "!weather_start [event_type]"
|
||||
|
||||
10
code/__DEFINES/lag_switch.dm
Normal file
10
code/__DEFINES/lag_switch.dm
Normal file
@@ -0,0 +1,10 @@
|
||||
// All of the possible Lag Switch lag mitigation measures
|
||||
// If you add more do not forget to update MEASURES_AMOUNT accordingly
|
||||
#define DISABLE_DEAD_KEYLOOP 1 // Stops ghosts flying around freely, they can still jump and orbit, staff exempted
|
||||
#define DISABLE_GHOST_ZOOM_TRAY 2 // Stops ghosts using zoom/t-ray verbs and resets their view if zoomed out, staff exempted
|
||||
#define DISABLE_RUNECHAT 3 // Disable runechat and enable the bubbles, speaking mobs with TRAIT_BYPASS_MEASURES exempted
|
||||
#define DISABLE_USR_ICON2HTML 4 // Disable icon2html procs from verbs like examine, mobs calling with TRAIT_BYPASS_MEASURES exempted
|
||||
#define DISABLE_NON_OBSJOBS 5 // Prevents anyone from joining the game as anything but observer
|
||||
#define SLOWMODE_SAY 6 // Limit IC/dchat spam to one message every x seconds per client, TRAIT_BYPASS_MEASURES exempted
|
||||
|
||||
#define MEASURES_AMOUNT 6 // The total number of switches defined above
|
||||
@@ -323,6 +323,8 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
|
||||
#define TRAIT_BLOODSHOT_EYES "bloodshot_eyes"
|
||||
/// This mob should never close UI even if it doesn't have a client
|
||||
#define TRAIT_PRESERVE_UI_WITHOUT_CLIENT "preserve_ui_without_client"
|
||||
/// This mob overrides certian SSlag_switch measures with this special trait
|
||||
#define TRAIT_BYPASS_MEASURES "bypass_lagswitch_measures"
|
||||
|
||||
#define TRAIT_NOBLEED "nobleed" //This carbon doesn't bleed
|
||||
/// This atom can ignore the "is on a turf" check for simple AI datum attacks, allowing them to attack from bags or lockers as long as any other conditions are met
|
||||
|
||||
@@ -1083,6 +1083,8 @@ GLOBAL_LIST_INIT(freon_color_matrix, list("#2E5E69", "#60A2A8", "#A1AFB1", rgb(0
|
||||
/*
|
||||
if (!thing)
|
||||
return
|
||||
if(SSlag_switch.measures[DISABLE_USR_ICON2HTML] && usr && !HAS_TRAIT(usr, TRAIT_BYPASS_MEASURES))
|
||||
return
|
||||
|
||||
var/key
|
||||
var/icon/I = thing
|
||||
@@ -1187,6 +1189,8 @@ GLOBAL_LIST_INIT(freon_color_matrix, list("#2E5E69", "#60A2A8", "#A1AFB1", rgb(0
|
||||
/* SKYRAT EDIT REMOVAL
|
||||
if (!thing)
|
||||
return
|
||||
if(SSlag_switch.measures[DISABLE_USR_ICON2HTML] && usr && !HAS_TRAIT(usr, TRAIT_BYPASS_MEASURES))
|
||||
return
|
||||
|
||||
if (isicon(thing))
|
||||
return icon2html(thing, target)
|
||||
|
||||
@@ -17,6 +17,7 @@ GLOBAL_LIST_INIT(dangerous_turfs, typecacheof(list(
|
||||
//This is for procs to replace all the goddamn 'in world's that are chilling around the code
|
||||
|
||||
GLOBAL_LIST_EMPTY(player_list) //all mobs **with clients attached**.
|
||||
GLOBAL_LIST_EMPTY(keyloop_list) //as above but can be limited to boost performance
|
||||
GLOBAL_LIST_EMPTY(mob_list) //all mobs, including clientless
|
||||
GLOBAL_LIST_EMPTY(mob_directory) //mob_id -> mob
|
||||
GLOBAL_LIST_EMPTY(alive_mob_list) //all alive mobs, including clientless. Excludes /mob/dead/new_player
|
||||
|
||||
@@ -88,6 +88,7 @@ GLOBAL_LIST_INIT(traits_by_type, list(
|
||||
"TRAIT_CANNOT_OPEN_PRESENTS" = TRAIT_CANNOT_OPEN_PRESENTS,
|
||||
"TRAIT_PRESENT_VISION" = TRAIT_PRESENT_VISION,
|
||||
"TRAIT_DISK_VERIFIER" = TRAIT_DISK_VERIFIER,
|
||||
"TRAIT_BYPASS_MEASURES" = TRAIT_BYPASS_MEASURES,
|
||||
"TRAIT_NOMOBSWAP" = TRAIT_NOMOBSWAP,
|
||||
"TRAIT_XRAY_VISION" = TRAIT_XRAY_VISION,
|
||||
"TRAIT_WEB_WEAVER" = TRAIT_WEB_WEAVER,
|
||||
|
||||
@@ -303,6 +303,10 @@
|
||||
|
||||
/datum/config_entry/flag/maprotation
|
||||
|
||||
/datum/config_entry/number/auto_lag_switch_pop //Number of clients at which drastic lag mitigation measures kick in
|
||||
config_entry_value = null
|
||||
min_val = 0
|
||||
|
||||
/datum/config_entry/number/soft_popcap
|
||||
default = null
|
||||
min_val = 0
|
||||
|
||||
@@ -35,5 +35,5 @@ SUBSYSTEM_DEF(input)
|
||||
user.set_macros()
|
||||
|
||||
/datum/controller/subsystem/input/fire()
|
||||
for(var/mob/user as anything in GLOB.player_list)
|
||||
for(var/mob/user as anything in GLOB.keyloop_list)
|
||||
user.focus?.keyLoop(user.client)
|
||||
|
||||
133
code/controllers/subsystem/lag_switch.dm
Normal file
133
code/controllers/subsystem/lag_switch.dm
Normal file
@@ -0,0 +1,133 @@
|
||||
/// The subsystem for controlling drastic performance enhancements aimed at reducing server load for a smoother albeit slightly duller gaming experience
|
||||
SUBSYSTEM_DEF(lag_switch)
|
||||
name = "Lag Switch"
|
||||
flags = SS_NO_FIRE
|
||||
|
||||
/// If the lag switch measures should attempt to trigger automatically, TRUE if a config value exists
|
||||
var/auto_switch = FALSE
|
||||
/// Amount of connected clients at which the Lag Switch should engage, set via config or admin panel
|
||||
var/trigger_pop = INFINITY - 1337
|
||||
/// List of bools corresponding to code/__DEFINES/lag_switch.dm
|
||||
var/static/list/measures[MEASURES_AMOUNT]
|
||||
/// List of measures that toggle automatically
|
||||
var/list/auto_measures = list(DISABLE_GHOST_ZOOM_TRAY, DISABLE_RUNECHAT, DISABLE_USR_ICON2HTML)
|
||||
/// Timer ID for the automatic veto period
|
||||
var/veto_timer_id
|
||||
/// Cooldown between say verb uses when slowmode is enabled
|
||||
var/slowmode_cooldown = 3 SECONDS
|
||||
|
||||
/datum/controller/subsystem/lag_switch/Initialize(start_timeofday)
|
||||
for(var/i = 1, i <= measures.len, i++)
|
||||
measures[i] = FALSE
|
||||
var/auto_switch_pop = CONFIG_GET(number/auto_lag_switch_pop)
|
||||
if(auto_switch_pop)
|
||||
auto_switch = TRUE
|
||||
trigger_pop = auto_switch_pop
|
||||
RegisterSignal(SSdcs, COMSIG_GLOB_CLIENT_CONNECT, .proc/client_connected)
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/lag_switch/proc/client_connected(datum/source, client/connected)
|
||||
SIGNAL_HANDLER
|
||||
if(TGS_CLIENT_COUNT < trigger_pop)
|
||||
return
|
||||
|
||||
auto_switch = FALSE
|
||||
UnregisterSignal(SSdcs, COMSIG_GLOB_CLIENT_CONNECT)
|
||||
veto_timer_id = addtimer(CALLBACK(src, .proc/set_all_measures, TRUE, TRUE), 20 SECONDS, TIMER_STOPPABLE)
|
||||
message_admins("Lag Switch population threshold reached. Automatic activation of lag mitigation measures occuring in 20 seconds. (<a href='?_src_=holder;[HrefToken()];change_lag_switch_option=CANCEL'>CANCEL</a>)")
|
||||
log_admin("Lag Switch population threshold reached. Automatic activation of lag mitigation measures occuring in 20 seconds.")
|
||||
|
||||
/// (En/Dis)able automatic triggering of switches based on client count
|
||||
/datum/controller/subsystem/lag_switch/proc/toggle_auto_enable()
|
||||
auto_switch = !auto_switch
|
||||
if(auto_switch)
|
||||
RegisterSignal(SSdcs, COMSIG_GLOB_CLIENT_CONNECT, .proc/client_connected)
|
||||
else
|
||||
UnregisterSignal(SSdcs, COMSIG_GLOB_CLIENT_CONNECT)
|
||||
|
||||
/// Called from an admin chat link
|
||||
/datum/controller/subsystem/lag_switch/proc/cancel_auto_enable_in_progress()
|
||||
if(!veto_timer_id)
|
||||
return FALSE
|
||||
|
||||
deltimer(veto_timer_id)
|
||||
veto_timer_id = null
|
||||
return TRUE
|
||||
|
||||
/// Update the slowmode timer length and clear existing ones if reduced
|
||||
/datum/controller/subsystem/lag_switch/proc/change_slowmode_cooldown(length)
|
||||
if(!length)
|
||||
return FALSE
|
||||
|
||||
var/length_secs = length SECONDS
|
||||
if(length_secs <= 0)
|
||||
length_secs = 1 // one tick because cooldowns do not like 0
|
||||
|
||||
if(length_secs < slowmode_cooldown)
|
||||
for(var/client/C as anything in GLOB.clients)
|
||||
COOLDOWN_RESET(C, say_slowmode)
|
||||
|
||||
slowmode_cooldown = length_secs
|
||||
if(measures[SLOWMODE_SAY])
|
||||
to_chat(world, span_boldannounce("Slowmode timer has been changed to [length] seconds by an admin."))
|
||||
return TRUE
|
||||
|
||||
/// Handle the state change for individual measures
|
||||
/datum/controller/subsystem/lag_switch/proc/set_measure(measure_key, state)
|
||||
if(isnull(measure_key) || isnull(state))
|
||||
stack_trace("SSlag_switch.set_measure() was called with a null arg")
|
||||
return FALSE
|
||||
if(isnull(LAZYACCESS(measures, measure_key)))
|
||||
stack_trace("SSlag_switch.set_measure() was called with a measure_key not in the list of measures")
|
||||
return FALSE
|
||||
if(measures[measure_key] == state)
|
||||
return TRUE
|
||||
|
||||
measures[measure_key] = state
|
||||
|
||||
switch(measure_key)
|
||||
if(DISABLE_DEAD_KEYLOOP)
|
||||
if(state)
|
||||
for(var/mob/user as anything in GLOB.player_list)
|
||||
if(user.stat == DEAD && !user.client?.holder)
|
||||
GLOB.keyloop_list -= user
|
||||
deadchat_broadcast(span_big("To increase performance Observer freelook is now disabled. Please use Orbit, Teleport, and Jump to look around."), message_type = DEADCHAT_ANNOUNCEMENT)
|
||||
else
|
||||
GLOB.keyloop_list |= GLOB.player_list
|
||||
deadchat_broadcast("Observer freelook has been re-enabled. Enjoy your wooshing.", message_type = DEADCHAT_ANNOUNCEMENT)
|
||||
if(DISABLE_GHOST_ZOOM_TRAY)
|
||||
if(state) // if enabling make sure current ghosts are updated
|
||||
for(var/mob/dead/observer/ghost in GLOB.dead_mob_list)
|
||||
if(!ghost.client)
|
||||
continue
|
||||
if(!ghost.client.holder && ghost.client.view_size.getView() != ghost.client.view_size.default)
|
||||
ghost.client.view_size.resetToDefault()
|
||||
if(SLOWMODE_SAY)
|
||||
if(state)
|
||||
to_chat(world, span_boldannounce("Slowmode for IC/dead chat has been enabled with [slowmode_cooldown/10] seconds between messages."))
|
||||
else
|
||||
for(var/client/C as anything in GLOB.clients)
|
||||
COOLDOWN_RESET(C, say_slowmode)
|
||||
to_chat(world, span_boldannounce("Slowmode for IC/dead chat has been disabled by an admin."))
|
||||
if(DISABLE_NON_OBSJOBS)
|
||||
world.update_status()
|
||||
|
||||
return TRUE
|
||||
|
||||
/// Helper to loop over all measures for mass changes
|
||||
/datum/controller/subsystem/lag_switch/proc/set_all_measures(state, automatic = FALSE)
|
||||
if(isnull(state))
|
||||
stack_trace("SSlag_switch.set_all_measures() was called with a null state arg")
|
||||
return FALSE
|
||||
|
||||
if(automatic)
|
||||
message_admins("Lag Switch enabling automatic measures now.")
|
||||
log_admin("Lag Switch enabling automatic measures now.")
|
||||
veto_timer_id = null
|
||||
for(var/i = 1, i <= auto_measures.len, i++)
|
||||
set_measure(auto_measures[i], state)
|
||||
return TRUE
|
||||
|
||||
for(var/i = 1, i <= measures.len, i++)
|
||||
set_measure(i, state)
|
||||
return TRUE
|
||||
@@ -43,7 +43,6 @@ SUBSYSTEM_DEF(ticker)
|
||||
|
||||
var/news_report
|
||||
|
||||
var/late_join_disabled
|
||||
|
||||
var/roundend_check_paused = FALSE
|
||||
|
||||
|
||||
@@ -235,6 +235,8 @@
|
||||
* * spans - Additional classes to be added to the message
|
||||
*/
|
||||
/mob/proc/create_chat_message(atom/movable/speaker, datum/language/message_language, raw_message, list/spans, runechat_flags = NONE)
|
||||
if(SSlag_switch.measures[DISABLE_RUNECHAT] && !HAS_TRAIT(speaker, TRAIT_BYPASS_MEASURES))
|
||||
return
|
||||
// Ensure the list we are using, if present, is a copy so we don't modify the list provided to us
|
||||
spans = spans ? spans.Copy() : list()
|
||||
|
||||
|
||||
@@ -142,7 +142,7 @@
|
||||
. = list()
|
||||
.["version"] = GLOB.game_version
|
||||
.["respawn"] = config ? !CONFIG_GET(flag/norespawn) : FALSE
|
||||
.["enter"] = GLOB.enter_allowed
|
||||
.["enter"] = !LAZYACCESS(SSlag_switch.measures, DISABLE_NON_OBSJOBS)
|
||||
.["ai"] = CONFIG_GET(flag/allow_ai)
|
||||
.["host"] = world.host ? world.host : null
|
||||
.["round_id"] = GLOB.round_id
|
||||
|
||||
@@ -276,7 +276,7 @@ GLOBAL_VAR(restart_counter)
|
||||
|
||||
var/list/features = list()
|
||||
|
||||
if (!GLOB.enter_allowed)
|
||||
if(LAZYACCESS(SSlag_switch.measures, DISABLE_NON_OBSJOBS))
|
||||
features += "closed"
|
||||
|
||||
var/s = ""
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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*/
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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//
|
||||
/////////
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -144,3 +144,4 @@ StyleMistake = Game Master
|
||||
actioninja = Game Master
|
||||
bobbahbrown = Game Master
|
||||
Jaredfogle = Game Master
|
||||
WaylandSmithy = Game Master
|
||||
|
||||
@@ -329,6 +329,9 @@ NOTE_FRESH_DAYS 91.31055
|
||||
## Notes older then this will be completely faded out.
|
||||
NOTE_STALE_DAYS 365.2422
|
||||
|
||||
## Uncomment to allow drastic performence enhancemet measures to turn on automatically once there are equal or more clients than the configured amount (will also prompt admin for veto)
|
||||
#AUTO_LAG_SWITCH_POP 75
|
||||
|
||||
##Note: all population caps can be used with each other if desired.
|
||||
|
||||
## Uncomment for 'soft' population caps, players will be warned while joining if the living crew exceeds the listed number.
|
||||
|
||||
@@ -209,7 +209,7 @@
|
||||
to_chat(usr, "<span class='danger'>The round is either not ready, or has already finished...</span>")
|
||||
return
|
||||
|
||||
if(!GLOB.enter_allowed)
|
||||
if(SSlag_switch.measures[DISABLE_NON_OBSJOBS])
|
||||
to_chat(usr, "<span class='notice'>There is an administrative lock on entering the game!</span>")
|
||||
return
|
||||
|
||||
@@ -241,7 +241,10 @@
|
||||
ready = PLAYER_NOT_READY
|
||||
return FALSE
|
||||
|
||||
var/this_is_like_playing_right = tgui_alert(src, "Are you sure you wish to observe?", "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
|
||||
@@ -341,10 +344,6 @@
|
||||
alert(src, get_job_unavailable_error_message(error, rank))
|
||||
return FALSE
|
||||
|
||||
if(SSticker.late_join_disabled)
|
||||
alert(src, "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
|
||||
@@ -435,7 +434,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>"
|
||||
dat += "<div class='notice'>Alert Level: [capitalize(num2seclevel(SSsecurity_level.current_level))]</div>"
|
||||
if(SSshuttle.emergency)
|
||||
switch(SSshuttle.emergency.mode)
|
||||
|
||||
@@ -78,6 +78,7 @@
|
||||
#include "code\__DEFINES\is_helpers.dm"
|
||||
#include "code\__DEFINES\jobs.dm"
|
||||
#include "code\__DEFINES\keybinding.dm"
|
||||
#include "code\__DEFINES\lag_switch.dm"
|
||||
#include "code\__DEFINES\language.dm"
|
||||
#include "code\__DEFINES\layers.dm"
|
||||
#include "code\__DEFINES\lighting.dm"
|
||||
@@ -365,6 +366,7 @@
|
||||
#include "code\controllers\subsystem\input.dm"
|
||||
#include "code\controllers\subsystem\ipintel.dm"
|
||||
#include "code\controllers\subsystem\job.dm"
|
||||
#include "code\controllers\subsystem\lag_switch.dm"
|
||||
#include "code\controllers\subsystem\language.dm"
|
||||
#include "code\controllers\subsystem\lighting.dm"
|
||||
#include "code\controllers\subsystem\machines.dm"
|
||||
|
||||
Reference in New Issue
Block a user