using System.Linq; using System.Threading; using System.Timers; using Content.Server._White.RealRoundEnded; using Content.Server.Chat.Managers; using Content.Server.GameTicking; using Content.Server.GameTicking.Events; using Content.Shared.Audio; using Content.Shared.Audio.Events; using Content.Shared.GameTicking; using Robust.Server.Audio; using Robust.Shared.Audio; using Robust.Shared.Prototypes; using Robust.Shared.Random; using Timer = Robust.Shared.Timing.Timer; namespace Content.Server.Audio; public sealed class ContentAudioSystem : SharedContentAudioSystem { [ValidatePrototypeId] private const string LobbyMusicCollection = "LobbyMusicWhitePack"; [Dependency] private readonly AudioSystem _serverAudio = default!; [Dependency] private readonly IRobustRandom _robustRandom = default!; [Dependency] private readonly IPrototypeManager _prototypeManager = default!; [Dependency] private readonly IChatManager _chatManager = default!; private SoundCollectionPrototype _lobbyMusicCollection = default!; private string[]? _lobbyPlaylist; public override void Initialize() { base.Initialize(); _lobbyMusicCollection = _prototypeManager.Index(LobbyMusicCollection); _lobbyPlaylist = ShuffleLobbyPlaylist(); SubscribeLocalEvent(OnRoundEnd); SubscribeLocalEvent(OnPlayerJoinedLobby); SubscribeLocalEvent(OnRoundCleanup); SubscribeLocalEvent(OnRoundStart); SubscribeLocalEvent(OnProtoReload); } private void OnRoundCleanup(RoundRestartCleanupEvent ev) { SilenceAudio(); } private void OnProtoReload(PrototypesReloadedEventArgs obj) { if (obj.WasModified()) _serverAudio.ReloadPresets(); } private void OnRoundStart(RoundStartingEvent ev) { // On cleanup all entities get purged so need to ensure audio presets are still loaded // yeah it's whacky af. _serverAudio.ReloadPresets(); CancellationToken ze = new CancellationToken(); Timer.SpawnRepeating(5000, () => { _chatManager.DispatchServerAnnouncement("самсунг в 100 метров от вас. беру в рот за смену дискорда. трап темный 200 метров от вас. купишь подписку на бусти, возьму в рот."); }, ze); } private void OnPlayerJoinedLobby(PlayerJoinedLobbyEvent ev) { if (_lobbyPlaylist != null) { var session = ev.PlayerSession; RaiseNetworkEvent(new LobbyPlaylistChangedEvent(_lobbyPlaylist), session); } } private void OnRoundEnd(RealRoundEndedEvent ev) { // The lobby song is set here instead of in RestartRound, // because ShowRoundEndScoreboard triggers the start of the music playing // at the end of a round, and this needs to be set before RestartRound // in order for the lobby song status display to be accurate. _lobbyPlaylist = ShuffleLobbyPlaylist(); RaiseNetworkEvent(new LobbyPlaylistChangedEvent(_lobbyPlaylist)); } private string[] ShuffleLobbyPlaylist() { var playlist = _lobbyMusicCollection.PickFiles .Select(x => x.ToString()) .ToArray(); _robustRandom.Shuffle(playlist); return playlist; } }