mirror of https://gitlab.com/litecord/litecord.git
add impl for VIP_REGIONS
(untested) - lvsp_manager: add Region, and store vip region status in it - lvsp_manager: add LVSPManager.region
This commit is contained in:
parent
977fa95ff2
commit
a12c63a7bf
|
|
@ -223,6 +223,12 @@ async def _update_guild(guild_id):
|
||||||
""", j['name'], guild_id)
|
""", j['name'], guild_id)
|
||||||
|
|
||||||
if 'region' in j:
|
if 'region' in j:
|
||||||
|
is_vip = app.voice.lvsp.region(j['region']).vip
|
||||||
|
can_vip = await app.storage.has_feature(guild_id, 'VIP_REGIONS')
|
||||||
|
|
||||||
|
if is_vip and not can_vip:
|
||||||
|
raise BadRequest('can not assign guild to vip-only region')
|
||||||
|
|
||||||
await app.db.execute("""
|
await app.db.execute("""
|
||||||
UPDATE guilds
|
UPDATE guilds
|
||||||
SET region = $1
|
SET region = $1
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
|
from dataclasses import dataclass
|
||||||
|
|
||||||
from logbook import Logger
|
from logbook import Logger
|
||||||
|
|
||||||
|
|
@ -26,6 +27,14 @@ from litecord.voice.lvsp_conn import LVSPConnection
|
||||||
|
|
||||||
log = Logger(__name__)
|
log = Logger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Region:
|
||||||
|
"""Voice region data."""
|
||||||
|
id: str
|
||||||
|
vip: bool
|
||||||
|
|
||||||
|
|
||||||
class LVSPManager:
|
class LVSPManager:
|
||||||
"""Manager class for Litecord Voice Server Protocol (LVSP) connections.
|
"""Manager class for Litecord Voice Server Protocol (LVSP) connections.
|
||||||
|
|
||||||
|
|
@ -44,46 +53,52 @@ class LVSPManager:
|
||||||
# maps Union[GuildID, DMId, GroupDMId] to server hostnames
|
# maps Union[GuildID, DMId, GroupDMId] to server hostnames
|
||||||
self.assign = {}
|
self.assign = {}
|
||||||
|
|
||||||
|
# quick storage for Region dataclass instances.
|
||||||
|
self._regions = {}
|
||||||
|
|
||||||
self.app.loop.create_task(self._spawn())
|
self.app.loop.create_task(self._spawn())
|
||||||
|
|
||||||
async def _spawn(self):
|
async def _spawn(self):
|
||||||
"""Spawn LVSPConnection for each region."""
|
"""Spawn LVSPConnection for each region."""
|
||||||
|
|
||||||
regions = await self.app.db.fetch("""
|
regions = await self.app.db.fetch("""
|
||||||
SELECT id
|
SELECT id, vip
|
||||||
FROM voice_regions
|
FROM voice_regions
|
||||||
WHERE deprecated = false
|
WHERE deprecated = false
|
||||||
""")
|
""")
|
||||||
|
|
||||||
regions = [r['id'] for r in regions]
|
regions = [Region(r['id'], r['vip']) for r in regions]
|
||||||
|
|
||||||
if not regions:
|
if not regions:
|
||||||
log.warning('no regions are setup')
|
log.warning('no regions are setup')
|
||||||
return
|
return
|
||||||
|
|
||||||
for region in regions:
|
for region in regions:
|
||||||
|
# store it locally for region() function
|
||||||
|
self._regions[region.id] = region
|
||||||
|
|
||||||
self.app.loop.create_task(
|
self.app.loop.create_task(
|
||||||
self._spawn_region(region)
|
self._spawn_region(region)
|
||||||
)
|
)
|
||||||
|
|
||||||
async def _spawn_region(self, region: str):
|
async def _spawn_region(self, region: Region):
|
||||||
"""Spawn a region. Involves fetching all the hostnames
|
"""Spawn a region. Involves fetching all the hostnames
|
||||||
for the regions and spawning a LVSPConnection for each."""
|
for the regions and spawning a LVSPConnection for each."""
|
||||||
servers = await self.app.db.fetch("""
|
servers = await self.app.db.fetch("""
|
||||||
SELECT hostname
|
SELECT hostname
|
||||||
FROM voice_servers
|
FROM voice_servers
|
||||||
WHERE region_id = $1
|
WHERE region_id = $1
|
||||||
""", region)
|
""", region.id)
|
||||||
|
|
||||||
if not servers:
|
if not servers:
|
||||||
log.warning('region {} does not have servers', region)
|
log.warning('region {} does not have servers', region)
|
||||||
return
|
return
|
||||||
|
|
||||||
servers = [r['hostname'] for r in servers]
|
servers = [r['hostname'] for r in servers]
|
||||||
self.servers[region] = servers
|
self.servers[region.id] = servers
|
||||||
|
|
||||||
for hostname in servers:
|
for hostname in servers:
|
||||||
conn = LVSPConnection(self, region, hostname)
|
conn = LVSPConnection(self, region.id, hostname)
|
||||||
self.conns[hostname] = conn
|
self.conns[hostname] = conn
|
||||||
|
|
||||||
self.app.loop.create_task(
|
self.app.loop.create_task(
|
||||||
|
|
@ -144,3 +159,7 @@ class LVSPManager:
|
||||||
async def assign_conn(self, key: int, hostname: str):
|
async def assign_conn(self, key: int, hostname: str):
|
||||||
"""Assign a connection to a given key in the assign map"""
|
"""Assign a connection to a given key in the assign map"""
|
||||||
self.assign[key] = hostname
|
self.assign[key] = hostname
|
||||||
|
|
||||||
|
def region(self, region_id: str) -> Optional[Region]:
|
||||||
|
"""Get a :class:`Region` instance:wq:wq"""
|
||||||
|
return self._regions.get(region_id)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue