aboutsummaryrefslogtreecommitdiff
path: root/discord/state.py
diff options
context:
space:
mode:
authorRapptz <[email protected]>2020-09-14 02:52:53 -0400
committerRapptz <[email protected]>2020-09-23 03:21:20 -0400
commit23ae084b8cb3bb5c9d815b791c1a94b0cf53e516 (patch)
tree2b50eb9d05bf3bb1d06d2d78d52fdca276e76e14 /discord/state.py
parentRaise if member intent is not enabled (diff)
downloaddiscord.py-23ae084b8cb3bb5c9d815b791c1a94b0cf53e516.tar.xz
discord.py-23ae084b8cb3bb5c9d815b791c1a94b0cf53e516.zip
Allow finer grained control over the member cache.
Diffstat (limited to 'discord/state.py')
-rw-r--r--discord/state.py33
1 files changed, 27 insertions, 6 deletions
diff --git a/discord/state.py b/discord/state.py
index ad491197..39190f1e 100644
--- a/discord/state.py
+++ b/discord/state.py
@@ -51,7 +51,7 @@ from .member import Member
from .role import Role
from .enums import ChannelType, try_enum, Status
from . import utils
-from .flags import Intents
+from .flags import Intents, MemberCacheFlags
from .embeds import Embed
from .object import Object
from .invite import Invite
@@ -116,8 +116,6 @@ class ConnectionState:
raise TypeError('allowed_mentions parameter must be AllowedMentions')
self.allowed_mentions = allowed_mentions
- # Only disable cache if both fetch_offline and guild_subscriptions are off.
- self._cache_members = (self._fetch_offline or self.guild_subscriptions)
self._chunk_requests = []
activity = options.get('activity', None)
@@ -142,6 +140,16 @@ class ConnectionState:
if not intents.members and self._fetch_offline:
raise ValueError('Intents.members has be enabled to fetch offline members.')
+ cache_flags = options.get('member_cache_flags', None)
+ if cache_flags is None:
+ cache_flags = MemberCacheFlags.all()
+ else:
+ if not isinstance(cache_flags, MemberCacheFlags):
+ raise TypeError('member_cache_flags parameter must be MemberCacheFlags not %r' % type(cache_flags))
+
+ cache_flags._verify_intents(intents)
+
+ self._member_cache_flags = cache_flags
self._activity = activity
self._status = status
self._intents = intents
@@ -564,6 +572,7 @@ class ConnectionState:
user = data['user']
member_id = int(user['id'])
member = guild.get_member(member_id)
+ flags = self._member_cache_flags
if member is None:
if 'username' not in user:
# sometimes we receive 'incomplete' member data post-removal.
@@ -571,13 +580,17 @@ class ConnectionState:
return
member, old_member = Member._from_presence_update(guild=guild, data=data, state=self)
- guild._add_member(member)
+ if flags.online or (flags._online_only and member.raw_status != 'offline'):
+ guild._add_member(member)
else:
old_member = Member._copy(member)
user_update = member._presence_update(data=data, user=user)
if user_update:
self.dispatch('user_update', user_update[0], user_update[1])
+ if flags._online_only and member.raw_status == 'offline':
+ guild._remove_member(member)
+
self.dispatch('member_update', old_member, member)
def parse_user_update(self, data):
@@ -697,7 +710,7 @@ class ConnectionState:
return
member = Member(guild=guild, data=data, state=self)
- if self._cache_members:
+ if self._member_cache_flags.joined:
guild._add_member(member)
guild._member_count += 1
self.dispatch('member_join', member)
@@ -760,7 +773,7 @@ class ConnectionState:
return self._add_guild_from_data(data)
async def chunk_guild(self, guild, *, wait=True, cache=None):
- cache = cache or self._cache_members
+ cache = cache or self._member_cache_flags.joined
future = self.loop.create_future()
request = ChunkRequest(guild.id, future, self._get_guild, cache=cache)
self._chunk_requests.append(request)
@@ -926,6 +939,7 @@ class ConnectionState:
def parse_voice_state_update(self, data):
guild = self._get_guild(utils._get_as_snowflake(data, 'guild_id'))
channel_id = utils._get_as_snowflake(data, 'channel_id')
+ flags = self._member_cache_flags
if guild is not None:
if int(data['user_id']) == self.user.id:
voice = self._get_voice_client(guild.id)
@@ -935,6 +949,13 @@ class ConnectionState:
member, before, after = guild._update_voice_state(data, channel_id)
if member is not None:
+ if flags.voice:
+ if channel_id is None and flags.value == MemberCacheFlags.voice.flag:
+ # Only remove from cache iff we only have the voice flag enabled
+ guild._remove_member(member)
+ else:
+ guild._add_member(member)
+
self.dispatch('voice_state_update', member, before, after)
else:
log.debug('VOICE_STATE_UPDATE referencing an unknown member ID: %s. Discarding.', data['user_id'])