Refactors sound file checking (#93734)

This commit is contained in:
FalloutFalcon
2025-11-10 09:58:26 -06:00
committed by GitHub
parent c70a1792d0
commit b0ddbf2fb1
9 changed files with 112 additions and 45 deletions

11
code/__DEFINES/files.dm Normal file
View File

@@ -0,0 +1,11 @@
// None of these should be trusted for the purpose of user input
// They do not check the actual type of the file, a user could just rename it
/// File types we can sniff the duration from using rustg.
#define IS_SOUND_FILE_SAFE(file) is_file_type_in_list(##file, SSsounds.safe_formats)
#define IS_SOUND_FILE(file) is_file_type_in_list(##file, SSsounds.byond_sound_formats)
#define IS_OGG_FILE(file) is_file_type(##file, "ogg")
#define IS_WAV_FILE(file) is_file_type(##file, "wav")
#define IS_MP3_FILE(file) is_file_type(##file, "mp3")

View File

@@ -136,3 +136,46 @@ GLOBAL_VAR_INIT(fileaccess_timer, 0)
if(.)
. += delimiter // Add the delimiter before each successive node.
. += SANITIZE_FILENAME(node)
/**
* Verifys wether a string or file ends with a given file type.
*
* this does not at all check the actual type of the file, a user could just rename it
*
* Arguments:
* * file - A string or file. No checks for if this file ACCTALLY exists
* * file_types - A list of strings to check against [e.g. list("ogg" = TRUE, "mp3" = TRUE)]
*/
/proc/is_file_type_in_list(file, file_types = list())
var/extstart = findlasttext("[file]", ".")
if(!extstart)
return FALSE
var/ext = copytext("[file]", extstart + 1)
if(file_types[ext])
return TRUE
/**
* Verifys wether a string or file ends with a given file type
*
* this does not at all check the actual type of the file, a user could just rename it
*
* Arguments:
* * file - A string or file. No checks for if this file ACCTALLY exists
* * file_type - A string to check against [e.g. "ogg"]
*/
/proc/is_file_type(file, file_type)
var/extstart = findlasttext("[file]", ".")
if(!extstart)
return FALSE
var/ext = copytext("[file]", extstart + 1)
if(ext == file_type)
return TRUE
/proc/strip_filepath_extension(file, file_types)
var/extstart = findlasttext("[file]", ".")
if(!extstart)
return "[file]"
var/ext = copytext("[file]", extstart)
if(ext in file_types)
return copytext("[file]", 1, extstart)
return "[file]"

View File

@@ -34,6 +34,50 @@ SUBSYSTEM_DEF(sounds)
/// Any errors from precaching.
VAR_PRIVATE/list/precache_errors = list()
// Comments from https://github.com/DaedalusDock/daedalusdock We love Francinum.
/// A list of sound formats that work in byond. Indexed for direct accesing rather then loop itteration or usage of `in`
var/static/list/byond_sound_formats = list(
"mid" = TRUE, //Midi, 8.3 File Name
"midi" = TRUE, //Midi, Long File Name
"mod" = TRUE, //Module, Original Amiga Tracker format
"it" = TRUE, //Impulse Tracker Module format
"s3m" = TRUE, //ScreamTracker 3 Module
"xm" = TRUE, //FastTracker 2 Module
"oxm" = TRUE, //FastTracker 2 (Vorbis Compressed Samples)
"wav" = TRUE, //Waveform Audio File Format, A (R)IFF-class format, and Microsoft's choice in the 80s sound format pissing match.
"ogg" = TRUE, //OGG Audio Container, Usually contains Vorbis-compressed Audio
//"raw" = TRUE, //On the tin, byond purports to support raw, uncompressed PCM Audio. I actually have no fucking idea how FMOD actually handles these.
//since they completely lack all information. As a confusion based anti-footgun, I'm just going to wire this to FALSE for now. It's here though.
"wma" = TRUE, //Windows Media Audio container
"aiff" = TRUE, //Audio Interchange File Format, Apple's side of the 80s sound format pissing match. It's also (R)IFF in a trenchcoat.
"mp3" = TRUE //MPeg Layer 3 Container (And usually, Codec.)
)
/// File types we can sniff the duration from using rustg.
var/static/list/safe_formats = list(
"ogg" = TRUE,
"mp3" = TRUE
)
// Currently set to private as I would prefer you use byond_sound_formats but you can unprivate it if you have a valid use!
// Put more common extensions first to speed this up a bit (So only ogg and mp3 lol.)
/// Similar to byond_sound_formats, a list of sound formats that work in byond.
VAR_PRIVATE/static/list/byond_sound_extensions = list(
".ogg",
".mp3",
".mid",
".midi",
".mod",
".it",
".s3m",
".xm",
".oxm",
".wav",
//".raw", See byond_sound_formats
".wma",
".aiff"
)
/datum/controller/subsystem/sounds/Initialize()
setup_available_channels()
find_all_available_sounds()
@@ -63,23 +107,7 @@ SUBSYSTEM_DEF(sounds)
/datum/controller/subsystem/sounds/proc/find_all_available_sounds()
all_sounds = list()
// Put more common extensions first to speed this up a bit
var/static/list/valid_file_extensions = list(
".ogg",
".wav",
".mid",
".midi",
".mod",
".it",
".s3m",
".xm",
".oxm",
".raw",
".wma",
".aiff",
)
all_sounds = pathwalk("sound/", valid_file_extensions)
all_sounds = pathwalk("sound/", byond_sound_extensions)
/// Removes a channel from using list.
/datum/controller/subsystem/sounds/proc/free_sound_channel(channel)

View File

@@ -73,21 +73,6 @@ SUBSYSTEM_DEF(ticker)
var/reboot_timer = null
/datum/controller/subsystem/ticker/Initialize()
var/list/byond_sound_formats = list(
"mid" = TRUE,
"midi" = TRUE,
"mod" = TRUE,
"it" = TRUE,
"s3m" = TRUE,
"xm" = TRUE,
"oxm" = TRUE,
"wav" = TRUE,
"ogg" = TRUE,
"raw" = TRUE,
"wma" = TRUE,
"aiff" = TRUE,
)
var/list/provisional_title_music = flist("[global.config.directory]/title_music/sounds/")
var/list/music = list()
var/use_rare_music = prob(1)
@@ -115,10 +100,7 @@ SUBSYSTEM_DEF(ticker)
music -= old_login_music
for(var/S in music)
var/list/L = splittext(S,".")
if(L.len >= 2)
var/ext = LOWER_TEXT(L[L.len]) //pick the real extension, no 'honk.ogg.exe' nonsense here
if(byond_sound_formats[ext])
if(IS_SOUND_FILE(S))
continue
music -= S

View File

@@ -100,7 +100,7 @@
var/datum/track/new_track = new()
new_track.song_path = file("[global.config.directory]/jukebox_music/sounds/[track_file]")
var/list/track_data = splittext(track_file, "+")
if(length(track_data) < 3)
if(length(track_data) < 3 || !IS_SOUND_FILE(new_track.song_path))
continue
new_track.song_name = track_data[1]
new_track.song_length = text2num(track_data[2])

View File

@@ -100,13 +100,13 @@ ADMIN_VERB(create_command_report, R_ADMIN, "Create Command Report", "Create a co
if("set_report_sound")
if(params["picked_sound"] == CUSTOM_SOUND_PRESET)
played_sound = DEFAULT_ANNOUNCEMENT_SOUND // fallback by default
var/sound_file = input(ui_user, "Select sound file (OGG, WAV, MP3)", "Upload sound") as file|null
var/sound_file = input(ui_user, "Select sound file", "Upload sound") as sound|null
if(!sound_file)
tgui_alert(ui_user, "The custom sound could not be loaded. The standard sound will be played.", "Loading error", list("Ok"))
return
if(!(copytext("[sound_file]", -4) in list(".ogg", ".wav", ".mp3")))
tgui_alert(ui_user, "Invalid file type. Please select an OGG, WAV, or MP3 file.", "Loading error", list("Ok"))
if(!IS_SOUND_FILE(sound_file))
tgui_alert(ui_user, "Invalid file type. Please select a sound file.", "Loading error", list("Ok"))
return
played_sound = sound_file

View File

@@ -1,4 +1,5 @@
The enclosed /sounds folder holds the sound files used for player selectable songs for an ingame jukebox. OGG and WAV are supported.
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.
Using unnecessarily huge sounds can cause client side lag and should be avoided.

View File

@@ -1,4 +1,5 @@
The enclosed /sounds folder holds the sound files used as the title music for the game. OGG and WAV are supported.
The enclosed /sounds folder holds the sound files used as the title music for the game.
OGG is the recommended sound format but see code/controllers/subsystem/sounds.dm for the rest of the supported ones.
Using unnecessarily huge sounds can cause client side lag and should be avoided.

View File

@@ -102,6 +102,7 @@
#include "code\__DEFINES\explosions.dm"
#include "code\__DEFINES\external_organs.dm"
#include "code\__DEFINES\fantasy_affixes.dm"
#include "code\__DEFINES\files.dm"
#include "code\__DEFINES\firealarm.dm"
#include "code\__DEFINES\fish.dm"
#include "code\__DEFINES\font_awesome_icons.dm"