From 18f1eb4b2355fdcd811313051560a565d5dcff2c Mon Sep 17 00:00:00 2001 From: AffectedArc07 Date: Sat, 16 May 2020 12:11:15 +0100 Subject: [PATCH] Relays are done! --- code/game/machinery/tcomms/core.dm | 23 +- code/game/machinery/tcomms/relay.dm | 81 ++++ code/game/machinery/telecomms/ntsl2.dm | 562 ------------------------- nano/templates/tcomms_core.tmpl | 16 +- nano/templates/tcomms_relay.tmpl | 107 +++++ 5 files changed, 220 insertions(+), 569 deletions(-) delete mode 100644 code/game/machinery/telecomms/ntsl2.dm create mode 100644 nano/templates/tcomms_relay.tmpl diff --git a/code/game/machinery/tcomms/core.dm b/code/game/machinery/tcomms/core.dm index 66c08ed0b32..59bf9c88375 100644 --- a/code/game/machinery/tcomms/core.dm +++ b/code/game/machinery/tcomms/core.dm @@ -121,7 +121,7 @@ // Now the actual UI stuff ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "tcomms_core.tmpl", "Telecommunications Core", 900, 525) + ui = new(user, src, ui_key, "tcomms_core.tmpl", "Telecommunications Core", 900, 600) ui.open() ui.set_auto_update(1) @@ -132,7 +132,8 @@ // Only send NTTC settings if were on the right tab. This saves on sending overhead. if(ui_tab == UI_TAB_CONFIG) - // Z-level list + // Z-level list. Note that this will also show sectors with hidden relay links, but you cant see the relays themselves + // This allows the crew to realise that sectors have hidden relays data["sectors_available"] = "Count: [length(reachable_zlevels)] | List: [jointext(reachable_zlevels, " ")]" // Toggles data["active"] = active @@ -143,6 +144,8 @@ // Strings data["nttc_setting_language"] = nttc.setting_language data["nttc_job_indicator_type"] = nttc.job_indicator_type + // Network ID + data["network_id"] = network_id if(ui_tab == UI_TAB_LINKS) data["link_password"] = link_password @@ -228,6 +231,13 @@ if(href_list["export"]) usr << browse(nttc.nttc_serialize(), "window=save_nttc") + // Set network ID + if(href_list["network_id"]) + var/new_id = input(usr, "Please enter a new network ID", "Network ID", network_id) + log_action(usr, "renamed core with ID [network_id] to [new_id]") + to_chat(usr, "Device ID changed from [network_id] to [new_id].") + network_id = new_id + if(ui_tab == UI_TAB_LINKS) if(href_list["unlink"]) var/obj/machinery/tcomms/relay/R = locate(href_list["unlink"]) @@ -239,7 +249,14 @@ else to_chat(usr, "ERROR: Relay not found. Please file an issue report.") - // Try to speed-update the UI + if(href_list["change_password"]) + var/new_password = input(usr, "Please enter a new password","New Password", link_password) + log_action(usr, "has changed the password on core with ID [network_id] from [link_password] to [new_password]") + to_chat(usr, "Successfully changed password from [link_password] to [new_password].") + link_password = new_password + + + // Hack to speed update the nanoUI SSnanoui.update_uis(src) #undef UI_TAB_CONFIG diff --git a/code/game/machinery/tcomms/relay.dm b/code/game/machinery/tcomms/relay.dm index f373bbe4a35..721006d0c11 100644 --- a/code/game/machinery/tcomms/relay.dm +++ b/code/game/machinery/tcomms/relay.dm @@ -94,3 +94,84 @@ ..() if(linked_core) linked_core.refresh_zlevels() + + +////////////// +// UI STUFF // +////////////// + +/obj/machinery/tcomms/relay/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) + ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open) + if(!ui) + ui = new(user, src, ui_key, "tcomms_relay.tmpl", "Telecommunications Relay", 600, 400) + ui.open() + ui.set_auto_update(1) + +/obj/machinery/tcomms/relay/ui_data(mob/user, ui_key = "main", datum/topic_state/state = GLOB.default_state) + var/data[0] + // Are we on or not + data["active"] = active + // What is our network ID + data["network_id"] = network_id + // Are we linked + data["linked"] = linked + // Is the link hidden + data["hidden_link"] = hidden_link + + // Only send linked tab stuff if we are linked. This saves on sending overhead. + if(linked) + data["linked_core_id"] = linked_core.network_id + data["linked_core_addr"] = "\ref[linked_core]" + + else + for(var/obj/machinery/tcomms/core/C in GLOB.tcomms_machines) + data["entries"] += list(list("addr" = "\ref[C]", "net_id" = C.network_id, "sector" = C.loc.z)) + + return data + +/obj/machinery/tcomms/relay/Topic(href, href_list) + // Check against href exploits + if(..()) + return + + // All the toggle on/offs go here + if(href_list["toggle_active"]) + active = !active + update_icon() + + // Set network ID + if(href_list["network_id"]) + var/new_id = input(usr, "Please enter a new network ID", "Network ID", network_id) + log_action(usr, "renamed core with ID [network_id] to [new_id]") + to_chat(usr, "Device ID changed from [network_id] to [new_id].") + network_id = new_id + + if(linked) + // Only do these hrefs if we are linked to prevent bugs/exploits + if(href_list["toggle_hidden_link"]) + hidden_link = !hidden_link + log_action(usr, "Modified hidden link for [network_id] (Now [hidden_link])") + + if(href_list["unlink"]) + var/choice = alert(usr, "Are you SURE you want to unlink this relay?\nYou wont be able to re-link without the core password", "Unlink","Yes","No") + if(choice == "Yes") + log_action(usr, "Unlinked [network_id] from [linked_core.network_id]") + Reset() + else + // You should only be able to link if its not linked, to prevent weirdness + if(href_list["link"]) + var/obj/machinery/tcomms/core/C = locate(href_list["link"]) + if(istype(C, /obj/machinery/tcomms/core)) + var/user_pass = input(usr, "Please enter core password","Password Entry") + // Check the password + if(user_pass == C.link_password) + AddLink(C) + to_chat(usr, "Successfully linked to [C.network_id].") + else + to_chat(usr, "ERROR: Password incorrect.") + else + to_chat(usr, "ERROR: Core not found. Please file an issue report.") + + + // Hack to speed update the nanoUI + SSnanoui.update_uis(src) diff --git a/code/game/machinery/telecomms/ntsl2.dm b/code/game/machinery/telecomms/ntsl2.dm deleted file mode 100644 index ec938c46bfd..00000000000 --- a/code/game/machinery/telecomms/ntsl2.dm +++ /dev/null @@ -1,562 +0,0 @@ -#define JOB_STYLE_1 "Name (Job)" -#define JOB_STYLE_2 "Name - Job" -#define JOB_STYLE_3 "\[Job\] Name" -#define JOB_STYLE_4 "(Job) Name" -// Custom Implementations for NTTC -/* NTTC Configuration Datum - * This is an abstract handler for the configuration loadout. It's set up like this both for ease of transfering in and out of the UI - * as well as allowing users to save and load configurations. - */ -/datum/nttc_configuration - var/regex/word_blacklist = new("(EXPLOIT WARNING: [ckey] attempted to upload an NTTC configuration containing JS abusable tags!") - log_admin("EXPLOIT WARNING: [ckey] attempted to upload an NTTC configuration containing JS abusable tags") - return FALSE - var/list/var_list = json_decode(text) - for(var/variable in var_list) - if(variable in to_serialize) // Don't just accept any random vars jesus christ! - if(requires_unlock[variable] && (source && !source.unlocked)) - continue - var/sanitize_method = serialize_sanitize[variable] - var/variable_value = var_list[variable] - variable_value = nttc_sanitize(variable_value, sanitize_method) - if(variable_value != null) - vars[variable] = variable_value - return TRUE - -// Sanitizing user input. Don't blindly trust the JSON. -/datum/nttc_configuration/proc/nttc_sanitize(variable, sanitize_method) - if(!sanitize_method) - return null - - switch(sanitize_method) - if("bool") - return variable ? TRUE : FALSE - // if("table", "array") - if("array") - if(!islist(variable)) - return list() - // Insert html filtering for the regexes here if you're boring - var/newlist = json_decode(html_decode(json_encode(variable))) - if(!islist(newlist)) - return null - return newlist - if("string") - return "[variable]" - - return variable - -// Primary signal modification. This is where all of the variables behavior are actually implemented. -/datum/nttc_configuration/proc/modify_signal(datum/signal/signal) - // Servers are deliberately turned off. Mark every signal as rejected. - if(!toggle_activated) - signal.data["reject"] = TRUE - return - - // Firewall - // This must happen before anything else modifies the signal ["name"]. - if(islist(firewall) && firewall.len > 0) - if(firewall.Find(signal.data["name"])) - signal.data["reject"] = 1 - - // All job and coloring shit - if(toggle_job_color || toggle_name_color) - var/job = signal.data["job"] - job_class = all_jobs[job] - - if(toggle_name_color) - var/new_name = "" + signal.data["name"] + "" - signal.data["name"] = new_name - signal.data["realname"] = new_name // this is required because the broadcaster uses this directly if the speaker doesn't have a voice changer on - - if(toggle_jobs) - var/new_name = "" - var/job = signal.data["job"] - if(job in ert_jobs) - job = "ERT" - if(toggle_job_color) - switch(job_indicator_type) - if(JOB_STYLE_1) - new_name = signal.data["name"] + " ([job]) " - if(JOB_STYLE_2) - new_name = signal.data["name"] + " - [job] " - if(JOB_STYLE_3) - new_name = "\[[job]\] " + signal.data["name"] + " " - if(JOB_STYLE_4) - new_name = "([job]) " + signal.data["name"] + " " - else - switch(job_indicator_type) - if(JOB_STYLE_1) - new_name = signal.data["name"] + " ([job]) " - if(JOB_STYLE_2) - new_name = signal.data["name"] + " - [job] " - if(JOB_STYLE_3) - new_name = "\[[job]\] " + signal.data["name"] + " " - if(JOB_STYLE_4) - new_name = "([job]) " + signal.data["name"] + " " - - signal.data["name"] = new_name - signal.data["realname"] = new_name // this is required because the broadcaster uses this directly if the speaker doesn't have a voice changer on - - // Add the current station time like a time code. - if(toggle_timecode) - var/new_name = "\[[station_time_timestamp()]] " + signal.data["name"] - signal.data["name"] = new_name - signal.data["realname"] = new_name // this is required because the broadcaster uses this directly if the speaker doesn't have a voice changer on - - // This is hacky stuff for multilingual messages... - var/list/message_pieces = signal.data["message"] - - // Makes heads of staff bold - if(toggle_command_bold) - var/job = signal.data["job"] - if((job in ert_jobs) || (job in heads)) - for(var/datum/multilingual_say_piece/S in message_pieces) - S.message = "[capitalize(S.message)]" // This only capitalizes the first word - - // Hacks! - // Censor dat shit like nobody's business - if(toggle_gibberish) - Gibberish_all(message_pieces, 80) - - // Replace everything with HONK! - if(toggle_honk) - var/list/split = splittext(signal.data["message"], " ") - var/honklength = split.len - var/new_message = "" - for(var/i in 1 to honklength) - new_message += pick("HoNK!", "HONK", "HOOOoONK", "HONKHONK!", "HoNnnkKK!!!", "HOOOOOOOOOOONK!!!!11!", "henk!") + " " - signal.data["message"] = message_to_multilingual(new_message) - - // Language Conversion - if(setting_language && valid_languages[setting_language]) - if(setting_language == "--DISABLE--") - setting_language = null - else - for(var/datum/multilingual_say_piece/S in message_pieces) - if(S.speaking != GLOB.all_languages["Noise"]) // check if they are emoting, these do not need to be translated - S.speaking = GLOB.all_languages[setting_language] - - // Regex replacements - // if(islist(regex) && regex.len > 0) - // for(var/datum/multilingual_say_piece/S in message_pieces) - // var/new_message = S.message - // for(var/reg in regex) - // var/replacePattern = pencode_to_html(regex[reg]) - // var/regex/start = regex("[reg]", "gi") - // new_message = start.Replace(new_message, replacePattern) - // S.message = new_message - - // Make sure the message is valid after we tinkered with it, otherwise reject it - if(signal.data["message"] == "" || !signal.data["message"]) - signal.data["reject"] = 1 - -/datum/nttc_configuration/Topic(mob/user, href_list, window_id, obj/machinery/computer/telecomms/traffic/source) - // Toggles - if(href_list["toggle"]) - var/var_to_toggle = href_list["toggle"] - if(requires_unlock[var_to_toggle] && !source.unlocked) - return - if(!(var_to_toggle in to_serialize)) - return - vars[var_to_toggle] = !vars[var_to_toggle] - log_action(user, "toggled NTTC variable [var_to_toggle] [vars[var_to_toggle] ? "on" : "off"]") - - // Job Format - if(href_list["setting_job_card_style"]) - var/card_style = input(user, "Pick a job card format.", "Job Card Format") as null|anything in job_card_styles - if(!card_style) - return - job_indicator_type = card_style - to_chat(user, "Jobs will now have the style of [card_style].") - log_action(user, "has set NTTC job card format to [card_style]", TRUE) - - // Strings - if(href_list["setting_language"]) - var/new_language = input(user, "Pick a language to convert messages to.", "Language Conversion") as null|anything in valid_languages - if(!new_language) - return - if(new_language == "--DISABLE--") - setting_language = null - to_chat(user, "Language conversion disabled.") - else - setting_language = new_language - to_chat(user, "Messages will now be converted to [new_language].") - - log_action(user, new_language == "--DISABLE--" ? "disabled NTTC language conversion" : "set NTTC language conversion to [new_language]", TRUE) - - // Tables - // if(href_list["create_row"]) - // if(href_list["table"] && href_list["table"] in tables) - // if(requires_unlock[href_list["table"]] && !source.unlocked) - // return - // var/new_key = clean_input(user, "Provide a key for the new row.", "New Row") - // if(!new_key) - // return - // var/new_value = clean_input(user, "Provide a new value for the key [new_key]", "New Row") - // if(new_value == null) - // return - // if(word_blacklist.Find(new_value)) //uh oh, they tried to be naughty - // message_admins("EXPLOIT WARNING: [user.ckey] attempted to add a NTTC regex row containing JS abusable tags!") - // log_admin("EXPLOIT WARNING: [user.ckey] attempted to add a NTTC regex row containing JS abusable tags") - // to_chat(user, "ERROR: Regex contained bad strings. Upload cancelled.") - // return - // var/list/table = vars[href_list["table"]] - // table[new_key] = new_value - // to_chat(user, "Added row [new_key] -> [new_value].") - // log_action(user, "updated [href_list["table"]] - new row [new_key] -> [new_value]") - - // if(href_list["delete_row"]) - // if(href_list["table"] && href_list["table"] in tables) - // if(requires_unlock[href_list["table"]] && !source.unlocked) - // return - // var/list/table = vars[href_list["table"]] - // table.Remove(href_list["delete_row"]) - // to_chat(user, "Removed row [href_list["delete_row"]] from [href_list["table"]]") - // log_action(user, "updated [href_list["table"]] - removed row [href_list["delete_row"]]") - - // Arrays - if(href_list["create_item"]) - if(href_list["array"] && (href_list["array"] in arrays)) - if(requires_unlock[href_list["array"]] && !source.unlocked) - return - var/new_value = clean_input(user, "Provide a value for the new index.", "New Index") - if(new_value == null) - return - var/list/array = vars[href_list["array"]] - array.Add(new_value) - to_chat(user, "Added row [new_value].") - log_action(user, "updated [href_list["array"]] - new value [new_value]", TRUE) - - if(href_list["delete_item"]) - if(href_list["array"] && (href_list["array"] in arrays)) - if(requires_unlock[href_list["array"]] && !source.unlocked) - return - var/list/array = vars[href_list["array"]] - array.Remove(href_list["delete_item"]) - to_chat(user, "Removed [href_list["delete_item"]] from [href_list["array"]]") - log_action(user, "updated [href_list["array"]] - removed [href_list["delete_item"]]") - - // Spit out the serialized config to the user - if(href_list["save_config"]) - user << browse(nttc_serialize(), "window=save_nttc") - - if(href_list["load_config"]) - var/json = input(user, "Provide configuration JSON below.", "Load Config", nttc_serialize()) as message - if(nttc_deserialize(json, source, user.ckey)) - log_action(user, "has uploaded a NTTC JSON configuration: [ADMIN_SHOWDETAILS("Show", json)]", TRUE) - - user << output(list2params(list(nttc_serialize())), "[window_id].browser:updateConfig") - -/datum/nttc_configuration/proc/log_action(user, msg, adminmsg = FALSE) - log_game("NTTC: [key_name(user)] [msg]") - log_investigate("[key_name(user)] [msg]", "ntsl") - if(adminmsg) - message_admins("[key_name_admin(user)] [msg]") - -/* Asset datum for the UI */ -/datum/asset/simple/nttc - assets = list( - "bundle.css" = 'html/nttc/dist/bundle.css', - "bundle.js" = 'html/nttc/dist/bundle.js', - "tab_home.html" = 'html/nttc/dist/tab_home.html', - "tab_hack.html" = 'html/nttc/dist/tab_hack.html', - "tab_filtering.html" = 'html/nttc/dist/tab_filtering.html', - "tab_firewall.html" = 'html/nttc/dist/tab_firewall.html', - // "tab_regex.html" = 'html/nttc/dist/tab_regex.html', - "uiTitleFluff.png" = 'html/nttc/dist/uiTitleFluff.png' - ) - -/* Custom subtype of /datum/browser that behaves as we want for our project */ -/datum/browser/nttc - var/initial_config // Initial NTTC configuration - -/datum/browser/nttc/New(nuser, nwindow_id, ntitle = 0, nwidth = 0, nheight = 0, var/atom/nref = null, nttc_config) - . = ..() - initial_config = nttc_config -// Prevent all stylesheets from being added, we have our own CSS that's bundled with gulp -/datum/browser/nttc/add_stylesheet() - return -// No header, we're running a fully complete .html file -/datum/browser/nttc/get_header() - return -// We inject a little code at the bottom of the file, similar to NanoUI, but more limited. -// This code is used for delivering live updates of config changes & allowing the UI to provide Topic data. -/datum/browser/nttc/get_footer() - var/byondSrc = "byond://?src=[ref.UID()];" - var/dat = "" - return dat - -//// NTTC PC //// -/obj/machinery/computer/telecomms/traffic - name = "telecommunications traffic control" - - light_color = LIGHT_COLOR_DARKGREEN - - req_access = list(ACCESS_TCOMSAT) - circuit = /obj/item/circuitboard/comm_traffic - - // NTTC - var/window_id // mostly used to let the configuration datum update the user's UI - var/unlocked = FALSE - -/obj/machinery/computer/telecomms/traffic/multitool_act(mob/user, obj/item/I) - . = TRUE - if(!I.use_tool(src, user, 0, volume = I.tool_volume)) - return - unlocked = !unlocked - to_chat(user, "This computer is now [unlocked ? "Unlocked" : "Locked"]. Reopen the UI to see the difference.") - -/obj/machinery/computer/telecomms/traffic/attack_hand(mob/user) - interact(user) - -/obj/machinery/computer/telecomms/traffic/interact(mob/user) - if(stat & (BROKEN|NOPOWER)) - return 0 - - /* - if(GLOB.nttc_config.valid_languages.len == 1) - GLOB.nttc_config.update_languages() // this is silly but it has to be done because NTTC inits before languages do - var/datum/asset/assets = get_asset_datum(/datum/asset/simple/nttc) - assets.send(user) - - var/dat = file2text("html/nttc/dist/index.html") - if(unlocked) - dat += "\n" - var/datum/browser/nttc/nt_browser = new(user, name, "NTTC", 720, 480, src, GLOB.nttc_config.nttc_serialize()) - nt_browser.set_content(dat) - nt_browser.open() - window_id = nt_browser.window_id - */ - -/obj/machinery/computer/telecomms/traffic/Topic(href, href_list) - if(..()) - return 1 - - var/mob/user = usr - if(!istype(user) || !user.client) - return 0 - - //GLOB.nttc_config.Topic(user, href_list, window_id, src) diff --git a/nano/templates/tcomms_core.tmpl b/nano/templates/tcomms_core.tmpl index dd8835e623b..2cf56a9f204 100644 --- a/nano/templates/tcomms_core.tmpl +++ b/nano/templates/tcomms_core.tmpl @@ -70,6 +70,14 @@ {{:helper.link(data.nttc_setting_language ? data.nttc_setting_language : 'Unset', 'globe', {'nttc_setting_language' : 1}, null, data.nttc_setting_language ? 'selected' : null)}} +
+
+ Network ID: +
+
+ {{:helper.link(data.network_id ? data.network_id : 'Unset', 'server', {'network_id' : 1}, null, data.network_id ? 'selected' : null)}} +
+

Maintenance

{{:helper.link('Import Configuration', 'sign-in', {'import' : 1})}} {{:helper.link('Export Configuration', 'sign-out', {'export' : 1})}} @@ -95,7 +103,7 @@ Link Password:
- {{:data.link_password}} + {{:helper.link(data.link_password ? data.link_password : 'Unset', 'lock', {'change_password' : 1}, null, data.link_password ? 'selected' : null)}}

@@ -125,7 +133,7 @@ {{:value.status ? 'Active' : 'Error'}} {{:helper.link('Unlink', 'unlink', {'unlink' : value.addr}, null, 'infoButton')}} - {{/for}} - - + {{/for}} + + {{/if}} diff --git a/nano/templates/tcomms_relay.tmpl b/nano/templates/tcomms_relay.tmpl new file mode 100644 index 00000000000..04f04820c98 --- /dev/null +++ b/nano/templates/tcomms_relay.tmpl @@ -0,0 +1,107 @@ +

Relay Configuration

+
+
+ Device Active: +
+
+ {{:helper.link(data.active ? 'Enabled' : 'Disabled', 'power-off', {'toggle_active' : 1}, null, data.active ? 'selected' : '')}} +
+
+
+
+ Network ID: +
+
+ {{:helper.link(data.network_id ? data.network_id : 'Unset', 'pencil', {'network_id' : 1}, null, data.network_id ? 'selected' : null)}} +
+
+
+
+ Link Status: +
+
+ {{if data.linked}} + Linked + {{else}} + Unlinked + {{/if}} +
+
+ +{{if data.linked}} +
+
+ Linked Core ID: +
+
+ {{:data.linked_core_id}} +
+
+
+
+ Linked Core Address: +
+
+ {{:data.linked_core_addr}} +
+
+
+
+ Hidden Link: +
+
+ {{:helper.link(data.hidden_link ? 'Yes' : 'No', 'eye-slash', {'toggle_hidden_link' : 1}, null, data.hidden_link ? 'selected' : null)}} +
+
+
+
+ Unlink: +
+
+ {{:helper.link('Unlink', 'unlink', {'unlink' : 1}, null, 'redButton')}} +
+
+{{else}} + +

Please select a Core to link to

+ + + + + + + + + + + + + + + + + {{for data.entries}} + + + + + + + {{/for}} + +
Network AddressNetwork IDSectorLink
{{:value.addr}}{{:value.net_id}}{{:value.sector}}{{:helper.link('Link', 'link', {'link' : value.addr}, null, 'infoButton')}}
+{{/if}}