DarkflameServer/dGame/LeaderboardManager.h

134 lines
4.1 KiB
C
Raw Permalink Normal View History

2023-05-30 11:11:37 +00:00
#ifndef __LEADERBOARDMANAGER__H__
#define __LEADERBOARDMANAGER__H__
#include <map>
2023-05-31 01:21:10 +00:00
#include <memory>
2023-05-30 11:11:37 +00:00
#include <string_view>
#include <vector>
2023-04-13 04:57:58 +00:00
#include "dCommonVars.h"
2023-04-14 08:32:52 +00:00
#include "LDFFormat.h"
2023-05-09 01:36:28 +00:00
namespace sql {
class ResultSet;
};
namespace RakNet {
2023-04-13 04:57:58 +00:00
class BitStream;
};
2023-05-30 11:38:19 +00:00
class Score {
public:
Score() {
primaryScore = 0;
secondaryScore = 0;
tertiaryScore = 0;
}
Score(const float primaryScore, const float secondaryScore = 0, const float tertiaryScore = 0) {
2023-05-30 11:38:19 +00:00
this->primaryScore = primaryScore;
this->secondaryScore = secondaryScore;
this->tertiaryScore = tertiaryScore;
}
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);
}
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);
}
void SetPrimaryScore(const float score) { primaryScore = score; }
float GetPrimaryScore() const { return primaryScore; }
2023-05-30 11:38:19 +00:00
void SetSecondaryScore(const float score) { secondaryScore = score; }
float GetSecondaryScore() const { return secondaryScore; }
2023-05-30 11:38:19 +00:00
void SetTertiaryScore(const float score) { tertiaryScore = score; }
float GetTertiaryScore() const { return tertiaryScore; }
2023-05-30 11:38:19 +00:00
private:
float primaryScore;
float secondaryScore;
float tertiaryScore;
2023-05-30 11:38:19 +00:00
};
using GameID = uint32_t;
class Leaderboard {
public:
2023-04-13 04:57:58 +00:00
// Enums for leaderboards
enum InfoType : uint32_t {
Top, // Top 11 all time players
MyStanding, // Ranking of the current player
Friends // Ranking between friends
};
enum Type : uint32_t {
ShootingGallery,
Racing,
MonumentRace,
FootRace,
UnusedLeaderboard4, // There is no 4 defined anywhere in the cdclient, but it takes a Score.
Survival,
2023-04-14 04:55:09 +00:00
SurvivalNS,
Donations,
2023-05-09 07:06:43 +00:00
None
2023-04-13 04:57:58 +00:00
};
Leaderboard() = delete;
Leaderboard(const GameID gameID, const Leaderboard::InfoType infoType, const bool weekly, LWOOBJID relatedPlayer, const Leaderboard::Type = None);
~Leaderboard();
2023-06-05 11:10:59 +00:00
/**
* @brief Resets the leaderboard state and frees its allocated memory
*
*/
void Clear();
2023-04-13 04:57:58 +00:00
/**
* Serialize the Leaderboard to a BitStream
2023-05-09 01:36:28 +00:00
*
2023-04-13 04:57:58 +00:00
* Expensive! Leaderboards are very string intensive so be wary of performatnce calling this method.
*/
void Serialize(RakNet::BitStream& bitStream) const;
2023-04-13 04:57:58 +00:00
/**
* Builds the leaderboard from the database based on the associated gameID
2023-05-30 11:11:37 +00:00
*
2023-05-09 02:59:10 +00:00
* @param resultStart The index to start the leaderboard at. Zero indexed.
* @param resultEnd The index to end the leaderboard at. Zero indexed.
2023-04-13 04:57:58 +00:00
*/
2023-06-05 23:04:56 +00:00
void SetupLeaderboard(bool weekly, uint32_t resultStart = 0, uint32_t resultEnd = 10);
2023-04-13 04:57:58 +00:00
/**
* Sends the leaderboard to the client specified by targetID.
*/
2023-05-30 11:23:48 +00:00
void Send(const LWOOBJID targetID) const;
2023-05-09 01:36:28 +00:00
2023-06-01 06:17:13 +00:00
// Helper function to get the columns, ordering and insert format for a leaderboard
2023-05-30 11:11:37 +00:00
static const std::string_view GetOrdering(Type leaderboardType);
private:
2023-05-09 01:36:28 +00:00
// Takes the resulting query from a leaderboard lookup and converts it to the LDF we need
// to send it to a client.
void QueryToLdf(std::unique_ptr<sql::ResultSet>& rows);
2023-05-28 11:30:20 +00:00
using LeaderboardEntry = std::vector<LDFBaseData*>;
using LeaderboardEntries = std::vector<LeaderboardEntry>;
2023-04-13 04:57:58 +00:00
LeaderboardEntries entries;
2022-07-28 13:39:57 +00:00
LWOOBJID relatedPlayer;
2023-04-13 04:57:58 +00:00
GameID gameID;
InfoType infoType;
Leaderboard::Type leaderboardType;
2022-07-28 13:39:57 +00:00
bool weekly;
};
2023-05-30 11:11:37 +00:00
namespace LeaderboardManager {
2023-06-05 09:50:40 +00:00
void SendLeaderboard(const GameID gameID, const Leaderboard::InfoType infoType, const bool weekly, const LWOOBJID playerID, const LWOOBJID targetID, const uint32_t resultStart = 0, const uint32_t resultEnd = 10);
2023-05-09 01:36:28 +00:00
2023-06-05 11:10:59 +00:00
void SaveScore(const LWOOBJID& playerID, const GameID activityId, const float primaryScore, const float secondaryScore = 0, const float tertiaryScore = 0);
2023-05-09 01:36:28 +00:00
2023-05-30 11:11:37 +00:00
Leaderboard::Type GetLeaderboardType(const GameID gameID);
2023-06-05 11:10:59 +00:00
extern std::map<GameID, Leaderboard::Type> leaderboardCache;
};
2023-05-30 11:11:37 +00:00
#endif //!__LEADERBOARDMANAGER__H__