mirror of https://gitlab.com/litecord/litecord.git
gateway.websocket: various fixes to presence
- handle BadRequest instead of passing raise_err=False - handle status.activities - ready: call update_status BEFORE subscribing and dispatching_ready presence: - better presence object on guild_presences schema: - handle activities, change required to false in game
This commit is contained in:
parent
14d3149f50
commit
d242ef230a
|
|
@ -35,8 +35,8 @@ class EventDispatcher:
|
||||||
users = self.guild_buckets[guild_id]
|
users = self.guild_buckets[guild_id]
|
||||||
dispatched = 0
|
dispatched = 0
|
||||||
|
|
||||||
log.info('Dispatching {} {!r} to {} users',
|
log.debug('Dispatching {} {!r} to {} users',
|
||||||
guild_id, event_name, len(users))
|
guild_id, event_name, len(users))
|
||||||
|
|
||||||
for user_id in set(users):
|
for user_id in set(users):
|
||||||
# fetch all connections that are tied to the guild,
|
# fetch all connections that are tied to the guild,
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ from .errors import DecodeError, UnknownOPCode, \
|
||||||
InvalidShard, ShardingRequired
|
InvalidShard, ShardingRequired
|
||||||
from .opcodes import OP
|
from .opcodes import OP
|
||||||
from .state import GatewayState
|
from .state import GatewayState
|
||||||
|
from ..errors import BadRequest
|
||||||
|
|
||||||
from ..schemas import validate, GW_STATUS_UPDATE
|
from ..schemas import validate, GW_STATUS_UPDATE
|
||||||
|
|
||||||
|
|
@ -279,6 +280,7 @@ class GatewayWebsocket:
|
||||||
async def subscribe_guilds(self):
|
async def subscribe_guilds(self):
|
||||||
"""Subscribe to all available guilds"""
|
"""Subscribe to all available guilds"""
|
||||||
guild_ids = await self._guild_ids()
|
guild_ids = await self._guild_ids()
|
||||||
|
log.info('subscribing to {} guilds', len(guild_ids))
|
||||||
self.ext.dispatcher.sub_many(self.state.user_id, guild_ids)
|
self.ext.dispatcher.sub_many(self.state.user_id, guild_ids)
|
||||||
|
|
||||||
async def update_status(self, status: dict):
|
async def update_status(self, status: dict):
|
||||||
|
|
@ -296,13 +298,31 @@ class GatewayWebsocket:
|
||||||
|
|
||||||
self.state.presence = status
|
self.state.presence = status
|
||||||
|
|
||||||
status = validate(status, GW_STATUS_UPDATE, False)
|
try:
|
||||||
|
status = validate(status, GW_STATUS_UPDATE)
|
||||||
if not status:
|
except BadRequest as err:
|
||||||
# invalid status, must ignore
|
log.warning(f'Invalid payload: {err}')
|
||||||
return
|
return
|
||||||
|
|
||||||
|
# try to extract game from activities
|
||||||
|
# when game not provided
|
||||||
|
if not status.get('game'):
|
||||||
|
try:
|
||||||
|
game = status['activities'][0]
|
||||||
|
except (KeyError, IndexError):
|
||||||
|
game = None
|
||||||
|
|
||||||
|
# construct final status
|
||||||
|
status = {
|
||||||
|
'afk': status.get('afk', False),
|
||||||
|
'status': status.get('status', 'online'),
|
||||||
|
'game': game,
|
||||||
|
'since': status.get('since', 0),
|
||||||
|
}
|
||||||
|
|
||||||
self.state.presence = status
|
self.state.presence = status
|
||||||
|
log.info(f'Updating presence status={status["status"]} for '
|
||||||
|
f'uid={self.state.user_id}')
|
||||||
await self.ext.presence.dispatch_pres(self.state.user_id,
|
await self.ext.presence.dispatch_pres(self.state.user_id,
|
||||||
self.state.presence)
|
self.state.presence)
|
||||||
|
|
||||||
|
|
@ -350,11 +370,9 @@ class GatewayWebsocket:
|
||||||
await self._check_shards()
|
await self._check_shards()
|
||||||
|
|
||||||
self.ext.state_manager.insert(self.state)
|
self.ext.state_manager.insert(self.state)
|
||||||
await self.dispatch_ready()
|
|
||||||
await self.subscribe_guilds()
|
|
||||||
|
|
||||||
# dispatch presence only after subscribing
|
|
||||||
await self.update_status(presence)
|
await self.update_status(presence)
|
||||||
|
await self.subscribe_guilds()
|
||||||
|
await self.dispatch_ready()
|
||||||
|
|
||||||
async def handle_3(self, payload: Dict[str, Any]):
|
async def handle_3(self, payload: Dict[str, Any]):
|
||||||
"""Handle OP 3 Status Update."""
|
"""Handle OP 3 Status Update."""
|
||||||
|
|
@ -593,6 +611,10 @@ class GatewayWebsocket:
|
||||||
guild_presences = await self.presence.guild_presences(member_ids,
|
guild_presences = await self.presence.guild_presences(member_ids,
|
||||||
guild_id)
|
guild_id)
|
||||||
|
|
||||||
|
pprint.pprint(guild_presences)
|
||||||
|
|
||||||
|
log.info('loading {} presences for guild', len(guild_presences))
|
||||||
|
|
||||||
online = [{'member': p}
|
online = [{'member': p}
|
||||||
for p in guild_presences
|
for p in guild_presences
|
||||||
if p['status'] == 'online']
|
if p['status'] == 'online']
|
||||||
|
|
|
||||||
|
|
@ -19,14 +19,24 @@ class PresenceManager:
|
||||||
member = await self.storage.get_member_data_one(
|
member = await self.storage.get_member_data_one(
|
||||||
guild_id, state.user_id)
|
guild_id, state.user_id)
|
||||||
|
|
||||||
presences.append({**member, **{
|
game = state.presence.get('game', None)
|
||||||
# NOTE: maybe remove guild_id?
|
|
||||||
|
print('state:', state)
|
||||||
|
print('state.presence:', state.presence)
|
||||||
|
|
||||||
|
# only use the data we need.
|
||||||
|
presences.append({
|
||||||
|
'user': member['user'],
|
||||||
|
'roles': member['roles'],
|
||||||
'guild_id': guild_id,
|
'guild_id': guild_id,
|
||||||
|
|
||||||
# basic presence
|
# basic presence
|
||||||
'game': state.presence.get('game', None),
|
'status': state.presence['status'],
|
||||||
'status': state.presence.get('status', None),
|
|
||||||
}})
|
# game is an activity object, for rich presence
|
||||||
|
'game': game,
|
||||||
|
'activities': [game] if game else []
|
||||||
|
})
|
||||||
|
|
||||||
return presences
|
return presences
|
||||||
|
|
||||||
|
|
@ -40,14 +50,19 @@ class PresenceManager:
|
||||||
|
|
||||||
member = await self.storage.get_member_data_one(guild_id, user_id)
|
member = await self.storage.get_member_data_one(guild_id, user_id)
|
||||||
|
|
||||||
|
game = state['game']
|
||||||
|
|
||||||
await self.dispatcher.dispatch_guild(
|
await self.dispatcher.dispatch_guild(
|
||||||
guild_id, 'PRESENCE_UPDATE', {
|
guild_id, 'PRESENCE_UPDATE', {
|
||||||
'user': member['user'],
|
'user': member['user'],
|
||||||
'roles': member['roles'],
|
'roles': member['roles'],
|
||||||
'guild_id': guild_id,
|
'guild_id': guild_id,
|
||||||
|
|
||||||
'game': state['game'],
|
|
||||||
'status': state['status'],
|
'status': state['status'],
|
||||||
|
|
||||||
|
# rich presence stuff
|
||||||
|
'game': game,
|
||||||
|
'activities': [game] if game else []
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -163,12 +163,13 @@ GW_ACTIVITY = {
|
||||||
|
|
||||||
GW_STATUS_UPDATE = {
|
GW_STATUS_UPDATE = {
|
||||||
'status': {'type': 'status_external', 'required': False},
|
'status': {'type': 'status_external', 'required': False},
|
||||||
|
'activities': {'type': 'list', 'schema': GW_ACTIVITY},
|
||||||
'afk': {'type': 'boolean', 'required': False},
|
'afk': {'type': 'boolean', 'required': False},
|
||||||
|
|
||||||
'since': {'type': 'number', 'required': True, 'nullable': True},
|
'since': {'type': 'number', 'required': True, 'nullable': True},
|
||||||
'game': {
|
'game': {
|
||||||
'type': 'dict',
|
'type': 'dict',
|
||||||
'required': True,
|
'required': False,
|
||||||
'nullable': True,
|
'nullable': True,
|
||||||
'schema': GW_ACTIVITY,
|
'schema': GW_ACTIVITY,
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -257,8 +257,6 @@ class Storage:
|
||||||
|
|
||||||
res = await self._channels_extra(drow)
|
res = await self._channels_extra(drow)
|
||||||
|
|
||||||
print(res)
|
|
||||||
|
|
||||||
res['permission_overwrites'] = \
|
res['permission_overwrites'] = \
|
||||||
list(await self._chan_overwrites(row['id']))
|
list(await self._chan_overwrites(row['id']))
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue