Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
fe8fff3
🔧 Update Kube config for SixMan deployment
MasterOfCubesAU Jun 2, 2024
3cefdec
Fixed local deployment + password files not resolving
MasterOfCubesAU Jan 24, 2025
c6f91ea
🔧 Update `values.yaml` to support DB statefulset
sam1357 Jan 24, 2025
de2b456
Remove extraneous print
MasterOfCubesAU Jan 24, 2025
165621d
Added queue timeout, renamed Team A/B with team name, queue prompt
MasterOfCubesAU Jan 24, 2025
8a4171e
Made queue prompt buttons persistent
MasterOfCubesAU Jan 29, 2025
f1e83f6
🔧 Update Kube config for SixMan deployment
MasterOfCubesAU Jun 2, 2024
a34fa51
Fixed local deployment + password files not resolving
MasterOfCubesAU Jan 24, 2025
c7c32af
🔧 Update `values.yaml` to support DB statefulset
sam1357 Jan 24, 2025
8e5b9f2
Remove extraneous print
MasterOfCubesAU Jan 24, 2025
8ae486c
Added queue timeout, renamed Team A/B with team name, queue prompt
MasterOfCubesAU Jan 24, 2025
b659ecf
🔧 Update helm chart
sam1357 Feb 2, 2025
94736a3
Revised queue timeout
MasterOfCubesAU Feb 1, 2025
bff9be8
Merge branch 'add-six-mans' of github.com:mocbotau/ScuffBot into add-…
sam1357 Feb 2, 2025
a3e67c6
Fixed bug stopping people from leaving queue
MasterOfCubesAU Feb 2, 2025
6d374bc
Stop double breakout + stop double select of ones nomination
MasterOfCubesAU Feb 5, 2025
684757c
Changed mysql connnector to be pooled connection
MasterOfCubesAU Feb 3, 2025
716a12f
Six mans lobby now is mentioned when a lobby is started
MasterOfCubesAU Feb 10, 2025
0957d24
Added administrative close command
MasterOfCubesAU Feb 11, 2025
1fd9b6f
Merge branch 'main' into add-six-mans
MasterOfCubesAU Feb 17, 2025
0046df7
fix: prompt now doesn't reset after a user reconnects to the call
MasterOfCubesAU Feb 18, 2025
ce21b89
fix: condition where more than 6 players would not trigger a lobby
MasterOfCubesAU Feb 20, 2025
44c7665
Added score inference
MasterOfCubesAU Feb 3, 2025
0c58898
Add support for best of 3s for 3s gamemode
MasterOfCubesAU Feb 23, 2025
6b7f835
Changed match creation to be of code/password type
MasterOfCubesAU Feb 26, 2025
846d9ed
Merge branch 'main' into add-six-mans
MasterOfCubesAU Oct 31, 2025
f1420e5
feat: use longhorn for pvcs + simplify secrets in Helm chart
sam1357 Dec 31, 2025
8559030
chore: update Dagger to v0.19.9
sam1357 Jan 9, 2026
245701c
chore: bump dagger to 20.3
sam1357 Mar 30, 2026
82018b2
Merge branch 'main' into add-six-mans
MasterOfCubesAU Apr 9, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .env.local
Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
BOT_TOKEN=/secrets/bot-token
CONFIG_FILE=/config/config.yaml.local
DB_DATABASE=SCUFFBOT
DB_HOST=db
DB_PASSWORD_FILE=/secrets/db-password
DB_USER=SCUFFBOT
27 changes: 27 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,32 @@ If you would like to run locally:
| Filename | Description |
|--------------------|------------------------------------|
| `bot-token` | Token for Discord bot |
| `db-password` | Default password for database |
| `db-root-password` | Root password for the database |
4. Copy [/db/.env.template](./db/.env.template) to `db/.env`, and adjust values as necessary.
5. Run the bot with `docker compose up -d --build`.

If you have something to suggest, whether it is feedback or a bug report, put it in the thread below. As I acknowledge your feedback, I will update this list. This is what I have so far:

# Feedback

- [x] Implement a queue timeout, perhaps 45-60mins?
- [x] Notify the channel when a player has joined the queue
- [ ] Have request to spectate six mans matches
- [x] Wait for all 6 people to join call before starting otherwise cancel after 5 mins
- [ ] Incorporate personal stats page
- [x] Disable general text chat messaging
- [x] Change Team A/B to actual team names
- [ ] Add rematch button
- [x] Disable break out button after clicked
- [x] Ping the six mans lobby channel when the lobby is created
- [ ] Connect up the MMR system
- [ ] Send players back to the general six mans voice channel after the game has been ended
- [x] Convert score reporting to win/loss reporting
- [x] Add administrative commands to manipulate six man lobbies
- Added `close` command

# Bugs

- [x] Users get kicked from queue even after finding a match
- [x] Captains are able to click select 1s players multiple times resulting in multiple 1s players in the party per team
23 changes: 23 additions & 0 deletions SIX-MANS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@

# Feedback

- [x] Implement a queue timeout, perhaps 45-60mins?
- [x] Notify the channel when a player has joined the queue
- [ ] Have request to spectate six mans matches
- [x] Wait for all 6 people to join call before starting otherwise cancel after 5 mins
- [ ] Incorporate personal stats page
- [x] Disable general text chat messaging
- [x] Change Team A/B to actual team names
- [ ] Add rematch button
- [x] Disable break out button after clicked
- [x] Ping the six mans lobby channel when the lobby is created
- [ ] Connect up the MMR system
- [ ] Send players back to the general six mans voice channel after the game has been ended
- [x] Convert score reporting to win/loss reporting
- [x] Add administrative commands to manipulate six man lobbies
- Added `close` command

# Bugs

- [x] Users get kicked from queue even after finding a match
- [x] Captains are able to click select 1s players multiple times resulting in multiple 1s players in the party per team
6 changes: 3 additions & 3 deletions dagger.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{
"name": "ScuffBot",
"engineVersion": "v0.19.9",
"engineVersion": "v0.20.3",
"blueprint": {
"name": "generic-deploy",
"source": "github.com/mocbotau/infra-dagger-modules/blueprints/generic-deploy@v0.2.1",
"pin": "d3b5d9928ca1aa7ab0199362d2d0f0e7cd6e792a"
"source": "github.com/mocbotau/infra-dagger-modules/blueprints/generic-deploy@v0.2.3",
"pin": "baa540a83e74639fb6ff0b1ef1a51a35dd688e85"
}
}
4 changes: 4 additions & 0 deletions db/.env.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
MYSQL_DATABASE=SCUFFBOT
MYSQL_USER=SCUFFBOT
MYSQL_PASSWORD_FILE=/secrets/db-password
MYSQL_ROOT_PASSWORD_FILE=/secrets/db-root-password
65 changes: 65 additions & 0 deletions db/data/init.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
CREATE TABLE
`SixManParty` (
`PartyID` INTEGER NOT NULL AUTO_INCREMENT,
`LobbyID` INTEGER DEFAULT NULL,
`GameID` INTEGER DEFAULT NULL,
PRIMARY KEY (`PartyID`)
);

CREATE TABLE
`SixManLobby` (
`LobbyID` INTEGER NOT NULL,
`MessageID` TEXT NOT NULL,
`VoiceChannelID` TEXT NOT NULL,
`TextChannelID` TEXT NOT NULL,
`RoleID` TEXT NOT NULL,
`VoiceChannelA` VARCHAR(255) DEFAULT NULL UNIQUE,
`VoiceChannelB` VARCHAR(255) DEFAULT NULL UNIQUE,
PRIMARY KEY (`LobbyID`)
);

CREATE TABLE
`SixManGames` (
`GameID` INTEGER NOT NULL AUTO_INCREMENT,
`Timestamp` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`MatchCode` TEXT NOT NULL,
`MatchPassword` TEXT NOT NULL,
`1v1_A` INTEGER DEFAULT NULL,
`1v1_B` INTEGER DEFAULT NULL,
`2v2_A` INTEGER DEFAULT NULL,
`2v2_B` INTEGER DEFAULT NULL,
`3v3_A_A` INTEGER DEFAULT NULL,
`3v3_A_B` INTEGER DEFAULT NULL,
`3v3_B_A` INTEGER DEFAULT NULL,
`3v3_B_B` INTEGER DEFAULT NULL,
`3v3_C_A` INTEGER DEFAULT NULL,
`3v3_C_B` INTEGER DEFAULT NULL,
PRIMARY KEY (`GameID`)
);

CREATE TABLE
`SixManUsers` (
`PartyID` INTEGER NOT NULL,
`UserID` VARCHAR(255) NOT NULL,
`Type` INTEGER NOT NULL DEFAULT 0,
`Team` INTEGER NOT NULL DEFAULT 0,
`isOnesPlayer` INTEGER DEFAULT NULL,
PRIMARY KEY (`PartyID`, `UserID`)
);

ALTER TABLE `SixManParty` ADD CONSTRAINT `FK_LobbyID_SixManParty` FOREIGN KEY (`LobbyID`) REFERENCES `SixManLobby` (`LobbyID`) ON DELETE SET NULL,
ADD CONSTRAINT `FK_GameID` FOREIGN KEY (`GameID`) REFERENCES `SixManGames` (`GameID`) ON DELETE SET NULL;

ALTER TABLE `SixManUsers` ADD CONSTRAINT `FK_PartyID_SixManUsers` FOREIGN KEY (`PartyID`) REFERENCES `SixManParty` (`PartyID`) ON DELETE CASCADE;

DELIMITER $$

CREATE TRIGGER DeletePartyCascade
AFTER DELETE ON SixManParty
FOR EACH ROW
BEGIN
DELETE FROM SixManLobby WHERE LobbyID = OLD.LobbyID;
DELETE FROM SixManGames WHERE GameID = OLD.GameID;
END $$

DELIMITER ;
40 changes: 40 additions & 0 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,45 @@ services:
volumes:
- ./.local-secrets:/secrets
- ./config.yaml.local:/config/config.yaml.local
depends_on:
db:
condition: service_healthy
env_file:
- ./.env.local
networks:
- backend
# MySQL Server
db:
image: "mysql:9.2.0"
restart: unless-stopped
env_file:
- ./db/.env
volumes:
- db_data:/var/lib/mysql
- ./db/data:/docker-entrypoint-initdb.d/
- .local-secrets/db-password:/secrets/db-password
- .local-secrets/db-root-password:/secrets/db-root-password
networks:
- backend
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1", "--silent"]
interval: 5s
timeout: 3s
retries: 2
start_period: 0s
# phpmyadmin
phpmyadmin:
depends_on:
- db
image: phpmyadmin
restart: always
ports:
- "8080:80"
environment:
PMA_HOST: db
networks:
- backend
volumes:
db_data:
networks:
backend:
2 changes: 2 additions & 0 deletions helmfile.yaml.gotmpl
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,5 @@ releases:
set:
- name: scuffbotConfig
file: config.yaml
- name: sqlInitFile
file: db/data/init.sql
36 changes: 36 additions & 0 deletions infra/values.yaml.gotmpl
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,43 @@ deployments:
environment:
BOT_TOKEN: "/secrets/bot-token"
CONFIG_FILE: "/config/config.yaml"
DB_DATABASE: "SCUFFBOT"
DB_HOST: "service-scuffbot-db"
DB_PASSWORD_FILE: "/secrets/db-password"
DB_USER: "SCUFFBOT"
secretProviderClass:
projectId: "e1420e9b-7c7d-4f54-b916-74d17f594a83"
secrets:
- secretKey: "BOT_TOKEN"
- secretKey: "DB_PASSWORD"

statefulSets:
- name: "scuffbot-db"
image: "mysql:9.2.0"
updateStrategy: "OnDelete"
config:
fileName: "init.sql"
fileVariable: "sqlInitFile"
mountPath: "/docker-entrypoint-initdb.d/"
environment:
MYSQL_DATABASE: "SCUFFBOT"
MYSQL_USER: "SCUFFBOT"
MYSQL_PASSWORD_FILE: "/secrets/db-password"
MYSQL_ROOT_PASSWORD_FILE: "/secrets/db-root-password"
readinessProbe:
tcpSocket:
port: 3306
secretProviderClass:
projectId: "e1420e9b-7c7d-4f54-b916-74d17f594a83"
secrets:
- secretKey: "DB_PASSWORD"
- secretKey: "DB_ROOT_PASSWORD"
service:
type: "ClusterIP"
port: 3306
targetPort: 3306
volumes:
- name: "scuffbot-db-longhorn"
storageClass: "longhorn"
mountPath: "/var/lib/mysql"
size: "1Gi"
Binary file modified requirements.txt
Binary file not shown.
19 changes: 12 additions & 7 deletions src/lib/bot/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,12 @@
with open(os.environ["CONFIG_FILE"], "r", encoding="utf-8") as f:
config = yaml.safe_load(f)


class SCUFFBOT(commands.Bot):

def __init__(self, is_dev):
super().__init__(command_prefix="!", owner_id=169402073404669952, intents=discord.Intents.all())
super().__init__(command_prefix="/",
owner_id=169402073404669952, intents=discord.Intents.all())
self.is_dev = is_dev
self.mode = "DEVELOPMENT" if is_dev else "PRODUCTION"

Expand All @@ -32,7 +34,6 @@ def setup_logger(self):
for handler in logging.getLogger().handlers:
if handler.name == "file" and os.path.isfile('logs/latest.log'):
handler.doRollover()
logging.getLogger('discord').setLevel(logging.DEBUG)

async def load_cog_manager(self):
await self.load_extension("src.lib.cogs.Cogs")
Expand All @@ -41,14 +42,17 @@ def run(self, bot_token: str):
super().run(bot_token, log_handler=None)

def create_embed(self, title, description, colour):
embed = discord.Embed(title=None, description=description, colour=colour if colour else 0xDC3145, timestamp=discord.utils.utcnow())
embed.set_author(name=title if title else None, icon_url=self.avatar_url)
embed = discord.Embed(title=None, description=description,
colour=colour if colour else 0xDC3145, timestamp=discord.utils.utcnow())
embed.set_author(name=title if title else None,
icon_url=self.avatar_url)
return embed

# Doesn't work, need to look into
@staticmethod
def has_permissions(**perms):
original = app_commands.checks.has_permissions(**perms)

async def extended_check(interaction):
if interaction.guild is None:
return False
Expand All @@ -63,15 +67,16 @@ async def on_ready(self):
self.appinfo = await super().application_info()
self.avatar_url = self.appinfo.icon.url if self.appinfo.icon is not None else None
self.logger.info(
f"Connected on {self.user.name} ({self.mode}) | d.py v{str(discord.__version__)}"
f"Connected on {self.user.name} | d.py v{str(discord.__version__)}"
)

async def on_interaction(self, interaction):
self.logger.info(f"[COMMAND] [{interaction.guild} // {interaction.guild.id}] {interaction.user} ({interaction.user.id}) used command {interaction.command.name}")
self.logger.info(
f"[COMMAND] [{interaction.guild} // {interaction.guild.id}] {interaction.user} ({interaction.user.id}) used command {interaction.command.name}")

async def on_message(self, message):
await self.wait_until_ready()
if(isinstance(message.channel, discord.DMChannel) and message.author.id == self.owner_id):
if (isinstance(message.channel, discord.DMChannel) and message.author.id == self.owner_id):
message_components = message.content.lower().split(" ")
match message_components[0]:
case "sync":
Expand Down
5 changes: 3 additions & 2 deletions src/lib/cogs/Cogs.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import os
import traceback


class Cogs(commands.Cog):

def __init__(self, bot):
Expand Down Expand Up @@ -71,8 +72,8 @@ async def load_cogs(self):
async def cog_load(self):
self.logger.info(f"[COG] Loaded {self.__class__.__name__}")

CogGroup = app_commands.Group(
name="cog", description="Manages SCUFFBOT cogs.", guild_ids=[1165195575013163038, 422983658257907732])
CogGroup = app_commands.Group(name="cog", description="Manages SCUFFBOT cogs.", guild_ids=[
1165195575013163038, 422983658257907732])

@CogGroup.command(name="list", description="Lists all cog statuses.")
@app_commands.checks.has_permissions(manage_guild=True)
Expand Down
12 changes: 8 additions & 4 deletions src/lib/cogs/ErrorHandler.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import logging
import traceback


class ErrorHandler(commands.Cog):

def __init__(self, bot):
Expand All @@ -11,14 +12,17 @@ def __init__(self, bot):

async def cog_load(self):
self.logger.info(f"[COG] Loaded {self.__class__.__name__}")

async def on_app_command_error(self, interaction, error):
embed = self.bot.create_embed("SCUFFBOT ERROR", "An unexpected error has occurred.", 0xFF0000)
embed.add_field(name="ERROR:", value="> {}\n\nIf this error is a regular occurrence, please contact {}. This error has been logged.".format(str(error), self.appinfo.owner.mention), inline=False)
embed = self.bot.create_embed(
"SCUFFBOT ERROR", "An unexpected error has occurred.", 0xFF0000)
embed.add_field(name="ERROR:", value="> {}\n\nIf this error is a regular occurrence, please contact {}. This error has been logged.".format(
str(error), self.appinfo.owner.mention), inline=False)
await interaction.response.send_message(embed=embed, ephemeral=True)

self.logger.error(f"[ERROR] Unhandled Error: {error}")
traceback.print_exc()


async def setup(bot):
await bot.add_cog(ErrorHandler(bot))
Loading
Loading