From 32fbb7d9651592b0addb359ca83537fc119507f0 Mon Sep 17 00:00:00 2001 From: "sentry[bot]" <39604003+sentry[bot]@users.noreply.github.com> Date: Mon, 1 Jun 2026 10:35:21 +0000 Subject: [PATCH] Fix statpanel obj_window null dereference (#22538) * Please describe the intent of your changes in a clear fashion. This PR addresses SERVER-PROD-75, where the `set_turf_examine_tab` and `return_object_images` procs in the statpanels subsystem would crash due to attempting to access `client.obj_window.atoms_to_show` when `client.obj_window` was null. The root cause was a lifecycle desync: `client.obj_window` is primarily initialized within `/mob/set_listed_turf` and can be explicitly nulled by `/datum/object_window_info/Destroy()`. However, the statpanels subsystem would still attempt to update the turf examine tab if `mob.listed_turf` was set, even if `client.obj_window` had become null (e.g., after a mob transfer, relogin, or `obj_window` destruction without a subsequent `set_listed_turf` call). The fix involves lazy-initializing `client.obj_window` within both `set_turf_examine_tab` and `return_object_images`. This ensures that `client.obj_window` is always a valid `/datum/object_window_info` instance before its properties are accessed, preventing the null dereference crash. * Please make sure that, in the case of mapping changes, you include images of these changes in the PR's description. * Please make sure to mark your PR as wip or review required by making a comment with !wip or !review required * If you include sprites/sounds/... (assets) that you have not created yourself specify the license and original author below. * Ensure that you also credit them in the appropriate location / changelog as specified in the contributor guidelines ### Asset Licenses The following assets that **have not** been created by myself are included in this PR: | Path | Original Author | License | | --- | --- | --- | | icons/example.dmi | ExamplePerson (Example Station) | CC0 | Fixes SERVER-PROD-75 --------- Co-authored-by: sentry[bot] <39604003+sentry[bot]@users.noreply.github.com> Co-authored-by: VMSolidus --- code/controllers/subsystems/statpanel.dm | 8 ++++++++ html/changelogs/hellfirejag-examine-turf-fix.yml | 4 ++++ 2 files changed, 12 insertions(+) create mode 100644 html/changelogs/hellfirejag-examine-turf-fix.yml diff --git a/code/controllers/subsystems/statpanel.dm b/code/controllers/subsystems/statpanel.dm index 465c6fad443..575d914a0db 100644 --- a/code/controllers/subsystems/statpanel.dm +++ b/code/controllers/subsystems/statpanel.dm @@ -186,6 +186,11 @@ SUBSYSTEM_DEF(statpanels) atoms_to_display += turf_content /// Set the atoms we're meant to display + // Lazy-init: SSstatpanels can fire for a client whose obj_window was never + // created (mob transfer / relogin) or was nulled by /datum/object_window_info/Destroy() + // while mob.listed_turf survived. Without this guard we'd null-deref atoms_to_show. + if(!target.obj_window) + target.obj_window = new /datum/object_window_info(target) var/datum/object_window_info/obj_window = target.obj_window obj_window.atoms_to_show = atoms_to_display START_PROCESSING(SSobj_tab_items, obj_window) @@ -210,6 +215,9 @@ SUBSYSTEM_DEF(statpanels) // No turf? go away if(!load_from.mob?.listed_turf) return list() + // Lazy-init for the same lifecycle reasons as set_turf_examine_tab + if(!load_from.obj_window) + load_from.obj_window = new /datum/object_window_info(load_from) var/datum/object_window_info/obj_window = load_from.obj_window var/list/already_seen = obj_window.atoms_to_images var/list/to_make = obj_window.atoms_to_imagify diff --git a/html/changelogs/hellfirejag-examine-turf-fix.yml b/html/changelogs/hellfirejag-examine-turf-fix.yml new file mode 100644 index 00000000000..4d6e6dea3e6 --- /dev/null +++ b/html/changelogs/hellfirejag-examine-turf-fix.yml @@ -0,0 +1,4 @@ +author: Hellfirejag +delete-after: True +changes: + - bugfix: "Fixed a runtime error caused by shift clicking a turf after logging out and relogging."