fix: weekly leaderboards and shooting gallery high score (#1719)

* fix them again

* name

* Update GameMessages.cpp

* Update SGCannon.cpp

* Use chrono library instead
This commit is contained in:
David Markowitz 2025-05-14 01:58:16 -07:00 committed by GitHub
parent 01917841cb
commit 91f6b2bf81
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 33 additions and 25 deletions

View File

@ -24,12 +24,13 @@ namespace LeaderboardManager {
std::map<GameID, Leaderboard::Type> leaderboardCache; std::map<GameID, Leaderboard::Type> 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->gameID = gameID;
this->weekly = weekly; this->weekly = weekly;
this->infoType = infoType; this->infoType = infoType;
this->leaderboardType = leaderboardType; this->leaderboardType = leaderboardType;
this->relatedPlayer = relatedPlayer; this->relatedPlayer = relatedPlayer;
this->numResults = numResults;
} }
Leaderboard::~Leaderboard() { Leaderboard::~Leaderboard() {
@ -144,7 +145,7 @@ void QueryToLdf(Leaderboard& leaderboard, const std::vector<ILeaderboard::Entry>
} }
} }
std::vector<ILeaderboard::Entry> FilterTo10(const std::vector<ILeaderboard::Entry>& leaderboard, const uint32_t relatedPlayer, const Leaderboard::InfoType infoType) { std::vector<ILeaderboard::Entry> FilterToNumResults(const std::vector<ILeaderboard::Entry>& leaderboard, const uint32_t relatedPlayer, const Leaderboard::InfoType infoType, const uint32_t numResults) {
std::vector<ILeaderboard::Entry> toReturn; std::vector<ILeaderboard::Entry> toReturn;
int32_t index = 0; int32_t index = 0;
@ -155,18 +156,19 @@ std::vector<ILeaderboard::Entry> FilterTo10(const std::vector<ILeaderboard::Entr
} }
} }
if (leaderboard.size() < 10) { if (leaderboard.size() < numResults) {
toReturn.assign(leaderboard.begin(), leaderboard.end()); toReturn.assign(leaderboard.begin(), leaderboard.end());
index = 0; index = 0;
} else if (index < 10) { } else if (index < numResults) {
toReturn.assign(leaderboard.begin(), leaderboard.begin() + 10); // get the top 10 since we are in the top 10 toReturn.assign(leaderboard.begin(), leaderboard.begin() + numResults); // get the top 10 since we are in the top 10
index = 0; index = 0;
} else if (index > leaderboard.size() - 10) { } else if (index > leaderboard.size() - numResults) {
toReturn.assign(leaderboard.end() - 10, leaderboard.end()); // get the bottom 10 since we are in the bottom 10 toReturn.assign(leaderboard.end() - numResults, leaderboard.end()); // get the bottom 10 since we are in the bottom 10
index = leaderboard.size() - 10; index = leaderboard.size() - numResults;
} else { } else {
toReturn.assign(leaderboard.begin() + index - 5, leaderboard.begin() + index + 5); // get the 5 above and below auto half = numResults / 2;
index -= 5; toReturn.assign(leaderboard.begin() + index - half, leaderboard.begin() + index + half); // get the 5 above and below
index -= half;
} }
int32_t i = index; int32_t i = index;
@ -178,14 +180,16 @@ std::vector<ILeaderboard::Entry> FilterTo10(const std::vector<ILeaderboard::Entr
} }
std::vector<ILeaderboard::Entry> FilterWeeklies(const std::vector<ILeaderboard::Entry>& leaderboard) { std::vector<ILeaderboard::Entry> FilterWeeklies(const std::vector<ILeaderboard::Entry>& leaderboard) {
using namespace std::chrono;
// Filter the leaderboard to only include entries from the last week // Filter the leaderboard to only include entries from the last week
const auto currentTime = std::chrono::system_clock::now(); const auto epochTime = system_clock::now();
auto epochTime = currentTime.time_since_epoch().count(); constexpr auto oneWeek = weeks(1);
constexpr auto SECONDS_IN_A_WEEK = 60 * 60 * 24 * 7; // if you think im taking leap seconds into account thats cute.
std::vector<ILeaderboard::Entry> weeklyLeaderboard; std::vector<ILeaderboard::Entry> weeklyLeaderboard;
for (const auto& entry : leaderboard) { for (const auto& entry : leaderboard) {
if (epochTime - entry.lastPlayedTimestamp < SECONDS_IN_A_WEEK) { const sys_time<seconds> asSysTime(seconds(entry.lastPlayedTimestamp));
const auto timeDiff = epochTime - asSysTime;
if (timeDiff < oneWeek) {
weeklyLeaderboard.push_back(entry); weeklyLeaderboard.push_back(entry);
} }
} }
@ -213,14 +217,15 @@ std::vector<ILeaderboard::Entry> ProcessLeaderboard(
const std::vector<ILeaderboard::Entry>& leaderboard, const std::vector<ILeaderboard::Entry>& leaderboard,
const bool weekly, const bool weekly,
const Leaderboard::InfoType infoType, const Leaderboard::InfoType infoType,
const uint32_t relatedPlayer) { const uint32_t relatedPlayer,
const uint32_t numResults) {
std::vector<ILeaderboard::Entry> toReturn; std::vector<ILeaderboard::Entry> toReturn;
if (infoType == Leaderboard::InfoType::Friends) { if (infoType == Leaderboard::InfoType::Friends) {
const auto friendsLeaderboard = FilterFriends(leaderboard, relatedPlayer); const auto friendsLeaderboard = FilterFriends(leaderboard, relatedPlayer);
toReturn = FilterTo10(weekly ? FilterWeeklies(friendsLeaderboard) : friendsLeaderboard, relatedPlayer, infoType); toReturn = FilterToNumResults(weekly ? FilterWeeklies(friendsLeaderboard) : friendsLeaderboard, relatedPlayer, infoType, numResults);
} else { } else {
toReturn = FilterTo10(weekly ? FilterWeeklies(leaderboard) : leaderboard, relatedPlayer, infoType); toReturn = FilterToNumResults(weekly ? FilterWeeklies(leaderboard) : leaderboard, relatedPlayer, infoType, numResults);
} }
return toReturn; return toReturn;
@ -255,7 +260,7 @@ void Leaderboard::SetupLeaderboard(bool weekly) {
break; break;
} }
const auto processedLeaderboard = ProcessLeaderboard(leaderboardRes, weekly, infoType, relatedPlayer); const auto processedLeaderboard = ProcessLeaderboard(leaderboardRes, weekly, infoType, relatedPlayer, numResults);
QueryToLdf(*this, processedLeaderboard); 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) { 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, GetLeaderboardType(gameID)); Leaderboard leaderboard(gameID, infoType, weekly, playerID, numResults, GetLeaderboardType(gameID));
leaderboard.SetupLeaderboard(weekly); leaderboard.SetupLeaderboard(weekly);
leaderboard.Send(targetID); leaderboard.Send(targetID);
} }

View File

@ -37,7 +37,7 @@ public:
None None
}; };
Leaderboard() = delete; 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(); ~Leaderboard();
@ -79,6 +79,7 @@ private:
InfoType infoType; InfoType infoType;
Leaderboard::Type leaderboardType; Leaderboard::Type leaderboardType;
bool weekly; bool weekly;
uint32_t numResults;
public: public:
LeaderboardEntry& PushBackEntry() { LeaderboardEntry& PushBackEntry() {
return entries.emplace_back(); return entries.emplace_back();
@ -90,7 +91,7 @@ public:
}; };
namespace LeaderboardManager { 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); void SaveScore(const LWOOBJID& playerID, const GameID activityId, const float primaryScore, const float secondaryScore = 0, const float tertiaryScore = 0);

View File

@ -1698,7 +1698,8 @@ void GameMessages::HandleRequestActivitySummaryLeaderboardData(RakNet::BitStream
bool weekly = inStream.ReadBit(); 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) { void GameMessages::HandleActivityStateChangeRequest(RakNet::BitStream& inStream, Entity* entity) {

View File

@ -121,7 +121,7 @@ void ActivityManager::GetLeaderboardData(Entity* self, const LWOOBJID playerID,
auto* sac = self->GetComponent<ScriptedActivityComponent>(); auto* sac = self->GetComponent<ScriptedActivityComponent>();
uint32_t gameID = sac != nullptr ? sac->GetActivityID() : self->GetLOT(); uint32_t gameID = sac != nullptr ? sac->GetActivityID() : self->GetLOT();
// Save the new score to the leaderboard and show the leaderboard to the player // 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, void ActivityManager::ActivityTimerStart(Entity* self, const std::string& timerName, const float_t updateInterval,

View File

@ -342,7 +342,8 @@ void SGCannon::StartGame(Entity* self) {
auto* player = Game::entityManager->GetEntity(self->GetVar<LWOOBJID>(PlayerIDVariable)); auto* player = Game::entityManager->GetEntity(self->GetVar<LWOOBJID>(PlayerIDVariable));
if (player != nullptr) { 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"); LOG("Sending ActivityStart");
GameMessages::SendActivityStart(self->GetObjectID(), player->GetSystemAddress()); GameMessages::SendActivityStart(self->GetObjectID(), player->GetSystemAddress());