From 9f15acdbee9e73a2e460a89efbe58590a27c096d Mon Sep 17 00:00:00 2001 From: Zwelf Date: Sun, 14 Jun 2020 23:51:58 +0200 Subject: [PATCH] Thread safe random_unfinished_map and modified sql statement --- src/game/server/player.cpp | 2 + src/game/server/score/sql_score.cpp | 70 ++++++++++++++++++----------- src/game/server/score/sql_score.h | 8 ---- 3 files changed, 46 insertions(+), 34 deletions(-) diff --git a/src/game/server/player.cpp b/src/game/server/player.cpp index 75c1fe804..75c66f223 100644 --- a/src/game/server/player.cpp +++ b/src/game/server/player.cpp @@ -167,6 +167,8 @@ void CPlayer::Tick() GameServer()->SendChatTarget(m_ClientID, m_SqlRandomMapResult->m_aMessage); if(m_SqlRandomMapResult->m_Map[0] != '\0') str_copy(g_Config.m_SvMap, m_SqlRandomMapResult->m_Map, sizeof(g_Config.m_SvMap)); + else + GameServer()->m_LastMapVote = 0; } m_SqlRandomMapResult = nullptr; } diff --git a/src/game/server/score/sql_score.cpp b/src/game/server/score/sql_score.cpp index bbd341a05..bc0239501 100644 --- a/src/game/server/score/sql_score.cpp +++ b/src/game/server/score/sql_score.cpp @@ -1432,23 +1432,25 @@ bool CSqlScore::RandomMapThread(CSqlServer* pSqlServer, const CSqlData(); + CPlayer *pCurPlayer = GameServer()->m_apPlayers[ClientID]; + auto pResult = std::make_shared(); + pCurPlayer->m_SqlRandomMapResult = pResult; - CSqlRandomMap *Tmp = new CSqlRandomMap(); - Tmp->m_Num = Stars; - Tmp->m_ClientID = ClientID; - Tmp->m_Name = GameServer()->Server()->ClientName(ClientID); - Tmp->m_pResult = *ppResult; + auto *Tmp = new CSqlRandomMapRequest(pResult); + Tmp->m_Stars = Stars; + Tmp->m_CurrentMap = g_Config.m_SvMap; + Tmp->m_ServerType = g_Config.m_SvServerType; + Tmp->m_RequestingPlayer = GameServer()->Server()->ClientName(ClientID); - thread_init_and_detach(ExecSqlFunc, new CSqlExecData(RandomUnfinishedMapThread, Tmp), "random unfinished map"); - */ + thread_init_and_detach( + CSqlExecData::ExecSqlFunc, + new CSqlExecData(RandomUnfinishedMapThread, Tmp), + "random unfinished map"); } bool CSqlScore::RandomUnfinishedMapThread(CSqlServer* pSqlServer, const CSqlData *pGameData, bool HandleFailure) { - /* - const CSqlRandomMap *pData = dynamic_cast(pGameData); + const CSqlRandomMapRequest *pData = dynamic_cast(pGameData); if (HandleFailure) return true; @@ -1456,25 +1458,48 @@ bool CSqlScore::RandomUnfinishedMapThread(CSqlServer* pSqlServer, const CSqlData try { char aBuf[512]; - if(pData->m_Num >= 0) - str_format(aBuf, sizeof(aBuf), "select * from %s_maps where Server = \"%s\" and Map != \"%s\" and Stars = \"%d\" and not exists (select * from %s_race where Name = \"%s\" and %s_race.Map = %s_maps.Map) order by RAND() limit 1;", pSqlServer->GetPrefix(), g_Config.m_SvServerType, g_Config.m_SvMap, pData->m_Num, pSqlServer->GetPrefix(), pData->m_Name.ClrStr(), pSqlServer->GetPrefix(), pSqlServer->GetPrefix()); + if(pData->m_Stars >= 0) + { + str_format(aBuf, sizeof(aBuf), + "SELECT Map " + "FROM %s_maps " + "WHERE Server = \"%s\" AND Map != \"%s\" AND Stars = \"%d\" AND Map NOT IN (" + "SELECT Map " + "FROM %s_race " + "WHERE Name = \"%s\"" + ") ORDER BY RAND() " + "LIMIT 1;", + pSqlServer->GetPrefix(), pData->m_ServerType.ClrStr(), pData->m_CurrentMap.ClrStr(), + pData->m_Stars, pSqlServer->GetPrefix(), pData->m_RequestingPlayer.ClrStr()); + } else - str_format(aBuf, sizeof(aBuf), "select * from %s_maps where Server = \"%s\" and Map != \"%s\" and not exists (select * from %s_race where Name = \"%s\" and %s_race.Map = %s_maps.Map) order by RAND() limit 1;", pSqlServer->GetPrefix(), g_Config.m_SvServerType, g_Config.m_SvMap, pSqlServer->GetPrefix(), pData->m_Name.ClrStr(), pSqlServer->GetPrefix(), pSqlServer->GetPrefix()); + { + str_format(aBuf, sizeof(aBuf), + "SELECT Map " + "FROM %s_maps AS maps " + "WHERE Server = \"%s\" AND Map != \"%s\" AND Map NOT IN (" + "SELECT Map " + "FROM %s_race as race " + "WHERE Name = \"%s\"" + ") ORDER BY RAND() " + "LIMIT 1;", + pSqlServer->GetPrefix(), pData->m_ServerType.ClrStr(), pData->m_CurrentMap.ClrStr(), + pSqlServer->GetPrefix(), pData->m_RequestingPlayer.ClrStr()); + } pSqlServer->executeSqlQuery(aBuf); if(pSqlServer->GetResults()->rowsCount() != 1) { - pData->GameServer()->SendChatTarget(pData->m_ClientID, "You have no more unfinished maps on this server!"); - pData->GameServer()->m_LastMapVote = 0; + str_copy(pData->m_pResult->m_aMessage, "You have no more unfinished maps on this server!", sizeof(pData->m_pResult->m_aMessage)); } else { pSqlServer->GetResults()->next(); - std::string Map = pSqlServer->GetResults()->getString("Map"); - str_copy(pData->m_pResult->m_aMap, Map.c_str(), sizeof(pData->m_pResult->m_aMap)); - pData->m_pResult->m_Done = true; + auto Map = pSqlServer->GetResults()->getString("Map"); + str_copy(pData->m_pResult->m_Map, Map.c_str(), sizeof(pData->m_pResult->m_Map)); } + pData->m_pResult->m_Done = true; dbg_msg("sql", "voting random unfinished map done"); return true; } @@ -1483,13 +1508,6 @@ bool CSqlScore::RandomUnfinishedMapThread(CSqlServer* pSqlServer, const CSqlData dbg_msg("sql", "MySQL Error: %s", e.what()); dbg_msg("sql", "ERROR: Could not vote random unfinished map"); } - catch (CGameContextError &e) - { - dbg_msg("sql", "WARNING: Aborted unfinished-map-thread due to reload/change of map."); - return true; - } - return false; - */ return false; } diff --git a/src/game/server/score/sql_score.h b/src/game/server/score/sql_score.h index 8d293a38a..183d3e2be 100644 --- a/src/game/server/score/sql_score.h +++ b/src/game/server/score/sql_score.h @@ -186,14 +186,6 @@ struct CSqlTeamLoad : CSqlData int m_NumPlayer; }; -struct CSqlRandomMap : CSqlData -{ - using CSqlData::CSqlData; - int m_Stars; - char m_aCurrentMap[64]; - char m_aServerType[64]; -}; - // controls one thread template < typename TResult > struct CSqlExecData