From e56d4dfbca6977995cbe1ea65245805d8e66ea08 Mon Sep 17 00:00:00 2001 From: David Markowitz Date: Wed, 4 Dec 2024 00:25:09 -0800 Subject: [PATCH] fix racing leaderboard --- dDatabase/GameDatabase/ITables/ILeaderboard.h | 3 +- dDatabase/GameDatabase/MySQL/MySQLDatabase.h | 3 +- .../GameDatabase/MySQL/Tables/Leaderboard.cpp | 35 ++++++++++++++----- .../GameDatabase/TestSQL/TestSQLDatabase.h | 9 ++--- dGame/LeaderboardManager.cpp | 12 ++++--- 5 files changed, 43 insertions(+), 19 deletions(-) diff --git a/dDatabase/GameDatabase/ITables/ILeaderboard.h b/dDatabase/GameDatabase/ITables/ILeaderboard.h index b685f934..fc4164bc 100644 --- a/dDatabase/GameDatabase/ITables/ILeaderboard.h +++ b/dDatabase/GameDatabase/ITables/ILeaderboard.h @@ -32,7 +32,8 @@ public: // Get the donation total for the given activity id. virtual std::optional GetDonationTotal(const uint32_t activityId) = 0; - virtual std::vector GetDefaultLeaderboard(const uint32_t activityId) = 0; + virtual std::vector GetDescendingLeaderboard(const uint32_t activityId) = 0; + virtual std::vector GetAscendingLeaderboard(const uint32_t activityId) = 0; virtual std::vector GetNsLeaderboard(const uint32_t activityId) = 0; virtual std::vector GetAgsLeaderboard(const uint32_t activityId) = 0; virtual std::optional GetPlayerScore(const uint32_t playerId, const uint32_t gameId) = 0; diff --git a/dDatabase/GameDatabase/MySQL/MySQLDatabase.h b/dDatabase/GameDatabase/MySQL/MySQLDatabase.h index bdbdf851..4e7d19a4 100644 --- a/dDatabase/GameDatabase/MySQL/MySQLDatabase.h +++ b/dDatabase/GameDatabase/MySQL/MySQLDatabase.h @@ -114,7 +114,8 @@ public: void RemoveBehavior(const int32_t characterId) override; void UpdateAccountGmLevel(const uint32_t accountId, const eGameMasterLevel gmLevel) override; std::optional GetProperties(const IProperty::PropertyLookup& params) override; - std::vector GetDefaultLeaderboard(const uint32_t activityId) override; + std::vector GetDescendingLeaderboard(const uint32_t activityId) override; + std::vector GetAscendingLeaderboard(const uint32_t activityId) override; std::vector GetNsLeaderboard(const uint32_t activityId) override; std::vector GetAgsLeaderboard(const uint32_t activityId) override; void SaveScore(const uint32_t playerId, const uint32_t gameId, const Score& score) override; diff --git a/dDatabase/GameDatabase/MySQL/Tables/Leaderboard.cpp b/dDatabase/GameDatabase/MySQL/Tables/Leaderboard.cpp index 5c5c0521..a6734030 100644 --- a/dDatabase/GameDatabase/MySQL/Tables/Leaderboard.cpp +++ b/dDatabase/GameDatabase/MySQL/Tables/Leaderboard.cpp @@ -23,9 +23,9 @@ std::vector ProcessQuery(UniqueResultSet& rows) { entry.charId = rows->getUInt("character_id"); entry.lastPlayedTimestamp = rows->getUInt("lp_unix"); - entry.primaryScore = rows->getUInt("primaryScore"); - entry.secondaryScore = rows->getUInt("secondaryScore"); - entry.tertiaryScore = rows->getUInt("tertiaryScore"); + 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"); @@ -35,11 +35,16 @@ std::vector ProcessQuery(UniqueResultSet& rows) { return entries; } -std::vector MySQLDatabase::GetDefaultLeaderboard(const uint32_t activityId) { +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;" : @@ -49,22 +54,34 @@ std::vector MySQLDatabase::GetAgsLeaderboard(const uint32_t } 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 ASC, secondaryscore DESC, tertiaryScore ASC, last_played ASC;", 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); } std::optional MySQLDatabase::GetPlayerScore(const uint32_t playerId, const uint32_t gameId) { - return std::nullopt; + 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); } diff --git a/dDatabase/GameDatabase/TestSQL/TestSQLDatabase.h b/dDatabase/GameDatabase/TestSQL/TestSQLDatabase.h index 933abf53..c2a3950a 100644 --- a/dDatabase/GameDatabase/TestSQL/TestSQLDatabase.h +++ b/dDatabase/GameDatabase/TestSQL/TestSQLDatabase.h @@ -91,12 +91,13 @@ class TestSQLDatabase : public GameDatabase { void RemoveBehavior(const int32_t behaviorId) override; void UpdateAccountGmLevel(const uint32_t accountId, const eGameMasterLevel gmLevel) override; std::optional GetProperties(const IProperty::PropertyLookup& params) override { return {}; }; - std::vector GetDefaultLeaderboard(const uint32_t activityId) override {return {};}; - std::vector GetNsLeaderboard(const uint32_t activityId) override {return {};}; - std::vector GetAgsLeaderboard(const uint32_t activityId) override {return {};}; + std::vector GetDescendingLeaderboard(const uint32_t activityId) override { return {}; }; + std::vector GetAscendingLeaderboard(const uint32_t activityId) override { return {}; }; + std::vector GetNsLeaderboard(const uint32_t activityId) override { return {}; }; + std::vector GetAgsLeaderboard(const uint32_t activityId) override { return {}; }; void SaveScore(const uint32_t playerId, const uint32_t gameId, const Score& score) override {}; void UpdateScore(const uint32_t playerId, const uint32_t gameId, const Score& score) override {}; - std::optional GetPlayerScore(const uint32_t playerId, const uint32_t gameId) override {return {};}; + std::optional GetPlayerScore(const uint32_t playerId, const uint32_t gameId) override { return {}; }; void IncrementNumWins(const uint32_t playerId, const uint32_t gameId) override {}; void InsertUgcBuild(const std::string& modules, const LWOOBJID bigId, const std::optional characterId) override {}; void DeleteUgcBuild(const LWOOBJID bigId) override {}; diff --git a/dGame/LeaderboardManager.cpp b/dGame/LeaderboardManager.cpp index e4b9db35..1d14a8ab 100644 --- a/dGame/LeaderboardManager.cpp +++ b/dGame/LeaderboardManager.cpp @@ -198,7 +198,10 @@ std::vector FilterFriends(const std::vectorGetFriendsList(relatedPlayer); std::vector friendsLeaderboard; for (const auto& entry : leaderboard) { - if (std::ranges::find_if(friendOfPlayer, [&entry](const FriendData& data) { return entry.charId == data.friendID; }) != friendOfPlayer.end()) { + const auto res = std::ranges::find_if(friendOfPlayer, [&entry, relatedPlayer](const FriendData& data) { + return entry.charId == data.friendID || entry.charId == relatedPlayer; + }); + if (res != friendOfPlayer.cend()) { friendsLeaderboard.push_back(entry); } } @@ -234,11 +237,12 @@ void Leaderboard::SetupLeaderboard(bool weekly) { case Type::Survival: leaderboardRes = Database::Get()->GetAgsLeaderboard(gameID); break; - case Type::ShootingGallery: - [[fallthrough]]; case Type::Racing: [[fallthrough]]; case Type::MonumentRace: + leaderboardRes = Database::Get()->GetAscendingLeaderboard(gameID); + break; + case Type::ShootingGallery: [[fallthrough]]; case Type::FootRace: [[fallthrough]]; @@ -247,7 +251,7 @@ void Leaderboard::SetupLeaderboard(bool weekly) { case Type::None: [[fallthrough]]; default: - leaderboardRes = Database::Get()->GetDefaultLeaderboard(gameID); + leaderboardRes = Database::Get()->GetDescendingLeaderboard(gameID); break; }