Skip to content
This repository has been archived by the owner on May 6, 2024. It is now read-only.

Commit

Permalink
Improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
thboss committed Aug 25, 2023
1 parent b12d23e commit 05ce69e
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 90 deletions.
167 changes: 80 additions & 87 deletions bot/cogs/lobby.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,8 @@ class LobbyCog(commands.Cog, name="Lobby"):

def __init__(self, bot: G5Bot):
self.bot = bot
self.lock = {}
self.lock = defaultdict(lambda: asyncio.Lock(), self.lock)
self.locks = defaultdict(lambda: asyncio.Lock())
self.in_progress = defaultdict(lambda: False)

@app_commands.command(
name='create-lobby',
Expand Down Expand Up @@ -220,7 +220,7 @@ async def empty_lobby(self, interaction: Interaction, lobby_id: int):
if lobby_model.guild.id != guild.id:
raise CustomError("This lobby was not created in this server.")

async with self.lock[lobby_model.id]:
async with self.locks[lobby_model.id]:
for user in lobby_model.voice_channel.members:
try:
await user.move_to(guild_model.prematch_channel)
Expand Down Expand Up @@ -385,96 +385,97 @@ async def on_voice_state_update(self, user: Member, before: VoiceState, after: V
if before.channel is not None:
lobby_model = await db.get_lobby_by_voice_channel(before.channel)
if lobby_model:
try:
await self._leave(user, lobby_model)
except Exception as e:
self.bot.log_exception(
"Uncaght exception when handling 'cogs.lobby._leave()' method:", e)
if not self.in_progress[lobby_model.id]:
async with self.locks[lobby_model.id]:
try:
await self._leave(user, lobby_model)
except Exception as e:
self.bot.log_exception(
"Uncaght exception when handling 'cogs.lobby._leave()' method:", e)

if after.channel is not None:
lobby_model = await db.get_lobby_by_voice_channel(after.channel)
if lobby_model and lobby_model.text_channel:
try:
await self._join(user, lobby_model)
except Exception as e:
self.bot.log_exception(
"Uncaught exception when handling 'cogs.lobby._join()' method:", e)
if not self.in_progress[lobby_model.id]:
async with self.locks[lobby_model.id]:
try:
await self._join(user, lobby_model)
except Exception as e:
self.bot.log_exception(
"Uncaught exception when handling 'cogs.lobby._join()' method:", e)

async def _leave(self, user: Member, lobby_model: LobbyModel):
""""""
async with self.lock[lobby_model.id]:
removed = await db.delete_lobby_users(lobby_model.id, [user])
if removed:
title = f"User {user.display_name} removed from the lobby"
await self.update_queue_msg(lobby_model, title)
removed = await db.delete_lobby_users(lobby_model.id, [user])
if removed:
title = f"User {user.display_name} removed from the lobby"
await self.update_queue_msg(lobby_model, title)

async def _join(self, user: Member, lobby_model: LobbyModel):
""""""
async with self.lock[lobby_model.id]:
queued_users = await db.get_lobby_users(lobby_model.id, lobby_model.guild)
try:
await self.add_user_to_lobby(user, lobby_model, queued_users)
except JoinLobbyError as e:
title = e.message
else:
title = f"User **{user.display_name}** added to the queue."
queued_users += [user]

if len(queued_users) == lobby_model.capacity:
title = None
guild_model = await db.get_guild_by_id(lobby_model.guild.id, self.bot)
queued_users = await db.get_lobby_users(lobby_model.id, lobby_model.guild)
try:
await self.add_user_to_lobby(user, lobby_model, queued_users)
except JoinLobbyError as e:
title = e.message
else:
title = f"User **{user.display_name}** added to the queue."
queued_users.append(user)

try:
queue_msg = await lobby_model.text_channel.fetch_message(lobby_model.message_id)
except HTTPException as e:
embed = Embed(description="Lobby message")
queue_msg = await lobby_model.text_channel.send(embed=embed)

unreadied_users = []
if not lobby_model.auto_ready:
mentions_msg = await lobby_model.text_channel.send(''.join(u.mention for u in queued_users))
ready_view = ReadyView(queued_users, queue_msg)
await queue_msg.edit(embed=ready_view._embed_ready(), view=ready_view)
await ready_view.wait()
unreadied_users = set(queued_users) - ready_view.ready_users
try:
await mentions_msg.delete()
except Exception as e:
pass
if len(queued_users) == lobby_model.capacity:
self.in_progress[lobby_model.id] = True
title = None
guild_model = await db.get_guild_by_id(lobby_model.guild.id, self.bot)
lobby_model = await db.get_lobby_by_id(lobby_model.id, self.bot)

try:
queue_msg = await lobby_model.text_channel.fetch_message(lobby_model.message_id)
await queue_msg.delete()
except:
pass

unreadied_users = []
if not lobby_model.auto_ready:
ready_view = ReadyView(queued_users, lobby_model.text_channel)
await ready_view.start()
await ready_view.wait()
unreadied_users = set(queued_users) - ready_view.ready_users
try:
await queue_msg.delete()
except Exception as e:
await ready_view.message.delete()
except:
pass

if unreadied_users:
await db.delete_lobby_users(lobby_model.id, unreadied_users)
await self.move_to_channel(guild_model.prematch_channel, unreadied_users)
else:
embed = Embed(description='Starting match setup...')
setup_match_msg = await lobby_model.text_channel.send(embed=embed)

map_pool = await db.get_lobby_maps(lobby_model.id)
match_cog = self.bot.get_cog('Match')
match_started = await match_cog.start_match(
lobby_model.guild,
setup_match_msg,
map_pool,
queue_users=queued_users,
game_mode=lobby_model.game_mode,
team_method=lobby_model.team_method,
captain_method=lobby_model.captain_method,
map_method=lobby_model.map_method,
series=lobby_model.series,
region=lobby_model.region,
season_id=lobby_model.season_id
)
if not match_started:
await self.move_to_channel(guild_model.prematch_channel, queued_users)

await db.clear_lobby_users(lobby_model.id)

await self.update_queue_msg(lobby_model, title)
if unreadied_users:
awaitables = [u.move_to(guild_model.prematch_channel) for u in unreadied_users]
awaitables.append(db.delete_lobby_users(lobby_model.id, unreadied_users))
await asyncio.gather(*awaitables)
else:
embed = Embed(description='Starting match setup...')
setup_match_msg = await lobby_model.text_channel.send(embed=embed)

map_pool = await db.get_lobby_maps(lobby_model.id)
match_cog = self.bot.get_cog('Match')
match_started = await match_cog.start_match(
lobby_model.guild,
setup_match_msg,
map_pool,
queue_users=queued_users,
game_mode=lobby_model.game_mode,
team_method=lobby_model.team_method,
captain_method=lobby_model.captain_method,
map_method=lobby_model.map_method,
series=lobby_model.series,
region=lobby_model.region,
season_id=lobby_model.season_id
)
if not match_started:
awaitables = [u.move_to(guild_model.prematch_channel) for u in queued_users]
await asyncio.gather(*awaitables)

await db.clear_lobby_users(lobby_model.id)
self.in_progress[lobby_model.id] = False

await self.update_queue_msg(lobby_model, title)

async def add_user_to_lobby(self, user: Member, lobby_model: LobbyModel, queued_users: List[Member]):
""""""
Expand All @@ -499,6 +500,7 @@ async def update_queue_msg(self, lobby_model: LobbyModel, title: str = None):
if not lobby_model.text_channel or not lobby_model.voice_channel:
return

lobby_model = await db.get_lobby_by_id(lobby_model.id, self.bot)
queued_users = await db.get_lobby_users(lobby_model.id, lobby_model.guild)

try:
Expand Down Expand Up @@ -536,15 +538,6 @@ def _embed_queue(self, title: str, lobby_model: LobbyModel, queued_users: List[M
embed.set_thumbnail(url=self.bot.user.avatar.url)
return embed

async def move_to_channel(self, channel: VoiceChannel, users: List[Member]):
""""""
for user in users:
try:
await user.move_to(channel)
except HTTPException as e:
self.bot.logger.warning(
f"Unable to move user \"{user.display_name}\" to voice channel \"{channel.name}\": {e.text}")


async def setup(bot: G5Bot):
await bot.add_cog(LobbyCog(bot))
14 changes: 11 additions & 3 deletions bot/views/readyView.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
# readyView.py

from discord import Interaction, Member, Message, ButtonStyle, Embed
from discord import Interaction, Member, TextChannel, ButtonStyle, Embed
from discord.ui import View, Button, button
from typing import List


class ReadyView(View):
def __init__(self, users: List[Member], message: Message, timeout=60):
def __init__(self, users: List[Member], channel: TextChannel, timeout=60):
super().__init__(timeout=timeout)
self.users = users
self.channel = channel
self.ready_users = set()
self.message = message
self.message = None

@property
def all_ready(self):
Expand Down Expand Up @@ -47,3 +48,10 @@ def _embed_ready(self):
embed.add_field(name="__Status__", value=statuses)
embed.set_footer(text="Click the button below when you are ready.")
return embed

async def start(self):
self.message = await self.channel.send(
content=''.join(u.mention for u in self.users),
embed=self._embed_ready(),
view=self
)

0 comments on commit 05ce69e

Please sign in to comment.