diff --git a/src/game/server/gamecontext.cpp b/src/game/server/gamecontext.cpp index fac06a828..3608ddc6e 100644 --- a/src/game/server/gamecontext.cpp +++ b/src/game/server/gamecontext.cpp @@ -1752,59 +1752,12 @@ void CGameContext::ConChangeMap(IConsole::IResult *pResult, void *pUserData) void CGameContext::ConRandomMap(IConsole::IResult *pResult, void *pUserData) { CGameContext *pSelf = (CGameContext *)pUserData; - int NumMaps = 0; - int NumVotes = 0; - int OurMap; - char* pMapName; - char pQuotedMapName[64]; - int stars = 0; + int stars = 0; if (pResult->NumArguments()) stars = pResult->GetInteger(0); - CVoteOptionServer *pOption = pSelf->m_pVoteOptionFirst; - while(pOption) - { - if(strncmp(pOption->m_aCommand, "change_map ", 11) == 0 - || strncmp(pOption->m_aCommand, "sv_map ", 7) == 0) - NumMaps++; - - NumVotes++; - pOption = pOption->m_pNext; - } - - if(!NumMaps) - { - pSelf->SendChat(-1, CGameContext::CHAT_ALL, "random_map called, but no maps available in votes"); - return; - } - - while(true) - { - OurMap = rand() % NumVotes; - pOption = pSelf->m_pVoteOptionFirst; - - while(OurMap > 0) - { - OurMap--; - pOption = pOption->m_pNext; - } - - if(strncmp(pOption->m_aCommand, "change_map ", 11) == 0) - pMapName = &pOption->m_aCommand[11]; - else if(strncmp(pOption->m_aCommand, "sv_map ", 7) == 0) - pMapName = &pOption->m_aCommand[7]; - else - continue; - - str_format(pQuotedMapName, sizeof(pQuotedMapName), "\"%s\"", g_Config.m_SvMap); - - if(str_comp(pMapName, g_Config.m_SvMap) == 0 || str_comp(pMapName, pQuotedMapName) == 0) - continue; - - pSelf->Console()->ExecuteLine(pOption->m_aCommand); - break; - } + pSelf->m_pScore->RandomMap(pSelf->m_VoteCreator, stars); } void CGameContext::ConRandomUnfinishedMap(IConsole::IResult *pResult, void *pUserData) diff --git a/src/game/server/score.h b/src/game/server/score.h index 56e7d165f..15fa5e8e2 100644 --- a/src/game/server/score.h +++ b/src/game/server/score.h @@ -13,7 +13,7 @@ public: { Reset(); } - + void Reset() { m_BestTime = 0; @@ -21,14 +21,14 @@ public: for(int i = 0; i < NUM_CHECKPOINTS; i++) m_aBestCpTime[i] = 0; } - + void Set(float Time, float CpTime[NUM_CHECKPOINTS]) { m_BestTime = Time; for(int i = 0; i < NUM_CHECKPOINTS; i++) m_aBestCpTime[i] = CpTime[i]; } - + float m_BestTime; float m_CurrentTime; float m_aBestCpTime[NUM_CHECKPOINTS]; @@ -37,19 +37,19 @@ public: class IScore { CPlayerData m_aPlayerData[MAX_CLIENTS]; - + public: virtual ~IScore() {} - + CPlayerData *PlayerData(int ID) { return &m_aPlayerData[ID]; } - + virtual void MapPoints(int ClientID, const char* MapName) = 0; virtual void MapVote(int ClientID, const char* MapName) = 0; 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; @@ -59,8 +59,9 @@ public: 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; + virtual void RandomMap(int ClientID, int stars) = 0; virtual void RandomUnfinishedMap(int ClientID, int stars) = 0; - + virtual void SaveTeam(int Team, const char* Code, int ClientID) = 0; virtual void LoadTeam(const char* Code, int ClientID) = 0; }; diff --git a/src/game/server/score/file_score.cpp b/src/game/server/score/file_score.cpp index 131bfd71d..8b24734a5 100644 --- a/src/game/server/score/file_score.cpp +++ b/src/game/server/score/file_score.cpp @@ -321,6 +321,13 @@ void CFileScore::ShowPoints(int ClientID, const char* pName, bool Search) GameServer()->SendChatTarget(ClientID, aBuf); } +void CFileScore::RandomMap(int ClientID, int stars) +{ + char aBuf[512]; + str_format(aBuf, sizeof(aBuf), "Random map not supported in file based servers"); + GameServer()->SendChatTarget(ClientID, aBuf); +} + void CFileScore::RandomUnfinishedMap(int ClientID, int stars) { char aBuf[512]; diff --git a/src/game/server/score/file_score.h b/src/game/server/score/file_score.h index 8b7aa6779..141599134 100644 --- a/src/game/server/score/file_score.h +++ b/src/game/server/score/file_score.h @@ -79,6 +79,7 @@ public: virtual void ShowTopPoints(IConsole::IResult *pResult, int ClientID, void *pUserData, int Debut); virtual void ShowPoints(int ClientID, const char* pName, bool Search); + virtual void RandomMap(int ClientID, int stars); virtual void RandomUnfinishedMap(int ClientID, int stars); virtual void SaveTeam(int Team, const char* Code, int ClientID); virtual void LoadTeam(const char* Code, int ClientID); diff --git a/src/game/server/score/sql_score.cpp b/src/game/server/score/sql_score.cpp index 01ae12ad8..e3303f297 100644 --- a/src/game/server/score/sql_score.cpp +++ b/src/game/server/score/sql_score.cpp @@ -1461,6 +1461,60 @@ void CSqlScore::ShowTopPoints(IConsole::IResult *pResult, int ClientID, void *pU #endif } +void CSqlScore::RandomMapThread(void *pUser) +{ + lock_wait(gs_SqlLock); + + CSqlScoreData *pData = (CSqlScoreData *)pUser; + + // Connect to database + if(pData->m_pSqlData->Connect()) + { + try + { + char aBuf[512]; + if(pData->m_Num) + str_format(aBuf, sizeof(aBuf), "select * from %s_maps where Server = \"%s\" and Stars = \"%d\" order by RAND() limit 1;", pData->m_pSqlData->m_pPrefix, g_Config.m_SvServerType, pData->m_Num); + else + str_format(aBuf, sizeof(aBuf), "select * from %s_maps where Server = \"%s\" order by RAND() limit 1;", pData->m_pSqlData->m_pPrefix, g_Config.m_SvServerType); + pData->m_pSqlData->m_pResults = pData->m_pSqlData->m_pStatement->executeQuery(aBuf); + + if(pData->m_pSqlData->m_pResults->rowsCount() != 1) + { + pData->m_pSqlData->GameServer()->SendChatTarget(pData->m_ClientID, "No maps found on this server!"); + } + else + { + pData->m_pSqlData->m_pResults->next(); + char aMap[128]; + strcpy(aMap, pData->m_pSqlData->m_pResults->getString("Map").c_str()); + + str_format(aBuf, sizeof(aBuf), "change_map \"%s\"", aMap); + pData->m_pSqlData->GameServer()->Console()->ExecuteLine(aBuf); + } + + dbg_msg("SQL", "Voting random map done"); + + // 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 vote random map"); + } + + // disconnect from database + pData->m_pSqlData->Disconnect(); + } + + delete pData; + + lock_release(gs_SqlLock); +} + void CSqlScore::RandomUnfinishedMapThread(void *pUser) { lock_wait(gs_SqlLock); @@ -1519,6 +1573,20 @@ void CSqlScore::RandomUnfinishedMapThread(void *pUser) lock_release(gs_SqlLock); } +void CSqlScore::RandomMap(int ClientID, int stars) +{ + CSqlScoreData *Tmp = new CSqlScoreData(); + Tmp->m_Num = stars; + Tmp->m_ClientID = ClientID; + str_copy(Tmp->m_aName, GameServer()->Server()->ClientName(ClientID), MAX_NAME_LENGTH); + Tmp->m_pSqlData = this; + + void *RandomThread = thread_create(RandomMapThread, Tmp); +#if defined(CONF_FAMILY_UNIX) + pthread_detach((pthread_t)RandomThread); +#endif +} + void CSqlScore::RandomUnfinishedMap(int ClientID, int stars) { CSqlScoreData *Tmp = new CSqlScoreData(); diff --git a/src/game/server/score/sql_score.h b/src/game/server/score/sql_score.h index 50f58c34d..0be84da1e 100644 --- a/src/game/server/score/sql_score.h +++ b/src/game/server/score/sql_score.h @@ -52,6 +52,7 @@ class CSqlScore: public IScore static void ShowTimesThread(void *pUser); static void ShowPointsThread(void *pUser); static void ShowTopPointsThread(void *pUser); + static void RandomMapThread(void *pUser); static void RandomUnfinishedMapThread(void *pUser); static void SaveTeamThread(void *pUser); static void LoadTeamThread(void *pUser); @@ -89,6 +90,7 @@ public: virtual void ShowPoints(int ClientID, const char* pName, bool Search = false); virtual void ShowTopPoints(IConsole::IResult *pResult, int ClientID, void *pUserData, int Debut = 1); + virtual void RandomMap(int ClientID, int stars); virtual void RandomUnfinishedMap(int ClientID, int stars); virtual void SaveTeam(int Team, const char* Code, int ClientID); virtual void LoadTeam(const char* Code, int ClientID);