Implement VoiceProtocol lower level hooks.

This allows changing the connect flow and taking control of it without
relying on internal events or tricks.
This commit is contained in:
Rapptz
2020-08-10 06:28:36 -04:00
parent 93fa46713a
commit 0b93fa3a82
9 changed files with 230 additions and 106 deletions

View File

@@ -36,7 +36,7 @@ from .permissions import PermissionOverwrite, Permissions
from .role import Role
from .invite import Invite
from .file import File
from .voice_client import VoiceClient
from .voice_client import VoiceClient, VoiceProtocol
from . import utils
class _Undefined:
@@ -1053,7 +1053,6 @@ class Messageable(metaclass=abc.ABCMeta):
"""
return HistoryIterator(self, limit=limit, before=before, after=after, around=around, oldest_first=oldest_first)
class Connectable(metaclass=abc.ABCMeta):
"""An ABC that details the common operations on a channel that can
connect to a voice server.
@@ -1072,7 +1071,7 @@ class Connectable(metaclass=abc.ABCMeta):
def _get_voice_state_pair(self):
raise NotImplementedError
async def connect(self, *, timeout=60.0, reconnect=True):
async def connect(self, *, timeout=60.0, reconnect=True, cls=VoiceClient):
"""|coro|
Connects to voice and creates a :class:`VoiceClient` to establish
@@ -1086,6 +1085,9 @@ class Connectable(metaclass=abc.ABCMeta):
Whether the bot should automatically attempt
a reconnect if a part of the handshake fails
or the gateway goes down.
cls: Type[:class:`VoiceProtocol`]
A type that subclasses :class:`~discord.VoiceProtocol` to connect with.
Defaults to :class:`~discord.VoiceClient`.
Raises
-------
@@ -1098,20 +1100,25 @@ class Connectable(metaclass=abc.ABCMeta):
Returns
--------
:class:`~discord.VoiceClient`
:class:`~discord.VoiceProtocol`
A voice client that is fully connected to the voice server.
"""
if not issubclass(cls, VoiceProtocol):
raise TypeError('Type must meet VoiceProtocol abstract base class.')
key_id, _ = self._get_voice_client_key()
state = self._state
if state._get_voice_client(key_id):
raise ClientException('Already connected to a voice channel.')
voice = VoiceClient(state=state, timeout=timeout, channel=self)
client = state._get_client()
voice = cls(client, self)
state._add_voice_client(key_id, voice)
try:
await voice.connect(reconnect=reconnect)
await voice.connect(timeout=timeout, reconnect=reconnect)
except asyncio.TimeoutError:
try:
await voice.disconnect(force=True)