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 1/9] 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} + + ))} +
+
+ )} +
+
+
+ ); +}; + From abd9bef2dd88c92502e518319e74f054e7ea8549 Mon Sep 17 00:00:00 2001 From: Archemagus <32466328+Archemagus@users.noreply.github.com> Date: Sun, 21 Apr 2024 20:48:31 +0300 Subject: [PATCH 2/9] refactor + bsod program --- .../file_system/programs/techweb.dm | 2 +- .../{access_helper.dm => _helper.dm} | 10 ++ .../_techweb.dm | 3 - .../circuit_disk.dm | 3 + .../file_browser.dm | 40 +++-- .../programms/_bsod_program.dm | 128 ++++++++++++++ .../programms/rdconsole.dm | 49 ++++-- .../programms/server_control.dm | 2 +- tgstation.dme | 4 +- .../tgui/interfaces/NtosConsolesRevamp.tsx | 65 +++++++ .../tgui/interfaces/NtosServerControl.tsx | 163 +----------------- 11 files changed, 266 insertions(+), 203 deletions(-) rename tff_modular/modules/all_computers_to_modular_consoles/{access_helper.dm => _helper.dm} (78%) delete mode 100644 tff_modular/modules/all_computers_to_modular_consoles/_techweb.dm create mode 100644 tff_modular/modules/all_computers_to_modular_consoles/programms/_bsod_program.dm create mode 100644 tgui/packages/tgui/interfaces/NtosConsolesRevamp.tsx diff --git a/code/modules/modular_computers/file_system/programs/techweb.dm b/code/modules/modular_computers/file_system/programs/techweb.dm index f5ceda23b18..e6ceafb28f5 100644 --- a/code/modules/modular_computers/file_system/programs/techweb.dm +++ b/code/modules/modular_computers/file_system/programs/techweb.dm @@ -33,7 +33,7 @@ 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 + handle_rnd_control_remove() // FLUFFY FRONTIER ADD stored_research = attacking_tool.buffer handle_rnd_control_install() // FLUFFY FRONTIER ADD return TRUE diff --git a/tff_modular/modules/all_computers_to_modular_consoles/access_helper.dm b/tff_modular/modules/all_computers_to_modular_consoles/_helper.dm similarity index 78% rename from tff_modular/modules/all_computers_to_modular_consoles/access_helper.dm rename to tff_modular/modules/all_computers_to_modular_consoles/_helper.dm index 47de9ac1663..9f0069174da 100644 --- a/tff_modular/modules/all_computers_to_modular_consoles/access_helper.dm +++ b/tff_modular/modules/all_computers_to_modular_consoles/_helper.dm @@ -9,6 +9,9 @@ computer.req_access = tmp_req_access computer.req_one_access = tmp_req_one_access */ +/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() /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. @@ -34,3 +37,10 @@ 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 + +/datum/computer_file/program/proc/can_run_on_flags_to_text(flags = can_run_on_flags, as_list = FALSE) + if (flags == PROGRAM_ALL) + return as_list ? list("Anything") : "Anything" + else + var/list/supportable = bitfield_to_list(flags, list("Console", "Laptop", "PDA")) + return as_list ? supportable : supportable.Join(" | ") diff --git a/tff_modular/modules/all_computers_to_modular_consoles/_techweb.dm b/tff_modular/modules/all_computers_to_modular_consoles/_techweb.dm deleted file mode 100644 index c31eaabb41c..00000000000 --- a/tff_modular/modules/all_computers_to_modular_consoles/_techweb.dm +++ /dev/null @@ -1,3 +0,0 @@ -/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/circuit_disk.dm b/tff_modular/modules/all_computers_to_modular_consoles/circuit_disk.dm index 10b8157533f..ec1459da4ba 100644 --- a/tff_modular/modules/all_computers_to_modular_consoles/circuit_disk.dm +++ b/tff_modular/modules/all_computers_to_modular_consoles/circuit_disk.dm @@ -25,3 +25,6 @@ installed_clone = null . = ..() + +/obj/item/computer_console_disk/command + icon_state = "datadisk7" 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 index 1259cd4be0c..83026144957 100644 --- a/tff_modular/modules/all_computers_to_modular_consoles/file_browser.dm +++ b/tff_modular/modules/all_computers_to_modular_consoles/file_browser.dm @@ -13,25 +13,26 @@ 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." + var/supported_hardware = attacking_item.program.can_run_on_flags_to_text() + if (supported_hardware == "Anything") + // how you aren't supported, if you support anything?! + computer.say("HARDWARE ERROR: Software compatibility mismatch! Please report that info to NTTechSupport. PC hardware code: [computer.hardware_flag]. Filename: [attacking_item.program.filename].[lowertext(attacking_item.program.filetype)]") + return FALSE 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 + computer.say("HARDWARE ERROR: Incompatible software. Ejecting... Supported devices: [supported_hardware]") + return FALSE - if(!user.transferItemToLoc(attacking_item, src)) + if(!user.transferItemToLoc(attacking_item, computer)) return FALSE console_disk = attacking_item - playsound(src, 'sound/machines/card_slide.ogg', 50) + playsound(computer, 'sound/machines/terminal_insert_disc.ogg', 50, FALSE) if (console_disk.program) + // Remove BSOD if present + var/datum/computer_file/program/bsod/bsod = computer.find_file_by_name("nt_recovery") + if (bsod) + computer.remove_file(bsod) + var/datum/computer_file/program/disk_binded/clone = console_disk.program.clone() console_disk.installed_clone = clone computer.store_file(clone) @@ -44,20 +45,27 @@ /datum/computer_file/program/filemanager/try_eject(mob/living/user, forced = FALSE) if (forced || !user || HAS_TRAIT(user, TRAIT_KNOW_ENGI_WIRES)) + if (user) + user.put_in_hands(console_disk) + user.visible_message(span_warning("[user] removes [console_disk] from [computer]!"), span_notice("You use 'Safely Remove Hardware' option to eject [console_disk] from [computer]...")) + else + console_disk.forceMove(computer.drop_location()) 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]...")) + user.visible_message(span_warning("[user] tries to rip off [console_disk] from [computer]!"), span_notice("You try to forcibly remove stuck [console_disk] from [computer]...")) if (do_after(user, 5 SECONDS, computer.physical ? computer.physical : get_turf(computer))) + var/datum/computer_file/program/bsod/bsod = new(lowertext("[console_disk.program.filename].[console_disk.program.filetype]")) + 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 + + computer.store_file(bsod) 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/programms/_bsod_program.dm b/tff_modular/modules/all_computers_to_modular_consoles/programms/_bsod_program.dm new file mode 100644 index 00000000000..4676c3f7e46 --- /dev/null +++ b/tff_modular/modules/all_computers_to_modular_consoles/programms/_bsod_program.dm @@ -0,0 +1,128 @@ +/datum/computer_file/program/bsod + filename = "nt_recovery" + filedesc = "System Recovery" + extended_desc = "When something goes wrong this program should tell you how to fix it." + undeletable = TRUE + size = 0 + power_cell_use = NONE + program_flags = PROGRAM_HEADER | PROGRAM_RUNS_WITHOUT_POWER + program_open_overlay = "bsod" + program_icon = "bug-slash" + tgui_id = "NtosConsolesRevamp" + + var/bsod_reason = "unknown.dbg" + var/initial_icon_state_menu = "menu" + var/modular_icon_state_menu = "menu" + var/modular_icon_state_screensaver = "standby" + +/datum/computer_file/program/bsod/New(bsod_source) + . = ..() + bsod_reason = bsod_source + +/datum/computer_file/program/bsod/on_install(datum/computer_file/source, obj/item/modular_computer/computer_installing) + ..() + RegisterSignal(computer, COMSIG_MODULAR_COMPUTER_TURNED_ON, PROC_REF(computer_on)) + + playsound(computer, 'sound/machines/terminal_alert.ogg', 100) + initial_icon_state_menu = computer_installing.icon_state_menu + + // Show BSOD in any condition + computer_installing.icon_state_menu = "bsod" + if (computer_installing.physical && istype(computer_installing.physical, /obj/machinery/modular_computer)) + var/obj/machinery/modular_computer/console = computer_installing.physical + modular_icon_state_menu = console.screen_icon_state_menu + modular_icon_state_screensaver = console.screen_icon_screensaver + + console.screen_icon_state_menu = "bsod" + console.screen_icon_screensaver = "bsod" + + if(!computer.open_program(null, src, computer_installing.enabled)) + // Opening program will update icon, so we need to do this only if program wasn't opened + update_computer_icon() + +/datum/computer_file/program/bsod/Destroy() + computer.icon_state_menu = initial_icon_state_menu + + // Curse you staionary console! + if (computer.physical && istype(computer.physical, /obj/machinery/modular_computer)) + var/obj/machinery/modular_computer/console = computer.physical + console.screen_icon_state_menu = modular_icon_state_menu + console.screen_icon_screensaver = modular_icon_state_screensaver + + computer.physical?.visible_message(span_notice("\The [computer] flashes its screen few times as it reboots from safe mode.")) + playsound(computer, 'sound/machines/computer/computer_start.ogg', 10) + update_computer_icon() + UnregisterSignal(computer, COMSIG_MODULAR_COMPUTER_TURNED_ON) + . = ..() + +/datum/computer_file/program/bsod/on_examine(obj/item/modular_computer/source, mob/user) + var/list/examine_text = list() + examine_text += span_warning("Its screen tells you that previous session of [bsod_reason] finished incorrectly.") + examine_text += span_notice("However you can reboot [computer]\s driver with multitool to remove that noisy message.\nOr just install another similar program.") + return examine_text + +/datum/computer_file/program/bsod/application_attackby(obj/item/attacking_item, mob/living/user) + if(!istype(attacking_item, /obj/item/multitool)) + return FALSE + + user.visible_message(span_notice("[user] tries to diagnose [computer]\s BSOD reason."), span_notice("You plug [attacking_item] pins into [computer] to force restart its drivers...")) + playsound(computer, 'sound/machines/terminal_processing.ogg', 50) + if (do_after(user, 10 SECONDS, computer.physical ? computer.physical : get_turf(computer))) + playsound(computer, 'sound/machines/high_tech_confirm.ogg', 50) + computer.remove_file(src) + return TRUE + return FALSE + +/datum/computer_file/program/bsod/ui_static_data(mob/user) + var/list/data = list() + data["show_imprint"] = istype(computer, /obj/item/modular_computer/pda) + return data + +// If PC has active program it won't sent us any data. +// But for fancy "Overlay" we still need it. So we will collect it manualy +/datum/computer_file/program/bsod/ui_data(mob/user) + var/list/data = list() + data["pai"] = computer.inserted_pai + data["has_light"] = computer.has_light + data["light_on"] = computer.light_on + data["comp_light_color"] = computer.comp_light_color + + data["login"] = list( + IDName = computer.saved_identification || "Unknown", + IDJob = computer.saved_job || "Unknown", + ) + + data["proposed_login"] = list( + IDInserted = computer.computer_id_slot ? TRUE : FALSE, + IDName = computer.computer_id_slot?.registered_name, + IDJob = computer.computer_id_slot?.assignment, + ) + + data["removable_media"] = list() + if(computer.inserted_disk) + data["removable_media"] += "Eject Disk" + var/datum/computer_file/program/ai_restorer/airestore_app = locate() in computer.stored_files + if(airestore_app?.stored_card) + data["removable_media"] += "intelliCard" + data["removable_media"] += computer.handle_ui_removable_media_insert(user) + + data["programs"] = list() + for(var/datum/computer_file/program/program in computer.stored_files) + data["programs"] += list(list( + "name" = program.filename, + "desc" = program.filedesc, + "header_program" = !!(program.program_flags & PROGRAM_HEADER), + "running" = !!(program in computer.idle_threads), + "icon" = program.program_icon, + "alert" = program.alert_pending, + )) + + // Nope no way to avoid us + data["PC_showexitprogram"] = FALSE + data["reason"] = bsod_reason + return data + +// I am inevitable +/datum/computer_file/program/bsod/proc/computer_on(datum/source, mob/user) + SIGNAL_HANDLER + computer.open_program(user, src, TRUE) 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 index 53bbb1198e4..cc484ed0697 100644 --- a/tff_modular/modules/all_computers_to_modular_consoles/programms/rdconsole.dm +++ b/tff_modular/modules/all_computers_to_modular_consoles/programms/rdconsole.dm @@ -2,10 +2,12 @@ #define RND_DESIGN_DISK "design" /datum/computer_file/program/science - /// The stored technology disk, if present + // The stored technology disk, if present var/obj/item/disk/tech_disk/t_disk - /// The stored design disk, if present + // The stored design disk, if present var/obj/item/disk/design_disk/d_disk + // Options same as can_run_on_flags + var/disk_support_hardware_flags = PROGRAM_CONSOLE var/techweb_tracked = FALSE /datum/computer_file/program/science/proc/handle_rnd_control_install() @@ -18,6 +20,8 @@ // Oh wait, you are off-station or emgged? Be unlocked, please! if (!istype(stored_research, /datum/techweb/science) || (computer.obj_flags & EMAGGED)) locked = FALSE + else + techweb_tracked = FALSE /datum/computer_file/program/science/proc/handle_rnd_control_remove() if (stored_research) @@ -28,6 +32,9 @@ handle_rnd_control_remove() . = ..() +// Why? Because on computer_file init moment, we are in nullspace. +// And bringing here LateInititialize() proc only for this is a bad idea +// Still do not need nullspaced apps in my RD Server Control >=( /datum/computer_file/program/science/on_start(mob/living/user) . = ..() if (!techweb_tracked) @@ -39,25 +46,30 @@ temp.locked = TRUE return temp -/* +/datum/computer_file/program/science/kill_program(mob/user) + try_eject(forced = TRUE) + return ..() + /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 -*/ + if (!(disk_support_hardware_flags & source.hardware_flag)) + return + + 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?")) + if (!(disk_support_hardware_flags & computer.hardware_flag)) + to_chat(user, span_warning("There is no slot for [D]. Maybe you should try: [can_run_on_flags_to_text(disk_support_hardware_flags)]?")) return FALSE // Unfortunatly eject code doesn't support diffrent ejectables if (t_disk || d_disk) @@ -74,7 +86,7 @@ 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) + playsound(computer, 'sound/machines/terminal_insert_disc.ogg', 50, FALSE) return TRUE /datum/computer_file/program/science/proc/handle_disks_ui_data(list/data) @@ -90,7 +102,6 @@ return data /datum/computer_file/program/science/proc/handle_disks_ui_act(action, list/params) - switch(action) if ("ejectDisk") return try_eject() 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 index 6d8d5f426ab..469a997f1bf 100644 --- 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 @@ -106,5 +106,5 @@ app.locked = !app.locked return TRUE */ -/obj/item/computer_console_disk/rdservercontrol +/obj/item/computer_console_disk/command/rdservercontrol program = /datum/computer_file/program/disk_binded/rdservercontrol diff --git a/tgstation.dme b/tgstation.dme index 6bc86115162..54c5d74d4cb 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -8282,13 +8282,13 @@ #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\_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\_bsod_program.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" diff --git a/tgui/packages/tgui/interfaces/NtosConsolesRevamp.tsx b/tgui/packages/tgui/interfaces/NtosConsolesRevamp.tsx new file mode 100644 index 00000000000..a1e8e791c50 --- /dev/null +++ b/tgui/packages/tgui/interfaces/NtosConsolesRevamp.tsx @@ -0,0 +1,65 @@ +// THIS IS A FLUFFY FONTIER UI FILE +import { ReactElement } from 'react'; +import { NtosWindow, Window } from '../layouts'; +import { Dimmer, Flex, Icon, Box } from '../components'; +import { NtosMain } from './NtosMain'; + +// Components for replacement +import { ServerControl } from './ServerControl'; +import { useBackend } from '../backend'; + +type Data = { + reason: string; +}; + +const replaceWindowWithNtosWindow = (node: ReactElement) => { + return ( + + + {node.props.children.props.children} + + + ); +}; + +export const NtosConsolesRevamp = (props) => { + const mainScreen = NtosMain(NtosWindow); + const { data } = useBackend(); + const { reason } = data; + return ( + + + + + + The application is not responding + +
+ + + +
+ + Error with process: +
' + + {reason} + + ' +
+
+ + Try to plug back installation device or restart disk drive systems + with multitool + +
+
+ {mainScreen.props.children.props.children} +
+
+ ); +}; + +export const NtServerControl = (props) => { + return replaceWindowWithNtosWindow(ServerControl(Window)); +}; diff --git a/tgui/packages/tgui/interfaces/NtosServerControl.tsx b/tgui/packages/tgui/interfaces/NtosServerControl.tsx index 4cf7d8c470d..0813a240217 100644 --- a/tgui/packages/tgui/interfaces/NtosServerControl.tsx +++ b/tgui/packages/tgui/interfaces/NtosServerControl.tsx @@ -1,164 +1,5 @@ -// 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; -}; +import { NtServerControl } from './NtosConsolesRevamp'; 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} - - ))} -
-
- )} -
-
-
- ); + return ; }; - From 1dab27e09188cf15ca7568b45af4fd9519a2831a Mon Sep 17 00:00:00 2001 From: Archemagus <32466328+Archemagus@users.noreply.github.com> Date: Sun, 21 Apr 2024 21:47:30 +0300 Subject: [PATCH 3/9] tgui fixes + sanity checks --- .../programms/_bsod_program.dm | 3 ++- .../programms/server_control.dm | 3 ++- .../tgui/interfaces/NtosConsolesRevamp.tsx | 27 ++++++++++++++----- 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/tff_modular/modules/all_computers_to_modular_consoles/programms/_bsod_program.dm b/tff_modular/modules/all_computers_to_modular_consoles/programms/_bsod_program.dm index 4676c3f7e46..e82d9b81c3d 100644 --- a/tff_modular/modules/all_computers_to_modular_consoles/programms/_bsod_program.dm +++ b/tff_modular/modules/all_computers_to_modular_consoles/programms/_bsod_program.dm @@ -17,7 +17,8 @@ /datum/computer_file/program/bsod/New(bsod_source) . = ..() - bsod_reason = bsod_source + if (bsod_source) + bsod_reason = bsod_source /datum/computer_file/program/bsod/on_install(datum/computer_file/source, obj/item/modular_computer/computer_installing) ..() 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 index 469a997f1bf..4b3850355e5 100644 --- 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 @@ -22,7 +22,8 @@ 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 + return TRUE + return FALSE /datum/computer_file/program/disk_binded/rdservercontrol/ui_data(mob/user) var/list/data = list() diff --git a/tgui/packages/tgui/interfaces/NtosConsolesRevamp.tsx b/tgui/packages/tgui/interfaces/NtosConsolesRevamp.tsx index a1e8e791c50..135d2e3c63f 100644 --- a/tgui/packages/tgui/interfaces/NtosConsolesRevamp.tsx +++ b/tgui/packages/tgui/interfaces/NtosConsolesRevamp.tsx @@ -1,12 +1,12 @@ // THIS IS A FLUFFY FONTIER UI FILE import { ReactElement } from 'react'; + +import { useBackend } from '../backend'; +import { Blink, Box, Dimmer, Flex, Icon } from '../components'; import { NtosWindow, Window } from '../layouts'; -import { Dimmer, Flex, Icon, Box } from '../components'; import { NtosMain } from './NtosMain'; - // Components for replacement import { ServerControl } from './ServerControl'; -import { useBackend } from '../backend'; type Data = { reason: string; @@ -36,16 +36,31 @@ export const NtosConsolesRevamp = (props) => {
- + + + +
+
Error with process: -
' +
+ ' {reason} - ' + '

From ead283b4c76b1540d3908c666cce8de81644fcda Mon Sep 17 00:00:00 2001 From: Archemagus <32466328+Archemagus@users.noreply.github.com> Date: Wed, 24 Apr 2024 14:34:01 +0300 Subject: [PATCH 4/9] access rework + console presets --- .../_helper.dm | 9 +- .../consoles_preset.dm | 99 +++++++++++++++++++ .../disk_binded.dm | 25 ++++- .../file_browser.dm | 9 +- .../programms/server_control.dm | 15 ++- tgstation.dme | 1 + 6 files changed, 145 insertions(+), 13 deletions(-) create mode 100644 tff_modular/modules/all_computers_to_modular_consoles/consoles_preset.dm diff --git a/tff_modular/modules/all_computers_to_modular_consoles/_helper.dm b/tff_modular/modules/all_computers_to_modular_consoles/_helper.dm index 9f0069174da..9da8b5c412f 100644 --- a/tff_modular/modules/all_computers_to_modular_consoles/_helper.dm +++ b/tff_modular/modules/all_computers_to_modular_consoles/_helper.dm @@ -10,7 +10,7 @@ computer.req_one_access = tmp_req_one_access */ /datum/techweb - // We wanna track not only consoles but NT apps that connected to us oo + // We wanna track not only consoles but NT apps that connected to us too var/list/datum/computer_file/program/science/apps_accessing = list() /datum/computer_file/program/proc/can_run_Adjacent(mob/accessor, loud, access_to_check, downloading, list/access) @@ -38,6 +38,13 @@ return can_run(accessor, loud, access_to_check, downloading, big_stompy_robot.accesses) return FALSE +// Required access override for disk_binded +/datum/computer_file/program/disk_binded/can_run_Adjacent(mob/accessor, loud, access_to_check, downloading, list/access) + if (!access_to_check && length(download_access)) + access_to_check = download_access + + return ..() + /datum/computer_file/program/proc/can_run_on_flags_to_text(flags = can_run_on_flags, as_list = FALSE) if (flags == PROGRAM_ALL) return as_list ? list("Anything") : "Anything" diff --git a/tff_modular/modules/all_computers_to_modular_consoles/consoles_preset.dm b/tff_modular/modules/all_computers_to_modular_consoles/consoles_preset.dm new file mode 100644 index 00000000000..278b5da47e3 --- /dev/null +++ b/tff_modular/modules/all_computers_to_modular_consoles/consoles_preset.dm @@ -0,0 +1,99 @@ +/obj/machinery/modular_computer/preset/battery_less + var/start_on_power_restore = FALSE + +/obj/machinery/modular_computer/preset/battery_less/Initialize(mapload) + . = ..() + if (!cpu) + return + + // ugh.. no idea how to change cpu type without breaking everything.. So just let it be and remove it's cell + var/cell = cpu.internal_cell + cpu.internal_cell = null + if (cell) + qdel(cell) + +/obj/machinery/modular_computer/preset/battery_less/power_change() + if (!start_on_power_restore) + return ..() + + var/was_unpowered = machine_stat & NOPOWER + . = ..() + if (was_unpowered && !(machine_stat & (BROKEN|NOPOWER)) && cpu && !cpu.enabled) + // Why not cpu.turn_on()? because its crashes without user =/ + if(cpu.looping_sound) + cpu.soundloop.start() + cpu.enabled = TRUE + cpu.update_appearance() + SEND_SIGNAL(cpu, COMSIG_MODULAR_COMPUTER_TURNED_ON, null) + +/obj/machinery/modular_computer/preset/battery_less/console + start_on_power_restore = TRUE + // Disk that will be installed on Initialize() + var/obj/item/computer_console_disk/console_disk + // If no disk. But us we making sure, that we autorun always as PC exist + // No need to fill if console_disk filled + var/datum/computer_file/program/autorunnable + // Sprites from consoles file. Written by program on console_disk. Can be overriden by you or mapper + var/icon_keyboard + +/obj/machinery/modular_computer/preset/battery_less/console/Initialize(mapload) + if (!console_disk && autorunnable && !(autorunnable in starting_programs)) + starting_programs += autorunnable + + . = ..() + + if (cpu && console_disk) + var/datum/computer_file/program/filemanager/filemanager = cpu.find_file_by_name("filemanager") + console_disk = new console_disk(cpu) + + // Oh, preset? Get fancy keyboard for free! (if provided by your program and not overriden) + if (!icon_keyboard && console_disk.program) + icon_keyboard = console_disk.program.icon_keyboard + + filemanager.application_attackby(console_disk) + + else if (cpu && autorunnable) + var/datum/computer_file/program/prog = locate(autorunnable) in cpu.stored_files + // First start for free + cpu.active_program = prog + RegisterSignal(cpu, COMSIG_MODULAR_COMPUTER_TURNED_ON, PROC_REF(autorun)) + +/obj/machinery/modular_computer/preset/battery_less/console/Destroy() + UnregisterSignal(cpu, COMSIG_MODULAR_COMPUTER_TURNED_ON) + . = ..() + +// Custom keyboard icon for maploaded consoles +/obj/machinery/modular_computer/preset/battery_less/console/update_overlays() + . = ..() + if (icon_keyboard) + // There was keyboard_change_icon var but its always TRUE... + if(machine_stat & NOPOWER || !cpu?.enabled) + . += mutable_appearance('icons/obj/machines/computer.dmi', "[icon_keyboard]_off") + else + . += mutable_appearance('icons/obj/machines/computer.dmi', icon_keyboard) + + +// Only for not disked programs like Science Hub or Cargo. Those who accessed ingame via NTnet +/obj/machinery/modular_computer/preset/battery_less/console/proc/autorun(datum/source, mob/user) + SIGNAL_HANDLER + + if (cpu && autorunnable) + var/datum/computer_file/program/prog = locate(autorunnable) in cpu.stored_files + if (prog) + // Not writing in active_programs so user need to check his access + cpu.open_program(user, prog, cpu.enabled) + else if (cpu) + UnregisterSignal(cpu, COMSIG_MODULAR_COMPUTER_TURNED_ON) + // If else - something goes wrong + +// Actual presets of non console_disk computers +/obj/machinery/modular_computer/preset/battery_less/console/rdconsole_unQoL + name = "R&D Console" + desc = "A console used to interface with R&D tools." + icon_keyboard = "rd_key" + autorunnable = /datum/computer_file/program/science + +/obj/machinery/modular_computer/preset/battery_less/console/cargo_unQoL + name = "supply console" + desc = "Used to order supplies, approve requests, and control the shuttle." + autorunnable = /datum/computer_file/program/budgetorders 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 index be84853696c..64bb3bbf379 100644 --- a/tff_modular/modules/all_computers_to_modular_consoles/disk_binded.dm +++ b/tff_modular/modules/all_computers_to_modular_consoles/disk_binded.dm @@ -1,7 +1,26 @@ /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 + undeletable = TRUE + // Okay. Now about accesses: we are never on NTstore, so download_access doesn't care + // Meanwhile program run is always (or almost) free, but interactions... + // So run_access should be empty, but all yours req_access type into download_access + // So I didn't have to create another access variable + download_access = list() + run_access = list() + // Icon_state of the keyboard overlay for mapload. If any... + var/icon_keyboard + +/datum/computer_file/program/disk_binded/on_install(datum/computer_file/source, obj/item/modular_computer/computer_installing) + ..() + RegisterSignal(computer, COMSIG_MODULAR_COMPUTER_TURNED_ON, PROC_REF(autorun)) + +/datum/computer_file/program/disk_binded/Destroy() + UnregisterSignal(computer, COMSIG_MODULAR_COMPUTER_TURNED_ON) + ..() + +/datum/computer_file/program/disk_binded/proc/autorun(datum/source, mob/user) + SIGNAL_HANDLER + + computer.open_program(user, src, computer.enabled) 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 index 83026144957..11e0cd40dbb 100644 --- a/tff_modular/modules/all_computers_to_modular_consoles/file_browser.dm +++ b/tff_modular/modules/all_computers_to_modular_consoles/file_browser.dm @@ -6,7 +6,8 @@ return FALSE if (console_disk) - to_chat(user, span_warning("It's secure disk drive already occupied!")) + if (user) + 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...") @@ -22,7 +23,7 @@ computer.say("HARDWARE ERROR: Incompatible software. Ejecting... Supported devices: [supported_hardware]") return FALSE - if(!user.transferItemToLoc(attacking_item, computer)) + if(user && !user.transferItemToLoc(attacking_item, computer)) return FALSE console_disk = attacking_item playsound(computer, 'sound/machines/terminal_insert_disc.ogg', 50, FALSE) @@ -36,10 +37,8 @@ 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() + // Initial start computer.open_program(user, clone, computer.enabled) - clone.run_access = console_disk.program.run_access return TRUE 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 index 4b3850355e5..d706b16da64 100644 --- 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 @@ -6,9 +6,10 @@ program_flags = PROGRAM_REQUIRES_NTNET size = 0 tgui_id = "NtosServerControl" - program_icon = "server" - run_access = list(ACCESS_RD) - /// Reference to global science techweb + program_icon = FA_ICON_SERVER + download_access = list(ACCESS_RD) + icon_keyboard = "rd_key" + // 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) @@ -22,6 +23,7 @@ var/obj/item/multitool/attacking_tool = attacking_item if(!QDELETED(attacking_tool.buffer) && istype(attacking_tool.buffer, /datum/techweb)) stored_research = attacking_tool.buffer + computer.say("[filedesc]: Established connection to [stored_research.organization] research network.") // Network id: [stored_research.id] not sure, id may be OOC info return TRUE return FALSE @@ -64,7 +66,7 @@ return TRUE if(!can_run_Adjacent(usr) && !(computer.obj_flags & EMAGGED)) computer.say("Access denied!") - playsound(src, 'sound/machines/click.ogg', 20, TRUE) + playsound(computer, 'sound/machines/terminal_error.ogg', 20, TRUE) return TRUE switch(action) @@ -109,3 +111,8 @@ */ /obj/item/computer_console_disk/command/rdservercontrol program = /datum/computer_file/program/disk_binded/rdservercontrol + +/obj/machinery/modular_computer/preset/battery_less/console/rdservercontrol + name = "R&D Server Controller" + desc = "Manages access to research databases and consoles." + console_disk = /obj/item/computer_console_disk/command/rdservercontrol diff --git a/tgstation.dme b/tgstation.dme index 54c5d74d4cb..953d08802b9 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -8285,6 +8285,7 @@ #include "tff_modular\modules\all_computers_to_modular_consoles\_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\consoles_preset.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" From 748261a2b4a1d1b7bc65291a8308d84105762717 Mon Sep 17 00:00:00 2001 From: Archemagus <32466328+Archemagus@users.noreply.github.com> Date: Wed, 24 Apr 2024 15:30:08 +0300 Subject: [PATCH 5/9] automatic consoles replacement system + autostart on Initialize --- .../consoles_preset.dm | 13 ++++++++++++ .../integration.dm | 21 +++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/tff_modular/modules/all_computers_to_modular_consoles/consoles_preset.dm b/tff_modular/modules/all_computers_to_modular_consoles/consoles_preset.dm index 278b5da47e3..1b56a255e51 100644 --- a/tff_modular/modules/all_computers_to_modular_consoles/consoles_preset.dm +++ b/tff_modular/modules/all_computers_to_modular_consoles/consoles_preset.dm @@ -58,6 +58,19 @@ cpu.active_program = prog RegisterSignal(cpu, COMSIG_MODULAR_COMPUTER_TURNED_ON, PROC_REF(autorun)) +/obj/machinery/modular_computer/preset/battery_less/console/LateInitialize() + . = ..() + // Autoenable on init + // cpu.turn_on() copycode + if(cpu.use_energy(cpu.base_active_power_usage)) // checks if the PC is powered + if(cpu.looping_sound) + cpu.soundloop.skip_starting_sounds = TRUE + cpu.soundloop.start() + cpu.soundloop.skip_starting_sounds = initial(cpu.soundloop.skip_starting_sounds) + cpu.enabled = TRUE + cpu.update_appearance() + SEND_SIGNAL(cpu, COMSIG_MODULAR_COMPUTER_TURNED_ON, null) + /obj/machinery/modular_computer/preset/battery_less/console/Destroy() UnregisterSignal(cpu, COMSIG_MODULAR_COMPUTER_TURNED_ON) . = ..() diff --git a/tff_modular/modules/all_computers_to_modular_consoles/integration.dm b/tff_modular/modules/all_computers_to_modular_consoles/integration.dm index e69de29bb2d..f6231584326 100644 --- a/tff_modular/modules/all_computers_to_modular_consoles/integration.dm +++ b/tff_modular/modules/all_computers_to_modular_consoles/integration.dm @@ -0,0 +1,21 @@ +GLOBAL_LIST_INIT(consoles_replacement_map, list( + /obj/machinery/computer/rdservercontrol = /obj/machinery/modular_computer/preset/battery_less/console/rdservercontrol, +)) + +/obj/machinery/computer/Initialize(mapload, obj/item/circuitboard/C) + . = ..() + if (mapload && (src.type in GLOB.consoles_replacement_map)) + var/obj/machinery/modular_computer/preset/battery_less/console/console = GLOB.consoles_replacement_map[src.type] + console = new console(src.loc) + transfer_data_to_modular_console(console) + console.update_appearance() + return INITIALIZE_HINT_QDEL + +/obj/machinery/computer/proc/transfer_data_to_modular_console(obj/machinery/modular_computer/preset/battery_less/console/console) + SHOULD_CALL_PARENT(TRUE) + + console.setDir(dir) + console.name = name + + if (console.cpu) + console.cpu.desc = desc From 44e0abe703ed723c582a5d79b2101e5b516157df Mon Sep 17 00:00:00 2001 From: Archemagus <32466328+Archemagus@users.noreply.github.com> Date: Wed, 24 Apr 2024 16:07:01 +0300 Subject: [PATCH 6/9] SignallFixes --- .../all_computers_to_modular_consoles/consoles_preset.dm | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tff_modular/modules/all_computers_to_modular_consoles/consoles_preset.dm b/tff_modular/modules/all_computers_to_modular_consoles/consoles_preset.dm index 1b56a255e51..1d99fc8a083 100644 --- a/tff_modular/modules/all_computers_to_modular_consoles/consoles_preset.dm +++ b/tff_modular/modules/all_computers_to_modular_consoles/consoles_preset.dm @@ -56,7 +56,7 @@ var/datum/computer_file/program/prog = locate(autorunnable) in cpu.stored_files // First start for free cpu.active_program = prog - RegisterSignal(cpu, COMSIG_MODULAR_COMPUTER_TURNED_ON, PROC_REF(autorun)) + RegisterSignal(cpu, COMSIG_MODULAR_COMPUTER_TURNED_ON, PROC_REF(autorun)) /obj/machinery/modular_computer/preset/battery_less/console/LateInitialize() . = ..() @@ -95,9 +95,6 @@ if (prog) // Not writing in active_programs so user need to check his access cpu.open_program(user, prog, cpu.enabled) - else if (cpu) - UnregisterSignal(cpu, COMSIG_MODULAR_COMPUTER_TURNED_ON) - // If else - something goes wrong // Actual presets of non console_disk computers /obj/machinery/modular_computer/preset/battery_less/console/rdconsole_unQoL From 6d776407c278f65a84797e0656b1a1ff11a6bae9 Mon Sep 17 00:00:00 2001 From: Archemagus <32466328+Archemagus@users.noreply.github.com> Date: Wed, 24 Apr 2024 16:18:06 +0300 Subject: [PATCH 7/9] bypassing very cringe LateInit error --- .../all_computers_to_modular_consoles/consoles_preset.dm | 2 -- 1 file changed, 2 deletions(-) diff --git a/tff_modular/modules/all_computers_to_modular_consoles/consoles_preset.dm b/tff_modular/modules/all_computers_to_modular_consoles/consoles_preset.dm index 1d99fc8a083..03068bc1659 100644 --- a/tff_modular/modules/all_computers_to_modular_consoles/consoles_preset.dm +++ b/tff_modular/modules/all_computers_to_modular_consoles/consoles_preset.dm @@ -58,8 +58,6 @@ cpu.active_program = prog RegisterSignal(cpu, COMSIG_MODULAR_COMPUTER_TURNED_ON, PROC_REF(autorun)) -/obj/machinery/modular_computer/preset/battery_less/console/LateInitialize() - . = ..() // Autoenable on init // cpu.turn_on() copycode if(cpu.use_energy(cpu.base_active_power_usage)) // checks if the PC is powered From c81ab5ce2f56b548f969acfc8b1a22018712f63c Mon Sep 17 00:00:00 2001 From: Archemagus <32466328+Archemagus@users.noreply.github.com> Date: Wed, 24 Apr 2024 16:35:06 +0300 Subject: [PATCH 8/9] attempt 1 --- .../all_computers_to_modular_consoles/disk_binded.dm | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) 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 index 64bb3bbf379..d0df6362088 100644 --- a/tff_modular/modules/all_computers_to_modular_consoles/disk_binded.dm +++ b/tff_modular/modules/all_computers_to_modular_consoles/disk_binded.dm @@ -15,10 +15,12 @@ /datum/computer_file/program/disk_binded/on_install(datum/computer_file/source, obj/item/modular_computer/computer_installing) ..() RegisterSignal(computer, COMSIG_MODULAR_COMPUTER_TURNED_ON, PROC_REF(autorun)) + RegisterSignal(src, COMSIG_COMPUTER_FILE_DELETE, PROC_REF(remove_handler)) + +/datum/computer_file/program/disk_binded/proc/remove_handler() + SIGNAL_HANDLER -/datum/computer_file/program/disk_binded/Destroy() UnregisterSignal(computer, COMSIG_MODULAR_COMPUTER_TURNED_ON) - ..() /datum/computer_file/program/disk_binded/proc/autorun(datum/source, mob/user) SIGNAL_HANDLER From 16d7bf0d02e6a00eaa4c67b40ee4dab3fe5bac03 Mon Sep 17 00:00:00 2001 From: Archemagus <32466328+Archemagus@users.noreply.github.com> Date: Wed, 24 Apr 2024 16:44:23 +0300 Subject: [PATCH 9/9] attempt 2 looks legit --- .../all_computers_to_modular_consoles/disk_binded.dm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) 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 index d0df6362088..da69453381c 100644 --- a/tff_modular/modules/all_computers_to_modular_consoles/disk_binded.dm +++ b/tff_modular/modules/all_computers_to_modular_consoles/disk_binded.dm @@ -15,12 +15,12 @@ /datum/computer_file/program/disk_binded/on_install(datum/computer_file/source, obj/item/modular_computer/computer_installing) ..() RegisterSignal(computer, COMSIG_MODULAR_COMPUTER_TURNED_ON, PROC_REF(autorun)) - RegisterSignal(src, COMSIG_COMPUTER_FILE_DELETE, PROC_REF(remove_handler)) -/datum/computer_file/program/disk_binded/proc/remove_handler() - SIGNAL_HANDLER +/datum/computer_file/program/disk_binded/Destroy() + . = ..() - UnregisterSignal(computer, COMSIG_MODULAR_COMPUTER_TURNED_ON) + if (!QDELETED(computer)) + UnregisterSignal(computer, COMSIG_MODULAR_COMPUTER_TURNED_ON) /datum/computer_file/program/disk_binded/proc/autorun(datum/source, mob/user) SIGNAL_HANDLER