From 91f6b2bf8116180f0b63cdabc3ad09ddf14db456 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Wed, 14 May 2025 01:58:16 -0700 Subject: [PATCH] fix: weekly leaderboards and shooting gallery high score (#1719) * fix them again * name * Update GameMessages.cpp * Update SGCannon.cpp * Use chrono library instead --- dGame/LeaderboardManager.cpp | 45 ++++++++++--------- dGame/LeaderboardManager.h | 5 ++- dGame/dGameMessages/GameMessages.cpp | 3 +- dScripts/ActivityManager.cpp | 2 +- .../ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp | 3 +- 5 files changed, 33 insertions(+), 25 deletions(-) diff --git a/dGame/LeaderboardManager.cpp b/dGame/LeaderboardManager.cpp index 5109e663..b08bbd70 100644 --- a/dGame/LeaderboardManager.cpp +++ b/dGame/LeaderboardManager.cpp @@ -24,12 +24,13 @@ namespace LeaderboardManager { std::map leaderboardCache; } -Leaderboard::Leaderboard(const GameID gameID, const Leaderboard::InfoType infoType, const bool weekly, LWOOBJID relatedPlayer, const Leaderboard::Type leaderboardType) { +Leaderboard::Leaderboard(const GameID gameID, const Leaderboard::InfoType infoType, const bool weekly, LWOOBJID relatedPlayer, const uint32_t numResults, const Leaderboard::Type leaderboardType) { this->gameID = gameID; this->weekly = weekly; this->infoType = infoType; this->leaderboardType = leaderboardType; this->relatedPlayer = relatedPlayer; + this->numResults = numResults; } Leaderboard::~Leaderboard() { @@ -144,7 +145,7 @@ void QueryToLdf(Leaderboard& leaderboard, const std::vector } } -std::vector FilterTo10(const std::vector& leaderboard, const uint32_t relatedPlayer, const Leaderboard::InfoType infoType) { +std::vector FilterToNumResults(const std::vector& leaderboard, const uint32_t relatedPlayer, const Leaderboard::InfoType infoType, const uint32_t numResults) { std::vector toReturn; int32_t index = 0; @@ -155,18 +156,19 @@ std::vector FilterTo10(const std::vector leaderboard.size() - 10) { - toReturn.assign(leaderboard.end() - 10, leaderboard.end()); // get the bottom 10 since we are in the bottom 10 - index = leaderboard.size() - 10; + } else if (index > leaderboard.size() - numResults) { + toReturn.assign(leaderboard.end() - numResults, leaderboard.end()); // get the bottom 10 since we are in the bottom 10 + index = leaderboard.size() - numResults; } else { - toReturn.assign(leaderboard.begin() + index - 5, leaderboard.begin() + index + 5); // get the 5 above and below - index -= 5; + auto half = numResults / 2; + toReturn.assign(leaderboard.begin() + index - half, leaderboard.begin() + index + half); // get the 5 above and below + index -= half; } int32_t i = index; @@ -178,14 +180,16 @@ std::vector FilterTo10(const std::vector FilterWeeklies(const std::vector& leaderboard) { + using namespace std::chrono; // Filter the leaderboard to only include entries from the last week - const auto currentTime = std::chrono::system_clock::now(); - auto epochTime = currentTime.time_since_epoch().count(); - constexpr auto SECONDS_IN_A_WEEK = 60 * 60 * 24 * 7; // if you think im taking leap seconds into account thats cute. + const auto epochTime = system_clock::now(); + constexpr auto oneWeek = weeks(1); std::vector weeklyLeaderboard; for (const auto& entry : leaderboard) { - if (epochTime - entry.lastPlayedTimestamp < SECONDS_IN_A_WEEK) { + const sys_time asSysTime(seconds(entry.lastPlayedTimestamp)); + const auto timeDiff = epochTime - asSysTime; + if (timeDiff < oneWeek) { weeklyLeaderboard.push_back(entry); } } @@ -213,14 +217,15 @@ std::vector ProcessLeaderboard( const std::vector& leaderboard, const bool weekly, const Leaderboard::InfoType infoType, - const uint32_t relatedPlayer) { + const uint32_t relatedPlayer, + const uint32_t numResults) { std::vector toReturn; if (infoType == Leaderboard::InfoType::Friends) { const auto friendsLeaderboard = FilterFriends(leaderboard, relatedPlayer); - toReturn = FilterTo10(weekly ? FilterWeeklies(friendsLeaderboard) : friendsLeaderboard, relatedPlayer, infoType); + toReturn = FilterToNumResults(weekly ? FilterWeeklies(friendsLeaderboard) : friendsLeaderboard, relatedPlayer, infoType, numResults); } else { - toReturn = FilterTo10(weekly ? FilterWeeklies(leaderboard) : leaderboard, relatedPlayer, infoType); + toReturn = FilterToNumResults(weekly ? FilterWeeklies(leaderboard) : leaderboard, relatedPlayer, infoType, numResults); } return toReturn; @@ -255,7 +260,7 @@ void Leaderboard::SetupLeaderboard(bool weekly) { break; } - const auto processedLeaderboard = ProcessLeaderboard(leaderboardRes, weekly, infoType, relatedPlayer); + const auto processedLeaderboard = ProcessLeaderboard(leaderboardRes, weekly, infoType, relatedPlayer, numResults); QueryToLdf(*this, processedLeaderboard); } @@ -301,8 +306,8 @@ void LeaderboardManager::SaveScore(const LWOOBJID& playerID, const GameID activi } } -void LeaderboardManager::SendLeaderboard(const GameID gameID, const Leaderboard::InfoType infoType, const bool weekly, const LWOOBJID playerID, const LWOOBJID targetID) { - Leaderboard leaderboard(gameID, infoType, weekly, playerID, GetLeaderboardType(gameID)); +void LeaderboardManager::SendLeaderboard(const GameID gameID, const Leaderboard::InfoType infoType, const bool weekly, const LWOOBJID playerID, const LWOOBJID targetID, const uint32_t numResults) { + Leaderboard leaderboard(gameID, infoType, weekly, playerID, numResults, GetLeaderboardType(gameID)); leaderboard.SetupLeaderboard(weekly); leaderboard.Send(targetID); } diff --git a/dGame/LeaderboardManager.h b/dGame/LeaderboardManager.h index af879573..760d282e 100644 --- a/dGame/LeaderboardManager.h +++ b/dGame/LeaderboardManager.h @@ -37,7 +37,7 @@ public: None }; Leaderboard() = delete; - Leaderboard(const GameID gameID, const Leaderboard::InfoType infoType, const bool weekly, LWOOBJID relatedPlayer, const Leaderboard::Type = None); + Leaderboard(const GameID gameID, const Leaderboard::InfoType infoType, const bool weekly, LWOOBJID relatedPlayer, const uint32_t numResults, const Leaderboard::Type = None); ~Leaderboard(); @@ -79,6 +79,7 @@ private: InfoType infoType; Leaderboard::Type leaderboardType; bool weekly; + uint32_t numResults; public: LeaderboardEntry& PushBackEntry() { return entries.emplace_back(); @@ -90,7 +91,7 @@ public: }; namespace LeaderboardManager { - void SendLeaderboard(const GameID gameID, const Leaderboard::InfoType infoType, const bool weekly, const LWOOBJID playerID, const LWOOBJID targetID); + void SendLeaderboard(const GameID gameID, const Leaderboard::InfoType infoType, const bool weekly, const LWOOBJID playerID, const LWOOBJID targetID, const uint32_t numResults); void SaveScore(const LWOOBJID& playerID, const GameID activityId, const float primaryScore, const float secondaryScore = 0, const float tertiaryScore = 0); diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index d1f2c587..3008fbdd 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -1698,7 +1698,8 @@ void GameMessages::HandleRequestActivitySummaryLeaderboardData(RakNet::BitStream bool weekly = inStream.ReadBit(); - LeaderboardManager::SendLeaderboard(gameID, queryType, weekly, entity->GetObjectID(), entity->GetObjectID()); + // The client won't accept more than 10 results even if we wanted it to + LeaderboardManager::SendLeaderboard(gameID, queryType, weekly, entity->GetObjectID(), entity->GetObjectID(), 10); } void GameMessages::HandleActivityStateChangeRequest(RakNet::BitStream& inStream, Entity* entity) { diff --git a/dScripts/ActivityManager.cpp b/dScripts/ActivityManager.cpp index 14cb9ed0..68ee79e4 100644 --- a/dScripts/ActivityManager.cpp +++ b/dScripts/ActivityManager.cpp @@ -121,7 +121,7 @@ void ActivityManager::GetLeaderboardData(Entity* self, const LWOOBJID playerID, auto* sac = self->GetComponent(); uint32_t gameID = sac != nullptr ? sac->GetActivityID() : self->GetLOT(); // Save the new score to the leaderboard and show the leaderboard to the player - LeaderboardManager::SendLeaderboard(activityID, Leaderboard::InfoType::MyStanding, false, playerID, self->GetObjectID()); + LeaderboardManager::SendLeaderboard(activityID, Leaderboard::InfoType::MyStanding, false, playerID, self->GetObjectID(), numResults); } void ActivityManager::ActivityTimerStart(Entity* self, const std::string& timerName, const float_t updateInterval, diff --git a/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp b/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp index 14900f67..71a8b50a 100644 --- a/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp +++ b/dScripts/ai/MINIGAME/SG_GF/SERVER/SGCannon.cpp @@ -342,7 +342,8 @@ void SGCannon::StartGame(Entity* self) { auto* player = Game::entityManager->GetEntity(self->GetVar(PlayerIDVariable)); if (player != nullptr) { - GetLeaderboardData(self, player->GetObjectID(), GetActivityID(self), 1); + // The client cant accept more than 10 results. + GetLeaderboardData(self, player->GetObjectID(), GetConstants().activityID, 10); LOG("Sending ActivityStart"); GameMessages::SendActivityStart(self->GetObjectID(), player->GetSystemAddress());