mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-19 14:38:18 +00:00
Add /map (for votes) and /mapinfo (instead of /mappoints)
This commit is contained in:
parent
434b2bec52
commit
a5f3de6827
|
@ -504,6 +504,37 @@ void CGameContext::ConDND(IConsole::IResult *pResult, void *pUserData)
|
|||
}
|
||||
}
|
||||
|
||||
void CGameContext::ConMap(IConsole::IResult *pResult, void *pUserData)
|
||||
{
|
||||
CGameContext *pSelf = (CGameContext *) pUserData;
|
||||
if (!CheckClientID(pResult->m_ClientID))
|
||||
return;
|
||||
|
||||
if (pResult->NumArguments() <= 0)
|
||||
{
|
||||
pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "map", "Example: /map adr3 to call vote for Adrenaline 3");
|
||||
pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "map", "This means that the map name must start with 'a' and contain the characters 'd', 'r' and '3' in that order");
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(CONF_SQL)
|
||||
if(pSelf->m_apPlayers[pResult->m_ClientID] && g_Config.m_SvUseSQL)
|
||||
if(pSelf->m_apPlayers[pResult->m_ClientID]->m_LastSQLQuery + pSelf->Server()->TickSpeed() >= pSelf->Server()->Tick())
|
||||
return;
|
||||
#endif
|
||||
|
||||
CPlayer *pPlayer = pSelf->m_apPlayers[pResult->m_ClientID];
|
||||
if (!pPlayer)
|
||||
return;
|
||||
|
||||
pSelf->Score()->MapVote(pResult->m_ClientID, pResult->GetString(0));
|
||||
|
||||
#if defined(CONF_SQL)
|
||||
if(pSelf->m_apPlayers[pResult->m_ClientID] && g_Config.m_SvUseSQL)
|
||||
pSelf->m_apPlayers[pResult->m_ClientID]->m_LastSQLQuery = pSelf->Server()->Tick();
|
||||
#endif
|
||||
}
|
||||
|
||||
void CGameContext::ConMapPoints(IConsole::IResult *pResult, void *pUserData)
|
||||
{
|
||||
CGameContext *pSelf = (CGameContext *) pUserData;
|
||||
|
|
|
@ -20,7 +20,8 @@ CHAT_COMMAND("converse", "r", CFGFLAG_CHAT|CFGFLAG_SERVER, ConConverse, this, "C
|
|||
CHAT_COMMAND("pause", "", CFGFLAG_CHAT|CFGFLAG_SERVER, ConTogglePause, this, "Toggles pause (if not activated on the server, it toggles spec)")
|
||||
CHAT_COMMAND("spec", "", CFGFLAG_CHAT|CFGFLAG_SERVER, ConToggleSpec, this, "Toggles spec")
|
||||
CHAT_COMMAND("dnd", "", CFGFLAG_CHAT|CFGFLAG_SERVER, ConDND, this, "Toggle Do Not Disturb (no chat and server messages)")
|
||||
CHAT_COMMAND("mappoints", "?r", CFGFLAG_CHAT|CFGFLAG_SERVER, ConMapPoints, this, "Show how man points the map with name r gives (current map by default)")
|
||||
CHAT_COMMAND("mapinfo", "?r", CFGFLAG_CHAT|CFGFLAG_SERVER, ConMapPoints, this, "Show info about the map with name r gives (current map by default)")
|
||||
CHAT_COMMAND("map", "?r", CFGFLAG_CHAT|CFGFLAG_SERVER, ConMap, this, "Vote a map by name")
|
||||
CHAT_COMMAND("rankteam", "?r", CFGFLAG_CHAT|CFGFLAG_SERVER, ConTeamRank, this, "Shows the team rank of player with name r (your team rank by default)")
|
||||
CHAT_COMMAND("rank", "?r", CFGFLAG_CHAT|CFGFLAG_SERVER, ConRank, this, "Shows the rank of player with name r (your rank by default)")
|
||||
CHAT_COMMAND("rules", "", CFGFLAG_CHAT|CFGFLAG_SERVER, ConRules, this, "Shows the server rules")
|
||||
|
|
|
@ -245,6 +245,22 @@ void CGameContext::CreateSoundGlobal(int Sound, int Target)
|
|||
}
|
||||
}
|
||||
|
||||
void CGameContext::CallVote(int ClientID, const char *aDesc, const char *aCmd, const char *pReason, const char *aChatmsg)
|
||||
{
|
||||
// check if a vote is already running
|
||||
if(m_VoteCloseTime)
|
||||
return;
|
||||
|
||||
int64 Now = Server()->Tick();
|
||||
CPlayer *pPlayer = m_apPlayers[ClientID];
|
||||
SendChat(-1, CGameContext::CHAT_ALL, aChatmsg);
|
||||
StartVote(aDesc, aCmd, pReason);
|
||||
pPlayer->m_Vote = 1;
|
||||
pPlayer->m_VotePos = m_VotePos = 1;
|
||||
m_VoteCreator = ClientID;
|
||||
pPlayer->m_LastVoteCall = Now;
|
||||
}
|
||||
|
||||
void CGameContext::SendChatTarget(int To, const char *pText)
|
||||
{
|
||||
CNetMsg_Sv_Chat Msg;
|
||||
|
@ -354,10 +370,6 @@ void CGameContext::SendBroadcast(const char *pText, int ClientID)
|
|||
//
|
||||
void CGameContext::StartVote(const char *pDesc, const char *pCommand, const char *pReason)
|
||||
{
|
||||
// check if a vote is already running
|
||||
if(m_VoteCloseTime)
|
||||
return;
|
||||
|
||||
// reset votes
|
||||
m_VoteEnforce = VOTE_ENFORCE_UNKNOWN;
|
||||
m_VoteEnforcer = -1;
|
||||
|
@ -1135,14 +1147,7 @@ void CGameContext::OnMessage(int MsgID, CUnpacker *pUnpacker, int ClientID)
|
|||
}
|
||||
|
||||
if(aCmd[0] && str_comp(aCmd,"info"))
|
||||
{
|
||||
SendChat(-1, CGameContext::CHAT_ALL, aChatmsg);
|
||||
StartVote(aDesc, aCmd, pReason);
|
||||
pPlayer->m_Vote = 1;
|
||||
pPlayer->m_VotePos = m_VotePos = 1;
|
||||
m_VoteCreator = ClientID;
|
||||
pPlayer->m_LastVoteCall = Now;
|
||||
}
|
||||
CallVote(ClientID, aDesc, aCmd, pReason, aChatmsg);
|
||||
}
|
||||
else if(MsgID == NETMSGTYPE_CL_VOTE)
|
||||
{
|
||||
|
|
|
@ -148,6 +148,7 @@ public:
|
|||
};
|
||||
|
||||
// network
|
||||
void CallVote(int ClientID, const char *aDesc, const char *aCmd, const char *pReason, const char *aChatmsg);
|
||||
void SendChatTarget(int To, const char *pText);
|
||||
void SendChat(int ClientID, int Team, const char *pText, int SpamProtectionClientID = -1);
|
||||
void SendEmoticon(int ClientID, int Emoticon);
|
||||
|
@ -251,6 +252,7 @@ private:
|
|||
static void ConUTF8(IConsole::IResult *pResult, void *pUserData);
|
||||
static void ConDND(IConsole::IResult *pResult, void *pUserData);
|
||||
static void ConMapPoints(IConsole::IResult *pResult, void *pUserData);
|
||||
static void ConMap(IConsole::IResult *pResult, void *pUserData);
|
||||
static void ConTeamRank(IConsole::IResult *pResult, void *pUserData);
|
||||
static void ConRank(IConsole::IResult *pResult, void *pUserData);
|
||||
static void ConBroadTime(IConsole::IResult *pResult, void *pUserData);
|
||||
|
|
|
@ -44,6 +44,7 @@ public:
|
|||
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;
|
||||
|
||||
|
|
|
@ -59,6 +59,11 @@ void CFileScore::MapPoints(int ClientID, const char* MapName)
|
|||
// TODO: implement
|
||||
}
|
||||
|
||||
void CFileScore::MapVote(int ClientID, const char* MapName)
|
||||
{
|
||||
// TODO: implement
|
||||
}
|
||||
|
||||
void CFileScore::SaveScoreThread(void *pUser)
|
||||
{
|
||||
CFileScore *pSelf = (CFileScore *) pUser;
|
||||
|
|
|
@ -64,6 +64,7 @@ public:
|
|||
|
||||
virtual void LoadScore(int ClientID);
|
||||
virtual void MapPoints(int ClientID, const char* MapName);
|
||||
virtual void MapVote(int ClientID, const char* MapName);
|
||||
virtual void SaveScore(int ClientID, float Time,
|
||||
float CpTime[NUM_CHECKPOINTS]);
|
||||
virtual void SaveTeamScore(int* ClientIDs, unsigned int Size, float Time);
|
||||
|
|
|
@ -394,6 +394,74 @@ void CSqlScore::SaveTeamScoreThread(void *pUser)
|
|||
lock_release(gs_SqlLock);
|
||||
}
|
||||
|
||||
void CSqlScore::MapVote(int ClientID, const char* MapName)
|
||||
{
|
||||
CSqlMapData *Tmp = new CSqlMapData();
|
||||
Tmp->m_ClientID = ClientID;
|
||||
str_copy(Tmp->m_aMap, MapName, 128);
|
||||
Tmp->m_pSqlData = this;
|
||||
|
||||
void *VoteThread = thread_create(MapVoteThread, Tmp);
|
||||
#if defined(CONF_FAMILY_UNIX)
|
||||
pthread_detach((pthread_t)VoteThread);
|
||||
#endif
|
||||
}
|
||||
|
||||
void CSqlScore::MapVoteThread(void *pUser)
|
||||
{
|
||||
lock_wait(gs_SqlLock);
|
||||
|
||||
CSqlMapData *pData = (CSqlMapData *)pUser;
|
||||
|
||||
// Connect to database
|
||||
if(pData->m_pSqlData->Connect())
|
||||
{
|
||||
char originalMap[128];
|
||||
strcpy(originalMap,pData->m_aMap);
|
||||
pData->m_pSqlData->ClearString(pData->m_aMap);
|
||||
pData->m_pSqlData->FuzzyString(pData->m_aMap);
|
||||
|
||||
try
|
||||
{
|
||||
char aBuf[768];
|
||||
str_format(aBuf, sizeof(aBuf), "SELECT Map, Server FROM %s_maps WHERE Map LIKE '%s' COLLATE utf8_general_ci ORDER BY LENGTH(Map), Map LIMIT 1;", pData->m_pSqlData->m_pPrefix, pData->m_aMap);
|
||||
pData->m_pSqlData->m_pResults = pData->m_pSqlData->m_pStatement->executeQuery(aBuf);
|
||||
|
||||
if(pData->m_pSqlData->m_pResults->rowsCount() != 1)
|
||||
{
|
||||
str_format(aBuf, sizeof(aBuf), "No map like \"%s\" found.", originalMap);
|
||||
}
|
||||
else
|
||||
{
|
||||
pData->m_pSqlData->m_pResults->next();
|
||||
char aMap[128];
|
||||
strcpy(aMap, pData->m_pSqlData->m_pResults->getString("Map").c_str());
|
||||
char aServer[32];
|
||||
strcpy(aServer, pData->m_pSqlData->m_pResults->getString("Server").c_str());
|
||||
char aCmd[256];
|
||||
str_format(aCmd, sizeof(aCmd), "sv_reset_file types/%s/flexreset.cfg; change_map %s", aServer, aMap);
|
||||
char aChatmsg[512];
|
||||
str_format(aChatmsg, sizeof(aChatmsg), "'%s' called vote to change server option '%s' (%s)", pData->m_pSqlData->GameServer()->Server()->ClientName(pData->m_ClientID), aMap, "/map");
|
||||
pData->m_pSqlData->GameServer()->CallVote(pData->m_ClientID, aMap, aCmd, "/map", aChatmsg);
|
||||
}
|
||||
|
||||
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 time");
|
||||
}
|
||||
|
||||
pData->m_pSqlData->Disconnect();
|
||||
}
|
||||
|
||||
delete pData;
|
||||
lock_release(gs_SqlLock);
|
||||
}
|
||||
|
||||
void CSqlScore::MapPoints(int ClientID, const char* MapName)
|
||||
{
|
||||
CSqlMapData *Tmp = new CSqlMapData();
|
||||
|
@ -401,9 +469,9 @@ void CSqlScore::MapPoints(int ClientID, const char* MapName)
|
|||
str_copy(Tmp->m_aMap, MapName, 128);
|
||||
Tmp->m_pSqlData = this;
|
||||
|
||||
void *PointsThread = thread_create(MapPointsThread, Tmp);
|
||||
void *InfoThread = thread_create(MapPointsThread, Tmp);
|
||||
#if defined(CONF_FAMILY_UNIX)
|
||||
pthread_detach((pthread_t)PointsThread);
|
||||
pthread_detach((pthread_t)InfoThread);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -419,22 +487,28 @@ void CSqlScore::MapPointsThread(void *pUser)
|
|||
char originalMap[128];
|
||||
strcpy(originalMap,pData->m_aMap);
|
||||
pData->m_pSqlData->ClearString(pData->m_aMap);
|
||||
pData->m_pSqlData->FuzzyString(pData->m_aMap);
|
||||
|
||||
try
|
||||
{
|
||||
char aBuf[768];
|
||||
str_format(aBuf, sizeof(aBuf), "SELECT Points FROM %s_maps WHERE Map ='%s'", pData->m_pSqlData->m_pPrefix, pData->m_aMap);
|
||||
str_format(aBuf, sizeof(aBuf), "SELECT Map, Server, Points FROM %s_maps WHERE Map LIKE '%s' COLLATE utf8_general_ci ORDER BY LENGTH(Map), Map LIMIT 1;", pData->m_pSqlData->m_pPrefix, pData->m_aMap);
|
||||
pData->m_pSqlData->m_pResults = pData->m_pSqlData->m_pStatement->executeQuery(aBuf);
|
||||
|
||||
if(pData->m_pSqlData->m_pResults->rowsCount() != 1)
|
||||
{
|
||||
str_format(aBuf, sizeof(aBuf), "No map called \"%s\" found.", originalMap);
|
||||
str_format(aBuf, sizeof(aBuf), "No map like \"%s\" found.", originalMap);
|
||||
}
|
||||
else
|
||||
{
|
||||
pData->m_pSqlData->m_pResults->next();
|
||||
int points = (int)pData->m_pSqlData->m_pResults->getInt("Points");
|
||||
str_format(aBuf, sizeof(aBuf), "Finishing \"%s\" will give you %d points.", originalMap, points);
|
||||
char aMap[128];
|
||||
strcpy(aMap, pData->m_pSqlData->m_pResults->getString("Map").c_str());
|
||||
char aServer[32];
|
||||
strcpy(aServer, pData->m_pSqlData->m_pResults->getString("Server").c_str());
|
||||
aServer[0] = toupper(aServer[0]);
|
||||
str_format(aBuf, sizeof(aBuf), "\"%s\" on %s (%d points)", aMap, aServer, points);
|
||||
}
|
||||
|
||||
pData->m_pSqlData->GameServer()->SendChatTarget(pData->m_ClientID, aBuf);
|
||||
|
@ -1055,8 +1129,25 @@ void CSqlScore::ShowTimes(int ClientID, const char* pName, int Debut)
|
|||
#endif
|
||||
}
|
||||
|
||||
// anti SQL injection
|
||||
void CSqlScore::FuzzyString(char *pString)
|
||||
{
|
||||
char newString[32*4-1];
|
||||
int pos = 0;
|
||||
|
||||
for(int i=0;i<64;i++)
|
||||
{
|
||||
if(!pString[i])
|
||||
break;
|
||||
|
||||
newString[pos++] = pString[i];
|
||||
newString[pos++] = '%';
|
||||
}
|
||||
|
||||
newString[pos] = '\0';
|
||||
strcpy(pString, newString);
|
||||
}
|
||||
|
||||
// anti SQL injection
|
||||
void CSqlScore::ClearString(char *pString)
|
||||
{
|
||||
char newString[32*2-1];
|
||||
|
|
|
@ -41,6 +41,7 @@ class CSqlScore: public IScore
|
|||
}
|
||||
|
||||
static void MapPointsThread(void *pUser);
|
||||
static void MapVoteThread(void *pUser);
|
||||
static void LoadScoreThread(void *pUser);
|
||||
static void SaveScoreThread(void *pUser);
|
||||
static void SaveTeamScoreThread(void *pUser);
|
||||
|
@ -57,6 +58,7 @@ class CSqlScore: public IScore
|
|||
bool Connect();
|
||||
void Disconnect();
|
||||
|
||||
void FuzzyString(char *pString);
|
||||
// anti SQL injection
|
||||
void ClearString(char *pString);
|
||||
|
||||
|
@ -69,6 +71,7 @@ public:
|
|||
|
||||
virtual void LoadScore(int ClientID);
|
||||
virtual void MapPoints(int ClientID, const char* MapName);
|
||||
virtual void MapVote(int ClientID, const char* MapName);
|
||||
virtual void SaveScore(int ClientID, float Time,
|
||||
float CpTime[NUM_CHECKPOINTS]);
|
||||
virtual void SaveTeamScore(int* aClientIDs, unsigned int Size, float Time);
|
||||
|
|
Loading…
Reference in a new issue