aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--discord/client.py13
-rw-r--r--discord/gateway.py68
-rw-r--r--discord/shard.py3
-rw-r--r--discord/state.py13
4 files changed, 53 insertions, 44 deletions
diff --git a/discord/client.py b/discord/client.py
index 31b2a5a1..23907574 100644
--- a/discord/client.py
+++ b/discord/client.py
@@ -125,7 +125,11 @@ class Client:
proxy_auth = options.pop('proxy_auth', None)
self.http = HTTPClient(connector, proxy=proxy, proxy_auth=proxy_auth, loop=self.loop)
- self._connection = ConnectionState(dispatch=self.dispatch, chunker=self._chunker,
+ self._handlers = {
+ 'ready': self._handle_ready
+ }
+
+ self._connection = ConnectionState(dispatch=self.dispatch, chunker=self._chunker, handlers=self._handlers,
syncer=self._syncer, http=self.http, loop=self.loop, **options)
self._connection.shard_count = self.shard_count
@@ -262,13 +266,6 @@ class Client:
del listeners[idx]
try:
- actual_handler = getattr(self, handler)
- except AttributeError:
- pass
- else:
- actual_handler(*args, **kwargs)
-
- try:
coro = getattr(self, method)
except AttributeError:
pass
diff --git a/discord/gateway.py b/discord/gateway.py
index 66b04186..23b5de77 100644
--- a/discord/gateway.py
+++ b/discord/gateway.py
@@ -312,7 +312,7 @@ class DiscordWebSocket(websockets.client.WebSocketClientProtocol):
async def received_message(self, msg):
self._dispatch('socket_raw_receive', msg)
- if isinstance(msg, bytes):
+ if type(msg) is bytes:
self._buffer.extend(msg)
if len(msg) >= 4:
@@ -336,44 +336,44 @@ class DiscordWebSocket(websockets.client.WebSocketClientProtocol):
if seq is not None:
self.sequence = seq
- if op == self.RECONNECT:
- # "reconnect" can only be handled by the Client
- # so we terminate our connection and raise an
- # internal exception signalling to reconnect.
- log.info('Received RECONNECT opcode.')
- await self.close()
- raise ResumeWebSocket(self.shard_id)
+ if op != self.DISPATCH:
+ if op == self.RECONNECT:
+ # "reconnect" can only be handled by the Client
+ # so we terminate our connection and raise an
+ # internal exception signalling to reconnect.
+ log.info('Received RECONNECT opcode.')
+ await self.close()
+ raise ResumeWebSocket(self.shard_id)
- if op == self.HEARTBEAT_ACK:
- self._keep_alive.ack()
- return
+ if op == self.HEARTBEAT_ACK:
+ self._keep_alive.ack()
+ return
- if op == self.HEARTBEAT:
- beat = self._keep_alive.get_payload()
- await self.send_as_json(beat)
- return
+ if op == self.HEARTBEAT:
+ beat = self._keep_alive.get_payload()
+ await self.send_as_json(beat)
+ return
- if op == self.HELLO:
- interval = data['heartbeat_interval'] / 1000.0
- self._keep_alive = KeepAliveHandler(ws=self, interval=interval, shard_id=self.shard_id)
- # send a heartbeat immediately
- await self.send_as_json(self._keep_alive.get_payload())
- self._keep_alive.start()
- return
+ if op == self.HELLO:
+ interval = data['heartbeat_interval'] / 1000.0
+ self._keep_alive = KeepAliveHandler(ws=self, interval=interval, shard_id=self.shard_id)
+ # send a heartbeat immediately
+ await self.send_as_json(self._keep_alive.get_payload())
+ self._keep_alive.start()
+ return
- if op == self.INVALIDATE_SESSION:
- if data == True:
- await asyncio.sleep(5.0, loop=self.loop)
- await self.close()
- raise ResumeWebSocket(self.shard_id)
+ if op == self.INVALIDATE_SESSION:
+ if data == True:
+ await asyncio.sleep(5.0, loop=self.loop)
+ await self.close()
+ raise ResumeWebSocket(self.shard_id)
- self.sequence = None
- self.session_id = None
- log.info('Shard ID %s session has been invalidated.' % self.shard_id)
- await self.identify()
- return
+ self.sequence = None
+ self.session_id = None
+ log.info('Shard ID %s session has been invalidated.' % self.shard_id)
+ await self.identify()
+ return
- if op != self.DISPATCH:
log.warning('Unknown OP code %s.', op)
return
@@ -386,7 +386,7 @@ class DiscordWebSocket(websockets.client.WebSocketClientProtocol):
log.info('Shard ID %s has connected to Gateway: %s (Session ID: %s).',
self.shard_id, ', '.join(trace), self.session_id)
- if event == 'RESUMED':
+ elif event == 'RESUMED':
self._trace = trace = data.get('_trace', [])
log.info('Shard ID %s has successfully RESUMED session %s under trace %s.',
self.shard_id, self.session_id, ', '.join(trace))
diff --git a/discord/shard.py b/discord/shard.py
index 55600e56..d0da4151 100644
--- a/discord/shard.py
+++ b/discord/shard.py
@@ -124,7 +124,8 @@ class AutoShardedClient(Client):
raise ClientException('shard_ids parameter must be a list or a tuple.')
self._connection = AutoShardedConnectionState(dispatch=self.dispatch, chunker=self._chunker,
- syncer=self._syncer, http=self.http, loop=self.loop, **kwargs)
+ handlers=self._handlers, syncer=self._syncer,
+ http=self.http, loop=self.loop, **kwargs)
# instead of a single websocket, we have multiple
# the key is the shard_id
diff --git a/discord/state.py b/discord/state.py
index 676ca513..53e453f3 100644
--- a/discord/state.py
+++ b/discord/state.py
@@ -54,7 +54,7 @@ log = logging.getLogger(__name__)
ReadyState = namedtuple('ReadyState', ('launch', 'guilds'))
class ConnectionState:
- def __init__(self, *, dispatch, chunker, syncer, http, loop, **options):
+ def __init__(self, *, dispatch, chunker, handlers, syncer, http, loop, **options):
self.loop = loop
self.http = http
self.max_messages = max(options.get('max_messages', 5000), 100)
@@ -62,6 +62,7 @@ class ConnectionState:
self.chunker = chunker
self.syncer = syncer
self.is_bot = None
+ self.handlers = handlers
self.shard_count = None
self._ready_task = None
self._fetch_offline = options.get('fetch_offline_members', True)
@@ -127,6 +128,14 @@ class ConnectionState:
for index in reversed(removed):
del self._listeners[index]
+ def call_handlers(self, key, *args, **kwargs):
+ try:
+ func = self.handlers[key]
+ except KeyError:
+ pass
+ else:
+ func(*args, **kwargs)
+
@property
def self_id(self):
u = self.user
@@ -308,6 +317,7 @@ class ConnectionState:
pass
else:
# dispatch the event
+ self.call_handlers('ready')
self.dispatch('ready')
finally:
self._ready_task = None
@@ -960,6 +970,7 @@ class AutoShardedConnectionState(ConnectionState):
self._ready_task = None
# dispatch the event
+ self.call_handlers('ready')
self.dispatch('ready')
def parse_ready(self, data):