diff --git a/code/modules/modular_computers/computers/item/computer_ui.dm b/code/modules/modular_computers/computers/item/computer_ui.dm index 4313bf2efbd..49859f46b4d 100644 --- a/code/modules/modular_computers/computers/item/computer_ui.dm +++ b/code/modules/modular_computers/computers/item/computer_ui.dm @@ -108,6 +108,7 @@ var/datum/computer_file/program/ai_restorer/airestore_app = locate() in stored_files if(airestore_app?.stored_card) data["removable_media"] += "intelliCard" + data["removable_media"] += handle_ui_removable_media_insert(user) // FLUFFY FRONTIER ADD data["programs"] = list() for(var/datum/computer_file/program/program in stored_files) @@ -207,6 +208,7 @@ if(RemoveID(user)) playsound(src, 'sound/machines/card_slide.ogg', 50) return TRUE + return handle_ui_removable_media_eject(param, user) // FLUFFFY FRONTIER ADD if("PC_Imprint_ID") imprint_id() diff --git a/code/modules/modular_computers/file_system/programs/techweb.dm b/code/modules/modular_computers/file_system/programs/techweb.dm index a72eef1bc9a..f5ceda23b18 100644 --- a/code/modules/modular_computers/file_system/programs/techweb.dm +++ b/code/modules/modular_computers/file_system/programs/techweb.dm @@ -25,13 +25,17 @@ . = ..() if(!CONFIG_GET(flag/no_default_techweb_link) && !stored_research) CONNECT_TO_RND_SERVER_ROUNDSTART(stored_research, computer) + handle_rnd_control_install() // FLUFFY FRONTIER ADD /datum/computer_file/program/science/application_attackby(obj/item/attacking_item, mob/living/user) + if (istype(attacking_item, /obj/item/disk/tech_disk) || istype(attacking_item, /obj/item/disk/design_disk)) return handle_disks_insertion(attacking_item, user) // FLUFFY FRONTTIER ADD if(!istype(attacking_item, /obj/item/multitool)) return FALSE var/obj/item/multitool/attacking_tool = attacking_item if(!QDELETED(attacking_tool.buffer) && istype(attacking_tool.buffer, /datum/techweb)) + if (stored_research) stored_research.apps_accessing -= src // FLUFFY FRONTIER ADD stored_research = attacking_tool.buffer + handle_rnd_control_install() // FLUFFY FRONTIER ADD return TRUE /datum/computer_file/program/science/ui_assets(mob/user) @@ -57,6 +61,7 @@ "d_disk" = null, //See above. "locked" = locked, ) + data = handle_disks_ui_data(data) // FLUFFY FRONTIER ADD // Serialize all nodes to display for(var/tier in stored_research.tiers) @@ -94,6 +99,7 @@ if (locked && action != "toggleLock") computer.say("Console is locked, cannot perform further actions.") return TRUE + if (action in list("ejectDisk", "uploadDisk", "loadTech")) return handle_disks_ui_act(action, params) // FLUFFY FRONTIER ADD switch (action) if ("toggleLock") diff --git a/tff_modular/modules/all_computers_to_modular_consoles/_techweb.dm b/tff_modular/modules/all_computers_to_modular_consoles/_techweb.dm new file mode 100644 index 00000000000..c31eaabb41c --- /dev/null +++ b/tff_modular/modules/all_computers_to_modular_consoles/_techweb.dm @@ -0,0 +1,3 @@ +/datum/techweb + // We wanna track not only consoles but NT apps that connected to us oo + var/list/datum/computer_file/program/science/apps_accessing = list() diff --git a/tff_modular/modules/all_computers_to_modular_consoles/access_helper.dm b/tff_modular/modules/all_computers_to_modular_consoles/access_helper.dm new file mode 100644 index 00000000000..47de9ac1663 --- /dev/null +++ b/tff_modular/modules/all_computers_to_modular_consoles/access_helper.dm @@ -0,0 +1,36 @@ +/* +// May I be cursed, but I am to lazy to copypast atom/allowed() code now +/datum/computer_file/program/proc/allowed(mob/accessor) + var/list/tmp_req_access = computer.req_access + var/list/tmp_req_one_access = computer.req_one_access + computer.req_access = null + computer.req_one_access = run_access + . = computer.allowed(accessor) + computer.req_access = tmp_req_access + computer.req_one_access = tmp_req_one_access +*/ + +/datum/computer_file/program/proc/can_run_Adjacent(mob/accessor, loud, access_to_check, downloading, list/access) + // TODO: atom/allowed() handles syndie borgs. We - not. + if (can_run(accessor, loud, access_to_check, downloading, access)) + return TRUE + + // atom/allowed() copycode + var/obj/item/active_item = accessor.get_active_held_item() + var/obj/item/inactive_item = accessor.get_inactive_held_item() + if((active_item && can_run(accessor, loud, access_to_check, downloading, active_item?.GetAccess())) || (inactive_item && can_run(accessor, loud, access_to_check, downloading, inactive_item?.GetAccess()))) + return TRUE + else if(ishuman(accessor)) + var/mob/living/carbon/human/human_accessor = accessor + if(can_run(accessor, loud, access_to_check, downloading, human_accessor.wear_id?.GetAccess())) + return TRUE + else if(isanimal(accessor)) + var/mob/living/simple_animal/animal = accessor + if(can_run(accessor, loud, access_to_check, downloading, animal.access_card?.GetAccess())) + return TRUE + else if(isbrain(accessor)) + var/obj/item/mmi/brain_mmi = get(accessor.loc, /obj/item/mmi) + if(brain_mmi && ismecha(brain_mmi.loc)) + var/obj/vehicle/sealed/mecha/big_stompy_robot = brain_mmi.loc + return can_run(accessor, loud, access_to_check, downloading, big_stompy_robot.accesses) + return FALSE diff --git a/tff_modular/modules/all_computers_to_modular_consoles/circuit_disk.dm b/tff_modular/modules/all_computers_to_modular_consoles/circuit_disk.dm new file mode 100644 index 00000000000..10b8157533f --- /dev/null +++ b/tff_modular/modules/all_computers_to_modular_consoles/circuit_disk.dm @@ -0,0 +1,27 @@ +/obj/item/computer_console_disk + name = "Encrypted NTnet Modem" + desc = "Contains software which allows computer to establish secure connection to NTNet for certain function" + icon = 'icons/obj/devices/circuitry_n_data.dmi' + icon_state = "datadisk6" + // Actual program for instalation + var/datum/computer_file/program/disk_binded/program + // Pointer to program, cloned into PC, to remove when disk ejecting + var/datum/computer_file/program/disk_binded/installed_clone + +/obj/item/computer_console_disk/Initialize(mapload) + . = ..() + if (program) + if (ispath(program)) + program = new program() + name = "encrypted connection driver ([program.filename])" + desc = "Contains software which allows computer to establish secure connection to NTNet for certain function.\n\n[program.extended_desc]" + +/obj/item/computer_console_disk/Destroy(force) + if (program && isdatum(program)) + qdel(program) + program = null + if (installed_clone) + qdel(installed_clone) + installed_clone = null + + . = ..() diff --git a/tff_modular/modules/all_computers_to_modular_consoles/computer_ui.dm b/tff_modular/modules/all_computers_to_modular_consoles/computer_ui.dm new file mode 100644 index 00000000000..ae01eaafa5a --- /dev/null +++ b/tff_modular/modules/all_computers_to_modular_consoles/computer_ui.dm @@ -0,0 +1,36 @@ +/obj/item/modular_computer/proc/handle_ui_removable_media_insert(mob/user) + var/list/removable_media = list() + + // Removable console data disk + var/datum/computer_file/program/filemanager/fm = locate() in stored_files + if (fm?.console_disk) + removable_media += "[HAS_TRAIT(user, TRAIT_KNOW_ENGI_WIRES) ? "Safe removal:" : "Unsafe eject:"] [fm.console_disk.program?.filename] driver" + + // Science Hub disks + var/datum/computer_file/program/science/rnd = locate() in stored_files + if (rnd?.t_disk) + removable_media += "Technology Disk" + if (rnd?.d_disk) + removable_media += "Design Disk" + + return removable_media + +/obj/item/modular_computer/proc/handle_ui_removable_media_eject(param, mob/user) + // Removable console data disk (switch wants constant expression) + var/datum/computer_file/program/filemanager/fm = locate() in stored_files + if (param == "[HAS_TRAIT(user, TRAIT_KNOW_ENGI_WIRES) ? "Safe removal:" : "Unsafe eject:"] [fm?.console_disk?.program?.filename] driver") + if (fm?.try_eject(user)) + playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, FALSE) + return TRUE + return + switch(param) + // Science Hub disks + if ("Technology Disk", "Design Disk") + var/datum/computer_file/program/science/rnd = locate() in stored_files + if (!rnd) + return + if(rnd.try_eject(user)) + playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, FALSE) + return TRUE + + return diff --git a/tff_modular/modules/all_computers_to_modular_consoles/disk_binded.dm b/tff_modular/modules/all_computers_to_modular_consoles/disk_binded.dm new file mode 100644 index 00000000000..be84853696c --- /dev/null +++ b/tff_modular/modules/all_computers_to_modular_consoles/disk_binded.dm @@ -0,0 +1,7 @@ +/datum/computer_file/program/disk_binded + undeletable = TRUE + download_access = list() + run_access = list() + size = 0 + program_flags = PROGRAM_REQUIRES_NTNET + can_run_on_flags = PROGRAM_CONSOLE diff --git a/tff_modular/modules/all_computers_to_modular_consoles/file_browser.dm b/tff_modular/modules/all_computers_to_modular_consoles/file_browser.dm new file mode 100644 index 00000000000..1259cd4be0c --- /dev/null +++ b/tff_modular/modules/all_computers_to_modular_consoles/file_browser.dm @@ -0,0 +1,63 @@ +/datum/computer_file/program/filemanager + var/obj/item/computer_console_disk/console_disk + +/datum/computer_file/program/filemanager/application_attackby(obj/item/computer_console_disk/attacking_item, mob/living/user) + if (!istype(attacking_item)) + return FALSE + + if (console_disk) + to_chat(user, span_warning("It's secure disk drive already occupied!")) + return FALSE + if (!attacking_item.program) + computer.say("I/O ERROR: Unable to access encrypted data disk. Ejecting...") + return FALSE + + if (!attacking_item.program.is_supported_by_hardware(computer.hardware_flag)) + var/list/supported_hardware = list() + if (attacking_item.program.can_run_on_flags == PROGRAM_ALL) + supported_hardware += "...Anything... please report info about your PC and program to NT TechSupport." + else + if (attacking_item.program.can_run_on_flags & PROGRAM_CONSOLE) + supported_hardware += "Console" + if (attacking_item.program.can_run_on_flags & PROGRAM_LAPTOP) + supported_hardware += "Laptop" + if (attacking_item.program.can_run_on_flags & PROGRAM_PDA) + supported_hardware += "PDA" + computer.say("HARDWARE ERROR: Incompatible software. Ejecting... Supported devices: [supported_hardware.Join(" | ")]") + return FALSE + + if(!user.transferItemToLoc(attacking_item, src)) + return FALSE + console_disk = attacking_item + playsound(src, 'sound/machines/card_slide.ogg', 50) + + if (console_disk.program) + var/datum/computer_file/program/disk_binded/clone = console_disk.program.clone() + console_disk.installed_clone = clone + computer.store_file(clone) + // Initial start after injecting is free + clone.run_access = list() + computer.open_program(user, clone, computer.enabled) + clone.run_access = console_disk.program.run_access + + return TRUE + +/datum/computer_file/program/filemanager/try_eject(mob/living/user, forced = FALSE) + if (forced || !user || HAS_TRAIT(user, TRAIT_KNOW_ENGI_WIRES)) + computer.remove_file(console_disk.installed_clone) + user.put_in_hands(console_disk) + console_disk.installed_clone = null + console_disk = null + return TRUE + else + // 2 to unscrew, 3 to eject glass, cut wires and eject circuit + user.visible_message(span_warning("[user] tries to rip off [console_disk] from [computer]!"), span_notice("You try to remove stuck [console_disk] from [computer]...")) + if (do_after(user, 5 SECONDS, computer.physical ? computer.physical : get_turf(computer))) + computer.remove_file(console_disk.installed_clone) + user.put_in_hands(console_disk) + console_disk.installed_clone = null + console_disk = null + // TODO add BSOD screen or something + return TRUE + to_chat(user, span_warning("You should be near \the [computer.physical ? computer.physical : computer]!")) + return FALSE diff --git a/tff_modular/modules/all_computers_to_modular_consoles/integration.dm b/tff_modular/modules/all_computers_to_modular_consoles/integration.dm new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tff_modular/modules/all_computers_to_modular_consoles/programms/rdconsole.dm b/tff_modular/modules/all_computers_to_modular_consoles/programms/rdconsole.dm new file mode 100644 index 00000000000..53bbb1198e4 --- /dev/null +++ b/tff_modular/modules/all_computers_to_modular_consoles/programms/rdconsole.dm @@ -0,0 +1,143 @@ +#define RND_TECH_DISK "tech" +#define RND_DESIGN_DISK "design" + +/datum/computer_file/program/science + /// The stored technology disk, if present + var/obj/item/disk/tech_disk/t_disk + /// The stored design disk, if present + var/obj/item/disk/design_disk/d_disk + var/techweb_tracked = FALSE + +/datum/computer_file/program/science/proc/handle_rnd_control_install() + if (stored_research) + if (!techweb_tracked) + // Do not count PDAs in nullspace, please + if (computer.loc && !(src in stored_research.apps_accessing)) + stored_research.apps_accessing += src + techweb_tracked = TRUE + // Oh wait, you are off-station or emgged? Be unlocked, please! + if (!istype(stored_research, /datum/techweb/science) || (computer.obj_flags & EMAGGED)) + locked = FALSE + +/datum/computer_file/program/science/proc/handle_rnd_control_remove() + if (stored_research) + stored_research.apps_accessing -= src + techweb_tracked = FALSE + +/datum/computer_file/program/science/Destroy() + handle_rnd_control_remove() + . = ..() + +/datum/computer_file/program/science/on_start(mob/living/user) + . = ..() + if (!techweb_tracked) + handle_rnd_control_install() + +/datum/computer_file/program/science/clone() + var/datum/computer_file/program/science/temp = ..() + // No, you can't reassemble console to reset access lock + temp.locked = TRUE + return temp + +/* +/datum/computer_file/program/science/on_examine(obj/item/modular_computer/source, mob/user) + var/list/examine_text = list() + if(!t_disk && !d_disk) + examine_text += "It has a slot installed for science data disk." + return examine_text + + if(computer.Adjacent(user)) + examine_text += "It has a slot installed for science data which contains: [t_disk ? t_disk.name : d_disk.name]" + else + examine_text += "It has a slot installed for science data, which appears to be occupied." + examine_text += span_info("Alt-click to eject the science data disk.") + return examine_text +*/ + +/datum/computer_file/program/science/proc/handle_disks_insertion(obj/item/D, mob/living/user) + // No disks in PDA please + if (!(computer.hardware_flag & PROGRAM_CONSOLE)) + to_chat(user, span_warning("You fail to insert [D]. Maybe you should try stationary console?")) + return FALSE + // Unfortunatly eject code doesn't support diffrent ejectables + if (t_disk || d_disk) + to_chat(user, span_warning("Science data disk slot already occupied!")) + return FALSE + if(istype(D, /obj/item/disk/tech_disk)) + if(!user.transferItemToLoc(D, computer)) + to_chat(user, span_warning("[D] is stuck to your hand!")) + return FALSE + t_disk = D + else if (istype(D, /obj/item/disk/design_disk)) + if(!user.transferItemToLoc(D, computer)) + to_chat(user, span_warning("[D] is stuck to your hand!")) + return FALSE + d_disk = D + to_chat(user, span_notice("You insert [D] into \the [computer.name]!")) + playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, FALSE) + return TRUE + +/datum/computer_file/program/science/proc/handle_disks_ui_data(list/data) + if (t_disk) + data["t_disk"] = list ( + "stored_research" = t_disk.stored_research.researched_nodes, + ) + if (d_disk) + data["d_disk"] = list("blueprints" = list()) + for (var/datum/design/D in d_disk.blueprints) + data["d_disk"]["blueprints"] += D.id + + return data + +/datum/computer_file/program/science/proc/handle_disks_ui_act(action, list/params) + + switch(action) + if ("ejectDisk") + return try_eject() + if ("uploadDisk") + if (params["type"] == RND_DESIGN_DISK) + if(QDELETED(d_disk)) + computer.say("No design disk inserted!") + return TRUE + for(var/D in d_disk.blueprints) + if(D) + stored_research.add_design(D, TRUE) + computer.say("Uploading blueprints from disk.") + d_disk.on_upload(stored_research) + return TRUE + if (params["type"] == RND_TECH_DISK) + if (QDELETED(t_disk)) + computer.say("No tech disk inserted!") + return TRUE + computer.say("Uploading technology disk.") + t_disk.stored_research.copy_research_to(stored_research) + return TRUE + //Tech disk-only action. + if ("loadTech") + if(QDELETED(t_disk)) + computer.say("No tech disk inserted!") + return + stored_research.copy_research_to(t_disk.stored_research) + computer.say("Downloading to technology disk.") + return TRUE + +/datum/computer_file/program/science/try_eject(mob/living/user, forced = FALSE) + if (!t_disk && !d_disk) + if (user) + to_chat(user, span_warning("There is no card in \the [computer.name].")) + return FALSE + + var/obj/item/disk = t_disk ? t_disk : d_disk + if(user && computer.Adjacent(user)) + to_chat(user, span_notice("You remove [disk] from [computer.name].")) + user.put_in_hands(disk) + else + disk.forceMove(computer.drop_location()) + + t_disk = null + d_disk = null + + return TRUE + +#undef RND_TECH_DISK +#undef RND_DESIGN_DISK diff --git a/tff_modular/modules/all_computers_to_modular_consoles/programms/server_control.dm b/tff_modular/modules/all_computers_to_modular_consoles/programms/server_control.dm new file mode 100644 index 00000000000..6d8d5f426ab --- /dev/null +++ b/tff_modular/modules/all_computers_to_modular_consoles/programms/server_control.dm @@ -0,0 +1,110 @@ +/datum/computer_file/program/disk_binded/rdservercontrol + filename = "sci_net_admin" + filedesc = "Researh Network Admin Panel" + program_open_overlay = "research" + extended_desc = "Connect to the internal science server in order to control their behavior." + program_flags = PROGRAM_REQUIRES_NTNET + size = 0 + tgui_id = "NtosServerControl" + program_icon = "server" + run_access = list(ACCESS_RD) + /// Reference to global science techweb + var/datum/techweb/stored_research + +/datum/computer_file/program/disk_binded/rdservercontrol/on_install(datum/computer_file/source, obj/item/modular_computer/computer_installing) + . = ..() + if(!CONFIG_GET(flag/no_default_techweb_link) && !stored_research) + CONNECT_TO_RND_SERVER_ROUNDSTART(stored_research, computer) + +/datum/computer_file/program/disk_binded/rdservercontrol/application_attackby(obj/item/attacking_item, mob/living/user) + if(!istype(attacking_item, /obj/item/multitool)) + return FALSE + var/obj/item/multitool/attacking_tool = attacking_item + if(!QDELETED(attacking_tool.buffer) && istype(attacking_tool.buffer, /datum/techweb)) + stored_research = attacking_tool.buffer + return TRUE + +/datum/computer_file/program/disk_binded/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" = console.loc == null ? "UNKNOWN" : get_area(console), + "console_locked" = console.locked, + "console_ref" = REF(console), + )) + for (var/datum/computer_file/program/science/app in stored_research.apps_accessing) + data["consoles"] += list(list( + "console_name" = app.computer, + "console_location" = app.computer.loc == null ? "UNKNOWN" : get_area(app.computer), + "console_locked" = app.locked, + "console_ref" = REF(app), + )) + + return data + +/datum/computer_file/program/disk_binded/rdservercontrol/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) + . = ..() + if(.) + return TRUE + if(!can_run_Adjacent(usr) && !(computer.obj_flags & EMAGGED)) + computer.say("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) + var/datum/computer_file/program/science/app = locate(params["selected_console"]) in stored_research.apps_accessing + if (!app) + return FALSE + app.locked = !app.locked + return TRUE + console_selected.locked = !console_selected.locked + return TRUE + +// Legacy computer code +// Inject into console code to add science app tracking +/* +/obj/machinery/computer/rdservercontrol/proc/handle_ui_data_apps_insertion() + var/list/data = list() + + for (var/datum/computer_file/program/science/app in stored_research.apps_accessing) + data += list(list( + "console_name" = app.computer, + "console_location" = app.computer.loc == null ? "UNKNOWN" : get_area(app.computer), + "console_locked" = app.locked, + "console_ref" = REF(app), + )) + return data + +/obj/machinery/computer/rdservercontrol/proc/handle_ui_act_apps_lock(choosen_app) + var/datum/computer_file/program/science/app = locate(choosen_app) in stored_research.apps_accessing + if (!app) + return FALSE + app.locked = !app.locked + return TRUE +*/ +/obj/item/computer_console_disk/rdservercontrol + program = /datum/computer_file/program/disk_binded/rdservercontrol diff --git a/tgstation.dme b/tgstation.dme index 33f9e58a08f..6bc86115162 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -8282,6 +8282,15 @@ #include "tff_modular\master_files\code\modules\mod\_module.dm" #include "tff_modular\master_files\code\modules\mod\mod_clothes.dm" #include "tff_modular\master_files\code\modules\reagents\recipe\coagulant_recipe.dm" +#include "tff_modular\modules\all_computers_to_modular_consoles\_techweb.dm" +#include "tff_modular\modules\all_computers_to_modular_consoles\access_helper.dm" +#include "tff_modular\modules\all_computers_to_modular_consoles\circuit_disk.dm" +#include "tff_modular\modules\all_computers_to_modular_consoles\computer_ui.dm" +#include "tff_modular\modules\all_computers_to_modular_consoles\disk_binded.dm" +#include "tff_modular\modules\all_computers_to_modular_consoles\file_browser.dm" +#include "tff_modular\modules\all_computers_to_modular_consoles\integration.dm" +#include "tff_modular\modules\all_computers_to_modular_consoles\programms\rdconsole.dm" +#include "tff_modular\modules\all_computers_to_modular_consoles\programms\server_control.dm" #include "tff_modular\modules\autoaccent\code\autoaccent.dm" #include "tff_modular\modules\barsigns\code\barsigns.dm" #include "tff_modular\modules\blooper\atoms_movable.dm" diff --git a/tgui/packages/tgui/interfaces/NtosServerControl.tsx b/tgui/packages/tgui/interfaces/NtosServerControl.tsx new file mode 100644 index 00000000000..4cf7d8c470d --- /dev/null +++ b/tgui/packages/tgui/interfaces/NtosServerControl.tsx @@ -0,0 +1,164 @@ +// THIS IS A FLUFFY FONTIER UI FILE +import { BooleanLike } from 'common/react'; + +import { useBackend } from '../backend'; +import { Button, Collapsible, NoticeBox, Section, Table } from '../components'; +import { NtosWindow, 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 NtosServerControl = (props) => { + const { act, data } = useBackend(); + 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} + + ))} +
+
+ )} +
+
+
+ ); +}; +