From ab9daa1cba210a7dc287cd8602a6ebba4f786ebd Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Fri, 1 Oct 2021 22:08:59 +0200 Subject: [PATCH] [MIRROR] Add the ability to cancel incoming and outgoing cross comms console messages for admins [MDB IGNORE] (#8538) * Add the ability to cancel incoming and outgoing cross comms console messages for admins (#61799) You can now cancel incoming and outgoing cross comms console messages. * Add the ability to cancel incoming and outgoing cross comms console messages for admins Co-authored-by: Mothblocks <35135081+Mothblocks@users.noreply.github.com> --- code/__DEFINES/communications.dm | 2 + code/datums/world_topic.dm | 54 +++++++++++++++- .../game/machinery/computer/communications.dm | 63 ++++++++++++++++--- tgstation.dme | 1 + 4 files changed, 108 insertions(+), 12 deletions(-) create mode 100644 code/__DEFINES/communications.dm diff --git a/code/__DEFINES/communications.dm b/code/__DEFINES/communications.dm new file mode 100644 index 00000000000..c8403bade30 --- /dev/null +++ b/code/__DEFINES/communications.dm @@ -0,0 +1,2 @@ +/// The time an admin has to cancel a cross-sector message +#define CROSS_SECTOR_CANCEL_TIME (10 SECONDS) diff --git a/code/datums/world_topic.dm b/code/datums/world_topic.dm index 63dcd56a542..662dc1a1472 100644 --- a/code/datums/world_topic.dm +++ b/code/datums/world_topic.dm @@ -90,6 +90,8 @@ keyword = "Comms_Console" require_comms_key = TRUE + var/list/timers + /datum/world_topic/comms_console/Run(list/input) // Reject comms messages from other servers that are not on our configured network, // if this has been configured. (See CROSS_COMMS_NETWORK in comms.txt) @@ -97,10 +99,58 @@ if (configured_network && configured_network != input["network"]) return + // We can't add the timer without the timer ID, but we can't get the timer ID without the timer! + // To solve this, we just use a list that we mutate later. + var/list/data = list("input" = input) + var/timer_id = addtimer(CALLBACK(src, .proc/receive_cross_comms_message, data), CROSS_SECTOR_CANCEL_TIME, TIMER_STOPPABLE) + data["timer_id"] = timer_id + + LAZYADD(timers, timer_id) + + to_chat( + GLOB.admins, + span_adminnotice( \ + "CROSS-SECTOR MESSAGE (INCOMING): [input["sender_ckey"]] (from [input["source"]]) is about to send \ + the following message (will autoapprove in [DisplayTimeText(CROSS_SECTOR_CANCEL_TIME)]): \ + REJECT
\ + [html_encode(input["message"])]" \ + ) + ) + +/datum/world_topic/comms_console/Topic(href, list/href_list) + . = ..() + if (.) + return + + if (href_list["reject_cross_comms_message"]) + if (!usr.client?.holder) + log_game("[key_name(usr)] tried to reject an incoming cross-comms message without being an admin.") + message_admins("[key_name(usr)] tried to reject an incoming cross-comms message without being an admin.") + return + + var/timer_id = href_list["reject_cross_comms_message"] + if (!(timer_id in timers)) + to_chat(usr, span_warning("It's too late!")) + return + + deltimer(timer_id) + LAZYREMOVE(timers, timer_id) + + log_admin("[key_name(usr)] has cancelled the incoming cross-comms message.") + message_admins("[key_name(usr)] has cancelled the incoming cross-comms message.") + + return TRUE + +/datum/world_topic/comms_console/proc/receive_cross_comms_message(list/data) + var/list/input = data["input"] + var/timer_id = data["timer_id"] + + LAZYREMOVE(timers, timer_id) + minor_announce(input["message"], "Incoming message from [input["message_sender"]]") message_admins("Receiving a message from [input["sender_ckey"]] at [input["source"]]") - for(var/obj/machinery/computer/communications/CM in GLOB.machines) - CM.override_cooldown() + for(var/obj/machinery/computer/communications/communications_console in GLOB.machines) + communications_console.override_cooldown() /datum/world_topic/news_report keyword = "News_Report" diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm index 9dc4a4c83a2..6dda8fcfb38 100755 --- a/code/game/machinery/computer/communications.dm +++ b/code/game/machinery/computer/communications.dm @@ -40,6 +40,9 @@ /// Used to clear the modal to change alert level var/alert_level_tick = 0 + /// The timer ID for sending the next cross-comms message + var/send_cross_comms_message_timer + /// The last lines used for changing the status display var/static/last_status_display @@ -272,18 +275,19 @@ playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE) var/destination = params["destination"] - var/list/payload = list() - var/network_name = CONFIG_GET(string/cross_comms_network) - if (network_name) - payload["network"] = network_name - payload["sender_ckey"] = usr.ckey + log_game("[key_name(usr)] is about to send the following message to [destination]: [message]") + to_chat( + GLOB.admins, + span_adminnotice( \ + "CROSS-SECTOR MESSAGE (OUTGOING): [ADMIN_LOOKUPFLW(usr)] is about to send \ + the following message to [destination] (will autoapprove in [DisplayTimeText(CROSS_SECTOR_CANCEL_TIME)]): \ + REJECT
\ + [html_encode(message)]" \ + ) + ) - send2otherserver(html_decode(station_name()), message, "Comms_Console", destination == "all" ? null : list(destination), additional_data = payload) - minor_announce(message, title = "Outgoing message to allied station") - usr.log_talk(message, LOG_SAY, tag = "message to the other server") - message_admins("[ADMIN_LOOKUPFLW(usr)] has sent a message to the other server\[s].") - deadchat_broadcast(" has sent an outgoing message to the other station(s).", "[usr.real_name]", usr, message_type = DEADCHAT_ANNOUNCEMENT) + send_cross_comms_message_timer = addtimer(CALLBACK(src, .proc/send_cross_comms_message, usr, destination, message), CROSS_SECTOR_CANCEL_TIME, TIMER_STOPPABLE) COOLDOWN_START(src, important_action_cooldown, IMPORTANT_ACTION_COOLDOWN) if ("setState") @@ -395,6 +399,22 @@ last_toggled = world.time return FALSE //if we are not in cooldown, allow using the button +/obj/machinery/computer/communications/proc/send_cross_comms_message(mob/user, destination, message) + send_cross_comms_message_timer = null + + var/list/payload = list() + + var/network_name = CONFIG_GET(string/cross_comms_network) + if (network_name) + payload["network"] = network_name + payload["sender_ckey"] = usr.ckey + + send2otherserver(html_decode(station_name()), message, "Comms_Console", destination == "all" ? null : list(destination), additional_data = payload) + minor_announce(message, title = "Outgoing message to allied station") + usr.log_talk(message, LOG_SAY, tag = "message to the other server") + message_admins("[ADMIN_LOOKUPFLW(usr)] has sent a message to the other server\[s].") + deadchat_broadcast(" has sent an outgoing message to the other station(s).", "[usr.real_name]", usr, message_type = DEADCHAT_ANNOUNCEMENT) + /obj/machinery/computer/communications/ui_data(mob/user) var/list/data = list( "authenticated" = FALSE, @@ -545,6 +565,29 @@ "maxMessageLength" = MAX_MESSAGE_LEN, ) +/obj/machinery/computer/communications/Topic(href, href_list) + . = ..() + if (.) + return + + if (href_list["reject_cross_comms_message"]) + if (!usr.client?.holder) + log_game("[key_name(usr)] tried to reject a cross-comms message without being an admin.") + message_admins("[key_name(usr)] tried to reject a cross-comms message without being an admin.") + return + + if (isnull(send_cross_comms_message_timer)) + to_chat(usr, span_warning("It's too late!")) + return + + deltimer(send_cross_comms_message_timer) + send_cross_comms_message_timer = null + + log_admin("[key_name(usr)] has cancelled the outgoing cross-comms message.") + message_admins("[key_name(usr)] has cancelled the outgoing cross-comms message.") + + return TRUE + /// Returns whether or not the communications console can communicate with the station /obj/machinery/computer/communications/proc/has_communication() var/turf/current_turf = get_turf(src) diff --git a/tgstation.dme b/tgstation.dme index 3f104c7e2a2..896d00cbd5a 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -48,6 +48,7 @@ #include "code\__DEFINES\cleaning.dm" #include "code\__DEFINES\colors.dm" #include "code\__DEFINES\combat.dm" +#include "code\__DEFINES\communications.dm" #include "code\__DEFINES\configuration.dm" #include "code\__DEFINES\construction.dm" #include "code\__DEFINES\cooldowns.dm"