mirror of
https://github.com/ddnet/ddnet.git
synced 2024-09-20 09:34:19 +00:00
Added timestamp into MySQL ranking, and function to have ago time web2.0 like printed on asking for /rank
This commit is contained in:
parent
604ae5286f
commit
60de0da1c3
|
@ -45,7 +45,7 @@ void CGameContext::ConMoveRaw(IConsole::IResult *pResult, void *pUserData, int C
|
|||
void CGameContext::MoveCharacter(int ClientID, int Victim, int X, int Y, bool Raw)
|
||||
{
|
||||
CCharacter* pChr = GetPlayerChar(ClientID);
|
||||
|
||||
|
||||
if(!pChr)
|
||||
return;
|
||||
|
||||
|
@ -135,10 +135,10 @@ void CGameContext::ConHammer(IConsole::IResult *pResult, void *pUserData, int Cl
|
|||
int Type = pResult->GetInteger(0);
|
||||
|
||||
CCharacter* pChr = pSelf->GetPlayerChar(Victim);
|
||||
|
||||
|
||||
if(!pChr)
|
||||
return;
|
||||
|
||||
|
||||
CServer* pServ = (CServer*)pSelf->Server();
|
||||
if(Type>3 || Type<0)
|
||||
{
|
||||
|
@ -249,16 +249,16 @@ void CGameContext::ModifyWeapons(int ClientID, int Victim, int Weapon, bool Remo
|
|||
Console()->PrintResponse(IConsole::OUTPUT_LEVEL_STANDARD, "info", "invalid weapon id");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
CCharacter* pChr = GetPlayerChar(Victim);
|
||||
if(!pChr)
|
||||
return;
|
||||
|
||||
|
||||
if(Weapon == -1)
|
||||
{
|
||||
if(Remove && (pChr->GetActiveWeapon() == WEAPON_SHOTGUN || pChr->GetActiveWeapon() == WEAPON_GRENADE || pChr->GetActiveWeapon() == WEAPON_RIFLE))
|
||||
pChr->SetActiveWeapon(WEAPON_GUN);
|
||||
|
||||
|
||||
if(Remove)
|
||||
{
|
||||
pChr->SetWeaponGot(WEAPON_SHOTGUN, false);
|
||||
|
@ -266,13 +266,13 @@ void CGameContext::ModifyWeapons(int ClientID, int Victim, int Weapon, bool Remo
|
|||
pChr->SetWeaponGot(WEAPON_RIFLE, false);
|
||||
}
|
||||
else
|
||||
pChr->GiveAllWeapons();
|
||||
pChr->GiveAllWeapons();
|
||||
}
|
||||
else if(Weapon != WEAPON_NINJA)
|
||||
{
|
||||
if(Remove && pChr->GetActiveWeapon() == Weapon)
|
||||
pChr->SetActiveWeapon(WEAPON_GUN);
|
||||
|
||||
|
||||
if(Remove)
|
||||
pChr->SetWeaponGot(Weapon, false);
|
||||
else
|
||||
|
@ -285,7 +285,7 @@ void CGameContext::ModifyWeapons(int ClientID, int Victim, int Weapon, bool Remo
|
|||
Console()->PrintResponse(IConsole::OUTPUT_LEVEL_STANDARD, "info", "you can't remove ninja");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
pChr->GiveNinja();
|
||||
}
|
||||
|
||||
|
@ -399,11 +399,11 @@ void CGameContext::ConFreeze(IConsole::IResult *pResult, void *pUserData, int Cl
|
|||
|
||||
if(pResult->NumArguments())
|
||||
Seconds = clamp(pResult->GetInteger(0), -2, 9999);
|
||||
|
||||
|
||||
CCharacter* pChr = pSelf->GetPlayerChar(Victim);
|
||||
if(!pChr)
|
||||
return;
|
||||
|
||||
|
||||
if(pSelf->m_apPlayers[Victim])
|
||||
{
|
||||
pChr->Freeze(Seconds);
|
||||
|
@ -757,7 +757,7 @@ void CGameContext::ConRank(IConsole::IResult *pResult, void *pUserData, int Clie
|
|||
|
||||
if(/*g_Config.m_SvSpamprotection && */pPlayer->m_Last_Chat && pPlayer->m_Last_Chat + pSelf->Server()->TickSpeed() + g_Config.m_SvChatDelay > pSelf->Server()->Tick())
|
||||
return;
|
||||
|
||||
|
||||
pPlayer->m_Last_Chat = pSelf->Server()->Tick();
|
||||
|
||||
if(pResult->NumArguments() > 0)
|
||||
|
@ -771,7 +771,7 @@ void CGameContext::ConRank(IConsole::IResult *pResult, void *pUserData, int Clie
|
|||
|
||||
void CGameContext::ConJoinTeam(IConsole::IResult *pResult, void *pUserData, int ClientID)
|
||||
{
|
||||
|
||||
|
||||
CGameContext *pSelf = (CGameContext *)pUserData;
|
||||
CGameControllerDDRace* Controller = (CGameControllerDDRace*)pSelf->m_pController;
|
||||
if(g_Config.m_SvTeam == 0)
|
||||
|
@ -868,7 +868,7 @@ void CGameContext::ConMe(IConsole::IResult *pResult, void *pUserData, int Client
|
|||
{
|
||||
CGameContext *pSelf = (CGameContext *)pUserData;
|
||||
char aBuf[256 + 24];
|
||||
|
||||
|
||||
str_format(aBuf, 256 + 24, "'%s' %s", pSelf->Server()->ClientName(ClientID), pResult->GetString(0));
|
||||
if(g_Config.m_SvSlashMe)
|
||||
pSelf->SendChat(-2, CGameContext::CHAT_ALL, aBuf, ClientID);
|
||||
|
@ -879,7 +879,7 @@ void CGameContext::ConMe(IConsole::IResult *pResult, void *pUserData, int Client
|
|||
void CGameContext::ConToggleEyeEmote(IConsole::IResult *pResult, void *pUserData, int ClientID)
|
||||
{
|
||||
CGameContext *pSelf = (CGameContext *)pUserData;
|
||||
|
||||
|
||||
CCharacter *pChr = pSelf->m_apPlayers[ClientID]->GetCharacter();
|
||||
|
||||
if(pChr)
|
||||
|
@ -892,7 +892,7 @@ void CGameContext::ConToggleEyeEmote(IConsole::IResult *pResult, void *pUserData
|
|||
void CGameContext::ConToggleBroadcast(IConsole::IResult *pResult, void *pUserData, int ClientID)
|
||||
{
|
||||
CGameContext *pSelf = (CGameContext *)pUserData;
|
||||
|
||||
|
||||
CCharacter *pChr = pSelf->m_apPlayers[ClientID]->GetCharacter();
|
||||
|
||||
if(pChr)
|
||||
|
@ -902,39 +902,39 @@ void CGameContext::ConToggleBroadcast(IConsole::IResult *pResult, void *pUserDat
|
|||
void CGameContext::ConEyeEmote(IConsole::IResult *pResult, void *pUserData, int ClientID)
|
||||
{
|
||||
CGameContext *pSelf = (CGameContext *)pUserData;
|
||||
|
||||
|
||||
CCharacter *pChr = pSelf->m_apPlayers[ClientID]->GetCharacter();
|
||||
|
||||
|
||||
if (pResult->NumArguments() == 0)
|
||||
{
|
||||
pSelf->Console()->PrintResponse(IConsole::OUTPUT_LEVEL_STANDARD, "info", "Emote commands are: /emote surprise /emote blink /emote close /emote angry /emote happy /emote pain");
|
||||
pSelf->Console()->PrintResponse(IConsole::OUTPUT_LEVEL_STANDARD, "info", "Example: /emote surprise 10 for 10 seconds or /emote surprise (default 1 second)");
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
if (pChr)
|
||||
if (pChr)
|
||||
{
|
||||
if (!str_comp(pResult->GetString(0), "angry"))
|
||||
pChr->m_DefEmote = EMOTE_ANGRY;
|
||||
pChr->m_DefEmote = EMOTE_ANGRY;
|
||||
else if (!str_comp(pResult->GetString(0), "blink"))
|
||||
pChr->m_DefEmote = EMOTE_BLINK;
|
||||
pChr->m_DefEmote = EMOTE_BLINK;
|
||||
else if (!str_comp(pResult->GetString(0), "close"))
|
||||
pChr->m_DefEmote = EMOTE_BLINK;
|
||||
pChr->m_DefEmote = EMOTE_BLINK;
|
||||
else if (!str_comp(pResult->GetString(0), "happy"))
|
||||
pChr->m_DefEmote = EMOTE_HAPPY;
|
||||
pChr->m_DefEmote = EMOTE_HAPPY;
|
||||
else if (!str_comp(pResult->GetString(0), "pain"))
|
||||
pChr->m_DefEmote = EMOTE_PAIN;
|
||||
pChr->m_DefEmote = EMOTE_PAIN;
|
||||
else if (!str_comp(pResult->GetString(0), "surprise"))
|
||||
pChr->m_DefEmote = EMOTE_SURPRISE;
|
||||
pChr->m_DefEmote = EMOTE_SURPRISE;
|
||||
else
|
||||
{
|
||||
pSelf->Console()->PrintResponse(IConsole::OUTPUT_LEVEL_STANDARD, "info", "Unkown emote... Say /emote");
|
||||
}
|
||||
|
||||
|
||||
int Duration = 1;
|
||||
if (pResult->NumArguments() > 1)
|
||||
Duration = pResult->GetInteger(1);
|
||||
|
||||
|
||||
pChr->m_DefEmoteReset = pSelf->Server()->Tick() + Duration * pSelf->Server()->TickSpeed();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -987,11 +987,13 @@ void CCharacter::OnFinish()
|
|||
}
|
||||
}
|
||||
|
||||
if(!pData->m_BestTime || time < pData->m_BestTime)
|
||||
if(!pData->m_BestTime || time < pData->m_BestTime && !g_Config.m_SvUseSQL)
|
||||
{
|
||||
// update the score
|
||||
pData->Set(time, m_CpCurrent);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if(str_comp_num(Server()->ClientName(m_pPlayer->GetCID()), "nameless tee", 12) != 0)
|
||||
GameServer()->Score()->SaveScore(m_pPlayer->GetCID(), time, this);
|
||||
}
|
||||
|
|
|
@ -33,10 +33,10 @@ void CGameControllerDDRace::InitTeleporter()
|
|||
|
||||
for(int i = 0; i < Width*Height; i++)
|
||||
{
|
||||
if(GameServer()->Collision()->TeleLayer()[i].m_Number > 0
|
||||
if(GameServer()->Collision()->TeleLayer()[i].m_Number > 0
|
||||
&& GameServer()->Collision()->TeleLayer()[i].m_Type == TILE_TELEOUT)
|
||||
{
|
||||
m_TeleOuts[GameServer()->Collision()->TeleLayer()[i].m_Number-1].push_back(vec2(i % GameServer()->Collision()->Layers()->TeleLayer()->m_Width*32+16,
|
||||
m_TeleOuts[GameServer()->Collision()->TeleLayer()[i].m_Number-1].push_back(vec2(i % GameServer()->Collision()->Layers()->TeleLayer()->m_Width*32+16,
|
||||
i/GameServer()->Collision()->Layers()->TeleLayer()->m_Width*32+16));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,14 +12,14 @@
|
|||
class CGameControllerDDRace : public IGameController
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
CGameControllerDDRace(class CGameContext *pGameServer);
|
||||
~CGameControllerDDRace();
|
||||
|
||||
|
||||
CGameTeams m_Teams;
|
||||
|
||||
std::map < int , std::vector < vec2 > > m_TeleOuts;
|
||||
|
||||
|
||||
void InitTeleporter();
|
||||
virtual void Tick();
|
||||
};
|
||||
|
|
|
@ -23,17 +23,17 @@ CFileScore::CFileScore(CGameContext *pGameServer) : m_pGameServer(pGameServer),
|
|||
{
|
||||
if(gs_ScoreLock == 0)
|
||||
gs_ScoreLock = lock_create();
|
||||
|
||||
|
||||
Init();
|
||||
}
|
||||
|
||||
CFileScore::~CFileScore()
|
||||
{
|
||||
lock_wait(gs_ScoreLock);
|
||||
|
||||
|
||||
// clear list
|
||||
m_Top.clear();
|
||||
|
||||
|
||||
lock_release(gs_ScoreLock);
|
||||
}
|
||||
|
||||
|
@ -85,14 +85,14 @@ void CFileScore::Save()
|
|||
void CFileScore::Init()
|
||||
{
|
||||
lock_wait(gs_ScoreLock);
|
||||
|
||||
|
||||
// create folder if not exist
|
||||
if(g_Config.m_SvScoreFolder[0])
|
||||
fs_makedir(g_Config.m_SvScoreFolder);
|
||||
|
||||
|
||||
std::fstream f;
|
||||
f.open(SaveFile().c_str(), std::ios::in);
|
||||
|
||||
|
||||
while(!f.eof() && !f.fail())
|
||||
{
|
||||
std::string TmpName, TmpScore, TmpCpLine;
|
||||
|
@ -118,7 +118,7 @@ void CFileScore::Init()
|
|||
}
|
||||
f.close();
|
||||
lock_release(gs_ScoreLock);
|
||||
|
||||
|
||||
// save the current best score
|
||||
if(m_Top.size())
|
||||
((CGameControllerDDRace*)GameServer()->m_pController)->m_CurrentRecord = m_Top[0].m_Score;
|
||||
|
@ -157,23 +157,23 @@ CFileScore::CPlayerScore *CFileScore::SearchName(const char *pName, int *pPositi
|
|||
void CFileScore::UpdatePlayer(int ID, float Score, float aCpTime[NUM_CHECKPOINTS])
|
||||
{
|
||||
const char *pName = Server()->ClientName(ID);
|
||||
|
||||
|
||||
lock_wait(gs_ScoreLock);
|
||||
CPlayerScore *pPlayer = SearchScore(ID, 0);
|
||||
|
||||
|
||||
if(pPlayer)
|
||||
{
|
||||
for(int c = 0; c < NUM_CHECKPOINTS; c++)
|
||||
pPlayer->m_aCpTime[c] = aCpTime[c];
|
||||
|
||||
|
||||
pPlayer->m_Score = Score;
|
||||
str_copy(pPlayer->m_aName, pName, sizeof(pPlayer->m_aName));
|
||||
|
||||
|
||||
sort(m_Top.all());
|
||||
}
|
||||
else
|
||||
m_Top.add(*new CPlayerScore(pName, Score, aCpTime));
|
||||
|
||||
|
||||
lock_release(gs_ScoreLock);
|
||||
Save();
|
||||
}
|
||||
|
@ -187,7 +187,7 @@ void CFileScore::LoadScore(int ClientID)
|
|||
lock_release(gs_ScoreLock);
|
||||
Save();
|
||||
}
|
||||
|
||||
|
||||
// set score
|
||||
if(pPlayer)
|
||||
PlayerData(ClientID)->Set(pPlayer->m_Score, pPlayer->m_aCpTime);
|
||||
|
@ -219,12 +219,12 @@ void CFileScore::ShowRank(int ClientID, const char* pName, bool Search)
|
|||
CPlayerScore *pScore;
|
||||
int Pos;
|
||||
char aBuf[512];
|
||||
|
||||
|
||||
if(!Search)
|
||||
pScore = SearchScore(ClientID, &Pos);
|
||||
else
|
||||
pScore = SearchName(pName, &Pos, 1);
|
||||
|
||||
|
||||
if(pScore && Pos > -1)
|
||||
{
|
||||
float Time = pScore->m_Score;
|
||||
|
@ -242,6 +242,6 @@ void CFileScore::ShowRank(int ClientID, const char* pName, bool Search)
|
|||
str_format(aBuf, sizeof(aBuf), "Several players were found.");
|
||||
else
|
||||
str_format(aBuf, sizeof(aBuf), "%s is not ranked", Search?pName:Server()->ClientName(ClientID));
|
||||
|
||||
|
||||
GameServer()->Console()->PrintResponse(IConsole::OUTPUT_LEVEL_STANDARD, "rank", aBuf);
|
||||
}
|
||||
|
|
|
@ -11,42 +11,42 @@ class CFileScore : public IScore
|
|||
{
|
||||
CGameContext *m_pGameServer;
|
||||
IServer *m_pServer;
|
||||
|
||||
|
||||
class CPlayerScore
|
||||
{
|
||||
public:
|
||||
char m_aName[MAX_NAME_LENGTH];
|
||||
float m_Score;
|
||||
float m_aCpTime[NUM_CHECKPOINTS];
|
||||
|
||||
|
||||
CPlayerScore() {};
|
||||
CPlayerScore(const char *pName, float Score, float aCpTime[NUM_CHECKPOINTS]);
|
||||
|
||||
|
||||
bool operator<(const CPlayerScore& other) { return (this->m_Score < other.m_Score); }
|
||||
};
|
||||
|
||||
|
||||
sorted_array<CPlayerScore> m_Top;
|
||||
|
||||
|
||||
CGameContext *GameServer() { return m_pGameServer; }
|
||||
IServer *Server() { return m_pServer; }
|
||||
|
||||
|
||||
CPlayerScore *SearchScore(int ID, int *pPosition){ return SearchName(Server()->ClientName(ID), pPosition, 0 );};
|
||||
;
|
||||
CPlayerScore *SearchName(const char *pName, int *pPosition, bool MatchCase);
|
||||
void UpdatePlayer(int ID, float Score, float aCpTime[NUM_CHECKPOINTS]);
|
||||
|
||||
|
||||
void Init();
|
||||
void Save();
|
||||
static void SaveScoreThread(void *pUser);
|
||||
|
||||
|
||||
public:
|
||||
|
||||
|
||||
CFileScore(CGameContext *pGameServer);
|
||||
~CFileScore();
|
||||
|
||||
|
||||
virtual void LoadScore(int ClientID);
|
||||
virtual void SaveScore(int ClientID, float Time, CCharacter *pChar);
|
||||
|
||||
|
||||
virtual void ShowTop5(int ClientID, int Debut=1);
|
||||
virtual void ShowRank(int ClientID, const char* pName, bool Search=false);
|
||||
};
|
||||
|
|
|
@ -9,22 +9,21 @@
|
|||
|
||||
static LOCK gs_SqlLock = 0;
|
||||
|
||||
CSqlScore::CSqlScore(CGameContext *pGameServer)
|
||||
: m_pGameServer(pGameServer),
|
||||
m_pServer(pGameServer->Server()),
|
||||
m_pDatabase(g_Config.m_SvSqlDatabase),
|
||||
m_pPrefix(g_Config.m_SvSqlPrefix),
|
||||
m_pUser(g_Config.m_SvSqlUser),
|
||||
m_pPass(g_Config.m_SvSqlPw),
|
||||
m_pIp(g_Config.m_SvSqlIp),
|
||||
m_Port(g_Config.m_SvSqlPort)
|
||||
CSqlScore::CSqlScore(CGameContext *pGameServer) : m_pGameServer(pGameServer),
|
||||
m_pServer(pGameServer->Server()),
|
||||
m_pDatabase(g_Config.m_SvSqlDatabase),
|
||||
m_pPrefix(g_Config.m_SvSqlPrefix),
|
||||
m_pUser(g_Config.m_SvSqlUser),
|
||||
m_pPass(g_Config.m_SvSqlPw),
|
||||
m_pIp(g_Config.m_SvSqlIp),
|
||||
m_Port(g_Config.m_SvSqlPort)
|
||||
{
|
||||
str_copy(m_aMap, g_Config.m_SvMap, sizeof(m_aMap));
|
||||
NormalizeMapname(m_aMap);
|
||||
|
||||
|
||||
if(gs_SqlLock == 0)
|
||||
gs_SqlLock = lock_create();
|
||||
|
||||
|
||||
Init();
|
||||
}
|
||||
|
||||
|
@ -36,65 +35,65 @@ CSqlScore::~CSqlScore()
|
|||
|
||||
bool CSqlScore::Connect()
|
||||
{
|
||||
try
|
||||
try
|
||||
{
|
||||
// Create connection
|
||||
m_pDriver = get_driver_instance();
|
||||
char aBuf[256];
|
||||
str_format(aBuf, sizeof(aBuf), "tcp://%s:%d", m_pIp, m_Port);
|
||||
m_pConnection = m_pDriver->connect(aBuf, m_pUser, m_pPass);
|
||||
|
||||
|
||||
// Create Statement
|
||||
m_pStatement = m_pConnection->createStatement();
|
||||
|
||||
|
||||
// Create database if not exists
|
||||
str_format(aBuf, sizeof(aBuf), "CREATE DATABASE IF NOT EXISTS %s", m_pDatabase);
|
||||
m_pStatement->execute(aBuf);
|
||||
|
||||
|
||||
// Connect to specific database
|
||||
m_pConnection->setSchema(m_pDatabase);
|
||||
dbg_msg("SQL", "SQL connection established");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
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: SQL connection failed");
|
||||
return false;
|
||||
}
|
||||
catch (const std::exception& ex) {
|
||||
// ...
|
||||
// ...
|
||||
dbg_msg("SQL", "1 %s",ex.what());
|
||||
|
||||
} catch (const std::string& ex) {
|
||||
// ...
|
||||
// ...
|
||||
dbg_msg("SQL", "2 %s",ex.c_str());
|
||||
}
|
||||
catch( int )
|
||||
{
|
||||
dbg_msg("SQL", "3 %s");
|
||||
}
|
||||
catch( float )
|
||||
{
|
||||
dbg_msg("SQL", "4 %s");
|
||||
}
|
||||
|
||||
catch( char[] )
|
||||
{
|
||||
dbg_msg("SQL", "5 %s");
|
||||
}
|
||||
|
||||
catch( char )
|
||||
{
|
||||
dbg_msg("SQL", "6 %s");
|
||||
}
|
||||
catch( int )
|
||||
{
|
||||
dbg_msg("SQL", "3 %s");
|
||||
}
|
||||
catch( float )
|
||||
{
|
||||
dbg_msg("SQL", "4 %s");
|
||||
}
|
||||
|
||||
catch( char[] )
|
||||
{
|
||||
dbg_msg("SQL", "5 %s");
|
||||
}
|
||||
|
||||
catch( char )
|
||||
{
|
||||
dbg_msg("SQL", "6 %s");
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
dbg_msg("SQL", "Unknown Error cause by the MySQL/C++ Connector, my advice compile server_debug and use it");
|
||||
|
||||
|
||||
dbg_msg("SQL", "ERROR: SQL connection failed");
|
||||
return false;
|
||||
}
|
||||
|
@ -124,32 +123,46 @@ void CSqlScore::Init()
|
|||
{
|
||||
// create tables
|
||||
char aBuf[768];
|
||||
str_format(aBuf, sizeof(aBuf), "CREATE TABLE IF NOT EXISTS %s_%s_race (Name VARCHAR(%d) NOT NULL, 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) CHARACTER SET utf8 ;", m_pPrefix, m_aMap, MAX_NAME_LENGTH);
|
||||
str_format(aBuf, sizeof(aBuf), "CREATE TABLE IF NOT EXISTS %s_%s_race (Name VARCHAR(%d) NOT NULL, Timestamp 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) 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);
|
||||
|
||||
if(m_pResults->rowsCount() < 1){
|
||||
// If not... add the column
|
||||
str_format(aBuf, sizeof(aBuf), "%s_%s_race has no column Timestamp, I will add it now",m_pPrefix, m_aMap);
|
||||
dbg_msg("SQL",aBuf);
|
||||
str_format(aBuf, sizeof(aBuf), "ALTER TABLE %s_%s_race ADD Timestamp TIMESTAMP AFTER Name",m_pPrefix, m_aMap);
|
||||
dbg_msg("SQL",aBuf);
|
||||
m_pStatement->execute(aBuf);
|
||||
}
|
||||
|
||||
dbg_msg("SQL", "Tables were created successfully");
|
||||
|
||||
|
||||
// get the best time
|
||||
str_format(aBuf, sizeof(aBuf), "SELECT Time FROM %s_%s_race ORDER BY `Time` ASC LIMIT 0, 1;", m_pPrefix, m_aMap);
|
||||
m_pResults = m_pStatement->executeQuery(aBuf);
|
||||
|
||||
|
||||
if(m_pResults->next())
|
||||
{
|
||||
((CGameControllerDDRace*)GameServer()->m_pController)->m_CurrentRecord = (float)m_pResults->getDouble("Time");
|
||||
|
||||
|
||||
dbg_msg("SQL", "Getting best time on server done");
|
||||
|
||||
|
||||
// delete results
|
||||
delete m_pResults;
|
||||
}
|
||||
|
||||
|
||||
// delete statement
|
||||
delete m_pStatement;
|
||||
}
|
||||
catch (sql::SQLException &e)
|
||||
{
|
||||
char aBuf[256];
|
||||
char aBuf[256];
|
||||
str_format(aBuf, sizeof(aBuf), "MySQL Error: %s", e.what());
|
||||
dbg_msg("SQL", aBuf);
|
||||
dbg_msg("SQL", aBuf);
|
||||
dbg_msg("SQL", "ERROR: Tables were NOT created");
|
||||
}
|
||||
|
||||
|
@ -162,9 +175,9 @@ void CSqlScore::Init()
|
|||
void CSqlScore::LoadScoreThread(void *pUser)
|
||||
{
|
||||
lock_wait(gs_SqlLock);
|
||||
|
||||
|
||||
CSqlScoreData *pData = (CSqlScoreData *)pUser;
|
||||
|
||||
|
||||
// Connect to database
|
||||
if(pData->m_pSqlData->Connect())
|
||||
{
|
||||
|
@ -172,11 +185,11 @@ void CSqlScore::LoadScoreThread(void *pUser)
|
|||
{
|
||||
// check strings
|
||||
pData->m_pSqlData->ClearString(pData->m_aName);
|
||||
|
||||
|
||||
char aBuf[512];
|
||||
|
||||
|
||||
str_format(aBuf, sizeof(aBuf), "SELECT * FROM %s_%s_race WHERE Name='%s';", pData->m_pSqlData->m_pPrefix, pData->m_pSqlData->m_aMap, pData->m_aName);
|
||||
|
||||
str_format(aBuf, sizeof(aBuf), "SELECT * FROM %s_%s_race WHERE Name='%s' ORDER BY time ASC LIMIT 1;", pData->m_pSqlData->m_pPrefix, pData->m_pSqlData->m_aMap, pData->m_aName);
|
||||
pData->m_pSqlData->m_pResults = pData->m_pSqlData->m_pStatement->executeQuery(aBuf);
|
||||
if(pData->m_pSqlData->m_pResults->next())
|
||||
{
|
||||
|
@ -192,25 +205,25 @@ void CSqlScore::LoadScoreThread(void *pUser)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
dbg_msg("SQL", "Getting best time done");
|
||||
|
||||
|
||||
// delete statement and results
|
||||
delete pData->m_pSqlData->m_pStatement;
|
||||
delete pData->m_pSqlData->m_pResults;
|
||||
}
|
||||
catch (sql::SQLException &e)
|
||||
{
|
||||
char aBuf[256];
|
||||
{
|
||||
char aBuf[256];
|
||||
str_format(aBuf, sizeof(aBuf), "MySQL Error: %s", e.what());
|
||||
dbg_msg("SQL", aBuf);
|
||||
dbg_msg("SQL", "ERROR: Could not update account");
|
||||
}
|
||||
|
||||
|
||||
// disconnect from database
|
||||
pData->m_pSqlData->Disconnect();
|
||||
}
|
||||
|
||||
|
||||
delete pData;
|
||||
|
||||
lock_release(gs_SqlLock);
|
||||
|
@ -222,7 +235,7 @@ void CSqlScore::LoadScore(int ClientID)
|
|||
Tmp->m_ClientID = ClientID;
|
||||
str_copy(Tmp->m_aName, Server()->ClientName(ClientID), sizeof(Tmp->m_aName));
|
||||
Tmp->m_pSqlData = this;
|
||||
|
||||
|
||||
void *LoadThread = thread_create(LoadScoreThread, Tmp);
|
||||
#if defined(CONF_FAMILY_UNIX)
|
||||
pthread_detach((pthread_t)LoadThread);
|
||||
|
@ -232,9 +245,9 @@ void CSqlScore::LoadScore(int ClientID)
|
|||
void CSqlScore::SaveScoreThread(void *pUser)
|
||||
{
|
||||
lock_wait(gs_SqlLock);
|
||||
|
||||
|
||||
CSqlScoreData *pData = (CSqlScoreData *)pUser;
|
||||
|
||||
|
||||
// Connect to database
|
||||
if(pData->m_pSqlData->Connect())
|
||||
{
|
||||
|
@ -242,61 +255,30 @@ void CSqlScore::SaveScoreThread(void *pUser)
|
|||
{
|
||||
// check strings
|
||||
pData->m_pSqlData->ClearString(pData->m_aName);
|
||||
|
||||
|
||||
char aBuf[768];
|
||||
|
||||
// fisrt check for the name
|
||||
str_format(aBuf, sizeof(aBuf), "SELECT * FROM %s_%s_race WHERE Name='%s';", pData->m_pSqlData->m_pPrefix, pData->m_pSqlData->m_aMap, pData->m_aName);
|
||||
pData->m_pSqlData->m_pResults = pData->m_pSqlData->m_pStatement->executeQuery(aBuf);
|
||||
|
||||
// if the name is found...
|
||||
if(pData->m_pSqlData->m_pResults->next())
|
||||
{
|
||||
// update time
|
||||
if(g_Config.m_SvCheckpointSave)
|
||||
str_format(aBuf, sizeof(aBuf), "UPDATE %s_%s_race SET Time='%.2f', cp1='%.2f', cp2='%.2f', cp3='%.2f', cp4='%.2f', cp5='%.2f', cp6='%.2f', cp7='%.2f', cp8='%.2f', cp9='%.2f', cp10='%.2f', cp11='%.2f', cp12='%.2f', cp13='%.2f', cp14='%.2f', cp15='%.2f', cp16='%.2f', cp17='%.2f', cp18='%.2f', cp19='%.2f', cp20='%.2f', cp21='%.2f', cp22='%.2f', cp23='%.2f', cp24='%.2f', cp25='%.2f' WHERE Name='%s';", pData->m_pSqlData->m_pPrefix, pData->m_pSqlData->m_aMap, pData->m_Time, 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_aName);
|
||||
else
|
||||
str_format(aBuf, sizeof(aBuf), "UPDATE %s_%s_race SET Time='%.2f' WHERE Name='%s';", pData->m_pSqlData->m_pPrefix, pData->m_pSqlData->m_aMap, pData->m_Time, pData->m_aName);
|
||||
pData->m_pSqlData->m_pStatement->execute(aBuf);
|
||||
|
||||
dbg_msg("SQL", "Updating time done");
|
||||
|
||||
// delete results statement
|
||||
delete pData->m_pSqlData->m_pResults;
|
||||
delete pData->m_pSqlData->m_pStatement;
|
||||
|
||||
// disconnect from database
|
||||
pData->m_pSqlData->Disconnect();
|
||||
|
||||
delete pData;
|
||||
|
||||
lock_release(gs_SqlLock);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// if no entry found... create a new one
|
||||
str_format(aBuf, sizeof(aBuf), "INSERT IGNORE INTO %s_%s_race(Name, Time, 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) VALUES ('%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', '%.2f');", pData->m_pSqlData->m_pPrefix, pData->m_pSqlData->m_aMap, pData->m_aName, pData->m_Time, 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_pSqlData->m_pStatement->execute(aBuf);
|
||||
|
||||
|
||||
dbg_msg("SQL", "Updating time done");
|
||||
|
||||
|
||||
// delete results statement
|
||||
delete pData->m_pSqlData->m_pResults;
|
||||
delete pData->m_pSqlData->m_pStatement;
|
||||
}
|
||||
catch (sql::SQLException &e)
|
||||
{
|
||||
char aBuf[256];
|
||||
char aBuf[256];
|
||||
str_format(aBuf, sizeof(aBuf), "MySQL Error: %s", e.what());
|
||||
dbg_msg("SQL", aBuf);
|
||||
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);
|
||||
|
@ -311,7 +293,7 @@ void CSqlScore::SaveScore(int ClientID, float Time, CCharacter *pChar)
|
|||
for(int i = 0; i < NUM_CHECKPOINTS; i++)
|
||||
Tmp->m_aCpCurrent[i] = pChar->m_CpCurrent[i];
|
||||
Tmp->m_pSqlData = this;
|
||||
|
||||
|
||||
void *SaveThread = thread_create(SaveScoreThread, Tmp);
|
||||
#if defined(CONF_FAMILY_UNIX)
|
||||
pthread_detach((pthread_t)SaveThread);
|
||||
|
@ -321,9 +303,9 @@ void CSqlScore::SaveScore(int ClientID, float Time, CCharacter *pChar)
|
|||
void CSqlScore::ShowRankThread(void *pUser)
|
||||
{
|
||||
lock_wait(gs_SqlLock);
|
||||
|
||||
|
||||
CSqlScoreData *pData = (CSqlScoreData *)pUser;
|
||||
|
||||
|
||||
// Connect to database
|
||||
if(pData->m_pSqlData->Connect())
|
||||
{
|
||||
|
@ -333,19 +315,27 @@ void CSqlScore::ShowRankThread(void *pUser)
|
|||
char originalName[MAX_NAME_LENGTH];
|
||||
strcpy(originalName,pData->m_aName);
|
||||
pData->m_pSqlData->ClearString(pData->m_aName);
|
||||
|
||||
|
||||
// check sort methode
|
||||
char aBuf[512];
|
||||
|
||||
|
||||
pData->m_pSqlData->m_pStatement->execute("SET @rownum := 0;");
|
||||
str_format(aBuf, sizeof(aBuf), "SELECT Rank, Name, Time "
|
||||
str_format(aBuf, sizeof(aBuf), "SELECT Rank, one_rank.Name, one_rank.Time, UNIX_TIMESTAMP(CURRENT_TIMESTAMP)-UNIX_TIMESTAMP(r.Timestamp) as Ago, UNIX_TIMESTAMP(r.Timestamp) as stamp "
|
||||
"FROM ("
|
||||
"SELECT @rownum := @rownum + 1 AS RANK, Name, Time FROM %s_%s_race ORDER BY Time ASC"
|
||||
") as Query "
|
||||
"WHERE Name = '%s';", pData->m_pSqlData->m_pPrefix, pData->m_pSqlData->m_aMap,pData->m_aName);
|
||||
|
||||
"SELECT * FROM ("
|
||||
"SELECT @rownum := @rownum + 1 AS RANK, Name, Time "
|
||||
"FROM ("
|
||||
"SELECT Name, min(Time) as Time "
|
||||
"FROM %s_%s_race "
|
||||
"Group By Name) as all_top_times "
|
||||
"ORDER BY Time ASC) as all_ranks "
|
||||
"WHERE all_ranks.Name = '%s') as one_rank "
|
||||
"LEFT JOIN %s_%s_race as r "
|
||||
"ON one_rank.Name = r.Name && one_rank.Time = r.Time "
|
||||
";", 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);
|
||||
|
||||
|
||||
if(pData->m_pSqlData->m_pResults->rowsCount() != 1)
|
||||
{
|
||||
str_format(aBuf, sizeof(aBuf), "%s is not ranked", originalName);
|
||||
|
@ -353,43 +343,115 @@ void CSqlScore::ShowRankThread(void *pUser)
|
|||
}
|
||||
else
|
||||
{
|
||||
pData->m_pSqlData->m_pResults->next();
|
||||
float Time = (float)pData->m_pSqlData->m_pResults->getDouble("Time");
|
||||
int Rank = (float)pData->m_pSqlData->m_pResults->getInt("Rank");
|
||||
pData->m_pSqlData->m_pResults->next();
|
||||
int since = (int)pData->m_pSqlData->m_pResults->getInt("Ago");
|
||||
char agoString[40];
|
||||
agoTimeToString(since,agoString);
|
||||
|
||||
float Time = (float)pData->m_pSqlData->m_pResults->getDouble("Time");
|
||||
int Rank = (int)pData->m_pSqlData->m_pResults->getInt("Rank");
|
||||
if(g_Config.m_SvHideScore)
|
||||
str_format(aBuf, sizeof(aBuf), "Your time: %d minute(s) %5.2f second(s)", (int)(Time/60), Time-((int)Time/60*60));
|
||||
else
|
||||
str_format(aBuf, sizeof(aBuf), "%d. %s Time: %d minute(s) %5.2f second(s)", Rank, pData->m_pSqlData->m_pResults->getString("Name").c_str(), (int)(Time/60), Time-((int)Time/60*60));
|
||||
|
||||
str_format(aBuf, sizeof(aBuf), "%d. %s Time: %d minute(s) %5.2f second(s)", Rank, pData->m_pSqlData->m_pResults->getString("Name").c_str(), (int)(Time/60), Time-((int)Time/60*60), agoString);
|
||||
|
||||
if(pData->m_pSqlData->m_pResults->getInt("stamp") != 0){
|
||||
pData->m_pSqlData->GameServer()->SendChatTarget(-1, aBuf);
|
||||
str_format(aBuf, sizeof(aBuf), "Finished: %s ago", agoString);
|
||||
}
|
||||
if(pData->m_Search)
|
||||
strcat(aBuf, pData->m_aRequestingPlayer);
|
||||
|
||||
pData->m_pSqlData->GameServer()->SendChatTarget(-1, aBuf);
|
||||
|
||||
}
|
||||
|
||||
|
||||
dbg_msg("SQL", "Showing rank done");
|
||||
|
||||
|
||||
// delete results and statement
|
||||
delete pData->m_pSqlData->m_pResults;
|
||||
delete pData->m_pSqlData->m_pResults;
|
||||
delete pData->m_pSqlData->m_pStatement;
|
||||
}
|
||||
catch (sql::SQLException &e)
|
||||
{
|
||||
char aBuf[256];
|
||||
char aBuf[256];
|
||||
str_format(aBuf, sizeof(aBuf), "MySQL Error: %s", e.what());
|
||||
dbg_msg("SQL", aBuf);
|
||||
dbg_msg("SQL", aBuf);
|
||||
dbg_msg("SQL", "ERROR: Could not show 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::agoTimeToString(int agoTime, char agoString[]){
|
||||
char aBuf[20];
|
||||
int times[7] = {
|
||||
60 * 60 * 24 * 365 ,
|
||||
60 * 60 * 24 * 30 ,
|
||||
60 * 60 * 24 * 7,
|
||||
60 * 60 * 24 ,
|
||||
60 * 60 ,
|
||||
60 ,
|
||||
1
|
||||
};
|
||||
char names[7][6] = {
|
||||
"year",
|
||||
"month",
|
||||
"week",
|
||||
"day",
|
||||
"hour",
|
||||
"min",
|
||||
"sec"
|
||||
};
|
||||
|
||||
int seconds = 0;
|
||||
char name[6];
|
||||
int count = 0;
|
||||
int i = 0;
|
||||
|
||||
// finding biggest match
|
||||
for(i = 0; i<7; i++){
|
||||
seconds = times[i];
|
||||
strcpy(name,names[i]);
|
||||
|
||||
count = floor(agoTime/seconds);
|
||||
if(count != 0){
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(count == 1){
|
||||
str_format(aBuf, sizeof(aBuf), "%d %s", 1 , name);
|
||||
}else{
|
||||
str_format(aBuf, sizeof(aBuf), "%d %ss", count , name);
|
||||
}
|
||||
strcat(agoString,aBuf);
|
||||
|
||||
if (i + 1 < 7) {
|
||||
// getting second piece now
|
||||
int seconds2 = times[i+1];
|
||||
char name2[6];
|
||||
strcpy(name2,names[i+1]);
|
||||
|
||||
// add second piece if it's greater than 0
|
||||
int count2 = floor((agoTime - (seconds * count)) / seconds2);
|
||||
|
||||
if (count2 != 0) {
|
||||
if(count2 == 1){
|
||||
str_format(aBuf, sizeof(aBuf), " and %d %s", 1 , name2);
|
||||
}else{
|
||||
str_format(aBuf, sizeof(aBuf), " and %d %ss", count2 , name2);
|
||||
}
|
||||
strcat(agoString,aBuf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CSqlScore::ShowRank(int ClientID, const char* pName, bool Search)
|
||||
{
|
||||
CSqlScoreData *Tmp = new CSqlScoreData();
|
||||
|
@ -398,7 +460,7 @@ void CSqlScore::ShowRank(int ClientID, const char* pName, bool Search)
|
|||
Tmp->m_Search = Search;
|
||||
str_format(Tmp->m_aRequestingPlayer, sizeof(Tmp->m_aRequestingPlayer), " (%s)", Server()->ClientName(ClientID));
|
||||
Tmp->m_pSqlData = this;
|
||||
|
||||
|
||||
void *RankThread = thread_create(ShowRankThread, Tmp);
|
||||
#if defined(CONF_FAMILY_UNIX)
|
||||
pthread_detach((pthread_t)RankThread);
|
||||
|
@ -408,9 +470,9 @@ void CSqlScore::ShowRank(int ClientID, const char* pName, bool Search)
|
|||
void CSqlScore::ShowTop5Thread(void *pUser)
|
||||
{
|
||||
lock_wait(gs_SqlLock);
|
||||
|
||||
|
||||
CSqlScoreData *pData = (CSqlScoreData *)pUser;
|
||||
|
||||
|
||||
// Connect to database
|
||||
if(pData->m_pSqlData->Connect())
|
||||
{
|
||||
|
@ -418,41 +480,41 @@ void CSqlScore::ShowTop5Thread(void *pUser)
|
|||
{
|
||||
// check sort methode
|
||||
char aBuf[512];
|
||||
str_format(aBuf, sizeof(aBuf), "SELECT Name, Time FROM %s_%s_race ORDER BY `Time` ASC LIMIT %d, 5;", pData->m_pSqlData->m_pPrefix, pData->m_pSqlData->m_aMap, pData->m_Num-1);
|
||||
str_format(aBuf, sizeof(aBuf), "SELECT Name, min(Time) as Time FROM %s_%s_race Group By Name ORDER BY `Time` ASC LIMIT %d, 5;", pData->m_pSqlData->m_pPrefix, pData->m_pSqlData->m_aMap, pData->m_Num-1);
|
||||
pData->m_pSqlData->m_pResults = pData->m_pSqlData->m_pStatement->executeQuery(aBuf);
|
||||
|
||||
|
||||
// show top5
|
||||
pData->m_pSqlData->GameServer()->SendChatTarget(pData->m_ClientID, "----------- Top 5 -----------");
|
||||
|
||||
|
||||
int Rank = pData->m_Num;
|
||||
float Time = 0;
|
||||
while(pData->m_pSqlData->m_pResults->next())
|
||||
{
|
||||
Time = (float)pData->m_pSqlData->m_pResults->getDouble("Time");
|
||||
str_format(aBuf, sizeof(aBuf), "%d. %s Time: %d minute(s) %.2f second(s)", Rank, pData->m_pSqlData->m_pResults->getString("Name").c_str(), (int)(Time/60), Time-((int)Time/60*60));
|
||||
str_format(aBuf, sizeof(aBuf), "%d. %s Time: %d minute(s) %.2f second(s)", Rank, pData->m_pSqlData->m_pResults->getString("Name").c_str(), (int)(Time/60), Time-((int)Time/60*60));
|
||||
pData->m_pSqlData->GameServer()->SendChatTarget(pData->m_ClientID, aBuf);
|
||||
Rank++;
|
||||
}
|
||||
pData->m_pSqlData->GameServer()->SendChatTarget(pData->m_ClientID, "------------------------------");
|
||||
|
||||
|
||||
dbg_msg("SQL", "Showing top5 done");
|
||||
|
||||
|
||||
// delete results and statement
|
||||
delete pData->m_pSqlData->m_pResults;
|
||||
delete pData->m_pSqlData->m_pStatement;
|
||||
}
|
||||
catch (sql::SQLException &e)
|
||||
{
|
||||
char aBuf[256];
|
||||
char aBuf[256];
|
||||
str_format(aBuf, sizeof(aBuf), "MySQL Error: %s", e.what());
|
||||
dbg_msg("SQL", aBuf);
|
||||
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);
|
||||
|
@ -464,7 +526,7 @@ void CSqlScore::ShowTop5(int ClientID, int Debut)
|
|||
Tmp->m_Num = Debut;
|
||||
Tmp->m_ClientID = ClientID;
|
||||
Tmp->m_pSqlData = this;
|
||||
|
||||
|
||||
void *Top5Thread = thread_create(ShowTop5Thread, Tmp);
|
||||
#if defined(CONF_FAMILY_UNIX)
|
||||
pthread_detach((pthread_t)Top5Thread);
|
||||
|
@ -477,7 +539,7 @@ void CSqlScore::ClearString(char *pString)
|
|||
{
|
||||
char newString[MAX_NAME_LENGTH*2-1];
|
||||
int pos = 0;
|
||||
|
||||
|
||||
for(int i=0;i<str_length(pString);i++) {
|
||||
if(pString[i] == '\\') {
|
||||
newString[pos++] = '\\';
|
||||
|
@ -492,15 +554,15 @@ void CSqlScore::ClearString(char *pString)
|
|||
newString[pos++] = pString[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
newString[pos] = '\0';
|
||||
|
||||
|
||||
strcpy(pString,newString);
|
||||
}
|
||||
|
||||
void CSqlScore::NormalizeMapname(char *pString) {
|
||||
std::string validChars("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_");
|
||||
|
||||
|
||||
for(int i=0;i<str_length(pString);i++) {
|
||||
if(validChars.find(pString[i]) == std::string::npos) {
|
||||
pString[i] = '_';
|
||||
|
|
|
@ -15,12 +15,12 @@ class CSqlScore : public IScore
|
|||
{
|
||||
CGameContext *m_pGameServer;
|
||||
IServer *m_pServer;
|
||||
|
||||
|
||||
sql::Driver *m_pDriver;
|
||||
sql::Connection *m_pConnection;
|
||||
sql::Statement *m_pStatement;
|
||||
sql::ResultSet *m_pResults;
|
||||
|
||||
|
||||
// copy of config vars
|
||||
const char* m_pDatabase;
|
||||
const char* m_pPrefix;
|
||||
|
@ -29,34 +29,35 @@ class CSqlScore : public IScore
|
|||
const char* m_pIp;
|
||||
char m_aMap[64];
|
||||
int m_Port;
|
||||
|
||||
|
||||
CGameContext *GameServer() { return m_pGameServer; }
|
||||
IServer *Server() { return m_pServer; }
|
||||
|
||||
|
||||
static void LoadScoreThread(void *pUser);
|
||||
static void SaveScoreThread(void *pUser);
|
||||
static void ShowRankThread(void *pUser);
|
||||
static void ShowTop5Thread(void *pUser);
|
||||
|
||||
|
||||
void Init();
|
||||
|
||||
|
||||
bool Connect();
|
||||
void Disconnect();
|
||||
|
||||
|
||||
// anti SQL injection
|
||||
void ClearString(char *pString);
|
||||
|
||||
|
||||
void NormalizeMapname(char *pString);
|
||||
|
||||
|
||||
public:
|
||||
|
||||
|
||||
CSqlScore(CGameContext *pGameServer);
|
||||
~CSqlScore();
|
||||
|
||||
|
||||
virtual void LoadScore(int ClientID);
|
||||
virtual void SaveScore(int ClientID, float Time, CCharacter *pChar);
|
||||
virtual void ShowRank(int ClientID, const char* pName, bool Search=false);
|
||||
virtual void ShowTop5(int ClientID, int Debut=1);
|
||||
static void agoTimeToString(int agoTime, char agoStrign[]);
|
||||
};
|
||||
|
||||
struct CSqlScoreData
|
||||
|
|
Loading…
Reference in a new issue