From c8a188647b38e22159d749d37863f1a6a47b3b51 Mon Sep 17 00:00:00 2001 From: lgoose Date: Fri, 21 Aug 2026 01:11:22 +0200 Subject: [PATCH] =?UTF-8?q?fix(music):=20zatrzymanie=20pomijania,=20gdy=20?= =?UTF-8?q?nie=20da=20si=C4=99=20odtworzy=C4=87=20=C5=BCadnego=20utworu?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Utwór, dla którego nie udało się zbudować świeżego źródła, był pomijany przez rekurencyjne wywołanie play_next(advance=True). Przy włączonym zapętlaniu kolejki - a przy zapętlaniu jednego utworu tym bardziej - kolejny indeks wskazywał znowu na utwór niedziałający, więc pomijanie kręciło się w kółko, zasypując kanał powiadomieniami. Licznik nieudanych prób wędruje teraz przez play_next. Po liczbie niepowodzeń równej długości kolejki odtwarzanie zatrzymuje się z jednym komunikatem zamiast pętli. Co-Authored-By: Claude Opus 5 --- zyrarbot/music/music_player.py | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/zyrarbot/music/music_player.py b/zyrarbot/music/music_player.py index c37e73f..c612e11 100644 --- a/zyrarbot/music/music_player.py +++ b/zyrarbot/music/music_player.py @@ -177,7 +177,8 @@ class MusicPlayer: # --- Odtwarzanie -------------------------------------------------------- - async def play_next(self, guild_id: int, advance: bool = True) -> None: + async def play_next(self, guild_id: int, advance: bool = True, _failures: int = 0) -> None: + """Przechodzi do kolejnego utworu; ``_failures`` chroni przed pętlą pomijania.""" state = self.state(guild_id) voice_client = self.voice_client(guild_id) if not voice_client: @@ -211,7 +212,7 @@ class MusicPlayer: await self.notify( guild_id, f"⚠️ Nie udało się odtworzyć: {track.title} ({error}). Pomijam." ) - await self.play_next(guild_id, advance=True) + await self._skip_failed(guild_id, _failures + 1) return track.played = True @@ -236,6 +237,18 @@ class MusicPlayer: embed = self._embeds.now_playing(track, position=next_index + 1, total=total) await self.notify(guild_id, embed=embed) + async def _skip_failed(self, guild_id: int, failures: int) -> None: + """Pomija niedziałający utwór, ale zatrzymuje się, gdy zawiodła cała kolejka.""" + state = self.state(guild_id) + if failures >= max(len(state.queue), 1): + state.current = None + await self.trigger_state_change() + await self.notify( + guild_id, "⛔ Nie udało się odtworzyć żadnego utworu z kolejki. Zatrzymuję." + ) + return + await self.play_next(guild_id, advance=True, _failures=failures) + def _next_index(self, state: GuildMusicState, *, advance: bool) -> int: index = state.index if state.index != -1 else 0