From 843559859b7423046bf6a36801c6bd5e9962507a Mon Sep 17 00:00:00 2001 From: Nadyr Date: Mon, 21 Oct 2024 22:18:56 -0400 Subject: [PATCH 01/64] Ports in-round record updates --- code/game/machinery/computer/medical.dm | 10 ++ code/game/machinery/computer/security.dm | 10 ++ code/game/machinery/computer/skills.dm | 10 ++ code/modules/client/record_updator.dm | 129 ++++++++++++++++++ .../GeneralRecords/GeneralRecordsOptions.tsx | 8 ++ .../GeneralRecordsViewGeneral.tsx | 1 + .../MedicalRecords/MedicalRecordsOptions.tsx | 8 ++ .../MedicalRecordsViewMedical.tsx | 15 +- .../SecurityRecordsOptions.tsx | 8 ++ .../SecurityRecordsViewSecurity.tsx | 21 ++- vorestation.dme | 1 + 11 files changed, 214 insertions(+), 7 deletions(-) create mode 100644 code/modules/client/record_updator.dm diff --git a/code/game/machinery/computer/medical.dm b/code/game/machinery/computer/medical.dm index 1fb0455476..22e3fb90c9 100644 --- a/code/game/machinery/computer/medical.dm +++ b/code/game/machinery/computer/medical.dm @@ -296,6 +296,16 @@ active1 = general_record active2 = medical_record screen = MED_DATA_RECORD + if("sync_r") + if(active2) + set_temp(client_update_record(src,usr)) + if("edit_notes") + // The modal input in tgui is busted for this sadly... + var/new_notes = strip_html_simple(tgui_input_text(usr,"Enter new information here.","Character Preference", html_decode(active2.fields["notes"]), MAX_RECORD_LENGTH, TRUE, prevent_enter = TRUE), MAX_RECORD_LENGTH) + if(usr.Adjacent(src)) + if(new_notes != "" || tgui_alert(usr, "Are you sure you want to delete the current record's notes?", "Confirm Delete", list("Delete", "No")) == "Delete") + if(usr.Adjacent(src)) + active2.fields["notes"] = new_notes if("new") if(istype(active1, /datum/data/record) && !istype(active2, /datum/data/record)) var/datum/data/record/R = new /datum/data/record() diff --git a/code/game/machinery/computer/security.dm b/code/game/machinery/computer/security.dm index 1be57d146e..9ed9242767 100644 --- a/code/game/machinery/computer/security.dm +++ b/code/game/machinery/computer/security.dm @@ -270,6 +270,16 @@ qdel(active1) if(active2) qdel(active2) + if("sync_r") + if(active2) + set_temp(client_update_record(src,usr)) + if("edit_notes") + // The modal input in tgui is busted for this sadly... + var/new_notes = strip_html_simple(tgui_input_text(usr,"Enter new information here.","Character Preference", html_decode(active2.fields["notes"]), MAX_RECORD_LENGTH, TRUE, prevent_enter = TRUE), MAX_RECORD_LENGTH) + if(usr.Adjacent(src)) + if(new_notes != "" || tgui_alert(usr, "Are you sure you want to delete the current record's notes?", "Confirm Delete", list("Delete", "No")) == "Delete") + if(usr.Adjacent(src)) + active2.fields["notes"] = new_notes if("d_rec") var/datum/data/record/general_record = locate(params["d_rec"] || "") if(!data_core.general.Find(general_record)) diff --git a/code/game/machinery/computer/skills.dm b/code/game/machinery/computer/skills.dm index 57524d95fd..9be405d36d 100644 --- a/code/game/machinery/computer/skills.dm +++ b/code/game/machinery/computer/skills.dm @@ -214,6 +214,16 @@ for(var/datum/data/record/R in data_core.general) qdel(R) set_temp("All employment records deleted.") + if("sync_r") + if(active1) + set_temp(client_update_record(src,active1,usr)) + if("edit_notes") + // The modal input in tgui is busted for this sadly... + var/new_notes = strip_html_simple(tgui_input_text(usr,"Enter new information here.","Character Preference", html_decode(active1.fields["notes"]), MAX_RECORD_LENGTH, TRUE, prevent_enter = TRUE), MAX_RECORD_LENGTH) + if(usr.Adjacent(src)) + if(new_notes != "" || tgui_alert(usr, "Are you sure you want to delete the current record's notes?", "Confirm Delete", list("Delete", "No")) == "Delete") + if(usr.Adjacent(src)) + active1.fields["notes"] = new_notes if("del_r") if(PDA_Manifest) PDA_Manifest.Cut() diff --git a/code/modules/client/record_updator.dm b/code/modules/client/record_updator.dm new file mode 100644 index 0000000000..de802eedcf --- /dev/null +++ b/code/modules/client/record_updator.dm @@ -0,0 +1,129 @@ +var/global/client_record_update_lock = FALSE + +// Manually updating records from medical console to a player's save. +/proc/get_current_mob_from_record(var/datum/data/record/active) + var/datum/transcore_db/db = SStranscore.db_by_mind_name(active.fields["name"]) + if(db) + var/datum/transhuman/mind_record/record = db.backed_up[active.fields["name"]] + if(record.mind_ref) + var/datum/mind/D = record.mind_ref + if(D.current) + var/client/C = D.current.client + if(C && C.ckey != record.ckey) + return null + return D.current + return null + + +/proc/client_update_record(var/obj/machinery/computer/COM, var/user) + if(!COM || QDELETED(COM)) + return "Invalid console" + + if(jobban_isbanned(user, "Records") ) + COM.visible_message(span_notice("\The [COM] buzzes!")) + playsound(COM, 'sound/machines/deniedbeep.ogg', 50, 0) + return "Update syncronization denied (OOC: You are banned from editing records)" + + var/record_string = "" + var/datum/data/record/active + var/console_path = null + if(istype(COM,/obj/machinery/computer/med_data)) + var/obj/machinery/computer/med_data/MCOM = COM + active = MCOM.active2 + record_string = "medical" + console_path = /obj/machinery/computer/med_data + if(istype(COM,/obj/machinery/computer/skills)) + var/obj/machinery/computer/skills/ECOM = COM + active = ECOM.active1 + record_string = "employment" + console_path = /obj/machinery/computer/skills + if(istype(COM,/obj/machinery/computer/secure_data)) + var/obj/machinery/computer/secure_data/SCOM = COM + active = SCOM.active2 + record_string = "security" + console_path = /obj/machinery/computer/secure_data + + if(client_record_update_lock) + to_chat(user,"Update already in progress! Please wait a moment...") + if(COM && !QDELETED(COM)) + COM.visible_message(span_notice("\The [COM] buzzes!")) + playsound(COM, 'sound/machines/deniedbeep.ogg', 50, 0) + return "Update already in progress! Please wait a moment..." + client_record_update_lock = TRUE + spawn(60 SECONDS) + client_record_update_lock = FALSE + + if(!active || !console_path) + if(COM && !QDELETED(COM)) + COM.visible_message(span_notice("\The [COM] buzzes!")) + playsound(COM, 'sound/machines/deniedbeep.ogg', 50, 0) + return "Update syncronization failed (OOC: Record or console destroyed)" + + to_chat(user,"Update sent! Please wait for a response...") + message_admins("[user] pushed [record_string] record update to [active.fields["name"]].") + + var/mob/M = get_current_mob_from_record(active) + if(!M) + if(COM && !QDELETED(COM)) + COM.visible_message(span_notice("\The [COM] buzzes!")) + playsound(COM, 'sound/machines/deniedbeep.ogg', 50, 0) + return "Update syncronization failed (OOC: Client mob does not exist, has no mind record, or is possesssed)" + + var/client/C = M.client + if(!C) + if(COM && !QDELETED(COM)) + COM.visible_message(span_notice("\The [COM] buzzes!")) + playsound(COM, 'sound/machines/deniedbeep.ogg', 50, 0) + return "Update syncronization failed (OOC: Record's owner is offline)" + + var/choice = tgui_alert(M, "Your [record_string] record has been updated from the a records console by [user]. Please review the changes made to your [record_string] record. Accepting these changes will SAVE your CURRENT character slot! If your new [record_string] record has errors, it is recomended to have it corrected IC instead of editing it yourself.", "Record Updated", list("Review Changes","Refuse Update")) + if(choice == "Refuse Update") + message_admins("[active.fields["name"]] refused [record_string] record update from [user] without review.") + if(COM && !QDELETED(COM)) + COM.visible_message(span_notice("\The [COM] buzzes!")) + playsound(COM, 'sound/machines/deniedbeep.ogg', 50, 0) + return "Update syncronization failed (OOC: Client refused without review)" + + var/datum/preferences/P = C.prefs + var/new_data = strip_html_simple(tgui_input_text(M,"Please review [user]'s changes to your [record_string] record before confirming. Confirming will SAVE your CURRENT character slot! If your new [record_string] record major errors, it is recomended to have it corrected IC instead of editing it yourself.","Character Preference", html_decode(active.fields["notes"]), MAX_RECORD_LENGTH, TRUE, prevent_enter = TRUE), MAX_RECORD_LENGTH) + if(!new_data) + message_admins("[active.fields["name"]] refused [record_string] record update from [user] with review.") + if(COM && !QDELETED(COM)) + COM.visible_message(span_notice("\The [COM] buzzes!")) + playsound(COM, 'sound/machines/deniedbeep.ogg', 50, 0) + return "Update syncronization failed (OOC: Client refused with review)" + if(!M || !M.client || !P) + message_admins("[active.fields["name"]]'s [record_string] record could not be updated, client disconnected.") + if(COM && !QDELETED(COM)) + COM.visible_message(span_notice("\The [COM] buzzes!")) + playsound(COM, 'sound/machines/deniedbeep.ogg', 50, 0) + return "Update syncronization failed (OOC: Client does not exist)" + + // Update records in the consoles, remember this can happen a while after a record is closed on the console... Use cached data. + switch(console_path) + if(/obj/machinery/computer/med_data) + P.med_record = new_data + if(active) + active.fields["notes"] = new_data + if(/obj/machinery/computer/skills) + P.gen_record = new_data + if(active) + active.fields["notes"] = new_data + if(/obj/machinery/computer/secure_data) + P.sec_record = new_data + if(active) + active.fields["notes"] = new_data + + // Update player record + P.save_preferences() + P.save_character() + if(M) + to_chat(M,span_notice("Your [record_string] record for [active.fields["name"]] has been updated.")) + message_admins("[active.fields["name"]] accepted the [record_string] record update from [user].") + + // ding! + if(COM && !QDELETED(COM)) + COM.visible_message(span_notice("\The [COM] dings!")) + playsound(COM, 'sound/machines/ding.ogg', 50, 1) + + return "Record syncronized." diff --git a/tgui/packages/tgui/interfaces/GeneralRecords/GeneralRecordsOptions.tsx b/tgui/packages/tgui/interfaces/GeneralRecords/GeneralRecordsOptions.tsx index 5db9a5c321..457294e6a0 100644 --- a/tgui/packages/tgui/interfaces/GeneralRecords/GeneralRecordsOptions.tsx +++ b/tgui/packages/tgui/interfaces/GeneralRecords/GeneralRecordsOptions.tsx @@ -21,6 +21,14 @@ export const GeneralRecordsView = (props) => {
+ {
{general.skills || 'No data found.'} + {
{general.comments && general.comments.length === 0 ? ( diff --git a/tgui/packages/tgui/interfaces/MedicalRecords/MedicalRecordsOptions.tsx b/tgui/packages/tgui/interfaces/MedicalRecords/MedicalRecordsOptions.tsx index 757e79b7cd..a711cdf931 100644 --- a/tgui/packages/tgui/interfaces/MedicalRecords/MedicalRecordsOptions.tsx +++ b/tgui/packages/tgui/interfaces/MedicalRecords/MedicalRecordsOptions.tsx @@ -36,6 +36,14 @@ export const MedicalRecordsView = (props) => {
+ { {field.value} -
+ { {field.value} -