mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-10 10:08:18 +00:00
Merge pull request #1744 from heinrich5991/pr_ddnet_quotefixquote_randommap
Hack around the race condition in random maps selection
This commit is contained in:
commit
0eded7e406
|
@ -870,6 +870,12 @@ void CGameContext::OnTick()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(m_pRandomMapResult && m_pRandomMapResult->m_Done)
|
||||||
|
{
|
||||||
|
str_copy(g_Config.m_SvMap, m_pRandomMapResult->m_aMap, sizeof(g_Config.m_SvMap));
|
||||||
|
m_pRandomMapResult = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef CONF_DEBUG
|
#ifdef CONF_DEBUG
|
||||||
if(g_Config.m_DbgDummies)
|
if(g_Config.m_DbgDummies)
|
||||||
{
|
{
|
||||||
|
@ -2151,11 +2157,11 @@ void CGameContext::ConRandomMap(IConsole::IResult *pResult, void *pUserData)
|
||||||
{
|
{
|
||||||
CGameContext *pSelf = (CGameContext *)pUserData;
|
CGameContext *pSelf = (CGameContext *)pUserData;
|
||||||
|
|
||||||
int stars = 0;
|
int Stars = 0;
|
||||||
if (pResult->NumArguments())
|
if(pResult->NumArguments())
|
||||||
stars = pResult->GetInteger(0);
|
Stars = pResult->GetInteger(0);
|
||||||
|
|
||||||
pSelf->m_pScore->RandomMap(pSelf->m_VoteCreator, stars);
|
pSelf->m_pScore->RandomMap(&pSelf->m_pRandomMapResult, pSelf->m_VoteCreator, Stars);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGameContext::ConRandomUnfinishedMap(IConsole::IResult *pResult, void *pUserData)
|
void CGameContext::ConRandomUnfinishedMap(IConsole::IResult *pResult, void *pUserData)
|
||||||
|
@ -2166,7 +2172,7 @@ void CGameContext::ConRandomUnfinishedMap(IConsole::IResult *pResult, void *pUse
|
||||||
if (pResult->NumArguments())
|
if (pResult->NumArguments())
|
||||||
stars = pResult->GetInteger(0);
|
stars = pResult->GetInteger(0);
|
||||||
|
|
||||||
pSelf->m_pScore->RandomUnfinishedMap(pSelf->m_VoteCreator, stars);
|
pSelf->m_pScore->RandomUnfinishedMap(&pSelf->m_pRandomMapResult, pSelf->m_VoteCreator, stars);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGameContext::ConRestart(IConsole::IResult *pResult, void *pUserData)
|
void CGameContext::ConRestart(IConsole::IResult *pResult, void *pUserData)
|
||||||
|
|
|
@ -56,6 +56,7 @@ enum
|
||||||
class IConsole;
|
class IConsole;
|
||||||
class IEngine;
|
class IEngine;
|
||||||
class IStorage;
|
class IStorage;
|
||||||
|
class CRandomMapResult;
|
||||||
|
|
||||||
class CGameContext : public IGameServer
|
class CGameContext : public IGameServer
|
||||||
{
|
{
|
||||||
|
@ -75,6 +76,8 @@ class CGameContext : public IGameServer
|
||||||
CUuid m_GameUuid;
|
CUuid m_GameUuid;
|
||||||
CMapBugs m_MapBugs;
|
CMapBugs m_MapBugs;
|
||||||
|
|
||||||
|
std::shared_ptr<CRandomMapResult> m_pRandomMapResult;
|
||||||
|
|
||||||
static void CommandCallback(int ClientID, int FlagMask, const char *pCmd, IConsole::IResult *pResult, void *pUser);
|
static void CommandCallback(int ClientID, int FlagMask, const char *pCmd, IConsole::IResult *pResult, void *pUser);
|
||||||
static void TeeHistorianWrite(const void *pData, int DataSize, void *pUser);
|
static void TeeHistorianWrite(const void *pData, int DataSize, void *pUser);
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#ifndef GAME_SERVER_SCORE_H
|
#ifndef GAME_SERVER_SCORE_H
|
||||||
#define GAME_SERVER_SCORE_H
|
#define GAME_SERVER_SCORE_H
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include "entities/character.h"
|
#include "entities/character.h"
|
||||||
#include "gamecontext.h"
|
#include "gamecontext.h"
|
||||||
|
|
||||||
|
@ -38,6 +40,17 @@ public:
|
||||||
float m_aBestCpTime[NUM_CHECKPOINTS];
|
float m_aBestCpTime[NUM_CHECKPOINTS];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Watch this: TODO(2019-05-20): Temporary fix for the random maps race
|
||||||
|
// condition. See you in ten years.
|
||||||
|
class CRandomMapResult
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bool m_Done;
|
||||||
|
char m_aMap[64];
|
||||||
|
|
||||||
|
CRandomMapResult() : m_Done(false) {}
|
||||||
|
};
|
||||||
|
|
||||||
class IScore
|
class IScore
|
||||||
{
|
{
|
||||||
CPlayerData m_aPlayerData[MAX_CLIENTS];
|
CPlayerData m_aPlayerData[MAX_CLIENTS];
|
||||||
|
@ -64,8 +77,8 @@ public:
|
||||||
virtual void ShowTopPoints(IConsole::IResult *pResult, int ClientID, void *pUserData, int Debut=1) = 0;
|
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 ShowPoints(int ClientID, const char *pName, bool Search=false) = 0;
|
||||||
|
|
||||||
virtual void RandomMap(int ClientID, int Stars) = 0;
|
virtual void RandomMap(std::shared_ptr<CRandomMapResult> *ppResult, int ClientID, int Stars) = 0;
|
||||||
virtual void RandomUnfinishedMap(int ClientID, int Stars) = 0;
|
virtual void RandomUnfinishedMap(std::shared_ptr<CRandomMapResult> *ppResult, int ClientID, int Stars) = 0;
|
||||||
|
|
||||||
virtual void SaveTeam(int Team, const char *pCode, int ClientID, const char *pServer) = 0;
|
virtual void SaveTeam(int Team, const char *pCode, int ClientID, const char *pServer) = 0;
|
||||||
virtual void LoadTeam(const char *pCode, int ClientID) = 0;
|
virtual void LoadTeam(const char *pCode, int ClientID) = 0;
|
||||||
|
|
|
@ -329,18 +329,20 @@ void CFileScore::ShowPoints(int ClientID, const char* pName, bool Search)
|
||||||
GameServer()->SendChatTarget(ClientID, aBuf);
|
GameServer()->SendChatTarget(ClientID, aBuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CFileScore::RandomMap(int ClientID, int stars)
|
void CFileScore::RandomMap(std::shared_ptr<CRandomMapResult> *ppResult, int ClientID, int stars)
|
||||||
{
|
{
|
||||||
char aBuf[512];
|
char aBuf[512];
|
||||||
str_format(aBuf, sizeof(aBuf), "Random map not supported in file based servers");
|
str_format(aBuf, sizeof(aBuf), "Random map not supported in file based servers");
|
||||||
GameServer()->SendChatTarget(ClientID, aBuf);
|
GameServer()->SendChatTarget(ClientID, aBuf);
|
||||||
|
*ppResult = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CFileScore::RandomUnfinishedMap(int ClientID, int stars)
|
void CFileScore::RandomUnfinishedMap(std::shared_ptr<CRandomMapResult> *ppResult, int ClientID, int stars)
|
||||||
{
|
{
|
||||||
char aBuf[512];
|
char aBuf[512];
|
||||||
str_format(aBuf, sizeof(aBuf), "Random unfinished map not supported in file based servers");
|
str_format(aBuf, sizeof(aBuf), "Random unfinished map not supported in file based servers");
|
||||||
GameServer()->SendChatTarget(ClientID, aBuf);
|
GameServer()->SendChatTarget(ClientID, aBuf);
|
||||||
|
*ppResult = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CFileScore::SaveTeam(int Team, const char* Code, int ClientID, const char* Server)
|
void CFileScore::SaveTeam(int Team, const char* Code, int ClientID, const char* Server)
|
||||||
|
|
|
@ -80,8 +80,8 @@ public:
|
||||||
|
|
||||||
virtual void ShowTopPoints(IConsole::IResult *pResult, int ClientID, void *pUserData, int Debut);
|
virtual void ShowTopPoints(IConsole::IResult *pResult, int ClientID, void *pUserData, int Debut);
|
||||||
virtual void ShowPoints(int ClientID, const char* pName, bool Search);
|
virtual void ShowPoints(int ClientID, const char* pName, bool Search);
|
||||||
virtual void RandomMap(int ClientID, int stars);
|
virtual void RandomMap(std::shared_ptr<CRandomMapResult> *ppResult, int ClientID, int stars);
|
||||||
virtual void RandomUnfinishedMap(int ClientID, int stars);
|
virtual void RandomUnfinishedMap(std::shared_ptr<CRandomMapResult> *ppResult, int ClientID, int stars);
|
||||||
virtual void SaveTeam(int Team, const char* Code, int ClientID, const char* Server);
|
virtual void SaveTeam(int Team, const char* Code, int ClientID, const char* Server);
|
||||||
virtual void LoadTeam(const char* Code, int ClientID);
|
virtual void LoadTeam(const char* Code, int ClientID);
|
||||||
|
|
||||||
|
|
|
@ -1259,19 +1259,22 @@ bool CSqlScore::ShowTopPointsThread(CSqlServer* pSqlServer, const CSqlData *pGam
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSqlScore::RandomMap(int ClientID, int stars)
|
void CSqlScore::RandomMap(std::shared_ptr<CRandomMapResult> *ppResult, int ClientID, int Stars)
|
||||||
{
|
{
|
||||||
CSqlScoreData *Tmp = new CSqlScoreData();
|
*ppResult = std::make_shared<CRandomMapResult>();
|
||||||
Tmp->m_Num = stars;
|
|
||||||
|
CSqlRandomMap *Tmp = new CSqlRandomMap();
|
||||||
|
Tmp->m_Num = Stars;
|
||||||
Tmp->m_ClientID = ClientID;
|
Tmp->m_ClientID = ClientID;
|
||||||
Tmp->m_Name = GameServer()->Server()->ClientName(ClientID);
|
Tmp->m_Name = GameServer()->Server()->ClientName(ClientID);
|
||||||
|
Tmp->m_pResult = *ppResult;
|
||||||
|
|
||||||
thread_init_and_detach(ExecSqlFunc, new CSqlExecData(RandomMapThread, Tmp), "random map");
|
thread_init_and_detach(ExecSqlFunc, new CSqlExecData(RandomMapThread, Tmp), "random map");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CSqlScore::RandomMapThread(CSqlServer* pSqlServer, const CSqlData *pGameData, bool HandleFailure)
|
bool CSqlScore::RandomMapThread(CSqlServer* pSqlServer, const CSqlData *pGameData, bool HandleFailure)
|
||||||
{
|
{
|
||||||
const CSqlScoreData *pData = dynamic_cast<const CSqlScoreData *>(pGameData);
|
const CSqlRandomMap *pData = dynamic_cast<const CSqlRandomMap *>(pGameData);
|
||||||
|
|
||||||
if (HandleFailure)
|
if (HandleFailure)
|
||||||
return true;
|
return true;
|
||||||
|
@ -1293,11 +1296,9 @@ bool CSqlScore::RandomMapThread(CSqlServer* pSqlServer, const CSqlData *pGameDat
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pSqlServer->GetResults()->next();
|
pSqlServer->GetResults()->next();
|
||||||
char aMap[128];
|
std::string Map = pSqlServer->GetResults()->getString("Map");
|
||||||
strcpy(aMap, pSqlServer->GetResults()->getString("Map").c_str());
|
str_copy(pData->m_pResult->m_aMap, Map.c_str(), sizeof(pData->m_pResult->m_aMap));
|
||||||
|
pData->m_pResult->m_Done = true;
|
||||||
str_format(aBuf, sizeof(aBuf), "change_map \"%s\"", aMap);
|
|
||||||
pData->GameServer()->Console()->ExecuteLine(aBuf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dbg_msg("sql", "voting random map done");
|
dbg_msg("sql", "voting random map done");
|
||||||
|
@ -1316,19 +1317,22 @@ bool CSqlScore::RandomMapThread(CSqlServer* pSqlServer, const CSqlData *pGameDat
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSqlScore::RandomUnfinishedMap(int ClientID, int stars)
|
void CSqlScore::RandomUnfinishedMap(std::shared_ptr<CRandomMapResult> *ppResult, int ClientID, int Stars)
|
||||||
{
|
{
|
||||||
CSqlScoreData *Tmp = new CSqlScoreData();
|
*ppResult = std::make_shared<CRandomMapResult>();
|
||||||
Tmp->m_Num = stars;
|
|
||||||
|
CSqlRandomMap *Tmp = new CSqlRandomMap();
|
||||||
|
Tmp->m_Num = Stars;
|
||||||
Tmp->m_ClientID = ClientID;
|
Tmp->m_ClientID = ClientID;
|
||||||
Tmp->m_Name = GameServer()->Server()->ClientName(ClientID);
|
Tmp->m_Name = GameServer()->Server()->ClientName(ClientID);
|
||||||
|
Tmp->m_pResult = *ppResult;
|
||||||
|
|
||||||
thread_init_and_detach(ExecSqlFunc, new CSqlExecData(RandomUnfinishedMapThread, Tmp), "random unfinished map");
|
thread_init_and_detach(ExecSqlFunc, new CSqlExecData(RandomUnfinishedMapThread, Tmp), "random unfinished map");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CSqlScore::RandomUnfinishedMapThread(CSqlServer* pSqlServer, const CSqlData *pGameData, bool HandleFailure)
|
bool CSqlScore::RandomUnfinishedMapThread(CSqlServer* pSqlServer, const CSqlData *pGameData, bool HandleFailure)
|
||||||
{
|
{
|
||||||
const CSqlScoreData *pData = dynamic_cast<const CSqlScoreData *>(pGameData);
|
const CSqlRandomMap *pData = dynamic_cast<const CSqlRandomMap *>(pGameData);
|
||||||
|
|
||||||
if (HandleFailure)
|
if (HandleFailure)
|
||||||
return true;
|
return true;
|
||||||
|
@ -1350,11 +1354,9 @@ bool CSqlScore::RandomUnfinishedMapThread(CSqlServer* pSqlServer, const CSqlData
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pSqlServer->GetResults()->next();
|
pSqlServer->GetResults()->next();
|
||||||
char aMap[128];
|
std::string Map = pSqlServer->GetResults()->getString("Map");
|
||||||
strcpy(aMap, pSqlServer->GetResults()->getString("Map").c_str());
|
str_copy(pData->m_pResult->m_aMap, Map.c_str(), sizeof(pData->m_pResult->m_aMap));
|
||||||
|
pData->m_pResult->m_Done = true;
|
||||||
str_format(aBuf, sizeof(aBuf), "change_map \"%s\"", aMap);
|
|
||||||
pData->GameServer()->Console()->ExecuteLine(aBuf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dbg_msg("sql", "voting random unfinished map done");
|
dbg_msg("sql", "voting random unfinished map done");
|
||||||
|
|
|
@ -136,6 +136,11 @@ struct CSqlTeamLoad : CSqlData
|
||||||
int m_ClientID;
|
int m_ClientID;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct CSqlRandomMap : CSqlScoreData
|
||||||
|
{
|
||||||
|
std::shared_ptr<CRandomMapResult> m_pResult;
|
||||||
|
};
|
||||||
|
|
||||||
class CSqlScore: public IScore
|
class CSqlScore: public IScore
|
||||||
{
|
{
|
||||||
CGameContext *GameServer() { return m_pGameServer; }
|
CGameContext *GameServer() { return m_pGameServer; }
|
||||||
|
@ -194,8 +199,8 @@ public:
|
||||||
virtual void ShowPoints(int ClientID, const char* pName, bool Search = false);
|
virtual void ShowPoints(int ClientID, const char* pName, bool Search = false);
|
||||||
virtual void ShowTopPoints(IConsole::IResult *pResult, int ClientID,
|
virtual void ShowTopPoints(IConsole::IResult *pResult, int ClientID,
|
||||||
void *pUserData, int Debut = 1);
|
void *pUserData, int Debut = 1);
|
||||||
virtual void RandomMap(int ClientID, int stars);
|
virtual void RandomMap(std::shared_ptr<CRandomMapResult> *ppResult, int ClientID, int stars);
|
||||||
virtual void RandomUnfinishedMap(int ClientID, int stars);
|
virtual void RandomUnfinishedMap(std::shared_ptr<CRandomMapResult> *ppResult, int ClientID, int stars);
|
||||||
virtual void SaveTeam(int Team, const char* Code, int ClientID, const char* Server);
|
virtual void SaveTeam(int Team, const char* Code, int ClientID, const char* Server);
|
||||||
virtual void LoadTeam(const char* Code, int ClientID);
|
virtual void LoadTeam(const char* Code, int ClientID);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue