mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-23 13:10:02 +01:00
Prevents protected audio from crashing the server with no survivors (#90975)
Fixes #90694 I believe the heart of this issue is that the audio player was trying to log an error object, but logs only take strings. This should prevent the blue screen and provide admin feedback - Everyone survives your fatal attempt to play king gizzard the lizard wizard - Better admin feedback why you cannot play aforementioned song 🆑 fix: We're no strangers to bugs: Playing protected audio shouldn't crash the server anymore! /🆑
This commit is contained in:
@@ -12,6 +12,8 @@
|
||||
var/datum/tgui_window/window
|
||||
var/broken = FALSE
|
||||
var/initialized_at
|
||||
/// Each client notifies on protected playback, so this prevents spamming admins.
|
||||
var/static/admins_warned = FALSE
|
||||
|
||||
/datum/tgui_panel/New(client/client, id)
|
||||
src.client = client
|
||||
@@ -86,9 +88,18 @@
|
||||
),
|
||||
))
|
||||
return TRUE
|
||||
|
||||
if(type == "audio/setAdminMusicVolume")
|
||||
client.admin_music_volume = payload["volume"]
|
||||
return TRUE
|
||||
|
||||
if(type == "audio/protected")
|
||||
if(!admins_warned)
|
||||
message_admins(span_notice("Audio returned a protected playback error, likely due to being copyrighted."))
|
||||
admins_warned = TRUE
|
||||
addtimer(VARSET_CALLBACK(src, admins_warned, FALSE), 10 SECONDS)
|
||||
return TRUE
|
||||
|
||||
if(type == "telemetry")
|
||||
analyze_telemetry(payload)
|
||||
return TRUE
|
||||
|
||||
@@ -31,3 +31,8 @@
|
||||
aggresively.
|
||||
- bugfix: Fixes feed detailed description lying about the time it takes to start
|
||||
feeding
|
||||
2025-05-05:
|
||||
LT3:
|
||||
- bugfix: Everyone's chat log no longer bluescreens due to Admins' bad taste in
|
||||
music. Their fatal attempts to make you listen to king gizzard the lizard
|
||||
wizard will now fail silently
|
||||
|
||||
@@ -14,6 +14,15 @@ type AudioOptions = {
|
||||
end?: number;
|
||||
};
|
||||
|
||||
function isProtectedError(error: ErrorEvent): boolean {
|
||||
return (
|
||||
typeof error === 'object' &&
|
||||
error !== null &&
|
||||
'isTrusted' in error &&
|
||||
error.isTrusted
|
||||
);
|
||||
}
|
||||
|
||||
export class AudioPlayer {
|
||||
element: HTMLAudioElement | null;
|
||||
options: AudioOptions;
|
||||
@@ -40,7 +49,13 @@ export class AudioPlayer {
|
||||
|
||||
this.options = options;
|
||||
|
||||
const audio = (this.element = new Audio(url));
|
||||
const audio = new Audio(url);
|
||||
if (!audio) {
|
||||
logger.log('failed to create audio element');
|
||||
return;
|
||||
}
|
||||
this.element = audio;
|
||||
|
||||
audio.volume = this.volume;
|
||||
audio.playbackRate = this.options.pitch || 1;
|
||||
|
||||
@@ -52,7 +67,11 @@ export class AudioPlayer {
|
||||
});
|
||||
|
||||
audio.addEventListener('error', (error) => {
|
||||
logger.log('playback error', error);
|
||||
if (isProtectedError(error)) {
|
||||
Byond.sendMessage('audio/protected');
|
||||
}
|
||||
logger.log('playback error:', JSON.stringify(error));
|
||||
this.stop();
|
||||
});
|
||||
|
||||
if (this.options.end) {
|
||||
@@ -67,7 +86,10 @@ export class AudioPlayer {
|
||||
});
|
||||
}
|
||||
|
||||
audio.play();
|
||||
audio.play()?.catch(() => {
|
||||
// no error is passed here, it's sent to the event listener
|
||||
logger.log('playback failed');
|
||||
});
|
||||
|
||||
this.onPlaySubscribers.forEach((subscriber) => subscriber());
|
||||
}
|
||||
@@ -78,7 +100,7 @@ export class AudioPlayer {
|
||||
logger.log('stopping');
|
||||
|
||||
this.element.pause();
|
||||
this.element = null;
|
||||
this.destroy();
|
||||
|
||||
this.onStopSubscribers.forEach((subscriber) => subscriber());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user