2026-03-02 10:16:30 +01:00
|
|
|
|
import random
|
2026-03-10 15:34:25 +01:00
|
|
|
|
from wood import logger
|
2026-06-21 16:29:32 +02:00
|
|
|
|
from pymysql.cursors import DictCursor
|
2026-05-12 15:36:31 +02:00
|
|
|
|
from data.database import db_connection
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# -----------------------------------------------------
|
|
|
|
|
|
# User / Session
|
|
|
|
|
|
# -----------------------------------------------------
|
2026-03-02 10:16:30 +01:00
|
|
|
|
|
2026-03-09 13:05:11 +01:00
|
|
|
|
def validate_user_session(db_id, discord_id):
|
2026-07-06 22:07:47 +02:00
|
|
|
|
"""Checks if the cookie still matches the current database."""
|
2026-05-12 15:36:31 +02:00
|
|
|
|
connection = db_connection()
|
2026-03-09 13:05:11 +01:00
|
|
|
|
cursor = connection.cursor()
|
|
|
|
|
|
|
2026-05-12 15:36:31 +02:00
|
|
|
|
cursor.execute("SELECT discord_id FROM players WHERE id = %s", (db_id,))
|
2026-03-09 13:05:11 +01:00
|
|
|
|
result = cursor.fetchone()
|
2026-05-12 15:36:31 +02:00
|
|
|
|
cursor.close()
|
2026-03-09 13:05:11 +01:00
|
|
|
|
connection.close()
|
|
|
|
|
|
|
|
|
|
|
|
if result is None:
|
2026-03-27 09:38:29 +01:00
|
|
|
|
logger.log(f"Player not found in database. Discord:{discord_id}")
|
2026-03-09 13:05:11 +01:00
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
|
if str(result[0]) != str(discord_id):
|
2026-07-06 22:07:47 +02:00
|
|
|
|
logger.log(f"Player with false cookies logged in! {discord_id} does not belong to {db_id}")
|
2026-03-09 13:05:11 +01:00
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
|
|
|
2026-03-02 10:16:30 +01:00
|
|
|
|
def change_display_name(player_id, new_name):
|
2026-05-12 15:36:31 +02:00
|
|
|
|
connection = db_connection()
|
2026-03-02 10:16:30 +01:00
|
|
|
|
cursor = connection.cursor()
|
|
|
|
|
|
|
2026-05-12 15:36:31 +02:00
|
|
|
|
cursor.execute("UPDATE players SET display_name = %s WHERE id = %s", (new_name, player_id))
|
2026-03-02 10:16:30 +01:00
|
|
|
|
|
|
|
|
|
|
connection.commit()
|
2026-05-12 15:36:31 +02:00
|
|
|
|
cursor.close()
|
2026-03-02 10:16:30 +01:00
|
|
|
|
connection.close()
|
|
|
|
|
|
|
2026-05-12 15:36:31 +02:00
|
|
|
|
|
2026-03-08 16:23:39 +01:00
|
|
|
|
def generate_silly_name():
|
2026-07-06 22:07:47 +02:00
|
|
|
|
adjectives = ["Confused", "Blind", "Howling", "Angry", "Chaos",
|
|
|
|
|
|
"Desperate", "Shouting", "Stumbling", "Sweating"]
|
|
|
|
|
|
nouns = ["Grot", "Cultist", "Servitor", "Snotling", "Guardmen",
|
|
|
|
|
|
"DiceLover", "RuleBreaker", "MetaChaser", "SlimeSniffer"]
|
2026-05-12 15:36:31 +02:00
|
|
|
|
return f"{random.choice(adjectives)} {random.choice(nouns)}"
|
2026-03-04 16:08:45 +01:00
|
|
|
|
|
|
|
|
|
|
|
2026-03-02 10:16:30 +01:00
|
|
|
|
def get_or_create_player(discord_id, discord_name, avatar_url):
|
2026-05-12 15:36:31 +02:00
|
|
|
|
connection = db_connection()
|
2026-06-21 16:29:32 +02:00
|
|
|
|
cursor = connection.cursor(cursor=DictCursor)
|
2026-03-02 10:16:30 +01:00
|
|
|
|
|
2026-05-12 15:36:31 +02:00
|
|
|
|
cursor.execute(
|
|
|
|
|
|
"SELECT id, discord_name, display_name, discord_avatar_url FROM players WHERE discord_id = %s",
|
|
|
|
|
|
(discord_id,)
|
|
|
|
|
|
)
|
2026-03-02 10:16:30 +01:00
|
|
|
|
player = cursor.fetchone()
|
|
|
|
|
|
|
|
|
|
|
|
if player is None:
|
|
|
|
|
|
silly_name = generate_silly_name()
|
2026-05-12 15:36:31 +02:00
|
|
|
|
cursor.execute(
|
|
|
|
|
|
"INSERT INTO players (discord_id, discord_name, display_name, discord_avatar_url) "
|
|
|
|
|
|
"VALUES (%s, %s, %s, %s)",
|
|
|
|
|
|
(discord_id, discord_name, silly_name, avatar_url)
|
|
|
|
|
|
)
|
2026-03-02 10:16:30 +01:00
|
|
|
|
connection.commit()
|
2026-05-12 15:36:31 +02:00
|
|
|
|
logger.log(f"new player added. Discord:{discord_name}")
|
|
|
|
|
|
|
|
|
|
|
|
cursor.execute(
|
|
|
|
|
|
"SELECT id, discord_name, display_name, discord_avatar_url FROM players WHERE discord_id = %s",
|
|
|
|
|
|
(discord_id,)
|
|
|
|
|
|
)
|
2026-03-02 10:16:30 +01:00
|
|
|
|
player = cursor.fetchone()
|
|
|
|
|
|
else:
|
2026-05-12 15:36:31 +02:00
|
|
|
|
cursor.execute(
|
|
|
|
|
|
"UPDATE players SET discord_name = %s, discord_avatar_url = %s WHERE discord_id = %s",
|
|
|
|
|
|
(discord_name, avatar_url, discord_id)
|
|
|
|
|
|
)
|
2026-03-02 10:16:30 +01:00
|
|
|
|
connection.commit()
|
|
|
|
|
|
|
2026-05-12 15:36:31 +02:00
|
|
|
|
cursor.execute(
|
|
|
|
|
|
"SELECT id, discord_name, display_name, discord_avatar_url FROM players WHERE discord_id = %s",
|
|
|
|
|
|
(discord_id,)
|
|
|
|
|
|
)
|
2026-03-02 10:16:30 +01:00
|
|
|
|
player = cursor.fetchone()
|
|
|
|
|
|
|
2026-05-12 15:36:31 +02:00
|
|
|
|
cursor.close()
|
2026-03-02 10:16:30 +01:00
|
|
|
|
connection.close()
|
|
|
|
|
|
return player
|
|
|
|
|
|
|
|
|
|
|
|
|
2026-05-12 15:36:31 +02:00
|
|
|
|
# -----------------------------------------------------
|
2026-07-06 22:07:47 +02:00
|
|
|
|
# Player Lists
|
2026-05-12 15:36:31 +02:00
|
|
|
|
# -----------------------------------------------------
|
2026-03-02 10:16:30 +01:00
|
|
|
|
|
2026-05-12 15:36:31 +02:00
|
|
|
|
def get_all_players():
|
2026-07-06 22:07:47 +02:00
|
|
|
|
"""All players – basic data."""
|
2026-05-12 15:36:31 +02:00
|
|
|
|
connection = db_connection()
|
2026-06-21 16:29:32 +02:00
|
|
|
|
cursor = connection.cursor(cursor=DictCursor)
|
2026-05-12 15:36:31 +02:00
|
|
|
|
|
|
|
|
|
|
cursor.execute(
|
|
|
|
|
|
"SELECT id, display_name, discord_name, discord_avatar_url FROM players "
|
|
|
|
|
|
"ORDER BY display_name ASC"
|
|
|
|
|
|
)
|
|
|
|
|
|
rows = cursor.fetchall()
|
2026-03-02 10:16:30 +01:00
|
|
|
|
|
2026-05-12 15:36:31 +02:00
|
|
|
|
cursor.close()
|
2026-03-02 10:16:30 +01:00
|
|
|
|
connection.close()
|
2026-05-12 15:36:31 +02:00
|
|
|
|
return rows
|
2026-03-02 16:17:50 +01:00
|
|
|
|
|
|
|
|
|
|
|
2026-03-03 15:49:40 +01:00
|
|
|
|
def get_all_players_from_system(system_name):
|
2026-05-12 15:36:31 +02:00
|
|
|
|
connection = db_connection()
|
2026-06-21 16:29:32 +02:00
|
|
|
|
cursor = connection.cursor(cursor=DictCursor)
|
2026-03-03 15:49:40 +01:00
|
|
|
|
|
|
|
|
|
|
query = """
|
|
|
|
|
|
SELECT DISTINCT
|
|
|
|
|
|
p.id AS player_id,
|
|
|
|
|
|
p.display_name,
|
|
|
|
|
|
p.discord_name
|
|
|
|
|
|
FROM players p
|
|
|
|
|
|
JOIN player_game_statistic stat ON p.id = stat.player_id
|
|
|
|
|
|
JOIN gamesystems sys ON stat.gamesystem_id = sys.id
|
2026-05-12 15:36:31 +02:00
|
|
|
|
WHERE sys.name = %s
|
2026-03-03 15:49:40 +01:00
|
|
|
|
ORDER BY p.display_name ASC
|
|
|
|
|
|
"""
|
|
|
|
|
|
cursor.execute(query, (system_name,))
|
|
|
|
|
|
rows = cursor.fetchall()
|
|
|
|
|
|
|
2026-05-12 15:36:31 +02:00
|
|
|
|
cursor.close()
|
|
|
|
|
|
connection.close()
|
|
|
|
|
|
return rows
|
2026-03-03 15:49:40 +01:00
|
|
|
|
|
2026-03-16 16:04:08 +01:00
|
|
|
|
|
2026-03-05 16:19:40 +01:00
|
|
|
|
def get_gamesystem_id_by_name(system_name):
|
2026-05-12 15:36:31 +02:00
|
|
|
|
connection = db_connection()
|
2026-03-05 16:19:40 +01:00
|
|
|
|
cursor = connection.cursor()
|
2026-03-03 15:49:40 +01:00
|
|
|
|
|
2026-05-12 15:36:31 +02:00
|
|
|
|
cursor.execute("SELECT id FROM gamesystems WHERE name = %s", (system_name,))
|
2026-03-05 16:19:40 +01:00
|
|
|
|
row = cursor.fetchone()
|
|
|
|
|
|
|
2026-05-12 15:36:31 +02:00
|
|
|
|
cursor.close()
|
2026-03-05 16:19:40 +01:00
|
|
|
|
connection.close()
|
|
|
|
|
|
|
2026-05-12 15:36:31 +02:00
|
|
|
|
return row[0] if row else None
|
2026-03-04 16:08:45 +01:00
|
|
|
|
|
|
|
|
|
|
|
2026-05-12 15:36:31 +02:00
|
|
|
|
# -----------------------------------------------------
|
|
|
|
|
|
# Player Statistics
|
|
|
|
|
|
# -----------------------------------------------------
|
2026-03-04 16:08:45 +01:00
|
|
|
|
|
2026-03-02 16:17:50 +01:00
|
|
|
|
def get_player_statistics(player_id):
|
2026-05-12 15:36:31 +02:00
|
|
|
|
connection = db_connection()
|
2026-06-21 16:29:32 +02:00
|
|
|
|
cursor = connection.cursor(cursor=DictCursor)
|
2026-03-02 16:17:50 +01:00
|
|
|
|
|
|
|
|
|
|
query = """
|
|
|
|
|
|
SELECT
|
|
|
|
|
|
sys.id AS gamesystem_id,
|
|
|
|
|
|
sys.name AS gamesystem_name,
|
|
|
|
|
|
sys.*,
|
|
|
|
|
|
stat.mmr,
|
|
|
|
|
|
stat.games_in_system,
|
2026-03-26 16:20:46 +01:00
|
|
|
|
stat.points,
|
|
|
|
|
|
stat.avv_points,
|
|
|
|
|
|
stat.last_played,
|
|
|
|
|
|
stat.win_rate,
|
|
|
|
|
|
stat.trend,
|
|
|
|
|
|
stat.tyrann_id,
|
|
|
|
|
|
stat.pushover_id,
|
|
|
|
|
|
stat.nemesis_id
|
2026-03-02 16:17:50 +01:00
|
|
|
|
FROM gamesystems sys
|
|
|
|
|
|
LEFT JOIN player_game_statistic stat
|
2026-05-12 15:36:31 +02:00
|
|
|
|
ON sys.id = stat.gamesystem_id AND stat.player_id = %s
|
2026-03-02 16:17:50 +01:00
|
|
|
|
"""
|
|
|
|
|
|
cursor.execute(query, (player_id,))
|
|
|
|
|
|
rows = cursor.fetchall()
|
|
|
|
|
|
|
2026-05-12 15:36:31 +02:00
|
|
|
|
cursor.close()
|
|
|
|
|
|
connection.close()
|
|
|
|
|
|
return rows
|
2026-03-02 16:17:50 +01:00
|
|
|
|
|
|
|
|
|
|
|
2026-06-09 15:23:00 +02:00
|
|
|
|
def get_player_statistic(player_id, system_id, season_id=None):
|
|
|
|
|
|
"""
|
2026-07-06 22:07:47 +02:00
|
|
|
|
- If season_id is provided: Data for this season.
|
|
|
|
|
|
- If season_id is None: Aggregated total statistics.
|
2026-06-09 15:23:00 +02:00
|
|
|
|
"""
|
|
|
|
|
|
connection = db_connection()
|
2026-06-21 16:29:32 +02:00
|
|
|
|
cursor = connection.cursor(cursor=DictCursor)
|
2026-06-09 15:23:00 +02:00
|
|
|
|
|
|
|
|
|
|
if season_id:
|
|
|
|
|
|
query = """
|
|
|
|
|
|
SELECT
|
|
|
|
|
|
sys.name AS gamesystem_name,
|
|
|
|
|
|
stat.mmr, stat.games_in_system, stat.points,
|
|
|
|
|
|
stat.avv_points, stat.last_played, stat.win_rate,
|
2026-07-01 14:15:21 +02:00
|
|
|
|
stat.trend, stat.tyrann_id, stat.pushover_id, stat.nemesis_id,
|
|
|
|
|
|
(
|
|
|
|
|
|
SELECT COUNT(*) + 1
|
|
|
|
|
|
FROM player_game_statistic rank_stat
|
|
|
|
|
|
WHERE rank_stat.gamesystem_id = %s
|
|
|
|
|
|
AND rank_stat.season_id = %s
|
|
|
|
|
|
AND rank_stat.games_in_system > 0
|
|
|
|
|
|
AND rank_stat.mmr > COALESCE(stat.mmr, 0)
|
|
|
|
|
|
) AS rank
|
2026-06-09 15:23:00 +02:00
|
|
|
|
FROM gamesystems sys
|
|
|
|
|
|
LEFT JOIN player_game_statistic stat
|
|
|
|
|
|
ON sys.id = stat.gamesystem_id
|
|
|
|
|
|
AND stat.player_id = %s
|
|
|
|
|
|
AND stat.season_id = %s
|
|
|
|
|
|
WHERE sys.id = %s
|
|
|
|
|
|
"""
|
2026-07-01 14:15:21 +02:00
|
|
|
|
cursor.execute(query, (system_id, season_id, player_id, season_id, system_id))
|
2026-06-09 15:23:00 +02:00
|
|
|
|
else:
|
|
|
|
|
|
query = """
|
|
|
|
|
|
SELECT
|
|
|
|
|
|
sys.name AS gamesystem_name,
|
2026-07-06 22:07:47 +02:00
|
|
|
|
SUM(stat.mmr) / COUNT(stat.season_id) AS mmr, -- Average MMR over seasons
|
2026-06-09 15:23:00 +02:00
|
|
|
|
SUM(stat.games_in_system) AS games_in_system,
|
|
|
|
|
|
SUM(stat.points) AS points,
|
|
|
|
|
|
SUM(stat.points) / SUM(stat.games_in_system) AS avv_points,
|
2026-07-01 14:15:21 +02:00
|
|
|
|
MAX(stat.last_played) AS last_played,
|
|
|
|
|
|
NULL AS rank
|
2026-06-09 15:23:00 +02:00
|
|
|
|
FROM gamesystems sys
|
|
|
|
|
|
LEFT JOIN player_game_statistic stat
|
|
|
|
|
|
ON sys.id = stat.gamesystem_id
|
|
|
|
|
|
AND stat.player_id = %s
|
|
|
|
|
|
WHERE sys.id = %s
|
|
|
|
|
|
GROUP BY sys.id
|
|
|
|
|
|
"""
|
|
|
|
|
|
cursor.execute(query, (player_id, system_id))
|
|
|
|
|
|
|
|
|
|
|
|
row = cursor.fetchone()
|
|
|
|
|
|
cursor.close()
|
|
|
|
|
|
connection.close()
|
2026-07-01 14:15:21 +02:00
|
|
|
|
|
|
|
|
|
|
# Sicherstellen dass rank nie None ist wenn season_id gesetzt
|
|
|
|
|
|
if row and season_id and row.get('rank') is None:
|
|
|
|
|
|
row['rank'] = 1
|
|
|
|
|
|
|
2026-06-09 15:23:00 +02:00
|
|
|
|
return row
|
|
|
|
|
|
|
|
|
|
|
|
|
2026-07-22 15:12:05 +02:00
|
|
|
|
def get_seasons_by_system(system_id):
|
|
|
|
|
|
|
2026-07-06 22:07:47 +02:00
|
|
|
|
"""Retrieves all seasons of a game system, sorted by number descending."""
|
2026-05-12 15:36:31 +02:00
|
|
|
|
connection = db_connection()
|
2026-06-21 16:29:32 +02:00
|
|
|
|
cursor = connection.cursor(cursor=DictCursor)
|
2026-05-06 14:30:30 +02:00
|
|
|
|
|
|
|
|
|
|
query = """
|
2026-06-09 15:23:00 +02:00
|
|
|
|
SELECT id, name, season_number
|
|
|
|
|
|
FROM seasons
|
|
|
|
|
|
WHERE gamesystem_id = %s
|
|
|
|
|
|
ORDER BY season_number DESC
|
2026-05-06 14:30:30 +02:00
|
|
|
|
"""
|
2026-05-21 16:00:51 +02:00
|
|
|
|
|
2026-06-25 15:26:19 +02:00
|
|
|
|
cursor.execute(query, (system_id,))
|
2026-06-09 15:23:00 +02:00
|
|
|
|
seasons = cursor.fetchall()
|
2026-03-02 16:17:50 +01:00
|
|
|
|
|
2026-05-12 15:36:31 +02:00
|
|
|
|
cursor.close()
|
|
|
|
|
|
connection.close()
|
2026-06-09 15:23:00 +02:00
|
|
|
|
return seasons
|
2026-03-04 16:08:45 +01:00
|
|
|
|
|
|
|
|
|
|
|
2026-06-09 15:23:00 +02:00
|
|
|
|
def get_player_rank(player_id, system_id, season_id):
|
2026-07-06 22:07:47 +02:00
|
|
|
|
"""Retrieves the rank of a player in a system for a specific season."""
|
2026-05-21 16:00:51 +02:00
|
|
|
|
connection = db_connection()
|
2026-06-21 16:29:32 +02:00
|
|
|
|
cursor = connection.cursor(cursor=DictCursor)
|
2026-05-21 16:00:51 +02:00
|
|
|
|
|
|
|
|
|
|
query = """
|
|
|
|
|
|
SELECT COUNT(*) + 1 AS rank
|
|
|
|
|
|
FROM player_game_statistic stat
|
|
|
|
|
|
WHERE stat.gamesystem_id = %s
|
2026-06-09 15:23:00 +02:00
|
|
|
|
AND stat.season_id = %s
|
2026-05-21 16:00:51 +02:00
|
|
|
|
AND stat.games_in_system > 0
|
|
|
|
|
|
AND stat.mmr > (
|
|
|
|
|
|
SELECT stat2.mmr
|
|
|
|
|
|
FROM player_game_statistic stat2
|
|
|
|
|
|
WHERE stat2.player_id = %s
|
|
|
|
|
|
AND stat2.gamesystem_id = %s
|
2026-06-09 15:23:00 +02:00
|
|
|
|
AND stat2.season_id = %s
|
2026-05-21 16:00:51 +02:00
|
|
|
|
)
|
|
|
|
|
|
"""
|
2026-07-06 22:07:47 +02:00
|
|
|
|
# Parameters: gamesystem, season, player, gamesystem, season
|
2026-06-09 15:23:00 +02:00
|
|
|
|
cursor.execute(query, (system_id, season_id, player_id, system_id, season_id))
|
2026-05-21 16:00:51 +02:00
|
|
|
|
row = cursor.fetchone()
|
|
|
|
|
|
|
|
|
|
|
|
cursor.close()
|
|
|
|
|
|
connection.close()
|
|
|
|
|
|
|
2026-06-09 15:23:00 +02:00
|
|
|
|
return row['rank'] if row and row['rank'] is not None else 1
|
2026-05-21 16:00:51 +02:00
|
|
|
|
|
2026-03-02 16:17:50 +01:00
|
|
|
|
|
2026-05-29 11:23:28 +02:00
|
|
|
|
|
|
|
|
|
|
def join_league(player_id, gamesystem_id):
|
2026-05-29 10:20:09 +02:00
|
|
|
|
try:
|
2026-07-06 22:07:47 +02:00
|
|
|
|
# 1. Get the correct season for this system
|
2026-05-29 11:23:28 +02:00
|
|
|
|
season_id = get_current_season_id(gamesystem_id)
|
|
|
|
|
|
|
|
|
|
|
|
connection = db_connection()
|
|
|
|
|
|
cursor = connection.cursor()
|
|
|
|
|
|
|
|
|
|
|
|
query = """
|
|
|
|
|
|
INSERT INTO player_game_statistic
|
|
|
|
|
|
(player_id, gamesystem_id, season_id)
|
|
|
|
|
|
VALUES (%s, %s, %s)
|
|
|
|
|
|
"""
|
|
|
|
|
|
cursor.execute(query, (player_id, gamesystem_id, season_id))
|
2026-05-29 10:20:09 +02:00
|
|
|
|
connection.commit()
|
2026-05-29 11:23:28 +02:00
|
|
|
|
|
2026-07-06 22:07:47 +02:00
|
|
|
|
logger.log(f"Success: Player {player_id} joined System {gamesystem_id} in Season {season_id}")
|
2026-05-29 11:23:28 +02:00
|
|
|
|
|
2026-05-29 10:23:07 +02:00
|
|
|
|
except Exception as e:
|
2026-07-06 22:07:47 +02:00
|
|
|
|
logger.log(f"ERROR joining league: {e}")
|
2026-05-29 11:23:28 +02:00
|
|
|
|
raise
|
2026-05-29 10:20:09 +02:00
|
|
|
|
finally:
|
2026-07-06 22:07:47 +02:00
|
|
|
|
# Here is a small check if the connection actually exists
|
2026-05-29 11:23:28 +02:00
|
|
|
|
if 'connection' in locals() and connection:
|
|
|
|
|
|
cursor.close()
|
|
|
|
|
|
connection.close()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2026-06-25 15:26:19 +02:00
|
|
|
|
def get_current_season_id(system_id):
|
2026-05-29 11:23:28 +02:00
|
|
|
|
connection = db_connection()
|
2026-06-21 16:29:32 +02:00
|
|
|
|
cursor = connection.cursor(cursor=DictCursor)
|
2026-05-29 11:23:28 +02:00
|
|
|
|
|
|
|
|
|
|
query = """
|
|
|
|
|
|
SELECT id FROM seasons
|
|
|
|
|
|
WHERE gamesystem_id = %s
|
|
|
|
|
|
ORDER BY start_date DESC
|
|
|
|
|
|
LIMIT 1
|
|
|
|
|
|
"""
|
2026-06-25 15:26:19 +02:00
|
|
|
|
cursor.execute(query, (system_id,))
|
2026-05-29 11:23:28 +02:00
|
|
|
|
result = cursor.fetchone()
|
|
|
|
|
|
|
|
|
|
|
|
cursor.close()
|
|
|
|
|
|
connection.close()
|
|
|
|
|
|
|
|
|
|
|
|
if result:
|
|
|
|
|
|
return result['id']
|
|
|
|
|
|
else:
|
2026-07-06 22:07:47 +02:00
|
|
|
|
# Here we know exactly which game system has no season
|
|
|
|
|
|
raise RuntimeError(f"No season found for {gamesystem_id}!")
|
2026-03-03 15:49:40 +01:00
|
|
|
|
|
|
|
|
|
|
|
2026-05-12 15:36:31 +02:00
|
|
|
|
# -----------------------------------------------------
|
2026-07-06 22:07:47 +02:00
|
|
|
|
# Matches: Reading
|
2026-05-12 15:36:31 +02:00
|
|
|
|
# -----------------------------------------------------
|
2026-03-04 16:08:45 +01:00
|
|
|
|
|
2026-03-03 15:49:40 +01:00
|
|
|
|
def get_recent_matches_for_player(player_id):
|
2026-05-12 15:36:31 +02:00
|
|
|
|
connection = db_connection()
|
2026-06-21 16:29:32 +02:00
|
|
|
|
cursor = connection.cursor(cursor=DictCursor)
|
2026-03-03 15:49:40 +01:00
|
|
|
|
|
|
|
|
|
|
query = """
|
|
|
|
|
|
SELECT
|
|
|
|
|
|
m.id AS match_id,
|
|
|
|
|
|
sys.name AS gamesystem_name,
|
|
|
|
|
|
m.player1_id,
|
|
|
|
|
|
p1.display_name AS p1_display,
|
|
|
|
|
|
p1.discord_name AS p1_discord,
|
|
|
|
|
|
m.score_player1,
|
|
|
|
|
|
m.player2_id,
|
|
|
|
|
|
p2.display_name AS p2_display,
|
|
|
|
|
|
p2.discord_name AS p2_discord,
|
|
|
|
|
|
m.score_player2,
|
|
|
|
|
|
m.played_at
|
|
|
|
|
|
FROM matches m
|
|
|
|
|
|
JOIN gamesystems sys ON m.gamesystem_id = sys.id
|
|
|
|
|
|
JOIN players p1 ON m.player1_id = p1.id
|
|
|
|
|
|
JOIN players p2 ON m.player2_id = p2.id
|
2026-05-12 15:36:31 +02:00
|
|
|
|
WHERE m.player1_id = %s OR m.player2_id = %s
|
2026-03-03 15:49:40 +01:00
|
|
|
|
ORDER BY m.played_at DESC
|
|
|
|
|
|
LIMIT 10
|
|
|
|
|
|
"""
|
|
|
|
|
|
cursor.execute(query, (player_id, player_id))
|
|
|
|
|
|
rows = cursor.fetchall()
|
|
|
|
|
|
|
2026-05-12 15:36:31 +02:00
|
|
|
|
cursor.close()
|
|
|
|
|
|
connection.close()
|
|
|
|
|
|
return rows
|
2026-03-04 16:08:45 +01:00
|
|
|
|
|
|
|
|
|
|
|
2026-03-03 15:49:40 +01:00
|
|
|
|
def add_new_match(system_name, player1_id, player2_id, score_p1, score_p2):
|
2026-06-20 22:01:56 +02:00
|
|
|
|
connection = None
|
|
|
|
|
|
try:
|
|
|
|
|
|
connection = db_connection()
|
|
|
|
|
|
cursor = connection.cursor()
|
2026-03-03 15:49:40 +01:00
|
|
|
|
|
2026-06-20 22:01:56 +02:00
|
|
|
|
cursor.execute("SELECT id FROM gamesystems WHERE name = %s", (system_name,))
|
|
|
|
|
|
sys_row = cursor.fetchone()
|
2026-03-03 15:49:40 +01:00
|
|
|
|
|
2026-06-20 22:01:56 +02:00
|
|
|
|
if not sys_row:
|
2026-07-06 22:07:47 +02:00
|
|
|
|
raise ValueError(f"Game system '{system_name}' not found.")
|
2026-03-03 15:49:40 +01:00
|
|
|
|
|
2026-06-20 22:01:56 +02:00
|
|
|
|
sys_id = sys_row[0]
|
2026-03-03 15:49:40 +01:00
|
|
|
|
|
2026-06-20 22:01:56 +02:00
|
|
|
|
query = """
|
|
|
|
|
|
INSERT INTO matches (gamesystem_id, player1_id, player2_id, score_player1, score_player2)
|
|
|
|
|
|
VALUES (%s, %s, %s, %s, %s)
|
|
|
|
|
|
"""
|
|
|
|
|
|
cursor.execute(query, (sys_id, player1_id, player2_id, score_p1, score_p2))
|
|
|
|
|
|
new_match_id = cursor.lastrowid
|
2026-03-03 15:49:40 +01:00
|
|
|
|
|
2026-06-20 22:01:56 +02:00
|
|
|
|
logger.log(
|
|
|
|
|
|
f"{get_player_name(player1_id)}:({score_p1}) posted Match. "
|
|
|
|
|
|
f"System: {system_name}, {get_player_name(player2_id)}:({score_p2})"
|
|
|
|
|
|
)
|
2026-03-10 15:34:25 +01:00
|
|
|
|
|
2026-06-20 22:01:56 +02:00
|
|
|
|
connection.commit()
|
|
|
|
|
|
return new_match_id
|
|
|
|
|
|
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
if connection:
|
|
|
|
|
|
connection.rollback()
|
2026-07-06 22:07:47 +02:00
|
|
|
|
raise # Propagate the exception
|
2026-06-20 22:01:56 +02:00
|
|
|
|
|
|
|
|
|
|
finally:
|
|
|
|
|
|
if connection:
|
|
|
|
|
|
cursor.close()
|
|
|
|
|
|
connection.close()
|
2026-03-03 15:49:40 +01:00
|
|
|
|
|
2026-03-04 16:08:45 +01:00
|
|
|
|
|
|
|
|
|
|
|
2026-03-16 16:04:08 +01:00
|
|
|
|
def save_calculated_match(calc_results: dict):
|
2026-05-12 15:36:31 +02:00
|
|
|
|
connection = db_connection()
|
2026-03-06 12:01:58 +01:00
|
|
|
|
cursor = connection.cursor()
|
|
|
|
|
|
|
2026-03-15 20:46:45 +01:00
|
|
|
|
try:
|
2026-05-12 15:36:31 +02:00
|
|
|
|
match_id = calc_results["match_id"]
|
|
|
|
|
|
winner_id = calc_results["winner_id"]
|
|
|
|
|
|
looser_id = calc_results["looser_id"]
|
2026-03-16 16:04:08 +01:00
|
|
|
|
|
|
|
|
|
|
cursor.execute(
|
2026-05-12 15:36:31 +02:00
|
|
|
|
"SELECT player1_id, player2_id, gamesystem_id FROM matches WHERE id = %s",
|
2026-03-16 16:04:08 +01:00
|
|
|
|
(match_id,)
|
|
|
|
|
|
)
|
|
|
|
|
|
row = cursor.fetchone()
|
|
|
|
|
|
if not row:
|
2026-07-06 22:07:47 +02:00
|
|
|
|
raise ValueError(f"Match ID {match_id} not found in the database.")
|
2026-03-16 16:04:08 +01:00
|
|
|
|
|
|
|
|
|
|
player1_id, player2_id, gamesystem_id = row
|
|
|
|
|
|
|
|
|
|
|
|
p1 = calc_results[player1_id]
|
|
|
|
|
|
p2 = calc_results[player2_id]
|
|
|
|
|
|
|
2026-03-15 20:46:45 +01:00
|
|
|
|
match_query = """
|
2026-03-16 16:04:08 +01:00
|
|
|
|
UPDATE matches
|
|
|
|
|
|
SET
|
2026-05-12 15:36:31 +02:00
|
|
|
|
player1_base_change = %s, player1_khorne = %s, player1_slaanesh = %s,
|
|
|
|
|
|
player1_tzeentch = %s, player1_mmr_change = %s,
|
|
|
|
|
|
player2_base_change = %s, player2_khorne = %s, player2_slaanesh = %s,
|
|
|
|
|
|
player2_tzeentch = %s, player2_mmr_change = %s,
|
|
|
|
|
|
rust_factor = %s, elo_factor = %s, point_inflation = %s,
|
2026-03-16 16:04:08 +01:00
|
|
|
|
match_is_counted = 1
|
2026-05-12 15:36:31 +02:00
|
|
|
|
WHERE id = %s
|
2026-03-15 20:46:45 +01:00
|
|
|
|
"""
|
|
|
|
|
|
cursor.execute(match_query, (
|
2026-03-16 16:04:08 +01:00
|
|
|
|
p1["base"], p1["khorne"], p1["slaanesh"], p1["tzeentch"], p1["total"],
|
|
|
|
|
|
p2["base"], p2["khorne"], p2["slaanesh"], p2["tzeentch"], p2["total"],
|
|
|
|
|
|
calc_results["rust_factor"], calc_results["elo_factor"], calc_results["point_inflation"],
|
|
|
|
|
|
match_id
|
2026-03-15 20:46:45 +01:00
|
|
|
|
))
|
|
|
|
|
|
|
2026-03-16 16:04:08 +01:00
|
|
|
|
cursor.execute(
|
2026-05-12 15:36:31 +02:00
|
|
|
|
"SELECT score_player1, score_player2 FROM matches WHERE id = %s",
|
2026-03-16 16:04:08 +01:00
|
|
|
|
(match_id,)
|
|
|
|
|
|
)
|
|
|
|
|
|
score_row = cursor.fetchone()
|
|
|
|
|
|
score_p1, score_p2 = score_row if score_row else (0, 0)
|
|
|
|
|
|
|
2026-03-15 20:46:45 +01:00
|
|
|
|
stat_query = """
|
|
|
|
|
|
UPDATE player_game_statistic
|
2026-03-16 16:04:08 +01:00
|
|
|
|
SET
|
2026-05-12 15:36:31 +02:00
|
|
|
|
mmr = mmr + %s,
|
2026-03-16 16:04:08 +01:00
|
|
|
|
games_in_system = games_in_system + 1,
|
2026-05-12 15:36:31 +02:00
|
|
|
|
points = points + %s,
|
|
|
|
|
|
avv_points = (points + %s) / (games_in_system + 1),
|
2026-03-16 16:04:08 +01:00
|
|
|
|
last_played = CURRENT_TIMESTAMP
|
2026-05-12 15:36:31 +02:00
|
|
|
|
WHERE player_id = %s AND gamesystem_id = %s
|
2026-03-15 20:46:45 +01:00
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
cursor.execute(stat_query, (
|
2026-05-12 15:36:31 +02:00
|
|
|
|
p1["total"], score_p1, score_p1, player1_id, gamesystem_id
|
2026-03-15 20:46:45 +01:00
|
|
|
|
))
|
|
|
|
|
|
cursor.execute(stat_query, (
|
2026-05-12 15:36:31 +02:00
|
|
|
|
p2["total"], score_p2, score_p2, player2_id, gamesystem_id
|
2026-03-15 20:46:45 +01:00
|
|
|
|
))
|
|
|
|
|
|
|
|
|
|
|
|
connection.commit()
|
2026-03-27 09:38:29 +01:00
|
|
|
|
logger.log(f"Match ID:{match_id} calculated.")
|
2026-03-15 20:46:45 +01:00
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
connection.rollback()
|
2026-07-06 22:07:47 +02:00
|
|
|
|
logger.log(f"CRITICAL ERROR saving the match: {e}")
|
2026-03-15 20:46:45 +01:00
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
|
finally:
|
2026-05-12 15:36:31 +02:00
|
|
|
|
cursor.close()
|
2026-03-15 20:46:45 +01:00
|
|
|
|
connection.close()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# -----------------------------------------------------
|
2026-07-06 22:07:47 +02:00
|
|
|
|
# Get Data Functions
|
2026-05-12 15:36:31 +02:00
|
|
|
|
# -----------------------------------------------------
|
|
|
|
|
|
|
2026-03-17 16:08:38 +01:00
|
|
|
|
def get_gamesystem_data(system_id):
|
2026-05-12 15:36:31 +02:00
|
|
|
|
connection = db_connection()
|
2026-06-21 16:29:32 +02:00
|
|
|
|
cursor = connection.cursor(cursor=DictCursor)
|
2026-05-12 15:36:31 +02:00
|
|
|
|
|
|
|
|
|
|
cursor.execute("SELECT * FROM gamesystems WHERE id = %s", (system_id,))
|
2026-03-17 16:08:38 +01:00
|
|
|
|
row = cursor.fetchone()
|
2026-05-12 15:36:31 +02:00
|
|
|
|
|
|
|
|
|
|
cursor.close()
|
2026-03-17 16:08:38 +01:00
|
|
|
|
connection.close()
|
2026-05-12 15:36:31 +02:00
|
|
|
|
return row
|
2026-03-17 16:08:38 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_gamesystems_data():
|
2026-05-12 15:36:31 +02:00
|
|
|
|
connection = db_connection()
|
2026-06-21 16:29:32 +02:00
|
|
|
|
cursor = connection.cursor(cursor=DictCursor)
|
2026-03-17 16:08:38 +01:00
|
|
|
|
|
|
|
|
|
|
cursor.execute("SELECT * FROM gamesystems")
|
|
|
|
|
|
rows = cursor.fetchall()
|
|
|
|
|
|
|
2026-05-12 15:36:31 +02:00
|
|
|
|
cursor.close()
|
|
|
|
|
|
connection.close()
|
|
|
|
|
|
return rows
|
2026-03-17 16:08:38 +01:00
|
|
|
|
|
2026-03-15 20:46:45 +01:00
|
|
|
|
|
2026-05-20 16:16:20 +02:00
|
|
|
|
|
2026-03-06 12:01:58 +01:00
|
|
|
|
def get_leaderboard(system_name):
|
2026-07-22 15:12:05 +02:00
|
|
|
|
"""Retrieves all players of a system sorted by MMR for the leaderboard (current season only)."""
|
2026-05-12 15:36:31 +02:00
|
|
|
|
connection = db_connection()
|
2026-06-21 16:29:32 +02:00
|
|
|
|
cursor = connection.cursor(cursor=DictCursor)
|
2026-03-06 12:01:58 +01:00
|
|
|
|
|
2026-07-06 22:07:47 +02:00
|
|
|
|
query = """
|
2026-05-20 16:16:20 +02:00
|
|
|
|
SELECT p.id, p.display_name, p.discord_name, p.discord_id, p.discord_avatar_url,
|
|
|
|
|
|
stat.mmr, stat.games_in_system, stat.wins, stat.loss, stat.avv_points
|
|
|
|
|
|
FROM players p
|
|
|
|
|
|
JOIN player_game_statistic stat ON p.id = stat.player_id
|
|
|
|
|
|
JOIN gamesystems sys ON stat.gamesystem_id = sys.id
|
2026-07-22 15:12:05 +02:00
|
|
|
|
JOIN seasons s ON stat.season_id = s.id
|
|
|
|
|
|
WHERE sys.name = %s
|
|
|
|
|
|
AND s.end_date IS NULL
|
|
|
|
|
|
AND stat.games_in_system > 0
|
2026-05-20 16:16:20 +02:00
|
|
|
|
ORDER BY stat.mmr DESC
|
2026-07-22 15:12:05 +02:00
|
|
|
|
"""
|
2026-03-06 12:01:58 +01:00
|
|
|
|
cursor.execute(query, (system_name,))
|
|
|
|
|
|
rows = cursor.fetchall()
|
|
|
|
|
|
|
2026-05-12 15:36:31 +02:00
|
|
|
|
cursor.close()
|
|
|
|
|
|
connection.close()
|
|
|
|
|
|
return rows
|
2026-03-06 21:20:48 +01:00
|
|
|
|
|
|
|
|
|
|
|
2026-03-16 16:04:08 +01:00
|
|
|
|
def get_match_by_id(match_id: int) -> dict | None:
|
2026-07-06 22:07:47 +02:00
|
|
|
|
"""Returns all match data including game system name as a dictionary."""
|
2026-05-12 15:36:31 +02:00
|
|
|
|
connection = db_connection()
|
2026-06-21 16:29:32 +02:00
|
|
|
|
cursor = connection.cursor(cursor=DictCursor)
|
2026-03-16 16:04:08 +01:00
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
|
cursor.execute("""
|
|
|
|
|
|
SELECT
|
|
|
|
|
|
m.id,
|
|
|
|
|
|
m.gamesystem_id,
|
|
|
|
|
|
g.name AS gamesystem_name,
|
|
|
|
|
|
m.player1_id,
|
|
|
|
|
|
m.score_player1,
|
|
|
|
|
|
m.player2_id,
|
|
|
|
|
|
m.score_player2,
|
|
|
|
|
|
m.played_at
|
|
|
|
|
|
FROM matches m
|
|
|
|
|
|
JOIN gamesystems g ON m.gamesystem_id = g.id
|
2026-05-12 15:36:31 +02:00
|
|
|
|
WHERE m.id = %s
|
2026-03-16 16:04:08 +01:00
|
|
|
|
""", (match_id,))
|
|
|
|
|
|
|
2026-05-12 15:36:31 +02:00
|
|
|
|
return cursor.fetchone()
|
2026-03-16 16:04:08 +01:00
|
|
|
|
|
|
|
|
|
|
except Exception as e:
|
2026-07-06 22:07:47 +02:00
|
|
|
|
logger.log(f"Error loading the match: {e}")
|
2026-03-16 16:04:08 +01:00
|
|
|
|
return None
|
|
|
|
|
|
|
|
|
|
|
|
finally:
|
2026-05-12 15:36:31 +02:00
|
|
|
|
cursor.close()
|
2026-03-16 16:04:08 +01:00
|
|
|
|
connection.close()
|
|
|
|
|
|
|
|
|
|
|
|
|
2026-03-10 15:34:25 +01:00
|
|
|
|
def get_player_name(player_id):
|
2026-07-06 22:07:47 +02:00
|
|
|
|
"""Returns the name of a player in the format 'Display Name (Discord Name)'."""
|
2026-03-10 15:34:25 +01:00
|
|
|
|
if player_id is None:
|
2026-07-06 22:07:47 +02:00
|
|
|
|
return "Unknown Player"
|
2026-03-10 15:34:25 +01:00
|
|
|
|
|
2026-05-12 15:36:31 +02:00
|
|
|
|
connection = db_connection()
|
2026-03-10 15:34:25 +01:00
|
|
|
|
cursor = connection.cursor()
|
|
|
|
|
|
|
2026-05-12 15:36:31 +02:00
|
|
|
|
cursor.execute("SELECT display_name, discord_name FROM players WHERE id = %s", (player_id,))
|
2026-03-10 15:34:25 +01:00
|
|
|
|
row = cursor.fetchone()
|
2026-05-12 15:36:31 +02:00
|
|
|
|
|
|
|
|
|
|
cursor.close()
|
2026-03-10 15:34:25 +01:00
|
|
|
|
connection.close()
|
|
|
|
|
|
|
|
|
|
|
|
if row:
|
2026-05-12 15:36:31 +02:00
|
|
|
|
return f"{row[0]} ({row[1]})"
|
2026-07-06 22:07:47 +02:00
|
|
|
|
return "Deleted Player"
|
2026-03-10 15:34:25 +01:00
|
|
|
|
|
2026-03-11 19:36:11 +01:00
|
|
|
|
|
2026-06-09 15:23:00 +02:00
|
|
|
|
def get_system_name_by_id(sys_id):
|
2026-03-10 15:34:25 +01:00
|
|
|
|
if sys_id is None:
|
2026-07-06 22:07:47 +02:00
|
|
|
|
return "Unknown System"
|
2026-05-12 15:36:31 +02:00
|
|
|
|
|
|
|
|
|
|
connection = db_connection()
|
2026-03-10 15:34:25 +01:00
|
|
|
|
cursor = connection.cursor()
|
|
|
|
|
|
|
2026-05-12 15:36:31 +02:00
|
|
|
|
cursor.execute("SELECT name FROM gamesystems WHERE id = %s", (sys_id,))
|
2026-03-10 15:34:25 +01:00
|
|
|
|
row = cursor.fetchone()
|
|
|
|
|
|
|
2026-05-12 15:36:31 +02:00
|
|
|
|
cursor.close()
|
|
|
|
|
|
connection.close()
|
2026-03-10 15:34:25 +01:00
|
|
|
|
|
2026-07-06 22:07:47 +02:00
|
|
|
|
return row[0] if row else "Deleted System"
|
2026-03-17 16:08:38 +01:00
|
|
|
|
|
|
|
|
|
|
|
2026-03-11 19:36:11 +01:00
|
|
|
|
def get_days_since_last_system_game(player_id, gamesystem_id):
|
2026-07-06 22:07:47 +02:00
|
|
|
|
"""Returns how many days the last game in a specific system was."""
|
2026-05-12 15:36:31 +02:00
|
|
|
|
connection = db_connection()
|
2026-03-11 19:36:11 +01:00
|
|
|
|
cursor = connection.cursor()
|
|
|
|
|
|
|
2026-07-06 22:07:47 +02:00
|
|
|
|
# MariaDB: DATEDIFF instead of julianday()
|
2026-03-11 19:36:11 +01:00
|
|
|
|
query = """
|
2026-05-12 15:36:31 +02:00
|
|
|
|
SELECT DATEDIFF(NOW(), last_played)
|
2026-03-11 19:36:11 +01:00
|
|
|
|
FROM player_game_statistic
|
2026-05-12 15:36:31 +02:00
|
|
|
|
WHERE player_id = %s AND gamesystem_id = %s
|
2026-03-11 19:36:11 +01:00
|
|
|
|
"""
|
|
|
|
|
|
cursor.execute(query, (player_id, gamesystem_id))
|
|
|
|
|
|
result = cursor.fetchone()
|
2026-05-12 15:36:31 +02:00
|
|
|
|
|
|
|
|
|
|
cursor.close()
|
2026-03-11 19:36:11 +01:00
|
|
|
|
connection.close()
|
|
|
|
|
|
|
|
|
|
|
|
if result and result[0] is not None:
|
2026-05-12 15:36:31 +02:00
|
|
|
|
return int(result[0])
|
2026-03-11 19:36:11 +01:00
|
|
|
|
return 0
|
|
|
|
|
|
|
|
|
|
|
|
|
2026-03-08 20:56:54 +01:00
|
|
|
|
# -----------------------------------------------------
|
2026-07-06 22:07:47 +02:00
|
|
|
|
# Matches Confirming, Deleting, Calculating, ...
|
2026-05-12 15:36:31 +02:00
|
|
|
|
# -----------------------------------------------------
|
2026-03-08 20:56:54 +01:00
|
|
|
|
|
2026-06-22 13:29:23 +02:00
|
|
|
|
def get_open_matches(player_id):
|
2026-07-06 22:07:47 +02:00
|
|
|
|
"""Retrieves all open matches (player2_check = 0)."""
|
2026-05-12 15:36:31 +02:00
|
|
|
|
connection = db_connection()
|
2026-06-21 16:29:32 +02:00
|
|
|
|
cursor = connection.cursor(cursor=DictCursor)
|
2026-03-06 21:20:48 +01:00
|
|
|
|
|
|
|
|
|
|
query = """
|
2026-06-22 13:29:23 +02:00
|
|
|
|
SELECT m.id AS match_id,
|
|
|
|
|
|
m.score_player1, m.score_player2,
|
|
|
|
|
|
m.played_at,
|
2026-03-06 21:20:48 +01:00
|
|
|
|
sys.name AS system_name,
|
2026-06-22 13:29:23 +02:00
|
|
|
|
p1.display_name AS player1_name,
|
|
|
|
|
|
p2.display_name AS player2_name,
|
|
|
|
|
|
CASE WHEN m.player1_id = %s THEN 1 ELSE 0 END AS is_submitter
|
2026-03-06 21:20:48 +01:00
|
|
|
|
FROM matches m
|
2026-06-22 15:47:34 +02:00
|
|
|
|
LEFT JOIN gamesystems sys ON m.gamesystem_id = sys.id
|
|
|
|
|
|
LEFT JOIN players p1 ON m.player1_id = p1.id
|
|
|
|
|
|
LEFT JOIN players p2 ON m.player2_id = p2.id
|
2026-06-22 13:29:23 +02:00
|
|
|
|
WHERE m.player2_check = 0
|
|
|
|
|
|
AND (m.player1_id = %s OR m.player2_id = %s)
|
2026-03-06 21:20:48 +01:00
|
|
|
|
"""
|
2026-06-22 13:29:23 +02:00
|
|
|
|
cursor.execute(query, (player_id, player_id, player_id))
|
2026-03-06 21:20:48 +01:00
|
|
|
|
rows = cursor.fetchall()
|
|
|
|
|
|
|
2026-05-12 15:36:31 +02:00
|
|
|
|
cursor.close()
|
|
|
|
|
|
connection.close()
|
2026-06-22 13:29:23 +02:00
|
|
|
|
|
|
|
|
|
|
submitted = []
|
|
|
|
|
|
to_confirm = []
|
|
|
|
|
|
|
|
|
|
|
|
for row in rows:
|
|
|
|
|
|
if row.pop('is_submitter'):
|
|
|
|
|
|
submitted.append(row)
|
|
|
|
|
|
else:
|
|
|
|
|
|
to_confirm.append(row)
|
|
|
|
|
|
|
|
|
|
|
|
return {"submitted": submitted, "to_confirm": to_confirm}
|
|
|
|
|
|
|
2026-03-06 21:20:48 +01:00
|
|
|
|
|
|
|
|
|
|
|
2026-06-22 15:47:34 +02:00
|
|
|
|
|
2026-03-10 15:34:25 +01:00
|
|
|
|
def delete_match(match_id, player_id):
|
2026-07-06 22:07:47 +02:00
|
|
|
|
"""Deletes a match completely from the database by its ID."""
|
2026-05-12 15:36:31 +02:00
|
|
|
|
connection = db_connection()
|
2026-03-06 21:20:48 +01:00
|
|
|
|
cursor = connection.cursor()
|
|
|
|
|
|
|
2026-05-12 15:36:31 +02:00
|
|
|
|
cursor.execute("DELETE FROM matches WHERE id = %s", (match_id,))
|
2026-03-27 09:38:29 +01:00
|
|
|
|
logger.log(f"Match ID{match_id} deleted from user {get_player_name(player_id)}(ID:{player_id})")
|
2026-03-06 21:20:48 +01:00
|
|
|
|
connection.commit()
|
2026-05-12 15:36:31 +02:00
|
|
|
|
|
|
|
|
|
|
cursor.close()
|
2026-03-06 21:20:48 +01:00
|
|
|
|
connection.close()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def confirm_match(match_id):
|
2026-05-12 15:36:31 +02:00
|
|
|
|
connection = db_connection()
|
2026-03-06 21:20:48 +01:00
|
|
|
|
cursor = connection.cursor()
|
|
|
|
|
|
|
2026-05-12 15:36:31 +02:00
|
|
|
|
cursor.execute("UPDATE matches SET player2_check = 1 WHERE id = %s", (match_id,))
|
2026-07-06 22:07:47 +02:00
|
|
|
|
logger.log(f"Match with ID{match_id} confirmed by Player2.")
|
2026-03-06 21:20:48 +01:00
|
|
|
|
connection.commit()
|
2026-05-12 15:36:31 +02:00
|
|
|
|
|
|
|
|
|
|
cursor.close()
|
2026-03-06 21:20:48 +01:00
|
|
|
|
connection.close()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def set_match_counted(match_id):
|
2026-07-06 22:07:47 +02:00
|
|
|
|
"""Sets the flag (1) that the match was successfully incorporated into the MMR."""
|
2026-05-12 15:36:31 +02:00
|
|
|
|
connection = db_connection()
|
2026-03-06 21:20:48 +01:00
|
|
|
|
cursor = connection.cursor()
|
|
|
|
|
|
|
2026-05-12 15:36:31 +02:00
|
|
|
|
cursor.execute("UPDATE matches SET match_is_counted = 1 WHERE id = %s", (match_id,))
|
2026-03-06 21:20:48 +01:00
|
|
|
|
connection.commit()
|
2026-05-12 15:36:31 +02:00
|
|
|
|
|
|
|
|
|
|
cursor.close()
|
2026-03-06 21:20:48 +01:00
|
|
|
|
connection.close()
|
|
|
|
|
|
|
2026-03-08 16:30:52 +01:00
|
|
|
|
|
2026-03-09 08:57:39 +01:00
|
|
|
|
|
|
|
|
|
|
def get_match_history_log(player_id):
|
2026-07-06 22:07:47 +02:00
|
|
|
|
"""Retrieves ALL matches of a player including MMR changes and factors."""
|
2026-05-12 15:36:31 +02:00
|
|
|
|
connection = db_connection()
|
2026-06-21 16:29:32 +02:00
|
|
|
|
cursor = connection.cursor(cursor=DictCursor)
|
2026-03-09 08:57:39 +01:00
|
|
|
|
|
|
|
|
|
|
query = """
|
|
|
|
|
|
SELECT m.played_at, sys.name AS gamesystem_name,
|
2026-03-18 21:24:05 +01:00
|
|
|
|
m.player1_id, p1.display_name AS p1_display, p1.discord_name AS p1_discord,
|
|
|
|
|
|
m.score_player1, m.player1_mmr_change,
|
|
|
|
|
|
m.player1_khorne, m.player1_tzeentch, m.player1_slaanesh, m.player1_base_change,
|
|
|
|
|
|
m.player2_id, p2.display_name AS p2_display, p2.discord_name AS p2_discord,
|
|
|
|
|
|
m.score_player2, m.player2_mmr_change,
|
|
|
|
|
|
m.player2_khorne, m.player2_tzeentch, m.player2_slaanesh, m.player2_base_change,
|
|
|
|
|
|
m.elo_factor, m.rust_factor,
|
2026-03-09 08:57:39 +01:00
|
|
|
|
m.player2_check, m.match_is_counted
|
|
|
|
|
|
FROM matches m
|
|
|
|
|
|
JOIN gamesystems sys ON m.gamesystem_id = sys.id
|
|
|
|
|
|
JOIN players p1 ON m.player1_id = p1.id
|
|
|
|
|
|
JOIN players p2 ON m.player2_id = p2.id
|
2026-05-12 15:36:31 +02:00
|
|
|
|
WHERE m.player1_id = %s OR m.player2_id = %s
|
2026-03-09 08:57:39 +01:00
|
|
|
|
ORDER BY m.played_at DESC
|
|
|
|
|
|
"""
|
|
|
|
|
|
cursor.execute(query, (player_id, player_id))
|
|
|
|
|
|
rows = cursor.fetchall()
|
2026-03-18 21:24:05 +01:00
|
|
|
|
|
2026-05-12 15:36:31 +02:00
|
|
|
|
cursor.close()
|
2026-03-11 19:36:11 +01:00
|
|
|
|
connection.close()
|
2026-05-12 15:36:31 +02:00
|
|
|
|
return rows
|