diff --git a/code/modules/modular_computers/file_system/programs/techweb.dm b/code/modules/modular_computers/file_system/programs/techweb.dm index 2e609a24374..80302abf894 100644 --- a/code/modules/modular_computers/file_system/programs/techweb.dm +++ b/code/modules/modular_computers/file_system/programs/techweb.dm @@ -204,21 +204,26 @@ computer.say("Successfully researched [tech_node.display_name].") var/logname = "Unknown" if(isAI(user)) - logname = "AI: [user.name]" + logname = "AI [user.name]" if(iscyborg(user)) - logname = "Cyborg: [user.name]" + logname = "CYBORG [user.name]" if(iscarbon(user)) var/obj/item/card/id/idcard = user.get_active_held_item() if(istype(idcard)) - logname = "User: [idcard.registered_name]" + logname = "[idcard.registered_name]" if(ishuman(user)) var/mob/living/carbon/human/human_user = user var/obj/item/worn = human_user.wear_id if(istype(worn)) var/obj/item/card/id/id_card_of_human_user = worn.GetID() if(istype(id_card_of_human_user)) - logname = "User: [id_card_of_human_user.registered_name]" - stored_research.research_logs += list(list(tech_node.display_name, price["General Research"], logname, "[get_area(computer)] ([user.x],[user.y],[user.z])")) + logname = "[id_card_of_human_user.registered_name]" + stored_research.research_logs += list(list( + "node_name" = tech_node.display_name, + "node_cost" = price["General Research"], + "node_researcher" = logname, + "node_research_location" = "[get_area(computer)] ([user.x],[user.y],[user.z])", + )) return TRUE else computer.say("Failed to research node: Internal database error!") diff --git a/code/modules/research/rdconsole.dm b/code/modules/research/rdconsole.dm index 790f7c8ab72..c6a330efd22 100644 --- a/code/modules/research/rdconsole.dm +++ b/code/modules/research/rdconsole.dm @@ -113,23 +113,26 @@ Nothing else in the console has ID requirements. say("Successfully researched [TN.display_name].") var/logname = "Unknown" if(isAI(user)) - logname = "AI: [user.name]" + logname = "AI [user.name]" if(iscyborg(user)) - logname = "Cyborg: [user.name]" + logname = "CYBORG [user.name]" if(iscarbon(user)) var/obj/item/card/id/idcard = user.get_active_held_item() if(istype(idcard)) - logname = "User: [idcard.registered_name]" + logname = "[idcard.registered_name]" if(ishuman(user)) var/mob/living/carbon/human/H = user var/obj/item/I = H.wear_id if(istype(I)) var/obj/item/card/id/ID = I.GetID() if(istype(ID)) - logname = "User: [ID.registered_name]" - var/i = stored_research.research_logs.len - stored_research.research_logs += null - stored_research.research_logs[++i] = list(TN.display_name, price["General Research"], logname, "[get_area(src)] ([src.x],[src.y],[src.z])") + logname = "[ID.registered_name]" + stored_research.research_logs += list(list( + "node_name" = TN.display_name, + "node_cost" = price["General Research"], + "node_researcher" = logname, + "node_research_location" = "[get_area(src)] ([src.x],[src.y],[src.z])", + )) return TRUE else say("Failed to research node: Internal database error!") diff --git a/code/modules/research/server.dm b/code/modules/research/server.dm index f4a7dfa0cb1..d611ea0bf96 100644 --- a/code/modules/research/server.dm +++ b/code/modules/research/server.dm @@ -9,7 +9,7 @@ /// The ninja has blown the HDD up. #define HDD_OVERLOADED 4 -#define SERVER_NOMINAL_TEXT "Nominal" +#define SERVER_NOMINAL_TEXT "Nominal" /obj/machinery/rnd/server name = "\improper R&D Server" @@ -87,15 +87,15 @@ /// Gets status text based on this server's status for the computer. /obj/machinery/rnd/server/proc/get_status_text() if(machine_stat & EMPED) - return "O&F@I*$ - R3*&O$T R@U!R%D" + return "O&F@I*$ - R3*&O$T R@U!R%D" else if(machine_stat & NOPOWER) - return "Offline - Server Unpowered" + return "Offline - Server Unpowered" else if(research_disabled) - return "Offline - Server Control Disabled" + return "Offline - Server Control Disabled" else if(!working) // If, for some reason, working is FALSE even though we're not emp'd or powerless, // We need something to update our working state - such as rebooting the server - return "Offline - Reboot Required" + return "Offline - Reboot Required" return SERVER_NOMINAL_TEXT @@ -106,86 +106,6 @@ to_chat(user, span_notice("Stored [src]'s techweb information in [tool].")) return TRUE -/obj/machinery/computer/rdservercontrol - name = "R&D Server Controller" - desc = "Used to manage access to research and manufacturing databases." - icon_screen = "rdcomp" - icon_keyboard = "rd_key" - circuit = /obj/item/circuitboard/computer/rdservercontrol - req_access = list(ACCESS_RD) - var/list/servers = list() - ///Connected techweb node the server is connected to. - var/datum/techweb/stored_research - -/obj/machinery/computer/rdservercontrol/Initialize(mapload, obj/item/circuitboard/C) - . = ..() - if(!CONFIG_GET(flag/no_default_techweb_link) && !stored_research) - stored_research = SSresearch.science_tech - -/obj/machinery/computer/rdservercontrol/Topic(href, href_list) - if(..()) - return - - add_fingerprint(usr) - if (href_list["toggle"]) - if(allowed(usr) || obj_flags & EMAGGED) - var/obj/machinery/rnd/server/S = locate(href_list["toggle"]) in stored_research.techweb_servers - S.toggle_disable(usr) - else - to_chat(usr, span_danger("Access Denied.")) - - updateUsrDialog() - return - -/obj/machinery/computer/rdservercontrol/ui_interact(mob/user) - . = ..() - var/list/dat = list() - - dat += "Connected Servers:" - dat += "" - for(var/obj/machinery/rnd/server/server as anything in stored_research.techweb_servers) - var/server_info = "" - - var/status_text = server.get_status_text() - var/disable_text = server.research_disabled ? "Disabled" : "Online" - - server_info += "" - server_info += "" - server_info += "
" - - dat += server_info - - dat += "
ServerStatusControl
[server.name][status_text]([disable_text])

" - - dat += "Research Log
" - if(stored_research && length(stored_research.research_logs)) - dat += "" - dat += "" - for(var/i = stored_research.research_logs.len, i>0, i--) - dat += "" - for(var/j in stored_research.research_logs[i]) - dat += "" - dat +="" - dat += "
EntryResearch NameCostResearcher NameConsole Location
[i][j]
" - - else - dat += "
No history found." - - var/datum/browser/popup = new(user, "server_com", src.name, 900, 620) - popup.set_content(dat.Join()) - popup.open() - -/obj/machinery/computer/rdservercontrol/attackby(obj/item/D, mob/user, params) - . = ..() - src.updateUsrDialog() - -/obj/machinery/computer/rdservercontrol/emag_act(mob/user) - if(obj_flags & EMAGGED) - return - playsound(src, SFX_SPARKS, 75, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) - obj_flags |= EMAGGED - to_chat(user, span_notice("You disable the security protocols.")) - /// Master R&D server. As long as this still exists and still holds the HDD for the theft objective, research points generate at normal speed. Destroy it or an antag steals the HDD? Half research speed. /obj/machinery/rnd/server/master max_integrity = 1800 //takes roughly ~15s longer to break then full deconstruction. diff --git a/code/modules/research/server_control.dm b/code/modules/research/server_control.dm new file mode 100644 index 00000000000..532f05ec965 --- /dev/null +++ b/code/modules/research/server_control.dm @@ -0,0 +1,84 @@ +/obj/machinery/computer/rdservercontrol + name = "R&D Server Controller" + desc = "Manages access to research databases and consoles." + icon_screen = "rdcomp" + icon_keyboard = "rd_key" + circuit = /obj/item/circuitboard/computer/rdservercontrol + req_access = list(ACCESS_RD) + + ///Connected techweb node the server is connected to. + var/datum/techweb/stored_research + +/obj/machinery/computer/rdservercontrol/Initialize(mapload, obj/item/circuitboard/C) + . = ..() + if(!CONFIG_GET(flag/no_default_techweb_link) && !stored_research) + stored_research = SSresearch.science_tech + +/obj/machinery/computer/rdservercontrol/multitool_act(mob/living/user, obj/item/multitool/tool) + if(!QDELETED(tool.buffer) && istype(tool.buffer, /datum/techweb)) + stored_research = tool.buffer + balloon_alert(user, "techweb connected") + return TRUE + +/obj/machinery/computer/rdservercontrol/emag_act(mob/user) + if(obj_flags & EMAGGED) + return + obj_flags |= EMAGGED + playsound(src, SFX_SPARKS, 75, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) + balloon_alert(user, "console emagged") + +/obj/machinery/computer/rdservercontrol/ui_interact(mob/user, datum/tgui/ui) + . = ..() + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "ServerControl", name) + ui.open() + +/obj/machinery/computer/rdservercontrol/ui_data(mob/user) + var/list/data = list() + + data["server_connected"] = !!stored_research + + if(stored_research) + data["logs"] += stored_research.research_logs + + for(var/obj/machinery/rnd/server/server as anything in stored_research.techweb_servers) + data["servers"] += list(list( + "server_name" = server, + "server_details" = server.get_status_text(), + "server_disabled" = server.research_disabled, + "server_ref" = REF(server), + )) + + for(var/obj/machinery/computer/rdconsole/console as anything in stored_research.consoles_accessing) + data["consoles"] += list(list( + "console_name" = console, + "console_location" = get_area(console), + "console_locked" = console.locked, + "console_ref" = REF(console), + )) + + return data + +/obj/machinery/computer/rdservercontrol/ui_act(action, params) + . = ..() + if(.) + return TRUE + if(!allowed(usr) && !(obj_flags & EMAGGED)) + balloon_alert(usr, "access denied!") + playsound(src, 'sound/machines/click.ogg', 20, TRUE) + return TRUE + + switch(action) + if("lockdown_server") + var/obj/machinery/rnd/server/server_selected = locate(params["selected_server"]) in stored_research.techweb_servers + if(!server_selected) + return FALSE + server_selected.toggle_disable(usr) + return TRUE + if("lock_console") + var/obj/machinery/computer/rdconsole/console_selected = locate(params["selected_console"]) in stored_research.consoles_accessing + if(!console_selected) + return FALSE + console_selected.locked = !console_selected.locked + return TRUE diff --git a/code/modules/research/techweb/_techweb.dm b/code/modules/research/techweb/_techweb.dm index b8b0d9b73e7..d5f127aae7d 100644 --- a/code/modules/research/techweb/_techweb.dm +++ b/code/modules/research/techweb/_techweb.dm @@ -30,7 +30,7 @@ var/list/deconstructed_items = list() /// Available research points, type = number var/list/research_points = list() - /// IC logs + /// Game logs of research nodes, "node_name" "node_cost" "node_researcher" "node_research_location" var/list/research_logs = list() /// Current per-second production, used for display only. var/list/last_bitcoins = list() diff --git a/tgstation.dme b/tgstation.dme index 65a5c375204..b5044d357f0 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -4503,6 +4503,7 @@ #include "code\modules\research\rdmachines.dm" #include "code\modules\research\research_disk.dm" #include "code\modules\research\server.dm" +#include "code\modules\research\server_control.dm" #include "code\modules\research\stock_parts.dm" #include "code\modules\research\anomaly\anomaly_core.dm" #include "code\modules\research\anomaly\anomaly_refinery.dm" diff --git a/tgui/packages/tgui/interfaces/ServerControl.tsx b/tgui/packages/tgui/interfaces/ServerControl.tsx new file mode 100644 index 00000000000..02aa2e67500 --- /dev/null +++ b/tgui/packages/tgui/interfaces/ServerControl.tsx @@ -0,0 +1,152 @@ +import { BooleanLike } from 'common/react'; +import { useBackend } from '../backend'; +import { Button, Collapsible, Section, Table, NoticeBox } from '../components'; +import { Window } from '../layouts'; + +type Data = { + server_connected: BooleanLike; + servers: ServerData[]; + consoles: ConsoleData[]; + logs: LogData[]; +}; + +type ServerData = { + server_name: string; + server_details: string; + server_disabled: string; + server_ref: string; +}; + +type ConsoleData = { + console_name: string; + console_location: string; + console_locked: string; + console_ref: string; +}; + +type LogData = { + node_name: string; + node_cost: string; + node_researcher: string; + node_research_location: string; +}; + +export const ServerControl = (props, context) => { + const { act, data } = useBackend(context); + const { server_connected, servers, consoles, logs } = data; + if (!server_connected) { + return ( + + + + Not connected to a Server. Please sync one using a multitool. + + + + ); + } + return ( + + + {!servers ? ( + + No servers found. + + ) : ( +
+ + + Research Servers + + {servers.map((server) => ( + <> + + {server.server_name} +
+
+ )} + + {!consoles ? ( + + No consoles found. + + ) : ( +
+ + + Research Consoles + + {consoles.map((console) => ( + <> + + + {' '} + {console.console_name} - Location:{' '} + {console.console_location}{' '} + +
+
+ )} + + + {!logs.length ? ( + + No history found. + + ) : ( +
+ + + Research Name + Cost + Researcher Name + Console Location + + {logs.map((server_log) => ( + + {server_log.node_name} + {server_log.node_cost} + {server_log.node_researcher} + {server_log.node_research_location} + + ))} +
+
+ )} +
+
+
+ ); +};