From 6bad9586305f73713ec3b14fcb24441665b5eb02 Mon Sep 17 00:00:00 2001 From: Archemagus <32466328+Archemagus@users.noreply.github.com> Date: Wed, 10 Apr 2024 02:54:50 +0300 Subject: [PATCH] Core mechanics Includes: 1. New programs for modular, which will function as station's consoles. Existing only on physical drives. 1.1. Currrently fully meged RD Server Control, and adapted Science Hub (tech disk support onboard) 2. New item which will contain said programs and handle their installation, removing. 3. Adding Science Hub app to tracking into RD Sever Conrol. Because... Why not? --- .../computers/item/computer_ui.dm | 2 + .../file_system/programs/techweb.dm | 6 + .../_techweb.dm | 3 + .../access_helper.dm | 36 ++++ .../circuit_disk.dm | 27 +++ .../computer_ui.dm | 36 ++++ .../disk_binded.dm | 7 + .../file_browser.dm | 63 +++++++ .../integration.dm | 0 .../programms/rdconsole.dm | 143 +++++++++++++++ .../programms/server_control.dm | 110 ++++++++++++ tgstation.dme | 9 + .../tgui/interfaces/NtosServerControl.tsx | 164 ++++++++++++++++++ 13 files changed, 606 insertions(+) create mode 100644 tff_modular/modules/all_computers_to_modular_consoles/_techweb.dm create mode 100644 tff_modular/modules/all_computers_to_modular_consoles/access_helper.dm create mode 100644 tff_modular/modules/all_computers_to_modular_consoles/circuit_disk.dm create mode 100644 tff_modular/modules/all_computers_to_modular_consoles/computer_ui.dm create mode 100644 tff_modular/modules/all_computers_to_modular_consoles/disk_binded.dm create mode 100644 tff_modular/modules/all_computers_to_modular_consoles/file_browser.dm create mode 100644 tff_modular/modules/all_computers_to_modular_consoles/integration.dm create mode 100644 tff_modular/modules/all_computers_to_modular_consoles/programms/rdconsole.dm create mode 100644 tff_modular/modules/all_computers_to_modular_consoles/programms/server_control.dm create mode 100644 tgui/packages/tgui/interfaces/NtosServerControl.tsx 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} + + ))} +
+
+ )} +
+
+
+ ); +}; +