diff --git a/code/__DEFINES/logging.dm b/code/__DEFINES/logging.dm index 8caf205817f6..62c770e6322e 100644 --- a/code/__DEFINES/logging.dm +++ b/code/__DEFINES/logging.dm @@ -5,6 +5,9 @@ /// Admins can still manually request a re-render #define LOG_UPDATE_TIMEOUT 5 SECONDS +// The maximum number of entries allowed in the signaler investigate log, keep this relatively small to prevent performance issues when an admin tries to query it +#define INVESTIGATE_SIGNALER_LOG_MAX_LENGTH 500 + //Investigate logging defines #define INVESTIGATE_ACCESSCHANGES "id_card_changes" #define INVESTIGATE_ATMOS "atmos" diff --git a/code/_globalvars/logging.dm b/code/_globalvars/logging.dm index 914665d17987..8a57ad13ea7e 100644 --- a/code/_globalvars/logging.dm +++ b/code/_globalvars/logging.dm @@ -61,9 +61,17 @@ GLOBAL_PROTECT(admin_activities) GLOBAL_LIST_EMPTY(bombers) GLOBAL_PROTECT(bombers) -/// All signals here in format: "[src] used [REF(src)] @ location [src.loc]: [freq]/[code]" -GLOBAL_LIST_EMPTY(lastsignalers) -GLOBAL_PROTECT(lastsignalers) +/// Investigate log for signaler usage, use the add_to_signaler_investigate_log proc +GLOBAL_LIST_EMPTY(investigate_signaler) +GLOBAL_PROTECT(investigate_signaler) + +/// Used to add a text log to the signaler investigation log. +/// Do not add to the list directly; if the list is too large it can cause lag when an admin tries to view it. +/proc/add_to_signaler_investigate_log(text) + var/log_length = length(GLOB.investigate_signaler) + if(log_length >= INVESTIGATE_SIGNALER_LOG_MAX_LENGTH) + GLOB.investigate_signaler = GLOB.investigate_signaler.Copy((INVESTIGATE_SIGNALER_LOG_MAX_LENGTH - log_length) + 2) + GLOB.investigate_signaler += list(text) /// Stores who uploaded laws to which silicon-based lifeform, and what the law was GLOBAL_LIST_EMPTY(lawchanges) diff --git a/code/modules/admin/verbs/list_exposer.dm b/code/modules/admin/verbs/list_exposer.dm index c2c48963051e..00a5960b3658 100644 --- a/code/modules/admin/verbs/list_exposer.dm +++ b/code/modules/admin/verbs/list_exposer.dm @@ -13,8 +13,8 @@ if(!SSticker.HasRoundStarted()) tgui_alert(usr, "The game hasn't started yet!") return - var/data = "Showing last [length(GLOB.lastsignalers)] signalers.
" - for(var/entry in GLOB.lastsignalers) + var/data = "Showing last [length(GLOB.investigate_signaler)] signalers.
" + for(var/entry in GLOB.investigate_signaler) data += "[entry]
" usr << browse(data, "window=lastsignalers;size=800x500") diff --git a/code/modules/assembly/signaler.dm b/code/modules/assembly/signaler.dm index de9a27404972..d38d20790e14 100644 --- a/code/modules/assembly/signaler.dm +++ b/code/modules/assembly/signaler.dm @@ -10,15 +10,20 @@ drop_sound = 'sound/items/handling/component_drop.ogg' pickup_sound = 'sound/items/handling/component_pickup.ogg' + /// The code sent by this signaler. var/code = DEFAULT_SIGNALER_CODE + /// The frequency this signaler is set to. var/frequency = FREQ_SIGNALER + /// How long of a cooldown exists on this signaller. + var/cooldown_length = 1 SECONDS + /// The radio frequency connection this signaler is using. var/datum/radio_frequency/radio_connection - ///Holds the mind that commited suicide. + /// Holds the mind that commited suicide. var/datum/mind/suicider - ///Holds a reference string to the mob, decides how much of a gamer you are. + /// Holds a reference string to the mob, decides how much of a gamer you are. var/suicide_mob + /// How many tiles away can you hear when this signaler is used or gets activated. var/hearing_range = 1 - /// String containing the last piece of logging data relating to when this signaller has received a signal. var/last_receive_signal_log @@ -77,23 +82,26 @@ /obj/item/assembly/signaler/ui_data(mob/user) var/list/data = list() data["frequency"] = frequency + data["cooldown"] = cooldown_length data["code"] = code data["minFrequency"] = MIN_FREE_FREQ data["maxFrequency"] = MAX_FREE_FREQ return data -/obj/item/assembly/signaler/ui_act(action, params) +/obj/item/assembly/signaler/ui_act(action, params, datum/tgui/ui) . = ..() if(.) return switch(action) if("signal") - if(TIMER_COOLDOWN_CHECK(src, COOLDOWN_SIGNALLER_SEND)) - to_chat(usr, span_warning("[src] is still recharging...")) - return - TIMER_COOLDOWN_START(src, COOLDOWN_SIGNALLER_SEND, 1 SECONDS) + if(cooldown_length > 0) + if(TIMER_COOLDOWN_CHECK(src, COOLDOWN_SIGNALLER_SEND)) + balloon_alert(ui.user, "recharging!") + return + TIMER_COOLDOWN_START(src, COOLDOWN_SIGNALLER_SEND, cooldown_length) INVOKE_ASYNC(src, PROC_REF(signal)) + balloon_alert(ui.user, "signaled") . = TRUE if("freq") var/new_frequency = sanitize_frequency(unformat_frequency(params["freq"]), TRUE) @@ -141,10 +149,8 @@ var/time = time2text(world.realtime,"hh:mm:ss") var/turf/T = get_turf(src) - var/logging_data - if(usr) - logging_data = "[time] : [usr.key] used [src] @ location ([T.x],[T.y],[T.z]) : [format_frequency(frequency)]/[code]" - GLOB.lastsignalers.Add(logging_data) + var/logging_data = "[time] : [key_name(usr)] used [src] @ location ([T.x],[T.y],[T.z]) : [format_frequency(frequency)]/[code]" + add_to_signaler_investigate_log(logging_data) var/datum/signal/signal = new(list("code" = code), logging_data = logging_data) radio_connection.post_signal(src, signal) diff --git a/code/modules/modular_computers/file_system/programs/signalcommander.dm b/code/modules/modular_computers/file_system/programs/signalcommander.dm index 6d636bab370a..e8140b62b17c 100644 --- a/code/modules/modular_computers/file_system/programs/signalcommander.dm +++ b/code/modules/modular_computers/file_system/programs/signalcommander.dm @@ -14,6 +14,10 @@ var/signal_code = DEFAULT_SIGNALER_CODE /// Radio connection datum used by signalers. var/datum/radio_frequency/radio_connection + /// How long do we cooldown before we can send another signal? + var/signal_cooldown_time = 1 SECONDS + /// Cooldown store + COOLDOWN_DECLARE(signal_cooldown) /datum/computer_file/program/signal_commander/on_start(mob/living/user) . = ..() @@ -26,6 +30,7 @@ /datum/computer_file/program/signal_commander/ui_data(mob/user) var/list/data = list() data["frequency"] = signal_frequency + data["cooldown"] = signal_cooldown_time data["code"] = signal_code data["minFrequency"] = MIN_FREE_FREQ data["maxFrequency"] = MAX_FREE_FREQ @@ -55,13 +60,18 @@ if(!radio_connection) return + if(!COOLDOWN_FINISHED(src, signal_cooldown)) + computer.balloon_alert(usr, "cooling down!") + return + + COOLDOWN_START(src, signal_cooldown, signal_cooldown_time) + computer.balloon_alert(usr, "signaled") + var/time = time2text(world.realtime,"hh:mm:ss") var/turf/T = get_turf(computer) - var/logging_data - if(usr) - logging_data = "[time] : [usr.key] used [computer] @ location ([T.x],[T.y],[T.z]) : [format_frequency(signal_frequency)]/[signal_code]" - GLOB.lastsignalers.Add(logging_data) + var/logging_data = "[time] : [key_name(usr)] used the computer '[initial(computer.name)]' @ location ([T.x],[T.y],[T.z]) : [format_frequency(signal_frequency)]/[signal_code]" + add_to_signaler_investigate_log(logging_data) var/datum/signal/signal = new(list("code" = signal_code), logging_data = logging_data) radio_connection.post_signal(computer, signal) @@ -70,4 +80,3 @@ SSradio.remove_object(computer, signal_frequency) signal_frequency = new_frequency radio_connection = SSradio.add_object(computer, signal_frequency, RADIO_SIGNALER) - return diff --git a/code/modules/wiremod/components/action/radio.dm b/code/modules/wiremod/components/action/radio.dm index cd13e0e1e451..74b2c54c1b81 100644 --- a/code/modules/wiremod/components/action/radio.dm +++ b/code/modules/wiremod/components/action/radio.dm @@ -28,8 +28,17 @@ /// The ckey of the user who used the shell we were placed in, important for signalling logs. var/owner_ckey = null + /// The radio connection we are using to receive signals. var/datum/radio_frequency/radio_connection + /// How long of a cooldown we have before we can send another signal. + var/signal_cooldown_time = 1 SECONDS + +/obj/item/circuit_component/radio/Initialize(mapload) + . = ..() + if(signal_cooldown_time > 0) + desc = "[desc] It has a [signal_cooldown_time * 0.1] second cooldown between sending signals." + /obj/item/circuit_component/radio/register_shell(atom/movable/shell) parent_shell = shell var/potential_fingerprints = shell.fingerprintslast @@ -65,8 +74,10 @@ INVOKE_ASYNC(src, PROC_REF(handle_radio_input), port) /obj/item/circuit_component/radio/proc/handle_radio_input(datum/port/input/port) - var/frequency = freq.value + if(!TIMER_COOLDOWN_CHECK(parent, COOLDOWN_SIGNALLER_SEND)) + return + var/frequency = freq.value if(frequency != current_freq) SSradio.remove_object(src, current_freq) radio_connection = SSradio.add_object(src, frequency, RADIO_SIGNALER) @@ -84,7 +95,8 @@ loggable_strings += ": The last fingerprints on the containing shell was [parent_shell.fingerprintslast]." var/loggable_string = loggable_strings.Join(" ") - GLOB.lastsignalers.Add(loggable_string) + add_to_signaler_investigate_log(loggable_string) + TIMER_COOLDOWN_START(parent, COOLDOWN_SIGNALLER_SEND, signal_cooldown_time) var/datum/signal/signal = new(list("code" = signal_code, "key" = parent?.owner_id), logging_data = loggable_string) radio_connection.post_signal(src, signal) diff --git a/tgui/packages/tgui/interfaces/Signaler.jsx b/tgui/packages/tgui/interfaces/Signaler.jsx index 81ee5a370c81..f3348b081c6c 100644 --- a/tgui/packages/tgui/interfaces/Signaler.jsx +++ b/tgui/packages/tgui/interfaces/Signaler.jsx @@ -16,7 +16,7 @@ export const Signaler = (props) => { export const SignalerContent = (props) => { const { act, data } = useBackend(); - const { code, frequency, minFrequency, maxFrequency } = data; + const { code, frequency, cooldown, minFrequency, maxFrequency } = data; const color = 'rgba(13, 13, 213, 0.7)'; const backColor = 'rgba(0, 0, 69, 0.5)'; return ( @@ -94,6 +94,7 @@ export const SignalerContent = (props) => {