From b2f6058c922cdcf3551a915738aa6965fac1e5fb Mon Sep 17 00:00:00 2001
From: SomeRandomOwl <2568378+SomeRandomOwl@users.noreply.github.com>
Date: Wed, 29 Mar 2023 20:04:41 -0500
Subject: [PATCH] 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.
Screenshots/Videos

Widget



New Prompts


Videos
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
## 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
:cl:
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
/:cl:
---------
Co-authored-by: Aleksej Komarov
---
code/__DEFINES/admin.dm | 3 +
code/__HELPERS/logging/game.dm | 5 +
.../configuration/entries/general.dm | 8 +
code/modules/admin/topic.dm | 10 +
code/modules/admin/verbs/admin.dm | 3 +
code/modules/admin/verbs/admingame.dm | 1 +
code/modules/admin/verbs/playsound.dm | 194 ++++++++++--------
.../admin/verbs/request_internet_sound.dm | 39 ++++
code/modules/requests/request_manager.dm | 24 +++
config/config.txt | 11 +
tgstation.dme | 1 +
.../tgui-panel/audio/NowPlayingWidget.js | 38 +++-
.../tgui/interfaces/RequestManager.js | 4 +
.../styles/interfaces/RequestManager.scss | 5 +
14 files changed, 247 insertions(+), 99 deletions(-)
create mode 100644 code/modules/admin/verbs/request_internet_sound.dm
diff --git a/code/__DEFINES/admin.dm b/code/__DEFINES/admin.dm
index 87fc73b2278..6c65c1ae747 100644
--- a/code/__DEFINES/admin.dm
+++ b/code/__DEFINES/admin.dm
@@ -6,6 +6,7 @@
#define MUTE_PRAY (1<<2)
#define MUTE_ADMINHELP (1<<3)
#define MUTE_DEADCHAT (1<<4)
+#define MUTE_INTERNET_REQUEST (1<<5)
#define MUTE_ALL (~0)
//Some constants for DB_Ban
@@ -70,6 +71,8 @@
#define ADMIN_LUAVIEW_CHUNK(state, log_index) "(VIEW CODE)"
/// Displays "(SHOW)" in the chat, when clicked it tries to show atom(paper). First you need to set the request_state variable to TRUE for the paper.
#define ADMIN_SHOW_PAPER(atom) "(SHOW)"
+/// Displays "(PLAY)" in the chat, when clicked it tries to play internet sounds from the request.
+#define ADMIN_PLAY_INTERNET(text) "(PLAY)"
/atom/proc/Admin_Coordinates_Readable(area_name, admin_jump_ref)
var/turf/T = Safe_COORD_Location()
diff --git a/code/__HELPERS/logging/game.dm b/code/__HELPERS/logging/game.dm
index 0bf180e1842..40fd458d1a9 100644
--- a/code/__HELPERS/logging/game.dm
+++ b/code/__HELPERS/logging/game.dm
@@ -23,6 +23,11 @@
if (CONFIG_GET(flag/log_prayer))
WRITE_LOG(GLOB.world_game_log, "PRAY: [text]")
+/// Logging for music requests
+/proc/log_internet_request(text)
+ if (CONFIG_GET(flag/log_internet_request))
+ WRITE_LOG(GLOB.world_game_log, "INTERNET REQUEST: [text]")
+
/// Logging for logging in & out of the game, with error messages.
/proc/log_access(text)
if (CONFIG_GET(flag/log_access))
diff --git a/code/controllers/configuration/entries/general.dm b/code/controllers/configuration/entries/general.dm
index f6a109df72b..e79fd0f6fc1 100644
--- a/code/controllers/configuration/entries/general.dm
+++ b/code/controllers/configuration/entries/general.dm
@@ -76,6 +76,9 @@
/// log prayers
/datum/config_entry/flag/log_prayer
+///Log Music Requests
+/datum/config_entry/flag/log_internet_request
+
/// log silicons
/datum/config_entry/flag/log_silicon
@@ -354,6 +357,11 @@
/datum/config_entry/string/invoke_youtubedl
protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN
+/datum/config_entry/flag/request_internet_sound
+
+/datum/config_entry/string/request_internet_allowed
+ protection = CONFIG_ENTRY_LOCKED
+
/datum/config_entry/flag/show_irc_name
/datum/config_entry/flag/no_default_techweb_link
diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm
index 085f53b5350..8d7aead7eb8 100644
--- a/code/modules/admin/topic.dm
+++ b/code/modules/admin/topic.dm
@@ -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)
+
diff --git a/code/modules/admin/verbs/admin.dm b/code/modules/admin/verbs/admin.dm
index 2558606499a..c7f3c740f83 100644
--- a/code/modules/admin/verbs/admin.dm
+++ b/code/modules/admin/verbs/admin.dm
@@ -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"
diff --git a/code/modules/admin/verbs/admingame.dm b/code/modules/admin/verbs/admingame.dm
index 21d17a05429..228e994a0c1 100644
--- a/code/modules/admin/verbs/admingame.dm
+++ b/code/modules/admin/verbs/admingame.dm
@@ -84,6 +84,7 @@
body += "OOC | "
body += "PRAY | "
body += "ADMINHELP | "
+ body += "WEBREQ | "
body += "DEADCHAT\]"
body += "(toggle all)"
diff --git a/code/modules/admin/verbs/playsound.dm b/code/modules/admin/verbs/playsound.dm
index b1031a38fa1..0b0fbaf0f58 100644
--- a/code/modules/admin/verbs/playsound.dm
+++ b/code/modules/admin/verbs/playsound.dm
@@ -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 = "[title]"
+ 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 = "[title]"
- 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"
diff --git a/code/modules/admin/verbs/request_internet_sound.dm b/code/modules/admin/verbs/request_internet_sound.dm
new file mode 100644
index 00000000000..9b5cbbbf9f9
--- /dev/null
+++ b/code/modules/admin/verbs/request_internet_sound.dm
@@ -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("MUSIC REQUEST: [ADMIN_FULLMONTY(src)] [ADMIN_SC(src)]: [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!
diff --git a/code/modules/requests/request_manager.dm b/code/modules/requests/request_manager.dm
index fef7e9fb0dd..19a94a61dad 100644
--- a/code/modules/requests/request_manager.dm
+++ b/code/modules/requests/request_manager.dm
@@ -8,6 +8,8 @@
#define REQUEST_NUKE "request_nuke"
/// Requests somebody from fax
#define REQUEST_FAX "request_fax"
+/// Requests from Request Music
+#define REQUEST_INTERNET_SOUND "request_internet_sound"
GLOBAL_DATUM_INIT(requests, /datum/request_manager, new)
@@ -107,6 +109,17 @@ GLOBAL_DATUM_INIT(requests, /datum/request_manager, new)
/datum/request_manager/proc/fax_request(client/requester, message, additional_info)
request_for_client(requester, REQUEST_FAX, message, additional_info)
+/**
+ * Creates a request for a song
+ *
+ * Arguments:
+ * * requester - The client who is sending the request
+ * * message - The URL of the song
+ */
+
+/datum/request_manager/proc/music_request(client/requester, message)
+ request_for_client(requester, REQUEST_INTERNET_SOUND, message)
+
/**
* Creates a request and registers the request with all necessary internal tracking lists
*
@@ -221,6 +234,16 @@ GLOBAL_DATUM_INIT(requests, /datum/request_manager, new)
var/obj/item/paper/request_message = request.additional_information
request_message.ui_interact(usr)
return TRUE
+ if ("play")
+ if(request.req_type != REQUEST_INTERNET_SOUND)
+ to_chat(usr, "Request doesn't have a sound to play.", confidential = TRUE)
+ return TRUE
+ if(findtext(request.message, ":") && !findtext(request.message, GLOB.is_http_protocol))
+ to_chat(usr, "Request is not a valid URL.", confidential = TRUE)
+ return TRUE
+
+ web_sound(usr, request.message)
+ return TRUE
/datum/request_manager/ui_data(mob/user)
. = list(
@@ -246,3 +269,4 @@ GLOBAL_DATUM_INIT(requests, /datum/request_manager, new)
#undef REQUEST_SYNDICATE
#undef REQUEST_NUKE
#undef REQUEST_FAX
+#undef REQUEST_INTERNET_SOUND
diff --git a/config/config.txt b/config/config.txt
index 9ee615a63ed..8a217d61292 100644
--- a/config/config.txt
+++ b/config/config.txt
@@ -130,6 +130,9 @@ LOG_TELECOMMS
## log prayers
LOG_PRAYER
+## Log Music requests
+LOG_INTERNET_REQUEST
+
## log silicons
LOG_SILICON
@@ -295,6 +298,14 @@ CHECK_RANDOMIZER
## The default value assumes youtube-dl is in your system PATH
# INVOKE_YOUTUBEDL youtube-dl
+## Comment this out to disable users ability to use the request internet sounds to be played.
+REQUEST_INTERNET_SOUND
+
+## Request Internet Sound Allowed URL'S comma separated, urls here are the only sites allowed through Request Internet Sound, Add more to allow more, or remove to disallow.
+## The Defaults here are all supported by youtube-dl
+## Ensure . and / are escaped with \
+REQUEST_INTERNET_ALLOWED youtube\.com\/watch?v=,youtu\.be\/,soundcloud\.com\/,bandcamp\.com\/track\/
+
## In-game features
## Toggle for having jobs load up from the jobconfig.toml (or jobs.txt) file. Will use codebase defaults if commented out.
diff --git a/tgstation.dme b/tgstation.dme
index 93808249bfd..45b8e986f67 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -2354,6 +2354,7 @@
#include "code\modules\admin\verbs\possess.dm"
#include "code\modules\admin\verbs\pray.dm"
#include "code\modules\admin\verbs\reestablish_db_connection.dm"
+#include "code\modules\admin\verbs\request_internet_sound.dm"
#include "code\modules\admin\verbs\requests.dm"
#include "code\modules\admin\verbs\secrets.dm"
#include "code\modules\admin\verbs\selectequipment.dm"
diff --git a/tgui/packages/tgui-panel/audio/NowPlayingWidget.js b/tgui/packages/tgui-panel/audio/NowPlayingWidget.js
index aeef414ec00..4495c2a8a1f 100644
--- a/tgui/packages/tgui-panel/audio/NowPlayingWidget.js
+++ b/tgui/packages/tgui-panel/audio/NowPlayingWidget.js
@@ -6,7 +6,7 @@
import { toFixed } from 'common/math';
import { useDispatch, useSelector } from 'common/redux';
-import { Button, Collapsible, Flex, Knob } from 'tgui/components';
+import { Button, Collapsible, Flex, Knob, Section } from 'tgui/components';
import { useSettings } from '../settings';
import { selectAudio } from './selectors';
@@ -17,7 +17,7 @@ export const NowPlayingWidget = (props, context) => {
title = audio.meta?.title,
URL = audio.meta?.link,
Artist = audio.meta?.artist || 'Unknown Artist',
- upload_date = audio.meta?.upload_date || 'Date Unknown',
+ upload_date = audio.meta?.upload_date || 'Unknown Date',
album = audio.meta?.album || 'Unknown Album',
duration = audio.meta?.duration,
date = !isNaN(upload_date)
@@ -41,13 +41,33 @@ export const NowPlayingWidget = (props, context) => {
}}>
{
-
- Url: {URL}
- Duration: {duration}
- Artist: {Artist}
- Album: {album}
- Uploaded: {date}
-
+
+ {URL !== 'Song Link Hidden' && (
+
+ Url: {URL}
+
+ )}
+
+ Duration: {duration}
+
+ {Artist !== 'Song Artist Hidden' &&
+ Artist !== 'Unknown Artist' && (
+
+ Artist: {Artist}
+
+ )}
+ {album !== 'Song Album Hidden' && album !== 'Unknown Album' && (
+
+ Album: {album}
+
+ )}
+ {upload_date !== 'Song Upload Date Hidden' &&
+ upload_date !== 'Unknown Date' && (
+
+ Uploaded: {date}
+
+ )}
+
}
diff --git a/tgui/packages/tgui/interfaces/RequestManager.js b/tgui/packages/tgui/interfaces/RequestManager.js
index ecc2a0ad515..d1ec5370f8a 100644
--- a/tgui/packages/tgui/interfaces/RequestManager.js
+++ b/tgui/packages/tgui/interfaces/RequestManager.js
@@ -85,6 +85,7 @@ const displayTypeMap = {
'request_syndicate': 'SYNDICATE',
'request_nuke': 'NUKE CODE',
'request_fax': 'FAX',
+ 'request_internet_sound': 'INTERNET SOUND',
};
const RequestType = (props) => {
@@ -121,6 +122,9 @@ const RequestControls = (props, context) => {
{request.req_type === 'request_fax' && (
)}
+ {request.req_type === 'request_internet_sound' && (
+
+ )}
);
};
diff --git a/tgui/packages/tgui/styles/interfaces/RequestManager.scss b/tgui/packages/tgui/styles/interfaces/RequestManager.scss
index f560918ed3d..1003440243a 100644
--- a/tgui/packages/tgui/styles/interfaces/RequestManager.scss
+++ b/tgui/packages/tgui/styles/interfaces/RequestManager.scss
@@ -12,6 +12,7 @@ $color-centcom: colors.bg(colors.$yellow) !default;
$color-syndicate: colors.bg(colors.$red) !default;
$color-nuke: colors.bg(colors.$yellow) !default;
$color-fax: colors.bg(colors.$green) !default;
+$color-music: colors.bg(colors.$teal) !default;
$color-muted: colors.bg(colors.$label) !default;
$color-header: colors.bg(colors.$label) !default;
$background-color: base.$color-bg-section !default;
@@ -44,6 +45,10 @@ $text-color: base.$color-fg !default;
color: $color-fax;
}
+.RequestManager__request_internet_sound {
+ color: $color-music;
+}
+
.RequestManager__header {
line-height: 1.375rem;
min-height: 1.375rem;