Browse Source

Refactor guild availability legacy cruft

pull/10109/head
dolfies 2 years ago
parent
commit
663033839f
  1. 5
      discord/enums.py
  2. 65
      discord/state.py

5
discord/enums.py

@ -794,11 +794,6 @@ class RelationshipAction(Enum):
remove_pending_request = 'remove'
class UnavailableGuildType(Enum):
existing = 'ready'
joined = 'joined'
class RequiredActionType(Enum):
update_agreements = 'AGREEMENTS'
acknowledge_tos_update = 'TOS_UPDATE_ACKNOWLEDGMENT'

65
discord/state.py

@ -72,7 +72,6 @@ from .enums import (
RequiredActionType,
Status,
try_enum,
UnavailableGuildType,
)
from . import utils
from .flags import MemberCacheFlags
@ -607,8 +606,6 @@ class ConnectionState:
self._emojis: Dict[int, Emoji] = {}
self._stickers: Dict[int, GuildSticker] = {}
self._guilds: Dict[int, Guild] = {}
self._queued_guilds: Dict[int, Guild] = {}
self._unavailable_guilds: Dict[int, UnavailableGuildType] = {}
self._calls: Dict[int, Call] = {}
self._call_message_cache: Dict[int, Message] = {} # Hopefully this won't be a memory leak
@ -774,10 +771,7 @@ class ConnectionState:
def _get_guild(self, guild_id: Optional[int]) -> Optional[Guild]:
# The keys of self._guilds are ints
guild = self._guilds.get(guild_id) # type: ignore
if guild is None:
guild = self._queued_guilds.get(guild_id) # type: ignore
return guild
return self._guilds.get(guild_id) # type: ignore
def _get_or_create_unavailable_guild(self, guild_id: int) -> Guild:
return self._guilds.get(guild_id) or Guild._create_unavailable(state=self, guild_id=guild_id)
@ -857,21 +851,13 @@ class ConnectionState:
else utils.find(lambda m: m.id == msg_id, reversed(self._call_message_cache.values()))
)
def _add_guild_from_data(self, data: GuildPayload, *, from_ready: bool = False) -> Optional[Guild]:
guild_id = int(data['id'])
unavailable = data.get('unavailable', False)
if not unavailable:
guild = Guild(data=data, state=self)
self._add_guild(guild)
return guild
else:
self._unavailable_guilds[guild_id] = UnavailableGuildType.existing if from_ready else UnavailableGuildType.joined
_log.debug('Forcing GUILD_CREATE for unavailable guild %s.' % guild_id)
asyncio.ensure_future(self.request_guild(guild_id), loop=self.loop)
def _add_guild_from_data(self, data: GuildPayload) -> Optional[Guild]:
guild = Guild(data=data, state=self)
self._add_guild(guild)
return guild
def _guild_needs_chunking(self, guild: Guild) -> bool:
return self._chunk_guilds and not guild.chunked and not guild._offline_members_hidden
return self._chunk_guilds and not guild.chunked and not guild._offline_members_hidden and not guild.unavailable
def _get_guild_channel(
self, data: PartialMessagePayload, guild_id: Optional[int] = None
@ -1010,7 +996,7 @@ class ConnectionState:
# Guild parsing
for guild_data in data.get('guilds', []):
self._add_guild_from_data(guild_data, from_ready=True)
self._add_guild_from_data(guild_data)
# Relationship parsing
for relationship in data.get('relationships', []):
@ -1083,6 +1069,7 @@ class ConnectionState:
if 'last_pin_timestamp' in channel_data and hasattr(channel, 'last_pin_timestamp'):
channel.last_pin_timestamp = utils.parse_time(channel_data['last_pin_timestamp']) # type: ignore
# Apparently, voice states not being in the payload means there are no longer any voice states
guild._voice_states = {}
members = {int(m['user']['id']): m for m in data.get('members', [])}
for voice_state in data.get('voice_states', []):
@ -1093,10 +1080,7 @@ class ConnectionState:
guild._update_voice_state(voice_state, utils._get_as_snowflake(voice_state, 'channel_id'))
def parse_message_create(self, data: gw.MessageCreateEvent) -> None:
guild_id = utils._get_as_snowflake(data, 'guild_id')
channel, _ = self._get_guild_channel(data)
if guild_id in self._unavailable_guilds: # I don't know how I feel about this :(
return
# channel will be the correct type here
message = Message(channel=channel, data=data, state=self) # type: ignore
@ -1685,8 +1669,6 @@ class ConnectionState:
for message in data.get('most_recent_messages', []):
guild_id = utils._get_as_snowflake(message, 'guild_id')
channel, _ = self._get_guild_channel(message)
if guild_id in self._unavailable_guilds: # I don't know how I feel about this :(
continue
# channel will be the correct type here
message = Message(channel=channel, data=message, state=self)
@ -2070,15 +2052,19 @@ class ConnectionState:
execution = AutoModAction(data=data, state=self)
self.dispatch('automod_action', execution)
def _get_create_guild(self, data: gw.GuildCreateEvent):
def _get_create_guild(self, data: gw.GuildCreateEvent) -> Optional[Guild]:
guild = self._get_guild(int(data['id']))
unavailable = data.get('unavailable')
# Discord being Discord sometimes sends a GUILD_CREATE after an OPCode 14 is sent (a la bots)
# However, we want that if we forced a GUILD_CREATE for an unavailable guild
# In this case, we just update it and return None to avoid a double dispatch
# However, if the guild became available, then we gotta go through the motions
if guild is not None:
guild._from_data(data)
return
if unavailable != False:
return
return self._add_guild_from_data(data)
return guild or self._add_guild_from_data(data)
def is_guild_evicted(self, guild: Guild) -> bool:
return guild.id not in self._guilds
@ -2212,9 +2198,7 @@ class ConnectionState:
return await request.wait()
return request.get_future()
async def _chunk_and_dispatch(self, guild, chunk) -> None:
self._queued_guilds[guild.id] = guild
async def _chunk_and_dispatch(self, guild: Guild, chunk: bool, unavailable: Optional[bool]) -> None:
if chunk:
try:
await asyncio.wait_for(self.chunk_guild(guild), timeout=10)
@ -2223,15 +2207,8 @@ class ConnectionState:
except (ClientException, InvalidData):
pass
self._queued_guilds.pop(guild.id)
# Dispatch available/join depending on circumstances
if guild.id in self._unavailable_guilds:
type = self._unavailable_guilds.pop(guild.id)
if type is UnavailableGuildType.existing:
self.dispatch('guild_available', guild)
else:
self.dispatch('guild_join', guild)
if unavailable is False:
self.dispatch('guild_available', guild)
else:
self.dispatch('guild_join', guild)
@ -2243,12 +2220,12 @@ class ConnectionState:
if guild is None:
return
if self._request_guilds:
if self._request_guilds and not guild.unavailable:
asyncio.ensure_future(self.request_guild(guild.id), loop=self.loop)
# Chunk if needed
needs_chunking = self._guild_needs_chunking(guild)
asyncio.ensure_future(self._chunk_and_dispatch(guild, needs_chunking), loop=self.loop)
asyncio.ensure_future(self._chunk_and_dispatch(guild, needs_chunking, data.get('unavailable')), loop=self.loop)
def parse_guild_update(self, data: gw.GuildUpdateEvent) -> None:
guild = self._get_guild(int(data['id']))

Loading…
Cancel
Save