mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-10 01:58:19 +00:00
Factor CScoreWorker out of CScore, add SaveScore test
This commit is contained in:
parent
f03cb08150
commit
baf9b94f2c
|
@ -2112,6 +2112,8 @@ if(SERVER)
|
|||
save.h
|
||||
score.cpp
|
||||
score.h
|
||||
scoreworker.cpp
|
||||
scoreworker.h
|
||||
teams.cpp
|
||||
teams.h
|
||||
teehistorian.cpp
|
||||
|
@ -2271,6 +2273,7 @@ if(GTEST_FOUND OR DOWNLOAD_GTEST)
|
|||
netaddr.cpp
|
||||
packer.cpp
|
||||
prng.cpp
|
||||
score.cpp
|
||||
secure_random.cpp
|
||||
serverbrowser.cpp
|
||||
serverinfo.cpp
|
||||
|
@ -2296,10 +2299,17 @@ if(GTEST_FOUND OR DOWNLOAD_GTEST)
|
|||
src/engine/client/serverbrowser_ping_cache.cpp
|
||||
src/engine/client/serverbrowser_ping_cache.h
|
||||
src/engine/client/sqlite.cpp
|
||||
src/engine/server/databases/connection.cpp
|
||||
src/engine/server/databases/connection.h
|
||||
src/engine/server/databases/sqlite.cpp
|
||||
src/engine/server/name_ban.cpp
|
||||
src/engine/server/name_ban.h
|
||||
src/engine/server/sql_string_helpers.cpp
|
||||
src/engine/server/sql_string_helpers.h
|
||||
src/game/server/teehistorian.cpp
|
||||
src/game/server/teehistorian.h
|
||||
src/game/server/scoreworker.cpp
|
||||
src/game/server/scoreworker.h
|
||||
)
|
||||
|
||||
set(TARGET_TESTRUNNER testrunner)
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,311 +1,21 @@
|
|||
#ifndef GAME_SERVER_SCORE_H
|
||||
#define GAME_SERVER_SCORE_H
|
||||
|
||||
#include <atomic>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include <engine/map.h>
|
||||
#include <engine/server/databases/connection_pool.h>
|
||||
#include <game/prng.h>
|
||||
#include <game/voting.h>
|
||||
|
||||
#include "save.h"
|
||||
#include "scoreworker.h"
|
||||
|
||||
struct ISqlData;
|
||||
class IDbConnection;
|
||||
class IServer;
|
||||
class CGameContext;
|
||||
|
||||
enum
|
||||
{
|
||||
NUM_CHECKPOINTS = 25,
|
||||
TIMESTAMP_STR_LENGTH = 20, // 2019-04-02 19:38:36
|
||||
};
|
||||
|
||||
struct CScorePlayerResult : ISqlResult
|
||||
{
|
||||
CScorePlayerResult();
|
||||
|
||||
enum
|
||||
{
|
||||
MAX_MESSAGES = 10,
|
||||
};
|
||||
|
||||
enum Variant
|
||||
{
|
||||
DIRECT,
|
||||
ALL,
|
||||
BROADCAST,
|
||||
MAP_VOTE,
|
||||
PLAYER_INFO,
|
||||
} m_MessageKind;
|
||||
union
|
||||
{
|
||||
char m_aaMessages[MAX_MESSAGES][512];
|
||||
char m_aBroadcast[1024];
|
||||
struct
|
||||
{
|
||||
float m_Time;
|
||||
float m_CpTime[NUM_CHECKPOINTS];
|
||||
int m_Score;
|
||||
int m_HasFinishScore;
|
||||
int m_Birthday; // 0 indicates no birthday
|
||||
} m_Info;
|
||||
struct
|
||||
{
|
||||
char m_aReason[VOTE_REASON_LENGTH];
|
||||
char m_aServer[32 + 1];
|
||||
char m_aMap[MAX_MAP_LENGTH + 1];
|
||||
} m_MapVote;
|
||||
} m_Data; // PLAYER_INFO
|
||||
|
||||
void SetVariant(Variant v);
|
||||
};
|
||||
|
||||
struct CScoreRandomMapResult : ISqlResult
|
||||
{
|
||||
CScoreRandomMapResult(int ClientID) :
|
||||
m_ClientID(ClientID)
|
||||
{
|
||||
m_aMap[0] = '\0';
|
||||
m_aMessage[0] = '\0';
|
||||
}
|
||||
int m_ClientID;
|
||||
char m_aMap[MAX_MAP_LENGTH];
|
||||
char m_aMessage[512];
|
||||
};
|
||||
|
||||
struct CScoreSaveResult : ISqlResult
|
||||
{
|
||||
CScoreSaveResult(int PlayerID, IGameController *Controller) :
|
||||
m_Status(SAVE_FAILED),
|
||||
m_SavedTeam(CSaveTeam(Controller)),
|
||||
m_RequestingPlayer(PlayerID)
|
||||
{
|
||||
m_aMessage[0] = '\0';
|
||||
m_aBroadcast[0] = '\0';
|
||||
}
|
||||
enum
|
||||
{
|
||||
SAVE_SUCCESS,
|
||||
// load team in the following two cases
|
||||
SAVE_FAILED,
|
||||
LOAD_SUCCESS,
|
||||
LOAD_FAILED,
|
||||
} m_Status;
|
||||
char m_aMessage[512];
|
||||
char m_aBroadcast[512];
|
||||
CSaveTeam m_SavedTeam;
|
||||
int m_RequestingPlayer;
|
||||
CUuid m_SaveID;
|
||||
};
|
||||
|
||||
struct CScoreInitResult : ISqlResult
|
||||
{
|
||||
CScoreInitResult() :
|
||||
m_CurrentRecord(0)
|
||||
{
|
||||
}
|
||||
float m_CurrentRecord;
|
||||
};
|
||||
|
||||
class CPlayerData
|
||||
{
|
||||
public:
|
||||
CPlayerData()
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
~CPlayerData() {}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
m_BestTime = 0;
|
||||
m_CurrentTime = 0;
|
||||
for(float &BestCpTime : m_aBestCpTime)
|
||||
BestCpTime = 0;
|
||||
}
|
||||
|
||||
void Set(float Time, float CpTime[NUM_CHECKPOINTS])
|
||||
{
|
||||
m_BestTime = Time;
|
||||
m_CurrentTime = Time;
|
||||
for(int i = 0; i < NUM_CHECKPOINTS; i++)
|
||||
m_aBestCpTime[i] = CpTime[i];
|
||||
}
|
||||
|
||||
float m_BestTime;
|
||||
float m_CurrentTime;
|
||||
float m_aBestCpTime[NUM_CHECKPOINTS];
|
||||
};
|
||||
|
||||
struct CSqlInitData : ISqlData
|
||||
{
|
||||
CSqlInitData(std::shared_ptr<CScoreInitResult> pResult) :
|
||||
ISqlData(std::move(pResult))
|
||||
{
|
||||
}
|
||||
|
||||
// current map
|
||||
char m_aMap[MAX_MAP_LENGTH];
|
||||
};
|
||||
|
||||
struct CSqlPlayerRequest : ISqlData
|
||||
{
|
||||
CSqlPlayerRequest(std::shared_ptr<CScorePlayerResult> pResult) :
|
||||
ISqlData(std::move(pResult))
|
||||
{
|
||||
}
|
||||
|
||||
// object being requested, either map (128 bytes) or player (16 bytes)
|
||||
char m_aName[MAX_MAP_LENGTH];
|
||||
// current map
|
||||
char m_aMap[MAX_MAP_LENGTH];
|
||||
char m_aRequestingPlayer[MAX_NAME_LENGTH];
|
||||
// relevant for /top5 kind of requests
|
||||
int m_Offset;
|
||||
char m_aServer[5];
|
||||
};
|
||||
|
||||
struct CSqlRandomMapRequest : ISqlData
|
||||
{
|
||||
CSqlRandomMapRequest(std::shared_ptr<CScoreRandomMapResult> pResult) :
|
||||
ISqlData(std::move(pResult))
|
||||
{
|
||||
}
|
||||
|
||||
char m_aServerType[32];
|
||||
char m_aCurrentMap[MAX_MAP_LENGTH];
|
||||
char m_aRequestingPlayer[MAX_NAME_LENGTH];
|
||||
int m_Stars;
|
||||
};
|
||||
|
||||
struct CSqlScoreData : ISqlData
|
||||
{
|
||||
CSqlScoreData(std::shared_ptr<CScorePlayerResult> pResult) :
|
||||
ISqlData(std::move(pResult))
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~CSqlScoreData(){};
|
||||
|
||||
char m_aMap[MAX_MAP_LENGTH];
|
||||
char m_aGameUuid[UUID_MAXSTRSIZE];
|
||||
char m_aName[MAX_MAP_LENGTH];
|
||||
|
||||
int m_ClientID;
|
||||
float m_Time;
|
||||
char m_aTimestamp[TIMESTAMP_STR_LENGTH];
|
||||
float m_aCpCurrent[NUM_CHECKPOINTS];
|
||||
int m_Num;
|
||||
bool m_Search;
|
||||
char m_aRequestingPlayer[MAX_NAME_LENGTH];
|
||||
};
|
||||
|
||||
struct CSqlTeamScoreData : ISqlData
|
||||
{
|
||||
CSqlTeamScoreData() :
|
||||
ISqlData(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
char m_aGameUuid[UUID_MAXSTRSIZE];
|
||||
char m_aMap[MAX_MAP_LENGTH];
|
||||
float m_Time;
|
||||
char m_aTimestamp[TIMESTAMP_STR_LENGTH];
|
||||
unsigned int m_Size;
|
||||
char m_aaNames[MAX_CLIENTS][MAX_NAME_LENGTH];
|
||||
};
|
||||
|
||||
struct CSqlTeamSave : ISqlData
|
||||
{
|
||||
CSqlTeamSave(std::shared_ptr<CScoreSaveResult> pResult) :
|
||||
ISqlData(std::move(pResult))
|
||||
{
|
||||
}
|
||||
virtual ~CSqlTeamSave(){};
|
||||
|
||||
char m_aClientName[MAX_NAME_LENGTH];
|
||||
char m_aMap[MAX_MAP_LENGTH];
|
||||
char m_aCode[128];
|
||||
char m_aGeneratedCode[128];
|
||||
char m_aServer[5];
|
||||
};
|
||||
|
||||
struct CSqlTeamLoad : ISqlData
|
||||
{
|
||||
CSqlTeamLoad(std::shared_ptr<CScoreSaveResult> pResult) :
|
||||
ISqlData(std::move(pResult))
|
||||
{
|
||||
}
|
||||
virtual ~CSqlTeamLoad(){};
|
||||
|
||||
char m_aCode[128];
|
||||
char m_aMap[MAX_MAP_LENGTH];
|
||||
char m_aRequestingPlayer[MAX_NAME_LENGTH];
|
||||
int m_ClientID;
|
||||
// struct holding all player names in the team or an empty string
|
||||
char m_aClientNames[MAX_CLIENTS][MAX_NAME_LENGTH];
|
||||
int m_aClientID[MAX_CLIENTS];
|
||||
int m_NumPlayer;
|
||||
};
|
||||
|
||||
struct CTeamrank
|
||||
{
|
||||
CUuid m_TeamID;
|
||||
char m_aaNames[MAX_CLIENTS][MAX_NAME_LENGTH];
|
||||
unsigned int m_NumNames;
|
||||
CTeamrank();
|
||||
|
||||
// Assumes that a database query equivalent to
|
||||
//
|
||||
// SELECT TeamID, Name [, ...] -- the order is important
|
||||
// FROM record_teamrace
|
||||
// ORDER BY TeamID, Name
|
||||
//
|
||||
// was executed and that the result line of the first team member is already selected.
|
||||
// Afterwards the team member of the next team is selected.
|
||||
//
|
||||
// Returns true on SQL failure
|
||||
//
|
||||
// if another team can be extracted
|
||||
bool NextSqlResult(IDbConnection *pSqlServer, bool *pEnd, char *pError, int ErrorSize);
|
||||
|
||||
bool SamePlayers(const std::vector<std::string> *aSortedNames);
|
||||
};
|
||||
|
||||
class CScore
|
||||
{
|
||||
CPlayerData m_aPlayerData[MAX_CLIENTS];
|
||||
CDbConnectionPool *m_pPool;
|
||||
|
||||
static bool Init(IDbConnection *pSqlServer, const ISqlData *pGameData, char *pError, int ErrorSize);
|
||||
|
||||
static bool RandomMapThread(IDbConnection *pSqlServer, const ISqlData *pGameData, char *pError, int ErrorSize);
|
||||
static bool RandomUnfinishedMapThread(IDbConnection *pSqlServer, const ISqlData *pGameData, char *pError, int ErrorSize);
|
||||
static bool MapVoteThread(IDbConnection *pSqlServer, const ISqlData *pGameData, char *pError, int ErrorSize);
|
||||
|
||||
static bool LoadPlayerDataThread(IDbConnection *pSqlServer, const ISqlData *pGameData, char *pError, int ErrorSize);
|
||||
static bool MapInfoThread(IDbConnection *pSqlServer, const ISqlData *pGameData, char *pError, int ErrorSize);
|
||||
static bool ShowRankThread(IDbConnection *pSqlServer, const ISqlData *pGameData, char *pError, int ErrorSize);
|
||||
static bool ShowTeamRankThread(IDbConnection *pSqlServer, const ISqlData *pGameData, char *pError, int ErrorSize);
|
||||
static bool ShowTopThread(IDbConnection *pSqlServer, const ISqlData *pGameData, char *pError, int ErrorSize);
|
||||
static bool ShowTeamTop5Thread(IDbConnection *pSqlServer, const ISqlData *pGameData, char *pError, int ErrorSize);
|
||||
static bool ShowPlayerTeamTop5Thread(IDbConnection *pSqlServer, const ISqlData *pGameData, char *pError, int ErrorSize);
|
||||
static bool ShowTimesThread(IDbConnection *pSqlServer, const ISqlData *pGameData, char *pError, int ErrorSize);
|
||||
static bool ShowPointsThread(IDbConnection *pSqlServer, const ISqlData *pGameData, char *pError, int ErrorSize);
|
||||
static bool ShowTopPointsThread(IDbConnection *pSqlServer, const ISqlData *pGameData, char *pError, int ErrorSize);
|
||||
static bool GetSavesThread(IDbConnection *pSqlServer, const ISqlData *pGameData, char *pError, int ErrorSize);
|
||||
|
||||
static bool SaveTeamThread(IDbConnection *pSqlServer, const ISqlData *pGameData, bool Failure, char *pError, int ErrorSize);
|
||||
static bool LoadTeamThread(IDbConnection *pSqlServer, const ISqlData *pGameData, bool Failure, char *pError, int ErrorSize);
|
||||
|
||||
static bool SaveScoreThread(IDbConnection *pSqlServer, const ISqlData *pGameData, bool Failure, char *pError, int ErrorSize);
|
||||
static bool SaveTeamScoreThread(IDbConnection *pSqlServer, const ISqlData *pGameData, bool Failure, char *pError, int ErrorSize);
|
||||
|
||||
CGameContext *GameServer() const { return m_pGameServer; }
|
||||
IServer *Server() const { return m_pServer; }
|
||||
CGameContext *m_pGameServer;
|
||||
|
|
1660
src/game/server/scoreworker.cpp
Normal file
1660
src/game/server/scoreworker.cpp
Normal file
File diff suppressed because it is too large
Load diff
305
src/game/server/scoreworker.h
Normal file
305
src/game/server/scoreworker.h
Normal file
|
@ -0,0 +1,305 @@
|
|||
#ifndef GAME_SERVER_SCOREWORKER_H
|
||||
#define GAME_SERVER_SCOREWORKER_H
|
||||
|
||||
#include <atomic>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include <engine/map.h>
|
||||
#include <engine/server/databases/connection_pool.h>
|
||||
#include <engine/shared/protocol.h>
|
||||
#include <engine/shared/uuid_manager.h>
|
||||
#include <game/server/save.h>
|
||||
#include <game/voting.h>
|
||||
|
||||
class IDbConnection;
|
||||
class IServer;
|
||||
|
||||
enum
|
||||
{
|
||||
NUM_CHECKPOINTS = 25,
|
||||
TIMESTAMP_STR_LENGTH = 20, // 2019-04-02 19:38:36
|
||||
};
|
||||
|
||||
struct CScorePlayerResult : ISqlResult
|
||||
{
|
||||
CScorePlayerResult();
|
||||
|
||||
enum
|
||||
{
|
||||
MAX_MESSAGES = 10,
|
||||
};
|
||||
|
||||
enum Variant
|
||||
{
|
||||
DIRECT,
|
||||
ALL,
|
||||
BROADCAST,
|
||||
MAP_VOTE,
|
||||
PLAYER_INFO,
|
||||
} m_MessageKind;
|
||||
union
|
||||
{
|
||||
char m_aaMessages[MAX_MESSAGES][512];
|
||||
char m_aBroadcast[1024];
|
||||
struct
|
||||
{
|
||||
float m_Time;
|
||||
float m_CpTime[NUM_CHECKPOINTS];
|
||||
int m_Score;
|
||||
int m_HasFinishScore;
|
||||
int m_Birthday; // 0 indicates no birthday
|
||||
} m_Info;
|
||||
struct
|
||||
{
|
||||
char m_aReason[VOTE_REASON_LENGTH];
|
||||
char m_aServer[32 + 1];
|
||||
char m_aMap[MAX_MAP_LENGTH + 1];
|
||||
} m_MapVote;
|
||||
} m_Data; // PLAYER_INFO
|
||||
|
||||
void SetVariant(Variant v);
|
||||
};
|
||||
|
||||
struct CScoreInitResult : ISqlResult
|
||||
{
|
||||
CScoreInitResult() :
|
||||
m_CurrentRecord(0)
|
||||
{
|
||||
}
|
||||
float m_CurrentRecord;
|
||||
};
|
||||
|
||||
struct CSqlInitData : ISqlData
|
||||
{
|
||||
CSqlInitData(std::shared_ptr<CScoreInitResult> pResult) :
|
||||
ISqlData(std::move(pResult))
|
||||
{
|
||||
}
|
||||
|
||||
// current map
|
||||
char m_aMap[MAX_MAP_LENGTH];
|
||||
};
|
||||
|
||||
struct CSqlPlayerRequest : ISqlData
|
||||
{
|
||||
CSqlPlayerRequest(std::shared_ptr<CScorePlayerResult> pResult) :
|
||||
ISqlData(std::move(pResult))
|
||||
{
|
||||
}
|
||||
|
||||
// object being requested, either map (128 bytes) or player (16 bytes)
|
||||
char m_aName[MAX_MAP_LENGTH];
|
||||
// current map
|
||||
char m_aMap[MAX_MAP_LENGTH];
|
||||
char m_aRequestingPlayer[MAX_NAME_LENGTH];
|
||||
// relevant for /top5 kind of requests
|
||||
int m_Offset;
|
||||
char m_aServer[5];
|
||||
};
|
||||
|
||||
struct CScoreRandomMapResult : ISqlResult
|
||||
{
|
||||
CScoreRandomMapResult(int ClientID) :
|
||||
m_ClientID(ClientID)
|
||||
{
|
||||
m_aMap[0] = '\0';
|
||||
m_aMessage[0] = '\0';
|
||||
}
|
||||
int m_ClientID;
|
||||
char m_aMap[MAX_MAP_LENGTH];
|
||||
char m_aMessage[512];
|
||||
};
|
||||
|
||||
struct CSqlRandomMapRequest : ISqlData
|
||||
{
|
||||
CSqlRandomMapRequest(std::shared_ptr<CScoreRandomMapResult> pResult) :
|
||||
ISqlData(std::move(pResult))
|
||||
{
|
||||
}
|
||||
|
||||
char m_aServerType[32];
|
||||
char m_aCurrentMap[MAX_MAP_LENGTH];
|
||||
char m_aRequestingPlayer[MAX_NAME_LENGTH];
|
||||
int m_Stars;
|
||||
};
|
||||
|
||||
struct CSqlScoreData : ISqlData
|
||||
{
|
||||
CSqlScoreData(std::shared_ptr<CScorePlayerResult> pResult) :
|
||||
ISqlData(std::move(pResult))
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~CSqlScoreData(){};
|
||||
|
||||
char m_aMap[MAX_MAP_LENGTH];
|
||||
char m_aGameUuid[UUID_MAXSTRSIZE];
|
||||
char m_aName[MAX_MAP_LENGTH];
|
||||
|
||||
int m_ClientID;
|
||||
float m_Time;
|
||||
char m_aTimestamp[TIMESTAMP_STR_LENGTH];
|
||||
float m_aCpCurrent[NUM_CHECKPOINTS];
|
||||
int m_Num;
|
||||
bool m_Search;
|
||||
char m_aRequestingPlayer[MAX_NAME_LENGTH];
|
||||
};
|
||||
|
||||
struct CScoreSaveResult : ISqlResult
|
||||
{
|
||||
CScoreSaveResult(int PlayerID, IGameController *Controller) :
|
||||
m_Status(SAVE_FAILED),
|
||||
m_SavedTeam(CSaveTeam(Controller)),
|
||||
m_RequestingPlayer(PlayerID)
|
||||
{
|
||||
m_aMessage[0] = '\0';
|
||||
m_aBroadcast[0] = '\0';
|
||||
}
|
||||
enum
|
||||
{
|
||||
SAVE_SUCCESS,
|
||||
// load team in the following two cases
|
||||
SAVE_FAILED,
|
||||
LOAD_SUCCESS,
|
||||
LOAD_FAILED,
|
||||
} m_Status;
|
||||
char m_aMessage[512];
|
||||
char m_aBroadcast[512];
|
||||
CSaveTeam m_SavedTeam;
|
||||
int m_RequestingPlayer;
|
||||
CUuid m_SaveID;
|
||||
};
|
||||
|
||||
struct CSqlTeamScoreData : ISqlData
|
||||
{
|
||||
CSqlTeamScoreData() :
|
||||
ISqlData(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
char m_aGameUuid[UUID_MAXSTRSIZE];
|
||||
char m_aMap[MAX_MAP_LENGTH];
|
||||
float m_Time;
|
||||
char m_aTimestamp[TIMESTAMP_STR_LENGTH];
|
||||
unsigned int m_Size;
|
||||
char m_aaNames[MAX_CLIENTS][MAX_NAME_LENGTH];
|
||||
};
|
||||
|
||||
struct CSqlTeamSave : ISqlData
|
||||
{
|
||||
CSqlTeamSave(std::shared_ptr<CScoreSaveResult> pResult) :
|
||||
ISqlData(std::move(pResult))
|
||||
{
|
||||
}
|
||||
virtual ~CSqlTeamSave(){};
|
||||
|
||||
char m_aClientName[MAX_NAME_LENGTH];
|
||||
char m_aMap[MAX_MAP_LENGTH];
|
||||
char m_aCode[128];
|
||||
char m_aGeneratedCode[128];
|
||||
char m_aServer[5];
|
||||
};
|
||||
|
||||
struct CSqlTeamLoad : ISqlData
|
||||
{
|
||||
CSqlTeamLoad(std::shared_ptr<CScoreSaveResult> pResult) :
|
||||
ISqlData(std::move(pResult))
|
||||
{
|
||||
}
|
||||
virtual ~CSqlTeamLoad(){};
|
||||
|
||||
char m_aCode[128];
|
||||
char m_aMap[MAX_MAP_LENGTH];
|
||||
char m_aRequestingPlayer[MAX_NAME_LENGTH];
|
||||
int m_ClientID;
|
||||
// struct holding all player names in the team or an empty string
|
||||
char m_aClientNames[MAX_CLIENTS][MAX_NAME_LENGTH];
|
||||
int m_aClientID[MAX_CLIENTS];
|
||||
int m_NumPlayer;
|
||||
};
|
||||
|
||||
class CPlayerData
|
||||
{
|
||||
public:
|
||||
CPlayerData()
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
~CPlayerData() {}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
m_BestTime = 0;
|
||||
m_CurrentTime = 0;
|
||||
for(float &BestCpTime : m_aBestCpTime)
|
||||
BestCpTime = 0;
|
||||
}
|
||||
|
||||
void Set(float Time, float CpTime[NUM_CHECKPOINTS])
|
||||
{
|
||||
m_BestTime = Time;
|
||||
m_CurrentTime = Time;
|
||||
for(int i = 0; i < NUM_CHECKPOINTS; i++)
|
||||
m_aBestCpTime[i] = CpTime[i];
|
||||
}
|
||||
|
||||
float m_BestTime;
|
||||
float m_CurrentTime;
|
||||
float m_aBestCpTime[NUM_CHECKPOINTS];
|
||||
};
|
||||
|
||||
struct CTeamrank
|
||||
{
|
||||
CUuid m_TeamID;
|
||||
char m_aaNames[MAX_CLIENTS][MAX_NAME_LENGTH];
|
||||
unsigned int m_NumNames;
|
||||
CTeamrank();
|
||||
|
||||
// Assumes that a database query equivalent to
|
||||
//
|
||||
// SELECT TeamID, Name [, ...] -- the order is important
|
||||
// FROM record_teamrace
|
||||
// ORDER BY TeamID, Name
|
||||
//
|
||||
// was executed and that the result line of the first team member is already selected.
|
||||
// Afterwards the team member of the next team is selected.
|
||||
//
|
||||
// Returns true on SQL failure
|
||||
//
|
||||
// if another team can be extracted
|
||||
bool NextSqlResult(IDbConnection *pSqlServer, bool *pEnd, char *pError, int ErrorSize);
|
||||
|
||||
bool SamePlayers(const std::vector<std::string> *aSortedNames);
|
||||
};
|
||||
|
||||
struct CScoreWorker
|
||||
{
|
||||
static bool Init(IDbConnection *pSqlServer, const ISqlData *pGameData, char *pError, int ErrorSize);
|
||||
|
||||
static bool RandomMap(IDbConnection *pSqlServer, const ISqlData *pGameData, char *pError, int ErrorSize);
|
||||
static bool RandomUnfinishedMap(IDbConnection *pSqlServer, const ISqlData *pGameData, char *pError, int ErrorSize);
|
||||
static bool MapVote(IDbConnection *pSqlServer, const ISqlData *pGameData, char *pError, int ErrorSize);
|
||||
|
||||
static bool LoadPlayerData(IDbConnection *pSqlServer, const ISqlData *pGameData, char *pError, int ErrorSize);
|
||||
static bool MapInfo(IDbConnection *pSqlServer, const ISqlData *pGameData, char *pError, int ErrorSize);
|
||||
static bool ShowRank(IDbConnection *pSqlServer, const ISqlData *pGameData, char *pError, int ErrorSize);
|
||||
static bool ShowTeamRank(IDbConnection *pSqlServer, const ISqlData *pGameData, char *pError, int ErrorSize);
|
||||
static bool ShowTop(IDbConnection *pSqlServer, const ISqlData *pGameData, char *pError, int ErrorSize);
|
||||
static bool ShowTeamTop5(IDbConnection *pSqlServer, const ISqlData *pGameData, char *pError, int ErrorSize);
|
||||
static bool ShowPlayerTeamTop5(IDbConnection *pSqlServer, const ISqlData *pGameData, char *pError, int ErrorSize);
|
||||
static bool ShowTimes(IDbConnection *pSqlServer, const ISqlData *pGameData, char *pError, int ErrorSize);
|
||||
static bool ShowPoints(IDbConnection *pSqlServer, const ISqlData *pGameData, char *pError, int ErrorSize);
|
||||
static bool ShowTopPoints(IDbConnection *pSqlServer, const ISqlData *pGameData, char *pError, int ErrorSize);
|
||||
static bool GetSaves(IDbConnection *pSqlServer, const ISqlData *pGameData, char *pError, int ErrorSize);
|
||||
|
||||
static bool SaveTeam(IDbConnection *pSqlServer, const ISqlData *pGameData, bool Failure, char *pError, int ErrorSize);
|
||||
static bool LoadTeam(IDbConnection *pSqlServer, const ISqlData *pGameData, bool Failure, char *pError, int ErrorSize);
|
||||
|
||||
static bool SaveScore(IDbConnection *pSqlServer, const ISqlData *pGameData, bool Failure, char *pError, int ErrorSize);
|
||||
static bool SaveTeamScore(IDbConnection *pSqlServer, const ISqlData *pGameData, bool Failure, char *pError, int ErrorSize);
|
||||
};
|
||||
|
||||
#endif // GAME_SERVER_SCOREWORKER_H
|
89
src/test/score.cpp
Normal file
89
src/test/score.cpp
Normal file
|
@ -0,0 +1,89 @@
|
|||
#include <gtest/gtest.h>
|
||||
|
||||
#include <base/detect.h>
|
||||
#include <engine/server/databases/connection.h>
|
||||
#include <engine/shared/config.h>
|
||||
#include <game/server/scoreworker.h>
|
||||
#include <iostream>
|
||||
|
||||
char *CSaveTeam::GetString()
|
||||
{
|
||||
// Dummy implementation for testing
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int CSaveTeam::FromString(char const *)
|
||||
{
|
||||
// Dummy implementation for testing
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool CSaveTeam::MatchPlayers(const char (*paNames)[MAX_NAME_LENGTH], const int *pClientID, int NumPlayer, char *pMessage, int MessageLen)
|
||||
{
|
||||
// Dummy implementation for testing
|
||||
return false;
|
||||
}
|
||||
|
||||
class Score : public ::testing::Test
|
||||
{
|
||||
public:
|
||||
~Score()
|
||||
{
|
||||
delete conn;
|
||||
}
|
||||
|
||||
protected:
|
||||
IDbConnection *conn{CreateSqliteConnection(":memory:", true)};
|
||||
char aError[256] = {};
|
||||
};
|
||||
|
||||
TEST_F(Score, SaveScore)
|
||||
{
|
||||
ASSERT_FALSE(conn->Connect(aError, sizeof(aError))) << aError;
|
||||
|
||||
CSqlInitData initData(std::make_shared<CScoreInitResult>());
|
||||
str_copy(initData.m_aMap, "Kobra 3", sizeof(initData.m_aMap));
|
||||
ASSERT_FALSE(CScoreWorker::Init(conn, &initData, aError, sizeof(aError))) << aError;
|
||||
|
||||
str_copy(g_Config.m_SvSqlServerName, "USA", sizeof(g_Config.m_SvSqlServerName));
|
||||
|
||||
CSqlScoreData scoreData(std::make_shared<CScorePlayerResult>());
|
||||
str_copy(scoreData.m_aMap, "Kobra 3", sizeof(scoreData.m_aMap));
|
||||
str_copy(scoreData.m_aGameUuid, "8d300ecf-5873-4297-bee5-95668fdff320", sizeof(scoreData.m_aGameUuid));
|
||||
str_copy(scoreData.m_aName, "nameless tee", sizeof(scoreData.m_aName));
|
||||
scoreData.m_ClientID = 0;
|
||||
scoreData.m_Time = 100.0;
|
||||
str_copy(scoreData.m_aTimestamp, "2021-11-24 19:24:08", sizeof(scoreData.m_aTimestamp));
|
||||
for(int i = 0; i < NUM_CHECKPOINTS; i++)
|
||||
scoreData.m_aCpCurrent[i] = i;
|
||||
scoreData.m_Num = 1;
|
||||
scoreData.m_Search = false;
|
||||
str_copy(scoreData.m_aRequestingPlayer, "deen", sizeof(scoreData.m_aRequestingPlayer));
|
||||
ASSERT_FALSE(CScoreWorker::SaveScore(conn, &scoreData, false, aError, sizeof(aError))) << aError;
|
||||
|
||||
auto pPlayerResult = std::make_shared<CScorePlayerResult>();
|
||||
CSqlPlayerRequest playerRequest(pPlayerResult);
|
||||
str_copy(playerRequest.m_aName, "Kobra 3", sizeof(playerRequest.m_aName));
|
||||
str_copy(playerRequest.m_aMap, "Kobra 3", sizeof(playerRequest.m_aMap));
|
||||
str_copy(playerRequest.m_aRequestingPlayer, "brainless tee", sizeof(playerRequest.m_aRequestingPlayer));
|
||||
playerRequest.m_Offset = 0;
|
||||
str_copy(playerRequest.m_aServer, "GER", sizeof(playerRequest.m_aServer));
|
||||
CScoreWorker::ShowTop(conn, &playerRequest, aError, sizeof(aError));
|
||||
|
||||
ASSERT_EQ(pPlayerResult->m_MessageKind, CScorePlayerResult::DIRECT);
|
||||
EXPECT_STREQ(pPlayerResult->m_Data.m_aaMessages[0], "------------ Global Top ------------");
|
||||
EXPECT_STREQ(pPlayerResult->m_Data.m_aaMessages[1], "1. nameless tee Time: 01:40.00");
|
||||
EXPECT_STREQ(pPlayerResult->m_Data.m_aaMessages[2], "------------ GER Top ------------");
|
||||
for(int i = 3; i < CScorePlayerResult::MAX_MESSAGES; i++)
|
||||
EXPECT_STREQ(pPlayerResult->m_Data.m_aaMessages[i], "");
|
||||
|
||||
str_copy(playerRequest.m_aServer, "USA", sizeof(playerRequest.m_aServer));
|
||||
CScoreWorker::ShowTop(conn, &playerRequest, aError, sizeof(aError));
|
||||
|
||||
ASSERT_EQ(pPlayerResult->m_MessageKind, CScorePlayerResult::DIRECT);
|
||||
EXPECT_STREQ(pPlayerResult->m_Data.m_aaMessages[0], "------------ Global Top ------------");
|
||||
EXPECT_STREQ(pPlayerResult->m_Data.m_aaMessages[1], "1. nameless tee Time: 01:40.00");
|
||||
EXPECT_STREQ(pPlayerResult->m_Data.m_aaMessages[2], "---------------------------------------");
|
||||
for(int i = 3; i < CScorePlayerResult::MAX_MESSAGES; i++)
|
||||
EXPECT_STREQ(pPlayerResult->m_Data.m_aaMessages[i], "");
|
||||
}
|
Loading…
Reference in a new issue