Make timestamp consistent in scores

The motivation is to have the exact same timestamp for every member
finishing in a team and the team rank as well. This makes the database
more consistent and tooling easier.
This commit is contained in:
def 2019-04-02 19:53:37 +02:00
parent 4f168ba936
commit ef0e685496
7 changed files with 42 additions and 39 deletions

View file

@ -4,7 +4,11 @@
#include "entities/character.h"
#include "gamecontext.h"
#define NUM_CHECKPOINTS 25
enum
{
NUM_CHECKPOINTS = 25,
TIMESTAMP_STR_LENGTH = 20, // 2019-04-02 19:38:36
};
class CPlayerData
{
@ -47,9 +51,9 @@ public:
virtual void MapVote(int ClientID, const char *pMapName) = 0;
virtual void CheckBirthday(int ClientID) = 0;
virtual void LoadScore(int ClientID) = 0;
virtual void SaveScore(int ClientID, float Time, float aCpTime[NUM_CHECKPOINTS], bool NotEligible) = 0;
virtual void SaveScore(int ClientID, float Time, const char *pTimestamp, float aCpTime[NUM_CHECKPOINTS], bool NotEligible) = 0;
virtual void SaveTeamScore(int *pClientIDs, unsigned int Size, float Time) = 0;
virtual void SaveTeamScore(int *pClientIDs, unsigned int Size, float Time, const char *pTimestamp) = 0;
virtual void ShowTop5(IConsole::IResult *pResult, int ClientID, void *pUserData, int Debut=1) = 0;
virtual void ShowRank(int ClientID, const char *pName, bool Search=false) = 0;

View file

@ -221,12 +221,12 @@ void CFileScore::LoadScore(int ClientID)
}
}
void CFileScore::SaveTeamScore(int* ClientIDs, unsigned int Size, float Time)
void CFileScore::SaveTeamScore(int* ClientIDs, unsigned int Size, float Time, const char *pTimestamp)
{
dbg_msg("filescore", "saveteamscore not implemented for filescore");
}
void CFileScore::SaveScore(int ClientID, float Time,
void CFileScore::SaveScore(int ClientID, float Time, const char *pTimestamp,
float CpTime[NUM_CHECKPOINTS], bool NotEligible)
{
CConsole* pCon = (CConsole*) GameServer()->Console();

View file

@ -66,9 +66,9 @@ public:
virtual void LoadScore(int ClientID);
virtual void MapInfo(int ClientID, const char* MapName);
virtual void MapVote(int ClientID, const char* MapName);
virtual void SaveScore(int ClientID, float Time,
virtual void SaveScore(int ClientID, float Time, const char *pTimestamp,
float CpTime[NUM_CHECKPOINTS], bool NotEligible);
virtual void SaveTeamScore(int* ClientIDs, unsigned int Size, float Time);
virtual void SaveTeamScore(int* ClientIDs, unsigned int Size, float Time, const char *pTimestamp);
virtual void ShowTop5(IConsole::IResult *pResult, int ClientID,
void *pUserData, int Debut = 1);

View file

@ -466,7 +466,7 @@ bool CSqlScore::MapInfoThread(CSqlServer* pSqlServer, const CSqlData *pGameData,
return false;
}
void CSqlScore::SaveScore(int ClientID, float Time, float CpTime[NUM_CHECKPOINTS], bool NotEligible)
void CSqlScore::SaveScore(int ClientID, float Time, const char *pTimestamp, float CpTime[NUM_CHECKPOINTS], bool NotEligible)
{
CConsole* pCon = (CConsole*)GameServer()->Console();
if(pCon->m_Cheated)
@ -475,6 +475,7 @@ void CSqlScore::SaveScore(int ClientID, float Time, float CpTime[NUM_CHECKPOINTS
Tmp->m_ClientID = ClientID;
Tmp->m_Name = Server()->ClientName(ClientID);
Tmp->m_Time = Time;
str_copy(Tmp->m_aTimestamp, pTimestamp, sizeof(Tmp->m_aTimestamp));
Tmp->m_NotEligible = NotEligible;
for(int i = 0; i < NUM_CHECKPOINTS; i++)
Tmp->m_aCpCurrent[i] = CpTime[i];
@ -497,11 +498,8 @@ bool CSqlScore::SaveScoreThread(CSqlServer* pSqlServer, const CSqlData *pGameDat
{
dbg_msg("sql", "ERROR: Could not save Score, writing insert to a file now...");
char aTimestamp [20];
sqlstr::GetTimeStamp(aTimestamp, sizeof(aTimestamp));
char aBuf[768];
str_format(aBuf, sizeof(aBuf), "INSERT IGNORE INTO %%s_race(Map, Name, Timestamp, Time, Server, cp1, cp2, cp3, cp4, cp5, cp6, cp7, cp8, cp9, cp10, cp11, cp12, cp13, cp14, cp15, cp16, cp17, cp18, cp19, cp20, cp21, cp22, cp23, cp24, cp25, GameID) VALUES ('%s', '%s', '%s', '%.2f', '%s', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%s');%s", pData->m_Map.ClrStr(), pData->m_Name.ClrStr(), aTimestamp, pData->m_Time, g_Config.m_SvSqlServerName, pData->m_aCpCurrent[0], pData->m_aCpCurrent[1], pData->m_aCpCurrent[2], pData->m_aCpCurrent[3], pData->m_aCpCurrent[4], pData->m_aCpCurrent[5], pData->m_aCpCurrent[6], pData->m_aCpCurrent[7], pData->m_aCpCurrent[8], pData->m_aCpCurrent[9], pData->m_aCpCurrent[10], pData->m_aCpCurrent[11], pData->m_aCpCurrent[12], pData->m_aCpCurrent[13], pData->m_aCpCurrent[14], pData->m_aCpCurrent[15], pData->m_aCpCurrent[16], pData->m_aCpCurrent[17], pData->m_aCpCurrent[18], pData->m_aCpCurrent[19], pData->m_aCpCurrent[20], pData->m_aCpCurrent[21], pData->m_aCpCurrent[22], pData->m_aCpCurrent[23], pData->m_aCpCurrent[24], pData->m_GameUuid.ClrStr(), pData->m_NotEligible ? " -- not eligible" : "");
str_format(aBuf, sizeof(aBuf), "INSERT IGNORE INTO %%s_race(Map, Name, Timestamp, Time, Server, cp1, cp2, cp3, cp4, cp5, cp6, cp7, cp8, cp9, cp10, cp11, cp12, cp13, cp14, cp15, cp16, cp17, cp18, cp19, cp20, cp21, cp22, cp23, cp24, cp25, GameID) VALUES ('%s', '%s', '%s', '%.2f', '%s', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%s');%s", pData->m_Map.ClrStr(), pData->m_Name.ClrStr(), pData->m_aTimestamp, pData->m_Time, g_Config.m_SvSqlServerName, pData->m_aCpCurrent[0], pData->m_aCpCurrent[1], pData->m_aCpCurrent[2], pData->m_aCpCurrent[3], pData->m_aCpCurrent[4], pData->m_aCpCurrent[5], pData->m_aCpCurrent[6], pData->m_aCpCurrent[7], pData->m_aCpCurrent[8], pData->m_aCpCurrent[9], pData->m_aCpCurrent[10], pData->m_aCpCurrent[11], pData->m_aCpCurrent[12], pData->m_aCpCurrent[13], pData->m_aCpCurrent[14], pData->m_aCpCurrent[15], pData->m_aCpCurrent[16], pData->m_aCpCurrent[17], pData->m_aCpCurrent[18], pData->m_aCpCurrent[19], pData->m_aCpCurrent[20], pData->m_aCpCurrent[21], pData->m_aCpCurrent[22], pData->m_aCpCurrent[23], pData->m_aCpCurrent[24], pData->m_GameUuid.ClrStr(), pData->m_NotEligible ? " -- not eligible" : "");
io_write(File, aBuf, str_length(aBuf));
io_write_newline(File);
io_close(File);
@ -553,7 +551,7 @@ bool CSqlScore::SaveScoreThread(CSqlServer* pSqlServer, const CSqlData *pGameDat
}
// if no entry found... create a new one
str_format(aBuf, sizeof(aBuf), "INSERT IGNORE INTO %s_race(Map, Name, Timestamp, Time, Server, cp1, cp2, cp3, cp4, cp5, cp6, cp7, cp8, cp9, cp10, cp11, cp12, cp13, cp14, cp15, cp16, cp17, cp18, cp19, cp20, cp21, cp22, cp23, cp24, cp25, GameID) VALUES ('%s', '%s', CURRENT_TIMESTAMP(), '%.2f', '%s', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%s');", pSqlServer->GetPrefix(), pData->m_Map.ClrStr(), pData->m_Name.ClrStr(), pData->m_Time, g_Config.m_SvSqlServerName, pData->m_aCpCurrent[0], pData->m_aCpCurrent[1], pData->m_aCpCurrent[2], pData->m_aCpCurrent[3], pData->m_aCpCurrent[4], pData->m_aCpCurrent[5], pData->m_aCpCurrent[6], pData->m_aCpCurrent[7], pData->m_aCpCurrent[8], pData->m_aCpCurrent[9], pData->m_aCpCurrent[10], pData->m_aCpCurrent[11], pData->m_aCpCurrent[12], pData->m_aCpCurrent[13], pData->m_aCpCurrent[14], pData->m_aCpCurrent[15], pData->m_aCpCurrent[16], pData->m_aCpCurrent[17], pData->m_aCpCurrent[18], pData->m_aCpCurrent[19], pData->m_aCpCurrent[20], pData->m_aCpCurrent[21], pData->m_aCpCurrent[22], pData->m_aCpCurrent[23], pData->m_aCpCurrent[24], pData->m_GameUuid.ClrStr());
str_format(aBuf, sizeof(aBuf), "INSERT IGNORE INTO %s_race(Map, Name, Timestamp, Time, Server, cp1, cp2, cp3, cp4, cp5, cp6, cp7, cp8, cp9, cp10, cp11, cp12, cp13, cp14, cp15, cp16, cp17, cp18, cp19, cp20, cp21, cp22, cp23, cp24, cp25, GameID) VALUES ('%s', '%s', '%s', '%.2f', '%s', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%.2f', '%s');", pSqlServer->GetPrefix(), pData->m_Map.ClrStr(), pData->m_Name.ClrStr(), pData->m_aTimestamp, pData->m_Time, g_Config.m_SvSqlServerName, pData->m_aCpCurrent[0], pData->m_aCpCurrent[1], pData->m_aCpCurrent[2], pData->m_aCpCurrent[3], pData->m_aCpCurrent[4], pData->m_aCpCurrent[5], pData->m_aCpCurrent[6], pData->m_aCpCurrent[7], pData->m_aCpCurrent[8], pData->m_aCpCurrent[9], pData->m_aCpCurrent[10], pData->m_aCpCurrent[11], pData->m_aCpCurrent[12], pData->m_aCpCurrent[13], pData->m_aCpCurrent[14], pData->m_aCpCurrent[15], pData->m_aCpCurrent[16], pData->m_aCpCurrent[17], pData->m_aCpCurrent[18], pData->m_aCpCurrent[19], pData->m_aCpCurrent[20], pData->m_aCpCurrent[21], pData->m_aCpCurrent[22], pData->m_aCpCurrent[23], pData->m_aCpCurrent[24], pData->m_GameUuid.ClrStr());
dbg_msg("sql", "%s", aBuf);
pSqlServer->executeSql(aBuf);
@ -568,7 +566,7 @@ bool CSqlScore::SaveScoreThread(CSqlServer* pSqlServer, const CSqlData *pGameDat
return false;
}
void CSqlScore::SaveTeamScore(int* aClientIDs, unsigned int Size, float Time)
void CSqlScore::SaveTeamScore(int* aClientIDs, unsigned int Size, float Time, const char *pTimestamp)
{
CConsole* pCon = (CConsole*)GameServer()->Console();
if(pCon->m_Cheated)
@ -583,6 +581,7 @@ void CSqlScore::SaveTeamScore(int* aClientIDs, unsigned int Size, float Time)
}
Tmp->m_Size = Size;
Tmp->m_Time = Time;
str_copy(Tmp->m_aTimestamp, pTimestamp, sizeof(Tmp->m_aTimestamp));
thread_init_and_detach(ExecSqlFunc, new CSqlExecData(SaveTeamScoreThread, Tmp, false), "save team score");
}
@ -606,13 +605,10 @@ bool CSqlScore::SaveTeamScoreThread(CSqlServer* pSqlServer, const CSqlData *pGam
io_write(File, pUUID, sizeof(pUUID) - 1);
io_write_newline(File);
char aTimestamp [20];
sqlstr::GetTimeStamp(aTimestamp, sizeof(aTimestamp));
char aBuf[2300];
for(unsigned int i = 0; i < pData->m_Size; i++)
{
str_format(aBuf, sizeof(aBuf), "INSERT IGNORE INTO %%s_teamrace(Map, Name, Timestamp, Time, ID, GameID) VALUES ('%s', '%s', '%s', '%.2f', @id, '%s');%s", pData->m_Map.ClrStr(), pData->m_aNames[i].ClrStr(), aTimestamp, pData->m_Time, pData->m_GameUuid.ClrStr(), pData->m_NotEligible ? " -- not eligible" : "");
str_format(aBuf, sizeof(aBuf), "INSERT IGNORE INTO %%s_teamrace(Map, Name, Timestamp, Time, ID, GameID) VALUES ('%s', '%s', '%s', '%.2f', @id, '%s');%s", pData->m_Map.ClrStr(), pData->m_aNames[i].ClrStr(), pData->m_aTimestamp, pData->m_Time, pData->m_GameUuid.ClrStr(), pData->m_NotEligible ? " -- not eligible" : "");
io_write(File, aBuf, str_length(aBuf));
io_write_newline(File);
}
@ -699,7 +695,7 @@ bool CSqlScore::SaveTeamScoreThread(CSqlServer* pSqlServer, const CSqlData *pGam
if (aUpdateID[0])
{
str_format(aBuf, sizeof(aBuf), "UPDATE %s_teamrace SET Time='%.2f', Timestamp=CURRENT_TIMESTAMP() WHERE ID = '%s';", pSqlServer->GetPrefix(), pData->m_Time, aUpdateID);
str_format(aBuf, sizeof(aBuf), "UPDATE %s_teamrace SET Time='%.2f', Timestamp='%s' WHERE ID = '%s';", pSqlServer->GetPrefix(), pData->m_Time, pData->m_aTimestamp, aUpdateID);
dbg_msg("sql", "%s", aBuf);
pSqlServer->executeSql(aBuf);
}
@ -710,7 +706,7 @@ bool CSqlScore::SaveTeamScoreThread(CSqlServer* pSqlServer, const CSqlData *pGam
for(unsigned int i = 0; i < pData->m_Size; i++)
{
// if no entry found... create a new one
str_format(aBuf, sizeof(aBuf), "INSERT IGNORE INTO %s_teamrace(Map, Name, Timestamp, Time, ID, GameID) VALUES ('%s', '%s', CURRENT_TIMESTAMP(), '%.2f', @id, '%s');", pSqlServer->GetPrefix(), pData->m_Map.ClrStr(), pData->m_aNames[i].ClrStr(), pData->m_Time, pData->m_GameUuid.ClrStr());
str_format(aBuf, sizeof(aBuf), "INSERT IGNORE INTO %s_teamrace(Map, Name, Timestamp, Time, ID, GameID) VALUES ('%s', '%s', '%s', '%.2f', @id, '%s');", pSqlServer->GetPrefix(), pData->m_Map.ClrStr(), pData->m_aNames[i].ClrStr(), pData->m_aTimestamp, pData->m_Time, pData->m_GameUuid.ClrStr());
dbg_msg("sql", "%s", aBuf);
pSqlServer->executeSql(aBuf);
}
@ -1454,11 +1450,8 @@ bool CSqlScore::SaveTeamThread(CSqlServer* pSqlServer, const CSqlData *pGameData
{
dbg_msg("sql", "ERROR: Could not save Teamsave, writing insert to a file now...");
char aTimestamp [20];
sqlstr::GetTimeStamp(aTimestamp, sizeof(aTimestamp));
char aBuf[65536];
str_format(aBuf, sizeof(aBuf), "INSERT IGNORE INTO %%s_saves(Savegame, Map, Code, Timestamp, Server) VALUES ('%s', '%s', '%s', '%s', '%s');", TeamString, pData->m_Map.ClrStr(), pData->m_Code.ClrStr(), aTimestamp, pData->m_Server);
str_format(aBuf, sizeof(aBuf), "INSERT IGNORE INTO %%s_saves(Savegame, Map, Code, Timestamp, Server) VALUES ('%s', '%s', '%s', CURRENT_TIMESTAMP(), '%s');", TeamString, pData->m_Map.ClrStr(), pData->m_Code.ClrStr(), pData->m_Server);
io_write(File, aBuf, str_length(aBuf));
io_write_newline(File);
io_close(File);

View file

@ -103,20 +103,21 @@ struct CSqlScoreData : CSqlData
bool m_NotEligible;
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];
char m_aRequestingPlayer[MAX_NAME_LENGTH];
};
struct CSqlTeamScoreData : CSqlData
{
bool m_NotEligible;
float m_Time;
char m_aTimestamp[TIMESTAMP_STR_LENGTH];
unsigned int m_Size;
int m_aClientIDs[MAX_CLIENTS];
sqlstr::CSqlString<MAX_NAME_LENGTH> m_aNames [MAX_CLIENTS];
float m_Time;
sqlstr::CSqlString<MAX_NAME_LENGTH> m_aNames[MAX_CLIENTS];
};
struct CSqlTeamSave : CSqlData
@ -179,9 +180,9 @@ public:
virtual void LoadScore(int ClientID);
virtual void MapInfo(int ClientID, const char* MapName);
virtual void MapVote(int ClientID, const char* MapName);
virtual void SaveScore(int ClientID, float Time,
virtual void SaveScore(int ClientID, float Time, const char *pTimestamp,
float CpTime[NUM_CHECKPOINTS], bool NotEligible);
virtual void SaveTeamScore(int* aClientIDs, unsigned int Size, float Time);
virtual void SaveTeamScore(int* aClientIDs, unsigned int Size, float Time, const char *pTimestamp);
virtual void ShowRank(int ClientID, const char* pName, bool Search = false);
virtual void ShowTeamRank(int ClientID, const char* pName, bool Search = false);
virtual void ShowTimes(int ClientID, const char* pName, int Debut = 1);

View file

@ -141,7 +141,10 @@ void CGameTeams::OnCharacterFinish(int ClientID)
/ ((float)Server()->TickSpeed());
if (Time < 0.000001f)
return;
OnFinish(pPlayer, Time);
char aTimestamp[TIMESTAMP_STR_LENGTH];
str_timestamp_format(aTimestamp, sizeof(aTimestamp), FORMAT_SPACE); // 2019-04-02 19:41:58
OnFinish(pPlayer, Time, aTimestamp);
}
}
else
@ -179,12 +182,14 @@ void CGameTeams::CheckTeamFinished(int Team)
/ ((float)Server()->TickSpeed());
if (Time < 0.000001f)
return;
char aTimestamp[TIMESTAMP_STR_LENGTH];
str_timestamp_format(aTimestamp, sizeof(aTimestamp), FORMAT_SPACE); // 2019-04-02 19:41:58
for (unsigned int i = 0; i < PlayersCount; ++i)
OnFinish(TeamPlayers[i], Time);
OnFinish(TeamPlayers[i], Time, aTimestamp);
ChangeTeamState(Team, TEAMSTATE_FINISHED); //TODO: Make it better
//ChangeTeamState(Team, TEAMSTATE_OPEN);
OnTeamFinish(TeamPlayers, PlayersCount, Time);
OnTeamFinish(TeamPlayers, PlayersCount, Time, aTimestamp);
}
}
}
@ -455,7 +460,7 @@ float *CGameTeams::GetCpCurrent(CPlayer* Player)
return NULL;
}
void CGameTeams::OnTeamFinish(CPlayer** Players, unsigned int Size, float Time)
void CGameTeams::OnTeamFinish(CPlayer** Players, unsigned int Size, float Time, const char *pTimestamp)
{
bool CallSaveScore = false;
@ -480,10 +485,10 @@ void CGameTeams::OnTeamFinish(CPlayer** Players, unsigned int Size, float Time)
}
if (CallSaveScore && Size >= 2)
GameServer()->Score()->SaveTeamScore(PlayerCIDs, Size, Time);
GameServer()->Score()->SaveTeamScore(PlayerCIDs, Size, Time, pTimestamp);
}
void CGameTeams::OnFinish(CPlayer* Player, float Time)
void CGameTeams::OnFinish(CPlayer* Player, float Time, const char *pTimestamp)
{
if (!Player || !Player->IsPlaying())
return;
@ -558,7 +563,7 @@ void CGameTeams::OnFinish(CPlayer* Player, float Time)
if (CallSaveScore)
if (g_Config.m_SvNamelessScore || !str_startswith(Server()->ClientName(Player->GetCID()), "nameless tee"))
GameServer()->Score()->SaveScore(Player->GetCID(), Time,
GameServer()->Score()->SaveScore(Player->GetCID(), Time, pTimestamp,
GetCpCurrent(Player), Player->m_NotEligibleForFinish);
bool NeedToSendNewRecord = false;

View file

@ -18,8 +18,8 @@ class CGameTeams
void CheckTeamFinished(int ClientID);
bool TeamFinished(int Team);
void OnTeamFinish(CPlayer** Players, unsigned int Size, float Time);
void OnFinish(CPlayer* Player, float Time);
void OnTeamFinish(CPlayer** Players, unsigned int Size, float Time, const char *pTimestamp);
void OnFinish(CPlayer* Player, float Time, const char *pTimestamp);
public:
enum