Fix song counter and inconsistent queue state
This commit is contained in:
2 files changed
+44
-6
No files matched your search
@@ -25,15 +25,36 @@ class MusicPlayerQueueTest(unittest.IsolatedAsyncioTestCase):
|
||||
self.assertIs(voice_client.playing, track)
|
||||
self.assertEqual(player.state(GUILD).index, 0)
|
||||
|
||||
async def test_single_play_budget_drops_track_from_queue(self):
|
||||
async def test_last_play_remains_pointed_to_until_playback_finishes(self):
|
||||
player, _ = build_player(default_plays=1)
|
||||
track = FakeTrack("a")
|
||||
await player.enqueue(GUILD, track)
|
||||
|
||||
state = player.state(GUILD)
|
||||
self.assertEqual(state.queue, [track])
|
||||
self.assertEqual(state.index, 0)
|
||||
self.assertIs(state.current, track)
|
||||
|
||||
await player.play_next(GUILD, advance=True)
|
||||
|
||||
self.assertEqual(state.queue, [])
|
||||
self.assertEqual(state.index, -1)
|
||||
self.assertIs(state.current, track)
|
||||
self.assertIsNone(state.current)
|
||||
|
||||
async def test_last_play_of_recreated_track_is_removed_after_callback(self):
|
||||
player, _, state = await self._queue_abc(default_plays=2)
|
||||
state.loop_mode = LoopMode.TRACK
|
||||
|
||||
await player.play_next(GUILD, advance=True)
|
||||
self.assertEqual([track.id for track in state.queue], ["a", "b", "c"])
|
||||
self.assertEqual(state.index, 0)
|
||||
self.assertEqual(state.current.plays_left, 0)
|
||||
|
||||
await player.play_next(GUILD, advance=True)
|
||||
|
||||
self.assertEqual([track.id for track in state.queue], ["b", "c"])
|
||||
self.assertEqual(state.index, 0)
|
||||
self.assertEqual(state.current.id, "b")
|
||||
|
||||
async def test_enqueue_while_playing_only_appends(self):
|
||||
_, _, state = await self._queue_abc()
|
||||
|
||||
@@ -189,11 +189,29 @@ class MusicPlayer:
|
||||
if state.consume_jump():
|
||||
advance = False
|
||||
|
||||
# Utwór z ostatnim odtworzeniem musi pozostać w kolejce do chwili
|
||||
# zakończenia źródła. W przeciwnym razie panel dostaje `current`, ale
|
||||
# `queue_index` wskazuje pozycję spoza kolejki podczas faktycznego
|
||||
# odtwarzania ostatniej kopii.
|
||||
retired_index: int | None = None
|
||||
if advance and state.current is not None and 0 <= state.index < len(state.queue):
|
||||
current = state.queue[state.index]
|
||||
if current is state.current and self.plays_left(current) <= 0:
|
||||
retired_index = state.index
|
||||
state.queue.pop(state.index)
|
||||
state.index -= 1
|
||||
|
||||
if not state.queue:
|
||||
state.index = -1
|
||||
state.current = None
|
||||
await self.trigger_state_change()
|
||||
return
|
||||
|
||||
if retired_index is not None:
|
||||
next_index = retired_index
|
||||
if state.loop_mode.loops_queue:
|
||||
next_index %= len(state.queue)
|
||||
else:
|
||||
next_index = self._next_index(state, advance=advance)
|
||||
if next_index >= len(state.queue):
|
||||
state.index = next_index
|
||||
@@ -220,13 +238,12 @@ class MusicPlayer:
|
||||
track.plays_left = self.plays_left(track) - 1
|
||||
track.volume = state.volume
|
||||
|
||||
state.queue[next_index] = track
|
||||
if track.plays_left <= 0:
|
||||
state.queue.pop(next_index)
|
||||
state.index = next_index - 1
|
||||
# Usunięcie nastąpi dopiero po callbacku discord.py, po tym jak
|
||||
# ostatnie odtworzenie rzeczywiście się zakończy.
|
||||
if state.loop_mode.loops_track:
|
||||
state.loop_mode = LoopMode.OFF
|
||||
else:
|
||||
state.queue[next_index] = track
|
||||
|
||||
state.current = track
|
||||
self._record_history(guild_id, track)
|
||||
|
||||
Reference in new issue
Block a user