From 1d2f929c901f1b8607c75dfb269202012507ab76 Mon Sep 17 00:00:00 2001 From: Contrabang <91113370+Contrabang@users.noreply.github.com> Date: Sun, 23 Jul 2023 18:31:29 -0400 Subject: [PATCH] Keycard Authenticator now has 20 seconds to swipe, but requires 2 different people. (#21682) * woo keycards * wowee --- .../security_levels/keycard_authentication.dm | 121 +++++++++--------- 1 file changed, 61 insertions(+), 60 deletions(-) diff --git a/code/modules/security_levels/keycard_authentication.dm b/code/modules/security_levels/keycard_authentication.dm index 0db0068b235..721f6c61f75 100644 --- a/code/modules/security_levels/keycard_authentication.dm +++ b/code/modules/security_levels/keycard_authentication.dm @@ -7,13 +7,12 @@ var/active = FALSE // This gets set to TRUE on all devices except the one where the initial request was made. var/event var/swiping = FALSE // on swiping screen? - var/list/ert_chosen = list() - var/confirmed = FALSE // This variable is set by the device that confirms the request. - var/confirm_delay = 5 SECONDS // time allowed for a second person to confirm a swipe. - var/busy = FALSE // Busy when waiting for authentication or an event request has been sent from this device. + var/confirm_delay = 20 SECONDS // time allowed for a second person to confirm a swipe. + /// True when a request is sent from another device. So someone on the other end can't just close the ERT menu while someone is typing + var/busy = FALSE var/obj/machinery/keycard_auth/event_source - var/mob/event_triggered_by - var/mob/event_confirmed_by + var/mob/triggered_by + var/mob/confirmed_by var/ert_reason anchored = TRUE @@ -27,7 +26,7 @@ /obj/machinery/keycard_auth/update_icon_state() . = ..() - if(event_triggered_by || event_source) + if(triggered_by || event_source) icon_state = "auth_on" else icon_state = "auth_off" @@ -36,37 +35,42 @@ . = ..() underlays.Cut() - if(event_triggered_by || event_source) + if(triggered_by || event_source) underlays += emissive_appearance(icon, "auth_lightmask") -/obj/machinery/keycard_auth/attack_ai(mob/user as mob) +/obj/machinery/keycard_auth/attack_ai(mob/user) to_chat(user, "The station AI is not to interact with these devices.") return -/obj/machinery/keycard_auth/attackby(obj/item/W as obj, mob/user as mob, params) +/obj/machinery/keycard_auth/attackby(obj/item/W, mob/user, params) if(stat & (NOPOWER|BROKEN)) to_chat(user, "This device is not powered.") return if(istype(W, /obj/item/card/id) || istype(W, /obj/item/pda)) - if(check_access(W)) - if(active) - //This is not the device that made the initial request. It is the device confirming the request. - if(event_source) - event_source.confirmed = TRUE - event_source.event_confirmed_by = usr - SStgui.update_uis(event_source) - SStgui.update_uis(src) - else if(swiping) - if(event == "Emergency Response Team" && !ert_reason) - to_chat(user, "Supply a reason for calling the ERT first!") - return - event_triggered_by = usr - SStgui.update_uis(src) - broadcast_request() //This is the device making the initial event request. It needs to broadcast to other devices - else + if(!check_access(W)) to_chat(user, "Access denied.") - return + return + if(user == event_source?.triggered_by) + to_chat(user, "Identical body-signature detected. Access denied.") + return + if(active) + //This is not the device that made the initial request. It is the device confirming the request. + if(!event_source) + return + event_source.confirmed_by = user + SStgui.update_uis(event_source) + SStgui.update_uis(src) + event_source.confirm_and_trigger() + reset() + return + if(swiping) + if(event == "Emergency Response Team" && !ert_reason) + to_chat(user, "Supply a reason for calling the ERT first!") + return + triggered_by = user + SStgui.update_uis(src) + broadcast_request() //This is the device making the initial event request. It needs to broadcast to other devices return ..() /obj/machinery/keycard_auth/power_change() @@ -97,8 +101,8 @@ data["event"] = active && event_source && event_source.event ? event_source.event : event data["ertreason"] = active && event_source && event_source.ert_reason ? event_source.ert_reason : ert_reason data["isRemote"] = active ? TRUE : FALSE - data["hasSwiped"] = event_triggered_by ? TRUE : FALSE - data["hasConfirm"] = event_confirmed_by || (active && event_source && event_source.event_confirmed_by) ? TRUE : FALSE + data["hasSwiped"] = triggered_by ? TRUE : FALSE + data["hasConfirm"] = confirmed_by || (active && event_source && event_source.confirmed_by) ? TRUE : FALSE return data /obj/machinery/keycard_auth/ui_act(action, params) @@ -126,10 +130,10 @@ active = FALSE event = null swiping = FALSE - confirmed = FALSE + busy = FALSE event_source = null - event_triggered_by = null - event_confirmed_by = null + triggered_by = null + confirmed_by = null set_light(0) update_icon() @@ -137,39 +141,32 @@ update_icon() set_light(1, LIGHTING_MINIMUM_POWER) for(var/obj/machinery/keycard_auth/KA in GLOB.machines) - if(KA == src) continue - KA.reset() - spawn() - KA.receive_request(src) + if(KA == src) + continue + KA.receive_request(src) + + addtimer(CALLBACK(src, PROC_REF(reset)), confirm_delay) + +/obj/machinery/keycard_auth/proc/confirm_and_trigger() + trigger_event(event) + log_game("[key_name(triggered_by)] triggered and [key_name(confirmed_by)] confirmed event [event]") + message_admins("[key_name_admin(triggered_by)] triggered and [key_name_admin(confirmed_by)] confirmed event [event]", 1) - sleep(confirm_delay) - if(confirmed) - confirmed = FALSE - trigger_event(event) - log_game("[key_name(event_triggered_by)] triggered and [key_name(event_confirmed_by)] confirmed event [event]") - message_admins("[key_name_admin(event_triggered_by)] triggered and [key_name_admin(event_confirmed_by)] confirmed event [event]", 1) reset() /obj/machinery/keycard_auth/proc/receive_request(obj/machinery/keycard_auth/source) if(stat & (BROKEN|NOPOWER)) return + reset() set_light(1, LIGHTING_MINIMUM_POWER) - event_source = source busy = TRUE active = TRUE SStgui.update_uis(src) update_icon() - sleep(confirm_delay) - - event_source = null - update_icon() - active = FALSE - busy = FALSE - - set_light(0) + addtimer(CALLBACK(src, PROC_REF(reset)), confirm_delay) /obj/machinery/keycard_auth/proc/trigger_event() switch(event) @@ -195,16 +192,20 @@ for(var/client/C in GLOB.admins) if(check_rights(R_EVENT, 0, C.mob)) fullmin_count++ - if(fullmin_count) - GLOB.ert_request_answered = TRUE - ERT_Announce(ert_reason , event_triggered_by, 0) - ert_reason = null - SSblackbox.record_feedback("nested tally", "keycard_auths", 1, list("ert", "called")) - spawn(3000) - if(!GLOB.ert_request_answered) - ERT_Announce(ert_reason , event_triggered_by, 1) - else + if(!fullmin_count) trigger_armed_response_team(new /datum/response_team/amber) // No admins? No problem. Automatically send a code amber ERT. + return + + ERT_Announce(ert_reason, triggered_by, repeat_warning = FALSE) + SSblackbox.record_feedback("nested tally", "keycard_auths", 1, list("ert", "called")) + addtimer(CALLBACK(src, PROC_REF(remind_admins), ert_reason, triggered_by), 5 MINUTES) + ert_reason = null + +/obj/machinery/keycard_auth/proc/remind_admins(old_reason, the_triggerer) // im great at naming variables + if(GLOB.ert_request_answered) + GLOB.ert_request_answered = FALSE // For ERT requests that may come later + return + ERT_Announce(old_reason, the_triggerer, repeat_warning = TRUE) /obj/machinery/keycard_auth/proc/is_ert_blocked() return SSticker.mode && SSticker.mode.ert_disabled