mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-21 20:20:33 +01:00
Music Widget Modifications + Request Music Verb (#74170)
## About The Pull Request This PR alters the Play Internet Sound, First off it modifies the Widget To clean up some info on the widget to hide information when that information is not available to be shown. Secondly it makes the URL input prompt for Play Internet Sound to be a TGUI text input box, as well as adds in a warning if a song being played is >10 minutes long, and adds in a proc to play music with a supplied variable. Secondly This PR adds in a new player facing VERB in the OOC tab called `Request Internet Sound` functionally the verb is similar to Pray but it grants admins the ability to play URL's directly from the chat or Request Manager, where it will prompt the admin if they wish to play the song. <details> <summary>Screenshots/Videos</summary>  <details> <summary>Widget</summary>    </details> <details> <summary>New Prompts</summary>   </details> <details> <summary>Videos</summary> https://user-images.githubusercontent.com/2568378/226794939-4ca018b3-bba5-4893-9301-6858b0d433b9.mp4 https://user-images.githubusercontent.com/2568378/226794783-ca750840-3149-489c-9239-00014ac4ca5c.mp4 </details> </details> ## Why It's Good For The Game This cleans up the UI for the Play Internet Sound so that things to hide info when admins choose to hide it, or to not show it if that information exists at all. As well as grants players a ability to request music to be played via Admin Midi and sorts them with prayers and allows admins to directly play URL's simultaneously cleaning up any music requests made through prays as well as a more obvious way for people to request music rather than them Ahelping for music ## Changelog 🆑 add: New VERB, Request Internet Sound, It is in the OOC tab and allows you to request music from admins to play, by default only allows bandcamp, youtube, and soundcloud links fix: Fixes the Admin Midi Widget UI to only present info that is available to players to be seen admin: Play Internet Sound URL input is now TGUI admin: Play Internet Sound warns you if a song length is >10 Minutes admin: Added new mute type to mute internet sound requests from a player config: Added thee new config options, LOG_INTERNET_REQUEST, REQUEST_INTERNET_SOUND, REQUEST_INTERNET_ALLOWED /🆑 --------- Co-authored-by: Aleksej Komarov <stylemistake@gmail.com>
This commit is contained in:
co-authored by
Aleksej Komarov
parent
401372c088
commit
b2f6058c92
@@ -1748,3 +1748,13 @@
|
||||
if(!paper_to_show)
|
||||
return
|
||||
paper_to_show.ui_interact(usr)
|
||||
else if(href_list["play_internet"])
|
||||
if(!check_rights(R_SOUND))
|
||||
return
|
||||
|
||||
var/link_url = href_list["play_internet"]
|
||||
if(!link_url)
|
||||
return
|
||||
|
||||
web_sound(usr, link_url)
|
||||
|
||||
|
||||
@@ -208,6 +208,9 @@
|
||||
if(MUTE_DEADCHAT)
|
||||
mute_string = "deadchat and DSAY"
|
||||
feedback_string = "Deadchat"
|
||||
if(MUTE_INTERNET_REQUEST)
|
||||
mute_string = "internet sound requests"
|
||||
feedback_string = "Internet Sound Requests"
|
||||
if(MUTE_ALL)
|
||||
mute_string = "everything"
|
||||
feedback_string = "Everything"
|
||||
|
||||
@@ -84,6 +84,7 @@
|
||||
body += "<A href='?_src_=holder;[HrefToken()];mute=[M.ckey];mute_type=[MUTE_OOC]'><font color='[(muted & MUTE_OOC)?"red":"blue"]'>OOC</font></a> | "
|
||||
body += "<A href='?_src_=holder;[HrefToken()];mute=[M.ckey];mute_type=[MUTE_PRAY]'><font color='[(muted & MUTE_PRAY)?"red":"blue"]'>PRAY</font></a> | "
|
||||
body += "<A href='?_src_=holder;[HrefToken()];mute=[M.ckey];mute_type=[MUTE_ADMINHELP]'><font color='[(muted & MUTE_ADMINHELP)?"red":"blue"]'>ADMINHELP</font></a> | "
|
||||
body += "<A href='?_src_=holder;[HrefToken()];mute=[M.ckey];mute_type=[MUTE_INTERNET_REQUEST]'><font color='[(muted & MUTE_INTERNET_REQUEST)?"red":"blue"]'>WEBREQ</font></a> | "
|
||||
body += "<A href='?_src_=holder;[HrefToken()];mute=[M.ckey];mute_type=[MUTE_DEADCHAT]'><font color='[(muted & MUTE_DEADCHAT)?"red":"blue"]'>DEADCHAT</font></a>\]"
|
||||
body += "(<A href='?_src_=holder;[HrefToken()];mute=[M.ckey];mute_type=[MUTE_ALL]'><font color='[(muted & MUTE_ALL)?"red":"blue"]'>toggle all</font></a>)"
|
||||
|
||||
|
||||
@@ -70,6 +70,100 @@
|
||||
SEND_SOUND(M, S)
|
||||
SSblackbox.record_feedback("tally", "admin_verb", 1, "Play Direct Mob Sound") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
///Takes an input from either proc/play_web_sound or the request manager and runs it through youtube-dl and prompts the user before playing it to the server.
|
||||
/proc/web_sound(mob/user, input)
|
||||
if(!check_rights(R_SOUND))
|
||||
return
|
||||
var/ytdl = CONFIG_GET(string/invoke_youtubedl)
|
||||
if(!ytdl)
|
||||
to_chat(user, span_boldwarning("Youtube-dl was not configured, action unavailable"), confidential = TRUE) //Check config.txt for the INVOKE_YOUTUBEDL value
|
||||
return
|
||||
var/web_sound_url = ""
|
||||
var/stop_web_sounds = FALSE
|
||||
var/list/music_extra_data = list()
|
||||
if(istext(input))
|
||||
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 -- \"[input]\"")
|
||||
var/errorlevel = output[SHELLEO_ERRORLEVEL]
|
||||
var/stdout = output[SHELLEO_STDOUT]
|
||||
var/stderr = output[SHELLEO_STDERR]
|
||||
if(errorlevel)
|
||||
to_chat(user, span_boldwarning("Youtube-dl URL retrieval FAILED:"), confidential = TRUE)
|
||||
to_chat(user, span_warning("[stderr]"), confidential = TRUE)
|
||||
return
|
||||
var/list/data
|
||||
try
|
||||
data = json_decode(stdout)
|
||||
catch(var/exception/e)
|
||||
to_chat(user, span_boldwarning("Youtube-dl JSON parsing FAILED:"), confidential = TRUE)
|
||||
to_chat(user, span_warning("[e]: [stdout]"), confidential = TRUE)
|
||||
return
|
||||
if (data["url"])
|
||||
web_sound_url = data["url"]
|
||||
var/title = "[data["title"]]"
|
||||
var/webpage_url = title
|
||||
if (data["webpage_url"])
|
||||
webpage_url = "<a href=\"[data["webpage_url"]]\">[title]</a>"
|
||||
music_extra_data["duration"] = DisplayTimeText(data["duration"] * 1 SECONDS)
|
||||
music_extra_data["link"] = data["webpage_url"]
|
||||
music_extra_data["artist"] = data["artist"]
|
||||
music_extra_data["upload_date"] = data["upload_date"]
|
||||
music_extra_data["album"] = data["album"]
|
||||
var/duration = data["duration"] * 1 SECONDS
|
||||
if (duration > 10 MINUTES)
|
||||
if((tgui_alert(user, "This song is over 10 minutes long. Are you sure you want to play it?", "Length Warning!", list("No", "Yes", "Cancel")) != "Yes"))
|
||||
return
|
||||
var/res = tgui_alert(user, "Show the title of and link to this song to the players?\n[title]", "Show Info?", list("Yes", "No", "Cancel"))
|
||||
switch(res)
|
||||
if("Yes")
|
||||
music_extra_data["title"] = data["title"]
|
||||
if("No")
|
||||
music_extra_data["link"] = "Song Link Hidden"
|
||||
music_extra_data["title"] = "Song Title Hidden"
|
||||
music_extra_data["artist"] = "Song Artist Hidden"
|
||||
music_extra_data["upload_date"] = "Song Upload Date Hidden"
|
||||
music_extra_data["album"] = "Song Album Hidden"
|
||||
if("Cancel", null)
|
||||
return
|
||||
var/anon = tgui_alert(user, "Display who played the song?", "Credit Yourself?", list("Yes", "No", "Cancel"))
|
||||
switch(anon)
|
||||
if("Yes")
|
||||
if(res == "Yes")
|
||||
to_chat(world, span_boldannounce("[user] played: [webpage_url]"), confidential = TRUE)
|
||||
else
|
||||
to_chat(world, span_boldannounce("[user] played some music"), confidential = TRUE)
|
||||
if("No")
|
||||
if(res == "Yes")
|
||||
to_chat(world, span_boldannounce("An admin played: [webpage_url]"), confidential = TRUE)
|
||||
if("Cancel", null)
|
||||
return
|
||||
SSblackbox.record_feedback("nested tally", "played_url", 1, list("[user.ckey]", "[input]"))
|
||||
log_admin("[key_name(user)] played web sound: [input]")
|
||||
message_admins("[key_name(user)] played web sound: [input]")
|
||||
else
|
||||
//pressed ok with blank
|
||||
log_admin("[key_name(user)] stopped web sounds.")
|
||||
|
||||
message_admins("[key_name(user)] stopped web sounds.")
|
||||
web_sound_url = null
|
||||
stop_web_sounds = TRUE
|
||||
if(web_sound_url && !findtext(web_sound_url, GLOB.is_http_protocol))
|
||||
tgui_alert(user, "The media provider returned a content URL that isn't using the HTTP or HTTPS protocol. This is a security risk and the sound will not be played.", "Security Risk", list("OK"))
|
||||
to_chat(user, span_boldwarning("BLOCKED: Content URL not using HTTP(S) Protocol!"), confidential = TRUE)
|
||||
|
||||
return
|
||||
if(web_sound_url || stop_web_sounds)
|
||||
for(var/m in GLOB.player_list)
|
||||
var/mob/M = m
|
||||
var/client/C = M.client
|
||||
if(C.prefs.read_preference(/datum/preference/toggle/sound_midi))
|
||||
if(!stop_web_sounds)
|
||||
C.tgui_panel?.play_music(web_sound_url, music_extra_data)
|
||||
else
|
||||
C.tgui_panel?.stop_music()
|
||||
|
||||
SSblackbox.record_feedback("tally", "admin_verb", 1, "Play Internet Sound")
|
||||
|
||||
|
||||
/client/proc/play_web_sound()
|
||||
set category = "Admin.Fun"
|
||||
set name = "Play Internet Sound"
|
||||
@@ -81,98 +175,18 @@
|
||||
to_chat(src, span_boldwarning("Youtube-dl was not configured, action unavailable"), confidential = TRUE) //Check config.txt for the INVOKE_YOUTUBEDL value
|
||||
return
|
||||
|
||||
var/web_sound_input = input("Enter content URL (supported sites only, leave blank to stop playing)", "Play Internet Sound via youtube-dl") as text|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))
|
||||
var/web_sound_input = tgui_input_text(usr, "Enter content URL (supported sites only, leave blank to stop playing)", "Play Internet Sound", null)
|
||||
|
||||
web_sound_input = trim(web_sound_input)
|
||||
if(findtext(web_sound_input, ":") && !findtext(web_sound_input, GLOB.is_http_protocol))
|
||||
to_chat(src, span_boldwarning("Non-http(s) URIs are not allowed."), confidential = TRUE)
|
||||
to_chat(src, span_warning("For youtube-dl shortcuts like ytsearch: please use the appropriate full url from the website."), confidential = TRUE)
|
||||
return
|
||||
var/shell_scrubbed_input = shell_url_scrub(web_sound_input)
|
||||
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_scrubbed_input]\"")
|
||||
var/errorlevel = output[SHELLEO_ERRORLEVEL]
|
||||
var/stdout = output[SHELLEO_STDOUT]
|
||||
var/stderr = output[SHELLEO_STDERR]
|
||||
if(!errorlevel)
|
||||
var/list/data
|
||||
try
|
||||
data = json_decode(stdout)
|
||||
catch(var/exception/e)
|
||||
to_chat(src, span_boldwarning("Youtube-dl JSON parsing FAILED:"), confidential = TRUE)
|
||||
to_chat(src, span_warning("[e]: [stdout]"), confidential = TRUE)
|
||||
return
|
||||
|
||||
if (data["url"])
|
||||
web_sound_url = data["url"]
|
||||
var/title = "[data["title"]]"
|
||||
var/webpage_url = title
|
||||
if (data["webpage_url"])
|
||||
webpage_url = "<a href=\"[data["webpage_url"]]\">[title]</a>"
|
||||
music_extra_data["duration"] = DisplayTimeText(data["duration"] * 1 SECONDS)
|
||||
music_extra_data["link"] = data["webpage_url"]
|
||||
music_extra_data["artist"] = data["artist"]
|
||||
music_extra_data["upload_date"] = data["upload_date"]
|
||||
music_extra_data["album"] = data["album"]
|
||||
|
||||
var/res = tgui_alert(usr, "Show the title of and link to this song to the players?\n[title]",, list("No", "Yes", "Cancel"))
|
||||
switch(res)
|
||||
if("Yes")
|
||||
music_extra_data["title"] = data["title"]
|
||||
if("No")
|
||||
music_extra_data["link"] = "Song Link Hidden"
|
||||
music_extra_data["title"] = "Song Title Hidden"
|
||||
music_extra_data["artist"] = "Song Artist Hidden"
|
||||
music_extra_data["upload_date"] = "Song Upload Date Hidden"
|
||||
music_extra_data["album"] = "Song Album Hidden"
|
||||
if("Cancel")
|
||||
return
|
||||
|
||||
var/anon = tgui_alert(usr, "Display who played the song?", "Credit Yourself?", list("No", "Yes", "Cancel"))
|
||||
switch(anon)
|
||||
if("Yes")
|
||||
if(res == "Yes")
|
||||
to_chat(world, span_boldannounce("[src] played: [webpage_url]"), confidential = TRUE)
|
||||
else
|
||||
to_chat(world, span_boldannounce("[src] played some music"), confidential = TRUE)
|
||||
if("No")
|
||||
if(res == "Yes")
|
||||
to_chat(world, span_boldannounce("An admin played: [webpage_url]"), confidential = TRUE)
|
||||
if("Cancel")
|
||||
return
|
||||
|
||||
SSblackbox.record_feedback("nested tally", "played_url", 1, list("[ckey]", "[web_sound_input]"))
|
||||
log_admin("[key_name(src)] played web sound: [web_sound_input]")
|
||||
message_admins("[key_name(src)] played web sound: [web_sound_input]")
|
||||
else
|
||||
to_chat(src, span_boldwarning("Youtube-dl URL retrieval FAILED:"), confidential = TRUE)
|
||||
to_chat(src, span_warning("[stderr]"), confidential = TRUE)
|
||||
|
||||
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, 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)
|
||||
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, span_boldwarning("Non-http(s) URIs are not allowed."), confidential = TRUE)
|
||||
to_chat(src, span_warning("For youtube-dl shortcuts like ytsearch: please use the appropriate full URL from the website."), confidential = TRUE)
|
||||
return
|
||||
if(web_sound_url || stop_web_sounds)
|
||||
for(var/m in GLOB.player_list)
|
||||
var/mob/M = m
|
||||
var/client/C = M.client
|
||||
if(C.prefs.read_preference(/datum/preference/toggle/sound_midi))
|
||||
if(!stop_web_sounds)
|
||||
C.tgui_panel?.play_music(web_sound_url, music_extra_data)
|
||||
else
|
||||
C.tgui_panel?.stop_music()
|
||||
|
||||
SSblackbox.record_feedback("tally", "admin_verb", 1, "Play Internet Sound")
|
||||
var/shell_scrubbed_input = shell_url_scrub(web_sound_input)
|
||||
web_sound(usr, shell_scrubbed_input)
|
||||
else
|
||||
web_sound(usr, null)
|
||||
|
||||
/client/proc/set_round_end_sound(S as sound)
|
||||
set category = "Admin.Fun"
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
/mob/verb/request_internet_sound()
|
||||
set category = "OOC"
|
||||
set name = "Request Internet Sound"
|
||||
|
||||
if(GLOB.say_disabled) //This is here to try to identify lag problems
|
||||
to_chat(usr, span_danger("Speech is currently admin-disabled."), confidential = TRUE)
|
||||
return
|
||||
|
||||
if (!CONFIG_GET(flag/request_internet_sound))
|
||||
to_chat(usr, span_danger("This server has disabled internet sound requests."), confidential = TRUE)
|
||||
return
|
||||
|
||||
var/request_url = tgui_input_text(usr, "Please Input a URL", "Only certain sites are allowed, such as YouTube, SoundCloud, and Bandcamp.", "")
|
||||
if(!request_url)
|
||||
return
|
||||
|
||||
//regex filter
|
||||
var/regex/allowed_regex = regex(replacetext(CONFIG_GET(string/request_internet_allowed), ",", "|"), "i")
|
||||
if(!allowed_regex.Find(request_url))
|
||||
to_chat(usr, span_danger("Invalid URL. Please use a URL from one of the following sites: [replacetext(CONFIG_GET(string/request_internet_allowed), "\\", "")]"), confidential = TRUE)
|
||||
return
|
||||
|
||||
request_url = shell_url_scrub(request_url)
|
||||
log_internet_request("[src.key]/([src.name]): [request_url]")
|
||||
if(usr.client)
|
||||
if(usr.client.prefs.muted & MUTE_INTERNET_REQUEST)
|
||||
to_chat(usr, span_danger("You cannot request music at this time. (muted)."), confidential = TRUE)
|
||||
return
|
||||
if(src.client.handle_spam_prevention(request_url,MUTE_INTERNET_REQUEST))
|
||||
return
|
||||
|
||||
GLOB.requests.music_request(usr.client, request_url)
|
||||
to_chat(usr, span_info("You requested: \"[request_url]\" to be played."), confidential = TRUE)
|
||||
request_url = span_adminnotice("<b><font color='cyan'>MUSIC REQUEST: </font>[ADMIN_FULLMONTY(src)] [ADMIN_SC(src)]:</b> [span_linkify(request_url)] [ADMIN_PLAY_INTERNET(request_url)]")
|
||||
for(var/client/admin_client in GLOB.admins)
|
||||
if(admin_client.prefs.chat_toggles & CHAT_PRAYER)
|
||||
to_chat(admin_client, request_url, type = MESSAGE_TYPE_PRAYER, confidential = TRUE)
|
||||
|
||||
SSblackbox.record_feedback("tally", "music_request", 1, "Music Request") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
Reference in New Issue
Block a user