diff --git a/README.md b/README.md index 2ba9030..01f12db 100644 --- a/README.md +++ b/README.md @@ -48,3 +48,26 @@ In few: + +## Sound files verification checklist +Use this quick process when HUD/chat says a song is playing but no audio is heard: + +1. **Copy the exact path from server logs** + - Example from logs: `play sounds/my_sound_pack/gdzie.vsnd_c` + +2. **Check that this exact path exists inside your workshop addon/VPK** + - Path must match exactly (folder names and letter case). + - Linux servers are case-sensitive. + +3. **Verify config paths** + - Every `music_list[].path` must point to a `.vsnd_c` file that exists in the mounted addon. + +4. **Verify addon is mounted on the server** + - Ensure MultiAddonManager mounted your workshop addon and search path points to your addon VPK. + +5. **Verify client can receive/use the resource** + - Join with a real player (not only bots) and test after one full round end. + +6. **Cross-check plugin diagnostics** + - If you see `PlaySound: executing 'play ...'` but still no sound, issue is usually missing/wrong resource path in addon. + diff --git a/RoundEndSound.cs b/RoundEndSound.cs index 3370357..13509ac 100644 --- a/RoundEndSound.cs +++ b/RoundEndSound.cs @@ -16,7 +16,7 @@ namespace RoundEndSound public class RoundEndSound : BasePlugin, IPluginConfig { public override string ModuleName => "Round End Sound"; - public override string ModuleVersion => "1.0.2"; + public override string ModuleVersion => "1.0.3"; public override string ModuleAuthor => "gleb_khlebov"; public override string ModuleDescription => "Plays a sound at the end of the round"; @@ -125,6 +125,8 @@ public void OnConfigParsed(Config.Config config) _tracks = config.MusicList; _trackCount = _tracks.Count; Config = config; + + _logUtils.Log($"Configuration loaded. Tracks count: {_trackCount}, random mode: {Config.RandomSelectionMode}, default music enabled: {Config.DefaultEnableMusic}"); } [GameEventHandler] @@ -137,6 +139,8 @@ public HookResult OnPlayerConnectFull(EventPlayerConnectFull @event, GameEventIn if (_playerUtils.IsInvalidPlayer(player)) return HookResult.Continue; + _logUtils.Log($"Player connected: {player.PlayerName} ({player.SteamID})"); + ResPlayer resPlayer = new ResPlayer { SteamId = player.SteamID.ToString(), @@ -158,6 +162,8 @@ public HookResult OnPlayerDisconnect(EventPlayerDisconnect @event, GameEventInfo if (_playerUtils.IsInvalidPlayer(player)) return HookResult.Continue; + _logUtils.Log($"Player disconnected: {player.PlayerName} ({player.SteamID})"); + if (!_players.ContainsKey(steamId)) return HookResult.Continue; @@ -187,10 +193,16 @@ public HookResult OnServerShutdown(EventServerShutdown @event, GameEventInfo inf public HookResult OnRoundEnd(EventRoundEnd @event, GameEventInfo info) { if (_players.Count < 1) + { + _logUtils.Log("Round end: skipped because no players are tracked."); return HookResult.Continue; + } if (_trackCount < 1) + { + _logUtils.Log("Round end: skipped because music list is empty."); return HookResult.Continue; + } int trackIndex; Sound currentSound; @@ -226,6 +238,8 @@ public HookResult OnRoundEnd(EventRoundEnd @event, GameEventInfo info) PlaySound(player, currentSound); } + _logUtils.Log($"Round end: selected track [{trackIndex}] '{currentSound.Name}' ({currentSound.Path}) for {_players.Count} player(s)."); + _lastPlayedTrack = currentSound; return HookResult.Continue; @@ -234,20 +248,44 @@ public HookResult OnRoundEnd(EventRoundEnd @event, GameEventInfo info) private void PlaySound(ResPlayer? resPlayer, Sound sound) { CCSPlayerController? player = Utils.PlayerUtils.GetPlayerFromSteamId(resPlayer!.SteamId); + + if (player == null) + { + _logUtils.Log($"PlaySound: player with SteamID {resPlayer.SteamId} was not found on server."); + return; + } Server.NextFrame(() => { if (resPlayer.SoundEnabled) + { + _logUtils.Log($"PlaySound: executing 'play {sound.Path}' for {player.PlayerName} ({player.SteamID})."); player?.ExecuteClientCommand($"play {sound.Path}"); + } + else + { + _logUtils.Log($"PlaySound: sound disabled for {player.PlayerName} ({player.SteamID})."); + } + if (resPlayer.ChatEnabled) + { + _logUtils.Log($"PlaySound: sending chat notification for {player.PlayerName} ({player.SteamID}) about '{sound.Name}'."); player?.PrintToChat($"{Localizer["chat.Prefix"]}{Localizer["chat.PlayedSong", sound.Name]}{NewLine}{Localizer["chat.Settings"]}"); + } }); } private void PlayLastSound(CCSPlayerController player) { + if (_lastPlayedTrack == null) + { + _logUtils.Log($"PlayLastSound: requested by {player.PlayerName} ({player.SteamID}) but there is no previously played track."); + return; + } + Server.NextFrame(() => { + _logUtils.Log($"PlayLastSound: executing 'play {_lastPlayedTrack!.Path}' for {player.PlayerName} ({player.SteamID})."); player.ExecuteClientCommand($"play {_lastPlayedTrack!.Path}"); player.PrintToChat($"{Localizer["chat.Prefix"]}{Localizer["chat.PlayedSong", _lastPlayedTrack.Name]}{NewLine}{Localizer["chat.Settings"]}"); }); @@ -403,4 +441,4 @@ private string BoolStateToString(bool state) }; } } -} \ No newline at end of file +} diff --git a/RoundEndSound.csproj b/RoundEndSound.csproj new file mode 100644 index 0000000..8c37e15 --- /dev/null +++ b/RoundEndSound.csproj @@ -0,0 +1,22 @@ + + + net8.0 + enable + enable + latest + RoundEndSound + RoundEndSound + false + + + + + + + + + + + + + diff --git a/Utils/PlayerUtils.cs b/Utils/PlayerUtils.cs index c1d80ae..fa01ce8 100644 --- a/Utils/PlayerUtils.cs +++ b/Utils/PlayerUtils.cs @@ -34,6 +34,6 @@ public static List GetOnlinePlayers(bool getBots = false) public bool IsInvalidPlayer(CCSPlayerController player) { - return player is { IsBot: true, IsHLTV: true, IsValid: false }; + return !player.IsValid || player.IsBot || player.IsHLTV; } -} \ No newline at end of file +}