about summary refs log tree commit diff
diff options
context:
space:
mode:
authorsavander <savander.pl@gmail.com>2014-10-18 22:10:33 +0200
committersavander <savander.pl@gmail.com>2014-10-18 22:10:33 +0200
commit484bc536af06bc71bc1f30f6f70f77afec4dc131 (patch)
tree720e4b757739ed0df9a7db695d0688fcec289a30
parent3affb938fba6dfe914e920ba8d44b780f74a1f62 (diff)
downloadzcatch-484bc536af06bc71bc1f30f6f70f77afec4dc131.tar.gz
zcatch-484bc536af06bc71bc1f30f6f70f77afec4dc131.zip
Add: /rank and /top5
-rw-r--r--src/game/server/gamecontext.cpp39
-rw-r--r--src/game/server/ranking.cpp140
-rw-r--r--src/game/server/ranking.h13
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