mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-10 10:08:18 +00:00
Thread safe saving of score
This commit is contained in:
parent
5dcb6f3b0d
commit
13c80fdc56
|
@ -123,6 +123,7 @@ void CPlayer::Reset()
|
||||||
#if defined(CONF_SQL)
|
#if defined(CONF_SQL)
|
||||||
m_LastSQLQuery = 0;
|
m_LastSQLQuery = 0;
|
||||||
m_SqlQueryResult = nullptr;
|
m_SqlQueryResult = nullptr;
|
||||||
|
m_SqlFinishResult = nullptr;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int64 Now = Server()->Tick();
|
int64 Now = Server()->Tick();
|
||||||
|
@ -148,8 +149,18 @@ void CPlayer::Tick()
|
||||||
if(!g_Config.m_DbgDummies || m_ClientID < MAX_CLIENTS-g_Config.m_DbgDummies)
|
if(!g_Config.m_DbgDummies || m_ClientID < MAX_CLIENTS-g_Config.m_DbgDummies)
|
||||||
#endif
|
#endif
|
||||||
#if defined(CONF_SQL)
|
#if defined(CONF_SQL)
|
||||||
ProcessSqlResult();
|
if(m_SqlQueryResult != nullptr && m_SqlQueryResult.use_count() == 1)
|
||||||
|
{
|
||||||
|
ProcessSqlResult(*m_SqlQueryResult);
|
||||||
|
m_SqlQueryResult = nullptr;
|
||||||
|
}
|
||||||
|
if(m_SqlFinishResult != nullptr && m_SqlFinishResult.use_count() == 1)
|
||||||
|
{
|
||||||
|
ProcessSqlResult(*m_SqlFinishResult);
|
||||||
|
m_SqlFinishResult = nullptr;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(!Server()->ClientIngame(m_ClientID))
|
if(!Server()->ClientIngame(m_ClientID))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -779,45 +790,45 @@ void CPlayer::SpectatePlayerName(const char *pName)
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(CONF_SQL)
|
#if defined(CONF_SQL)
|
||||||
void CPlayer::ProcessSqlResult()
|
void CPlayer::ProcessSqlResult(CSqlPlayerResult &Result)
|
||||||
{
|
{
|
||||||
if(m_SqlQueryResult == nullptr || m_SqlQueryResult.use_count() != 1)
|
if(Result.m_Done) // SQL request was successful
|
||||||
return;
|
|
||||||
|
|
||||||
if(m_SqlQueryResult->m_Done) // SQL request was successful
|
|
||||||
{
|
{
|
||||||
int NumMessages = (int)(sizeof(m_SqlQueryResult->m_aaMessages)/sizeof(m_SqlQueryResult->m_aaMessages[0]));
|
int NumMessages = (int)(sizeof(Result.m_aaMessages)/sizeof(Result.m_aaMessages[0]));
|
||||||
switch(m_SqlQueryResult->m_MessageKind)
|
switch(Result.m_MessageKind)
|
||||||
{
|
{
|
||||||
case CSqlPlayerResult::DIRECT:
|
case CSqlPlayerResult::DIRECT:
|
||||||
for(int i = 0; i < NumMessages; i++)
|
for(int i = 0; i < NumMessages; i++)
|
||||||
{
|
{
|
||||||
if(m_SqlQueryResult->m_aaMessages[i][0] == 0)
|
if(Result.m_aaMessages[i][0] == 0)
|
||||||
break;
|
break;
|
||||||
GameServer()->SendChatTarget(m_ClientID, m_SqlQueryResult->m_aaMessages[i]);
|
GameServer()->SendChatTarget(m_ClientID, Result.m_aaMessages[i]);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CSqlPlayerResult::ALL:
|
case CSqlPlayerResult::ALL:
|
||||||
for(int i = 0; i < NumMessages; i++)
|
for(int i = 0; i < NumMessages; i++)
|
||||||
{
|
{
|
||||||
if(m_SqlQueryResult->m_aaMessages[i][0] == 0)
|
if(Result.m_aaMessages[i][0] == 0)
|
||||||
break;
|
break;
|
||||||
GameServer()->SendChat(-1, CGameContext::CHAT_ALL, m_SqlQueryResult->m_aaMessages[i]);
|
GameServer()->SendChat(-1, CGameContext::CHAT_ALL, Result.m_aaMessages[i]);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case CSqlPlayerResult::BROADCAST:
|
||||||
|
if(Result.m_Data.m_Broadcast[0] != 0)
|
||||||
|
GameServer()->SendBroadcast(Result.m_Data.m_Broadcast, -1);
|
||||||
|
break;
|
||||||
case CSqlPlayerResult::MAP_VOTE:
|
case CSqlPlayerResult::MAP_VOTE:
|
||||||
// TODO: start vote
|
// TODO: start vote
|
||||||
break;
|
break;
|
||||||
case CSqlPlayerResult::PLAYER_INFO:
|
case CSqlPlayerResult::PLAYER_INFO:
|
||||||
GameServer()->Score()->PlayerData(m_ClientID)->Set(
|
GameServer()->Score()->PlayerData(m_ClientID)->Set(
|
||||||
m_SqlQueryResult->m_Data.m_Info.m_Time,
|
Result.m_Data.m_Info.m_Time,
|
||||||
m_SqlQueryResult->m_Data.m_Info.m_CpTime
|
Result.m_Data.m_Info.m_CpTime
|
||||||
);
|
);
|
||||||
printf("%d", m_SqlQueryResult->m_Data.m_Info.m_Score);
|
m_Score = Result.m_Data.m_Info.m_Score;
|
||||||
m_Score = m_SqlQueryResult->m_Data.m_Info.m_Score;
|
m_HasFinishScore = Result.m_Data.m_Info.m_HasFinishScore;
|
||||||
m_HasFinishScore = m_SqlQueryResult->m_Data.m_Info.m_HasFinishScore;
|
|
||||||
Server()->ExpireServerInfo();
|
Server()->ExpireServerInfo();
|
||||||
int Birthday = m_SqlQueryResult->m_Data.m_Info.m_Birthday;
|
int Birthday = Result.m_Data.m_Info.m_Birthday;
|
||||||
if(Birthday != 0)
|
if(Birthday != 0)
|
||||||
{
|
{
|
||||||
char aBuf[512];
|
char aBuf[512];
|
||||||
|
@ -833,6 +844,5 @@ void CPlayer::ProcessSqlResult()
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_SqlQueryResult = nullptr;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -198,9 +198,10 @@ public:
|
||||||
bool m_Halloween;
|
bool m_Halloween;
|
||||||
bool m_FirstPacket;
|
bool m_FirstPacket;
|
||||||
#if defined(CONF_SQL)
|
#if defined(CONF_SQL)
|
||||||
void ProcessSqlResult();
|
void ProcessSqlResult(CSqlPlayerResult &Result);
|
||||||
int64 m_LastSQLQuery;
|
int64 m_LastSQLQuery;
|
||||||
std::shared_ptr<CSqlPlayerResult> m_SqlQueryResult;
|
std::shared_ptr<CSqlPlayerResult> m_SqlQueryResult;
|
||||||
|
std::shared_ptr<CSqlPlayerResult> m_SqlFinishResult;
|
||||||
#endif
|
#endif
|
||||||
bool m_NotEligibleForFinish;
|
bool m_NotEligibleForFinish;
|
||||||
int64 m_EligibleForFinishCheck;
|
int64 m_EligibleForFinishCheck;
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
std::atomic_int CSqlScore::ms_InstanceCount(0);
|
std::atomic_int CSqlScore::ms_InstanceCount(0);
|
||||||
|
|
||||||
CSqlPlayerResult::CSqlPlayerResult() :
|
CSqlPlayerResult::CSqlPlayerResult() :
|
||||||
m_Done(0)
|
m_Done(false)
|
||||||
{
|
{
|
||||||
SetVariant(Variant::DIRECT);
|
SetVariant(Variant::DIRECT);
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,9 @@ void CSqlPlayerResult::SetVariant(Variant v)
|
||||||
for(int i = 0; i < (int)(sizeof(m_aaMessages)/sizeof(m_aaMessages[0])); i++)
|
for(int i = 0; i < (int)(sizeof(m_aaMessages)/sizeof(m_aaMessages[0])); i++)
|
||||||
m_aaMessages[i][0] = 0;
|
m_aaMessages[i][0] = 0;
|
||||||
break;
|
break;
|
||||||
|
case BROADCAST:
|
||||||
|
m_Data.m_Broadcast[0] = 0;
|
||||||
|
break;
|
||||||
case MAP_VOTE:
|
case MAP_VOTE:
|
||||||
break;
|
break;
|
||||||
case PLAYER_INFO:
|
case PLAYER_INFO:
|
||||||
|
@ -476,14 +479,20 @@ bool CSqlScore::MapInfoThread(CSqlServer* pSqlServer, const CSqlData<CSqlPlayerR
|
||||||
void CSqlScore::SaveScore(int ClientID, float Time, const char *pTimestamp, 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();
|
CConsole* pCon = (CConsole*)GameServer()->Console();
|
||||||
if(pCon->m_Cheated)
|
if(pCon->m_Cheated || NotEligible)
|
||||||
return;
|
return;
|
||||||
CSqlScoreData *Tmp = new CSqlScoreData(nullptr);
|
|
||||||
|
CPlayer *pCurPlayer = GameServer()->m_apPlayers[ClientID];
|
||||||
|
if(pCurPlayer->m_SqlFinishResult != nullptr)
|
||||||
|
dbg_msg("sql", "WARNING: previous save score result didn't complete, overwriting it now");
|
||||||
|
pCurPlayer->m_SqlFinishResult = std::make_shared<CSqlPlayerResult>();
|
||||||
|
CSqlScoreData *Tmp = new CSqlScoreData(pCurPlayer->m_SqlFinishResult);
|
||||||
|
Tmp->m_Map = g_Config.m_SvMap;
|
||||||
|
FormatUuid(GameServer()->GameUuid(), Tmp->m_GameUuid, sizeof(Tmp->m_GameUuid));
|
||||||
Tmp->m_ClientID = ClientID;
|
Tmp->m_ClientID = ClientID;
|
||||||
Tmp->m_Name = Server()->ClientName(ClientID);
|
Tmp->m_Name = Server()->ClientName(ClientID);
|
||||||
Tmp->m_Time = Time;
|
Tmp->m_Time = Time;
|
||||||
str_copy(Tmp->m_aTimestamp, pTimestamp, sizeof(Tmp->m_aTimestamp));
|
str_copy(Tmp->m_aTimestamp, pTimestamp, sizeof(Tmp->m_aTimestamp));
|
||||||
Tmp->m_NotEligible = NotEligible;
|
|
||||||
for(int i = 0; i < NUM_CHECKPOINTS; i++)
|
for(int i = 0; i < NUM_CHECKPOINTS; i++)
|
||||||
Tmp->m_aCpCurrent[i] = CpTime[i];
|
Tmp->m_aCpCurrent[i] = CpTime[i];
|
||||||
|
|
||||||
|
@ -494,8 +503,8 @@ void CSqlScore::SaveScore(int ClientID, float Time, const char *pTimestamp, floa
|
||||||
|
|
||||||
bool CSqlScore::SaveScoreThread(CSqlServer* pSqlServer, const CSqlData<CSqlPlayerResult> *pGameData, bool HandleFailure)
|
bool CSqlScore::SaveScoreThread(CSqlServer* pSqlServer, const CSqlData<CSqlPlayerResult> *pGameData, bool HandleFailure)
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
const CSqlScoreData *pData = dynamic_cast<const CSqlScoreData *>(pGameData);
|
const CSqlScoreData *pData = dynamic_cast<const CSqlScoreData *>(pGameData);
|
||||||
|
auto paMessages = pData->m_pResult->m_aaMessages;
|
||||||
|
|
||||||
if(HandleFailure)
|
if(HandleFailure)
|
||||||
{
|
{
|
||||||
|
@ -504,38 +513,60 @@ bool CSqlScore::SaveScoreThread(CSqlServer* pSqlServer, const CSqlData<CSqlPlaye
|
||||||
|
|
||||||
lock_wait(ms_FailureFileLock);
|
lock_wait(ms_FailureFileLock);
|
||||||
IOHANDLE File = io_open(g_Config.m_SvSqlFailureFile, IOFLAG_APPEND);
|
IOHANDLE File = io_open(g_Config.m_SvSqlFailureFile, IOFLAG_APPEND);
|
||||||
if(File)
|
if(File == 0)
|
||||||
{
|
{
|
||||||
|
lock_unlock(ms_FailureFileLock);
|
||||||
|
dbg_msg("sql", "ERROR: Could not save Score, NOT even to a file");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
dbg_msg("sql", "ERROR: Could not save Score, writing insert to a file now...");
|
dbg_msg("sql", "ERROR: Could not save Score, writing insert to a file now...");
|
||||||
|
|
||||||
char aBuf[768];
|
char aBuf[1024];
|
||||||
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, DDNet7) 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', false);", 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());
|
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, DDNet7) "
|
||||||
|
"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', false);",
|
||||||
|
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);
|
||||||
io_write(File, aBuf, str_length(aBuf));
|
io_write(File, aBuf, str_length(aBuf));
|
||||||
io_write_newline(File);
|
io_write_newline(File);
|
||||||
io_close(File);
|
io_close(File);
|
||||||
lock_unlock(ms_FailureFileLock);
|
lock_unlock(ms_FailureFileLock);
|
||||||
|
|
||||||
pData->GameServer()->SendBroadcast("Database connection failed, score written to a file instead. Admins will add it manually in a few days.", -1);
|
pData->m_pResult->SetVariant(CSqlPlayerResult::BROADCAST);
|
||||||
|
strcpy(pData->m_pResult->m_Data.m_Broadcast,
|
||||||
|
"Database connection failed, score written to a file instead. Admins will add it manually in a few days.");
|
||||||
|
pData->m_pResult->m_Done = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
lock_unlock(ms_FailureFileLock);
|
|
||||||
dbg_msg("sql", "ERROR: Could not save Score, NOT even to a file");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(pData->m_NotEligible)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
char aBuf[768];
|
char aBuf[1024];
|
||||||
|
|
||||||
str_format(aBuf, sizeof(aBuf), "SELECT * FROM %s_race WHERE Map='%s' AND Name='%s' ORDER BY time ASC LIMIT 1;", pSqlServer->GetPrefix(), pData->m_Map.ClrStr(), pData->m_Name.ClrStr());
|
str_format(aBuf, sizeof(aBuf),
|
||||||
|
"SELECT COUNT(*) AS NumFinished FROM %s_race WHERE Map='%s' AND Name='%s' ORDER BY time ASC LIMIT 1;",
|
||||||
|
pSqlServer->GetPrefix(), pData->m_Map.ClrStr(), pData->m_Name.ClrStr());
|
||||||
pSqlServer->executeSqlQuery(aBuf);
|
pSqlServer->executeSqlQuery(aBuf);
|
||||||
if(!pSqlServer->GetResults()->next())
|
pSqlServer->GetResults()->first();
|
||||||
|
int NumFinished = pSqlServer->GetResults()->getInt("NumFinished");
|
||||||
|
if(NumFinished == 0)
|
||||||
{
|
{
|
||||||
str_format(aBuf, sizeof(aBuf), "SELECT Points FROM %s_maps WHERE Map ='%s'", pSqlServer->GetPrefix(), pData->m_Map.ClrStr());
|
str_format(aBuf, sizeof(aBuf), "SELECT Points FROM %s_maps WHERE Map ='%s'", pSqlServer->GetPrefix(), pData->m_Map.ClrStr());
|
||||||
pSqlServer->executeSqlQuery(aBuf);
|
pSqlServer->executeSqlQuery(aBuf);
|
||||||
|
@ -543,37 +574,57 @@ bool CSqlScore::SaveScoreThread(CSqlServer* pSqlServer, const CSqlData<CSqlPlaye
|
||||||
if(pSqlServer->GetResults()->rowsCount() == 1)
|
if(pSqlServer->GetResults()->rowsCount() == 1)
|
||||||
{
|
{
|
||||||
pSqlServer->GetResults()->next();
|
pSqlServer->GetResults()->next();
|
||||||
int points = pSqlServer->GetResults()->getInt("Points");
|
int Points = pSqlServer->GetResults()->getInt("Points");
|
||||||
if (points == 1)
|
if(Points == 1)
|
||||||
str_format(aBuf, sizeof(aBuf), "You earned %d point for finishing this map!", points);
|
str_format(paMessages[0], sizeof(paMessages[0]), "You earned %d point for finishing this map!", Points);
|
||||||
else
|
else
|
||||||
str_format(aBuf, sizeof(aBuf), "You earned %d points for finishing this map!", points);
|
str_format(paMessages[0], sizeof(paMessages[0]), "You earned %d points for finishing this map!", Points);
|
||||||
|
|
||||||
try
|
str_format(aBuf, sizeof(aBuf),
|
||||||
{
|
"INSERT INTO %s_points(Name, Points) "
|
||||||
pData->GameServer()->SendChatTarget(pData->m_ClientID, aBuf);
|
"VALUES ('%s', '%d') "
|
||||||
}
|
"ON duplicate key "
|
||||||
catch (CGameContextError &e) {} // just do nothing, it is not much of a problem if the player is not informed about points during mapchange
|
"UPDATE Name=VALUES(Name), Points=Points+VALUES(Points);",
|
||||||
|
pSqlServer->GetPrefix(), pData->m_Name.ClrStr(), Points);
|
||||||
str_format(aBuf, sizeof(aBuf), "INSERT INTO %s_points(Name, Points) VALUES ('%s', '%d') ON duplicate key UPDATE Name=VALUES(Name), Points=Points+VALUES(Points);", pSqlServer->GetPrefix(), pData->m_Name.ClrStr(), points);
|
|
||||||
pSqlServer->executeSql(aBuf);
|
pSqlServer->executeSql(aBuf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if no entry found... create a new one
|
// save score
|
||||||
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, DDNet7) 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', false);", 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());
|
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, DDNet7) "
|
||||||
|
"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', false);",
|
||||||
|
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);
|
||||||
dbg_msg("sql", "%s", aBuf);
|
dbg_msg("sql", "%s", aBuf);
|
||||||
pSqlServer->executeSql(aBuf);
|
pSqlServer->executeSql(aBuf);
|
||||||
|
|
||||||
dbg_msg("sql", "Updating time done");
|
pData->m_pResult->m_Done = true;
|
||||||
|
dbg_msg("sql", "Saving score done");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch (sql::SQLException &e)
|
catch (sql::SQLException &e)
|
||||||
{
|
{
|
||||||
dbg_msg("sql", "MySQL Error: %s", e.what());
|
dbg_msg("sql", "MySQL Error: %s", e.what());
|
||||||
dbg_msg("sql", "ERROR: Could not update time");
|
dbg_msg("sql", "ERROR: Could not insert time");
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,11 +19,13 @@ struct CSqlPlayerResult
|
||||||
{
|
{
|
||||||
DIRECT,
|
DIRECT,
|
||||||
ALL,
|
ALL,
|
||||||
|
BROADCAST,
|
||||||
MAP_VOTE, // 3 Messages: Reason, Server, Map
|
MAP_VOTE, // 3 Messages: Reason, Server, Map
|
||||||
PLAYER_INFO,
|
PLAYER_INFO,
|
||||||
} m_MessageKind;
|
} m_MessageKind;
|
||||||
char m_aaMessages[7][512];
|
char m_aaMessages[7][512];
|
||||||
union {
|
union {
|
||||||
|
char m_Broadcast[1024];
|
||||||
struct {
|
struct {
|
||||||
float m_Time;
|
float m_Time;
|
||||||
float m_CpTime[NUM_CHECKPOINTS];
|
float m_CpTime[NUM_CHECKPOINTS];
|
||||||
|
@ -104,10 +106,11 @@ struct CSqlScoreData : CSqlData<CSqlPlayerResult>
|
||||||
{
|
{
|
||||||
using CSqlData<CSqlPlayerResult>::CSqlData;
|
using CSqlData<CSqlPlayerResult>::CSqlData;
|
||||||
|
|
||||||
|
sqlstr::CSqlString<MAX_NAME_LENGTH> m_Map;
|
||||||
|
char m_GameUuid[UUID_MAXSTRSIZE];
|
||||||
sqlstr::CSqlString<MAX_NAME_LENGTH> m_Name;
|
sqlstr::CSqlString<MAX_NAME_LENGTH> m_Name;
|
||||||
|
|
||||||
int m_ClientID;
|
int m_ClientID;
|
||||||
bool m_NotEligible;
|
|
||||||
float m_Time;
|
float m_Time;
|
||||||
char m_aTimestamp[TIMESTAMP_STR_LENGTH];
|
char m_aTimestamp[TIMESTAMP_STR_LENGTH];
|
||||||
float m_aCpCurrent[NUM_CHECKPOINTS];
|
float m_aCpCurrent[NUM_CHECKPOINTS];
|
||||||
|
|
Loading…
Reference in a new issue