From ea111b194e0cbd1ed9766f9cb58269310cab3b7c Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Thu, 7 Mar 2024 04:27:03 +0100 Subject: [PATCH] [MIRROR] Feeds OOC messages back to client if blocked in validate_client() (#26779) * Feeds OOC messages back to client if blocked in validate_client() (#81769) ## About The Pull Request Basically, if your long and well-thought-out OOC message gets eaten due to your client not being fully initialized, the server will feed back the message to you so you can copy-paste and try again. In order to facilitate this, I turned `validate_client` into a proc. This didn't have the ubiquitous usage that we were hoping for (where it could be dropped and placed anywhere) and I don't think I liked the "always exit out of proc" stuff anyhow. Also adds some code niceties. There's probably a way cooler way to do this with tgui_say and whatever but I don't use tgui_say (byond command bar my beloved) so we'll cope with this. ## Why It's Good For The Game ![image](https://github.com/tgstation/tgstation/assets/34697715/a96f7168-aad3-4772-9abe-7a6aa2b8779a) Let me know if I should revert the `span_big()` stuff, I just added it because I wanted it to be obvious to the player instead of look like a generic error message. ## Changelog :cl: qol: If your OOC message gets eaten due to some weird circumstance in how your message is handled, it will feed the applicable message back to you so you can copy-paste and try to send it again. /:cl: * Feeds OOC messages back to client if blocked in validate_client() --------- Co-authored-by: san7890 --- code/__DEFINES/client.dm | 11 +++-------- code/__HELPERS/clients.dm | 6 ++++++ code/modules/client/verbs/ooc.dm | 11 +++++++---- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/code/__DEFINES/client.dm b/code/__DEFINES/client.dm index 0914bc025ad..17571b5270b 100644 --- a/code/__DEFINES/client.dm +++ b/code/__DEFINES/client.dm @@ -1,11 +1,6 @@ /// Checks if the given target is either a client or a mock client #define IS_CLIENT_OR_MOCK(target) (istype(target, /client) || istype(target, /datum/client_interface)) -/// Ensures that the client has been fully initialized via New(), and can't somehow execute actions before that. Security measure. -/// WILL RETURN OUT OF THE ENTIRE PROC COMPLETELY IF THE CLIENT IS NOT FULLY INITIALIZED. BE WARNED IF YOU WANT RETURN VALUES. -#define VALIDATE_CLIENT(target)\ - if (!target.fully_created) {\ - to_chat(target, span_warning("You are not fully initialized yet! Please wait a moment."));\ - log_access("Client [key_name(target)] attempted to execute a verb before being fully initialized.");\ - return\ - } +/// Checks to see if a /client has fully gone through New() as a safeguard against certain operations. +/// Should return the boolean value of the fully_created var, which should be TRUE if New() has finished running. FALSE otherwise. +#define VALIDATE_CLIENT_INITIALIZATION(target) (target.fully_created) diff --git a/code/__HELPERS/clients.dm b/code/__HELPERS/clients.dm index 3b61cf1e1c4..156f9e2b5dc 100644 --- a/code/__HELPERS/clients.dm +++ b/code/__HELPERS/clients.dm @@ -10,3 +10,9 @@ if (ch < 48 || ch > 57) //0-9 return FALSE return TRUE + +/// Proc that just logs whenever an uninitialized client tries to do something before they have fully gone through New(). +/// Intended to be used in conjunction with the `VALIDATE_CLIENT_INITIALIZATION()` macro, but can be dropped anywhere when we look at the `fully_created` var on /client. +/proc/unvalidated_client_error(client/target) + to_chat(target, span_warning("You are not fully initialized yet! Please wait a moment.")) + log_access("Client [key_name(target)] attempted to execute a verb before being fully initialized.") diff --git a/code/modules/client/verbs/ooc.dm b/code/modules/client/verbs/ooc.dm index 5df802b9f60..dc55b72b09d 100644 --- a/code/modules/client/verbs/ooc.dm +++ b/code/modules/client/verbs/ooc.dm @@ -10,12 +10,15 @@ GLOBAL_VAR_INIT(normal_ooc_colour, "#002eb8") to_chat(usr, span_danger("Speech is currently admin-disabled.")) return - if(!mob) + var/client_initalized = VALIDATE_CLIENT_INITIALIZATION(src) + if(isnull(mob) || !client_initalized) + if(!client_initalized) + unvalidated_client_error() // we only want to throw this warning message when it's directly related to client failure. + + to_chat(usr, span_warning("Failed to send your OOC message. You attempted to send the following message:\n[span_big(msg)]")) return - VALIDATE_CLIENT(src) - - if(!holder) + if(isnull(holder)) if(!GLOB.ooc_allowed) to_chat(src, span_danger("OOC is globally muted.")) return