diff options
| author | savander <savander.pl@gmail.com> | 2014-10-18 22:10:33 +0200 |
|---|---|---|
| committer | savander <savander.pl@gmail.com> | 2014-10-18 22:10:33 +0200 |
| commit | 484bc536af06bc71bc1f30f6f70f77afec4dc131 (patch) | |
| tree | 720e4b757739ed0df9a7db695d0688fcec289a30 | |
| parent | 3affb938fba6dfe914e920ba8d44b780f74a1f62 (diff) | |
| download | zcatch-484bc536af06bc71bc1f30f6f70f77afec4dc131.tar.gz zcatch-484bc536af06bc71bc1f30f6f70f77afec4dc131.zip | |
Add: /rank and /top5
| -rw-r--r-- | src/game/server/gamecontext.cpp | 39 | ||||
| -rw-r--r-- | src/game/server/ranking.cpp | 140 | ||||
| -rw-r--r-- | src/game/server/ranking.h | 13 |
3 files changed, 185 insertions, 7 deletions
diff --git a/src/game/server/gamecontext.cpp b/src/game/server/gamecontext.cpp index 0b618d2d..6fb036c9 100644 --- a/src/game/server/gamecontext.cpp +++ b/src/game/server/gamecontext.cpp @@ -849,6 +849,30 @@ void CGameContext::OnMessage(int MsgID, CUnpacker *pUnpacker, int ClientID) SendChatTarget(ClientID, aBuf); } } + else if(!str_comp_nocase("top5", pMsg->m_pMessage + 1) || !str_comp_nocase_num("top5 ", pMsg->m_pMessage + 1, 5)) + { + if(!str_comp_nocase_num("top5 ", pMsg->m_pMessage + 1, 5)){ + const char *Number = pMsg->m_pMessage + 5; + for(int i = 0; Number[i] != '\0'; i++){ + if(isalpha(Number[i])){ + SendChatTarget(ClientID, "It must be a number."); + return; + } + } + int i = str_toint(Number); + m_Ranking->ShowTop5(ClientID, i); + }else{ + m_Ranking->ShowTop5(ClientID, 0); + } + } + else if(!str_comp_nocase("rank", pMsg->m_pMessage + 1) || !str_comp_nocase_num("rank ", pMsg->m_pMessage + 1, 5)) + { + if(!str_comp_nocase_num("rank ", pMsg->m_pMessage + 1, 5)){ + m_Ranking->ShowRanking(ClientID, pMsg->m_pMessage + 6); + }else{ + m_Ranking->ShowRanking(ClientID, Server()->ClientName(ClientID)); + } + } else if(!str_comp_nocase("help", pMsg->m_pMessage + 1)) { SendChatTarget(ClientID, "/victims: who is waiting for your death"); @@ -936,11 +960,12 @@ void CGameContext::OnMessage(int MsgID, CUnpacker *pUnpacker, int ClientID) } } int i = str_toint(recipientStart); - if(m_apPlayers[i]) - { - recipient = i; - msgStart = str_skip_whitespaces(str_skip_to_whitespace((char*)recipientStart)); - } + if(i <= MAX_CLIENTS) + if(m_apPlayers[i]) + { + recipient = i; + msgStart = str_skip_whitespaces(str_skip_to_whitespace((char*)recipientStart)); + } } if(recipient >= 0) @@ -2168,3 +2193,7 @@ const char *CGameContext::Version() { return GAME_VERSION; } const char *CGameContext::NetVersion() { return GAME_NETVERSION; } IGameServer *CreateGameServer() { return new CGameContext; } + + + + diff --git a/src/game/server/ranking.cpp b/src/game/server/ranking.cpp index 0a8cfa9f..155d570a 100644 --- a/src/game/server/ranking.cpp +++ b/src/game/server/ranking.cpp @@ -212,7 +212,7 @@ void CRanking::SaveRankingThread(void *pUser){ str_format(aBuf2, sizeof(aBuf), "Woah! You won for the first time! Now you have 1 win."); pData->m_pSqlData->GameServer()->SendChatTarget(pData->m_ClientID, aBuf2); }else{ - str_format(aBuf2, sizeof(aBuf), "You're winner! Now you have %d wins!", wins); + str_format(aBuf2, sizeof(aBuf), "You're winner! Now you have %d wins!", wins+1); pData->m_pSqlData->GameServer()->SendChatTarget(pData->m_ClientID, aBuf2); } } @@ -246,6 +246,144 @@ void CRanking::SaveRankingThread(void *pUser){ } +void CRanking::ShowRanking(int ClientID, const char* pName){ + + CSqlRankData *Tmp = new CSqlRankData(); + Tmp->m_ClientID = ClientID; + str_copy(Tmp->m_aName, pName, MAX_NAME_LENGTH); + str_format(Tmp->m_aRequestingPlayer, sizeof(Tmp->m_aRequestingPlayer), "%s", Server()->ClientName(ClientID)); + Tmp->m_pSqlData = this; + + void *ShowRanking = thread_create(ShowRankingThread, Tmp); +#if defined(CONF_FAMILY_UNIX) + pthread_detach((pthread_t)ShowRanking); +#endif +} + +void CRanking::ShowRankingThread(void *pUser){ + + lock_wait(gs_SqlLock); + CSqlRankData *pData = (CSqlRankData *)pUser; + + // Connect to database + if(pData->m_pSqlData->Connect()) + { + try + { + // check strings + pData->m_pSqlData->ClearString(pData->m_aName); + char originalName[MAX_NAME_LENGTH]; + strcpy(originalName,pData->m_aName); + + + char aBuf[768]; + char aBuf2[768]; + pData->m_pSqlData->m_pStatement->execute("SET @pos := 0;"); + pData->m_pSqlData->m_pStatement->execute("SET @prev := NULL;"); + pData->m_pSqlData->m_pStatement->execute("SET @rank := 1;"); + + str_format(aBuf, sizeof(aBuf), "SELECT Wins,Name, rank FROM (SELECT (@pos := @pos+1) pos, (@rank := IF(@prev = Wins,@rank, @pos)) rank, Name, (@prev := Wins) Wins FROM zcatch_ranks ORDER BY Wins DESC) as result WHERE Name='%s';", pData->m_aName); + pData->m_pSqlData->m_pResults = pData->m_pSqlData->m_pStatement->executeQuery(aBuf); + + if(pData->m_pSqlData->m_pResults->next()) + { + if(pData->m_pSqlData->m_pResults->rowsCount() == 1){ + int wins = (int)pData->m_pSqlData->m_pResults->getInt("Wins"); + int rank = (int)pData->m_pSqlData->m_pResults->getInt("rank"); + str_format(aBuf2, sizeof(aBuf2), "%d. %s's have %d %s Requested by %s.", rank,originalName,wins, (wins > 1) ? "wins." : "win.", pData->m_aRequestingPlayer); + pData->m_pSqlData->GameServer()->SendChatTarget(pData->m_ClientID, aBuf2); + } + }else{ + str_format(aBuf2, sizeof(aBuf2), "%s's is not ranked.", originalName); + pData->m_pSqlData->GameServer()->SendChatTarget(pData->m_ClientID, aBuf2); + } + + // delete results and statement + delete pData->m_pSqlData->m_pResults; + } + 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 rank"); + } + pData->m_pSqlData->Disconnect(); + } + + delete pData; + lock_release(gs_SqlLock); +} + + +void CRanking::ShowTop5(int ClientID, int Offset){ + + CSqlTop5Data *Tmp = new CSqlTop5Data(); + Tmp->m_ClientID = ClientID; + Tmp->m_Offset = Offset; + str_format(Tmp->m_aRequestingPlayer, sizeof(Tmp->m_aRequestingPlayer), "%s", Server()->ClientName(ClientID)); + Tmp->m_pSqlData = this; + + void *ShowTop5 = thread_create(ShowTop5Thread, Tmp); +#if defined(CONF_FAMILY_UNIX) + pthread_detach((pthread_t)ShowTop5); +#endif +} + +void CRanking::ShowTop5Thread(void *pUser){ + + lock_wait(gs_SqlLock); + CSqlTop5Data *pData = (CSqlTop5Data *)pUser; + + // Connect to database + if(pData->m_pSqlData->Connect()) + { + try + { + + char aBuf[768]; + char aBuf2[768]; + + str_format(aBuf, sizeof(aBuf2), "SELECT Name FROM zcatch_ranks;"); + pData->m_pSqlData->m_pResults = pData->m_pSqlData->m_pStatement->executeQuery(aBuf); + str_format(aBuf2, sizeof(aBuf2), "------=====] Top5 (%d records)", (int)pData->m_pSqlData->m_pResults->rowsCount()); + + pData->m_pSqlData->m_pStatement->execute("SET @pos := 0;"); + pData->m_pSqlData->m_pStatement->execute("SET @prev := NULL;"); + pData->m_pSqlData->m_pStatement->execute("SET @rank := 1;"); + + str_format(aBuf, sizeof(aBuf), "SELECT Wins,Name, rank FROM (SELECT (@pos := @pos+1) pos, (@rank := IF(@prev = Wins,@rank, @pos)) rank, Name, (@prev := Wins) Wins FROM zcatch_ranks ORDER BY Wins DESC) as result ORDER BY rank Limit %d,5;", pData->m_Offset); + pData->m_pSqlData->m_pResults = pData->m_pSqlData->m_pStatement->executeQuery(aBuf); + + + pData->m_pSqlData->GameServer()->SendChatTarget(pData->m_ClientID, aBuf2); + while(pData->m_pSqlData->m_pResults->next()){ + int wins = (int)pData->m_pSqlData->m_pResults->getInt("Wins"); + int rank = (int)pData->m_pSqlData->m_pResults->getInt("rank"); + str_format(aBuf2, sizeof(aBuf2), "%d. %s's have %d %s", rank, pData->m_pSqlData->m_pResults->getString("Name").c_str(),wins, (wins > 1) ? "wins." : "win."); + pData->m_pSqlData->GameServer()->SendChatTarget(pData->m_ClientID, aBuf2); + } + str_format(aBuf2, sizeof(aBuf2), "------=====]"); + pData->m_pSqlData->GameServer()->SendChatTarget(pData->m_ClientID, aBuf2); + + + // delete results and statement + delete pData->m_pSqlData->m_pResults; + } + 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 rank"); + } + pData->m_pSqlData->Disconnect(); + } + + delete pData; + lock_release(gs_SqlLock); +} + // anti SQL injection void CRanking::ClearString(char *pString, int size) { diff --git a/src/game/server/ranking.h b/src/game/server/ranking.h index 6c4d1495..cdb8c2b6 100644 --- a/src/game/server/ranking.h +++ b/src/game/server/ranking.h @@ -38,6 +38,8 @@ class CRanking } static void SaveRankingThread(void *pUser); + static void ShowRankingThread(void *pUser); + static void ShowTop5Thread(void *pUser); void Init(); @@ -54,6 +56,8 @@ public: ~CRanking(); void SaveRanking(int ClientID); + void ShowRanking(int ClientID, const char* pName); + void ShowTop5(int ClientID, int Offset); }; struct CSqlRankData @@ -65,6 +69,13 @@ struct CSqlRankData #else char m_aName[MAX_NAME_LENGTH * 2 - 1]; #endif + char m_aRequestingPlayer[MAX_NAME_LENGTH]; +}; +struct CSqlTop5Data +{ + CRanking *m_pSqlData; + int m_Offset; + int m_ClientID; + char m_aRequestingPlayer[MAX_NAME_LENGTH]; }; - #endif |