diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 052e298b7a0..928045eba68 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -85,7 +85,7 @@ GLOBAL_LIST_INIT(admin_verbs_sounds, list( /client/proc/play_intercomm_sound, /client/proc/stop_global_admin_sounds, /client/proc/stop_sounds_global, - /client/proc/play_web_sound + /client/proc/play_sound_tgchat )) GLOBAL_LIST_INIT(admin_verbs_event, list( /client/proc/object_talk, diff --git a/code/modules/admin/verbs/playsound.dm b/code/modules/admin/verbs/playsound.dm index 12beb8fbe8a..bc62a9dbd9d 100644 --- a/code/modules/admin/verbs/playsound.dm +++ b/code/modules/admin/verbs/playsound.dm @@ -17,9 +17,12 @@ GLOBAL_LIST_EMPTY(sounds_cache) /client/proc/play_sound(S as sound) set category = "Event" - set name = "Play Global Sound" + set name = "Legacy Play Global Sound" if(!check_rights(R_SOUNDS)) return + if(alert("WARNING: Legacy Play Global Sound does not support CDN asset sending. Sounds will have to be sent directly to players, which may freeze the game for long durations. Are you SURE?", "Really use Legacy Play Global Sound?", "Yes", "No") == "No") + return + var/sound/uploaded_sound = sound(S, repeat = 0, wait = 1, channel = CHANNEL_ADMIN) uploaded_sound.priority = 250 @@ -130,107 +133,135 @@ GLOBAL_LIST_EMPTY(sounds_cache) var/client/C = M.client C?.tgui_panel?.stop_music() -/client/proc/play_web_sound() +/client/proc/play_sound_tgchat() set category = "Event" - set name = "Play Internet Sound" + set name = "Play Global Sound" if(!check_rights(R_SOUNDS)) return - if(!GLOB.configuration.system.ytdlp_url) - to_chat(src, "yt-dlp was not configured, action unavailable") //Check config + var/sound_mode = tgui_alert(src, "Play a sound from which source?", "Select Source", list("Web", "Upload MP3")) + if(!sound_mode) return + var/web_sound_input + var/asset_name + var/must_send_assets = FALSE + var/web_sound_url = "" + var/list/music_extra_data = list() + var/list/data = list() - var/web_sound_input = tgui_input_text(src, "Enter content URL (supported sites only, leave blank to stop playing)", "Play Internet Sound", null) - if(istext(web_sound_input)) - var/web_sound_url = "" - var/stop_web_sounds = FALSE - var/list/music_extra_data = list() - if(length(web_sound_input)) - web_sound_input = trim(web_sound_input) - if(findtext(web_sound_input, ":") && !findtext(web_sound_input, GLOB.is_http_protocol)) - to_chat(src, "Non-http(s) URIs are not allowed.") - to_chat(src, "For yt-dlp shortcuts like ytsearch: please use the appropriate full url from the website.") - return - - // Prepare the body - var/list/request_body = list("url" = web_sound_input) - // Send the request off - var/datum/http_request/media_poll_request = new() - // The fact we are using GET with a body offends me - media_poll_request.prepare(RUSTLIBS_HTTP_METHOD_GET, GLOB.configuration.system.ytdlp_url, json_encode(request_body)) - // Start it off and wait - media_poll_request.begin_async() - UNTIL(media_poll_request.is_complete()) - var/datum/http_response/media_poll_response = media_poll_request.into_response() - - if(media_poll_response.status_code == 200) - var/list/data - try - data = json_decode(media_poll_response.body) - catch(var/exception/e) - to_chat(src, "yt-dlp JSON parsing FAILED:") - to_chat(src, "[e]: [media_poll_response.body]") - return - - if(data["sound_url"]) - web_sound_url = data["sound_url"] - var/title = "[data["title"]]" - var/webpage_url = title - if(data["webpage_url"]) - webpage_url = "[title]" - music_extra_data["start"] = data["start"] - music_extra_data["end"] = data["end"] - music_extra_data["link"] = data["webpage_url"] - music_extra_data["title"] = data["title"] - - var/res = tgui_alert(src, "Show the title of and link to this song to the players?\n[title]", "Show Info?", list("Yes", "No", "Cancel")) - switch(res) - if("Yes") - log_admin("[key_name(src)] played web sound: [web_sound_input]") - message_admins("[key_name(src)] played web sound: [web_sound_input]") - to_chat(world, "[src.ckey] played: [webpage_url]") - if("No") - music_extra_data["link"] = "Song Link Hidden" - music_extra_data["title"] = "Song Title Hidden" - music_extra_data["artist"] = "Song Artist Hidden" - log_admin("[key_name(src)] played web sound: [web_sound_input]") - message_admins("[key_name(src)] played web sound: [web_sound_input]") - to_chat(world, "[src.ckey] played an internet sound") - if("Cancel") - return - - SSblackbox.record_feedback("tally", "admin_verb", 1, "Play Internet Sound") - - else - to_chat(src, "yt-dlp URL retrieval FAILED:") - to_chat(src, "[media_poll_response.body]") - - else //pressed ok with blank - log_admin("[key_name(src)] stopped web sound") - message_admins("[key_name(src)] stopped web sound") - web_sound_url = null - stop_web_sounds = TRUE - - if(web_sound_url && !findtext(web_sound_url, GLOB.is_http_protocol)) - to_chat(src, "BLOCKED: Content URL not using http(s) protocol", confidential = TRUE) - to_chat(src, "The media provider returned a content URL that isn't using the HTTP or HTTPS protocol", confidential = TRUE) + if(sound_mode == "Web") + if(!GLOB.configuration.system.ytdlp_url) + to_chat(src, "yt-dlp was not configured, action unavailable") //Check config return - if(web_sound_url || stop_web_sounds) - for(var/mob/M in GLOB.player_list) - var/client/C = M.client - var/this_uid = M.client.UID() - if(stop_web_sounds) - C.tgui_panel?.stop_music() + web_sound_input = tgui_input_text(src, "Enter content URL", "Play Internet Sound", null) + if(!length(web_sound_input)) + return + + web_sound_input = trim(web_sound_input) + + if(findtext(web_sound_input, ":") && !findtext(web_sound_input, GLOB.is_http_protocol)) + to_chat(src, "Non-http(s) URIs are not allowed.") + to_chat(src, "For yt-dlp shortcuts like ytsearch: please use the appropriate full url from the website.") + return + + // Prepare the body + var/list/request_body = list("url" = web_sound_input) + // Send the request off + var/datum/http_request/media_poll_request = new() + // The fact we are using GET with a body offends me + media_poll_request.prepare(RUSTLIBS_HTTP_METHOD_GET, GLOB.configuration.system.ytdlp_url, json_encode(request_body)) + // Start it off and wait + media_poll_request.begin_async() + UNTIL(media_poll_request.is_complete()) + var/datum/http_response/media_poll_response = media_poll_request.into_response() + + if(media_poll_response.status_code == 200) + try + data = json_decode(media_poll_response.body) + catch(var/exception/e) + to_chat(src, "yt-dlp JSON parsing FAILED:") + to_chat(src, "[e]: [media_poll_response.body]") + return + else + to_chat(src, "yt-dlp URL retrieval FAILED:") + to_chat(src, "[media_poll_response.body]") + return + + else if(sound_mode == "Upload MP3") + if(GLOB.configuration.asset_cache.asset_transport == "simple") + if(tgui_alert(src, "WARNING: Your server is using simple asset transport. Sounds will have to be sent directly to players, which may freeze the game for long durations. Are you SURE?", "Really play direct sound?", list("Yes", "No")) != "Yes") + return + must_send_assets = TRUE + + var/soundfile = input(src, "Choose an MP3 file to play", "Upload Sound") as null|file + if(!soundfile) + return + + var/static/regex/only_extension = regex(@{"^.*\.([a-z0-9]{1,5})$"}, "gi") + var/extension = only_extension.Replace("[soundfile]", "$1") + if(!length(extension) || extension != "mp3") + to_chat(src, "Invalid filename extension.") + return + + var/static/playsound_notch = 1 + asset_name = "admin_sound_[playsound_notch++].[extension]" + SSassets.transport.register_asset(asset_name, soundfile) + log_admin("[key_name_admin(src)] uploaded admin sound '[soundfile]' to asset transport.") + message_admins("[key_name_admin(src)] uploaded admin sound '[soundfile]' to asset transport.") + + var/static/regex/remove_extension = regex(@{"\.[a-z0-9]+$"}, "gi") + data["title"] = remove_extension.Replace("[soundfile]", "") + data["sound_url"] = SSassets.transport.get_asset_url(asset_name) + web_sound_input = "[soundfile]" + + if(data["sound_url"]) + web_sound_url = data["sound_url"] + var/title = "[data["title"]]" + var/webpage_url = title + if(data["webpage_url"]) + webpage_url = "[title]" + music_extra_data["start"] = data["start"] + music_extra_data["end"] = data["end"] + music_extra_data["link"] = data["webpage_url"] + music_extra_data["title"] = data["title"] + + var/res = tgui_alert(src, "Show the title of and link to this song to the players?\n[title]", "Show Info?", list("Yes", "No")) + if(!res) + return + if(res == "Yes") + log_admin("[key_name(src)] played sound: [web_sound_input]") + message_admins("[key_name(src)] played sound: [web_sound_input]") + to_chat(world, "[src.ckey] played: [webpage_url]") + else if(res == "No") + music_extra_data["link"] = "Song Link Hidden" + music_extra_data["title"] = "Song Title Hidden" + music_extra_data["artist"] = "Song Artist Hidden" + log_admin("[key_name(src)] played sound: [web_sound_input]") + message_admins("[key_name(src)] played sound: [web_sound_input]") + to_chat(world, "[src.ckey] played a sound") + + SSblackbox.record_feedback("tally", "admin_verb", 1, "Play Global Sound TGchat") + + if(!must_send_assets && web_sound_url && !findtext(web_sound_url, GLOB.is_http_protocol)) + to_chat(src, "BLOCKED: Content URL not using http(s) protocol", confidential = TRUE) + to_chat(src, "The media provider returned a content URL that isn't using the HTTP or HTTPS protocol", confidential = TRUE) + return + + if(web_sound_url) + for(var/mob/M in GLOB.player_list) + var/client/C = M.client + var/player_uid = M.client.UID() + if(C.prefs.sound & SOUND_MIDI) + if(ckey in M.client.prefs.admin_sound_ckey_ignore) + to_chat(C, "But [src.ckey] is muted locally in preferences!") continue - if(C.prefs.sound & SOUND_MIDI) - if(ckey in M.client.prefs.admin_sound_ckey_ignore) - to_chat(C, "But [src.ckey] is muted locally in preferences!") - continue - else - C.tgui_panel?.play_music(web_sound_url, music_extra_data) - to_chat(C, "(SILENCE) (ALWAYS SILENCE THIS ADMIN)") else - to_chat(C, "But Admin MIDIs are disabled in preferences!") + if(must_send_assets) + SSassets.transport.send_assets(C, asset_name) + C.tgui_panel?.play_music(web_sound_url, music_extra_data) + to_chat(C, "(SILENCE) (ALWAYS SILENCE THIS ADMIN)") + else + to_chat(C, "But Admin MIDIs are disabled in preferences!") return diff --git a/code/modules/tgui/tgui_panel/audio.dm b/code/modules/tgui/tgui_panel/audio.dm index b91dc6bd5a7..1659f336683 100644 --- a/code/modules/tgui/tgui_panel/audio.dm +++ b/code/modules/tgui/tgui_panel/audio.dm @@ -22,8 +22,6 @@ /datum/tgui_panel/proc/play_music(url, extra_data) if(!is_ready()) return - if(!findtext(url, GLOB.is_http_protocol)) - return var/list/payload = list() if(length(extra_data) > 0) for(var/key in extra_data)