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

Commit

Permalink
Lock specific lobby
Browse files Browse the repository at this point in the history
  • Loading branch information
thboss committed Aug 22, 2023
1 parent 7abd81e commit 314ea88
Showing 1 changed file with 90 additions and 99 deletions.
189 changes: 90 additions & 99 deletions bot/cogs/lobby.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,8 @@ class LobbyCog(commands.Cog, name="Lobby"):

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

@app_commands.command(
name='create-lobby',
Expand Down Expand Up @@ -221,20 +220,15 @@ 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.")

if self.awaiting[lobby_model.id]:
raise CustomError(
f"Unable to empty lobby #{lobby_model.id} at this moment, please try again later.")

self.awaiting[lobby_model.id] = True
for user in lobby_model.voice_channel.members:
try:
await user.move_to(guild_model.prematch_channel)
except Exception as e:
pass
async with self.lock[lobby_model.id]:
for user in lobby_model.voice_channel.members:
try:
await user.move_to(guild_model.prematch_channel)
except Exception as e:
pass

await db.clear_lobby_users(lobby_model.id)
await self.update_queue_msg(lobby_model, title="Lobby has been emptied")
self.awaiting[lobby_model.id] = False
await db.clear_lobby_users(lobby_model.id)
await self.update_queue_msg(lobby_model, title="Lobby has been emptied")

embed = Embed(description=f"Lobby #{lobby_model.id} has been emptied.")
await interaction.followup.send(embed=embed, ephemeral=True)
Expand Down Expand Up @@ -388,102 +382,99 @@ async def on_voice_state_update(self, user: Member, before: VoiceState, after: V
if before.channel == after.channel:
return

async with self.lock:
if before.channel is not None:
lobby_model = await db.get_lobby_by_voice_channel(before.channel)
if lobby_model and not self.awaiting[lobby_model.id]:
self.awaiting[lobby_model.id] = True
try:
await self._leave(user, lobby_model)
except Exception as e:
self.bot.log_exception(
"Uncaght exception when handling 'cogs.lobby._leave()' method:", e)
self.awaiting[lobby_model.id] = False

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 and not self.awaiting[lobby_model.id]:
self.awaiting[lobby_model.id] = True
try:
await self._join(user, lobby_model)
except Exception as e:
self.bot.log_exception(
"Uncaught exception when handling 'cogs.lobby._join()' method:", e)
self.awaiting[lobby_model.id] = False
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 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)

async def _leave(self, user: Member, lobby_model: LobbyModel):
""""""
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 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)

async def _join(self, user: Member, lobby_model: LobbyModel):
""""""
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]
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)
if len(queued_users) == lobby_model.capacity:
title = None
guild_model = await db.get_guild_by_id(lobby_model.guild.id, self.bot)

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()
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

try:
await queue_msg.delete()
except Exception as e:
pass

try:
await queue_msg.delete()
except Exception as e:
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)

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)
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 Down

0 comments on commit 314ea88

Please sign in to comment.