diff --git a/code/__DEFINES/ARES.dm b/code/__DEFINES/ARES.dm index a1b82af25821..0e3cc4a8ff6e 100644 --- a/code/__DEFINES/ARES.dm +++ b/code/__DEFINES/ARES.dm @@ -1,21 +1,22 @@ +#define ARES_ACCESS_LOGOUT 0 /// Generic access for 1:1 conversations with ARES and unrestricted commands. -#define ARES_ACCESS_BASIC 0 +#define ARES_ACCESS_BASIC 1 /// Secure Access, can read ARES Announcements and Bioscans. -#define ARES_ACCESS_COMMAND 1 -#define ARES_ACCESS_JOE 2 +#define ARES_ACCESS_COMMAND 2 +#define ARES_ACCESS_JOE 3 /// CL, can read Apollo Log and also Delete Announcements. -#define ARES_ACCESS_CORPORATE 3 +#define ARES_ACCESS_CORPORATE 4 /// Senior Command, can Delete Bioscans. -#define ARES_ACCESS_SENIOR 4 +#define ARES_ACCESS_SENIOR 5 /// Synth, CE & Commanding Officer, can read the access log. -#define ARES_ACCESS_CE 5 -#define ARES_ACCESS_SYNTH 6 -#define ARES_ACCESS_CO 7 +#define ARES_ACCESS_CE 6 +#define ARES_ACCESS_SYNTH 7 +#define ARES_ACCESS_CO 8 /// High Command, can read the deletion log. -#define ARES_ACCESS_HIGH 8 -#define ARES_ACCESS_WY_COMMAND 9 +#define ARES_ACCESS_HIGH 9 +#define ARES_ACCESS_WY_COMMAND 10 /// Debugging. Allows me to view everything without using a high command rank. Unlikely to stay in a full merge. -#define ARES_ACCESS_DEBUG 10 +#define ARES_ACCESS_DEBUG 11 #define ARES_RECORD_ANNOUNCE "Announcement Record" #define ARES_RECORD_ANTIAIR "AntiAir Control Log" @@ -67,6 +68,12 @@ #define TICKET_OPEN "OPEN" #define TICKET_CLOSED "CLOSED" +// Priority status changes. +/// Upgraded to Priority +#define TICKET_PRIORITY "priority" +/// Downgraded from Priority +#define TICKET_NON_PRIORITY "non-priority" + /// Cooldowns #define COOLDOWN_ARES_SENSOR 60 SECONDS #define COOLDOWN_ARES_ACCESS_CONTROL 20 SECONDS diff --git a/code/game/machinery/ARES/ARES_interface.dm b/code/game/machinery/ARES/ARES_interface.dm index aa1cd92547ec..cfe3fe2669bc 100644 --- a/code/game/machinery/ARES/ARES_interface.dm +++ b/code/game/machinery/ARES/ARES_interface.dm @@ -9,10 +9,10 @@ var/current_menu = "login" var/last_menu = "" - var/authentication = ARES_ACCESS_BASIC + var/authentication = ARES_ACCESS_LOGOUT /// The last person to login. - var/last_login + var/last_login = "No User" /// The person pretending to be last_login var/sudo_holder @@ -275,6 +275,8 @@ last_login = sudo_holder sudo_holder = null datacore.interface_access_list += "[last_login] logged out at [worldtime2text()]." + last_login = "No User" + authentication = ARES_ACCESS_LOGOUT if("home") last_menu = current_menu @@ -319,6 +321,8 @@ // -- Delete Button -- // if("delete_record") var/datum/ares_record/record = locate(params["record"]) + if(!istype(record)) + return FALSE if(record.record_name == ARES_RECORD_DELETED) return FALSE var/datum/ares_record/deletion/new_delete = new @@ -372,6 +376,8 @@ if("read_record") var/datum/ares_record/deleted_talk/conversation = locate(params["record"]) + if(!istype(conversation)) + return FALSE deleted_1to1 = conversation.conversation last_menu = current_menu current_menu = "read_deleted" diff --git a/code/game/machinery/ARES/ARES_interface_admin.dm b/code/game/machinery/ARES/ARES_interface_admin.dm new file mode 100644 index 000000000000..e388c0eb453d --- /dev/null +++ b/code/game/machinery/ARES/ARES_interface_admin.dm @@ -0,0 +1,479 @@ +/client/proc/cmd_admin_open_ares() + set name = "Open ARES Interface" + set category = "Admin.Factions" + + var/mob/user = usr + if(!check_rights(R_MOD)) + to_chat(user, SPAN_WARNING("You do not have access to this command.")) + return FALSE + + if(!SSticker.mode) + to_chat(user, SPAN_WARNING("The round has not started yet.")) + return FALSE + + if(!GLOB.ares_link || !GLOB.ares_link.admin_interface || !GLOB.ares_link.interface) + to_chat(usr, SPAN_BOLDWARNING("ERROR: ARES Link or Interface not found!")) + return FALSE + GLOB.ares_link.tgui_interact(user) + var/log = "[key_name(user)] opened the remote ARES Interface." + if(user.job) + log = "[key_name(user)] ([user.job]) opened the remote ARES Interface." + log_admin(log) + +/datum/ares_console_admin + var/current_menu = "login" + var/last_menu = "" + + var/authentication = ARES_ACCESS_BASIC + + /// The last admin to login. + var/last_login + /// The currently logged in admin. + var/logged_in + /// A record of who logged in and when. + var/list/access_list = list() + var/list/deleted_1to1 = list() + + +/datum/ares_link/tgui_interact(mob/user, datum/tgui/ui) + if(!interface || !admin_interface) + to_chat(user, SPAN_WARNING("ARES ADMIN DATA LINK FAILED")) + return FALSE + ui = SStgui.try_update_ui(user, GLOB.ares_link, ui) + if(!ui) + ui = new(user, GLOB.ares_link, "AresAdmin", "ARES Admin Interface") + ui.open() + +/datum/ares_link/ui_data(mob/user) + if(!interface) + to_chat(user, SPAN_WARNING("ARES ADMIN DATA LINK FAILED")) + return FALSE + var/list/data = list() + + data["admin_login"] = "[admin_interface.logged_in], [user.client.admin_holder?.rank]" + data["admin_access_log"] = list(admin_interface.access_list) + + data["current_menu"] = admin_interface.current_menu + data["last_page"] = admin_interface.last_menu + + data["logged_in"] = interface.last_login + data["sudo"] = interface.sudo_holder ? TRUE : FALSE + + data["access_text"] = "[interface.sudo_holder ? "(SUDO)," : ""] access level [interface.authentication], [interface.ares_auth_to_text(interface.authentication)]." + data["access_level"] = interface.authentication + + data["alert_level"] = GLOB.security_level + data["evac_status"] = SShijack.evac_status + data["worldtime"] = world.time + + data["access_log"] = datacore.interface_access_list + data["apollo_log"] = datacore.apollo_log + + data["deleted_conversation"] = admin_interface.deleted_1to1 + + data["distresstime"] = datacore.ares_distress_cooldown + data["distresstimelock"] = DISTRESS_TIME_LOCK + data["mission_failed"] = SSticker.mode.is_in_endgame + data["nuketimelock"] = NUCLEAR_TIME_LOCK + data["nuke_available"] = datacore.nuke_available + + var/list/logged_announcements = list() + for(var/datum/ares_record/announcement/broadcast in datacore.records_announcement) + var/list/current_broadcast = list() + current_broadcast["time"] = broadcast.time + current_broadcast["title"] = broadcast.title + current_broadcast["details"] = broadcast.details + current_broadcast["ref"] = "\ref[broadcast]" + logged_announcements += list(current_broadcast) + data["records_announcement"] = logged_announcements + + var/list/logged_alerts = list() + for(var/datum/ares_record/security/security_alert in datacore.records_security) + var/list/current_alert = list() + current_alert["time"] = security_alert.time + current_alert["title"] = security_alert.title + current_alert["details"] = security_alert.details + current_alert["ref"] = "\ref[security_alert]" + logged_alerts += list(current_alert) + data["records_security"] = logged_alerts + + var/list/logged_flights = list() + for(var/datum/ares_record/flight/flight_log in datacore.records_flight) + var/list/current_flight = list() + current_flight["time"] = flight_log.time + current_flight["title"] = flight_log.title + current_flight["details"] = flight_log.details + current_flight["user"] = flight_log.user + current_flight["ref"] = "\ref[flight_log]" + logged_flights += list(current_flight) + data["records_flight"] = logged_flights + + var/list/logged_bioscans = list() + for(var/datum/ares_record/bioscan/scan in datacore.records_bioscan) + var/list/current_scan = list() + current_scan["time"] = scan.time + current_scan["title"] = scan.title + current_scan["details"] = scan.details + current_scan["ref"] = "\ref[scan]" + logged_bioscans += list(current_scan) + data["records_bioscan"] = logged_bioscans + + var/list/logged_bombs = list() + for(var/datum/ares_record/bombardment/bomb in datacore.records_bombardment) + var/list/current_bomb = list() + current_bomb["time"] = bomb.time + current_bomb["title"] = bomb.title + current_bomb["details"] = bomb.details + current_bomb["user"] = bomb.user + current_bomb["ref"] = "\ref[bomb]" + logged_bombs += list(current_bomb) + data["records_bombardment"] = logged_bombs + + var/list/logged_deletes = list() + for(var/datum/ares_record/deletion/deleted in datacore.records_deletion) + var/list/current_delete = list() + current_delete["time"] = deleted.time + current_delete["title"] = deleted.title + current_delete["details"] = deleted.details + current_delete["user"] = deleted.user + current_delete["ref"] = "\ref[deleted]" + logged_deletes += list(current_delete) + data["records_deletion"] = logged_deletes + + var/list/logged_discussions = list() + for(var/datum/ares_record/deleted_talk/deleted_convo in datacore.records_deletion) + var/list/deleted_disc = list() + deleted_disc["time"] = deleted_convo.time + deleted_disc["title"] = deleted_convo.title + deleted_disc["ref"] = "\ref[deleted_convo]" + logged_discussions += list(deleted_disc) + data["deleted_discussions"] = logged_discussions + + var/list/logged_orders = list() + for(var/datum/ares_record/requisition_log/req_order in datacore.records_asrs) + var/list/current_order = list() + current_order["time"] = req_order.time + current_order["details"] = req_order.details + current_order["title"] = req_order.title + current_order["user"] = req_order.user + current_order["ref"] = "\ref[req_order]" + logged_orders += list(current_order) + data["records_requisition"] = logged_orders + + var/list/logged_convos = list() + var/list/active_convo = list() + var/active_ref + for(var/datum/ares_record/talk_log/log in datacore.records_talking) + if(log.user == interface.last_login) + active_convo = log.conversation + active_ref = "\ref[log]" + + var/list/current_convo = list() + current_convo["user"] = log.user + current_convo["ref"] = "\ref[log]" + current_convo["conversation"] = log.conversation + logged_convos += list(current_convo) + + data["active_convo"] = active_convo + data["active_ref"] = active_ref + data["conversations"] = logged_convos + + var/list/logged_maintenance = list() + for(var/datum/ares_ticket/maintenance/maint_ticket in tickets_maintenance) + var/lock_status = TICKET_OPEN + switch(maint_ticket.ticket_status) + if(TICKET_REJECTED, TICKET_CANCELLED, TICKET_COMPLETED) + lock_status = TICKET_CLOSED + + var/list/current_maint = list() + current_maint["id"] = maint_ticket.ticket_id + current_maint["time"] = maint_ticket.ticket_time + current_maint["priority_status"] = maint_ticket.ticket_priority + current_maint["category"] = maint_ticket.ticket_name + current_maint["details"] = maint_ticket.ticket_details + current_maint["status"] = maint_ticket.ticket_status + current_maint["submitter"] = maint_ticket.ticket_submitter + current_maint["assignee"] = maint_ticket.ticket_assignee + current_maint["lock_status"] = lock_status + current_maint["ref"] = "\ref[maint_ticket]" + logged_maintenance += list(current_maint) + data["maintenance_tickets"] = logged_maintenance + + var/list/logged_access = list() + for(var/datum/ares_ticket/access/access_ticket in tickets_access) + var/lock_status = TICKET_OPEN + switch(access_ticket.ticket_status) + if(TICKET_REJECTED, TICKET_CANCELLED, TICKET_REVOKED) + lock_status = TICKET_CLOSED + + var/list/current_ticket = list() + current_ticket["id"] = access_ticket.ticket_id + current_ticket["time"] = access_ticket.ticket_time + current_ticket["priority_status"] = access_ticket.ticket_priority + current_ticket["title"] = access_ticket.ticket_name + current_ticket["details"] = access_ticket.ticket_details + current_ticket["status"] = access_ticket.ticket_status + current_ticket["submitter"] = access_ticket.ticket_submitter + current_ticket["assignee"] = access_ticket.ticket_assignee + current_ticket["lock_status"] = lock_status + current_ticket["ref"] = "\ref[access_ticket]" + logged_access += list(current_ticket) + data["access_tickets"] = logged_access + + return data + + +/datum/ares_link/ui_state(mob/user) + return GLOB.admin_state + +/datum/ares_link/ui_close(mob/user) + . = ..() + if(admin_interface.logged_in && (user.ckey == admin_interface.logged_in)) + admin_interface.current_menu = "login" + admin_interface.last_menu = "login" + admin_interface.access_list += "[admin_interface.logged_in] logged out at [worldtime2text()]." + admin_interface.last_login = admin_interface.logged_in + admin_interface.logged_in = null + +/datum/ares_link/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) + . = ..() + if(.) + return + var/mob/user = ui.user + if(!check_rights_for(user.client, R_MOD)) + to_chat(user, SPAN_WARNING("You require staff identification to access this terminal!")) + return FALSE + switch (action) + if("go_back") + if(!admin_interface.last_menu) + to_chat(user, SPAN_WARNING("Error, no previous page detected.")) + return FALSE + var/temp_holder = admin_interface.current_menu + admin_interface.current_menu = admin_interface.last_menu + admin_interface.last_menu = temp_holder + + if("login") + admin_interface.logged_in = user.client.ckey + admin_interface.access_list += "[user.client.ckey] at [worldtime2text()], Access Level '[user.client.admin_holder?.rank]'." + admin_interface.current_menu = "main" + + // -- Page Changers -- // + if("logout") + admin_interface.current_menu = "login" + admin_interface.last_menu = "login" + admin_interface.access_list += "[admin_interface.logged_in] logged out at [worldtime2text()]. (UI Termination)" + admin_interface.last_login = admin_interface.logged_in + admin_interface.logged_in = null + + if("home") + admin_interface.last_menu = admin_interface.current_menu + admin_interface.current_menu = "main" + if("page_1to1") + admin_interface.last_menu = admin_interface.current_menu + admin_interface.current_menu = "talking" + if("page_announcements") + admin_interface.last_menu = admin_interface.current_menu + admin_interface.current_menu = "announcements" + if("page_bioscans") + admin_interface.last_menu = admin_interface.current_menu + admin_interface.current_menu = "bioscans" + if("page_bombardments") + admin_interface.last_menu = admin_interface.current_menu + admin_interface.current_menu = "bombardments" + if("page_apollo") + admin_interface.last_menu = admin_interface.current_menu + admin_interface.current_menu = "apollo" + if("page_access") + admin_interface.last_menu = admin_interface.current_menu + admin_interface.current_menu = "access_log" + if("page_admin_list") + admin_interface.last_menu = admin_interface.current_menu + admin_interface.current_menu = "admin_access_log" + if("page_security") + admin_interface.last_menu = admin_interface.current_menu + admin_interface.current_menu = "security" + if("page_requisitions") + admin_interface.last_menu = admin_interface.current_menu + admin_interface.current_menu = "requisitions" + if("page_flight") + admin_interface.last_menu = admin_interface.current_menu + admin_interface.current_menu = "flight_log" + if("page_emergency") + admin_interface.last_menu = admin_interface.current_menu + admin_interface.current_menu = "emergency" + if("page_deleted") + admin_interface.last_menu = admin_interface.current_menu + admin_interface.current_menu = "delete_log" + if("page_deleted_1to1") + admin_interface.last_menu = admin_interface.current_menu + admin_interface.current_menu = "deleted_talks" + if("page_access_management") + admin_interface.last_menu = admin_interface.current_menu + admin_interface.current_menu = "access_management" + if("page_maint_management") + admin_interface.last_menu = admin_interface.current_menu + admin_interface.current_menu = "maintenance_management" + + // -- 1:1 Conversation -- // + if("new_conversation") + var/datum/ares_record/talk_log/convo = new(interface.last_login) + convo.conversation += "[MAIN_AI_SYSTEM] at [worldtime2text()], 'New 1:1 link initiated. Greetings, [interface.last_login].'" + datacore.records_talking += convo + + if("clear_conversation") + var/datum/ares_record/talk_log/conversation = locate(params["active_convo"]) + if(!istype(conversation)) + return FALSE + var/datum/ares_record/deleted_talk/deleted = new + deleted.title = conversation.title + deleted.conversation = conversation.conversation + deleted.user = MAIN_AI_SYSTEM + datacore.records_deletion += deleted + datacore.records_talking -= conversation + + if("fake_message_ares") + var/message = tgui_input_text(user, "What do you wish to say to ARES?", "ARES Message", encode = FALSE) + if(message) + interface.message_ares(message, user, params["active_convo"], TRUE) + if("ares_reply") + var/message = tgui_input_text(user, "What do you wish to reply with?", "ARES Response", encode = FALSE) + if(message) + interface.response_from_ares(message, params["active_convo"]) + var/datum/ares_record/talk_log/conversation = locate(params["active_convo"]) + if(!istype(conversation)) + return FALSE + var/admin_log = SPAN_STAFF_IC("ADMINS/MODS: [SPAN_RED("[key_name(user)] replied to [conversation.user]'s ARES message")] [SPAN_GREEN("via Remote Interface")] with: [SPAN_BLUE(message)] ") + for(var/client/admin in GLOB.admins) + if((R_ADMIN|R_MOD) & admin.admin_holder.rights) + to_chat(admin, admin_log) + + if("read_record") + var/datum/ares_record/deleted_talk/conversation = locate(params["record"]) + if(!istype(conversation)) + return FALSE + admin_interface.deleted_1to1 = conversation.conversation + admin_interface.last_menu = admin_interface.current_menu + admin_interface.current_menu = "read_deleted" + + if("claim_ticket") + var/datum/ares_ticket/ticket = locate(params["ticket"]) + if(!istype(ticket)) + return FALSE + var/claim = TRUE + var/assigned = ticket.ticket_assignee + if(assigned) + if(assigned == MAIN_AI_SYSTEM) + var/prompt = tgui_alert(user, "ARES already claimed this ticket! Do you wish to drop the claim?", "Unclaim ticket", list("Yes", "No")) + if(prompt != "Yes") + return FALSE + /// set ticket back to pending + ticket.ticket_assignee = null + ticket.ticket_status = TICKET_PENDING + return claim + var/choice = tgui_alert(user, "This ticket has already been claimed by [assigned]! Do you wish to override their claim?", "Claim Override", list("Yes", "No")) + if(choice != "Yes") + claim = FALSE + if(claim) + ticket.ticket_assignee = MAIN_AI_SYSTEM + ticket.ticket_status = TICKET_ASSIGNED + return claim + + if("auth_access") + var/datum/ares_ticket/access/access_ticket = locate(params["ticket"]) + if(!istype(access_ticket)) + return FALSE + for(var/obj/item/card/id/identification in waiting_ids) + if(identification.registered_gid != access_ticket.user_id_num) + continue + identification.handle_ares_access(MAIN_AI_SYSTEM, user) + access_ticket.ticket_status = TICKET_GRANTED + ares_apollo_talk("Access Ticket [access_ticket.ticket_id]: [access_ticket.ticket_submitter] granted core access.") + return TRUE + for(var/obj/item/card/id/identification in active_ids) + if(identification.registered_gid != access_ticket.user_id_num) + continue + identification.handle_ares_access(MAIN_AI_SYSTEM, user) + access_ticket.ticket_status = TICKET_REVOKED + ares_apollo_talk("Access Ticket [access_ticket.ticket_id]: core access for [access_ticket.ticket_submitter] revoked.") + return TRUE + return FALSE + + if("reject_access") + var/datum/ares_ticket/access/access_ticket = locate(params["ticket"]) + if(!istype(access_ticket)) + return FALSE + access_ticket.ticket_status = TICKET_REJECTED + to_chat(user, SPAN_NOTICE("[access_ticket.ticket_type] [access_ticket.ticket_id] marked as rejected.")) + ares_apollo_talk("Access Ticket [access_ticket.ticket_id] rejected.") + return TRUE + + if("new_report") + var/priority_report = FALSE + var/maint_type = tgui_input_list(user, "What is the type of maintenance item you wish to report?", "Report Category", GLOB.maintenance_categories, 30 SECONDS) + switch(maint_type) + if("Major Structural Damage", "Fire", "Communications Failure", "Power Generation Failure") + priority_report = TRUE + + if(!maint_type) + return FALSE + var/details = tgui_input_text(user, "What are the details for this report?", "Ticket Details", encode = FALSE) + if(!details) + return FALSE + + if(!priority_report) + var/is_priority = tgui_alert(user, "Is this a priority report?", "Priority designation", list("Yes", "No")) + if(is_priority == "Yes") + priority_report = TRUE + + var/confirm = alert(user, "Please confirm the submission of your maintenance report. \n\n Priority: [priority_report ? "Yes" : "No"]\n Category: '[maint_type]'\n Details: '[details]'\n\n Is this correct?", "Confirmation", "Yes", "No") + if(confirm == "Yes") + var/datum/ares_ticket/maintenance/maint_ticket = new(MAIN_AI_SYSTEM, maint_type, details, priority_report) + tickets_maintenance += maint_ticket + if(priority_report) + ares_apollo_talk("Priority Maintenance Report: [maint_type] - ID [maint_ticket.ticket_id]. Seek and resolve.") + log_game("ARES: Maintenance Ticket '\ref[maint_ticket]' created by [key_name(user)] as [MAIN_AI_SYSTEM] with Category '[maint_type]' and Details of '[details]'.") + return TRUE + return FALSE + + if("cancel_ticket") + var/datum/ares_ticket/ticket = locate(params["ticket"]) + if(!istype(ticket)) + return FALSE + if(ticket.ticket_submitter != MAIN_AI_SYSTEM) + to_chat(user, SPAN_WARNING("You cannot cancel a ticket that does not belong to [MAIN_AI_SYSTEM]!")) + return FALSE + to_chat(user, SPAN_WARNING("[ticket.ticket_type] [ticket.ticket_id] has been cancelled.")) + ticket.ticket_status = TICKET_CANCELLED + if(ticket.ticket_priority) + ares_apollo_talk("Priority [ticket.ticket_type] [ticket.ticket_id] has been cancelled.") + return TRUE + + if("mark_ticket") + var/datum/ares_ticket/ticket = locate(params["ticket"]) + if(!istype(ticket)) + return FALSE + var/options_list = list(TICKET_COMPLETED, TICKET_REJECTED) + if(ticket.ticket_priority) + options_list += TICKET_NON_PRIORITY + else + options_list += TICKET_PRIORITY + var/choice = tgui_alert(user, "What do you wish to mark the ticket as?", "Mark", options_list, 20 SECONDS) + switch(choice) + if(TICKET_PRIORITY) + ticket.ticket_priority = TRUE + ares_apollo_talk("[ticket.ticket_type] [ticket.ticket_id] upgraded to Priority.") + return TRUE + if(TICKET_NON_PRIORITY) + ticket.ticket_priority = FALSE + ares_apollo_talk("[ticket.ticket_type] [ticket.ticket_id] downgraded from Priority.") + return TRUE + if(TICKET_COMPLETED) + ticket.ticket_status = TICKET_COMPLETED + if(TICKET_REJECTED) + ticket.ticket_status = TICKET_REJECTED + else + return FALSE + if(ticket.ticket_priority) + ares_apollo_talk("Priority [ticket.ticket_type] [ticket.ticket_id] has been [choice] by [MAIN_AI_SYSTEM].") + to_chat(user, SPAN_NOTICE("[ticket.ticket_type] [ticket.ticket_id] marked as [choice].")) + return TRUE diff --git a/code/game/machinery/ARES/ARES_procs.dm b/code/game/machinery/ARES/ARES_procs.dm index 8113614d9b92..90616add6d25 100644 --- a/code/game/machinery/ARES/ARES_procs.dm +++ b/code/game/machinery/ARES/ARES_procs.dm @@ -1,5 +1,5 @@ -GLOBAL_DATUM_INIT(ares_link, /datum/ares_link, new) GLOBAL_DATUM_INIT(ares_datacore, /datum/ares_datacore, new) +GLOBAL_DATUM_INIT(ares_link, /datum/ares_link, new) GLOBAL_LIST_INIT(maintenance_categories, list( "Broken Light", "Shattered Glass", @@ -25,6 +25,9 @@ GLOBAL_LIST_INIT(maintenance_categories, list( var/obj/structure/machinery/ares/processor/apollo/processor_apollo var/obj/structure/machinery/ares/processor/bioscan/processor_bioscan var/obj/structure/machinery/computer/ares_console/interface + var/datum/ares_console_admin/admin_interface + var/datum/ares_datacore/datacore + var/list/obj/structure/machinery/computer/working_joe/ticket_computers = list() /// Working Joe stuff @@ -33,6 +36,25 @@ GLOBAL_LIST_INIT(maintenance_categories, list( var/list/waiting_ids = list() var/list/active_ids = list() +/datum/ares_link/New() + admin_interface = new + datacore = GLOB.ares_datacore + +/datum/ares_link/Destroy() + qdel(admin_interface) + for(var/obj/structure/machinery/ares/link in linked_systems) + link.delink() + for(var/obj/structure/machinery/computer/ares_console/interface in linked_systems) + interface.delink() + for(var/obj/effect/step_trigger/ares_alert/alert in linked_alerts) + alert.delink() + ..() + +/* BELOW ARE IN AdminAres.dm +/datum/ares_link/tgui_interact(mob/user, datum/tgui/ui) +/datum/ares_link/ui_data(mob/user) +*/ + /datum/ares_datacore /// A record of who logged in and when. var/list/interface_access_list = list() @@ -61,21 +83,10 @@ GLOBAL_LIST_INIT(maintenance_categories, list( /// Is nuke request usable or not? var/nuke_available = TRUE - COOLDOWN_DECLARE(ares_distress_cooldown) COOLDOWN_DECLARE(ares_nuclear_cooldown) COOLDOWN_DECLARE(ares_quarters_cooldown) -/datum/ares_link/Destroy() - for(var/obj/structure/machinery/ares/link in linked_systems) - link.delink() - for(var/obj/structure/machinery/computer/ares_console/interface in linked_systems) - interface.delink() - for(var/obj/effect/step_trigger/ares_alert/alert in linked_alerts) - alert.delink() - ..() - - // ------ ARES Logging Procs ------ // /proc/ares_is_active() for(var/mob/living/silicon/decoy/ship_ai/ai in GLOB.ai_mob_list) @@ -196,43 +207,58 @@ GLOBAL_LIST_INIT(maintenance_categories, list( /obj/structure/machinery/computer/proc/ares_auth_to_text(access_level) switch(access_level) - if(ARES_ACCESS_BASIC)//0 + if(ARES_ACCESS_LOGOUT) + return "Logged Out" + if(ARES_ACCESS_BASIC) return "Authorized" - if(ARES_ACCESS_COMMAND)//1 + if(ARES_ACCESS_COMMAND) return "[MAIN_SHIP_NAME] Command" - if(ARES_ACCESS_JOE)//2 + if(ARES_ACCESS_JOE) return "Working Joe" - if(ARES_ACCESS_CORPORATE)//3 + if(ARES_ACCESS_CORPORATE) return "Weyland-Yutani" - if(ARES_ACCESS_SENIOR)//4 + if(ARES_ACCESS_SENIOR) return "[MAIN_SHIP_NAME] Senior Command" - if(ARES_ACCESS_CE)//5 + if(ARES_ACCESS_CE) return "Chief Engineer" - if(ARES_ACCESS_SYNTH)//6 + if(ARES_ACCESS_SYNTH) return "USCM Synthetic" - if(ARES_ACCESS_CO)//7 + if(ARES_ACCESS_CO) return "[MAIN_SHIP_NAME] Commanding Officer" - if(ARES_ACCESS_HIGH)//8 + if(ARES_ACCESS_HIGH) return "USCM High Command" - if(ARES_ACCESS_WY_COMMAND)//9 + if(ARES_ACCESS_WY_COMMAND) return "Weyland-Yutani Directorate" - if(ARES_ACCESS_DEBUG)//10 + if(ARES_ACCESS_DEBUG) return "AI Service Technician" -/obj/structure/machinery/computer/ares_console/proc/message_ares(text, mob/Sender, ref) - var/msg = SPAN_STAFF_IC("ARES: [key_name(Sender, 1)] [ARES_MARK(Sender)] [ADMIN_PP(Sender)] [ADMIN_VV(Sender)] [ADMIN_SM(Sender)] [ADMIN_JMP_USER(Sender)] [ARES_REPLY(Sender, ref)]: [text]") +/obj/structure/machinery/computer/ares_console/proc/message_ares(text, mob/Sender, ref, fake = FALSE) var/datum/ares_record/talk_log/conversation = locate(ref) + if(!istype(conversation)) + return + var/msg = SPAN_STAFF_IC("ARES: [key_name(Sender, 1)] [ARES_MARK(Sender)] [ADMIN_PP(Sender)] [ADMIN_VV(Sender)] [ADMIN_SM(Sender)] [ADMIN_JMP_USER(Sender)] [ARES_REPLY(Sender, ref)]: [text]") conversation.conversation += "[last_login] at [worldtime2text()], '[text]'" + if(fake) + log_say("[key_name(Sender)] faked the message '[text]' from [last_login] in ARES 1:1.") + msg = SPAN_STAFF_IC("ARES: [key_name(Sender, 1)] faked a message from '[last_login]': [text]") + else + log_say("[key_name(Sender)] sent '[text]' to ARES 1:1.") + for(var/client/admin in GLOB.admins) + if(admin.prefs.toggles_sound & SOUND_ARES_MESSAGE) + playsound_client(admin, 'sound/machines/chime.ogg', vol = 25) + for(var/client/admin in GLOB.admins) if((R_ADMIN|R_MOD) & admin.admin_holder.rights) to_chat(admin, msg) - if(admin.prefs.toggles_sound & SOUND_ARES_MESSAGE) - playsound_client(admin, 'sound/machines/chime.ogg', vol = 25) - log_say("[key_name(Sender)] sent '[text]' to ARES 1:1.") + var/admin_user = GLOB.ares_link.admin_interface.logged_in + if(admin_user && !fake) + to_chat(admin, SPAN_STAFF_IC("ADMINS/MODS: [SPAN_RED("[admin_user] is logged in to ARES Remote Interface! They may be replying to this message!")]")) /obj/structure/machinery/computer/ares_console/proc/response_from_ares(text, ref) var/datum/ares_record/talk_log/conversation = locate(ref) + if(!istype(conversation)) + return conversation.conversation += "[MAIN_AI_SYSTEM] at [worldtime2text()], '[text]'" // ------ End ARES Interface Procs ------ // diff --git a/code/game/machinery/ARES/ARES_records.dm b/code/game/machinery/ARES/ARES_records.dm index f89b2c120e05..e8dc11fa3995 100644 --- a/code/game/machinery/ARES/ARES_records.dm +++ b/code/game/machinery/ARES/ARES_records.dm @@ -45,7 +45,7 @@ /datum/ares_record/flight/New(details, user) time = worldtime2text() - src.title = "Flight Log" + title = "Flight Log" src.details = details src.user = user diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 56002d139599..d9cecdfa9e96 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -68,6 +68,7 @@ GLOBAL_LIST_INIT(admin_verbs_default, list( /datum/admins/proc/alertall, /datum/admins/proc/imaginary_friend, /client/proc/toggle_admin_pings, + /client/proc/cmd_admin_open_ares, /client/proc/cmd_admin_say, /*staff-only ooc chat*/ /client/proc/cmd_mod_say, /* alternate way of typing asay, no different than cmd_admin_say */ /client/proc/cmd_admin_tacmaps_panel, diff --git a/colonialmarines.dme b/colonialmarines.dme index fbdc6b7a61d8..55359f09de58 100644 --- a/colonialmarines.dme +++ b/colonialmarines.dme @@ -866,6 +866,7 @@ #include "code\game\machinery\ARES\apollo_pda.dm" #include "code\game\machinery\ARES\ARES.dm" #include "code\game\machinery\ARES\ARES_interface.dm" +#include "code\game\machinery\ARES\ARES_interface_admin.dm" #include "code\game\machinery\ARES\ARES_interface_apollo.dm" #include "code\game\machinery\ARES\ARES_procs.dm" #include "code\game\machinery\ARES\ARES_records.dm" diff --git a/tgui/packages/tgui/interfaces/AresAdmin.js b/tgui/packages/tgui/interfaces/AresAdmin.js new file mode 100644 index 000000000000..4f19cf452b17 --- /dev/null +++ b/tgui/packages/tgui/interfaces/AresAdmin.js @@ -0,0 +1,1946 @@ +import { useBackend } from '../backend'; +import { Flex, Box, Section, Button, Stack } from '../components'; +import { Window } from '../layouts'; + +const PAGES = { + 'login': () => Login, + 'main': () => MainMenu, + 'announcements': () => AnnouncementLogs, + 'bioscans': () => BioscanLogs, + 'bombardments': () => BombardmentLogs, + 'apollo': () => ApolloLog, + 'access_log': () => AccessLogs, + 'delete_log': () => DeletionLogs, + 'flight_log': () => FlightLogs, + 'talking': () => ARESTalk, + 'deleted_talks': () => DeletedTalks, + 'read_deleted': () => ReadingTalks, + 'security': () => Security, + 'requisitions': () => Requisitions, + 'emergency': () => Emergency, + 'admin_access_log': () => AdminAccessLogs, + 'access_management': () => AccessManagement, + 'maintenance_management': () => MaintManagement, +}; + +export const AresAdmin = (props, context) => { + const { data } = useBackend(context); + const { current_menu, sudo } = data; + const PageComponent = PAGES[current_menu](); + + let themecolor = 'crtyellow'; + if (sudo >= 1) { + themecolor = 'crtred'; + } + + return ( + + + + + + ); +}; + +const Login = (props, context) => { + const { act } = useBackend(context); + + return ( + + ARES v3.2 Remote Interface + + WY-DOS Executive + + Version 4.5.2 + Copyright © 2182, Weyland Yutani Corp. + +