diff --git a/code/__DEFINES/~monkestation/admin.dm b/code/__DEFINES/~monkestation/admin.dm index 64ddc4de5ccd..642dc3d9d1dd 100644 --- a/code/__DEFINES/~monkestation/admin.dm +++ b/code/__DEFINES/~monkestation/admin.dm @@ -18,3 +18,8 @@ #define AHELP_CLOSEREASON_MENTOR 2 #define ADMIN_SUSINFO(user) "[ADMIN_LOOKUP(user)] [ADMIN_PP(user)] [ADMIN_INDIVIDUALLOG(user)] [ADMIN_SMITE(user)]" + +// Command reports +#define DEFAULT_COMMANDREPORT_SOUND "default_commandreport" +#define DEFAULT_ALERT_SOUND "default_alert" +#define CUSTOM_ALERT_SOUND "custom_alert" diff --git a/code/__HELPERS/priority_announce.dm b/code/__HELPERS/priority_announce.dm index d9b4dfe900cd..59592ca27e6d 100644 --- a/code/__HELPERS/priority_announce.dm +++ b/code/__HELPERS/priority_announce.dm @@ -37,7 +37,7 @@ * * encode_title - if TRUE, the title will be HTML encoded * * encode_text - if TRUE, the text will be HTML encoded */ -/proc/priority_announce(text, title = "", sound, type, sender_override, has_important_message = FALSE, list/mob/players = GLOB.player_list, encode_title = TRUE, encode_text = TRUE, color_override) +/proc/priority_announce(text, title = "", sound, type, sender_override, has_important_message = FALSE, list/mob/players = GLOB.player_list, encode_title = TRUE, encode_text = TRUE, color_override, append_update = TRUE) if(!text) return @@ -74,7 +74,7 @@ header = MAJOR_ANNOUNCEMENT_TITLE("Station Announcement by [sender.name] (AI)") // MONKESTATION ADDITION END else - header += generate_unique_announcement_header(title, sender_override) + header += generate_unique_announcement_header(title, sender_override, append_update) // Monkestation edit - update append announcement_strings += ANNOUNCEMENT_HEADER(header) @@ -96,9 +96,9 @@ if(length(title) > 0) GLOB.news_network.submit_article(title + "

" + text, "[command_name()]", "Station Announcements", null) else - GLOB.news_network.submit_article(text, "[command_name()] Update", "Station Announcements", null) + GLOB.news_network.submit_article(text, "[command_name()][append_update ? " Update" : ""]", "Station Announcements", null) -/proc/print_command_report(text = "", title = null, announce=TRUE) +/proc/print_command_report(text = "", title = null, announce = TRUE, sanitize = TRUE) // monkestation edit - sanitization if(!title) title = "Classified [command_name()] Update" @@ -114,7 +114,7 @@ message.title = title message.content = text - SScommunications.send_message(message) + SScommunications.send_message(message, sanitize)// monkestation edit - sanitization /** * Sends a minor annoucement to players. @@ -179,10 +179,10 @@ /// Proc that just generates a custom header based on variables fed into `priority_announce()` /// Will return a string. -/proc/generate_unique_announcement_header(title, sender_override) +/proc/generate_unique_announcement_header(title, sender_override, append_update = TRUE) var/list/returnable_strings = list() if(isnull(sender_override)) - returnable_strings += MAJOR_ANNOUNCEMENT_TITLE("[command_name()] Update") + returnable_strings += MAJOR_ANNOUNCEMENT_TITLE("[command_name()][append_update ? " Update" : ""]") else returnable_strings += MAJOR_ANNOUNCEMENT_TITLE(sender_override) diff --git a/code/controllers/subsystem/communications.dm b/code/controllers/subsystem/communications.dm index 35f9a6ac4fc6..cb5ec1a29f3d 100644 --- a/code/controllers/subsystem/communications.dm +++ b/code/controllers/subsystem/communications.dm @@ -47,7 +47,7 @@ SUBSYSTEM_DEF(communications) user.log_talk(input, LOG_SAY, tag="priority announcement") message_admins("[ADMIN_LOOKUPFLW(user)] has made a priority announcement.") -/datum/controller/subsystem/communications/proc/send_message(datum/comm_message/sending,print = TRUE,unique = FALSE) +/datum/controller/subsystem/communications/proc/send_message(datum/comm_message/sending, print = TRUE, unique = FALSE, sanitize = TRUE) // monkestation edit - sanitization for(var/obj/machinery/computer/communications/C in GLOB.shuttle_caller_list) if(!(C.machine_stat & (BROKEN|NOPOWER)) && is_station_level(C.z)) if(unique) @@ -58,7 +58,7 @@ SUBSYSTEM_DEF(communications) if(print) var/obj/item/paper/printed_paper = new /obj/item/paper(C.loc) printed_paper.name = "paper - '[sending.title]'" - printed_paper.add_raw_text(sending.content) + printed_paper.add_raw_text(sending.content, advanced_html = !sanitize) // monkestation edit - sanitization printed_paper.update_appearance() #undef COMMUNICATION_COOLDOWN diff --git a/code/modules/admin/verbs/commandreport.dm b/code/modules/admin/verbs/commandreport.dm index e35499c82c12..bc3122ef5247 100644 --- a/code/modules/admin/verbs/commandreport.dm +++ b/code/modules/admin/verbs/commandreport.dm @@ -1,6 +1,3 @@ -/// The default command report announcement sound. -#define DEFAULT_ANNOUNCEMENT_SOUND "default_announcement" - /// Preset central command names to chose from for centcom reports. #define CENTCOM_PRESET "Central Command" #define SYNDICATE_PRESET "The Syndicate" @@ -49,7 +46,7 @@ /// Whether a copy of the report is printed at every console. var/print_report = TRUE /// The sound that's going to accompany our message. - var/played_sound = DEFAULT_ANNOUNCEMENT_SOUND + var/played_sound = DEFAULT_COMMANDREPORT_SOUND /// The colour of the announcement when sent var/announcement_color = "default" /// The subheader to include when sending the announcement. Keep blank to not include a subheader @@ -91,7 +88,7 @@ /datum/command_report_menu/ui_static_data(mob/user) var/list/data = list() data["command_name_presets"] = preset_names - data["announcer_sounds"] = list(DEFAULT_ANNOUNCEMENT_SOUND) + GLOB.announcer_keys + data["announcer_sounds"] = list(DEFAULT_COMMANDREPORT_SOUND, DEFAULT_ALERT_SOUND, CUSTOM_ALERT_SOUND) + GLOB.announcer_keys // Monkestation edit - custom alert sounds data["announcement_colors"] = ANNOUNCEMENT_COLORS return data @@ -110,7 +107,19 @@ command_name = params["updated_name"] if("set_report_sound") - played_sound = params["picked_sound"] + // monkestation start + if (params["picked_sound"] == CUSTOM_ALERT_SOUND) + var/soundInput = input(ui_user, "Please pick a sound file to play when you create the command report.", "Pick a Sound File") as null|sound + if (isnull(soundInput)) + to_chat(ui_user, span_danger("No file was selected.")) + custom_played_sound = null + played_sound = DEFAULT_ALERT_SOUND + else + custom_played_sound = soundInput + played_sound = CUSTOM_ALERT_SOUND + else + played_sound = params["picked_sound"] + //monkestation end if("toggle_announce") announce_contents = !announce_contents if("toggle_printing") @@ -130,7 +139,8 @@ to_chat(ui_user, span_danger("You can't send a report with no contents.")) return command_report_content = params["report"] - send_announcement() + var/is_preview = params["preview"] //monkestation edit - report previewing + send_announcement(is_preview) //monkestation edit - report previewing return TRUE @@ -139,15 +149,28 @@ * * Uses the variables set by the user on our datum as the arguments for the report. */ -/datum/command_report_menu/proc/send_announcement() +/datum/command_report_menu/proc/send_announcement(preview = FALSE) /// Our current command name to swap back to after sending the report. var/original_command_name = command_name() change_command_name(command_name) /// The sound we're going to play on report. var/report_sound = played_sound - if(played_sound == DEFAULT_ANNOUNCEMENT_SOUND) - report_sound = SSstation.announcer.get_rand_report_sound() + // monkestation edit start - Custom alert sounds + switch(played_sound) + if (DEFAULT_COMMANDREPORT_SOUND) + report_sound = SSstation.announcer.get_rand_report_sound() + if (DEFAULT_ALERT_SOUND) + report_sound = SSstation.announcer.get_rand_alert_sound() + if (CUSTOM_ALERT_SOUND) + if (!isnull(custom_played_sound)) + report_sound = custom_played_sound + else + to_chat(ui_user, span_danger("The custom sound you selected was not able to be played. Aborting...")) + played_sound = DEFAULT_ALERT_SOUND + change_command_name(original_command_name) + return + // monkestation end if(announce_contents) var/chosen_color = announcement_color @@ -156,18 +179,23 @@ chosen_color = "red" else if(command_name == WIZARD_PRESET) chosen_color = "purple" - priority_announce(command_report_content, subheader == ""? null : subheader, report_sound, has_important_message = TRUE, color_override = chosen_color) + // monkestation edit start - preview reports, togglable update append + if (preview) + to_chat(ui_user, "The following is a preview of what the command report will look like for other players.") + priority_announce(command_report_content, subheader == ""? null : subheader, report_sound, has_important_message = TRUE, color_override = chosen_color, append_update = append_update_name, encode_title = sanitize_content, encode_text = sanitize_content, players = list(ui_user)) + else + priority_announce(command_report_content, subheader == ""? null : subheader, report_sound, has_important_message = TRUE, color_override = chosen_color, append_update = append_update_name, encode_title = sanitize_content, encode_text = sanitize_content) + // monkestation edit end - if(!announce_contents || print_report) - print_command_report(command_report_content, "[announce_contents ? "" : "Classified "][command_name] Update", !announce_contents) + if(!preview && (!announce_contents || print_report)) + print_command_report(command_report_content, "[announce_contents ? "" : "Classified "][command_name] Update", !announce_contents, sanitize = sanitize_content) change_command_name(original_command_name) - log_admin("[key_name(ui_user)] has created a command report: \"[command_report_content]\", sent from \"[command_name]\" with the sound \"[played_sound]\".") - message_admins("[key_name_admin(ui_user)] has created a command report, sent from \"[command_name]\" with the sound \"[played_sound]\"") - + if (!preview) // monkestation edit - preview reports + log_admin("[key_name(ui_user)] has created a command report: \"[command_report_content]\", sent from \"[command_name]\" with the sound \"[played_sound]\".") + message_admins("[key_name_admin(ui_user)] has created a command report, sent from \"[command_name]\" with the sound \"[played_sound]\"") -#undef DEFAULT_ANNOUNCEMENT_SOUND #undef CENTCOM_PRESET #undef SYNDICATE_PRESET diff --git a/monkestation/code/modules/admin/verbs/commandreport.dm b/monkestation/code/modules/admin/verbs/commandreport.dm new file mode 100644 index 000000000000..cab470114396 --- /dev/null +++ b/monkestation/code/modules/admin/verbs/commandreport.dm @@ -0,0 +1,46 @@ +/datum/command_report_menu + var/append_update_name = TRUE + var/sanitize_content = TRUE + var/custom_played_sound + +/datum/command_report_menu/ui_data(mob/user) + . = ..() + .["append_update_name"] = append_update_name + .["sanitize_content"] = sanitize_content + +/datum/command_report_menu/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) + switch(action) + if("toggle_update_append") + append_update_name = !append_update_name + if("toggle_sanitization") + sanitize_content = !sanitize_content + if("preview_sound") + preview_sound() + if("preview_paper_report") + preview_paper_report(params["report"]) + + . = ..() + +/datum/command_report_menu/proc/preview_paper_report(report) + var/obj/item/paper/report_paper = new /obj/item/paper(null) + report_paper.name = "paper - '[announce_contents ? "" : "Classified "][command_name] Update'" + report_paper.add_raw_text(report, advanced_html = !sanitize_content) + report_paper.ui_interact(ui_user) + +/datum/command_report_menu/proc/preview_sound() + var/volume_pref = ui_user.client.prefs.channel_volume["[CHANNEL_VOX]"] + switch(played_sound) + if(DEFAULT_COMMANDREPORT_SOUND) + SEND_SOUND(ui_user, sound(SSstation.announcer.get_rand_report_sound(), volume = volume_pref)) + if(DEFAULT_ALERT_SOUND) + SEND_SOUND(ui_user, sound(SSstation.announcer.get_rand_alert_sound(), volume = volume_pref)) + if(CUSTOM_ALERT_SOUND) + if (isnull(custom_played_sound)) + to_chat(ui_user, span_danger("There's no custom alert loaded! Cannot preview.")) + return + SEND_SOUND(ui_user, sound(custom_played_sound, volume = volume_pref)) + else + if(SSstation.announcer.event_sounds[played_sound]) + SEND_SOUND(ui_user, sound(SSstation.announcer.event_sounds[played_sound], volume = volume_pref)) + else + to_chat(ui_user, span_danger("No announcer sound available for [played_sound]")) diff --git a/tgstation.dme b/tgstation.dme index 5d8664095565..605cc4d636e9 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -6254,6 +6254,7 @@ #include "monkestation\code\modules\admin\smites\smite.dm" #include "monkestation\code\modules\admin\smites\swisscheese.dm" #include "monkestation\code\modules\admin\smites\where_are_your_fingers.dm" +#include "monkestation\code\modules\admin\verbs\commandreport.dm" #include "monkestation\code\modules\admin\verbs\diagnostics.dm" #include "monkestation\code\modules\admin\verbs\getlogs.dm" #include "monkestation\code\modules\admin\verbs\glowshrooms.dm" diff --git a/tgui/packages/tgui/interfaces/CommandReport.tsx b/tgui/packages/tgui/interfaces/CommandReport.tsx index 3ca782b0585c..990ae00ab3d3 100644 --- a/tgui/packages/tgui/interfaces/CommandReport.tsx +++ b/tgui/packages/tgui/interfaces/CommandReport.tsx @@ -1,8 +1,10 @@ +import { BooleanLike } from 'common/react'; import { useBackend, useLocalState } from '../backend'; import { Box, Button, Dropdown, + Flex, Input, Section, Stack, @@ -16,12 +18,14 @@ type Data = { command_name: string; command_name_presets: string[]; command_report_content: string; + sanitize_content: BooleanLike; announcement_color: string; announcement_colors: string[]; subheader: string; custom_name: string; played_sound: string; print_report: string; + append_update_name: BooleanLike; }; export const CommandReport = () => { @@ -29,7 +33,7 @@ export const CommandReport = () => { @@ -54,7 +58,12 @@ export const CommandReport = () => { /** Allows the user to set the "sender" of the message via dropdown */ const CentComName = (props) => { const { act, data } = useBackend(); - const { command_name, command_name_presets = [], custom_name } = data; + const { + command_name, + command_name_presets = [], + custom_name, + append_update_name, + } = data; return (
@@ -81,6 +90,12 @@ const CentComName = (props) => { } /> )} + act('toggle_update_append')} + />
); }; @@ -134,18 +149,38 @@ const AnnouncementSound = (props) => { const { act, data } = useBackend(); const { announcer_sounds = [], played_sound } = data; + // We have to do a shitty style hack below because applying props to doesn't apply it to the root element, and in order for it to have a full width, we have to do this, and this is the only way I could figure it out. return (
- - act('set_report_sound', { - picked_sound: value, - }) - } - /> + + +
); }; @@ -153,14 +188,34 @@ const AnnouncementSound = (props) => { /** Creates the report textarea with a submit button. */ const ReportText = (props) => { const { act, data } = useBackend(); - const { announce_contents, print_report, command_report_content } = data; + const { + announce_contents, + print_report, + command_report_content, + sanitize_content, + } = data; const [commandReport, setCommandReport] = useLocalState( 'textArea', command_report_content, ); return ( -
+
act('toggle_sanitization')} + tooltip={ + "Whether or not to sanitize the contents. Disabling this means you can use custom HTML in your reports. Be careful though, you don't want to get ridiculed for an embed fail :) " + } + > + Sanitize + + } + >