From 1ebb3a4f40d33fbad5967037d3bc4565ae765ef5 Mon Sep 17 00:00:00 2001 From: ARGUS <268038739+ARGUS-Memory@users.noreply.github.com> Date: Fri, 20 Mar 2026 00:24:27 +0100 Subject: [PATCH] Fix laptop card slot not being checked for software access (#19300) can_run() only checked the user's worn/held ID via GetIdCard(), ignoring any card inserted into the computer's RFID card slot. This caused access-locked software to always show an RFID error for users relying on a slotted card. Three fixes: - can_run(): add explicit_card param; resolution order is explicit_card, then user.GetIdCard(), then computer.card_slot.stored_card - run_program(): set TM.using_access from the slotted card when present, falling back to user.GetAccess() - ntdownloader.dm: pass my_computer.card_slot.stored_card to can_run() so the software download list respects the slotted card --- .../modular_computers/file_system/program.dm | 14 ++++++++++---- .../file_system/programs/generic/ntdownloader.dm | 5 +++-- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/code/modules/modular_computers/file_system/program.dm b/code/modules/modular_computers/file_system/program.dm index 953e4fb8d0..dc06e82279 100644 --- a/code/modules/modular_computers/file_system/program.dm +++ b/code/modules/modular_computers/file_system/program.dm @@ -100,8 +100,9 @@ // Check if the user can run program. Only humans can operate computer. Automatically called in run_program() // User has to wear their ID or have it inhand for ID Scan to work. -// Can also be called manually, with optional parameter being access_to_check to scan the user's ID -/datum/computer_file/program/proc/can_run(var/mob/living/user, var/loud = 0, var/access_to_check) +// Can also be called manually, with optional parameter being access_to_check to scan the user's ID. +// explicit_card can be passed by callers that already have a card reference (e.g. the laptop's inserted card). +/datum/computer_file/program/proc/can_run(var/mob/living/user, var/loud = 0, var/access_to_check, var/obj/item/card/id/explicit_card) // Defaults to required_access if(!access_to_check) access_to_check = required_access @@ -115,7 +116,9 @@ if(!istype(user)) return 0 - var/obj/item/card/id/I = user.GetIdCard() + // Resolve the card to check: caller-supplied card first, then the user's worn/held ID, + // then fall back to whatever is inserted in the computer's card slot. + var/obj/item/card/id/I = explicit_card || user.GetIdCard() || computer?.card_slot?.stored_card if(!I) if(loud) to_chat(user, span_notice("\The [computer] flashes an \"RFID Error - Unable to scan ID\" warning.")) @@ -140,7 +143,10 @@ computer.active_program = src if(tguimodule_path) TM = new tguimodule_path(src) - TM.using_access = user.GetAccess() + // Prefer the card inserted into the computer's card slot for access checks; + // fall back to the user's own access if no card is slotted. + var/obj/item/card/id/auth_card = computer?.card_slot?.stored_card + TM.using_access = auth_card ? auth_card.GetAccess() : user.GetAccess() if(requires_ntnet && network_destination) generate_network_log("Connection opened to [network_destination].") program_state = PROGRAM_STATE_ACTIVE diff --git a/code/modules/modular_computers/file_system/programs/generic/ntdownloader.dm b/code/modules/modular_computers/file_system/programs/generic/ntdownloader.dm index 7acc272f49..d8398c7577 100644 --- a/code/modules/modular_computers/file_system/programs/generic/ntdownloader.dm +++ b/code/modules/modular_computers/file_system/programs/generic/ntdownloader.dm @@ -155,8 +155,9 @@ data["disk_used"] = my_computer.hard_drive.used_capacity var/list/all_entries[0] for(var/datum/computer_file/program/P in GLOB.ntnet_global.available_station_software) - // Only those programs our user can run will show in the list - if(!P.can_run(user) && P.requires_access_to_download || my_computer.hard_drive.find_file_by_name(P.filename)) + // Only those programs our user can run will show in the list. + // Pass the card inserted in the laptop's slot so slotted IDs are respected. + if(!P.can_run(user, 0, null, my_computer.card_slot?.stored_card) && P.requires_access_to_download || my_computer.hard_drive.find_file_by_name(P.filename)) continue all_entries.Add(list(list( "filename" = P.filename,