Add /teamrank and /teamtop5

This commit is contained in:
def 2013-07-21 08:46:52 +02:00
parent 012de29d60
commit 42a8783f00
10 changed files with 473 additions and 2 deletions

View file

@ -377,6 +377,37 @@ void CGameContext::ConToggleSpec(IConsole::IResult *pResult, void *pUserData)
pPlayer->m_Paused = (pPlayer->m_Paused == CPlayer::PAUSED_SPEC) ? CPlayer::PAUSED_NONE : CPlayer::PAUSED_SPEC;
}
void CGameContext::ConTeamTop5(IConsole::IResult *pResult, void *pUserData)
{
CGameContext *pSelf = (CGameContext *) pUserData;
if (!CheckClientID(pResult->m_ClientID))
return;
#if defined(CONF_SQL)
if(pSelf->m_apPlayers[pResult->m_ClientID] && g_Config.m_SvUseSQL)
if(pSelf->m_apPlayers[pResult->m_ClientID]->m_LastSQLQuery + pSelf->Server()->TickSpeed() >= pSelf->Server()->Tick())
return;
#endif
if (g_Config.m_SvHideScore)
{
pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "teamtop5",
"Showing the team top 5 is not allowed on this server.");
return;
}
if (pResult->NumArguments() > 0 && pResult->GetInteger(0) >= 0)
pSelf->Score()->ShowTeamTop5(pResult, pResult->m_ClientID, pUserData,
pResult->GetInteger(0));
else
pSelf->Score()->ShowTeamTop5(pResult, pResult->m_ClientID, pUserData);
#if defined(CONF_SQL)
if(pSelf->m_apPlayers[pResult->m_ClientID] && g_Config.m_SvUseSQL)
pSelf->m_apPlayers[pResult->m_ClientID]->m_LastSQLQuery = pSelf->Server()->Tick();
#endif
}
void CGameContext::ConTop5(IConsole::IResult *pResult, void *pUserData)
{
CGameContext *pSelf = (CGameContext *) pUserData;
@ -462,6 +493,41 @@ void CGameContext::ConTimes(IConsole::IResult *pResult, void *pUserData)
}
#endif
void CGameContext::ConTeamRank(IConsole::IResult *pResult, void *pUserData)
{
CGameContext *pSelf = (CGameContext *) pUserData;
if (!CheckClientID(pResult->m_ClientID))
return;
#if defined(CONF_SQL)
if(pSelf->m_apPlayers[pResult->m_ClientID] && g_Config.m_SvUseSQL)
if(pSelf->m_apPlayers[pResult->m_ClientID]->m_LastSQLQuery + pSelf->Server()->TickSpeed() >= pSelf->Server()->Tick())
return;
#endif
CPlayer *pPlayer = pSelf->m_apPlayers[pResult->m_ClientID];
if (!pPlayer)
return;
if (pResult->NumArguments() > 0)
if (!g_Config.m_SvHideScore)
pSelf->Score()->ShowTeamRank(pResult->m_ClientID, pResult->GetString(0),
true);
else
pSelf->Console()->Print(
IConsole::OUTPUT_LEVEL_STANDARD,
"teamrank",
"Showing the team rank of other players is not allowed on this server.");
else
pSelf->Score()->ShowTeamRank(pResult->m_ClientID,
pSelf->Server()->ClientName(pResult->m_ClientID));
#if defined(CONF_SQL)
if(pSelf->m_apPlayers[pResult->m_ClientID] && g_Config.m_SvUseSQL)
pSelf->m_apPlayers[pResult->m_ClientID]->m_LastSQLQuery = pSelf->Server()->Tick();
#endif
}
void CGameContext::ConRank(IConsole::IResult *pResult, void *pUserData)
{
CGameContext *pSelf = (CGameContext *) pUserData;

View file

@ -15,9 +15,11 @@ CHAT_COMMAND("info", "", CFGFLAG_CHAT|CFGFLAG_SERVER, ConInfo, this, "Shows info
CHAT_COMMAND("me", "r", CFGFLAG_CHAT|CFGFLAG_SERVER, ConMe, this, "Like the famous irc command '/me says hi' will display '<yourname> says hi'")
CHAT_COMMAND("pause", "", CFGFLAG_CHAT|CFGFLAG_SERVER, ConTogglePause, this, "Toggles pause (if not activated on the server, it toggles spec)")
CHAT_COMMAND("spec", "", CFGFLAG_CHAT|CFGFLAG_SERVER, ConToggleSpec, this, "Toggles spec")
CHAT_COMMAND("teamrank", "?r", CFGFLAG_CHAT|CFGFLAG_SERVER, ConTeamRank, this, "Shows the team rank of player with name r (your team rank by default)")
CHAT_COMMAND("rank", "?r", CFGFLAG_CHAT|CFGFLAG_SERVER, ConRank, this, "Shows the rank of player with name r (your rank by default)")
CHAT_COMMAND("rules", "", CFGFLAG_CHAT|CFGFLAG_SERVER, ConRules, this, "Shows the server rules")
CHAT_COMMAND("team", "?i", CFGFLAG_CHAT|CFGFLAG_SERVER, ConJoinTeam, this, "Lets you join team i (shows your team if left blank)")
CHAT_COMMAND("teamtop5", "?i", CFGFLAG_CHAT|CFGFLAG_SERVER, ConTeamTop5, this, "Shows five team ranks of the ladder beginning with rank i (1 by default)")
CHAT_COMMAND("top5", "?i", CFGFLAG_CHAT|CFGFLAG_SERVER, ConTop5, this, "Shows five ranks of the ladder beginning with rank i (1 by default)")
CHAT_COMMAND("showothers", "?i", CFGFLAG_CHAT|CFGFLAG_SERVER, ConShowOthers, this, "Whether to showplayers from other teams or not (off by default), optional i = 0 for off else for on")
CHAT_COMMAND("saytime", "", CFGFLAG_CHAT|CFGFLAG_SERVER, ConSayTime, this, "Privately messages you your current time in this current running race")

View file

@ -226,6 +226,7 @@ private:
static void ConTogglePause(IConsole::IResult *pResult, void *pUserData);
static void ConToggleSpec(IConsole::IResult *pResult, void *pUserData);
static void ConForcePause(IConsole::IResult *pResult, void *pUserData);
static void ConTeamTop5(IConsole::IResult *pResult, void *pUserData);
static void ConTop5(IConsole::IResult *pResult, void *pUserData);
#if defined(CONF_SQL)
static void ConTimes(IConsole::IResult *pResult, void *pUserData);
@ -234,6 +235,7 @@ private:
#endif
static void ConUTF8(IConsole::IResult *pResult, void *pUserData);
static void ConTeamRank(IConsole::IResult *pResult, void *pUserData);
static void ConRank(IConsole::IResult *pResult, void *pUserData);
static void ConBroadTime(IConsole::IResult *pResult, void *pUserData);
static void ConJoinTeam(IConsole::IResult *pResult, void *pUserData);

View file

@ -45,10 +45,15 @@ public:
virtual void LoadScore(int ClientID) = 0;
virtual void SaveScore(int ClientID, float Time, float CpTime[NUM_CHECKPOINTS]) = 0;
virtual void SaveTeamScore(int* ClientIDs, unsigned int Size, float Time) = 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;
virtual void ShowTeamTop5(IConsole::IResult *pResult, int ClientID, void *pUserData, int Debut=1) = 0;
virtual void ShowTeamRank(int ClientID, const char* pName, bool Search=false) = 0;
virtual void ShowTopPoints(IConsole::IResult *pResult, int ClientID, void *pUserData, int Debut=1) = 0;
virtual void ShowPoints(int ClientID, const char* pName, bool Search=false) = 0;
};

View file

@ -209,6 +209,11 @@ void CFileScore::LoadScore(int ClientID)
PlayerData(ClientID)->Set(pPlayer->m_Score, pPlayer->m_aCpTime);
}
void CFileScore::SaveTeamScore(int* ClientIDs, unsigned int Size, float Time)
{
dbg_msg("FileScore", "SaveTeamScore not implemented for FileScore");
}
void CFileScore::SaveScore(int ClientID, float Time,
float CpTime[NUM_CHECKPOINTS])
{
@ -278,10 +283,24 @@ void CFileScore::ShowRank(int ClientID, const char* pName, bool Search)
GameServer()->SendChatTarget(ClientID, aBuf);
}
void CFileScore::ShowTeamTop5(IConsole::IResult *pResult, int ClientID, void *pUserData, int Debut)
{
char aBuf[512];
str_format(aBuf, sizeof(aBuf), "Team ranks not supported in file based servers");
GameServer()->SendChatTarget(ClientID, aBuf);
}
void CFileScore::ShowTeamRank(int ClientID, const char* pName, bool Search)
{
char aBuf[512];
str_format(aBuf, sizeof(aBuf), "Team ranks not supported in file based servers");
GameServer()->SendChatTarget(ClientID, aBuf);
}
void CFileScore::ShowTopPoints(IConsole::IResult *pResult, int ClientID, void *pUserData, int Debut)
{
char aBuf[512];
str_format(aBuf, sizeof(aBuf), "Points not supported in file based servers");
str_format(aBuf, sizeof(aBuf), "Team ranks not supported in file based servers");
GameServer()->SendChatTarget(ClientID, aBuf);
}

View file

@ -65,11 +65,16 @@ public:
virtual void LoadScore(int ClientID);
virtual void SaveScore(int ClientID, float Time,
float CpTime[NUM_CHECKPOINTS]);
virtual void SaveTeamScore(int* ClientIDs, unsigned int Size, float Time);
virtual void ShowTop5(IConsole::IResult *pResult, int ClientID,
void *pUserData, int Debut = 1);
virtual void ShowRank(int ClientID, const char* pName, bool Search = false);
virtual void ShowTeamTop5(IConsole::IResult *pResult, int ClientID,
void *pUserData, int Debut = 1);
virtual void ShowTeamRank(int ClientID, const char* pName, bool Search = false);
virtual void ShowTopPoints(IConsole::IResult *pResult, int ClientID, void *pUserData, int Debut);
virtual void ShowPoints(int ClientID, const char* pName, bool Search);
};

View file

@ -3,7 +3,6 @@
/* CSqlScore class by Sushi */
#if defined(CONF_SQL)
#include <string.h>
#include <iostream>
#include <fstream>
#include <algorithm>
@ -180,6 +179,9 @@ void CSqlScore::Init()
str_format(aBuf, sizeof(aBuf), "CREATE TABLE IF NOT EXISTS %s_%s_race (Name VARCHAR(%d) NOT NULL, Timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP , Time FLOAT DEFAULT 0, cp1 FLOAT DEFAULT 0, cp2 FLOAT DEFAULT 0, cp3 FLOAT DEFAULT 0, cp4 FLOAT DEFAULT 0, cp5 FLOAT DEFAULT 0, cp6 FLOAT DEFAULT 0, cp7 FLOAT DEFAULT 0, cp8 FLOAT DEFAULT 0, cp9 FLOAT DEFAULT 0, cp10 FLOAT DEFAULT 0, cp11 FLOAT DEFAULT 0, cp12 FLOAT DEFAULT 0, cp13 FLOAT DEFAULT 0, cp14 FLOAT DEFAULT 0, cp15 FLOAT DEFAULT 0, cp16 FLOAT DEFAULT 0, cp17 FLOAT DEFAULT 0, cp18 FLOAT DEFAULT 0, cp19 FLOAT DEFAULT 0, cp20 FLOAT DEFAULT 0, cp21 FLOAT DEFAULT 0, cp22 FLOAT DEFAULT 0, cp23 FLOAT DEFAULT 0, cp24 FLOAT DEFAULT 0, cp25 FLOAT DEFAULT 0, KEY Name (Name)) CHARACTER SET utf8 ;", m_pPrefix, m_aMap, MAX_NAME_LENGTH);
m_pStatement->execute(aBuf);
str_format(aBuf, sizeof(aBuf), "CREATE TABLE IF NOT EXISTS %s_%s_teamrace (Name VARCHAR(%d) NOT NULL, Timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, Time FLOAT DEFAULT 0, ID VARBINARY(16) NOT NULL, KEY Name (Name)) CHARACTER SET utf8 ;", m_pPrefix, m_aMap, MAX_NAME_LENGTH);
m_pStatement->execute(aBuf);
// Check if table has new column with timestamp
str_format(aBuf, sizeof(aBuf), "SELECT column_name FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = '%s_%s_race' AND column_name = 'Timestamp'",m_pPrefix, m_aMap);
m_pResults = m_pStatement->executeQuery(aBuf);
@ -191,6 +193,17 @@ void CSqlScore::Init()
m_pStatement->execute(aBuf);
}
// Check if table has new column with timestamp
str_format(aBuf, sizeof(aBuf), "SELECT column_name FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = '%s_%s_teamrace' AND column_name = 'Timestamp'",m_pPrefix, m_aMap);
m_pResults = m_pStatement->executeQuery(aBuf);
if(m_pResults->rowsCount() < 1)
{
// If not... add the column
str_format(aBuf, sizeof(aBuf), "ALTER TABLE %s_%s_teamrace ADD Timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP AFTER Name, ADD INDEX(Name);",m_pPrefix, m_aMap);
m_pStatement->execute(aBuf);
}
dbg_msg("SQL", "Tables were created successfully");
// get the best time
@ -293,6 +306,62 @@ void CSqlScore::LoadScore(int ClientID)
#endif
}
void CSqlScore::SaveTeamScoreThread(void *pUser)
{
lock_wait(gs_SqlLock);
CSqlTeamScoreData *pData = (CSqlTeamScoreData *)pUser;
// Connect to database
if(pData->m_pSqlData->Connect())
{
try
{
char aBuf[2300];
//char bBuf[2300];
//bBuf[0] = '\0';
pData->m_pSqlData->m_pStatement->execute("SET @id = UUID();");
for(unsigned int i = 0; i < pData->m_Size; i++)
{
pData->m_pSqlData->ClearString(pData->m_aNames[i]);
//strcat(bBuf, pData->m_aNames[i]);
//if (i < pData->m_Size - 2)
// strcat(bBuf, ", ");
//else if (i < pData->m_Size - 1)
// strcat(bBuf, " & ");
// if no entry found... create a new one
str_format(aBuf, sizeof(aBuf), "INSERT IGNORE INTO %s_%s_teamrace(Name, Timestamp, Time, ID) VALUES ('%s', CURRENT_TIMESTAMP(), '%.2f', @id);", pData->m_pSqlData->m_pPrefix, pData->m_pSqlData->m_aMap, pData->m_aNames[i], pData->m_Time);
pData->m_pSqlData->m_pStatement->execute(aBuf);
}
//str_format(aBuf, sizeof(aBuf), "INSERT IGNORE INTO %s_%s_teamrace(Name, Timestamp, Time) VALUES ('%s', CURRENT_TIMESTAMP(), '%.2f');", pData->m_pSqlData->m_pPrefix, pData->m_pSqlData->m_aMap, bBuf, pData->m_Time);
//pData->m_pSqlData->m_pStatement->execute(aBuf);
dbg_msg("SQL", "Updating time done");
// delete results statement
delete pData->m_pSqlData->m_pStatement;
}
catch (sql::SQLException &e)
{
char aBuf[256];
str_format(aBuf, sizeof(aBuf), "MySQL Error: %s", e.what());
dbg_msg("SQL", aBuf);
dbg_msg("SQL", "ERROR: Could not update time");
}
// disconnect from database
pData->m_pSqlData->Disconnect();//TODO:Check if an exception is caught will this still execute ?
}
delete pData;
lock_release(gs_SqlLock);
}
void CSqlScore::SaveScoreThread(void *pUser)
{
lock_wait(gs_SqlLock);
@ -354,6 +423,223 @@ void CSqlScore::SaveScore(int ClientID, float Time, float CpTime[NUM_CHECKPOINTS
#endif
}
void CSqlScore::SaveTeamScore(int* aClientIDs, unsigned int Size, float Time)
{
CConsole* pCon = (CConsole*)GameServer()->Console();
if(pCon->m_Cheated)
return;
CSqlTeamScoreData *Tmp = new CSqlTeamScoreData();
for(unsigned int i = 0; i < Size; i++)
{
Tmp->m_aClientIDs[i] = aClientIDs[i];
str_copy(Tmp->m_aNames[i], Server()->ClientName(aClientIDs[i]), sizeof(Tmp->m_aNames[i]));
}
Tmp->m_Size = Size;
Tmp->m_Time = Time;
Tmp->m_pSqlData = this;
void *SaveTeamThread = thread_create(SaveTeamScoreThread, Tmp);
#if defined(CONF_FAMILY_UNIX)
pthread_detach((pthread_t)SaveTeamThread);
#endif
}
void CSqlScore::ShowTeamRankThread(void *pUser)
{
lock_wait(gs_SqlLock);
CSqlScoreData *pData = (CSqlScoreData *)pUser;
// Connect to database
if(pData->m_pSqlData->Connect())
{
try
{
// check strings
char originalName[MAX_NAME_LENGTH];
strcpy(originalName,pData->m_aName);
pData->m_pSqlData->ClearString(pData->m_aName);
// check sort methode
char aBuf[600];
char aNames[2300];
aNames[0] = '\0';
pData->m_pSqlData->m_pStatement->execute("SET @rownum := 0;");
str_format(aBuf, sizeof(aBuf), "SELECT Rank, Name, Time, UNIX_TIMESTAMP(CURRENT_TIMESTAMP)-UNIX_TIMESTAMP(Timestamp) as Ago, UNIX_TIMESTAMP(Timestamp) as stamp FROM ((SELECT @rownum := @rownum + 1 AS RANK, ID FROM (SELECT ID, MIN(Time) as Time FROM %s_%s_teamrace WHERE Name = '%s' GROUP BY ID) as all_top_times ORDER BY Time ASC LIMIT 1) as l) LEFT JOIN %s_%s_teamrace as r ON l.ID = r.ID ORDER BY Name ASC;", pData->m_pSqlData->m_pPrefix, pData->m_pSqlData->m_aMap, pData->m_aName, pData->m_pSqlData->m_pPrefix, pData->m_pSqlData->m_aMap);
pData->m_pSqlData->m_pResults = pData->m_pSqlData->m_pStatement->executeQuery(aBuf);
int Rows = pData->m_pSqlData->m_pResults->rowsCount();
if(Rows < 1)
{
str_format(aBuf, sizeof(aBuf), "%s has no team ranks", originalName);
pData->m_pSqlData->GameServer()->SendChatTarget(pData->m_ClientID, aBuf);
}
else
{
pData->m_pSqlData->m_pResults->first();
int since = (int)pData->m_pSqlData->m_pResults->getInt("Ago");
char agoString[40];
mem_zero(agoString, sizeof(agoString));
agoTimeToString(since,agoString);
float Time = (float)pData->m_pSqlData->m_pResults->getDouble("Time");
int Rank = (int)pData->m_pSqlData->m_pResults->getInt("Rank");
for(int Row = 0; Row < Rows; Row++)
{
strcat(aNames, pData->m_pSqlData->m_pResults->getString("Name").c_str());
pData->m_pSqlData->m_pResults->next();
if (Row < Rows - 2)
strcat(aNames, ", ");
else if (Row < Rows - 1)
strcat(aNames, " & ");
}
pData->m_pSqlData->m_pResults->first();
if(g_Config.m_SvHideScore)
str_format(aBuf, sizeof(aBuf), "Your team time: %d minute(s) %5.2f second(s)", (int)(Time/60), Time-((int)Time/60*60));
else
str_format(aBuf, sizeof(aBuf), "%d. %s Team time: %d minute(s) %5.2f second(s), requested by %s", Rank, aNames, (int)(Time/60), Time-((int)Time/60*60), pData->m_aRequestingPlayer, agoString);
if(pData->m_pSqlData->m_pResults->getInt("stamp") != 0)
{
pData->m_pSqlData->GameServer()->SendChat(-1, CGameContext::CHAT_ALL, aBuf, pData->m_ClientID);
str_format(aBuf, sizeof(aBuf), "Finished: %s ago", agoString);
}
if(pData->m_Search)
strcat(aBuf, pData->m_aRequestingPlayer);
pData->m_pSqlData->GameServer()->SendChat(-1, CGameContext::CHAT_ALL, aBuf, pData->m_ClientID);
}
dbg_msg("SQL", "Showing teamrank done");
// delete results and statement
delete pData->m_pSqlData->m_pResults;
delete pData->m_pSqlData->m_pStatement;
}
catch (sql::SQLException &e)
{
char aBuf[256];
str_format(aBuf, sizeof(aBuf), "MySQL Error: %s", e.what());
dbg_msg("SQL", aBuf);
dbg_msg("SQL", "ERROR: Could not show team rank");
}
// disconnect from database
pData->m_pSqlData->Disconnect();//TODO:Check if an exception is caught will this still execute ?
}
delete pData;
lock_release(gs_SqlLock);
}
void CSqlScore::ShowTeamTop5Thread(void *pUser)
{
lock_wait(gs_SqlLock);
CSqlScoreData *pData = (CSqlScoreData *)pUser;
// Connect to database
if(pData->m_pSqlData->Connect())
{
try
{
// check sort methode
char aBuf[512];
str_format(aBuf, sizeof(aBuf), "SELECT r.ID, Name, Time, UNIX_TIMESTAMP(CURRENT_TIMESTAMP)-UNIX_TIMESTAMP(Timestamp) as Ago, UNIX_TIMESTAMP(Timestamp) as stamp FROM ((SELECT ID FROM (SELECT ID, MIN(Time) as Time FROM %s_%s_teamrace GROUP BY ID) as all_top_times ORDER BY Time ASC LIMIT %d, 5) as l) LEFT JOIN %s_%s_teamrace as r ON l.ID = r.ID ORDER BY Time ASC, Name ASC, r.ID;", pData->m_pSqlData->m_pPrefix, pData->m_pSqlData->m_aMap, pData->m_Num-1, pData->m_pSqlData->m_pPrefix, pData->m_pSqlData->m_aMap);
pData->m_pSqlData->m_pResults = pData->m_pSqlData->m_pStatement->executeQuery(aBuf);
// show teamtop5
pData->m_pSqlData->GameServer()->SendChatTarget(pData->m_ClientID, "------- Team Top 5 -------");
int Rows = pData->m_pSqlData->m_pResults->rowsCount();
if (Rows >= 1) {
char aID[17];
char aID2[17];
char aNames[2300];
int Rank = pData->m_Num;
float Time = 0;
int aCuts[Rows];
int CutPos = 0;
aNames[0] = '\0';
aCuts[0] = -1;
pData->m_pSqlData->m_pResults->first();
strcpy(aID, pData->m_pSqlData->m_pResults->getString("ID").c_str());
for(int Row = 0; Row < Rows; Row++)
{
strcpy(aID2, pData->m_pSqlData->m_pResults->getString("ID").c_str());
if (str_comp(aID, aID2) != 0)
{
strcpy(aID, aID2);
aCuts[CutPos++] = Row - 1;
}
pData->m_pSqlData->m_pResults->next();
}
aCuts[CutPos] = Rows - 1;
CutPos = 0;
pData->m_pSqlData->m_pResults->first();
for(int Row = 0; Row < Rows; Row++)
{
strcat(aNames, pData->m_pSqlData->m_pResults->getString("Name").c_str());
if (Row < aCuts[CutPos] - 1)
strcat(aNames, ", ");
else if (Row < aCuts[CutPos])
strcat(aNames, " & ");
Time = (float)pData->m_pSqlData->m_pResults->getDouble("Time");
if (Row == aCuts[CutPos])
{
str_format(aBuf, sizeof(aBuf), "%d. %s Team Time: %d minute(s) %.2f second(s)", Rank, aNames, (int)(Time/60), Time-((int)Time/60*60));
pData->m_pSqlData->GameServer()->SendChatTarget(pData->m_ClientID, aBuf);
Rank++;
CutPos++;
aNames[0] = '\0';
}
pData->m_pSqlData->m_pResults->next();
}
}
pData->m_pSqlData->GameServer()->SendChatTarget(pData->m_ClientID, "-------------------------------");
dbg_msg("SQL", "Showing teamtop5 done");
// delete results and statement
delete pData->m_pSqlData->m_pResults;
delete pData->m_pSqlData->m_pStatement;
}
catch (sql::SQLException &e)
{
char aBuf[256];
str_format(aBuf, sizeof(aBuf), "MySQL Error: %s", e.what());
dbg_msg("SQL", aBuf);
dbg_msg("SQL", "ERROR: Could not show top5");
}
// disconnect from database
pData->m_pSqlData->Disconnect();
}
delete pData;
lock_release(gs_SqlLock);
}
void CSqlScore::ShowRankThread(void *pUser)
{
lock_wait(gs_SqlLock);
@ -446,6 +732,21 @@ void CSqlScore::ShowRankThread(void *pUser)
lock_release(gs_SqlLock);
}
void CSqlScore::ShowTeamRank(int ClientID, const char* pName, bool Search)
{
CSqlScoreData *Tmp = new CSqlScoreData();
Tmp->m_ClientID = ClientID;
str_copy(Tmp->m_aName, pName, sizeof(Tmp->m_aName));
Tmp->m_Search = Search;
str_format(Tmp->m_aRequestingPlayer, sizeof(Tmp->m_aRequestingPlayer), "%s", Server()->ClientName(ClientID));
Tmp->m_pSqlData = this;
void *TeamRankThread = thread_create(ShowTeamRankThread, Tmp);
#if defined(CONF_FAMILY_UNIX)
pthread_detach((pthread_t)TeamRankThread);
#endif
}
void CSqlScore::ShowRank(int ClientID, const char* pName, bool Search)
{
CSqlScoreData *Tmp = new CSqlScoreData();
@ -600,6 +901,19 @@ void CSqlScore::ShowTimesThread(void *pUser)
lock_release(gs_SqlLock);
}
void CSqlScore::ShowTeamTop5(IConsole::IResult *pResult, int ClientID, void *pUserData, int Debut)
{
CSqlScoreData *Tmp = new CSqlScoreData();
Tmp->m_Num = Debut;
Tmp->m_ClientID = ClientID;
Tmp->m_pSqlData = this;
void *TeamTop5Thread = thread_create(ShowTeamTop5Thread, Tmp);
#if defined(CONF_FAMILY_UNIX)
pthread_detach((pthread_t)TeamTop5Thread);
#endif
}
void CSqlScore::ShowTop5(IConsole::IResult *pResult, int ClientID, void *pUserData, int Debut)
{
CSqlScoreData *Tmp = new CSqlScoreData();

View file

@ -51,8 +51,11 @@ class CSqlScore: public IScore
static void LoadScoreThread(void *pUser);
static void SaveScoreThread(void *pUser);
static void SaveTeamScoreThread(void *pUser);
static void ShowRankThread(void *pUser);
static void ShowTop5Thread(void *pUser);
static void ShowTeamRankThread(void *pUser);
static void ShowTeamTop5Thread(void *pUser);
static void ShowTimesThread(void *pUser);
static void ShowPointsThread(void *pUser);
static void ShowTopPointsThread(void *pUser);
@ -78,11 +81,15 @@ public:
virtual void LoadScore(int ClientID);
virtual void SaveScore(int ClientID, float Time,
float CpTime[NUM_CHECKPOINTS]);
virtual void SaveTeamScore(int* aClientIDs, unsigned int Size, float Time);
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);
virtual void ShowTimes(int ClientID, int Debut = 1);
virtual void ShowTop5(IConsole::IResult *pResult, int ClientID,
void *pUserData, int Debut = 1);
virtual void ShowTeamTop5(IConsole::IResult *pResult, int ClientID,
void *pUserData, int Debut = 1);
virtual void ShowPoints(int ClientID, const char* pName, bool Search = false);
virtual void ShowTopPoints(IConsole::IResult *pResult, int ClientID,
void *pUserData, int Debut = 1);
@ -106,4 +113,22 @@ struct CSqlScoreData
char m_aRequestingPlayer[MAX_NAME_LENGTH];
};
struct CSqlTeamScoreData
{
CSqlScore *m_pSqlData;
unsigned int m_Size;
int m_aClientIDs[MAX_CLIENTS];
#if defined(CONF_FAMILY_WINDOWS)
char m_aNames[16][MAX_CLIENTS]; // Don't edit this, or all your teeth will fall http://bugs.mysql.com/bug.php?id=50046
#else
char m_aNames[MAX_NAME_LENGTH * 2 - 1][MAX_CLIENTS];
#endif
float m_Time;
float m_aCpCurrent[NUM_CHECKPOINTS];
int m_Num;
bool m_Search;
char m_aRequestingPlayer[MAX_NAME_LENGTH];
};
#endif

View file

@ -110,6 +110,10 @@ void CGameTeams::OnCharacterFinish(int ClientID)
{
ChangeTeamState(m_Core.Team(ClientID), TEAMSTATE_FINISHED); //TODO: Make it better
//ChangeTeamState(m_Core.Team(ClientID), TEAMSTATE_OPEN);
CPlayer *TeamPlayers[MAX_CLIENTS];
unsigned int PlayersCount = 0;
for (int i = 0; i < MAX_CLIENTS; ++i)
{
if (m_Core.Team(ClientID) == m_Core.Team(i))
@ -119,10 +123,14 @@ void CGameTeams::OnCharacterFinish(int ClientID)
{
OnFinish(pPlayer);
m_TeeFinished[i] = false;
TeamPlayers[PlayersCount++] = pPlayer;
}
}
}
OnTeamFinish(TeamPlayers, PlayersCount);
}
}
}
@ -331,6 +339,30 @@ float *CGameTeams::GetCpCurrent(CPlayer* Player)
return NULL;
}
void CGameTeams::OnTeamFinish(CPlayer** Players, unsigned int Size)
{
float time = (float) (Server()->Tick() - GetStartTime(Players[0]))
/ ((float) Server()->TickSpeed());
if (time < 0.000001f)
return;
bool CallSaveScore = false;
#if defined(CONF_SQL)
CallSaveScore = g_Config.m_SvUseSQL;
#endif
int PlayerCIDs[Size];
for(unsigned int i = 0; i < Size; i++)
{
PlayerCIDs[i] = Players[i]->GetCID();
}
if (CallSaveScore)
GameServer()->Score()->SaveTeamScore(PlayerCIDs, Size, time);
}
void CGameTeams::OnFinish(CPlayer* Player)
{
if (!Player || !Player->IsPlaying())

View file

@ -74,6 +74,7 @@ public:
void SetStartTime(CPlayer* Player, int StartTime);
void SetRefreshTime(CPlayer* Player, int RefreshTime);
void SetCpActive(CPlayer* Player, int CpActive);
void OnTeamFinish(CPlayer** Players, unsigned int Size);
void OnFinish(CPlayer* Player);
bool TeeFinished(int ClientID)
{