diff --git a/code/__DEFINES/__game.dm b/code/__DEFINES/__game.dm
index f1424f5560ec..765603df629c 100644
--- a/code/__DEFINES/__game.dm
+++ b/code/__DEFINES/__game.dm
@@ -103,7 +103,7 @@ block( \
#define SOUND_MIDI (1<<1)
#define SOUND_AMBIENCE (1<<2)
#define SOUND_LOBBY (1<<3)
-#define SOUND_INTERNET (1<<4)
+#define SOUND_INTERNET (1<<4) // Unused currently. Kept for default prefs compat only
#define SOUND_REBOOT (1<<5)
#define SOUND_ADMIN_MEME (1<<6)
#define SOUND_ADMIN_ATMOSPHERIC (1<<7)
diff --git a/code/__DEFINES/sounds.dm b/code/__DEFINES/sounds.dm
index a6bb381100e7..541d95d28189 100644
--- a/code/__DEFINES/sounds.dm
+++ b/code/__DEFINES/sounds.dm
@@ -27,7 +27,7 @@
#define SOUND_CHANNEL_AMBIENCE 1019
#define SOUND_CHANNEL_WALKMAN 1020
#define SOUND_CHANNEL_SOUNDSCAPE 1021
-#define SOUND_CHANNEL_ADMIN_MIDI 1022
+//#define SOUND_CHANNEL_ADMIN_MIDI 1022
#define SOUND_CHANNEL_LOBBY 1023
#define SOUND_CHANNEL_Z 1024
diff --git a/code/datums/soundOutput.dm b/code/datums/soundOutput.dm
index bc5ffd8efcfb..1f4512b28d59 100644
--- a/code/datums/soundOutput.dm
+++ b/code/datums/soundOutput.dm
@@ -152,11 +152,6 @@
adjust_volume_prefs(VOLUME_AMB, "Set the volume for ambience and soundscapes", 0)
soundOutput.update_ambience(null, null, TRUE)
-/client/verb/adjust_volume_admin_music()
- set name = "Adjust Volume Admin MIDIs"
- set category = "Preferences.Sound"
- adjust_volume_prefs(VOLUME_ADM, "Set the volume for admin MIDIs", SOUND_CHANNEL_ADMIN_MIDI)
-
/client/verb/adjust_volume_lobby_music()
set name = "Adjust Volume LobbyMusic"
set category = "Preferences.Sound"
diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm
index 7d9127313094..33b09a941a7b 100644
--- a/code/modules/admin/admin_verbs.dm
+++ b/code/modules/admin/admin_verbs.dm
@@ -99,10 +99,8 @@ var/list/admin_verbs_ban = list(
)
var/list/admin_verbs_sounds = list(
- /client/proc/play_web_sound,
- /client/proc/play_sound,
- /client/proc/stop_web_sound,
- /client/proc/stop_sound,
+ /client/proc/play_admin_sound,
+ /client/proc/stop_admin_sound,
/client/proc/cmd_admin_vox_panel
)
diff --git a/code/modules/admin/verbs/playsound.dm b/code/modules/admin/verbs/playsound.dm
index 9d622fce501b..0763a0e10795 100644
--- a/code/modules/admin/verbs/playsound.dm
+++ b/code/modules/admin/verbs/playsound.dm
@@ -1,45 +1,83 @@
-/client/proc/play_web_sound()
+/client/proc/play_admin_sound()
set category = "Admin.Fun"
- set name = "Play Internet Sound"
+ set name = "Play Admin Sound"
if(!check_rights(R_SOUNDS))
return
- var/ytdl = CONFIG_GET(string/invoke_youtubedl)
- if(!ytdl)
- to_chat(src, SPAN_BOLDWARNING("Youtube-dl was not configured, action unavailable"), confidential = TRUE) //Check config.txt for the INVOKE_YOUTUBEDL value
+ var/sound_mode = tgui_input_list(src, "Play a sound from which source?", "Select Source", list("Web", "Upload"))
+ if(!sound_mode)
return
- var/web_sound_input = input("Enter content URL (supported sites only)", "Play Internet Sound via youtube-dl") as text|null
- if(!istext(web_sound_input) || !length(web_sound_input))
- return
+ var/list/data = list()
+ var/log_title = TRUE
+ var/web_sound_input
+ var/asset_name
+ var/must_send_assets = FALSE
+ var/announce_title = TRUE
+
+ if(sound_mode == "Web")
+ var/ytdl = CONFIG_GET(string/invoke_youtubedl)
+ if(!ytdl)
+ to_chat(src, SPAN_BOLDWARNING("Youtube-dl was not configured, action unavailable"), confidential = TRUE) //Check config.txt for the INVOKE_YOUTUBEDL value
+ return
- web_sound_input = trim(web_sound_input)
+ web_sound_input = input("Enter content URL (supported sites only)", "Play Internet Sound via youtube-dl") as text|null
+ if(!istext(web_sound_input) || !length(web_sound_input))
+ return
- if(findtext(web_sound_input, ":") && !findtext(web_sound_input, GLOB.is_http_protocol))
- to_chat(src, SPAN_WARNING("Non-http(s) URIs are not allowed."))
- to_chat(src, SPAN_WARNING("For youtube-dl shortcuts like ytsearch: please use the appropriate full url from the website."))
- return
+ web_sound_input = trim(web_sound_input)
- var/web_sound_url = ""
- var/list/music_extra_data = list()
- var/title
+ if(findtext(web_sound_input, ":") && !findtext(web_sound_input, GLOB.is_http_protocol))
+ to_chat(src, SPAN_WARNING("Non-http(s) URIs are not allowed."))
+ to_chat(src, SPAN_WARNING("For youtube-dl shortcuts like ytsearch: please use the appropriate full url from the website."))
+ return
- var/list/output = world.shelleo("[ytdl] --geo-bypass --format \"bestaudio\[ext=mp3]/best\[ext=mp4]\[height<=360]/bestaudio\[ext=m4a]/bestaudio\[ext=aac]\" --dump-single-json --no-playlist -- \"[shell_url_scrub(web_sound_input)]\"")
- var/errorlevel = output[SHELLEO_ERRORLEVEL]
- var/stdout = output[SHELLEO_STDOUT]
- var/stderr = output[SHELLEO_STDERR]
+ var/list/output = world.shelleo("[ytdl] --geo-bypass --format \"bestaudio\[ext=mp3]/best\[ext=mp4]\[height<=360]/bestaudio\[ext=m4a]/bestaudio\[ext=aac]\" --dump-single-json --no-playlist -- \"[shell_url_scrub(web_sound_input)]\"")
+ var/errorlevel = output[SHELLEO_ERRORLEVEL]
+ var/stdout = output[SHELLEO_STDOUT]
+ var/stderr = output[SHELLEO_STDERR]
- if(errorlevel)
- to_chat(src, SPAN_WARNING("Youtube-dl URL retrieval FAILED: [stderr]"))
- return
+ if(errorlevel)
+ to_chat(src, SPAN_WARNING("Youtube-dl URL retrieval FAILED: [stderr]"))
+ return
- var/list/data = list()
- try
- data = json_decode(stdout)
- catch(var/exception/e)
- to_chat(src, SPAN_WARNING("Youtube-dl JSON parsing FAILED: [e]: [stdout]"))
- return
+ try
+ data = json_decode(stdout)
+ catch(var/exception/e)
+ to_chat(src, SPAN_WARNING("Youtube-dl JSON parsing FAILED: [e]: [stdout]"))
+ return
+
+ else if(sound_mode == "Upload")
+ var/current_transport = CONFIG_GET(string/asset_transport)
+ if(!current_transport || current_transport == "simple")
+ if(tgui_alert(usr, "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(usr, "Choose a sound 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))
+ to_chat(src, SPAN_WARNING("Invalid filename extension."))
+ return
+
+ var/static/playsound_notch = 1
+ asset_name = "admin_sound_[playsound_notch++].[extension]"
+ SSassets.transport.register_asset(asset_name, soundfile)
+ 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["url"] = SSassets.transport.get_asset_url(asset_name)
+ web_sound_input = "[soundfile]"
+ log_title = FALSE
+ var/title
+ var/web_sound_url = ""
+ var/list/music_extra_data = list()
if(data["url"])
music_extra_data["link"] = data["url"]
music_extra_data["title"] = data["title"]
@@ -48,19 +86,28 @@
music_extra_data["start"] = data["start_time"]
music_extra_data["end"] = data["end_time"]
- if(web_sound_url && !findtext(web_sound_url, GLOB.is_http_protocol))
+ if(!must_send_assets && web_sound_url && !findtext(web_sound_url, GLOB.is_http_protocol))
to_chat(src, SPAN_BOLDWARNING("BLOCKED: Content URL not using http(s) protocol"), confidential = TRUE)
to_chat(src, SPAN_WARNING("The media provider returned a content URL that isn't using the HTTP or HTTPS protocol"), confidential = TRUE)
return
+ switch(tgui_alert(src, "Show the name of this sound to the players?", "Sound Name", list("Yes","No","Cancel")))
+ if("No")
+ music_extra_data["title"] = "Admin sound"
+ announce_title = FALSE
+ if("Cancel")
+ return
+
var/list/targets = list()
var/list/sound_type_list = list(
"Meme" = SOUND_ADMIN_MEME,
"Atmospheric" = SOUND_ADMIN_ATMOSPHERIC
)
- var/style = tgui_input_list(src, "Who do you want to play this to?", "Select Listeners", list("Globally", "Xenos", "Marines", "Ghosts", "All Inview", "Single Inview"))
+
+ var/style = tgui_input_list(src, "Who do you want to play this to?", "Select Listeners", list("Globally", "Xenos", "Marines", "Ghosts", "All In View Range", "Single Mob"))
var/sound_type = tgui_input_list(src, "What kind of sound is this?", "Select Sound Type", sound_type_list)
sound_type = sound_type_list[sound_type]
+
switch(style)
if("Globally")
targets = GLOB.mob_list
@@ -70,30 +117,40 @@
targets = GLOB.human_mob_list + GLOB.dead_mob_list
if("Ghosts")
targets = GLOB.observer_list + GLOB.dead_mob_list
- if("All Inview")
- targets = viewers(usr.client.view, src)
- if("Single Inview")
- var/mob/choice = tgui_input_list(src, "Select the mob to play to:","Select Mob", sortmobs())
+ if("All In View Range")
+ var/list/atom/ranged_atoms = urange(usr.client.view, get_turf(usr))
+ for(var/mob/receiver in ranged_atoms)
+ targets += receiver
+ if("Single Mob")
+ var/list/mob/all_mobs = sortmobs()
+ var/list/mob/all_client_mobs = list()
+ for(var/mob/mob in all_mobs)
+ if(mob.client)
+ all_client_mobs += mob
+ var/mob/choice = tgui_input_list(src, "Select the mob to play to:","Select Mob", all_client_mobs)
if(QDELETED(choice))
return
targets.Add(choice)
else
return
- for(var/i in targets)
- var/mob/M = i
- var/client/client = M?.client
- if((client?.prefs.toggles_sound & SOUND_INTERNET) && (client?.prefs.toggles_sound & sound_type))
+ for(var/mob/mob as anything in targets)
+ var/client/client = mob?.client
+ if((client?.prefs?.toggles_sound & SOUND_MIDI) && (client?.prefs?.toggles_sound & sound_type))
+ if(must_send_assets)
+ SSassets.transport.send_assets(client, asset_name)
client?.tgui_panel?.play_music(web_sound_url, music_extra_data)
+ if(announce_title)
+ to_chat(client, SPAN_BOLDANNOUNCE("An admin played: [music_extra_data["title"]]"), confidential = TRUE)
else
client?.tgui_panel?.stop_music()
- log_admin("[key_name(src)] played web sound: [web_sound_input] - [title] - [style]")
- message_admins("[key_name_admin(src)] played web sound: [web_sound_input] - [title] - [style]")
+ log_admin("[key_name(src)] played admin sound: [web_sound_input] -[log_title ? " [title] -" : ""] [style]")
+ message_admins("[key_name_admin(src)] played admin sound: [web_sound_input] -[log_title ? " [title] -" : ""] [style]")
-/client/proc/stop_web_sound()
+/client/proc/stop_admin_sound()
set category = "Admin.Fun"
- set name = "Stop Internet Sounds"
+ set name = "Stop Admin Sounds"
if(!check_rights(R_SOUNDS))
return
@@ -105,86 +162,3 @@
log_admin("[key_name(src)] stopped the currently playing web sounds.")
message_admins("[key_name_admin(src)] stopped the currently playing web sounds.")
-/client/proc/play_sound(S as sound)
- set category = "Admin.Fun"
- set name = "Play Midi Sound"
- if(!check_rights(R_SOUNDS))
- return
-
- var/freq = 1
- var/vol = tgui_input_number(src, "What volume would you like the sound to play at?", "Volume", 25, 100, 1)
- if(!vol)
- return
- vol = clamp(vol, 1, 100)
-
- var/sound/admin_sound = new()
- admin_sound.file = S
- admin_sound.priority = 250
- admin_sound.channel = SOUND_CHANNEL_ADMIN_MIDI
- admin_sound.frequency = freq
- admin_sound.wait = 1
- admin_sound.repeat = FALSE
- admin_sound.status = SOUND_STREAM
- admin_sound.volume = vol
-
- var/showtitle = FALSE
- var/res = alert(src, "Show the title of this song to the players?",, "Yes","No", "Cancel")
- switch(res)
- if("Yes")
- showtitle = TRUE
- if("Cancel")
- return
-
- var/list/targets = list()
- var/list/sound_type_list = list(
- "Meme" = SOUND_ADMIN_MEME,
- "Atmospheric" = SOUND_ADMIN_ATMOSPHERIC
- )
- var/style = tgui_input_list(src, "Who do you want to play this to?", "Select Listeners", list("Globally", "Xenos", "Marines", "Ghosts", "All Inview", "Single Inview"))
- var/sound_type = tgui_input_list(src, "What kind of sound is this?", "Select Sound Type", sound_type_list)
- sound_type = sound_type_list[sound_type]
- switch(style)
- if("Globally")
- targets = GLOB.mob_list
- if("Xenos")
- targets = GLOB.xeno_mob_list + GLOB.dead_mob_list
- if("Marines")
- targets = GLOB.human_mob_list + GLOB.dead_mob_list
- if("Ghosts")
- targets = GLOB.observer_list + GLOB.dead_mob_list
- if("All Inview")
- targets = viewers(usr.client.view, src)
- if("Single Inview")
- var/mob/choice = tgui_input_list(src, "Select the mob to play to:","Select Mob", sortmobs())
- if(QDELETED(choice))
- return
- targets.Add(choice)
- else
- return
-
- for(var/items in targets)
- var/mob/Mob = items
- var/client/client = Mob?.client
- if((client?.prefs.toggles_sound & SOUND_INTERNET) && (client?.prefs.toggles_sound & sound_type))
- admin_sound.volume = vol * client?.admin_music_volume
- SEND_SOUND(Mob, admin_sound)
- admin_sound.volume = vol
- if(showtitle)
- to_chat(client, SPAN_BOLDANNOUNCE("An admin played: [S]"), confidential = TRUE)
-
- log_admin("[key_name(src)] played midi sound [S] - [style]")
- message_admins("[key_name_admin(src)] played midi sound [S] - [style]")
-
-/client/proc/stop_sound()
- set category = "Admin.Fun"
- set name = "Stop Midi Sounds"
-
- if(!check_rights(R_SOUNDS))
- return
-
- for(var/mob/M in GLOB.player_list)
- if(M.client)
- SEND_SOUND(M, sound(null))
-
- log_admin("[key_name(src)] stopped midi sounds.")
- message_admins("[key_name_admin(src)] stopped midi sounds.")
diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm
index 04b82628e3c6..ad12cb99b50e 100644
--- a/code/modules/client/preferences.dm
+++ b/code/modules/client/preferences.dm
@@ -586,8 +586,7 @@ var/const/MAX_SAVE_SLOTS = 10
dat += "Tooltips: [tooltips ? "Enabled" : "Disabled"]
"
dat += "tgui Window Mode: [(tgui_fancy) ? "Fancy (default)" : "Compatible (slower)"]
"
dat += "tgui Window Placement: [(tgui_lock) ? "Primary monitor" : "Free (default)"]
"
- dat += "Play Admin Midis: [(toggles_sound & SOUND_MIDI) ? "Yes" : "No"]
"
- dat += "Play Admin Internet Sounds: [(toggles_sound & SOUND_INTERNET) ? "Yes" : "No"]
"
+ dat += "Play Admin Sounds: [(toggles_sound & SOUND_MIDI) ? "Yes" : "No"]
"
dat += "Toggle Meme or Atmospheric Sounds: Toggle
"
dat += "Set Eye Blur Type: Set
"
dat += "Play Lobby Music: [(toggles_sound & SOUND_LOBBY) ? "Yes" : "No"]
"
@@ -1807,11 +1806,10 @@ var/const/MAX_SAVE_SLOTS = 10
if("rand_body")
be_random_body = !be_random_body
- if("hear_midis")
+ if("hear_admin_sounds")
toggles_sound ^= SOUND_MIDI
-
- if("hear_internet")
- toggles_sound ^= SOUND_INTERNET
+ if(!(toggles_sound & SOUND_MIDI))
+ user?.client?.tgui_panel?.stop_music()
if("lobby_music")
toggles_sound ^= SOUND_LOBBY
diff --git a/code/modules/client/preferences_toggles.dm b/code/modules/client/preferences_toggles.dm
index 6f9026a437dd..080f071823f8 100644
--- a/code/modules/client/preferences_toggles.dm
+++ b/code/modules/client/preferences_toggles.dm
@@ -48,25 +48,10 @@
to_chat(src, "You will [(prefs.toggles_sound & SOUND_REBOOT) ? "now" : "no longer"] hear server reboot sounds.")
/client/verb/togglemidis()
- set name = "Silence Current Midi"
+ set name = "Silence Current Admin Sound"
set category = "Preferences.Sound"
- set desc = "Toggles hearing sounds uploaded by admins"
- // prefs.toggles_sound ^= SOUND_MIDI // Toggle on/off
- // prefs.save_preferences() // We won't save the change - it'll be a temporary switch instead of permanent, but they can still make it permanent in character setup.
- if(prefs.toggles_sound & SOUND_MIDI) // Not using && midi_playing here - since we can't tell how long an admin midi is, the user should always be able to turn it off at any time.
- to_chat(src, SPAN_BOLDNOTICE("The currently playing midi has been silenced."))
- var/sound/break_sound = sound(null, repeat = 0, wait = 0, channel = SOUND_CHANNEL_ADMIN_MIDI)
- break_sound.priority = 250
- src << break_sound //breaks the client's sound output on SOUND_CHANNEL_ADMIN_MIDI
- if(src.mob.client.midi_silenced) return
- if(midi_playing)
- total_silenced++
- message_admins("A player has silenced the currently playing midi. Total: [total_silenced] player(s).", 1)
- src.mob.client.midi_silenced = 1
- spawn(30 SECONDS) // Prevents message_admins() spam. Should match with the midi_playing_timer spawn() in playsound.dm
- src.mob.client.midi_silenced = 0
- else
- to_chat(src, SPAN_BOLDNOTICE("You have 'Play Admin Midis' disabled in your Character Setup, so this verb is useless to you."))
+ set desc = "Stops the current admin sound. You can also use the STOP icon in the player above tgchat."
+ tgui_panel?.stop_music()
/client/verb/togglechat()
set name = "Toggle Abovehead Chat"
diff --git a/code/modules/tgui_panel/audio.dm b/code/modules/tgui_panel/audio.dm
index 680696159943..d66421df5348 100644
--- a/code/modules/tgui_panel/audio.dm
+++ b/code/modules/tgui_panel/audio.dm
@@ -3,8 +3,6 @@
* SPDX-License-Identifier: MIT
*/
-/// Admin music volume, from 0 to 1.
-/client/var/admin_music_volume = 1
/**
* public
@@ -22,8 +20,9 @@
/datum/tgui_panel/proc/play_music(url, extra_data)
if(!is_ready())
return
- if(!findtext(url, GLOB.is_http_protocol))
- return
+ // Commented to allow playing via simple asset transport. Just check when calling.
+// if(!findtext(url, GLOB.is_http_protocol))
+// return
var/list/payload = list()
if(length(extra_data) > 0)
for(var/key in extra_data)
diff --git a/code/modules/tgui_panel/tgui_panel.dm b/code/modules/tgui_panel/tgui_panel.dm
index 9fb8b02b0196..f33f190d80e0 100644
--- a/code/modules/tgui_panel/tgui_panel.dm
+++ b/code/modules/tgui_panel/tgui_panel.dm
@@ -85,9 +85,10 @@
),
))
return TRUE
- if(type == "audio/setAdminMusicVolume")
- client.admin_music_volume = payload["volume"]
- return TRUE
+// Deprecated due to removal of old sound play commands
+// if(type == "audio/setAdminMusicVolume")
+// client.admin_music_volume = payload["volume"]
+// return TRUE
if(type == "telemetry")
analyze_telemetry(payload)
return TRUE
diff --git a/tgui/packages/tgui-panel/settings/reducer.js b/tgui/packages/tgui-panel/settings/reducer.js
index 42d799fd6597..0c93a5b94d4e 100644
--- a/tgui/packages/tgui-panel/settings/reducer.js
+++ b/tgui/packages/tgui-panel/settings/reducer.js
@@ -16,7 +16,7 @@ const initialState = {
fontFamily: FONTS[0],
lineHeight: 1.2,
theme: 'light',
- adminMusicVolume: 0.5,
+ adminMusicVolume: 0.2,
// Keep these two state vars for compatibility with other servers
highlightText: '',
highlightColor: '#ffdd44',