mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-10 02:09:41 +00:00
[MIRROR] Sound updates (#7430)
Co-authored-by: Heroman3003 <31296024+Heroman3003@users.noreply.github.com> Co-authored-by: Selis <sirlionfur@hotmail.de> Co-authored-by: Selis <selis@xynolabs.com>
This commit is contained in:
@@ -1,3 +1,62 @@
|
|||||||
|
//// COOLDOWN SYSTEMS
|
||||||
|
/*
|
||||||
|
* We have 2 cooldown systems: timer cooldowns (divided between stoppable and regular) and world.time cooldowns.
|
||||||
|
*
|
||||||
|
* When to use each?
|
||||||
|
*
|
||||||
|
* * Adding a commonly-checked cooldown, like on a subsystem to check for processing
|
||||||
|
* * * Use the world.time ones, as they are cheaper.
|
||||||
|
*
|
||||||
|
* * Adding a rarely-used one for special situations, such as giving an uncommon item a cooldown on a target.
|
||||||
|
* * * Timer cooldown, as adding a new variable on each mob to track the cooldown of said uncommon item is going too far.
|
||||||
|
*
|
||||||
|
* * Triggering events at the end of a cooldown.
|
||||||
|
* * * Timer cooldown, registering to its signal.
|
||||||
|
*
|
||||||
|
* * Being able to check how long left for the cooldown to end.
|
||||||
|
* * * Either world.time or stoppable timer cooldowns, depending on the other factors. Regular timer cooldowns do not support this.
|
||||||
|
*
|
||||||
|
* * Being able to stop the timer before it ends.
|
||||||
|
* * * Either world.time or stoppable timer cooldowns, depending on the other factors. Regular timer cooldowns do not support this.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Cooldown system based on an datum-level associative lazylist using timers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// admin verb cooldowns
|
||||||
|
#define COOLDOWN_INTERNET_SOUND "internet_sound"
|
||||||
|
|
||||||
|
//TIMER COOLDOWN MACROS
|
||||||
|
|
||||||
|
#define COMSIG_CD_STOP(cd_index) "cooldown_[cd_index]"
|
||||||
|
#define COMSIG_CD_RESET(cd_index) "cd_reset_[cd_index]"
|
||||||
|
|
||||||
|
#define TIMER_COOLDOWN_START(cd_source, cd_index, cd_time) LAZYSET(cd_source.cooldowns, cd_index, addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(end_cooldown), cd_source, cd_index), cd_time))
|
||||||
|
|
||||||
|
/// Checks if a timer based cooldown is NOT finished.
|
||||||
|
#define TIMER_COOLDOWN_RUNNING(cd_source, cd_index) LAZYACCESS(cd_source.cooldowns, cd_index)
|
||||||
|
|
||||||
|
/// Checks if a timer based cooldown is finished.
|
||||||
|
#define TIMER_COOLDOWN_FINISHED(cd_source, cd_index) (!TIMER_COOLDOWN_RUNNING(cd_source, cd_index))
|
||||||
|
|
||||||
|
#define TIMER_COOLDOWN_END(cd_source, cd_index) LAZYREMOVE(cd_source.cooldowns, cd_index)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Stoppable timer cooldowns.
|
||||||
|
* Use indexes the same as the regular tiemr cooldowns.
|
||||||
|
* They make use of the TIMER_COOLDOWN_RUNNING() and TIMER_COOLDOWN_END() macros the same, just not the TIMER_COOLDOWN_START() one.
|
||||||
|
* A bit more expensive than the regular timers, but can be reset before they end and the time left can be checked.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define S_TIMER_COOLDOWN_START(cd_source, cd_index, cd_time) LAZYSET(cd_source.cooldowns, cd_index, addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(end_cooldown), cd_source, cd_index), cd_time, TIMER_STOPPABLE))
|
||||||
|
|
||||||
|
#define S_TIMER_COOLDOWN_RESET(cd_source, cd_index) reset_cooldown(cd_source, cd_index)
|
||||||
|
|
||||||
|
#define S_TIMER_COOLDOWN_TIMELEFT(cd_source, cd_index) (timeleft(TIMER_COOLDOWN_RUNNING(cd_source, cd_index)))
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Cooldown system based on storing world.time on a variable, plus the cooldown time.
|
* Cooldown system based on storing world.time on a variable, plus the cooldown time.
|
||||||
* Better performance over timer cooldowns, lower control. Same functionality.
|
* Better performance over timer cooldowns, lower control. Same functionality.
|
||||||
@@ -5,6 +64,8 @@
|
|||||||
|
|
||||||
#define COOLDOWN_DECLARE(cd_index) var/##cd_index = 0
|
#define COOLDOWN_DECLARE(cd_index) var/##cd_index = 0
|
||||||
|
|
||||||
|
#define STATIC_COOLDOWN_DECLARE(cd_index) var/static/##cd_index = 0
|
||||||
|
|
||||||
#define COOLDOWN_START(cd_source, cd_index, cd_time) (cd_source.cd_index = world.time + (cd_time))
|
#define COOLDOWN_START(cd_source, cd_index, cd_time) (cd_source.cd_index = world.time + (cd_time))
|
||||||
|
|
||||||
//Returns true if the cooldown has run its course, false otherwise
|
//Returns true if the cooldown has run its course, false otherwise
|
||||||
@@ -12,4 +73,6 @@
|
|||||||
|
|
||||||
#define COOLDOWN_RESET(cd_source, cd_index) cd_source.cd_index = 0
|
#define COOLDOWN_RESET(cd_source, cd_index) cd_source.cd_index = 0
|
||||||
|
|
||||||
|
#define COOLDOWN_STARTED(cd_source, cd_index) (cd_source.cd_index != 0)
|
||||||
|
|
||||||
#define COOLDOWN_TIMELEFT(cd_source, cd_index) (max(0, cd_source.cd_index - world.time))
|
#define COOLDOWN_TIMELEFT(cd_source, cd_index) (max(0, cd_source.cd_index - world.time))
|
||||||
60
code/_helpers/shell.dm
Normal file
60
code/_helpers/shell.dm
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
//Runs the command in the system's shell, returns a list of (error code, stdout, stderr)
|
||||||
|
|
||||||
|
#define SHELLEO_NAME "data/shelleo."
|
||||||
|
#define SHELLEO_ERR ".err"
|
||||||
|
#define SHELLEO_OUT ".out"
|
||||||
|
/world/proc/shelleo(command)
|
||||||
|
var/static/list/shelleo_ids = list()
|
||||||
|
var/stdout = ""
|
||||||
|
var/stderr = ""
|
||||||
|
var/errorcode = 1
|
||||||
|
var/shelleo_id
|
||||||
|
var/out_file = ""
|
||||||
|
var/err_file = ""
|
||||||
|
var/static/list/interpreters = list("[MS_WINDOWS]" = "cmd /c", "[UNIX]" = "sh -c")
|
||||||
|
var/interpreter = interpreters["[world.system_type]"]
|
||||||
|
if(interpreter)
|
||||||
|
for(var/seo_id in shelleo_ids)
|
||||||
|
if(!shelleo_ids[seo_id])
|
||||||
|
shelleo_ids[seo_id] = TRUE
|
||||||
|
shelleo_id = "[seo_id]"
|
||||||
|
break
|
||||||
|
if(!shelleo_id)
|
||||||
|
shelleo_id = "[shelleo_ids.len + 1]"
|
||||||
|
shelleo_ids += shelleo_id
|
||||||
|
shelleo_ids[shelleo_id] = TRUE
|
||||||
|
out_file = "[SHELLEO_NAME][shelleo_id][SHELLEO_OUT]"
|
||||||
|
err_file = "[SHELLEO_NAME][shelleo_id][SHELLEO_ERR]"
|
||||||
|
if(world.system_type == UNIX)
|
||||||
|
errorcode = shell("[interpreter] \"[replacetext(command, "\"", "\\\"")]\" > [out_file] 2> [err_file]")
|
||||||
|
else
|
||||||
|
errorcode = shell("[interpreter] \"[command]\" > [out_file] 2> [err_file]")
|
||||||
|
if(fexists(out_file))
|
||||||
|
stdout = file2text(out_file)
|
||||||
|
fdel(out_file)
|
||||||
|
if(fexists(err_file))
|
||||||
|
stderr = file2text(err_file)
|
||||||
|
fdel(err_file)
|
||||||
|
shelleo_ids[shelleo_id] = FALSE
|
||||||
|
else
|
||||||
|
CRASH("Operating System: [world.system_type] not supported") // If you encounter this error, you are encouraged to update this proc with support for the new operating system
|
||||||
|
. = list(errorcode, stdout, stderr)
|
||||||
|
#undef SHELLEO_NAME
|
||||||
|
#undef SHELLEO_ERR
|
||||||
|
#undef SHELLEO_OUT
|
||||||
|
|
||||||
|
/proc/shell_url_scrub(url)
|
||||||
|
var/static/regex/bad_chars_regex = regex("\[^#%&./:=?\\w]*", "g")
|
||||||
|
var/scrubbed_url = ""
|
||||||
|
var/bad_match = ""
|
||||||
|
var/last_good = 1
|
||||||
|
var/bad_chars = 1
|
||||||
|
do
|
||||||
|
bad_chars = bad_chars_regex.Find(url)
|
||||||
|
scrubbed_url += copytext(url, last_good, bad_chars)
|
||||||
|
if(bad_chars)
|
||||||
|
bad_match = url_encode(bad_chars_regex.match)
|
||||||
|
scrubbed_url += bad_match
|
||||||
|
last_good = bad_chars + length(bad_chars_regex.match)
|
||||||
|
while(bad_chars)
|
||||||
|
. = scrubbed_url
|
||||||
@@ -304,6 +304,8 @@ var/list/gamemode_cache = list()
|
|||||||
var/static/suggested_byond_version
|
var/static/suggested_byond_version
|
||||||
var/static/suggested_byond_build
|
var/static/suggested_byond_build
|
||||||
|
|
||||||
|
var/static/invoke_youtubedl = null
|
||||||
|
|
||||||
/datum/configuration/New()
|
/datum/configuration/New()
|
||||||
var/list/L = subtypesof(/datum/game_mode)
|
var/list/L = subtypesof(/datum/game_mode)
|
||||||
for (var/T in L)
|
for (var/T in L)
|
||||||
@@ -982,6 +984,9 @@ var/list/gamemode_cache = list()
|
|||||||
config.vgs_server_port = text2num(value)
|
config.vgs_server_port = text2num(value)
|
||||||
// VOREStation Edit End
|
// VOREStation Edit End
|
||||||
|
|
||||||
|
if("invoke_youtubedl")
|
||||||
|
config.invoke_youtubedl = value
|
||||||
|
|
||||||
else
|
else
|
||||||
log_misc("Unknown setting in configuration: '[name]'")
|
log_misc("Unknown setting in configuration: '[name]'")
|
||||||
|
|
||||||
|
|||||||
@@ -512,6 +512,26 @@ SUBSYSTEM_DEF(timer)
|
|||||||
return TRUE
|
return TRUE
|
||||||
return FALSE
|
return FALSE
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the remaining deciseconds on a timer
|
||||||
|
*
|
||||||
|
* Arguments:
|
||||||
|
* * id a timerid or a /datum/timedevent
|
||||||
|
*/
|
||||||
|
/proc/timeleft(id, datum/controller/subsystem/timer/timer_subsystem)
|
||||||
|
if (!id)
|
||||||
|
return null
|
||||||
|
if (id == TIMER_ID_NULL)
|
||||||
|
CRASH("Tried to get timeleft of a null timerid. Use TIMER_STOPPABLE flag")
|
||||||
|
if (istype(id, /datum/timedevent))
|
||||||
|
var/datum/timedevent/timer = id
|
||||||
|
return timer.timeToRun - world.time
|
||||||
|
timer_subsystem = timer_subsystem || SStimer
|
||||||
|
//id is string
|
||||||
|
var/datum/timedevent/timer = timer_subsystem.timer_id_dict[id]
|
||||||
|
if(!timer || timer.spent)
|
||||||
|
return null
|
||||||
|
return timer.timeToRun - (timer.flags & TIMER_CLIENT_TIME ? REALTIMEOFDAY : world.time)
|
||||||
|
|
||||||
#undef BUCKET_LEN
|
#undef BUCKET_LEN
|
||||||
#undef BUCKET_POS
|
#undef BUCKET_POS
|
||||||
|
|||||||
@@ -47,6 +47,14 @@
|
|||||||
/// A weak reference to another datum
|
/// A weak reference to another datum
|
||||||
var/datum/weakref/weak_reference
|
var/datum/weakref/weak_reference
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Lazy associative list of currently active cooldowns.
|
||||||
|
*
|
||||||
|
* cooldowns [ COOLDOWN_INDEX ] = add_timer()
|
||||||
|
* add_timer() returns the truthy value of -1 when not stoppable, and else a truthy numeric index
|
||||||
|
*/
|
||||||
|
var/list/cooldowns
|
||||||
|
|
||||||
#ifdef REFERENCE_TRACKING
|
#ifdef REFERENCE_TRACKING
|
||||||
var/tmp/running_find_references
|
var/tmp/running_find_references
|
||||||
var/tmp/last_find_references = 0
|
var/tmp/last_find_references = 0
|
||||||
@@ -104,3 +112,33 @@
|
|||||||
tag = null
|
tag = null
|
||||||
SStgui.close_uis(src)
|
SStgui.close_uis(src)
|
||||||
return QDEL_HINT_QUEUE
|
return QDEL_HINT_QUEUE
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback called by a timer to end an associative-list-indexed cooldown.
|
||||||
|
*
|
||||||
|
* Arguments:
|
||||||
|
* * source - datum storing the cooldown
|
||||||
|
* * index - string index storing the cooldown on the cooldowns associative list
|
||||||
|
*
|
||||||
|
* This sends a signal reporting the cooldown end.
|
||||||
|
*/
|
||||||
|
/proc/end_cooldown(datum/source, index)
|
||||||
|
if(QDELETED(source))
|
||||||
|
return
|
||||||
|
SEND_SIGNAL(source, COMSIG_CD_STOP(index))
|
||||||
|
TIMER_COOLDOWN_END(source, index)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Proc used by stoppable timers to end a cooldown before the time has ran out.
|
||||||
|
*
|
||||||
|
* Arguments:
|
||||||
|
* * source - datum storing the cooldown
|
||||||
|
* * index - string index storing the cooldown on the cooldowns associative list
|
||||||
|
*
|
||||||
|
* This sends a signal reporting the cooldown end, passing the time left as an argument.
|
||||||
|
*/
|
||||||
|
/proc/reset_cooldown(datum/source, index)
|
||||||
|
if(QDELETED(source))
|
||||||
|
return
|
||||||
|
SEND_SIGNAL(source, COMSIG_CD_RESET(index), S_TIMER_COOLDOWN_TIMELEFT(source, index))
|
||||||
|
TIMER_COOLDOWN_END(source, index)
|
||||||
|
|||||||
@@ -123,7 +123,8 @@ var/list/admin_verbs_ban = list(
|
|||||||
var/list/admin_verbs_sounds = list(
|
var/list/admin_verbs_sounds = list(
|
||||||
/client/proc/play_local_sound,
|
/client/proc/play_local_sound,
|
||||||
/client/proc/play_sound,
|
/client/proc/play_sound,
|
||||||
/client/proc/play_server_sound
|
/client/proc/play_server_sound,
|
||||||
|
/client/proc/play_web_sound
|
||||||
)
|
)
|
||||||
|
|
||||||
var/list/admin_verbs_fun = list(
|
var/list/admin_verbs_fun = list(
|
||||||
@@ -244,7 +245,8 @@ var/list/admin_verbs_debug = list(
|
|||||||
/datum/admins/proc/view_feedback,
|
/datum/admins/proc/view_feedback,
|
||||||
/client/proc/debug_global_variables,
|
/client/proc/debug_global_variables,
|
||||||
/client/proc/ping_webhook,
|
/client/proc/ping_webhook,
|
||||||
/client/proc/reload_webhooks
|
/client/proc/reload_webhooks,
|
||||||
|
/client/proc/stop_sounds
|
||||||
)
|
)
|
||||||
|
|
||||||
var/list/admin_verbs_paranoid_debug = list(
|
var/list/admin_verbs_paranoid_debug = list(
|
||||||
@@ -290,6 +292,7 @@ var/list/admin_verbs_hideable = list(
|
|||||||
/client/proc/play_local_sound,
|
/client/proc/play_local_sound,
|
||||||
/client/proc/play_sound,
|
/client/proc/play_sound,
|
||||||
/client/proc/play_server_sound,
|
/client/proc/play_server_sound,
|
||||||
|
/client/proc/play_web_sound,
|
||||||
/client/proc/object_talk,
|
/client/proc/object_talk,
|
||||||
/datum/admins/proc/cmd_admin_dress,
|
/datum/admins/proc/cmd_admin_dress,
|
||||||
/client/proc/cmd_admin_gib_self,
|
/client/proc/cmd_admin_gib_self,
|
||||||
@@ -339,7 +342,8 @@ var/list/admin_verbs_hideable = list(
|
|||||||
/proc/possess,
|
/proc/possess,
|
||||||
/proc/release,
|
/proc/release,
|
||||||
/datum/admins/proc/set_tcrystals,
|
/datum/admins/proc/set_tcrystals,
|
||||||
/client/proc/debug_global_variables
|
/client/proc/debug_global_variables,
|
||||||
|
/client/proc/stop_sounds
|
||||||
)
|
)
|
||||||
var/list/admin_verbs_mod = list(
|
var/list/admin_verbs_mod = list(
|
||||||
/client/proc/cmd_admin_pm_context, //right-click adminPM interface,
|
/client/proc/cmd_admin_pm_context, //right-click adminPM interface,
|
||||||
|
|||||||
@@ -143,6 +143,7 @@ var/list/admin_verbs_sounds = list(
|
|||||||
/client/proc/play_local_sound,
|
/client/proc/play_local_sound,
|
||||||
/client/proc/play_sound,
|
/client/proc/play_sound,
|
||||||
/client/proc/play_server_sound,
|
/client/proc/play_server_sound,
|
||||||
|
/client/proc/play_web_sound,
|
||||||
/client/proc/play_z_sound
|
/client/proc/play_z_sound
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -279,6 +280,7 @@ var/list/admin_verbs_debug = list(
|
|||||||
/client/proc/admin_give_modifier,
|
/client/proc/admin_give_modifier,
|
||||||
/client/proc/simple_DPS,
|
/client/proc/simple_DPS,
|
||||||
/datum/admins/proc/view_feedback,
|
/datum/admins/proc/view_feedback,
|
||||||
|
/client/proc/stop_sounds,
|
||||||
/datum/admins/proc/quick_nif, //CHOMPStation Add,
|
/datum/admins/proc/quick_nif, //CHOMPStation Add,
|
||||||
/datum/admins/proc/quick_authentic_nif //CHOMPStation add
|
/datum/admins/proc/quick_authentic_nif //CHOMPStation add
|
||||||
)
|
)
|
||||||
@@ -327,6 +329,7 @@ var/list/admin_verbs_hideable = list(
|
|||||||
/client/proc/play_local_sound,
|
/client/proc/play_local_sound,
|
||||||
/client/proc/play_sound,
|
/client/proc/play_sound,
|
||||||
/client/proc/play_server_sound,
|
/client/proc/play_server_sound,
|
||||||
|
/client/proc/play_web_sound,
|
||||||
/client/proc/object_talk,
|
/client/proc/object_talk,
|
||||||
/datum/admins/proc/cmd_admin_dress,
|
/datum/admins/proc/cmd_admin_dress,
|
||||||
/client/proc/cmd_admin_gib_self,
|
/client/proc/cmd_admin_gib_self,
|
||||||
@@ -376,7 +379,8 @@ var/list/admin_verbs_hideable = list(
|
|||||||
/proc/possess,
|
/proc/possess,
|
||||||
/proc/release,
|
/proc/release,
|
||||||
/datum/admins/proc/set_uplink, //VOREStation Add,
|
/datum/admins/proc/set_uplink, //VOREStation Add,
|
||||||
/datum/admins/proc/set_tcrystals
|
/datum/admins/proc/set_tcrystals,
|
||||||
|
/client/proc/stop_sounds
|
||||||
)
|
)
|
||||||
var/list/admin_verbs_mod = list(
|
var/list/admin_verbs_mod = list(
|
||||||
/client/proc/cmd_admin_pm_context, //right-click adminPM interface,
|
/client/proc/cmd_admin_pm_context, //right-click adminPM interface,
|
||||||
|
|||||||
@@ -1,35 +1,77 @@
|
|||||||
|
//world/proc/shelleo
|
||||||
|
#define SHELLEO_ERRORLEVEL 1
|
||||||
|
#define SHELLEO_STDOUT 2
|
||||||
|
#define SHELLEO_STDERR 3
|
||||||
|
|
||||||
var/list/sounds_cache = list()
|
var/list/sounds_cache = list()
|
||||||
|
|
||||||
/client/proc/play_sound(S as sound)
|
/client/proc/play_sound(S as sound)
|
||||||
set category = "Fun"
|
set category = "Fun"
|
||||||
set name = "Play Global Sound"
|
set name = "Play Global Sound"
|
||||||
if(!check_rights(R_SOUNDS)) return
|
if(!check_rights(R_SOUNDS))
|
||||||
|
return
|
||||||
|
|
||||||
var/sound/uploaded_sound = sound(S, volume = 50, repeat = 0, wait = 1, channel = 777)
|
var/freq = 1
|
||||||
uploaded_sound.priority = 250
|
var/vol = tgui_input_number(usr, "What volume would you like the sound to play at?",, 100, 100, 1)
|
||||||
|
if(!vol)
|
||||||
|
return
|
||||||
|
vol = clamp(vol, 1, 100)
|
||||||
|
|
||||||
|
var/sound/admin_sound = new()
|
||||||
|
admin_sound.file = S
|
||||||
|
admin_sound.priority = 250
|
||||||
|
admin_sound.channel = 777
|
||||||
|
admin_sound.frequency = freq
|
||||||
|
admin_sound.wait = 1
|
||||||
|
admin_sound.repeat = FALSE
|
||||||
|
admin_sound.status = SOUND_STREAM
|
||||||
|
admin_sound.volume = vol
|
||||||
|
|
||||||
sounds_cache += S
|
sounds_cache += S
|
||||||
|
|
||||||
if(tgui_alert(usr, "Do you ready?\nSong: [S]\nNow you can also play this sound using \"Play Server Sound\".", "Confirmation request", list("Play","Cancel")) == "Cancel")
|
var/res = tgui_alert(usr, "Show the title of this song ([S]) to the players?\nOptions 'Yes' and 'No' will play the sound.",, list("Yes", "No", "Cancel"))
|
||||||
return
|
switch(res)
|
||||||
|
if("Yes")
|
||||||
|
to_chat(world, "<span class='boldannounce'>An admin played: [S]</span>", confidential = TRUE)
|
||||||
|
if("Cancel")
|
||||||
|
return
|
||||||
|
|
||||||
log_admin("[key_name(src)] played sound [S]")
|
log_admin("[key_name(src)] played sound [S]")
|
||||||
message_admins("[key_name_admin(src)] played sound [S]", 1)
|
message_admins("[key_name_admin(src)] played sound [S]", 1)
|
||||||
|
|
||||||
for(var/mob/M in player_list)
|
for(var/mob/M in player_list)
|
||||||
if(M.is_preference_enabled(/datum/client_preference/play_admin_midis))
|
if(M.is_preference_enabled(/datum/client_preference/play_admin_midis))
|
||||||
M << uploaded_sound
|
admin_sound.volume = vol * M.client.admin_music_volume
|
||||||
|
SEND_SOUND(M, admin_sound)
|
||||||
|
admin_sound.volume = vol
|
||||||
|
|
||||||
feedback_add_details("admin_verb","PGS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
feedback_add_details("admin_verb", "Play Global Sound")
|
||||||
|
|
||||||
/client/proc/play_local_sound(S as sound)
|
/client/proc/play_local_sound(S as sound)
|
||||||
set category = "Fun"
|
set category = "Fun"
|
||||||
set name = "Play Local Sound"
|
set name = "Play Local Sound"
|
||||||
if(!check_rights(R_SOUNDS)) return
|
if(!check_rights(R_SOUNDS))
|
||||||
|
return
|
||||||
|
|
||||||
log_admin("[key_name(src)] played a local sound [S]")
|
log_admin("[key_name(src)] played a local sound [S]")
|
||||||
message_admins("[key_name_admin(src)] played a local sound [S]", 1)
|
message_admins("[key_name_admin(src)] played a local sound [S]", 1)
|
||||||
playsound(src.mob, S, 50, 0, 0)
|
playsound(src.mob, S, 50, 0, 0)
|
||||||
feedback_add_details("admin_verb","PLS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
feedback_add_details("admin_verb", "Play Local Sound")
|
||||||
|
|
||||||
|
/client/proc/play_direct_mob_sound(S as sound, mob/M)
|
||||||
|
set category = "Fun"
|
||||||
|
set name = "Play Direct Mob Sound"
|
||||||
|
if(!check_rights(R_SOUNDS))
|
||||||
|
return
|
||||||
|
|
||||||
|
if(!M)
|
||||||
|
M = tgui_input_list(usr, "Choose a mob to play the sound to. Only they will hear it.", "Play Mob Sound", sortNames(player_list))
|
||||||
|
if(!M || QDELETED(M))
|
||||||
|
return
|
||||||
|
log_admin("[key_name(src)] played a direct mob sound [S] to [M].")
|
||||||
|
message_admins("[key_name_admin(src)] played a direct mob sound [S] to [ADMIN_LOOKUPFLW(M)].")
|
||||||
|
SEND_SOUND(M, S)
|
||||||
|
feedback_add_details("admin_verb", "Play Direct Mob Sound")
|
||||||
|
|
||||||
/client/proc/play_z_sound(S as sound)
|
/client/proc/play_z_sound(S as sound)
|
||||||
set category = "Fun"
|
set category = "Fun"
|
||||||
@@ -50,13 +92,14 @@ var/list/sounds_cache = list()
|
|||||||
if(M.is_preference_enabled(/datum/client_preference/play_admin_midis) && M.z == target_z)
|
if(M.is_preference_enabled(/datum/client_preference/play_admin_midis) && M.z == target_z)
|
||||||
M << uploaded_sound
|
M << uploaded_sound
|
||||||
|
|
||||||
feedback_add_details("admin_verb","PZS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
feedback_add_details("admin_verb", "Play Z Sound") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||||
|
|
||||||
|
|
||||||
/client/proc/play_server_sound()
|
/client/proc/play_server_sound()
|
||||||
set category = "Fun"
|
set category = "Fun"
|
||||||
set name = "Play Server Sound"
|
set name = "Play Server Sound"
|
||||||
if(!check_rights(R_SOUNDS)) return
|
if(!check_rights(R_SOUNDS))
|
||||||
|
return
|
||||||
|
|
||||||
var/list/sounds = file2list("sound/serversound_list.txt");
|
var/list/sounds = file2list("sound/serversound_list.txt");
|
||||||
sounds += "--CANCEL--"
|
sounds += "--CANCEL--"
|
||||||
@@ -64,10 +107,159 @@ var/list/sounds_cache = list()
|
|||||||
|
|
||||||
var/melody = tgui_input_list(usr, "Select a sound from the server to play", "Server sound list", sounds, "--CANCEL--")
|
var/melody = tgui_input_list(usr, "Select a sound from the server to play", "Server sound list", sounds, "--CANCEL--")
|
||||||
|
|
||||||
if(melody == "--CANCEL--") return
|
if(melody == "--CANCEL--")
|
||||||
|
return
|
||||||
|
|
||||||
play_sound(melody)
|
play_sound(melody)
|
||||||
feedback_add_details("admin_verb","PSS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
feedback_add_details("admin_verb", "Play Server 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, credit)
|
||||||
|
if(!check_rights(R_SOUNDS))
|
||||||
|
return
|
||||||
|
var/ytdl = config.invoke_youtubedl
|
||||||
|
if(!ytdl)
|
||||||
|
to_chat(user, "<span class='boldwarning'>Youtube-dl was not configured, action unavailable</span>", 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()
|
||||||
|
var/duration = 0
|
||||||
|
if(istext(input))
|
||||||
|
var/shell_scrubbed_input = shell_url_scrub(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)
|
||||||
|
to_chat(user, "<span class='boldwarning'>Youtube-dl URL retrieval FAILED:</span>", confidential = TRUE)
|
||||||
|
to_chat(user, "<span class='warning'>[stderr]</span>", confidential = TRUE)
|
||||||
|
return
|
||||||
|
var/list/data
|
||||||
|
try
|
||||||
|
data = json_decode(stdout)
|
||||||
|
catch(var/exception/e)
|
||||||
|
to_chat(user, "<span class='boldwarning'>Youtube-dl JSON parsing FAILED:</span>", confidential = TRUE)
|
||||||
|
to_chat(user, "<span class='warning'>[e]: [stdout]</span>", 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"]
|
||||||
|
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 class='boldannounce'>[user.key] played: [webpage_url]</span>", confidential = TRUE)
|
||||||
|
else
|
||||||
|
to_chat(world, "<span class='boldannounce'>[user.key] played a sound</span>", confidential = TRUE)
|
||||||
|
if("No")
|
||||||
|
if(res == "Yes")
|
||||||
|
to_chat(world, "<span class='boldannounce'>An admin played: [webpage_url]</span>", confidential = TRUE)
|
||||||
|
if("Cancel", null)
|
||||||
|
return
|
||||||
|
if(credit)
|
||||||
|
to_chat(world, "<span class='boldannounce'>[credit]</span>", confidential = TRUE)
|
||||||
|
//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 class='boldwarning'>BLOCKED: Content URL not using HTTP(S) Protocol!</span>", confidential = TRUE)
|
||||||
|
|
||||||
|
return
|
||||||
|
if(web_sound_url || stop_web_sounds)
|
||||||
|
for(var/m in player_list)
|
||||||
|
var/mob/M = m
|
||||||
|
var/client/C = M.client
|
||||||
|
if(C.is_preference_enabled(/datum/client_preference/play_admin_midis))
|
||||||
|
if(!stop_web_sounds)
|
||||||
|
C.tgui_panel?.play_music(web_sound_url, music_extra_data)
|
||||||
|
else
|
||||||
|
C.tgui_panel?.stop_music()
|
||||||
|
|
||||||
|
S_TIMER_COOLDOWN_START(SStimer, COOLDOWN_INTERNET_SOUND, duration)
|
||||||
|
|
||||||
|
feedback_add_details("admin_verb", "Play Internet Sound")
|
||||||
|
|
||||||
|
/client/proc/play_web_sound()
|
||||||
|
set category = "Fun"
|
||||||
|
set name = "Play Internet Sound"
|
||||||
|
if(!check_rights(R_SOUNDS))
|
||||||
|
return
|
||||||
|
|
||||||
|
var/ytdl = config.invoke_youtubedl
|
||||||
|
if(!ytdl)
|
||||||
|
to_chat(src, "<span class='boldwarning'>Youtube-dl was not configured, action unavailable</span>", confidential = TRUE) //Check config.txt for the INVOKE_YOUTUBEDL value
|
||||||
|
return
|
||||||
|
|
||||||
|
if(S_TIMER_COOLDOWN_TIMELEFT(SStimer, COOLDOWN_INTERNET_SOUND))
|
||||||
|
if(tgui_alert(usr, "Someone else is already playing an Internet sound! It has [DisplayTimeText(S_TIMER_COOLDOWN_TIMELEFT(SStimer, COOLDOWN_INTERNET_SOUND), 1)] remaining. \
|
||||||
|
Would you like to override?", "Musicalis Interruptus", list("No","Yes")) != "Yes")
|
||||||
|
return
|
||||||
|
|
||||||
|
var/web_sound_input = tgui_input_text(usr, "Enter content URL (supported sites only, leave blank to stop playing)", "Play Internet Sound", null)
|
||||||
|
|
||||||
|
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 class='boldwarning'>Non-http(s) URIs are not allowed.</span>", confidential = TRUE)
|
||||||
|
to_chat(src, "<span class='warning'>For youtube-dl shortcuts like ytsearch: please use the appropriate full URL from the website.</span>", confidential = TRUE)
|
||||||
|
return
|
||||||
|
web_sound(usr, web_sound_input)
|
||||||
|
else
|
||||||
|
web_sound(usr, null)
|
||||||
|
|
||||||
|
/client/proc/stop_sounds()
|
||||||
|
set category = "Debug"
|
||||||
|
set name = "Stop All Playing Sounds"
|
||||||
|
if(!src.holder)
|
||||||
|
return
|
||||||
|
|
||||||
|
log_admin("[key_name(src)] stopped all currently playing sounds.")
|
||||||
|
message_admins("[key_name_admin(src)] stopped all currently playing sounds.")
|
||||||
|
for(var/mob/M in player_list)
|
||||||
|
SEND_SOUND(M, sound(null))
|
||||||
|
var/client/C = M.client
|
||||||
|
C?.tgui_panel?.stop_music()
|
||||||
|
|
||||||
|
S_TIMER_COOLDOWN_RESET(SStimer, COOLDOWN_INTERNET_SOUND)
|
||||||
|
feedback_add_details("admin_verb", "Stop All Playing Sounds")
|
||||||
|
|
||||||
|
//world/proc/shelleo
|
||||||
|
#undef SHELLEO_ERRORLEVEL
|
||||||
|
#undef SHELLEO_STDOUT
|
||||||
|
#undef SHELLEO_STDERR
|
||||||
|
|
||||||
/*
|
/*
|
||||||
/client/proc/cuban_pete()
|
/client/proc/cuban_pete()
|
||||||
|
|||||||
@@ -257,6 +257,14 @@ SERVER your.domain:6000
|
|||||||
## Ban appeals URL - usually for a forum or wherever people should go to contact your admins.
|
## Ban appeals URL - usually for a forum or wherever people should go to contact your admins.
|
||||||
#BANAPPEALS http://bans.your.domain/
|
#BANAPPEALS http://bans.your.domain/
|
||||||
|
|
||||||
|
## System command that invokes yt-dlp, used by Play Internet Sound.
|
||||||
|
## You can install yt-dlp with
|
||||||
|
## "pip install yt-dlp" if you have pip installed
|
||||||
|
## from https://github.com/yt-dlp/yt-dlp
|
||||||
|
## or your package manager
|
||||||
|
## The default value assumes yt-dlp is in your system PATH
|
||||||
|
# INVOKE_YOUTUBEDL yt-dlp
|
||||||
|
|
||||||
## In-game features
|
## In-game features
|
||||||
## spawns a spellbook which gives object-type spells instead of verb-type spells for the wizard
|
## spawns a spellbook which gives object-type spells instead of verb-type spells for the wizard
|
||||||
# FEATURE_OBJECT_SPELL_SYSTEM
|
# FEATURE_OBJECT_SPELL_SYSTEM
|
||||||
|
|||||||
@@ -153,6 +153,7 @@
|
|||||||
#include "code\_helpers\mobs.dm"
|
#include "code\_helpers\mobs.dm"
|
||||||
#include "code\_helpers\names.dm"
|
#include "code\_helpers\names.dm"
|
||||||
#include "code\_helpers\sanitize_values.dm"
|
#include "code\_helpers\sanitize_values.dm"
|
||||||
|
#include "code\_helpers\shell.dm"
|
||||||
#include "code\_helpers\storage.dm"
|
#include "code\_helpers\storage.dm"
|
||||||
#include "code\_helpers\string_lists.dm"
|
#include "code\_helpers\string_lists.dm"
|
||||||
#include "code\_helpers\text.dm"
|
#include "code\_helpers\text.dm"
|
||||||
|
|||||||
Reference in New Issue
Block a user