Lag War Day 2: TGUI performance improvements (#21848)

<img width="707" height="659" alt="image"
src="https://github.com/user-attachments/assets/6c8db0bf-dec6-40f2-86e8-120531fa5693"
/>

the traitor uplink is causing a genuine hostage situation to the server
by simply being open due to the frankly insane amount of data that it
builds and ships every single UI process tick (which is very often!!!)

i've never been ragebaited by a single .dm file before so hard in my
entire developer career so I simply neutered it into using static data
and hit the commit button. it might break, if it does we're burning it
to the ground and remaking it. genuinely heinous crimes going on there

In addition I'm porting:

* [Fix several SHOULD_NOT_SLEEP hits in SStgui.update_uis()
tgstation/tgstation#75411](https://github.com/tgstation/tgstation/pull/75411)
* [Moves ui references from the tgui subsystem to datums themselves
tgstation/tgstation#76215](https://github.com/tgstation/tgstation/pull/76215)
* [Fixes some spurious runtimes in SStgui procs
tgstation/tgstation#76251](https://github.com/tgstation/tgstation/pull/76251)
* [Fixes tgui_open_uis tracking
tgstation/tgstation#77101](https://github.com/tgstation/tgstation/pull/77101)

moving ui references to the datums themselves is a pretty nice
performance boost because otherwise we have to iterate across all open
uis every time a list input closes which sucks! the rest are just fixes
to that original PR.

thank you for your attention to this matter
This commit is contained in:
Wildkins
2026-02-13 21:17:23 -05:00
committed by GitHub
parent efe710f425
commit 84d3a447ab
7 changed files with 126 additions and 124 deletions
+53 -52
View File
@@ -25,8 +25,6 @@ A list of items and costs is stored under the datum of every game mode, alongsid
var/list/tgui_items
/// The current menu we are in.
var/tgui_menu = 0
/// Additional data for TGUI use.
var/list/tgui_data = list()
// Assoc list of item to times bought; shared/referenced by child uplinks
var/list/purchase_log = list()
/// Mind of the uplink's owner.
@@ -73,12 +71,6 @@ Then check if it's true, if true return. This will stop the normal menu appearin
var/pda_code = ""
/obj/item/uplink/hidden/New()
..()
tgui_data = list()
update_tgui_data()
/obj/item/uplink/hidden/Initialize(mapload, datum/mind/owner, new_telecrystals, new_bluecrystals)
. = ..()
return INITIALIZE_HINT_LATELOAD
@@ -119,13 +111,15 @@ Then check if it's true, if true return. This will stop the normal menu appearin
/obj/item/uplink/hidden/ui_data(mob/user)
var/list/data = list()
data["welcome"] = welcome
data["menu"] = tgui_menu
data["telecrystals"] = telecrystals
data["bluecrystals"] = bluecrystals
data["menu"] = tgui_menu
update_tgui_data()
data += tgui_data
return data
/obj/item/uplink/hidden/ui_static_data(mob/user)
. = ..()
. += update_tgui_data()
// Interaction code. Gathers a list of items purchasable from the paren't uplink and displays it. It also adds a lock button.
/obj/item/uplink/hidden/interact(mob/user)
ui_interact(user, null)
@@ -137,25 +131,31 @@ Then check if it's true, if true return. This will stop the normal menu appearin
if(action == "buy_item")
var/datum/uplink_item/UI = (locate(params["buy_item"]) in GLOB.uplink.items)
UI.buy(src, usr)
update_static_data(usr, ui)
else if(action == "lock")
toggle()
SStgui.close_uis(src)
else if(action == "return")
tgui_menu = round(tgui_menu/10)
update_static_data(usr, ui)
else if(action == "menu")
tgui_menu = text2num(params["menu"])
if(params["id"])
exploit_id = params["id"]
if(params["category"])
category = locate(params["category"]) in GLOB.uplink.categories
update_static_data(usr, ui)
if(action == "contract_interact")
var/list/params_webint = list("location" = "contract_details", "contract" = params["contract_interact"])
usr.client.process_webint_link("interface/login/sso_server", list2params(params_webint))
update_static_data(usr, ui)
if(action == "contract_page")
tgui_data["contracts_current_page"] = text2num(params["contract_page"])
.["contracts_current_page"] = text2num(params["contract_page"])
update_static_data(usr, ui)
if(action == "contract_view")
tgui_data["contracts_view"] = text2num(params["contract_view"])
tgui_data["contracts_current_page"] = 1
.["contracts_view"] = text2num(params["contract_view"])
.["contracts_current_page"] = 1
update_static_data(usr, ui)
return 1
@@ -175,6 +175,7 @@ Then check if it's true, if true return. This will stop the normal menu appearin
return newItem
/obj/item/uplink/hidden/proc/update_tgui_data()
. = list()
if(tgui_menu == 0)
var/list/categories = list()
var/list/items = list()
@@ -185,62 +186,62 @@ Then check if it's true, if true return. This will stop the normal menu appearin
if(item.can_view(src))
items[++items.len] = new_tgui_item_data(item)
tgui_data["categories"] = categories
tgui_data["items"] = items
.["categories"] = categories
.["items"] = items
else if(tgui_menu == 1)
var/items[0]
for(var/datum/uplink_item/item in category?.items)
if(item.can_view(src))
items[++items.len] = new_tgui_item_data(item)
tgui_data["items"] = items
.["items"] = items
else if(tgui_menu == 2)
var/permanentData[0]
for(var/datum/record/general/locked/record in SSrecords.records_locked)
permanentData[++permanentData.len] = list("name" = record.name,"id" = record.id, "has_exploitables" = !!record.exploit_record)
tgui_data["exploit_records"] = permanentData
.["exploit_records"] = permanentData
else if(tgui_menu == 21)
tgui_data["exploit_exists"] = 0
.["exploit_exists"] = 0
for(var/datum/record/general/locked/L in SSrecords.records_locked)
if(L.id == exploit_id)
tgui_data["exploit"] = list() // Setting this to equal L.fields passes it's variables that are lists as reference instead of value.
.["exploit"] = list() // Setting this to equal L.fields passes it's variables that are lists as reference instead of value.
// We trade off being able to automatically add shit for more control over what gets passed to json
// and if it's sanitized for html.
tgui_data["exploit"]["tgui_exploit_record"] = html_decode(L.exploit_record) // this user input is already sanitized and encoded when saved to the DB, we can just decode it and slap it into a span
tgui_data["exploit"]["name"] = html_encode(L.name)
tgui_data["exploit"]["sex"] = html_encode(L.sex)
tgui_data["exploit"]["age"] = html_encode(L.age)
tgui_data["exploit"]["species"] = html_encode(L.species)
tgui_data["exploit"]["rank"] = html_encode(L.rank)
tgui_data["exploit"]["citizenship"] = html_encode(L.citizenship)
tgui_data["exploit"]["employer"] = html_encode(L.employer)
tgui_data["exploit"]["religion"] = html_encode(L.religion)
tgui_data["exploit"]["fingerprint"] = html_encode(L.fingerprint)
.["exploit"]["tgui_exploit_record"] = html_decode(L.exploit_record) // this user input is already sanitized and encoded when saved to the DB, we can just decode it and slap it into a span
.["exploit"]["name"] = html_encode(L.name)
.["exploit"]["sex"] = html_encode(L.sex)
.["exploit"]["age"] = html_encode(L.age)
.["exploit"]["species"] = html_encode(L.species)
.["exploit"]["rank"] = html_encode(L.rank)
.["exploit"]["citizenship"] = html_encode(L.citizenship)
.["exploit"]["employer"] = html_encode(L.employer)
.["exploit"]["religion"] = html_encode(L.religion)
.["exploit"]["fingerprint"] = html_encode(L.fingerprint)
tgui_data["exploit_exists"] = 1
.["exploit_exists"] = 1
break
else if(tgui_menu == 3)
tgui_data["contracts_found"] = 0
.["contracts_found"] = 0
if(establish_db_connection(GLOB.dbcon))
tgui_data["contracts"] = list()
.["contracts"] = list()
if (!tgui_data["contracts_current_page"])
tgui_data["contracts_current_page"] = 1
if (!.["contracts_current_page"])
.["contracts_current_page"] = 1
if (!tgui_data["contracts_view"])
tgui_data["contracts_view"] = 1
if (!.["contracts_view"])
.["contracts_view"] = 1
var/query_details[0]
switch (tgui_data["contracts_view"])
switch (.["contracts_view"])
if (1)
query_details["status"] = "open"
if (2)
query_details["status"] = "closed"
else
tgui_data["contracts_view"] = 1
.["contracts_view"] = 1
query_details["status"] = "open"
var/DBQuery/index_query = GLOB.dbcon.NewQuery("SELECT count(*) as Total_Contracts FROM ss13_syndie_contracts WHERE deleted_at IS NULL AND status = :status:")
@@ -263,12 +264,12 @@ Then check if it's true, if true return. This will stop the normal menu appearin
for (var/i = 1, i <= pages, i++)
contracts_pages.Add(i)
tgui_data["contracts_pages"] = contracts_pages
.["contracts_pages"] = contracts_pages
if (tgui_data["contracts_current_page"] > pages)
if (.["contracts_current_page"] > pages)
return
query_details["offset"] = (tgui_data["contracts_current_page"] - 1) * 10
query_details["offset"] = (.["contracts_current_page"] - 1) * 10
var/DBQuery/list_query = GLOB.dbcon.NewQuery("SELECT contract_id, contractee_name, title FROM ss13_syndie_contracts WHERE deleted_at IS NULL AND status = :status: LIMIT 10 OFFSET :offset:")
list_query.Execute(query_details)
@@ -279,21 +280,21 @@ Then check if it's true, if true return. This will stop the normal menu appearin
"contractee" = list_query.item[2],
"title" = list_query.item[3])))
tgui_data["contracts"] = contracts
.["contracts"] = contracts
tgui_data["contracts_found"] = 1
.["contracts_found"] = 1
if(tgui_menu == 31)
tgui_data["contracts_found"] = 0
.["contracts_found"] = 0
if (GLOB.config.sql_enabled && establish_db_connection(GLOB.dbcon))
tgui_data["contracts"] = list()
.["contracts"] = list()
if (!tgui_data["contracts_current_page"])
tgui_data["contracts_current_page"] = 1
if (!.["contracts_current_page"])
.["contracts_current_page"] = 1
if (!tgui_data["contracts_view"])
tgui_data["contracts_view"] = 1
if (!.["contracts_view"])
.["contracts_view"] = 1
var/query_details[0]
query_details["contract_id"] = exploit_id
@@ -302,7 +303,7 @@ Then check if it's true, if true return. This will stop the normal menu appearin
select_query.Execute(query_details)
if (select_query.NextRow())
tgui_data["contracts_found"] = 1
.["contracts_found"] = 1
var/contract[0]
contract["id"] = select_query.item[1]
@@ -322,7 +323,7 @@ Then check if it's true, if true return. This will stop the normal menu appearin
contract["description"] = replacetext(contract["description"], ascii2text(13), "")
contract["reward_other"] = select_query.item[6]
tgui_data["contract"] = contract
.["contract"] = contract
// I placed this here because of how relevant it is.
// You place this in your uplinkable item to check if an uplink is active or not.