share lobby creation between 10-man and bingo and fix lobby timeouts

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
leanderandClaude Opus 5.5 committed 2026-10-29 22:43:01 +01:00
1 parent f957299e70
commit 03b79ed98a
3 files changed
+66 -80

No files matched your search

+3 -34
View File
@@ -15,6 +15,7 @@ from cogs.utils import embed_templates
from cogs.utils import misc_utils
from cogs.utils.discord_utils import Lobby
from cogs.utils.discord_utils import LobbyView
from cogs.utils.discord_utils import open_lobby
class CS2Bingo(commands.Cog):
@@ -28,7 +29,7 @@ class CS2Bingo(commands.Cog):
"""
self.bot = bot
self.active_lobbies = {} # dict[str, discord_utils.Lobby]
self.active_lobbies: dict[int, Lobby] = {}
bingo_group = app_commands.Group(name="cs2bingo", description="Bingo commands for CS2")
@@ -44,39 +45,7 @@ class CS2Bingo(commands.Cog):
interaction (discord.Interaction): Slash command context object
"""
if lobby := self.active_lobbies.get(str(interaction.user.id), None):
if lobby.ends < discord.utils.utcnow():
self.active_lobbies.pop(str(interaction.user.id))
else:
return await interaction.response.send_message(
embed=embed_templates.error_warning("Du hoster allerede en lobby")
)
for lobby in self.active_lobbies.values():
if lobby.ends > discord.utils.utcnow() and any(p.id == interaction.user.id for p in lobby.players):
return await interaction.response.send_message(
embed=embed_templates.error_warning("Du er allerede i en lobby")
)
self.active_lobbies[str(interaction.user.id)] = Lobby(
host=interaction.user,
players=[interaction.user],
ends=discord.utils.utcnow() + timedelta(minutes=10),
kicked_players=[],
)
time_left = discord.utils.format_dt(self.active_lobbies[str(interaction.user.id)].ends, "R")
embed = discord.Embed(
title="Bingolobby",
description=f"Lobbyen stenger {time_left}. Bli med innen da!",
color=interaction.user.color,
)
embed.set_author(name=interaction.user.global_name, icon_url=interaction.user.avatar)
embed.add_field(name="Spillere", value=f"* {interaction.user.mention}", inline=False)
view = BingoView(self.active_lobbies[str(interaction.user.id)], self.bot)
await interaction.response.send_message(embed=embed, view=view)
view.message = await interaction.original_response()
await open_lobby(interaction, self.active_lobbies, BingoView, "Bingolobby", timedelta(minutes=10))
class BingoGenerator:
+3 -38
View File
@@ -16,6 +16,7 @@ from discord.ext import commands
from cogs.utils import embed_templates
from cogs.utils.discord_utils import Lobby
from cogs.utils.discord_utils import LobbyView
from cogs.utils.discord_utils import open_lobby
# Seconds without any interaction before the menus and buttons are disabled
SELECTION_TIMEOUT = 300
@@ -32,7 +33,7 @@ class TenMan(commands.Cog):
"""
self.bot = bot
self.active_lobbies = {}
self.active_lobbies: dict[int, Lobby] = {}
ten_man_group = app_commands.Group(name="10man", description="For planlegging og arrangering av 10 mans")
@@ -48,43 +49,7 @@ class TenMan(commands.Cog):
interaction (discord.Interaction): Slash command context object
"""
if lobby := self.active_lobbies.get(str(interaction.user.id), None):
if lobby.ends < discord.utils.utcnow():
self.active_lobbies.pop(str(interaction.user.id))
else:
return await interaction.response.send_message(
embed=embed_templates.error_warning(
"Du hoster allerede en lobby",
)
)
for lobby in self.active_lobbies.values():
if lobby.ends > discord.utils.utcnow() and any(p.id == interaction.user.id for p in lobby.players):
return await interaction.response.send_message(
embed=embed_templates.error_warning(
"Du er allerede i en lobby",
)
)
self.active_lobbies[str(interaction.user.id)] = Lobby(
host=interaction.user,
players=[interaction.user],
ends=discord.utils.utcnow() + timedelta(minutes=30),
kicked_players=[],
)
time_left = discord.utils.format_dt(self.active_lobbies[str(interaction.user.id)].ends, "R")
embed = discord.Embed(
title="10 Man Lobby",
description=f"Lobbyen stenger {time_left}. Bli med innen da!",
color=interaction.user.color,
)
embed.set_author(name=interaction.user.global_name, icon_url=interaction.user.avatar)
embed.add_field(name="Spillere", value=f"* {interaction.user.mention}", inline=False)
view = TenManView(self.active_lobbies[str(interaction.user.id)], self.bot)
await interaction.response.send_message(embed=embed, view=view)
view.message = await interaction.original_response()
await open_lobby(interaction, self.active_lobbies, TenManView, "10 Man Lobby", timedelta(minutes=30))
class TenManView(LobbyView):
+60 -8
View File
@@ -1,5 +1,7 @@
from dataclasses import dataclass
from dataclasses import field
from datetime import datetime
from datetime import timedelta
from io import BytesIO
import discord
@@ -186,7 +188,56 @@ class Lobby:
host: discord.User
players: list[discord.User]
ends: datetime
kicked_players: list[discord.User]
kicked_players: set[int] = field(default_factory=set)
closed: bool = False
async def open_lobby(
interaction: discord.Interaction,
lobbies: dict[int, Lobby],
view_class: type["LobbyView"],
title: str,
duration: timedelta,
):
"""
Open a lobby hosted by the invoking user, unless they already host or are in an open lobby
Parameters
----------
interaction (discord.Interaction): Slash command context object
lobbies (dict[int, Lobby]): The cog's lobbies by host ID. The new lobby is added to it
view_class (type[LobbyView]): The view to show the lobby with
title (str): The title of the lobby message
duration (timedelta): How long the lobby stays open
"""
for host_id in [host_id for host_id, lobby in lobbies.items() if lobby.closed]:
del lobbies[host_id]
if interaction.user.id in lobbies:
return await interaction.response.send_message(
embed=embed_templates.error_warning("Du hoster allerede en lobby")
)
if any(interaction.user in lobby.players for lobby in lobbies.values()):
return await interaction.response.send_message(embed=embed_templates.error_warning("Du er allerede i en lobby"))
lobby = Lobby(host=interaction.user, players=[interaction.user], ends=discord.utils.utcnow() + duration)
lobbies[interaction.user.id] = lobby
time_left = discord.utils.format_dt(lobby.ends, "R")
embed = discord.Embed(
title=title, description=f"Lobbyen stenger {time_left}. Bli med innen da!", color=interaction.user.color
)
embed.set_author(name=interaction.user.global_name, icon_url=interaction.user.avatar)
embed.add_field(name="Spillere", value=f"* {interaction.user.mention}", inline=False)
view = view_class(lobby, interaction.client)
await interaction.response.send_message(embed=embed, view=view)
# Edit the message with the bot's own token later, since the interaction's token expires after 15 minutes
response = await interaction.original_response()
view.message = interaction.channel.get_partial_message(response.id)
class LobbyView(discord.ui.View):
@@ -196,7 +247,7 @@ class LobbyView(discord.ui.View):
self.lobby = lobby
self.bot = bot
self.message: discord.Message | None = None
self.message: discord.PartialMessage | None = None
self.kick_menu = _KickSelectMenu(self)
self.add_item(self.kick_menu)
@@ -206,13 +257,14 @@ class LobbyView(discord.ui.View):
if self.message:
try:
await self.message.edit(view=self)
except discord.NotFound:
pass
except discord.HTTPException:
pass # The message has been deleted
async def end_lobby(self):
self.lobby.ends = discord.utils.utcnow()
self.lobby.closed = True
for item in self.children:
item.disabled = True
self.stop()
async def rerender_players(self, interaction: discord.Interaction):
self.kick_menu.update_options()
@@ -225,7 +277,7 @@ class LobbyView(discord.ui.View):
@discord.ui.button(label="Bli med", style=discord.ButtonStyle.blurple)
async def join_lobby(self, interaction: discord.Interaction, button: discord.ui.Button):
if discord.utils.utcnow() > self.lobby.ends:
if self.lobby.closed:
embed = embed_templates.error_warning("Lobbyen har allerede startet")
return await interaction.response.send_message(embed=embed, ephemeral=True, delete_after=10)
@@ -289,7 +341,7 @@ class LobbyView(discord.ui.View):
embed = embed_templates.error_warning("Bare hosten kan slette lobbyen")
return await interaction.response.send_message(embed=embed, ephemeral=True, delete_after=10)
self.lobby.ends = discord.utils.utcnow()
await self.end_lobby()
await interaction.message.delete()
embed = embed_templates.success("Lobbyen har blitt slettet")
@@ -323,7 +375,7 @@ class _KickSelectMenu(discord.ui.Select):
embed = embed_templates.error_warning("Du kan ikke kicke deg selv")
return await interaction.response.send_message(embed=embed, ephemeral=True, delete_after=10)
self.parent_view.lobby.kicked_players.append(int(interaction.data["values"][0]))
self.parent_view.lobby.kicked_players.add(int(interaction.data["values"][0]))
# Remove the player from the lobby
# Since we only have the ID, we have to iterate through the list