DarkflameServer/dGame/LeaderboardManager.h

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

155 lines
5.2 KiB
C
Raw Normal View History

#pragma once
#include <climits>
#include <map>
#include <vector>
2023-04-13 04:57:58 +00:00
#include "Singleton.h"
#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-04-13 04:57:58 +00:00
typedef uint32_t GameID;
class Leaderboard {
public:
using LeaderboardEntry = std::vector<LDFBaseData*>;
using LeaderboardEntries = std::vector<LeaderboardEntry>;
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-04-13 04:57:58 +00:00
None = UINT_MAX
};
Leaderboard(const GameID gameID, const Leaderboard::InfoType infoType, const bool weekly, LWOOBJID relatedPlayer, const Leaderboard::Type = None);
~Leaderboard();
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);
2023-04-13 04:57:58 +00:00
/**
* Based on the associated gameID, return true if the score provided
* is better than the current entries' score
2023-05-09 01:36:28 +00:00
* @param score
* @return true
* @return false
2023-04-13 04:57:58 +00:00
*/
bool IsScoreBetter(const uint32_t score) const { return false; };
2023-04-13 04:57:58 +00:00
/**
* Builds the leaderboard from the database based on the associated gameID
*/
2023-05-09 02:35:19 +00:00
void SetupLeaderboard(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-09 02:35:19 +00:00
void Send(LWOOBJID targetID);
2023-05-09 01:36:28 +00:00
// Helper functions to get the columns, ordering and insert format for a leaderboard
static std::string GetColumns(Type leaderboardType);
static std::string GetInsertFormat(Type leaderboardType);
static std::string GetOrdering(Type leaderboardType);
private:
inline void WriteLeaderboardRow(std::ostringstream& leaderboard, const uint32_t& index, LDFBaseData* data);
2023-05-04 23:53:36 +00:00
// Returns true if the string needs formatting
bool GetRankingQuery(std::string& lookupReturn) const;
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-04-13 04:57:58 +00:00
LeaderboardEntries entries;
LWOOBJID relatedPlayer;
2023-04-13 04:57:58 +00:00
GameID gameID;
InfoType infoType;
Leaderboard::Type leaderboardType;
bool weekly;
};
2023-05-09 01:36:28 +00:00
class LeaderboardManager : public Singleton<LeaderboardManager> {
2023-04-13 04:57:58 +00:00
typedef std::map<GameID, Leaderboard::Type> LeaderboardCache;
public:
2023-05-09 01:36:28 +00:00
void SendLeaderboard(GameID gameID, Leaderboard::InfoType infoType, bool weekly, LWOOBJID targetID, LWOOBJID playerID = LWOOBJID_EMPTY);
// Saves a score to the database for the Racing minigame
inline void SaveRacingScore(const LWOOBJID& playerID, GameID gameID, uint32_t bestLapTime, uint32_t bestTime, bool won) {
SaveScore(playerID, gameID, Leaderboard::Racing, 3, bestLapTime, bestTime, won);
};
// Saves a score to the database for the Shooting Gallery minigame
inline void SaveShootingGalleryScore(const LWOOBJID& playerID, GameID gameID, uint32_t score, float hitPercentage, uint32_t streak) {
SaveScore(playerID, gameID, Leaderboard::ShootingGallery, 3, score, hitPercentage, streak);
};
// Saves a score to the database for the footrace minigame
inline void SaveFootRaceScore(const LWOOBJID& playerID, GameID gameID, uint32_t bestTime) {
SaveScore(playerID, gameID, Leaderboard::FootRace, 1, bestTime);
};
// Saves a score to the database for the Monument footrace minigame
inline void SaveMonumentRaceScore(const LWOOBJID& playerID, GameID gameID, uint32_t bestTime) {
SaveScore(playerID, gameID, Leaderboard::MonumentRace, 1, bestTime);
};
// Saves a score to the database for the Survival minigame
inline void SaveSurvivalScore(const LWOOBJID& playerID, GameID gameID, uint32_t score, uint32_t waves) {
SaveScore(playerID, gameID, Leaderboard::Survival, 2, score, waves);
};
// Saves a score to the database for the SurvivalNS minigame
// Same as the Survival minigame, but good for explicitness
inline void SaveSurvivalNSScore(const LWOOBJID& playerID, GameID gameID, uint32_t score, uint32_t waves) {
SaveScore(playerID, gameID, Leaderboard::SurvivalNS, 2, score, waves);
};
// Saves a score to the database for the Donations minigame
inline void SaveDonationsScore(const LWOOBJID& playerID, GameID gameID, uint32_t score) {
SaveScore(playerID, gameID, Leaderboard::Donations, 1, score);
};
private:
void SaveScore(const LWOOBJID& playerID, GameID gameID, Leaderboard::Type leaderboardType, va_list args);
void GetLeaderboard(uint32_t gameID, Leaderboard::InfoType infoType, bool weekly, LWOOBJID playerID = LWOOBJID_EMPTY);
2023-04-18 08:26:35 +00:00
/**
* @brief Public facing Score saving method. This method is simply a wrapper to ensure va_end is called properly.
2023-05-09 01:36:28 +00:00
*
2023-04-18 08:26:35 +00:00
* @param playerID The player whos score to save
* @param gameID The ID of the game which was played
* @param argumentCount The number of arguments in the va_list
2023-05-09 01:36:28 +00:00
* @param ... The score to save
2023-04-18 08:26:35 +00:00
*/
void SaveScore(const LWOOBJID& playerID, GameID gameID, Leaderboard::Type leaderboardType, uint32_t argumentCount, ...);
2023-05-09 01:36:28 +00:00
2023-04-18 08:26:35 +00:00
Leaderboard::Type GetLeaderboardType(const GameID gameID);
2023-04-13 04:57:58 +00:00
LeaderboardCache leaderboardCache;
};