fix racing leaderboard

This commit is contained in:
David Markowitz 2024-12-04 00:25:09 -08:00
parent 0ce02cac87
commit e56d4dfbca
5 changed files with 43 additions and 19 deletions

View File

@ -32,7 +32,8 @@ public:
// Get the donation total for the given activity id. // Get the donation total for the given activity id.
virtual std::optional<uint32_t> GetDonationTotal(const uint32_t activityId) = 0; virtual std::optional<uint32_t> GetDonationTotal(const uint32_t activityId) = 0;
virtual std::vector<ILeaderboard::Entry> GetDefaultLeaderboard(const uint32_t activityId) = 0; virtual std::vector<ILeaderboard::Entry> GetDescendingLeaderboard(const uint32_t activityId) = 0;
virtual std::vector<ILeaderboard::Entry> GetAscendingLeaderboard(const uint32_t activityId) = 0;
virtual std::vector<ILeaderboard::Entry> GetNsLeaderboard(const uint32_t activityId) = 0; virtual std::vector<ILeaderboard::Entry> GetNsLeaderboard(const uint32_t activityId) = 0;
virtual std::vector<ILeaderboard::Entry> GetAgsLeaderboard(const uint32_t activityId) = 0; virtual std::vector<ILeaderboard::Entry> GetAgsLeaderboard(const uint32_t activityId) = 0;
virtual std::optional<Score> GetPlayerScore(const uint32_t playerId, const uint32_t gameId) = 0; virtual std::optional<Score> GetPlayerScore(const uint32_t playerId, const uint32_t gameId) = 0;

View File

@ -114,7 +114,8 @@ public:
void RemoveBehavior(const int32_t characterId) override; void RemoveBehavior(const int32_t characterId) override;
void UpdateAccountGmLevel(const uint32_t accountId, const eGameMasterLevel gmLevel) override; void UpdateAccountGmLevel(const uint32_t accountId, const eGameMasterLevel gmLevel) override;
std::optional<IProperty::PropertyEntranceResult> GetProperties(const IProperty::PropertyLookup& params) override; std::optional<IProperty::PropertyEntranceResult> GetProperties(const IProperty::PropertyLookup& params) override;
std::vector<ILeaderboard::Entry> GetDefaultLeaderboard(const uint32_t activityId) override; std::vector<ILeaderboard::Entry> GetDescendingLeaderboard(const uint32_t activityId) override;
std::vector<ILeaderboard::Entry> GetAscendingLeaderboard(const uint32_t activityId) override;
std::vector<ILeaderboard::Entry> GetNsLeaderboard(const uint32_t activityId) override; std::vector<ILeaderboard::Entry> GetNsLeaderboard(const uint32_t activityId) override;
std::vector<ILeaderboard::Entry> GetAgsLeaderboard(const uint32_t activityId) override; std::vector<ILeaderboard::Entry> GetAgsLeaderboard(const uint32_t activityId) override;
void SaveScore(const uint32_t playerId, const uint32_t gameId, const Score& score) override; void SaveScore(const uint32_t playerId, const uint32_t gameId, const Score& score) override;

View File

@ -23,9 +23,9 @@ std::vector<ILeaderboard::Entry> ProcessQuery(UniqueResultSet& rows) {
entry.charId = rows->getUInt("character_id"); entry.charId = rows->getUInt("character_id");
entry.lastPlayedTimestamp = rows->getUInt("lp_unix"); entry.lastPlayedTimestamp = rows->getUInt("lp_unix");
entry.primaryScore = rows->getUInt("primaryScore"); entry.primaryScore = rows->getFloat("primaryScore");
entry.secondaryScore = rows->getUInt("secondaryScore"); entry.secondaryScore = rows->getFloat("secondaryScore");
entry.tertiaryScore = rows->getUInt("tertiaryScore"); entry.tertiaryScore = rows->getFloat("tertiaryScore");
entry.numWins = rows->getUInt("numWins"); entry.numWins = rows->getUInt("numWins");
entry.numTimesPlayed = rows->getUInt("timesPlayed"); entry.numTimesPlayed = rows->getUInt("timesPlayed");
entry.name = rows->getString("char_name"); entry.name = rows->getString("char_name");
@ -35,11 +35,16 @@ std::vector<ILeaderboard::Entry> ProcessQuery(UniqueResultSet& rows) {
return entries; return entries;
} }
std::vector<ILeaderboard::Entry> MySQLDatabase::GetDefaultLeaderboard(const uint32_t activityId) { std::vector<ILeaderboard::Entry> 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); 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); return ProcessQuery(leaderboard);
} }
std::vector<ILeaderboard::Entry> 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<ILeaderboard::Entry> MySQLDatabase::GetAgsLeaderboard(const uint32_t activityId) { std::vector<ILeaderboard::Entry> MySQLDatabase::GetAgsLeaderboard(const uint32_t activityId) {
auto query = Game::config->GetValue("classic_survival_scoring") != "1" ? 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 primaryscore DESC, secondaryscore DESC, tertiaryScore DESC, last_played ASC;" :
@ -49,22 +54,34 @@ std::vector<ILeaderboard::Entry> MySQLDatabase::GetAgsLeaderboard(const uint32_t
} }
std::vector<ILeaderboard::Entry> MySQLDatabase::GetNsLeaderboard(const uint32_t activityId) { std::vector<ILeaderboard::Entry> 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); return ProcessQuery(leaderboard);
} }
void MySQLDatabase::SaveScore(const uint32_t playerId, const uint32_t gameId, const Score& score) { 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) { 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<ILeaderboard::Score> MySQLDatabase::GetPlayerScore(const uint32_t playerId, const uint32_t gameId) { std::optional<ILeaderboard::Score> MySQLDatabase::GetPlayerScore(const uint32_t playerId, const uint32_t gameId) {
return std::nullopt; std::optional<ILeaderboard::Score> 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) { 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);
} }

View File

@ -91,12 +91,13 @@ class TestSQLDatabase : public GameDatabase {
void RemoveBehavior(const int32_t behaviorId) override; void RemoveBehavior(const int32_t behaviorId) override;
void UpdateAccountGmLevel(const uint32_t accountId, const eGameMasterLevel gmLevel) override; void UpdateAccountGmLevel(const uint32_t accountId, const eGameMasterLevel gmLevel) override;
std::optional<IProperty::PropertyEntranceResult> GetProperties(const IProperty::PropertyLookup& params) override { return {}; }; std::optional<IProperty::PropertyEntranceResult> GetProperties(const IProperty::PropertyLookup& params) override { return {}; };
std::vector<ILeaderboard::Entry> GetDefaultLeaderboard(const uint32_t activityId) override {return {};}; std::vector<ILeaderboard::Entry> GetDescendingLeaderboard(const uint32_t activityId) override { return {}; };
std::vector<ILeaderboard::Entry> GetNsLeaderboard(const uint32_t activityId) override {return {};}; std::vector<ILeaderboard::Entry> GetAscendingLeaderboard(const uint32_t activityId) override { return {}; };
std::vector<ILeaderboard::Entry> GetAgsLeaderboard(const uint32_t activityId) override {return {};}; std::vector<ILeaderboard::Entry> GetNsLeaderboard(const uint32_t activityId) override { return {}; };
std::vector<ILeaderboard::Entry> GetAgsLeaderboard(const uint32_t activityId) override { return {}; };
void SaveScore(const uint32_t playerId, const uint32_t gameId, const Score& score) override {}; 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 {}; void UpdateScore(const uint32_t playerId, const uint32_t gameId, const Score& score) override {};
std::optional<ILeaderboard::Score> GetPlayerScore(const uint32_t playerId, const uint32_t gameId) override {return {};}; std::optional<ILeaderboard::Score> GetPlayerScore(const uint32_t playerId, const uint32_t gameId) override { return {}; };
void IncrementNumWins(const uint32_t playerId, const uint32_t gameId) override {}; void IncrementNumWins(const uint32_t playerId, const uint32_t gameId) override {};
void InsertUgcBuild(const std::string& modules, const LWOOBJID bigId, const std::optional<uint32_t> characterId) override {}; void InsertUgcBuild(const std::string& modules, const LWOOBJID bigId, const std::optional<uint32_t> characterId) override {};
void DeleteUgcBuild(const LWOOBJID bigId) override {}; void DeleteUgcBuild(const LWOOBJID bigId) override {};

View File

@ -198,7 +198,10 @@ std::vector<ILeaderboard::Entry> FilterFriends(const std::vector<ILeaderboard::E
auto friendOfPlayer = Database::Get()->GetFriendsList(relatedPlayer); auto friendOfPlayer = Database::Get()->GetFriendsList(relatedPlayer);
std::vector<ILeaderboard::Entry> friendsLeaderboard; std::vector<ILeaderboard::Entry> friendsLeaderboard;
for (const auto& entry : leaderboard) { 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); friendsLeaderboard.push_back(entry);
} }
} }
@ -234,11 +237,12 @@ void Leaderboard::SetupLeaderboard(bool weekly) {
case Type::Survival: case Type::Survival:
leaderboardRes = Database::Get()->GetAgsLeaderboard(gameID); leaderboardRes = Database::Get()->GetAgsLeaderboard(gameID);
break; break;
case Type::ShootingGallery:
[[fallthrough]];
case Type::Racing: case Type::Racing:
[[fallthrough]]; [[fallthrough]];
case Type::MonumentRace: case Type::MonumentRace:
leaderboardRes = Database::Get()->GetAscendingLeaderboard(gameID);
break;
case Type::ShootingGallery:
[[fallthrough]]; [[fallthrough]];
case Type::FootRace: case Type::FootRace:
[[fallthrough]]; [[fallthrough]];
@ -247,7 +251,7 @@ void Leaderboard::SetupLeaderboard(bool weekly) {
case Type::None: case Type::None:
[[fallthrough]]; [[fallthrough]];
default: default:
leaderboardRes = Database::Get()->GetDefaultLeaderboard(gameID); leaderboardRes = Database::Get()->GetDescendingLeaderboard(gameID);
break; break;
} }