From 58caf75e0c5a3bf0c164f8fcd525a8bf8d76b39f Mon Sep 17 00:00:00 2001 From: Roxy <75404941+TealSeer@users.noreply.github.com> Date: Thu, 16 Jul 2026 16:12:43 -0500 Subject: [PATCH] Fix FaxBond not notifying for new faxes (#96990) ## About The Pull Request Using a (DCS) signal was a nice idea but it ran into the problem of spam filters on telecomms machines, if each subscribed PDA is responsible for sending the (PDA message) signal to themselves (and because there is always at least 5 instances of head PDAs stored in `SSwardrobe`) only the first one gets through before telecomms refuses to send the rest. This moves it from a DCS signal registered on the fax machine and handled on the PDA to a system where PDAs register themselves with the fax machine and when it receives a fax it builds a single message signal addressed to all the targets and sends that instead. ## Why It's Good For The Game Fixes #96902 ## Changelog :cl: fix: fixed FaxBond not sending notifications when faxes are received /:cl: --- .../file_system/programs/faxnotif.dm | 34 +++---------------- code/modules/paperwork/fax.dm | 32 +++++++++++++++++ 2 files changed, 36 insertions(+), 30 deletions(-) diff --git a/code/modules/modular_computers/file_system/programs/faxnotif.dm b/code/modules/modular_computers/file_system/programs/faxnotif.dm index 5cadc4b4d1f..7b359f9f52c 100644 --- a/code/modules/modular_computers/file_system/programs/faxnotif.dm +++ b/code/modules/modular_computers/file_system/programs/faxnotif.dm @@ -14,7 +14,7 @@ var/list/connected_faxes = list() /** - * Proc for subscribing to faxes. Registers needed signal and updates fax related vars for program. Includes type checking. + * Proc for subscribing to faxes. Adds weakref to fax's listeners and updates fax related vars for program. Includes type checking. * Arguments: * * target - [/datum/computer_file/program/proc/tap] proc target, can be anything */ @@ -25,7 +25,7 @@ var/our_id = target.fax_id if(!connected_faxes[our_id]) - RegisterSignal(target, COMSIG_FAX_MESSAGE_RECEIVED, PROC_REF(on_fax_message_received)) + LAZYSET(target.fax_listeners, REF(src), WEAKREF(src)) var/list/fax_info = list() var/area/our_area = get_area(target) @@ -38,7 +38,7 @@ return TRUE /** - * Disconnects a fax given its ID (if it was connected before), removing it from a list and unregistering relevant signal + * Disconnects a fax given its ID (if it was connected before), removing it from the relevant lists. * Arguments: * * fax_id - fax id to disconnect from our PDA */ @@ -50,36 +50,10 @@ var/datum/weakref/fax_ref = fax_info["ref"] var/obj/machinery/fax/our_fax = fax_ref.resolve() if (our_fax) - UnregisterSignal(our_fax, COMSIG_FAX_MESSAGE_RECEIVED) + LAZYREMOVE(our_fax.fax_listeners, REF(src)) connected_faxes -= fax_id - -/** - * Signal handler for [COMSIG_FAX_MESSAGE_RECEIVED]. - * Arguments: - * * receiver - [/obj/machinery/fax] that received a message - * * message_source - name of a sender - */ -/datum/computer_file/program/faxbond/proc/on_fax_message_received(obj/machinery/fax/receiver, message_source) - SIGNAL_HANDLER - - var/id = receiver.fax_id - var/list/fax_info = connected_faxes[id] - - if (fax_info["muted"]) - return - - var/datum/computer_file/program/messenger/messenger = locate() in computer.stored_files - var/datum/signal/subspace/messaging/tablet_message/signal = new(receiver, list( - "fakename" = "Fax Notificator", - "fakejob" = "PDA Program", - "message" = "Your fax [receiver.fax_name] has received a new message from [message_source]", - "targets" = list(messenger), - "automated" = TRUE - )) - INVOKE_ASYNC(signal, TYPE_PROC_REF(/datum/signal/subspace, send_to_receivers)) - /datum/computer_file/program/faxbond/Destroy() . = ..() for(var/fax in connected_faxes) diff --git a/code/modules/paperwork/fax.dm b/code/modules/paperwork/fax.dm index 80c84d5d333..8d43a108524 100644 --- a/code/modules/paperwork/fax.dm +++ b/code/modules/paperwork/fax.dm @@ -32,6 +32,8 @@ GLOBAL_VAR_INIT(fax_autoprinting, FALSE) var/allow_exotic_faxes = FALSE /// This is where the dispatch and reception history for each fax is stored. var/list/fax_history = list() + /// Lazy assoc list of (FaxBond ref string = FaxBond weakref) connected to us + var/list/fax_listeners /// List of types which should always be allowed to be faxed var/static/list/allowed_types = list( /obj/item/canvas, @@ -441,6 +443,36 @@ GLOBAL_VAR_INIT(fax_autoprinting, FALSE) history_add("Receive", sender_name) addtimer(CALLBACK(src, PROC_REF(vend_item), loaded), 1.9 SECONDS) SEND_SIGNAL(src, COMSIG_FAX_MESSAGE_RECEIVED, sender_name) + if(LAZYLEN(fax_listeners)) + alert_listeners(sender_name) + +/** + * Called when a fax is received, iterates through subscribed Faxbonds and notifies them. + * Arguments: + * * sender_name - Name of fax sender, used in the PDA message. +*/ +/obj/machinery/fax/proc/alert_listeners(sender_name) + set waitfor = FALSE + + var/list/targets = list() + for(var/refstring, weakref in fax_listeners) + var/datum/weakref/app_ref = weakref + var/datum/computer_file/program/faxbond/app = app_ref?.resolve() + if(!app || app.connected_faxes[fax_id]["muted"]) + continue + var/datum/computer_file/program/messenger/messenger = locate() in app.computer.stored_files + if(messenger) + targets += messenger + if(!length(targets)) + return + var/datum/signal/subspace/messaging/tablet_message/signal = new(src, list( + "fakename" = "Fax Notificator", + "fakejob" = "PDA Program", + "message" = "Your fax [fax_name] has received a new message from [sender_name]", + "targets" = targets, + "automated" = TRUE + )) + signal.send_to_receivers() /** * Procedure for animating an object entering or leaving the fax machine.