@@ -159,6 +159,9 @@ def __init__(
159159 self ._auto_lock : asyncio .Lock = asyncio .Lock ()
160160 self ._error_count : int = 0
161161
162+ self ._inactive_channel_limit : int | None = self ._node ._inactive_channel_tokens
163+ self ._inactive_channel_count : int = self ._inactive_channel_limit if self ._inactive_channel_limit else 0
164+
162165 self ._filters : Filters = Filters ()
163166
164167 # Needed for the inactivity checks...
@@ -216,7 +219,21 @@ async def _track_start(self, payload: TrackStartEventPayload) -> None:
216219 self ._inactivity_cancel ()
217220
218221 async def _auto_play_event (self , payload : TrackEndEventPayload ) -> None :
219- if self ._autoplay is AutoPlayMode .disabled :
222+ if not self .channel :
223+ return
224+
225+ members : int = len ([m for m in self .channel .members if not m .bot ])
226+ self ._inactive_channel_count = (
227+ self ._inactive_channel_count - 1 if not members else self ._inactive_channel_limit or 0
228+ )
229+
230+ if self ._inactive_channel_limit and self ._inactive_channel_count <= 0 :
231+ self ._inactive_channel_count = self ._inactive_channel_limit # Reset...
232+
233+ self ._inactivity_cancel ()
234+ self .client .dispatch ("wavelink_inactive_player" , self )
235+
236+ elif self ._autoplay is AutoPlayMode .disabled :
220237 self ._inactivity_start ()
221238 return
222239
@@ -353,7 +370,7 @@ async def _search(query: str | None) -> T_a:
353370 return []
354371
355372 try :
356- search : wavelink .Search = await Pool .fetch_tracks (query )
373+ search : wavelink .Search = await Pool .fetch_tracks (query , node = self . _node )
357374 except (LavalinkLoadException , LavalinkException ):
358375 return []
359376
@@ -403,6 +420,49 @@ async def _search(query: str | None) -> T_a:
403420 logger .info ('Player "%s" could not load any songs via AutoPlay.' , self .guild .id )
404421 self ._inactivity_start ()
405422
423+ @property
424+ def inactive_channel_tokens (self ) -> int | None :
425+ """A settable property which returns the token limit as an ``int`` of the amount of tracks to play before firing
426+ the :func:`on_wavelink_inactive_player` event when a channel is inactive.
427+
428+ This property could return ``None`` if the check has been disabled.
429+
430+ A channel is considered inactive when no real members (Members other than bots) are in the connected voice
431+ channel. On each consecutive track played without a real member in the channel, this token bucket will reduce
432+ by ``1``. After hitting ``0``, the :func:`on_wavelink_inactive_player` event will be fired and the token bucket
433+ will reset to the set value. The default value for this property is ``3``.
434+
435+ This property can be set with any valid ``int`` or ``None``. If this property is set to ``<= 0`` or ``None``,
436+ the check will be disabled.
437+
438+ Setting this property to ``1`` will fire the :func:`on_wavelink_inactive_player` event at the end of every track
439+ if no real members are in the channel and you have not disconnected the player.
440+
441+ If this check successfully fires the :func:`on_wavelink_inactive_player` event, it will cancel any waiting
442+ :attr:`inactive_timeout` checks until a new track is played.
443+
444+ The default for every player can be set on :class:`~wavelink.Node`.
445+
446+ - See: :class:`~wavelink.Node`
447+ - See: :func:`on_wavelink_inactive_player`
448+
449+ .. warning::
450+
451+ Setting this property will reset the bucket.
452+
453+ .. versionadded:: 3.4.0
454+ """
455+ return self ._inactive_channel_limit
456+
457+ @inactive_channel_tokens .setter
458+ def inactive_channel_tokens (self , value : int | None ) -> None :
459+ if not value or value <= 0 :
460+ self ._inactive_channel_limit = None
461+ return
462+
463+ self ._inactive_channel_limit = value
464+ self ._inactive_channel_count = value
465+
406466 @property
407467 def inactive_timeout (self ) -> int | None :
408468 """A property which returns the time as an ``int`` of seconds to wait before this player dispatches the
@@ -616,14 +676,11 @@ async def _dispatch_voice_update(self) -> None:
616676 assert self .guild is not None
617677 data : VoiceState = self ._voice_state ["voice" ]
618678
619- try :
620- session_id : str = data ["session_id" ]
621- token : str = data ["token" ]
622- except KeyError :
623- return
624-
679+ session_id : str | None = data .get ("session_id" , None )
680+ token : str | None = data .get ("token" , None )
625681 endpoint : str | None = data .get ("endpoint" , None )
626- if not endpoint :
682+
683+ if not session_id or not token or not endpoint :
627684 return
628685
629686 request : RequestPayload = {"voice" : {"sessionId" : session_id , "token" : token , "endpoint" : endpoint }}
0 commit comments