Skip to content

Commit 03ce6fe

Browse files
Merge pull request #308 from RemainingDelta/220-Feature
220-Feature add counting game feature with sequential validation and set-count command
2 parents 5271f22 + 3a3de48 commit 03ce6fe

4 files changed

Lines changed: 124 additions & 0 deletions

File tree

database/mongo.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,36 @@ async def set_setting(key: str, value: str):
179179
await db.settings.update_one({"_id": key}, {"$set": {"value": value}}, upsert=True)
180180

181181

182+
# --- COUNTING HELPERS ---
183+
184+
185+
async def get_counting_state() -> dict:
186+
if db is None:
187+
return {"current_count": 0, "last_user_id": None}
188+
doc = await db.counting.find_one({"_id": "state"})
189+
if not doc:
190+
return {"current_count": 0, "last_user_id": None}
191+
return {
192+
"current_count": doc.get("current_count", 0),
193+
"last_user_id": doc.get("last_user_id"),
194+
}
195+
196+
197+
async def update_counting_state(current_count: int, last_user_id: int | None):
198+
if db is None:
199+
return
200+
await db.counting.update_one(
201+
{"_id": "state"},
202+
{
203+
"$set": {
204+
"current_count": current_count,
205+
"last_user_id": last_user_id,
206+
}
207+
},
208+
upsert=True,
209+
)
210+
211+
182212
# --- LEADERBOARD HELPERS ---
183213

184214

features/config.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161

6262
ECONOMY_COMMANDS_CHANNEL_ID = 1352841132735860746
6363
BOT_COMMANDS_CHANNEL_ID = 546405233736155151
64+
COUNTING_CHANNEL_ID = 909853678863790092
6465

6566
EMOJIS_CURRENCY = {
6667
"coins": "<:bs_coin:1454305320015888516>",
@@ -239,6 +240,7 @@
239240

240241
ECONOMY_COMMANDS_CHANNEL_ID = 1484768262649675776
241242
BOT_COMMANDS_CHANNEL_ID = 1484768347756167228
243+
COUNTING_CHANNEL_ID = 1513450829707874354
242244

243245
EMOJIS_CURRENCY = {
244246
"coins": "<:bs_coin:1454290949780934678>",

features/counting.py

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import discord
2+
from discord import app_commands
3+
from discord.ext import commands
4+
5+
from database.mongo import get_counting_state, update_counting_state
6+
from features.config import (
7+
ADMIN_ROLE_ID,
8+
COUNTING_CHANNEL_ID,
9+
FOUNDER_ROLE_ID,
10+
MODERATOR_ROLE_ID,
11+
)
12+
13+
COUNTING_MOD_ROLES = {MODERATOR_ROLE_ID, ADMIN_ROLE_ID, FOUNDER_ROLE_ID}
14+
15+
16+
class Counting(commands.Cog):
17+
def __init__(self, bot):
18+
self.bot = bot
19+
20+
@commands.Cog.listener()
21+
async def on_message(self, message: discord.Message):
22+
if message.author.bot:
23+
return
24+
if not message.guild:
25+
return
26+
if message.channel.id != COUNTING_CHANNEL_ID:
27+
return
28+
29+
state = await get_counting_state()
30+
current_count = state["current_count"]
31+
last_user_id = state["last_user_id"]
32+
expected = current_count + 1
33+
34+
if message.author.id == last_user_id:
35+
await message.delete()
36+
await message.channel.send(
37+
f"{message.author.mention} You can't count twice in a row!",
38+
delete_after=5,
39+
)
40+
return
41+
42+
try:
43+
number = int(message.content.strip())
44+
except ValueError:
45+
await message.delete()
46+
await message.channel.send(
47+
f"{message.author.mention} That's not a number! Next number is **{expected}**.",
48+
delete_after=5,
49+
)
50+
return
51+
52+
if number != expected:
53+
await message.delete()
54+
await message.channel.send(
55+
f"{message.author.mention} Wrong number! Next number is **{expected}**.",
56+
delete_after=5,
57+
)
58+
return
59+
60+
await update_counting_state(number, message.author.id)
61+
62+
@app_commands.command(
63+
name="set-count", description="Set the current count (staff only)."
64+
)
65+
@app_commands.describe(count="The number to set the count to")
66+
async def set_count(self, interaction: discord.Interaction, count: int):
67+
if not isinstance(interaction.user, discord.Member) or not any(
68+
role.id in COUNTING_MOD_ROLES for role in interaction.user.roles
69+
):
70+
await interaction.response.send_message(
71+
"❌ You don't have permission to use this command.", ephemeral=True
72+
)
73+
return
74+
75+
if interaction.channel_id != COUNTING_CHANNEL_ID:
76+
await interaction.response.send_message(
77+
f"❌ This command can only be used in <#{COUNTING_CHANNEL_ID}>.",
78+
ephemeral=True,
79+
)
80+
return
81+
82+
await update_counting_state(count, None)
83+
await interaction.response.send_message(
84+
f"✅ Count set to **{count}**.", ephemeral=True
85+
)
86+
87+
88+
async def setup(bot):
89+
await bot.add_cog(Counting(bot))

main.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,9 @@ async def on_ready():
7373
await bot.load_extension("features.sticky")
7474
print("✅ Loaded Feature: Sticky Messages")
7575

76+
await bot.load_extension("features.counting")
77+
print("✅ Loaded Feature: Counting")
78+
7679
except Exception as e:
7780
print(f"❌ Error loading features: {e}")
7881

0 commit comments

Comments
 (0)