mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-28 23:58:07 +01:00
Admin Jukebox Moderation and Sound File code improvments (#93610)
## About The Pull Request The primary feature of this pr is two admin verbs: Both locked behind `R_SERVER` at present. Also both can be removed from this pr if we arent interested in giving admins easy control over this. Changes will not take effect untill the next round unless someone has yet to touch/spawn a jukebox. please ignore the "#. " in the titles, thats just how my spotify scraper formats the titles and I am lazy. ### Jukebox Upload Music Allows for the upload of any music to the jukebox (currently restricted to `.ogg` file types for being the better format but I can release that restriction). Adding Beats is optional but not required as it does not do a ton tbh. https://github.com/user-attachments/assets/859cdba8-c1dd-4ce4-bfce-40727a0a30b8 ### Jukebox Browse Music Allows you to delete any of them, this noticeably catches ANY sound format stored within the list. Also play and download https://github.com/user-attachments/assets/cffca3dc-d7f2-4926-bda9-2bf3fef80adb ### Refactors In order to add both of these verbs seemisly i made a bunch of improvments, Sound length for music is now gotten via the rust_g call instead of being baked into the title, this means you only need two args for jukebox titles. (This will mess up the bpm of old music tracks unfortunately.) Standerized the behavoir for validating the file type of a file, this is not full proof from what im aware and there is no checks for if the file ACCTALLY exists. ## Why It's Good For The Game Atleast on a downstream, R_SERVER is alot more commonly handed out then direct access to the tgs configs. And TGS kinda blows bubbles for doing large scale file managment. ## Changelog 🆑 code: generic helpers and defines for validating file extenstion refactor: the jukebox has had some improvements in how it validates the sound file. hopefully none of your funny songs disappear. admin: command_report_menu will let you set ANY sound file type for the sound it plays. admin: Admins can now manage jukebox songs in game server: Jukebox songs length are now set automatically, update your jukebox configs! /🆑 --------- Co-authored-by: san7890 <the@san7890.com>
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
#define CONFIG_JUKEBOX_SOUNDS "[global.config.directory]/jukebox_music/sounds/"
|
||||
|
||||
#define JUKEBOX_NAME 1
|
||||
#define JUKEBOX_BEATS 2
|
||||
@@ -175,7 +175,7 @@ GLOBAL_VAR_INIT(fileaccess_timer, 0)
|
||||
var/extstart = findlasttext("[file]", ".")
|
||||
if(!extstart)
|
||||
return "[file]"
|
||||
var/ext = copytext("[file]", extstart)
|
||||
var/ext = copytext("[file]", extstart + 1)
|
||||
if(ext in file_types)
|
||||
return copytext("[file]", 1, extstart)
|
||||
return "[file]"
|
||||
|
||||
@@ -95,16 +95,26 @@
|
||||
var/static/list/config_songs
|
||||
if(isnull(config_songs))
|
||||
config_songs = list()
|
||||
var/list/tracks = flist("[global.config.directory]/jukebox_music/sounds/")
|
||||
var/list/tracks = flist(CONFIG_JUKEBOX_SOUNDS)
|
||||
for(var/track_file in tracks)
|
||||
var/datum/track/new_track = new()
|
||||
new_track.song_path = file("[global.config.directory]/jukebox_music/sounds/[track_file]")
|
||||
new_track.song_path = file("[CONFIG_JUKEBOX_SOUNDS][track_file]")
|
||||
var/list/track_data = splittext(track_file, "+")
|
||||
if(length(track_data) < 3 || !IS_SOUND_FILE(new_track.song_path))
|
||||
if(!length(track_data) || !IS_SOUND_FILE_SAFE(new_track.song_path))
|
||||
continue
|
||||
new_track.song_name = track_data[1]
|
||||
new_track.song_length = text2num(track_data[2])
|
||||
new_track.song_beat = text2num(track_data[3])
|
||||
var/track_name = track_data[JUKEBOX_NAME]
|
||||
track_name = strip_filepath_extension(track_name, SSsounds.safe_formats)
|
||||
new_track.song_name = track_name
|
||||
new_track.song_length = SSsounds.get_sound_length(new_track.song_path)
|
||||
if(track_data.len >= 3) // Bandaid for legacy tracks to not use the length for the bpm rather then the actual beats.
|
||||
var/static/logged_to_admins = FALSE
|
||||
log_game("[new_track.song_path] track data seems to be using the legacy format; we will attempt to make it work.")
|
||||
if(!logged_to_admins)
|
||||
message_admins("The jukebox has tracks uploaded in a legacy format. Length is now fetched programmatically, with title and beats being the only required fields.")
|
||||
logged_to_admins = TRUE
|
||||
new_track.song_beat_deciseconds = text2num(track_data[3])
|
||||
else if(track_data.len >= 2)
|
||||
new_track.song_beat_deciseconds = text2num(track_data[JUKEBOX_BEATS])
|
||||
config_songs[new_track.song_name] = new_track
|
||||
|
||||
if(!length(config_songs))
|
||||
@@ -128,7 +138,7 @@
|
||||
UNTYPED_LIST_ADD(songs_data, list( \
|
||||
"name" = song_name, \
|
||||
"length" = DisplayTimeText(one_song.song_length), \
|
||||
"beat" = one_song.song_beat, \
|
||||
"beat" = one_song.song_beat_deciseconds || "Unknown", \
|
||||
))
|
||||
|
||||
data["active"] = !!active_song_sound
|
||||
@@ -399,11 +409,12 @@
|
||||
var/song_length = 0
|
||||
/// How long is a beat of the song in decisconds
|
||||
/// Used to determine time between effects when played
|
||||
var/song_beat = 0
|
||||
/// Do note this is NOT BPM.
|
||||
var/song_beat_deciseconds = 0
|
||||
|
||||
// Default track supplied for testing and also because it's a banger
|
||||
/datum/track/default
|
||||
song_path = 'sound/music/lobby_music/title3.ogg'
|
||||
song_name = "Tintin on the Moon"
|
||||
song_length = 3 MINUTES + 52 SECONDS
|
||||
song_beat = 1 SECONDS
|
||||
song_beat_deciseconds = 1 SECONDS
|
||||
|
||||
@@ -337,7 +337,7 @@
|
||||
glow.even_cycle = !glow.even_cycle
|
||||
if(prob(2)) // Unique effects for the dance floor that show up randomly to mix things up
|
||||
INVOKE_ASYNC(src, PROC_REF(hierofunk))
|
||||
sleep(music_player.selection.song_beat)
|
||||
sleep(music_player.selection.song_beat_deciseconds || 1 SECONDS)
|
||||
if(QDELETED(src))
|
||||
return
|
||||
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
ADMIN_VERB(upload_jukebox_music, R_SERVER, "Jukebox Upload Music", "Upload a valid .ogg file to be accessed via the jukebox.", ADMIN_CATEGORY_SERVER)
|
||||
var/file = input(user, "Select a .ogg file to upload to the jukebox.") as sound|null
|
||||
if(!file)
|
||||
return
|
||||
|
||||
// we could theorticly support other sound types but OGG is the better format from what I am aware and I am 100% sure its length is properly fetched.
|
||||
if(!IS_OGG_FILE(file))
|
||||
tgui_alert(user, "Invalid file type. Please select an OGG file.", "Loading error", list("Ok"))
|
||||
return
|
||||
|
||||
var/list/track_data = splittext(file, "+")
|
||||
if(track_data.len < 2)
|
||||
if(tgui_alert(user, "Your song currently does not have a beat in deciseconds added to its title, e.g: SS13+5.ogg. Continue?", "Confirmation", list("Yes", "No")) != "Yes")
|
||||
return
|
||||
if(track_data.len > 2)
|
||||
tgui_alert(user, "Titles should only have its title and beat in deciseconds, e.g: SS13+5.ogg", "Loading error", list("Ok"))
|
||||
return
|
||||
|
||||
|
||||
var/clean_name = SANITIZE_FILENAME("[file]")
|
||||
var/save_path = "[CONFIG_JUKEBOX_SOUNDS][clean_name]"
|
||||
|
||||
// Copy uploaded file to the server
|
||||
fcopy(file, save_path)
|
||||
|
||||
message_admins("[key_name_admin(user)] uploaded [clean_name] to the jukebox!")
|
||||
to_chat(user, span_notice("Successfully uploaded [clean_name]!"))
|
||||
|
||||
ADMIN_VERB(browse_jukebox_music, R_SERVER, "Jukebox Browse Music", "Browse music files for moderation.", ADMIN_CATEGORY_SERVER)
|
||||
var/list/files = flist(CONFIG_JUKEBOX_SOUNDS)
|
||||
// Filter out things that are not sound files, like the exclude
|
||||
for(var/thing in files)
|
||||
if(!IS_SOUND_FILE(thing))
|
||||
files -= thing
|
||||
if(!files.len)
|
||||
to_chat(user, span_warning("No uploaded tracks found."))
|
||||
return
|
||||
|
||||
var/choice = tgui_input_list(user, "Select a track:", "Select Jukebox Music", files)
|
||||
if(!choice)
|
||||
return
|
||||
|
||||
var/path = "[CONFIG_JUKEBOX_SOUNDS][choice]"
|
||||
|
||||
switch(tgui_alert(user, "Play, Delete, or Download?", choice, list("Play", "Delete", "Download")))
|
||||
if ("Play")
|
||||
SEND_SOUND(user, sound(path))
|
||||
if ("Delete")
|
||||
fdel(path)
|
||||
var/msg = "[key_name_admin(user)] deleted [choice] from the jukebox!"
|
||||
message_admins(msg)
|
||||
log_admin(msg)
|
||||
SSblackbox.record_feedback("associative", "jukebox_deletion", 1, list("round_id" = "[GLOB.round_id]", "deletor" = "[key_name_admin(user)]", "deleted" = "[choice]"))
|
||||
if ("Download")
|
||||
user << ftp(file(path))
|
||||
else
|
||||
return
|
||||
@@ -1,5 +1,5 @@
|
||||
The enclosed /sounds folder holds the sound files used for player selectable songs for an ingame jukebox.
|
||||
OGG is the recommended sound format but see code/controllers/subsystem/sounds.dm for the rest of the supported ones.
|
||||
OGG, WAV, and MP3 are supported. (I recommend verifying this is up to date with the list of `IS_SOUND_FILE_SAFE`)
|
||||
|
||||
Using unnecessarily huge sounds can cause client side lag and should be avoided.
|
||||
|
||||
@@ -11,6 +11,8 @@ Naming Conventions:
|
||||
|
||||
Every sound you add must have a unique name. Avoid using the plus sign "+" and the period "." in names, as these are used internally to classify sounds.
|
||||
|
||||
Sound names must be in the format of [song name]+[length in deciseconds]+[beat in deciseconds].ogg
|
||||
Sound names must be in the format of [song name]+[beat in deciseconds].ogg
|
||||
|
||||
A three minute song title "SS13" that lasted 3 minutes would have a file name SS13+1800+5.ogg
|
||||
beat is recommended but the code does not require it as its only used in the disco jukebox and UI
|
||||
|
||||
A song title "SS13" would have a file name SS13+5.ogg or SS13.ogg
|
||||
|
||||
@@ -131,6 +131,7 @@
|
||||
#include "code\__DEFINES\ipintel.dm"
|
||||
#include "code\__DEFINES\is_helpers.dm"
|
||||
#include "code\__DEFINES\jobs.dm"
|
||||
#include "code\__DEFINES\jukebox.dm"
|
||||
#include "code\__DEFINES\keybinding.dm"
|
||||
#include "code\__DEFINES\lag_switch.dm"
|
||||
#include "code\__DEFINES\language.dm"
|
||||
@@ -3171,6 +3172,7 @@
|
||||
#include "code\modules\admin\verbs\hiddenprints.dm"
|
||||
#include "code\modules\admin\verbs\highlander_datum.dm"
|
||||
#include "code\modules\admin\verbs\individual_logging.dm"
|
||||
#include "code\modules\admin\verbs\jukebox_moderation.dm"
|
||||
#include "code\modules\admin\verbs\lawpanel.dm"
|
||||
#include "code\modules\admin\verbs\light_debug.dm"
|
||||
#include "code\modules\admin\verbs\list_exposer.dm"
|
||||
|
||||
Reference in New Issue
Block a user