mirror of
https://github.com/DarkflameUniverse/DarkflameServer
synced 2024-08-30 18:43:58 +00:00
Convert to using only floats
This will cover all of our bases for any type of score. No need to do any conversions.
This commit is contained in:
parent
47deca6f4f
commit
b8878da61b
@ -1,7 +1,8 @@
|
|||||||
#define _DEBUG
|
|
||||||
|
|
||||||
#include "LeaderboardManager.h"
|
#include "LeaderboardManager.h"
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include "Database.h"
|
#include "Database.h"
|
||||||
#include "EntityManager.h"
|
#include "EntityManager.h"
|
||||||
#include "Character.h"
|
#include "Character.h"
|
||||||
@ -14,7 +15,6 @@
|
|||||||
#include "Entity.h"
|
#include "Entity.h"
|
||||||
#include "LDFFormat.h"
|
#include "LDFFormat.h"
|
||||||
#include "DluAssert.h"
|
#include "DluAssert.h"
|
||||||
#include <sstream>
|
|
||||||
|
|
||||||
#include "CDActivitiesTable.h"
|
#include "CDActivitiesTable.h"
|
||||||
#include "Metrics.hpp"
|
#include "Metrics.hpp"
|
||||||
@ -32,7 +32,12 @@ Leaderboard::Leaderboard(const GameID gameID, const Leaderboard::InfoType infoTy
|
|||||||
}
|
}
|
||||||
|
|
||||||
Leaderboard::~Leaderboard() {
|
Leaderboard::~Leaderboard() {
|
||||||
|
Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Leaderboard::Clear() {
|
||||||
for (auto& entry : entries) for (auto data : entry) delete data;
|
for (auto& entry : entries) for (auto data : entry) delete data;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void WriteLeaderboardRow(std::ostringstream& leaderboard, const uint32_t& index, LDFBaseData* data) {
|
inline void WriteLeaderboardRow(std::ostringstream& leaderboard, const uint32_t& index, LDFBaseData* data) {
|
||||||
@ -44,7 +49,7 @@ void Leaderboard::Serialize(RakNet::BitStream* bitStream) const {
|
|||||||
bitStream->Write(infoType);
|
bitStream->Write(infoType);
|
||||||
|
|
||||||
std::ostringstream leaderboard;
|
std::ostringstream leaderboard;
|
||||||
Game::logger->Log("LeaderboardManager", "game is %i info type %i ", gameID, infoType);
|
|
||||||
leaderboard << "ADO.Result=7:1"; // Unused in 1.10.64, but is in captures
|
leaderboard << "ADO.Result=7:1"; // Unused in 1.10.64, but is in captures
|
||||||
leaderboard << "\nResult.Count=1:1"; // number of results, always 1
|
leaderboard << "\nResult.Count=1:1"; // number of results, always 1
|
||||||
if (!this->entries.empty()) leaderboard << "\nResult[0].Index=0:RowNumber"; // "Primary key". Live doesn't include this if there are no entries.
|
if (!this->entries.empty()) leaderboard << "\nResult[0].Index=0:RowNumber"; // "Primary key". Live doesn't include this if there are no entries.
|
||||||
@ -63,12 +68,12 @@ void Leaderboard::Serialize(RakNet::BitStream* bitStream) const {
|
|||||||
bitStream->Write<uint32_t>(leaderboardSize);
|
bitStream->Write<uint32_t>(leaderboardSize);
|
||||||
// Doing this all in 1 call so there is no possbility of a dangling pointer.
|
// Doing this all in 1 call so there is no possbility of a dangling pointer.
|
||||||
bitStream->WriteAlignedBytes(reinterpret_cast<const unsigned char*>(GeneralUtils::ASCIIToUTF16(leaderboard.str()).c_str()), leaderboardSize * sizeof(char16_t));
|
bitStream->WriteAlignedBytes(reinterpret_cast<const unsigned char*>(GeneralUtils::ASCIIToUTF16(leaderboard.str()).c_str()), leaderboardSize * sizeof(char16_t));
|
||||||
if (leaderboardSize > 0) bitStream->Write<uint16_t>(0);
|
|
||||||
bitStream->Write0();
|
bitStream->Write0();
|
||||||
bitStream->Write0();
|
bitStream->Write0();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Leaderboard::QueryToLdf(std::unique_ptr<sql::ResultSet>& rows) {
|
void Leaderboard::QueryToLdf(std::unique_ptr<sql::ResultSet>& rows) {
|
||||||
|
Clear();
|
||||||
if (rows->rowsCount() == 0) return;
|
if (rows->rowsCount() == 0) return;
|
||||||
|
|
||||||
this->entries.reserve(rows->rowsCount());
|
this->entries.reserve(rows->rowsCount());
|
||||||
@ -84,49 +89,49 @@ void Leaderboard::QueryToLdf(std::unique_ptr<sql::ResultSet>& rows) {
|
|||||||
entry.push_back(new LDFData<uint64_t>(u"RowNumber", rows->getInt("ranking")));
|
entry.push_back(new LDFData<uint64_t>(u"RowNumber", rows->getInt("ranking")));
|
||||||
switch (leaderboardType) {
|
switch (leaderboardType) {
|
||||||
case Type::ShootingGallery:
|
case Type::ShootingGallery:
|
||||||
entry.push_back(new LDFData<float>(u"HitPercentage", (rows->getInt("hitPercentage") / 100.0f)));
|
entry.push_back(new LDFData<float>(u"HitPercentage", (rows->getInt("primaryScore") / 100.0f)));
|
||||||
// HitPercentage:3 between 0 and 1
|
// HitPercentage:3 between 0 and 1
|
||||||
entry.push_back(new LDFData<int32_t>(u"Score", rows->getInt("score")));
|
entry.push_back(new LDFData<int32_t>(u"Score", rows->getInt("secondaryScore")));
|
||||||
// Score:1
|
// Score:1
|
||||||
entry.push_back(new LDFData<int32_t>(u"Streak", rows->getInt("streak")));
|
entry.push_back(new LDFData<int32_t>(u"Streak", rows->getInt("tertiaryScore")));
|
||||||
// Streak:1
|
// Streak:1
|
||||||
break;
|
break;
|
||||||
case Type::Racing:
|
case Type::Racing:
|
||||||
entry.push_back(new LDFData<float>(u"BestLapTime", rows->getDouble("bestLapTime")));
|
entry.push_back(new LDFData<float>(u"BestTime", rows->getDouble("primaryScore")));
|
||||||
// BestLapTime:3
|
// BestLapTime:3
|
||||||
entry.push_back(new LDFData<float>(u"BestTime", rows->getDouble("bestTime")));
|
entry.push_back(new LDFData<float>(u"BestLapTime", rows->getDouble("secondaryScore")));
|
||||||
// BestTime:3
|
// BestTime:3
|
||||||
entry.push_back(new LDFData<int32_t>(u"License", 1));
|
entry.push_back(new LDFData<int32_t>(u"License", 1));
|
||||||
// License:1 - 1 if player has completed mission 637 and 0 otherwise
|
// License:1 - 1 if player has completed mission 637 and 0 otherwise
|
||||||
entry.push_back(new LDFData<int32_t>(u"NumWins", rows->getInt("numWins")));
|
entry.push_back(new LDFData<int32_t>(u"NumWins", rows->getInt("tertiaryScore")));
|
||||||
// NumWins:1
|
// NumWins:1
|
||||||
break;
|
break;
|
||||||
case Type::UnusedLeaderboard4:
|
case Type::UnusedLeaderboard4:
|
||||||
entry.push_back(new LDFData<int32_t>(u"Points", rows->getInt("score")));
|
entry.push_back(new LDFData<int32_t>(u"Points", rows->getInt("primaryScore")));
|
||||||
// Points:1
|
// Points:1
|
||||||
break;
|
break;
|
||||||
case Type::MonumentRace:
|
case Type::MonumentRace:
|
||||||
entry.push_back(new LDFData<int32_t>(u"Time", rows->getInt("bestTime")));
|
entry.push_back(new LDFData<int32_t>(u"Time", rows->getInt("primaryScore")));
|
||||||
// Time:1(?)
|
// Time:1(?)
|
||||||
break;
|
break;
|
||||||
case Type::FootRace:
|
case Type::FootRace:
|
||||||
entry.push_back(new LDFData<int32_t>(u"Time", rows->getInt("bestTime")));
|
entry.push_back(new LDFData<int32_t>(u"Time", rows->getInt("primaryScore")));
|
||||||
// Time:1
|
// Time:1
|
||||||
break;
|
break;
|
||||||
case Type::Survival:
|
case Type::Survival:
|
||||||
entry.push_back(new LDFData<int32_t>(u"Points", rows->getInt("score")));
|
entry.push_back(new LDFData<int32_t>(u"Points", rows->getInt("primaryScore")));
|
||||||
// Points:1
|
// Points:1
|
||||||
entry.push_back(new LDFData<int32_t>(u"Time", rows->getInt("bestTime")));
|
entry.push_back(new LDFData<int32_t>(u"Time", rows->getInt("secondaryScore")));
|
||||||
// Time:1
|
// Time:1
|
||||||
break;
|
break;
|
||||||
case Type::SurvivalNS:
|
case Type::SurvivalNS:
|
||||||
entry.push_back(new LDFData<int32_t>(u"Wave", rows->getInt("score")));
|
entry.push_back(new LDFData<int32_t>(u"Wave", rows->getInt("primaryScore")));
|
||||||
// Wave:1
|
// Wave:1
|
||||||
entry.push_back(new LDFData<int32_t>(u"Time", rows->getInt("bestTime")));
|
entry.push_back(new LDFData<int32_t>(u"Time", rows->getInt("secondaryScore")));
|
||||||
// Time:1
|
// Time:1
|
||||||
break;
|
break;
|
||||||
case Type::Donations:
|
case Type::Donations:
|
||||||
entry.push_back(new LDFData<int32_t>(u"Points", rows->getInt("score")));
|
entry.push_back(new LDFData<int32_t>(u"Points", rows->getInt("primaryScore")));
|
||||||
// Score:1
|
// Score:1
|
||||||
break;
|
break;
|
||||||
case Type::None:
|
case Type::None:
|
||||||
@ -139,98 +144,33 @@ void Leaderboard::QueryToLdf(std::unique_ptr<sql::ResultSet>& rows) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const std::string_view Leaderboard::GetColumns(Leaderboard::Type leaderboardType) {
|
const std::string_view Leaderboard::GetColumns(Leaderboard::Type leaderboardType) {
|
||||||
const char* columns;
|
return "primaryScore, secondaryScore, tertiaryScore";
|
||||||
switch (leaderboardType) {
|
|
||||||
case Type::ShootingGallery:
|
|
||||||
columns = "hitPercentage, score, streak";
|
|
||||||
break;
|
|
||||||
case Type::Racing:
|
|
||||||
columns = "bestLapTime, bestTime, numWins";
|
|
||||||
break;
|
|
||||||
case Type::Donations:
|
|
||||||
case Type::UnusedLeaderboard4:
|
|
||||||
columns = "score";
|
|
||||||
break;
|
|
||||||
case Type::MonumentRace:
|
|
||||||
case Type::FootRace:
|
|
||||||
columns = "bestTime";
|
|
||||||
break;
|
|
||||||
case Type::Survival:
|
|
||||||
columns = "bestTime, score";
|
|
||||||
break;
|
|
||||||
case Type::SurvivalNS:
|
|
||||||
columns = "bestTime, score";
|
|
||||||
break;
|
|
||||||
case Type::None:
|
|
||||||
columns = "";
|
|
||||||
// This type is included here simply to resolve a compiler warning on mac about unused enum types
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return columns;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string_view Leaderboard::GetInsertFormat(Leaderboard::Type leaderboardType) {
|
const std::string_view Leaderboard::GetInsertFormat(Leaderboard::Type leaderboardType) {
|
||||||
const char* columns;
|
return "primaryScore %f, secondaryScore %f, tertiaryScore %f";
|
||||||
switch (leaderboardType) {
|
|
||||||
case Type::ShootingGallery:
|
|
||||||
columns = "score=%i, hitPercentage=%i, streak=%i";
|
|
||||||
break;
|
|
||||||
case Type::Racing:
|
|
||||||
columns = "bestLapTime=%i, bestTime=%i, numWins=numWins + %i";
|
|
||||||
break;
|
|
||||||
case Type::Donations:
|
|
||||||
case Type::UnusedLeaderboard4:
|
|
||||||
columns = "score=%i";
|
|
||||||
break;
|
|
||||||
case Type::MonumentRace:
|
|
||||||
case Type::FootRace:
|
|
||||||
columns = "bestTime=%i";
|
|
||||||
break;
|
|
||||||
case Type::Survival:
|
|
||||||
columns = "bestTime=%i, score=%i";
|
|
||||||
break;
|
|
||||||
case Type::SurvivalNS:
|
|
||||||
columns = "bestTime=%i, score=%i";
|
|
||||||
break;
|
|
||||||
case Type::None:
|
|
||||||
columns = "";
|
|
||||||
// This type is included here simply to resolve a compiler warning on mac about unused enum types
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return columns;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string_view Leaderboard::GetOrdering(Leaderboard::Type leaderboardType) {
|
const std::string_view Leaderboard::GetOrdering(Leaderboard::Type leaderboardType) {
|
||||||
const char* orderBase;
|
// Use a switch case and return desc for all 3 columns if higher is better and asc if lower is better
|
||||||
switch (leaderboardType) {
|
switch (leaderboardType) {
|
||||||
case Type::ShootingGallery:
|
case Type::ShootingGallery:
|
||||||
orderBase = "score DESC, streak DESC, hitPercentage DESC";
|
|
||||||
break;
|
|
||||||
case Type::Racing:
|
|
||||||
orderBase = "bestTime ASC, bestLapTime ASC, numWins DESC";
|
|
||||||
break;
|
|
||||||
case Type::Donations:
|
|
||||||
case Type::UnusedLeaderboard4:
|
|
||||||
orderBase = "score DESC";
|
|
||||||
break;
|
|
||||||
case Type::MonumentRace:
|
|
||||||
orderBase = "bestTime ASC";
|
|
||||||
break;
|
|
||||||
case Type::FootRace:
|
case Type::FootRace:
|
||||||
orderBase = "bestTime DESC";
|
case Type::UnusedLeaderboard4:
|
||||||
break;
|
|
||||||
case Type::Survival:
|
|
||||||
orderBase = "score DESC, bestTime DESC";
|
|
||||||
break;
|
|
||||||
case Type::SurvivalNS:
|
case Type::SurvivalNS:
|
||||||
orderBase = "bestTime DESC, score DESC";
|
case Type::Donations:
|
||||||
break;
|
return "primaryScore DESC, secondaryScore DESC, tertiaryScore DESC";
|
||||||
|
case Type::Racing:
|
||||||
|
case Type::MonumentRace:
|
||||||
|
return "primaryScore ASC, secondaryScore ASC, tertiaryScore ASC";
|
||||||
case Type::None:
|
case Type::None:
|
||||||
orderBase = "";
|
case Type::Survival:
|
||||||
// This type is included here simply to resolve a compiler warning on mac about unused enum types
|
return Game::config->GetValue("classic_survival_scoring") == "1" ?
|
||||||
break;
|
"primaryScore DESC, secondaryScore DESC, tertiaryScore DESC" :
|
||||||
|
"secondaryScore DESC, primaryScore DESC, tertiaryScore DESC";
|
||||||
|
default:
|
||||||
|
return "";
|
||||||
}
|
}
|
||||||
return orderBase;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Leaderboard::SetupLeaderboard(uint32_t resultStart, uint32_t resultEnd) {
|
void Leaderboard::SetupLeaderboard(uint32_t resultStart, uint32_t resultEnd) {
|
||||||
@ -285,34 +225,22 @@ void Leaderboard::SetupLeaderboard(uint32_t resultStart, uint32_t resultEnd) {
|
|||||||
)
|
)
|
||||||
)QUERY";
|
)QUERY";
|
||||||
|
|
||||||
[[likely]] if (this->infoType != InfoType::Friends) friendsQuery.clear();
|
if (this->infoType != InfoType::Friends) friendsQuery.clear();
|
||||||
const auto orderBase = GetOrdering(this->leaderboardType);
|
const auto orderBase = GetOrdering(this->leaderboardType);
|
||||||
const auto selectBase = GetColumns(this->leaderboardType);
|
const auto selectBase = GetColumns(this->leaderboardType);
|
||||||
|
|
||||||
constexpr uint16_t STRING_LENGTH = 2048;
|
std::string baseLookup;
|
||||||
char lookupBuffer[STRING_LENGTH];
|
if (this->infoType == InfoType::Top) {
|
||||||
int32_t res = snprintf(lookupBuffer, STRING_LENGTH, queryBase.data(), orderBase.data(), friendsQuery.data(), selectBase.data(), resultStart, resultEnd);
|
baseLookup = "SELECT id FROM leaderboard WHERE game_id = ? ORDER BY ";
|
||||||
DluAssert(res != -1);
|
baseLookup += orderBase.data();
|
||||||
|
|
||||||
std::string baseLookupStr;
|
|
||||||
char baseRankingBuffer[STRING_LENGTH];
|
|
||||||
bool neededFormatting;
|
|
||||||
[[unlikely]] if (this->infoType == InfoType::Top) {
|
|
||||||
baseLookupStr = "SELECT id FROM leaderboard WHERE game_id = ? ORDER BY %s LIMIT 1";
|
|
||||||
neededFormatting = true;
|
|
||||||
} else {
|
} else {
|
||||||
baseLookupStr = "SELECT id FROM leaderboard WHERE game_id = ? AND character_id = ? LIMIT 1";
|
baseLookup = "SELECT id FROM leaderboard WHERE game_id = ? AND character_id = ";
|
||||||
neededFormatting = false;
|
baseLookup += std::to_string(this->relatedPlayer);
|
||||||
}
|
}
|
||||||
|
baseLookup += " LIMIT 1";
|
||||||
|
|
||||||
// If we need to format the base ranking query, do so, otherwise just copy the query since it's already formatted.
|
std::unique_ptr<sql::PreparedStatement> baseQuery(Database::CreatePreppedStmt(baseLookup));
|
||||||
if (neededFormatting) snprintf(baseRankingBuffer, STRING_LENGTH, baseLookupStr.c_str(), orderBase.data());
|
|
||||||
else std::copy(baseLookupStr.begin(), baseLookupStr.end() + 1, baseRankingBuffer);
|
|
||||||
|
|
||||||
std::unique_ptr<sql::PreparedStatement> baseQuery(Database::CreatePreppedStmt(baseRankingBuffer));
|
|
||||||
baseQuery->setInt(1, this->gameID);
|
baseQuery->setInt(1, this->gameID);
|
||||||
if (!neededFormatting) baseQuery->setInt(2, this->relatedPlayer);
|
|
||||||
|
|
||||||
std::unique_ptr<sql::ResultSet> baseResult(baseQuery->executeQuery());
|
std::unique_ptr<sql::ResultSet> baseResult(baseQuery->executeQuery());
|
||||||
|
|
||||||
if (!baseResult->next()) return; // In this case, there are no entries in the leaderboard for this game.
|
if (!baseResult->next()) return; // In this case, there are no entries in the leaderboard for this game.
|
||||||
@ -320,6 +248,10 @@ void Leaderboard::SetupLeaderboard(uint32_t resultStart, uint32_t resultEnd) {
|
|||||||
uint32_t relatedPlayerLeaderboardId = baseResult->getInt("id");
|
uint32_t relatedPlayerLeaderboardId = baseResult->getInt("id");
|
||||||
|
|
||||||
// Create and execute the actual save here
|
// Create and execute the actual save here
|
||||||
|
constexpr uint16_t STRING_LENGTH = 2048;
|
||||||
|
char lookupBuffer[STRING_LENGTH];
|
||||||
|
[[maybe_unused]] int32_t res = snprintf(lookupBuffer, STRING_LENGTH, queryBase.data(), orderBase.data(), friendsQuery.data(), selectBase.data(), resultStart, resultEnd);
|
||||||
|
DluAssert(res != -1);
|
||||||
std::unique_ptr<sql::PreparedStatement> query(Database::CreatePreppedStmt(lookupBuffer));
|
std::unique_ptr<sql::PreparedStatement> query(Database::CreatePreppedStmt(lookupBuffer));
|
||||||
|
|
||||||
query->setInt(1, this->gameID);
|
query->setInt(1, this->gameID);
|
||||||
@ -365,7 +297,7 @@ std::string FormatInsert(const Leaderboard::Type& type, const Score& score, cons
|
|||||||
return finishedQuery;
|
return finishedQuery;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LeaderboardManager::SaveScore(const LWOOBJID& playerID, const GameID gameID, const Leaderboard::Type leaderboardType, const uint32_t primaryScore, const uint32_t secondaryScore, const uint32_t tertiaryScore) {
|
void LeaderboardManager::SaveScore(const LWOOBJID& playerID, const GameID gameID, const Leaderboard::Type leaderboardType, const float primaryScore, const float secondaryScore, const float tertiaryScore) {
|
||||||
auto* lookup = "SELECT * FROM leaderboard WHERE character_id = ? AND game_id = ?;";
|
auto* lookup = "SELECT * FROM leaderboard WHERE character_id = ? AND game_id = ?;";
|
||||||
|
|
||||||
std::unique_ptr<sql::PreparedStatement> query(Database::CreatePreppedStmt(lookup));
|
std::unique_ptr<sql::PreparedStatement> query(Database::CreatePreppedStmt(lookup));
|
||||||
@ -381,46 +313,46 @@ void LeaderboardManager::SaveScore(const LWOOBJID& playerID, const GameID gameID
|
|||||||
switch (leaderboardType) {
|
switch (leaderboardType) {
|
||||||
// Higher score better
|
// Higher score better
|
||||||
case Leaderboard::Type::ShootingGallery: {
|
case Leaderboard::Type::ShootingGallery: {
|
||||||
oldScore.SetPrimaryScore(myScoreResult->getInt("score"));
|
oldScore.SetPrimaryScore(myScoreResult->getInt("primaryScore"));
|
||||||
oldScore.SetSecondaryScore(myScoreResult->getInt("hitPercentage"));
|
oldScore.SetSecondaryScore(myScoreResult->getInt("secondaryScore"));
|
||||||
oldScore.SetTertiaryScore(myScoreResult->getInt("streak"));
|
oldScore.SetTertiaryScore(myScoreResult->getInt("tertiaryScore"));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Leaderboard::Type::FootRace: {
|
case Leaderboard::Type::FootRace: {
|
||||||
oldScore.SetPrimaryScore(myScoreResult->getInt("bestTime"));
|
oldScore.SetPrimaryScore(myScoreResult->getInt("primaryScore"));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Leaderboard::Type::Survival: {
|
case Leaderboard::Type::Survival: {
|
||||||
// Config option may reverse these
|
// Config option may reverse these
|
||||||
oldScore.SetPrimaryScore(myScoreResult->getInt("bestTime"));
|
oldScore.SetPrimaryScore(myScoreResult->getInt("primaryScore"));
|
||||||
oldScore.SetSecondaryScore(myScoreResult->getInt("score"));
|
oldScore.SetSecondaryScore(myScoreResult->getInt("secondaryScore"));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Leaderboard::Type::SurvivalNS: {
|
case Leaderboard::Type::SurvivalNS: {
|
||||||
oldScore.SetPrimaryScore(myScoreResult->getInt("bestTime"));
|
oldScore.SetPrimaryScore(myScoreResult->getInt("primaryScore"));
|
||||||
oldScore.SetSecondaryScore(myScoreResult->getInt("score"));
|
oldScore.SetSecondaryScore(myScoreResult->getInt("secondaryScore"));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Leaderboard::Type::UnusedLeaderboard4:
|
case Leaderboard::Type::UnusedLeaderboard4:
|
||||||
case Leaderboard::Type::Donations: {
|
case Leaderboard::Type::Donations: {
|
||||||
oldScore.SetPrimaryScore(myScoreResult->getInt("score"));
|
oldScore.SetPrimaryScore(myScoreResult->getInt("primaryScore"));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Leaderboard::Type::Racing: {
|
case Leaderboard::Type::Racing: {
|
||||||
oldScore.SetPrimaryScore(myScoreResult->getInt("bestTime"));
|
oldScore.SetPrimaryScore(myScoreResult->getInt("primaryScore"));
|
||||||
oldScore.SetSecondaryScore(myScoreResult->getInt("bestLapTime"));
|
oldScore.SetSecondaryScore(myScoreResult->getInt("secondaryScore"));
|
||||||
lowerScoreBetter = true;
|
lowerScoreBetter = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Leaderboard::Type::MonumentRace: {
|
case Leaderboard::Type::MonumentRace: {
|
||||||
oldScore.SetPrimaryScore(myScoreResult->getInt("bestTime"));
|
oldScore.SetPrimaryScore(myScoreResult->getInt("primaryScore"));
|
||||||
lowerScoreBetter = true;
|
lowerScoreBetter = true;
|
||||||
// Do score checking here
|
// Do score checking here
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Leaderboard::Type::None:
|
case Leaderboard::Type::None:
|
||||||
default:
|
default:
|
||||||
Game::logger->Log("LeaderboardManager", "Unknown leaderboard type %i. Cannot save score!", leaderboardType);
|
Game::logger->Log("LeaderboardManager", "Unknown leaderboard type %i for game %i. Cannot save score!", leaderboardType, gameID);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
bool newHighScore = lowerScoreBetter ? newScore < oldScore : newScore > oldScore;
|
bool newHighScore = lowerScoreBetter ? newScore < oldScore : newScore > oldScore;
|
||||||
|
@ -25,7 +25,7 @@ public:
|
|||||||
secondaryScore = 0;
|
secondaryScore = 0;
|
||||||
tertiaryScore = 0;
|
tertiaryScore = 0;
|
||||||
}
|
}
|
||||||
Score(const uint32_t primaryScore, const uint32_t secondaryScore = 0, const uint32_t tertiaryScore = 0) {
|
Score(const float primaryScore, const float secondaryScore = 0, const float tertiaryScore = 0) {
|
||||||
this->primaryScore = primaryScore;
|
this->primaryScore = primaryScore;
|
||||||
this->secondaryScore = secondaryScore;
|
this->secondaryScore = secondaryScore;
|
||||||
this->tertiaryScore = tertiaryScore;
|
this->tertiaryScore = tertiaryScore;
|
||||||
@ -36,18 +36,18 @@ public:
|
|||||||
bool operator>(const Score& rhs) const {
|
bool operator>(const Score& rhs) const {
|
||||||
return primaryScore > rhs.primaryScore || (primaryScore == rhs.primaryScore && secondaryScore > rhs.secondaryScore) || (primaryScore == rhs.primaryScore && secondaryScore == rhs.secondaryScore && tertiaryScore > rhs.tertiaryScore);
|
return primaryScore > rhs.primaryScore || (primaryScore == rhs.primaryScore && secondaryScore > rhs.secondaryScore) || (primaryScore == rhs.primaryScore && secondaryScore == rhs.secondaryScore && tertiaryScore > rhs.tertiaryScore);
|
||||||
}
|
}
|
||||||
void SetPrimaryScore(const uint32_t score) { primaryScore = score; }
|
void SetPrimaryScore(const float score) { primaryScore = score; }
|
||||||
uint32_t GetPrimaryScore() const { return primaryScore; }
|
float GetPrimaryScore() const { return primaryScore; }
|
||||||
|
|
||||||
void SetSecondaryScore(const uint32_t score) { secondaryScore = score; }
|
void SetSecondaryScore(const float score) { secondaryScore = score; }
|
||||||
uint32_t GetSecondaryScore() const { return secondaryScore; }
|
float GetSecondaryScore() const { return secondaryScore; }
|
||||||
|
|
||||||
void SetTertiaryScore(const uint32_t score) { tertiaryScore = score; }
|
void SetTertiaryScore(const float score) { tertiaryScore = score; }
|
||||||
uint32_t GetTertiaryScore() const { return tertiaryScore; }
|
float GetTertiaryScore() const { return tertiaryScore; }
|
||||||
private:
|
private:
|
||||||
uint32_t primaryScore;
|
float primaryScore;
|
||||||
uint32_t secondaryScore;
|
float secondaryScore;
|
||||||
uint32_t tertiaryScore;
|
float tertiaryScore;
|
||||||
};
|
};
|
||||||
|
|
||||||
using GameID = uint32_t;
|
using GameID = uint32_t;
|
||||||
@ -73,10 +73,11 @@ public:
|
|||||||
Donations,
|
Donations,
|
||||||
None
|
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 Leaderboard::Type = None);
|
||||||
|
|
||||||
~Leaderboard();
|
~Leaderboard();
|
||||||
|
void Clear();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Serialize the Leaderboard to a BitStream
|
* Serialize the Leaderboard to a BitStream
|
||||||
@ -85,15 +86,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
void Serialize(RakNet::BitStream* bitStream) const;
|
void Serialize(RakNet::BitStream* bitStream) const;
|
||||||
|
|
||||||
/**
|
|
||||||
* Based on the associated gameID, return true if the score provided
|
|
||||||
* is better than the current entries' score
|
|
||||||
* @param score
|
|
||||||
* @return true
|
|
||||||
* @return false
|
|
||||||
*/
|
|
||||||
bool IsScoreBetter(const uint32_t score) const { return false; };
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builds the leaderboard from the database based on the associated gameID
|
* Builds the leaderboard from the database based on the associated gameID
|
||||||
*
|
*
|
||||||
@ -135,7 +127,7 @@ namespace LeaderboardManager {
|
|||||||
using LeaderboardCache = std::map<GameID, Leaderboard::Type>;
|
using LeaderboardCache = std::map<GameID, Leaderboard::Type>;
|
||||||
void SendLeaderboard(GameID gameID, Leaderboard::InfoType infoType, bool weekly, LWOOBJID playerID, LWOOBJID targetID, uint32_t resultStart = 0, uint32_t resultEnd = 10);
|
void SendLeaderboard(GameID gameID, Leaderboard::InfoType infoType, bool weekly, LWOOBJID playerID, LWOOBJID targetID, uint32_t resultStart = 0, uint32_t resultEnd = 10);
|
||||||
|
|
||||||
void SaveScore(const LWOOBJID& playerID, const GameID gameID, const Leaderboard::Type leaderboardType, const uint32_t primaryScore, const uint32_t secondaryScore = 0, const uint32_t tertiaryScore = 0);
|
void SaveScore(const LWOOBJID& playerID, const GameID gameID, const Leaderboard::Type leaderboardType, const float primaryScore, const float secondaryScore = 0, const float tertiaryScore = 0);
|
||||||
|
|
||||||
void GetLeaderboard(const uint32_t gameID, const Leaderboard::InfoType infoType, const bool weekly, const LWOOBJID playerID = LWOOBJID_EMPTY);
|
void GetLeaderboard(const uint32_t gameID, const Leaderboard::InfoType infoType, const bool weekly, const LWOOBJID playerID = LWOOBJID_EMPTY);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user