#include "MySQLDatabase.h" #include "Game.h" #include "Logger.h" #include "dConfig.h" std::optional MySQLDatabase::GetDonationTotal(const uint32_t activityId) { auto donation_total = ExecuteSelect("SELECT SUM(primaryScore) as donation_total FROM leaderboard WHERE game_id = ?;", activityId); if (!donation_total->next()) { return std::nullopt; } return donation_total->getUInt("donation_total"); } std::vector ProcessQuery(UniqueResultSet& rows) { std::vector entries; entries.reserve(rows->rowsCount()); while (rows->next()) { auto& entry = entries.emplace_back(); entry.charId = rows->getUInt("character_id"); entry.lastPlayedTimestamp = rows->getUInt("lp_unix"); entry.primaryScore = rows->getFloat("primaryScore"); entry.secondaryScore = rows->getFloat("secondaryScore"); entry.tertiaryScore = rows->getFloat("tertiaryScore"); entry.numWins = rows->getUInt("numWins"); entry.numTimesPlayed = rows->getUInt("timesPlayed"); entry.name = rows->getString("char_name"); // entry.ranking is never set because its calculated in leaderboard in code. } return entries; } std::vector MySQLDatabase::GetDescendingLeaderboard(const uint32_t activityId) { auto leaderboard = ExecuteSelect("SELECT *, UNIX_TIMESTAMP(last_played) as lp_unix, ci.name as char_name FROM leaderboard lb JOIN charinfo ci on ci.id = lb.character_id where game_id = ? ORDER BY primaryscore DESC, secondaryscore DESC, tertiaryScore DESC, last_played ASC;", activityId); return ProcessQuery(leaderboard); } std::vector MySQLDatabase::GetAscendingLeaderboard(const uint32_t activityId) { auto leaderboard = ExecuteSelect("SELECT *, UNIX_TIMESTAMP(last_played) as lp_unix, ci.name as char_name FROM leaderboard lb JOIN charinfo ci on ci.id = lb.character_id where game_id = ? ORDER BY primaryscore ASC, secondaryscore ASC, tertiaryScore ASC, last_played ASC;", activityId); return ProcessQuery(leaderboard); } std::vector MySQLDatabase::GetAgsLeaderboard(const uint32_t activityId) { auto query = Game::config->GetValue("classic_survival_scoring") != "1" ? "SELECT *, UNIX_TIMESTAMP(last_played) as lp_unix, ci.name as char_name FROM leaderboard lb JOIN charinfo ci on ci.id = lb.character_id where game_id = ? ORDER BY primaryscore DESC, secondaryscore DESC, tertiaryScore DESC, last_played ASC;" : "SELECT *, UNIX_TIMESTAMP(last_played) as lp_unix, ci.name as char_name FROM leaderboard lb JOIN charinfo ci on ci.id = lb.character_id where game_id = ? ORDER BY secondaryscore DESC, primaryscore DESC, tertiaryScore DESC, last_played ASC;"; auto leaderboard = ExecuteSelect(query, activityId); return ProcessQuery(leaderboard); } std::vector MySQLDatabase::GetNsLeaderboard(const uint32_t activityId) { auto leaderboard = ExecuteSelect("SELECT *, UNIX_TIMESTAMP(last_played) as lp_unix, ci.name as char_name FROM leaderboard lb JOIN charinfo ci on ci.id = lb.character_id where game_id = ? ORDER BY primaryscore DESC, secondaryscore ASC, tertiaryScore DESC, last_played ASC;", activityId); return ProcessQuery(leaderboard); } void MySQLDatabase::SaveScore(const uint32_t playerId, const uint32_t gameId, const Score& score) { ExecuteInsert("INSERT leaderboard SET primaryScore = ?, secondaryScore = ?, tertiaryScore = ?, character_id = ?, game_id = ?;", score.primaryScore, score.secondaryScore, score.tertiaryScore, playerId, gameId); } void MySQLDatabase::UpdateScore(const uint32_t playerId, const uint32_t gameId, const Score& score) { ExecuteInsert("UPDATE leaderboard SET primaryScore = ?, secondaryScore = ?, tertiaryScore = ?, timesPlayed = timesPlayed + 1 WHERE character_id = ? AND game_id = ?;", score.primaryScore, score.secondaryScore, score.tertiaryScore, playerId, gameId); } void MySQLDatabase::IncrementTimesPlayed(const uint32_t playerId, const uint32_t gameId) { ExecuteUpdate("UPDATE leaderboard SET timesPlayed = timesPlayed + 1 WHERE character_id = ? AND game_id = ?;", playerId, gameId); } std::optional MySQLDatabase::GetPlayerScore(const uint32_t playerId, const uint32_t gameId) { std::optional toReturn = std::nullopt; auto res = ExecuteSelect("SELECT * FROM leaderboard WHERE character_id = ? AND game_id = ?;", playerId, gameId); if (res->next()) { toReturn = ILeaderboard::Score{ .primaryScore = res->getFloat("primaryScore"), .secondaryScore = res->getFloat("secondaryScore"), .tertiaryScore = res->getFloat("tertiaryScore") }; } return toReturn; } void MySQLDatabase::IncrementNumWins(const uint32_t playerId, const uint32_t gameId) { ExecuteUpdate("UPDATE leaderboard SET numWins = numWins + 1 WHERE character_id = ? AND game_id = ?;", playerId, gameId); }