diff --git a/code/datums/world_topic.dm b/code/datums/world_topic.dm
index e01b525e02..9e2efd1d4e 100644
--- a/code/datums/world_topic.dm
+++ b/code/datums/world_topic.dm
@@ -1,183 +1,189 @@
-// SETUP
-
-/proc/TopicHandlers()
- . = list()
- var/list/all_handlers = subtypesof(/datum/world_topic)
- for(var/I in all_handlers)
- var/datum/world_topic/WT = I
- var/keyword = initial(WT.keyword)
- if(!keyword)
- warning("[WT] has no keyword! Ignoring...")
- continue
- var/existing_path = .[keyword]
- if(existing_path)
- warning("[existing_path] and [WT] have the same keyword! Ignoring [WT]...")
- else if(keyword == "key")
- warning("[WT] has keyword 'key'! Ignoring...")
- else
- .[keyword] = WT
-
-// DATUM
-
-/datum/world_topic
- var/keyword
- var/log = TRUE
- var/key_valid
- var/require_comms_key = FALSE
-
-/datum/world_topic/proc/TryRun(list/input, addr)
- key_valid = config && (CONFIG_GET(string/comms_key) == input["key"])
- if(require_comms_key && !key_valid)
- return "Bad Key"
- input -= "key"
- . = Run(input, addr)
- if(islist(.))
- . = list2params(.)
-
-/datum/world_topic/proc/Run(list/input, addr)
- CRASH("Run() not implemented for [type]!")
-
-// TOPICS
-
-/datum/world_topic/ping
- keyword = "ping"
- log = FALSE
-
-/datum/world_topic/ping/Run(list/input, addr)
- . = 0
- for (var/client/C in GLOB.clients)
- ++.
-
-/datum/world_topic/playing
- keyword = "playing"
- log = FALSE
-
-/datum/world_topic/playing/Run(list/input, addr)
- return GLOB.player_list.len
-
-/datum/world_topic/pr_announce
- keyword = "announce"
- require_comms_key = TRUE
- var/static/list/PRcounts = list() //PR id -> number of times announced this round
-
-/datum/world_topic/pr_announce/Run(list/input, addr)
- var/list/payload = json_decode(input["payload"])
- var/id = "[payload["pull_request"]["id"]]"
- if(!PRcounts[id])
- PRcounts[id] = 1
- else
- ++PRcounts[id]
- if(PRcounts[id] > PR_ANNOUNCEMENTS_PER_ROUND)
- return
-
- var/final_composed = "PR: [input[keyword]]"
- for(var/client/C in GLOB.clients)
- C.AnnouncePR(final_composed)
-
-/datum/world_topic/ahelp_relay
- keyword = "Ahelp"
- require_comms_key = TRUE
-
-/datum/world_topic/ahelp_relay/Run(list/input, addr)
- relay_msg_admins("HELP: [input["source"]] [input["message_sender"]]: [input["message"]]")
-
-/datum/world_topic/comms_console
- keyword = "Comms_Console"
- require_comms_key = TRUE
-
-/datum/world_topic/comms_console/Run(list/input, addr)
- minor_announce(input["message"], "Incoming message from [input["message_sender"]]")
- for(var/obj/machinery/computer/communications/CM in GLOB.machines)
- CM.overrideCooldown()
-
-/datum/world_topic/news_report
- keyword = "News_Report"
- require_comms_key = TRUE
-
-/datum/world_topic/news_report/Run(list/input, addr)
- minor_announce(input["message"], "Breaking Update From [input["message_sender"]]")
-
-/datum/world_topic/server_hop
- keyword = "server_hop"
-
-/datum/world_topic/server_hop/Run(list/input, addr)
- var/expected_key = input[keyword]
- for(var/mob/dead/observer/O in GLOB.player_list)
- if(O.key == expected_key)
- if(O.client?.address == addr)
- new /obj/screen/splash(O.client, TRUE)
- break
-
-/datum/world_topic/adminmsg
- keyword = "adminmsg"
- require_comms_key = TRUE
-
-/datum/world_topic/adminmsg/Run(list/input, addr)
- return IrcPm(input[keyword], input["msg"], input["sender"])
-
-/datum/world_topic/namecheck
- keyword = "namecheck"
- require_comms_key = TRUE
-
-/datum/world_topic/namecheck/Run(list/input, addr)
- //Oh this is a hack, someone refactor the functionality out of the chat command PLS
- var/datum/tgs_chat_command/namecheck/NC = new
- var/datum/tgs_chat_user/user = new
- user.friendly_name = input["sender"]
- user.mention = user.friendly_name
- return NC.Run(user, input["namecheck"])
-
-/datum/world_topic/adminwho
- keyword = "adminwho"
- require_comms_key = TRUE
-
-/datum/world_topic/adminwho/Run(list/input, addr)
- return ircadminwho()
-
-/datum/world_topic/status
- keyword = "status"
-
-/datum/world_topic/status/Run(list/input, addr)
- . = list()
- .["version"] = GLOB.game_version
- .["mode"] = "hidden" //CIT CHANGE - hides the gamemode in topic() calls to prevent meta'ing the gamemode
- .["respawn"] = config ? !CONFIG_GET(flag/norespawn) : FALSE
- .["enter"] = GLOB.enter_allowed
- .["vote"] = CONFIG_GET(flag/allow_vote_mode)
- .["ai"] = CONFIG_GET(flag/allow_ai)
- .["host"] = world.host ? world.host : null
- .["round_id"] = GLOB.round_id
- .["players"] = GLOB.clients.len
- .["revision"] = GLOB.revdata.commit
- .["revision_date"] = GLOB.revdata.date
-
- var/list/adm = get_admin_counts()
- var/list/presentmins = adm["present"]
- var/list/afkmins = adm["afk"]
- .["admins"] = presentmins.len + afkmins.len //equivalent to the info gotten from adminwho
- .["gamestate"] = SSticker.current_state
-
- .["map_name"] = SSmapping.config?.map_name || "Loading..."
-
- if(key_valid)
- .["active_players"] = get_active_player_count()
- if(SSticker.HasRoundStarted())
- .["real_mode"] = SSticker.mode.name
- // Key-authed callers may know the truth behind the "secret"
-
- .["security_level"] = get_security_level()
- .["round_duration"] = SSticker ? round((world.time-SSticker.round_start_time)/10) : 0
- // Amount of world's ticks in seconds, useful for calculating round duration
-
- //Time dilation stats.
- .["time_dilation_current"] = SStime_track.time_dilation_current
- .["time_dilation_avg"] = SStime_track.time_dilation_avg
- .["time_dilation_avg_slow"] = SStime_track.time_dilation_avg_slow
- .["time_dilation_avg_fast"] = SStime_track.time_dilation_avg_fast
-
- if(SSshuttle && SSshuttle.emergency)
- .["shuttle_mode"] = SSshuttle.emergency.mode
- // Shuttle status, see /__DEFINES/stat.dm
- .["shuttle_timer"] = SSshuttle.emergency.timeLeft()
- // Shuttle timer, in seconds
-
+// SETUP
+
+/proc/TopicHandlers()
+ . = list()
+ var/list/all_handlers = subtypesof(/datum/world_topic)
+ for(var/I in all_handlers)
+ var/datum/world_topic/WT = I
+ var/keyword = initial(WT.keyword)
+ if(!keyword)
+ warning("[WT] has no keyword! Ignoring...")
+ continue
+ var/existing_path = .[keyword]
+ if(existing_path)
+ warning("[existing_path] and [WT] have the same keyword! Ignoring [WT]...")
+ else if(keyword == "key")
+ warning("[WT] has keyword 'key'! Ignoring...")
+ else
+ .[keyword] = WT
+
+// DATUM
+
+/datum/world_topic
+ var/keyword
+ var/log = TRUE
+ var/key_valid
+ var/require_comms_key = FALSE
+
+/datum/world_topic/proc/TryRun(list/input, addr)
+ key_valid = config && (CONFIG_GET(string/comms_key) == input["key"])
+ if(require_comms_key && !key_valid)
+ return "Bad Key"
+ input -= "key"
+ . = Run(input, addr)
+ if(islist(.))
+ . = list2params(.)
+
+/datum/world_topic/proc/Run(list/input, addr)
+ CRASH("Run() not implemented for [type]!")
+
+// TOPICS
+
+/datum/world_topic/ping
+ keyword = "ping"
+ log = FALSE
+
+/datum/world_topic/ping/Run(list/input, addr)
+ . = 0
+ for (var/client/C in GLOB.clients)
+ ++.
+
+/datum/world_topic/playing
+ keyword = "playing"
+ log = FALSE
+
+/datum/world_topic/playing/Run(list/input, addr)
+ return GLOB.player_list.len
+
+/datum/world_topic/pr_announce
+ keyword = "announce"
+ require_comms_key = TRUE
+ var/static/list/PRcounts = list() //PR id -> number of times announced this round
+
+/datum/world_topic/pr_announce/Run(list/input, addr)
+ var/list/payload = json_decode(input["payload"])
+ var/id = "[payload["pull_request"]["id"]]"
+ if(!PRcounts[id])
+ PRcounts[id] = 1
+ else
+ ++PRcounts[id]
+ if(PRcounts[id] > PR_ANNOUNCEMENTS_PER_ROUND)
+ return
+
+ var/final_composed = "PR: [input[keyword]]"
+ for(var/client/C in GLOB.clients)
+ C.AnnouncePR(final_composed)
+
+/datum/world_topic/ahelp_relay
+ keyword = "Ahelp"
+ require_comms_key = TRUE
+
+/datum/world_topic/ahelp_relay/Run(list/input, addr)
+ relay_msg_admins("HELP: [input["source"]] [input["message_sender"]]: [input["message"]]")
+
+/datum/world_topic/comms_console
+ keyword = "Comms_Console"
+ require_comms_key = TRUE
+
+/datum/world_topic/comms_console/Run(list/input, addr)
+ minor_announce(input["message"], "Incoming message from [input["message_sender"]]")
+ for(var/obj/machinery/computer/communications/CM in GLOB.machines)
+ CM.overrideCooldown()
+
+/datum/world_topic/news_report
+ keyword = "News_Report"
+ require_comms_key = TRUE
+
+/datum/world_topic/news_report/Run(list/input, addr)
+ minor_announce(input["message"], "Breaking Update From [input["message_sender"]]")
+
+/datum/world_topic/server_hop
+ keyword = "server_hop"
+
+/datum/world_topic/server_hop/Run(list/input, addr)
+ var/expected_key = input[keyword]
+ for(var/mob/dead/observer/O in GLOB.player_list)
+ if(O.key == expected_key)
+ if(O.client?.address == addr)
+ new /obj/screen/splash(O.client, TRUE)
+ break
+
+/datum/world_topic/adminmsg
+ keyword = "adminmsg"
+ require_comms_key = TRUE
+
+/datum/world_topic/adminmsg/Run(list/input, addr)
+ return IrcPm(input[keyword], input["msg"], input["sender"])
+
+/datum/world_topic/namecheck
+ keyword = "namecheck"
+ require_comms_key = TRUE
+
+/datum/world_topic/namecheck/Run(list/input, addr)
+ //Oh this is a hack, someone refactor the functionality out of the chat command PLS
+ var/datum/tgs_chat_command/namecheck/NC = new
+ var/datum/tgs_chat_user/user = new
+ user.friendly_name = input["sender"]
+ user.mention = user.friendly_name
+ return NC.Run(user, input["namecheck"])
+
+/datum/world_topic/adminwho
+ keyword = "adminwho"
+ require_comms_key = TRUE
+
+/datum/world_topic/adminwho/Run(list/input, addr)
+ return ircadminwho()
+
+/datum/world_topic/status
+ keyword = "status"
+
+/datum/world_topic/status/Run(list/input, addr)
+ if(!key_valid) //If we have a key, then it's safe to trust that this isn't a malicious packet. Also prevents the extra info from leaking
+ if(GLOB.topic_status_lastcache <= world.time + 5)
+ return GLOB.topic_status_cache
+ GLOB.topic_status_lastcache = world.time
+ . = list()
+ .["version"] = GLOB.game_version
+ .["mode"] = "hidden" //CIT CHANGE - hides the gamemode in topic() calls to prevent meta'ing the gamemode
+ .["respawn"] = config ? !CONFIG_GET(flag/norespawn) : FALSE
+ .["enter"] = GLOB.enter_allowed
+ .["vote"] = CONFIG_GET(flag/allow_vote_mode)
+ .["ai"] = CONFIG_GET(flag/allow_ai)
+ .["host"] = world.host ? world.host : null
+ .["round_id"] = GLOB.round_id
+ .["players"] = GLOB.clients.len
+ .["revision"] = GLOB.revdata.commit
+ .["revision_date"] = GLOB.revdata.date
+
+ var/list/adm = get_admin_counts()
+ var/list/presentmins = adm["present"]
+ var/list/afkmins = adm["afk"]
+ .["admins"] = presentmins.len + afkmins.len //equivalent to the info gotten from adminwho
+ .["gamestate"] = SSticker.current_state
+
+ .["map_name"] = SSmapping.config?.map_name || "Loading..."
+
+ if(key_valid)
+ .["active_players"] = get_active_player_count()
+ if(SSticker.HasRoundStarted())
+ .["real_mode"] = SSticker.mode.name
+ // Key-authed callers may know the truth behind the "secret"
+
+ .["security_level"] = get_security_level()
+ .["round_duration"] = SSticker ? round((world.time-SSticker.round_start_time)/10) : 0
+ // Amount of world's ticks in seconds, useful for calculating round duration
+
+ //Time dilation stats.
+ .["time_dilation_current"] = SStime_track.time_dilation_current
+ .["time_dilation_avg"] = SStime_track.time_dilation_avg
+ .["time_dilation_avg_slow"] = SStime_track.time_dilation_avg_slow
+ .["time_dilation_avg_fast"] = SStime_track.time_dilation_avg_fast
+
+ if(SSshuttle && SSshuttle.emergency)
+ .["shuttle_mode"] = SSshuttle.emergency.mode
+ // Shuttle status, see /__DEFINES/stat.dm
+ .["shuttle_timer"] = SSshuttle.emergency.timeLeft()
+ // Shuttle timer, in seconds
+
+ if(!key_valid)
+ GLOB.topic_status_cache = .
diff --git a/code/game/world.dm b/code/game/world.dm
index 034ecddfa2..e68372d768 100644
--- a/code/game/world.dm
+++ b/code/game/world.dm
@@ -2,6 +2,9 @@
GLOBAL_VAR(restart_counter)
+GLOBAL_VAR(topic_status_lastcache)
+GLOBAL_LIST(topic_status_cache)
+
//This happens after the Master subsystem new(s) (it's a global datum)
//So subsystems globals exist, but are not initialised
/world/New()