Eh, kinda working

This commit is contained in:
2026-02-09 14:08:41 -06:00
parent 377b6b496b
commit 6f693dc19c
7 changed files with 384 additions and 0 deletions

264
commands.py Normal file
View File

@@ -0,0 +1,264 @@
import discord
from discord import app_commands
from db import get_db
from constants import VALORANT_RANKS, WORKOUTS
from helpers import apply_rr
import random
def register(tree: app_commands.CommandTree):
# -------------------
# /create
# -------------------
@tree.command(name="create", description="Link your Valorant account")
@app_commands.describe(
val_tag="VALUSERNAME#TAG",
rank="Your current Valorant rank",
rr="Current RR (0-99)"
)
@app_commands.choices(
rank=[app_commands.Choice(name=r, value=r) for r in VALORANT_RANKS]
)
async def create(
interaction: discord.Interaction,
val_tag: str,
rank: str,
rr: int
):
db = get_db()
cur = db.cursor()
cur.execute("""
INSERT INTO users (discord_id, val_tag, rank, rr)
VALUES (%s, %s, %s, %s)
ON DUPLICATE KEY UPDATE
val_tag=VALUES(val_tag),
rank=VALUES(rank),
rr=VALUES(rr)
""", (str(interaction.user.id), val_tag, rank, rr))
cur.close()
db.close()
await interaction.response.send_message("✅ Account linked", ephemeral=True)
# -------------------
# /match
# -------------------
enabled_workouts = [
app_commands.Choice(name=name, value=name)
for name, value in WORKOUTS.items()
if value > 0
]
@tree.command(name="match", description="Log a Valorant match")
@app_commands.describe(
result="Match result",
rr_change="RR gained or lost",
kd="Kills/Deaths (e.g. 20/15)",
workout="Workout assigned for deaths"
)
@app_commands.choices(
result=[
app_commands.Choice(name="WIN", value="WIN"),
app_commands.Choice(name="LOSS", value="LOSS")
],
workout=enabled_workouts
)
async def match(
interaction: discord.Interaction,
result: str,
rr_change: int,
kd: str,
workout: str
):
try:
kills, deaths = map(int, kd.split("/"))
except ValueError:
await interaction.response.send_message(
"❌ K/D must be in format `kills/deaths` (e.g. 20/15)",
ephemeral=True
)
return
db = get_db()
cur = db.cursor(dictionary=True)
cur.execute(
"SELECT * FROM users WHERE discord_id=%s",
(str(interaction.user.id),)
)
user = cur.fetchone()
if not user:
await interaction.response.send_message(
"❌ You must run `/create` first",
ephemeral=True
)
return
new_rank, new_rr = apply_rr(user["rank"], user["rr"], rr_change)
per_death = WORKOUTS[workout]
workout_total = deaths * per_death
cur.execute("""
UPDATE users
SET
kills = kills + %s,
deaths = deaths + %s,
rank = %s,
rr = %s
WHERE discord_id = %s
""", (kills, deaths, new_rank, new_rr, str(interaction.user.id)))
cur.execute("""
INSERT INTO workouts (discord_id, workout, amount)
VALUES (%s, %s, %s)
ON DUPLICATE KEY UPDATE amount = amount + %s
""", (str(interaction.user.id), workout, workout_total, workout_total))
cur.close()
db.close()
await interaction.response.send_message(
f"🏆 Match logged\n"
f"**Rank:** {new_rank} ({new_rr} RR)\n"
f"**Workout:** {workout} × {workout_total}"
)
# -------------------
# /stats
# -------------------
@tree.command(name="stats", description="Show Momentum stats")
async def stats(
interaction: discord.Interaction,
user: discord.User | None = None
):
target = user or interaction.user
db = get_db()
cur = db.cursor(dictionary=True)
cur.execute(
"SELECT * FROM users WHERE discord_id=%s",
(str(target.id),)
)
u = cur.fetchone()
if not u:
await interaction.response.send_message(
"❌ User not found",
ephemeral=True
)
return
cur.execute(
"SELECT workout, amount FROM workouts WHERE discord_id=%s",
(str(target.id),)
)
workout_rows = cur.fetchall()
embed = discord.Embed(
title=f"{target.display_name}'s Momentum Stats",
color=discord.Color.red()
)
embed.add_field(
name="Rank",
value=f"{u['rank']} ({u['rr']} RR)",
inline=False
)
embed.add_field(
name="Valorant",
value=u["val_tag"],
inline=False
)
embed.add_field(
name="Kills / Deaths",
value=f"{u['kills']} / {u['deaths']}",
inline=False
)
workout_text = (
"\n".join(f"{w['workout']}: {w['amount']}" for w in workout_rows)
if workout_rows else "None"
)
embed.add_field(
name="Workouts Completed",
value=workout_text,
inline=False
)
cur.close()
db.close()
await interaction.response.send_message(embed=embed)
# -------------------
# /workout
# -------------------
@tree.command(name="workout", description="Get a random workout")
async def workout(interaction: discord.Interaction):
enabled = [w for w, v in WORKOUTS.items() if v > 0]
choice = random.choice(enabled)
await interaction.response.send_message(
f"💪 **{choice}**\n"
f"{WORKOUTS[choice]} per death"
)
# -------------------
# /edit (admin)
# -------------------
@tree.command(name="edit", description="Edit a user's stats (Admin)")
@app_commands.choices(
rank=[app_commands.Choice(name=r, value=r) for r in VALORANT_RANKS]
)
async def edit(
interaction: discord.Interaction,
user: discord.User,
rank: str | None = None,
rr: int | None = None,
val_tag: str | None = None
):
if not interaction.user.guild_permissions.administrator:
await interaction.response.send_message(
"❌ Admins only",
ephemeral=True
)
return
fields = []
values = []
if rank:
fields.append("rank=%s")
values.append(rank)
if rr is not None:
fields.append("rr=%s")
values.append(rr)
if val_tag:
fields.append("val_tag=%s")
values.append(val_tag)
if not fields:
await interaction.response.send_message(
"Nothing to update",
ephemeral=True
)
return
values.append(str(user.id))
db = get_db()
cur = db.cursor()
cur.execute(
f"UPDATE users SET {', '.join(fields)} WHERE discord_id=%s",
values
)
cur.close()
db.close()
await interaction.response.send_message("✏️ User updated")