mirror of https://gitlab.com/litecord/litecord.git
lvsp_conn: add basic INFO handling for channel assign
- lvsp: finish defining data for channel info messages - lvsp_conn: add send_info() - lvsp_opcodes: add InfoTable, InfoReverse - voice.manager: handle channels without bitrate
This commit is contained in:
parent
00100f9abb
commit
579a71dd9b
21
docs/lvsp.md
21
docs/lvsp.md
|
|
@ -175,24 +175,37 @@ Request a channel to be created inside the voice server.
|
|||
The Server MUST reply back with a CHANNEL\_ASSIGN when resources are
|
||||
allocated for the channel.
|
||||
|
||||
**TODO:** fields
|
||||
| field | type | description |
|
||||
| --: | :-- | :-- |
|
||||
| channel\_id | snowflake | channel id |
|
||||
| guild\_id | Optional[snowflake] | guild id, not provided if dm / group dm |
|
||||
| channel\_properties | ChannelProperties | channel properties |
|
||||
|
||||
#### ChannelProperties
|
||||
|
||||
| field | type | description |
|
||||
| --: | :-- | :-- |
|
||||
| bitrate | integer | channel bitrate |
|
||||
|
||||
### CHANNEL\_ASSIGN
|
||||
|
||||
Sent by the Server to signal the successful creation of a voice channel.
|
||||
|
||||
**TODO:** fields
|
||||
| field | type | description |
|
||||
| --: | :-- | :-- |
|
||||
| channel\_id | snowflake | channel id |
|
||||
| guild\_id | Optional[snowflake] | guild id, not provided if dm / group dm |
|
||||
|
||||
### CHANNEL\_UPDATE
|
||||
|
||||
Sent by the client to signal an update to the properties of a channel,
|
||||
such as its bitrate.
|
||||
|
||||
**TODO:** fields
|
||||
Same data as CHANNEL\_REQ.
|
||||
|
||||
### CHANNEL\_DESTROY
|
||||
|
||||
Sent by the client to signal the destruction of a voice channel. Be it
|
||||
a channel being deleted, or all members in it leaving.
|
||||
|
||||
**TODO:** fields
|
||||
Same data as CHANNEL\_ASSIGN.
|
||||
|
|
|
|||
|
|
@ -19,11 +19,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
import json
|
||||
import asyncio
|
||||
from typing import Dict
|
||||
|
||||
import websockets
|
||||
from logbook import Logger
|
||||
|
||||
from litecord.voice.lvsp_opcodes import OPCodes as OP
|
||||
from litecord.voice.lvsp_opcodes import OPCodes as OP, InfoTable, InfoReverse
|
||||
|
||||
log = Logger(__name__)
|
||||
|
||||
|
|
@ -65,6 +66,16 @@ class LVSPConnection:
|
|||
'd': data
|
||||
})
|
||||
|
||||
async def send_info(self, info_type: str, info_data: Dict):
|
||||
"""Send an INFO message down the websocket."""
|
||||
await self.send({
|
||||
'op': OP.info,
|
||||
'd': {
|
||||
'type': InfoTable[info_type.upper()],
|
||||
'data': info_data
|
||||
}
|
||||
})
|
||||
|
||||
async def _heartbeater(self, hb_interval: int):
|
||||
try:
|
||||
await asyncio.sleep(hb_interval)
|
||||
|
|
@ -121,6 +132,35 @@ class LVSPConnection:
|
|||
await self._update_health(msg['health'])
|
||||
self._start_hb()
|
||||
|
||||
async def _handle_6(self, msg):
|
||||
"""Handle INFO messages."""
|
||||
info = msg['d']
|
||||
info_type_str = InfoReverse[info['type']].lower()
|
||||
|
||||
try:
|
||||
info_handler = getattr(self, f'_handle_info_{info_type_str}')
|
||||
except AttributeError:
|
||||
return
|
||||
|
||||
await info_handler(info['data'])
|
||||
|
||||
async def _handle_info_channel_assign(self, data: dict):
|
||||
"""called by the server once we got a channel assign."""
|
||||
try:
|
||||
channel_id = data['channel_id']
|
||||
channel_id = int(channel_id)
|
||||
except (TypeError, ValueError):
|
||||
return
|
||||
|
||||
try:
|
||||
guild_id = data['guild_id']
|
||||
guild_id = int(guild_id)
|
||||
except (TypeError, ValueError):
|
||||
guild_id = None
|
||||
|
||||
main_key = guild_id if guild_id is not None else channel_id
|
||||
await self.lvsp.assign(main_key, self.hostname)
|
||||
|
||||
async def _loop(self):
|
||||
while True:
|
||||
msg = await self.recv()
|
||||
|
|
|
|||
|
|
@ -41,8 +41,8 @@ class LVSPManager:
|
|||
# maps regions to server hostnames
|
||||
self.servers = defaultdict(list)
|
||||
|
||||
# maps guilds to server hostnames
|
||||
self.guild_servers = {}
|
||||
# maps Union[GuildID, DMId, GroupDMId] to server hostnames
|
||||
self.assign = {}
|
||||
|
||||
self.app.loop.create_task(self._spawn())
|
||||
|
||||
|
|
@ -119,12 +119,12 @@ class LVSPManager:
|
|||
|
||||
return conn.health
|
||||
|
||||
async def get_server(self, guild_id: int) -> str:
|
||||
async def get_guild_server(self, guild_id: int) -> str:
|
||||
"""Get a voice server for the given guild, assigns
|
||||
one if there isn't any."""
|
||||
one if there isn't any"""
|
||||
|
||||
try:
|
||||
hostname = self.guild_servers[guild_id]
|
||||
hostname = self.assign[guild_id]
|
||||
except KeyError:
|
||||
region = await self.guild_region(guild_id)
|
||||
|
||||
|
|
@ -137,3 +137,7 @@ class LVSPManager:
|
|||
hostname = sorted_servers[0]
|
||||
|
||||
return hostname
|
||||
|
||||
async def assign_conn(self, key: int, hostname: str):
|
||||
"""Assign a connection to a given key in the assign map"""
|
||||
self.assign[key] = hostname
|
||||
|
|
|
|||
|
|
@ -26,3 +26,16 @@ class OPCodes:
|
|||
heartbeat = 4
|
||||
heartbeat_ack = 5
|
||||
info = 6
|
||||
|
||||
|
||||
InfoTable = {
|
||||
'CHANNEL_REQ': 0,
|
||||
'CHANNEL_ASSIGN': 1,
|
||||
'CHANNEL_UPDATE': 2,
|
||||
'CHANNEL_DESTROY': 3,
|
||||
'VST_CREATE': 4,
|
||||
'VST_UPDATE': 5,
|
||||
'VST_LEAVE': 6,
|
||||
}
|
||||
|
||||
InfoReverse = {v: k for k, v in InfoTable.items()}
|
||||
|
|
|
|||
|
|
@ -156,24 +156,19 @@ class VoiceManager:
|
|||
await self.create_state(old_voice_key, {'channel_id': channel_id})
|
||||
|
||||
async def _lvsp_info_guild(self, guild_id, info_type, info_data):
|
||||
hostname = await self.lvsp.get_server(guild_id)
|
||||
hostname = await self.lvsp.get_guild_server(guild_id)
|
||||
conn = self.lvsp.get_conn(hostname)
|
||||
|
||||
# TODO: impl send_info
|
||||
await conn.send_info(info_type, info_data)
|
||||
|
||||
async def _create_ctx_guild(self, guild_id, channel_id):
|
||||
chan = await self.app.storage.get_channel(channel_id)
|
||||
|
||||
# TODO: this, but properly
|
||||
# TODO: when the server sends a reply to CHAN_REQ, we need to update
|
||||
# LVSPManager.guild_servers.
|
||||
await self._lvsp_info_guild(guild_id, 'CHAN_REQ', {
|
||||
await self._lvsp_info_guild(guild_id, 'CHANNEL_REQ', {
|
||||
'guild_id': str(guild_id),
|
||||
'channel_id': str(channel_id),
|
||||
|
||||
'channel_properties': {
|
||||
'bitrate': chan['bitrate']
|
||||
'bitrate': chan.get('bitrate', 96)
|
||||
}
|
||||
})
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue