From e1aaf74fa7d46897f9eb32e4b52d3db88609a6c4 Mon Sep 17 00:00:00 2001 From: Rapptz Date: Mon, 23 Jan 2017 07:07:42 -0500 Subject: Add option to disable auto member chunking. --- discord/client.py | 92 ++++++++++++++++++++++++++++++++----------------------- 1 file changed, 53 insertions(+), 39 deletions(-) (limited to 'discord/client.py') diff --git a/discord/client.py b/discord/client.py index 25408b7f..c9ada5df 100644 --- a/discord/client.py +++ b/discord/client.py @@ -96,6 +96,11 @@ class Client: Integer starting at 0 and less than shard_count. shard_count : Optional[int] The total number of shards. + fetch_offline_members: bool + Indicates if :func:`on_ready` should be delayed to fetch all offline + members from the guilds the bot belongs to. If this is ``False``\, then + no offline members are received and :meth:`request_offline_members` + must be used to fetch the offline members of the guild. Attributes ----------- @@ -120,7 +125,6 @@ class Client: The websocket gateway the client is currently connected to. Could be None. loop The `event loop`_ that the client uses for HTTP requests and websocket operations. - """ def __init__(self, *, loop=None, **options): self.ws = None @@ -133,7 +137,7 @@ class Client: connector = options.pop('connector', None) self.http = HTTPClient(connector, loop=self.loop) - self.connection = ConnectionState(dispatch=self.dispatch, chunker=self.request_offline_members, + self.connection = ConnectionState(dispatch=self.dispatch, chunker=self._chunker, syncer=self._syncer, http=self.http, loop=self.loop, **options) self.connection.shard_count = self.shard_count @@ -151,6 +155,24 @@ class Client: def _syncer(self, guilds): yield from self.ws.request_sync(guilds) + @asyncio.coroutine + def _chunker(self, guild): + if hasattr(guild, 'id'): + guild_id = guild.id + else: + guild_id = [s.id for s in guild] + + payload = { + 'op': 8, + 'd': { + 'guild_id': guild_id, + 'query': '', + 'limit': 0 + } + } + + yield from self.ws.send_as_json(payload) + def handle_reaction_add(self, reaction, user): removed = [] for i, (condition, future, event_type) in enumerate(self._listeners): @@ -261,6 +283,35 @@ class Client: print('Ignoring exception in {}'.format(event_method), file=sys.stderr) traceback.print_exc() + @asyncio.coroutine + def request_offline_members(self, *guilds): + """|coro| + + Requests previously offline members from the guild to be filled up + into the :attr:`Guild.members` cache. This function is usually not + called. It should only be used if you have the ``fetch_offline_members`` + parameter set to ``False``. + + When the client logs on and connects to the websocket, Discord does + not provide the library with offline members if the number of members + in the guild is larger than 250. You can check if a guild is large + if :attr:`Guild.large` is ``True``. + + Parameters + ----------- + \*guilds + An argument list of guilds to request offline members for. + + Raises + ------- + InvalidArgument + If any guild is unavailable or not large in the collection. + """ + if any(not g.large or g.unavailable for g in guilds): + raise InvalidArgument('An unavailable or non-large guild was passed.') + + yield from self.connection.request_offline_members(guilds) + # login state management @asyncio.coroutine @@ -777,43 +828,6 @@ class Client: return self.event(coro) - @asyncio.coroutine - def request_offline_members(self, guild): - """|coro| - - Requests previously offline members from the guild to be filled up - into the :attr:`Guild.members` cache. This function is usually not - called. - - When the client logs on and connects to the websocket, Discord does - not provide the library with offline members if the number of members - in the guild is larger than 250. You can check if a guild is large - if :attr:`Guild.large` is ``True``. - - Parameters - ----------- - guild : :class:`Guild` or iterable - The guild to request offline members for. If this parameter is a - iterable then it is interpreted as an iterator of guilds to - request offline members for. - """ - - if hasattr(guild, 'id'): - guild_id = guild.id - else: - guild_id = [s.id for s in guild] - - payload = { - 'op': 8, - 'd': { - 'guild_id': guild_id, - 'query': '', - 'limit': 0 - } - } - - yield from self.ws.send_as_json(payload) - @asyncio.coroutine def change_presence(self, *, game=None, status=None, afk=False): """|coro| -- cgit v1.2.3