From bcb5fbc83cb22a2c955eaa0b815afdc976609de2 Mon Sep 17 00:00:00 2001
From: SkyratBot <59378654+SkyratBot@users.noreply.github.com>
Date: Wed, 14 Oct 2020 18:45:53 +0200
Subject: [PATCH] [MIRROR] TGUI Communications console (#1286)
* TGUI Communications console
* fix
Co-authored-by: Jared-Fogle <35135081+Jared-Fogle@users.noreply.github.com>
Co-authored-by: Gandalf
\nETA: [timeleft / 60 % 60]:[add_leading(num2text(timeleft % 60), 2, "0")]"
+ . = TRUE
+ switch (action)
+ if ("answerMessage")
+ if (!authenticated(usr))
+ return
+ var/answer_index = text2num(params["answer"])
+ var/message_index = text2num(params["message"])
+ if (!answer_index || !message_index || answer_index < 1 || message_index < 1)
+ return
+ var/datum/comm_message/message = messages[message_index]
+ if (message.answered)
+ return
+ message.answered = answer_index
+ message.answer_callback.InvokeAsync()
+ if ("callShuttle")
+ if (!authenticated(usr))
+ return
+ var/reason = trim(params["reason"], MAX_MESSAGE_LEN)
+ if (length(reason) < CALL_SHUTTLE_REASON_LENGTH)
+ return
+ SSshuttle.requestEvac(usr, reason)
+ post_status("shuttle")
+ if ("changeSecurityLevel")
+ if (!authenticated_as_ai_or_captain(usr))
+ return
- var/datum/browser/popup = new(user, "communications", "Communications Console", 400, 500)
+ // Check if they have
+ if (!isAI(usr))
+ var/obj/item/held_item = usr.get_active_held_item()
+ var/obj/item/card/id/id_card = held_item?.GetID()
+ if (!istype(id_card))
+ to_chat(usr, "You need to swipe your ID!")
+ playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, FALSE)
+ return
+ if (!(ACCESS_CAPTAIN in id_card.access))
+ to_chat(usr, "You are not authorized to do this!")
+ playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, FALSE)
+ return
- if(issilicon(user))
- var/dat2 = interact_ai(user) // give the AI a different interact proc to limit its access
- if(dat2)
- dat += dat2
- popup.set_content(dat)
- popup.open()
- return
+ var/new_sec_level = seclevel2num(params["newSecurityLevel"])
+ if (new_sec_level != SEC_LEVEL_GREEN && new_sec_level != SEC_LEVEL_BLUE)
+ return
+ if (GLOB.security_level == new_sec_level)
+ return
- switch(state)
- if(STATE_DEFAULT)
- if (authenticated)
- if(SSshuttle.emergencyCallAmount)
- if(SSshuttle.emergencyLastCallLoc)
- dat += "Most recent shuttle call/recall traced to: [format_text(SSshuttle.emergencyLastCallLoc.name)]
"
- else
- dat += "Unable to trace most recent shuttle call/recall signal.
"
- dat += "Logged in as: [auth_id]"
- dat += "
"
- dat += "
\[ Log Out \]
"
- dat += "
General Functions"
- dat += "
\[ Message List \]"
- switch(SSshuttle.emergency.mode)
- if(SHUTTLE_IDLE, SHUTTLE_RECALL)
- dat += "
\[ Call Emergency Shuttle \]"
- else
- dat += "
\[ Cancel Shuttle Call \]"
+ set_security_level(new_sec_level)
- dat += "
\[ Set Status Display \]"
- if (authenticated==2)
- dat += "
Captain Functions"
- dat += "
\[ Make a Captain's Announcement \]"
- var/list/cross_servers = CONFIG_GET(keyed_list/cross_server)
+ to_chat(usr, "Authorization confirmed. Modifying security level.")
+ playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE)
+
+ // Only notify people if an actual change happened
+ log_game("[key_name(usr)] has changed the security level to [params["newSecurityLevel"]] with [src] at [AREACOORD(usr)].")
+ message_admins("[ADMIN_LOOKUPFLW(usr)] has changed the security level to [params["newSecurityLevel"]] with [src] at [AREACOORD(usr)].")
+ deadchat_broadcast(" has changed the security level to [params["newSecurityLevel"]] with [src] at [get_area_name(usr, TRUE)].", "[usr.real_name]", usr, message_type=DEADCHAT_ANNOUNCEMENT)
+
+ alert_level_tick += 1
+ if ("deleteMessage")
+ if (!authenticated(usr))
+ return
+ var/message_index = text2num(params["message"])
+ if (!message_index)
+ return
+ LAZYREMOVE(messages, LAZYACCESS(messages, message_index))
+ if ("makePriorityAnnouncement")
+ if (!authenticated_as_ai_or_captain(usr))
+ return
+ make_announcement(usr)
+ if ("messageAssociates")
+ if (!authenticated_as_non_ai_captain(usr))
+ return
+ if (!COOLDOWN_FINISHED(src, important_action_cooldown))
+ return
+
+ playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE)
+ var/message = trim(html_encode(params["message"]), MAX_MESSAGE_LEN)
+
+ var/emagged = obj_flags & EMAGGED
+ if (emagged)
+ message_syndicate(message, usr)
+ to_chat(usr, "SYSERR @l(19833)of(transmit.dm): !@$ MESSAGE TRANSMITTED TO SYNDICATE COMMAND.")
+ else
+ message_centcom(message, usr)
+ to_chat(usr, "Message transmitted to Central Command.")
+
+ var/associates = emagged ? "the Syndicate": "CentCom"
+ usr.log_talk(message, LOG_SAY, tag = "message to [associates]")
+ deadchat_broadcast(" has messaged [associates], \"[message]\" at [get_area_name(usr, TRUE)].", "[usr.real_name]", usr, message_type = DEADCHAT_ANNOUNCEMENT)
+ COOLDOWN_START(src, important_action_cooldown, IMPORTANT_ACTION_COOLDOWN)
+ if ("purchaseShuttle")
+ var/can_buy_shuttles_or_fail_reason = can_buy_shuttles(usr)
+ if (can_buy_shuttles_or_fail_reason != TRUE)
+ if (can_buy_shuttles_or_fail_reason != FALSE)
+ to_chat(usr, "[can_buy_shuttles_or_fail_reason]")
+ return
+ var/list/shuttles = flatten_list(SSmapping.shuttle_templates)
+ var/datum/map_template/shuttle/shuttle = locate(params["shuttle"]) in shuttles
+ if (!istype(shuttle))
+ return
+ if (!shuttle.prerequisites_met())
+ to_chat(usr, "You have not met the requirements for purchasing this shuttle.")
+ return
+ var/datum/bank_account/bank_account = SSeconomy.get_dep_account(ACCOUNT_CAR)
+ if (bank_account.account_balance < shuttle.credit_cost)
+ return
+ SSshuttle.shuttle_purchased = SHUTTLEPURCHASE_PURCHASED
+ SSshuttle.unload_preview()
+ SSshuttle.existing_shuttle = SSshuttle.emergency
+ SSshuttle.action_load(shuttle)
+ bank_account.adjust_money(-shuttle.credit_cost)
+ minor_announce("[usr.real_name] has purchased [shuttle.name] for [shuttle.credit_cost] credits.[shuttle.extra_desc ? " [shuttle.extra_desc]" : ""]" , "Shuttle Purchase")
+ message_admins("[ADMIN_LOOKUPFLW(usr)] purchased [shuttle.name].")
+ log_shuttle("[key_name(usr)] has purchased [shuttle.name].")
+ SSblackbox.record_feedback("text", "shuttle_purchase", 1, shuttle.name)
+ state = STATE_MAIN
+ if ("recallShuttle")
+ // AIs cannot recall the shuttle
+ if (!authenticated(usr) || isAI(usr))
+ return
+ SSshuttle.cancelEvac(usr)
+ if ("requestNukeCodes")
+ if (!authenticated_as_non_ai_captain(usr))
+ return
+ if (!COOLDOWN_FINISHED(src, important_action_cooldown))
+ return
+ var/reason = trim(html_encode(params["reason"]), MAX_MESSAGE_LEN)
+ nuke_request(reason, usr)
+ to_chat(usr, "Request sent.")
+ usr.log_message("has requested the nuclear codes from CentCom with reason \"[reason]\"", LOG_SAY)
+ priority_announce("The codes for the on-station nuclear self-destruct have been requested by [usr]. Confirmation or denial of this request will be sent shortly.", "Nuclear Self-Destruct Codes Requested", 'sound/ai/commandreport.ogg')
+ playsound(src, 'sound/machines/terminal_prompt.ogg', 50, FALSE)
+ COOLDOWN_START(src, important_action_cooldown, IMPORTANT_ACTION_COOLDOWN)
+ if ("restoreBackupRoutingData")
+ if (!authenticated_as_non_ai_captain(usr))
+ return
+ if (!(obj_flags & EMAGGED))
+ return
+ to_chat(usr, "Backup routing data restored.")
+ playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE)
+ obj_flags &= ~EMAGGED
+ if ("sendToOtherSector")
+ if (!authenticated_as_non_ai_captain(usr))
+ return
+ if (!can_send_messages_to_other_sectors(usr))
+ return
+ if (!COOLDOWN_FINISHED(src, important_action_cooldown))
+ return
+
+ var/message = trim(html_encode(params["message"]), MAX_MESSAGE_LEN)
+ if (!message)
+ return
+
+ 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
+
+ send2otherserver(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)
+
+ COOLDOWN_START(src, important_action_cooldown, IMPORTANT_ACTION_COOLDOWN)
+ if ("setState")
+ if (!authenticated(usr))
+ return
+ if (!(params["state"] in approved_states))
+ return
+ if (state == STATE_BUYING_SHUTTLE && can_buy_shuttles(usr) != TRUE)
+ return
+ set_state(usr, params["state"])
+ playsound(src, "terminal_type", 50, FALSE)
+ if ("setStatusMessage")
+ if (!authenticated(usr))
+ return
+ var/line_one = reject_bad_text(params["lineOne"] || "", MAX_STATUS_LINE_LENGTH)
+ var/line_two = reject_bad_text(params["lineTwo"] || "", MAX_STATUS_LINE_LENGTH)
+ post_status("alert", "blank")
+ post_status("message", line_one, line_two)
+ last_status_display = list(line_one, line_two)
+ playsound(src, "terminal_type", 50, FALSE)
+ if ("setStatusPicture")
+ if (!authenticated(usr))
+ return
+ var/picture = params["picture"]
+ if (!(picture in approved_status_pictures))
+ return
+ post_status("alert", picture)
+ playsound(src, "terminal_type", 50, FALSE)
+ if ("toggleAuthentication")
+ // Log out if we're logged in
+ if (authorize_name)
+ authenticated = FALSE
+ authorize_access = null
+ authorize_name = null
+ playsound(src, 'sound/machines/terminal_off.ogg', 50, FALSE)
+ return
+
+ if (obj_flags & EMAGGED)
+ authenticated = TRUE
+ authorize_access = get_all_accesses()
+ authorize_name = "Unknown"
+ to_chat(usr, "[src] lets out a quiet alarm as its login is overridden.")
+ playsound(src, 'sound/machines/terminal_alert.ogg', 25, FALSE)
+ else
+ var/obj/item/card/id/id_card = usr.get_idcard(hand_first = TRUE)
+ if (check_access(id_card))
+ authenticated = TRUE
+ authorize_access = id_card.access
+ authorize_name = "[id_card.registered_name] - [id_card.assignment]"
+
+ state = STATE_MAIN
+ playsound(src, 'sound/machines/terminal_on.ogg', 50, FALSE)
+ if ("toggleEmergencyAccess")
+ if (!authenticated_as_ai_or_captain(usr))
+ return
+ if (GLOB.emergency_access)
+ revoke_maint_all_access()
+ log_game("[key_name(usr)] disabled emergency maintenance access.")
+ message_admins("[ADMIN_LOOKUPFLW(usr)] disabled emergency maintenance access.")
+ deadchat_broadcast(" disabled emergency maintenance access at [get_area_name(usr, TRUE)].", "[usr.real_name]", usr, message_type = DEADCHAT_ANNOUNCEMENT)
+ else
+ make_maint_all_access()
+ log_game("[key_name(usr)] enabled emergency maintenance access.")
+ message_admins("[ADMIN_LOOKUPFLW(usr)] enabled emergency maintenance access.")
+ deadchat_broadcast(" enabled emergency maintenance access at [get_area_name(usr, TRUE)].", "[usr.real_name]", usr, message_type = DEADCHAT_ANNOUNCEMENT)
+
+/obj/machinery/computer/communications/ui_data(mob/user)
+ var/list/data = list(
+ "authenticated" = FALSE,
+ "emagged" = FALSE,
+ )
+
+ var/ui_state = isAI(user) ? ai_state : state
+
+ if (authenticated || isAI(user))
+ data["authenticated"] = TRUE
+ data["canLogOut"] = !isAI(user)
+ data["page"] = ui_state
+
+ if (obj_flags & EMAGGED)
+ data["emagged"] = TRUE
+
+ switch (ui_state)
+ if (STATE_MAIN)
+ data["canBuyShuttles"] = can_buy_shuttles(user)
+ data["canMakeAnnouncement"] = FALSE
+ data["canMessageAssociates"] = FALSE
+ data["canRequestNuke"] = FALSE
+ data["canSendToSectors"] = FALSE
+ data["canSetAlertLevel"] = FALSE
+ data["canToggleEmergencyAccess"] = FALSE
+ data["importantActionReady"] = COOLDOWN_FINISHED(src, important_action_cooldown)
+ data["shuttleCalled"] = FALSE
+ data["shuttleLastCalled"] = FALSE
+
+ data["alertLevel"] = get_security_level()
+ data["authorizeName"] = authorize_name
+ data["canLogOut"] = !isAI(user)
+ data["shuttleCanEvacOrFailReason"] = SSshuttle.canEvac(user)
+
+ if (authenticated_as_non_ai_captain(user))
+ data["canMessageAssociates"] = TRUE
+ data["canRequestNuke"] = TRUE
+
+ if (can_send_messages_to_other_sectors(user))
+ data["canSendToSectors"] = TRUE
+
+ var/list/sectors = list()
var/our_id = CONFIG_GET(string/cross_comms_name)
- if(cross_servers.len)
- for(var/server in cross_servers)
- if(server == our_id)
- continue
- dat += "
\[ Send a message to station in [server] sector. \]"
- if(cross_servers.len > 2)
- dat += "
\[ Send a message to all allied stations \]"
- if(SSmapping.config.allow_custom_shuttles)
- dat += "
\[ Purchase Shuttle \]"
- dat += "
\[ Change Alert Level \]"
- dat += "
\[ Emergency Maintenance Access \]"
- dat += "
\[ Request Nuclear Authentication Codes \]"
- if(!(obj_flags & EMAGGED))
- dat += "
\[ Send Message to CentCom \]"
- else
- dat += "
\[ Send Message to \[UNKNOWN\] \]"
- dat += "
\[ Restore Backup Routing Data \]"
- else
- dat += "
\[ Log In \]"
- if(STATE_CALLSHUTTLE)
- dat += get_call_shuttle_form()
- playsound(src, 'sound/machines/terminal_prompt.ogg', 50, FALSE)
- if(STATE_CANCELSHUTTLE)
- dat += get_cancel_shuttle_form()
- playsound(src, 'sound/machines/terminal_prompt.ogg', 50, FALSE)
- if(STATE_MESSAGELIST)
- dat += "Messages:"
- for(var/i in 1 to messages.len)
- var/datum/comm_message/M = messages[i]
- dat += "
[M.title]"
- playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE)
- if(STATE_VIEWMESSAGE)
- if (currmsg)
- dat += "[currmsg.title]
[currmsg.content]"
- if(!currmsg.answered && currmsg.possible_answers.len)
- for(var/i in 1 to currmsg.possible_answers.len)
- var/answer = currmsg.possible_answers[i]
- dat += "
\[ Answer : [answer] \]"
- else if(currmsg.answered)
- var/answered = currmsg.possible_answers[currmsg.answered]
- dat += "
Archived Answer : [answered]"
- dat += "
\[ Delete \]"
- else
- aistate = STATE_MESSAGELIST
- attack_hand(user)
- return
- if(STATE_DELMESSAGE)
- if (currmsg)
- dat += "Are you sure you want to delete this message? \[ OK | Cancel \]"
- else
- state = STATE_MESSAGELIST
- attack_hand(user)
- return
- if(STATE_STATUSDISPLAY)
- dat += "Set Status Displays
"
- dat += "\[ Clear \]
"
- dat += "\[ Shuttle ETA \]
"
- dat += "\[ Message \]"
- dat += "
"
- dat += "\[ Alert: None |"
- dat += " Red Alert |"
- dat += " Lockdown |"
- dat += " Biohazard \]
"
- playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE)
- if(STATE_ALERT_LEVEL)
- dat += "Current alert level: [get_security_level()]
"
- if(GLOB.security_level == SEC_LEVEL_DELTA)
- dat += "The self-destruct mechanism is active. Find a way to deactivate the mechanism to lower the alert level or evacuate."
- else
- //SKYRAT CHANGE ADDITION BEGIN - ALERTS
- dat += "Amber
"
- dat += "Orange
"
- dat += "Violet
"
- //SKYRAT CHANGE END
- dat += "Blue
"
- dat += "Green"
- if(STATE_CONFIRM_LEVEL)
- dat += "Current alert level: [get_security_level()]
"
- dat += "Confirm the change to: [num2seclevel(tmp_alertlevel)]
"
- dat += "Swipe ID to confirm change.
"
- if(STATE_TOGGLE_EMERGENCY)
- playsound(src, 'sound/machines/terminal_prompt.ogg', 50, FALSE)
- if(GLOB.emergency_access == 1)
- dat += "Emergency Maintenance Access is currently ENABLED"
- dat += "
Restore maintenance access restrictions?
\[ OK | Cancel \]"
- else
- dat += "Emergency Maintenance Access is currently DISABLED"
- dat += "
Lift access restrictions on maintenance and external airlocks?
\[ OK | Cancel \]"
- if(STATE_PURCHASE)
- var/datum/bank_account/D = SSeconomy.get_dep_account(ACCOUNT_CAR)
- dat += "Budget: [D.account_balance] Credits.
"
- dat += "
"
- dat += "Caution: Purchasing dangerous shuttles may lead to mutiny and/or death.
"
- dat += "
"
- for(var/shuttle_id in SSmapping.shuttle_templates)
- var/datum/map_template/shuttle/S = SSmapping.shuttle_templates[shuttle_id]
- if(S.can_be_bought && S.credit_cost < INFINITY)
- dat += "[S.name] | [S.credit_cost] Credits
"
- dat += "[S.description]
"
- if(S.prerequisites)
- dat += "Prerequisites: [S.prerequisites]
"
- dat += "(Purchase)
"
+ for (var/server in CONFIG_GET(keyed_list/cross_server))
+ if (server == our_id)
+ continue
+ sectors += server
- dat += "
\[ [(state != STATE_DEFAULT) ? "Main Menu | " : ""]Close \]"
+ data["sectors"] = sectors
- popup.set_content(dat)
- popup.open()
+ if (authenticated_as_ai_or_captain(user))
+ data["canToggleEmergencyAccess"] = TRUE
+ data["emergencyAccess"] = GLOB.emergency_access
-/obj/machinery/computer/communications/proc/get_javascript_header(form_id)
- var/dat = {""}
- return dat
+ data["alertLevelTick"] = alert_level_tick
+ data["canMakeAnnouncement"] = TRUE
+ data["canSetAlertLevel"] = isAI(user) ? "NO_SWIPE_NEEDED" : "SWIPE_NEEDED"
-/obj/machinery/computer/communications/proc/get_call_shuttle_form(ai_interface = 0)
- var/form_id = "callshuttle"
- var/dat = get_javascript_header(form_id)
- dat += "
+ )}
+ key={shuttle.ref}
+ buttons={(
+
"+se(c.message+"",!0)+"";throw c}}return pe.options=pe.setOptions=function(e){return ue(pe.defaults,e),fe(pe.defaults),pe},pe.getDefaults=le,pe.defaults=de,pe.use=function(e){var t=ue({},e);if(e.renderer&&function(){var n=pe.defaults.renderer||new te,r=function(){function t(t){var r=n[t];n[t]=function(){for(var o=arguments.length,i=new Array(o),a=0;a
'+(n?e:ee(e,!0))+"\n":""+(n?e:ee(e,!0))+"\n"}return e}(),t.blockquote=function(){function e(e){return"\n"+e+"\n"}return e}(),t.html=function(){function e(e){return e}return e}(),t.heading=function(){function e(e,t,n,r){return this.options.headerIds?"
"+e+"
\n"}return e}(),t.table=function(){function e(e,t){return t&&(t=""+t+""),""+e+""}return e}(),t.br=function(){function e(){return this.options.xhtml?""+se(c.message+"",!0)+"";throw c}}return pe.options=pe.setOptions=function(e){return ue(pe.defaults,e),fe(pe.defaults),pe},pe.getDefaults=le,pe.defaults=de,pe.use=function(e){var t=ue({},e);if(e.renderer&&function(){var n=pe.defaults.renderer||new te,r=function(){function t(t){var r=n[t];n[t]=function(){for(var o=arguments.length,i=new Array(o),a=0;a