mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-19 22:48:18 +00:00
merged "List maps" by Learath2 and cinaera. skipped redundant "maps" command. closes #1086
This commit is contained in:
parent
981cba1605
commit
bc38f67750
|
@ -29,5 +29,7 @@ for filename in sys.argv[1:]:
|
||||||
f += cstrip([l.strip() for l in open(filename, "rb")])
|
f += cstrip([l.strip() for l in open(filename, "rb")])
|
||||||
|
|
||||||
hash = hashlib.md5(f).hexdigest().lower()[16:]
|
hash = hashlib.md5(f).hexdigest().lower()[16:]
|
||||||
#TODO 0.7: improve nethash creation
|
#TODO 0.8: improve nethash creation
|
||||||
|
if hash == "0a027ded5791b521":
|
||||||
|
hash = "802f1be60a05665f"
|
||||||
print('#define GAME_NETVERSION_HASH "%s"' % hash)
|
print('#define GAME_NETVERSION_HASH "%s"' % hash)
|
||||||
|
|
|
@ -509,6 +509,7 @@ void CClient::Connect(const char *pAddress)
|
||||||
}
|
}
|
||||||
|
|
||||||
m_RconAuthed = 0;
|
m_RconAuthed = 0;
|
||||||
|
m_UseTempRconCommands = 0;
|
||||||
if(m_ServerAddress.port == 0)
|
if(m_ServerAddress.port == 0)
|
||||||
m_ServerAddress.port = Port;
|
m_ServerAddress.port = Port;
|
||||||
m_NetClient.Connect(&m_ServerAddress);
|
m_NetClient.Connect(&m_ServerAddress);
|
||||||
|
@ -1175,6 +1176,18 @@ void CClient::ProcessServerPacket(CNetChunk *pPacket)
|
||||||
if(Unpacker.Error() == 0)
|
if(Unpacker.Error() == 0)
|
||||||
m_pConsole->DeregisterTemp(pName);
|
m_pConsole->DeregisterTemp(pName);
|
||||||
}
|
}
|
||||||
|
else if((pPacket->m_Flags&NET_CHUNKFLAG_VITAL) != 0 && Msg == NETMSG_MAPLIST_ENTRY_ADD)
|
||||||
|
{
|
||||||
|
const char *pName = Unpacker.GetString(CUnpacker::SANITIZE_CC);
|
||||||
|
if(Unpacker.Error() == 0)
|
||||||
|
m_pConsole->RegisterTempMap(pName);
|
||||||
|
}
|
||||||
|
else if((pPacket->m_Flags&NET_CHUNKFLAG_VITAL) != 0 && Msg == NETMSG_MAPLIST_ENTRY_REM)
|
||||||
|
{
|
||||||
|
const char *pName = Unpacker.GetString(CUnpacker::SANITIZE_CC);
|
||||||
|
if(Unpacker.Error() == 0)
|
||||||
|
m_pConsole->DeregisterTempMap(pName);
|
||||||
|
}
|
||||||
else if((pPacket->m_Flags&NET_CHUNKFLAG_VITAL) != 0 && Msg == NETMSG_RCON_AUTH_ON)
|
else if((pPacket->m_Flags&NET_CHUNKFLAG_VITAL) != 0 && Msg == NETMSG_RCON_AUTH_ON)
|
||||||
{
|
{
|
||||||
m_RconAuthed = 1;
|
m_RconAuthed = 1;
|
||||||
|
@ -1186,6 +1199,7 @@ void CClient::ProcessServerPacket(CNetChunk *pPacket)
|
||||||
if(m_UseTempRconCommands)
|
if(m_UseTempRconCommands)
|
||||||
m_pConsole->DeregisterTempAll();
|
m_pConsole->DeregisterTempAll();
|
||||||
m_UseTempRconCommands = 0;
|
m_UseTempRconCommands = 0;
|
||||||
|
m_pConsole->DeregisterTempMapAll();
|
||||||
}
|
}
|
||||||
else if((pPacket->m_Flags&NET_CHUNKFLAG_VITAL) != 0 && Msg == NETMSG_RCON_LINE)
|
else if((pPacket->m_Flags&NET_CHUNKFLAG_VITAL) != 0 && Msg == NETMSG_RCON_LINE)
|
||||||
{
|
{
|
||||||
|
|
|
@ -24,6 +24,8 @@ public:
|
||||||
TEMPCMD_HELP_LENGTH=96,
|
TEMPCMD_HELP_LENGTH=96,
|
||||||
TEMPCMD_PARAMS_LENGTH=16,
|
TEMPCMD_PARAMS_LENGTH=16,
|
||||||
|
|
||||||
|
TEMPMAP_NAME_LENGTH = 32,
|
||||||
|
|
||||||
MAX_PRINT_CB=4,
|
MAX_PRINT_CB=4,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -67,12 +69,16 @@ public:
|
||||||
virtual const CCommandInfo *FirstCommandInfo(int AccessLevel, int Flagmask) const = 0;
|
virtual const CCommandInfo *FirstCommandInfo(int AccessLevel, int Flagmask) const = 0;
|
||||||
virtual const CCommandInfo *GetCommandInfo(const char *pName, int FlagMask, bool Temp) = 0;
|
virtual const CCommandInfo *GetCommandInfo(const char *pName, int FlagMask, bool Temp) = 0;
|
||||||
virtual void PossibleCommands(const char *pStr, int FlagMask, bool Temp, FPossibleCallback pfnCallback, void *pUser) = 0;
|
virtual void PossibleCommands(const char *pStr, int FlagMask, bool Temp, FPossibleCallback pfnCallback, void *pUser) = 0;
|
||||||
|
virtual void PossibleMaps(const char *pStr, FPossibleCallback pfnCallback, void *pUser) = 0;
|
||||||
virtual void ParseArguments(int NumArgs, const char **ppArguments) = 0;
|
virtual void ParseArguments(int NumArgs, const char **ppArguments) = 0;
|
||||||
|
|
||||||
virtual void Register(const char *pName, const char *pParams, int Flags, FCommandCallback pfnFunc, void *pUser, const char *pHelp) = 0;
|
virtual void Register(const char *pName, const char *pParams, int Flags, FCommandCallback pfnFunc, void *pUser, const char *pHelp) = 0;
|
||||||
virtual void RegisterTemp(const char *pName, const char *pParams, int Flags, const char *pHelp) = 0;
|
virtual void RegisterTemp(const char *pName, const char *pParams, int Flags, const char *pHelp) = 0;
|
||||||
virtual void DeregisterTemp(const char *pName) = 0;
|
virtual void DeregisterTemp(const char *pName) = 0;
|
||||||
virtual void DeregisterTempAll() = 0;
|
virtual void DeregisterTempAll() = 0;
|
||||||
|
virtual void RegisterTempMap(const char *pName) = 0;
|
||||||
|
virtual void DeregisterTempMap(const char *pName) = 0;
|
||||||
|
virtual void DeregisterTempMapAll() = 0;
|
||||||
virtual void Chain(const char *pName, FChainCommandCallback pfnChainFunc, void *pUser) = 0;
|
virtual void Chain(const char *pName, FChainCommandCallback pfnChainFunc, void *pUser) = 0;
|
||||||
virtual void StoreCommands(bool Store) = 0;
|
virtual void StoreCommands(bool Store) = 0;
|
||||||
|
|
||||||
|
|
|
@ -280,6 +280,10 @@ CServer::CServer() : m_DemoRecorder(&m_SnapshotDelta)
|
||||||
m_pCurrentMapData = 0;
|
m_pCurrentMapData = 0;
|
||||||
m_CurrentMapSize = 0;
|
m_CurrentMapSize = 0;
|
||||||
|
|
||||||
|
m_NumMapEntries = 0;
|
||||||
|
m_pFirstMapEntry = 0;
|
||||||
|
m_pLastMapEntry = 0;
|
||||||
|
|
||||||
m_MapReload = 0;
|
m_MapReload = 0;
|
||||||
|
|
||||||
m_RconClientID = IServer::RCON_CID_SERV;
|
m_RconClientID = IServer::RCON_CID_SERV;
|
||||||
|
@ -664,6 +668,7 @@ int CServer::NewClientCallback(int ClientID, void *pUser)
|
||||||
pThis->m_aClients[ClientID].m_Authed = AUTHED_NO;
|
pThis->m_aClients[ClientID].m_Authed = AUTHED_NO;
|
||||||
pThis->m_aClients[ClientID].m_AuthTries = 0;
|
pThis->m_aClients[ClientID].m_AuthTries = 0;
|
||||||
pThis->m_aClients[ClientID].m_pRconCmdToSend = 0;
|
pThis->m_aClients[ClientID].m_pRconCmdToSend = 0;
|
||||||
|
pThis->m_aClients[ClientID].m_pMapListEntryToSend = 0;
|
||||||
pThis->m_aClients[ClientID].m_NoRconNote = false;
|
pThis->m_aClients[ClientID].m_NoRconNote = false;
|
||||||
pThis->m_aClients[ClientID].m_Quitting = false;
|
pThis->m_aClients[ClientID].m_Quitting = false;
|
||||||
pThis->m_aClients[ClientID].Reset();
|
pThis->m_aClients[ClientID].Reset();
|
||||||
|
@ -694,6 +699,7 @@ int CServer::DelClientCallback(int ClientID, const char *pReason, void *pUser)
|
||||||
pThis->m_aClients[ClientID].m_Authed = AUTHED_NO;
|
pThis->m_aClients[ClientID].m_Authed = AUTHED_NO;
|
||||||
pThis->m_aClients[ClientID].m_AuthTries = 0;
|
pThis->m_aClients[ClientID].m_AuthTries = 0;
|
||||||
pThis->m_aClients[ClientID].m_pRconCmdToSend = 0;
|
pThis->m_aClients[ClientID].m_pRconCmdToSend = 0;
|
||||||
|
pThis->m_aClients[ClientID].m_pMapListEntryToSend = 0;
|
||||||
pThis->m_aClients[ClientID].m_NoRconNote = false;
|
pThis->m_aClients[ClientID].m_NoRconNote = false;
|
||||||
pThis->m_aClients[ClientID].m_Quitting = false;
|
pThis->m_aClients[ClientID].m_Quitting = false;
|
||||||
pThis->m_aClients[ClientID].m_Snapshots.PurgeAll();
|
pThis->m_aClients[ClientID].m_Snapshots.PurgeAll();
|
||||||
|
@ -774,6 +780,36 @@ void CServer::UpdateClientRconCommands()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CServer::SendMapListEntryAdd(const CMapListEntry *pMapListEntry, int ClientID)
|
||||||
|
{
|
||||||
|
CMsgPacker Msg(NETMSG_MAPLIST_ENTRY_ADD, true);
|
||||||
|
Msg.AddString(pMapListEntry->m_aName, 256);
|
||||||
|
SendMsg(&Msg, MSGFLAG_VITAL, ClientID);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CServer::SendMapListEntryRem(const CMapListEntry *pMapListEntry, int ClientID)
|
||||||
|
{
|
||||||
|
CMsgPacker Msg(NETMSG_MAPLIST_ENTRY_REM, true);
|
||||||
|
Msg.AddString(pMapListEntry->m_aName, 256);
|
||||||
|
SendMsg(&Msg, MSGFLAG_VITAL, ClientID);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CServer::UpdateClientMapListEntries()
|
||||||
|
{
|
||||||
|
for(int ClientID = Tick() % MAX_RCONCMD_RATIO; ClientID < MaxClients(); ClientID += MAX_RCONCMD_RATIO)
|
||||||
|
{
|
||||||
|
if(m_aClients[ClientID].m_State != CClient::STATE_EMPTY && m_aClients[ClientID].m_Authed)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < MAX_MAPLISTENTRY_SEND && m_aClients[ClientID].m_pMapListEntryToSend; ++i)
|
||||||
|
{
|
||||||
|
SendMapListEntryAdd(m_aClients[ClientID].m_pMapListEntryToSend, ClientID);
|
||||||
|
m_aClients[ClientID].m_pMapListEntryToSend = m_aClients[ClientID].m_pMapListEntryToSend->m_pNext;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CServer::ProcessClientPacket(CNetChunk *pPacket)
|
void CServer::ProcessClientPacket(CNetChunk *pPacket)
|
||||||
{
|
{
|
||||||
int ClientID = pPacket->m_ClientID;
|
int ClientID = pPacket->m_ClientID;
|
||||||
|
@ -979,6 +1015,7 @@ void CServer::ProcessClientPacket(CNetChunk *pPacket)
|
||||||
|
|
||||||
m_aClients[ClientID].m_Authed = AUTHED_ADMIN;
|
m_aClients[ClientID].m_Authed = AUTHED_ADMIN;
|
||||||
m_aClients[ClientID].m_pRconCmdToSend = Console()->FirstCommandInfo(IConsole::ACCESS_LEVEL_ADMIN, CFGFLAG_SERVER);
|
m_aClients[ClientID].m_pRconCmdToSend = Console()->FirstCommandInfo(IConsole::ACCESS_LEVEL_ADMIN, CFGFLAG_SERVER);
|
||||||
|
m_aClients[ClientID].m_pMapListEntryToSend = m_pFirstMapEntry;
|
||||||
SendRconLine(ClientID, "Admin authentication successful. Full remote console access granted.");
|
SendRconLine(ClientID, "Admin authentication successful. Full remote console access granted.");
|
||||||
char aBuf[256];
|
char aBuf[256];
|
||||||
str_format(aBuf, sizeof(aBuf), "ClientID=%d authed (admin)", ClientID);
|
str_format(aBuf, sizeof(aBuf), "ClientID=%d authed (admin)", ClientID);
|
||||||
|
@ -992,6 +1029,9 @@ void CServer::ProcessClientPacket(CNetChunk *pPacket)
|
||||||
m_aClients[ClientID].m_Authed = AUTHED_MOD;
|
m_aClients[ClientID].m_Authed = AUTHED_MOD;
|
||||||
m_aClients[ClientID].m_pRconCmdToSend = Console()->FirstCommandInfo(IConsole::ACCESS_LEVEL_MOD, CFGFLAG_SERVER);
|
m_aClients[ClientID].m_pRconCmdToSend = Console()->FirstCommandInfo(IConsole::ACCESS_LEVEL_MOD, CFGFLAG_SERVER);
|
||||||
SendRconLine(ClientID, "Moderator authentication successful. Limited remote console access granted.");
|
SendRconLine(ClientID, "Moderator authentication successful. Limited remote console access granted.");
|
||||||
|
const IConsole::CCommandInfo *pInfo = Console()->GetCommandInfo("sv_map", CFGFLAG_SERVER, false);
|
||||||
|
if(pInfo && pInfo->GetAccessLevel() == IConsole::ACCESS_LEVEL_MOD)
|
||||||
|
m_aClients[ClientID].m_pMapListEntryToSend = m_pFirstMapEntry;
|
||||||
char aBuf[256];
|
char aBuf[256];
|
||||||
str_format(aBuf, sizeof(aBuf), "ClientID=%d authed (moderator)", ClientID);
|
str_format(aBuf, sizeof(aBuf), "ClientID=%d authed (moderator)", ClientID);
|
||||||
Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", aBuf);
|
Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", aBuf);
|
||||||
|
@ -1232,6 +1272,13 @@ int CServer::Run()
|
||||||
//
|
//
|
||||||
m_PrintCBIndex = Console()->RegisterPrintCallback(g_Config.m_ConsoleOutputLevel, SendRconLineAuthed, this);
|
m_PrintCBIndex = Console()->RegisterPrintCallback(g_Config.m_ConsoleOutputLevel, SendRconLineAuthed, this);
|
||||||
|
|
||||||
|
// list maps
|
||||||
|
m_pMapListHeap = new CHeap();
|
||||||
|
CSubdirCallbackUserdata Userdata;
|
||||||
|
Userdata.m_pServer = this;
|
||||||
|
str_copy(Userdata.m_aName, "", sizeof(Userdata.m_aName));
|
||||||
|
m_pStorage->ListDirectory(IStorage::TYPE_ALL, "maps/", MapListEntryCallback, &Userdata);
|
||||||
|
|
||||||
// load map
|
// load map
|
||||||
if(!LoadMap(g_Config.m_SvMap))
|
if(!LoadMap(g_Config.m_SvMap))
|
||||||
{
|
{
|
||||||
|
@ -1361,6 +1408,7 @@ int CServer::Run()
|
||||||
DoSnapshot();
|
DoSnapshot();
|
||||||
|
|
||||||
UpdateClientRconCommands();
|
UpdateClientRconCommands();
|
||||||
|
UpdateClientMapListEntries();
|
||||||
}
|
}
|
||||||
|
|
||||||
// master server stuff
|
// master server stuff
|
||||||
|
@ -1414,6 +1462,52 @@ int CServer::Run()
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int CServer::MapListEntryCallback(const char *pFilename, int IsDir, int DirType, void *pUser)
|
||||||
|
{
|
||||||
|
CSubdirCallbackUserdata *pUserdata = (CSubdirCallbackUserdata *)pUser;
|
||||||
|
CServer *pThis = pUserdata->m_pServer;
|
||||||
|
|
||||||
|
if(pFilename[0] == '.') // hidden files
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
char aFilename[512];
|
||||||
|
if(pUserdata->m_aName[0])
|
||||||
|
str_format(aFilename, sizeof(aFilename), "%s/%s", pUserdata->m_aName, pFilename);
|
||||||
|
else
|
||||||
|
str_format(aFilename, sizeof(aFilename), "%s", pFilename);
|
||||||
|
|
||||||
|
if(IsDir)
|
||||||
|
{
|
||||||
|
CSubdirCallbackUserdata Userdata;
|
||||||
|
Userdata.m_pServer = pThis;
|
||||||
|
str_copy(Userdata.m_aName, aFilename, sizeof(Userdata.m_aName));
|
||||||
|
char FindPath[512];
|
||||||
|
str_format(FindPath, sizeof(FindPath), "maps/%s/", aFilename);
|
||||||
|
pThis->m_pStorage->ListDirectory(IStorage::TYPE_ALL, FindPath, MapListEntryCallback, &Userdata);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *pSuffix = str_endswith(aFilename, ".map");
|
||||||
|
if(!pSuffix) // not ending with .map
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
CMapListEntry *pEntry = (CMapListEntry *)pThis->m_pMapListHeap->Allocate(sizeof(CMapListEntry));
|
||||||
|
pThis->m_NumMapEntries++;
|
||||||
|
pEntry->m_pNext = 0;
|
||||||
|
pEntry->m_pPrev = pThis->m_pLastMapEntry;
|
||||||
|
if(pEntry->m_pPrev)
|
||||||
|
pEntry->m_pPrev->m_pNext = pEntry;
|
||||||
|
pThis->m_pLastMapEntry = pEntry;
|
||||||
|
if(!pThis->m_pFirstMapEntry)
|
||||||
|
pThis->m_pFirstMapEntry = pEntry;
|
||||||
|
|
||||||
|
str_truncate(pEntry->m_aName, sizeof(pEntry->m_aName), aFilename, pSuffix-aFilename);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void CServer::ConKick(IConsole::IResult *pResult, void *pUser)
|
void CServer::ConKick(IConsole::IResult *pResult, void *pUser)
|
||||||
{
|
{
|
||||||
if(pResult->NumArguments() > 1)
|
if(pResult->NumArguments() > 1)
|
||||||
|
@ -1446,7 +1540,7 @@ void CServer::ConStatus(IConsole::IResult *pResult, void *pUser)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
str_format(aBuf, sizeof(aBuf), "id=%d addr=%s connecting", i, aAddrStr);
|
str_format(aBuf, sizeof(aBuf), "id=%d addr=%s connecting", i, aAddrStr);
|
||||||
pThis->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "Server", aBuf);
|
pThis->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", aBuf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1518,6 +1612,7 @@ void CServer::ConLogout(IConsole::IResult *pResult, void *pUser)
|
||||||
pServer->m_aClients[pServer->m_RconClientID].m_Authed = AUTHED_NO;
|
pServer->m_aClients[pServer->m_RconClientID].m_Authed = AUTHED_NO;
|
||||||
pServer->m_aClients[pServer->m_RconClientID].m_AuthTries = 0;
|
pServer->m_aClients[pServer->m_RconClientID].m_AuthTries = 0;
|
||||||
pServer->m_aClients[pServer->m_RconClientID].m_pRconCmdToSend = 0;
|
pServer->m_aClients[pServer->m_RconClientID].m_pRconCmdToSend = 0;
|
||||||
|
pServer->m_aClients[pServer->m_RconClientID].m_pMapListEntryToSend = 0;
|
||||||
pServer->SendRconLine(pServer->m_RconClientID, "Logout successful.");
|
pServer->SendRconLine(pServer->m_RconClientID, "Logout successful.");
|
||||||
char aBuf[32];
|
char aBuf[32];
|
||||||
str_format(aBuf, sizeof(aBuf), "ClientID=%d logged out", pServer->m_RconClientID);
|
str_format(aBuf, sizeof(aBuf), "ClientID=%d logged out", pServer->m_RconClientID);
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
#define ENGINE_SERVER_SERVER_H
|
#define ENGINE_SERVER_SERVER_H
|
||||||
|
|
||||||
#include <engine/server.h>
|
#include <engine/server.h>
|
||||||
|
#include <engine/shared/memheap.h>
|
||||||
|
|
||||||
class CSnapIDPool
|
class CSnapIDPool
|
||||||
{
|
{
|
||||||
|
@ -76,9 +76,12 @@ public:
|
||||||
AUTHED_ADMIN,
|
AUTHED_ADMIN,
|
||||||
|
|
||||||
MAX_RCONCMD_SEND=16,
|
MAX_RCONCMD_SEND=16,
|
||||||
|
MAX_MAPLISTENTRY_SEND = 32,
|
||||||
MAX_RCONCMD_RATIO=8,
|
MAX_RCONCMD_RATIO=8,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class CMapListEntry;
|
||||||
|
|
||||||
class CClient
|
class CClient
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -128,6 +131,7 @@ public:
|
||||||
bool m_NoRconNote;
|
bool m_NoRconNote;
|
||||||
bool m_Quitting;
|
bool m_Quitting;
|
||||||
const IConsole::CCommandInfo *m_pRconCmdToSend;
|
const IConsole::CCommandInfo *m_pRconCmdToSend;
|
||||||
|
const CMapListEntry *m_pMapListEntryToSend;
|
||||||
|
|
||||||
void Reset();
|
void Reset();
|
||||||
};
|
};
|
||||||
|
@ -163,6 +167,25 @@ public:
|
||||||
int m_CurrentMapSize;
|
int m_CurrentMapSize;
|
||||||
int m_MapChunksPerRequest;
|
int m_MapChunksPerRequest;
|
||||||
|
|
||||||
|
//maplist
|
||||||
|
struct CMapListEntry
|
||||||
|
{
|
||||||
|
CMapListEntry *m_pPrev;
|
||||||
|
CMapListEntry *m_pNext;
|
||||||
|
char m_aName[IConsole::TEMPMAP_NAME_LENGTH];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CSubdirCallbackUserdata
|
||||||
|
{
|
||||||
|
CServer *m_pServer;
|
||||||
|
char m_aName[IConsole::TEMPMAP_NAME_LENGTH];
|
||||||
|
};
|
||||||
|
|
||||||
|
CHeap *m_pMapListHeap;
|
||||||
|
CMapListEntry *m_pLastMapEntry;
|
||||||
|
CMapListEntry *m_pFirstMapEntry;
|
||||||
|
int m_NumMapEntries;
|
||||||
|
|
||||||
int m_RconPasswordSet;
|
int m_RconPasswordSet;
|
||||||
int m_GeneratedRconPassword;
|
int m_GeneratedRconPassword;
|
||||||
|
|
||||||
|
@ -214,6 +237,9 @@ public:
|
||||||
void SendRconCmdAdd(const IConsole::CCommandInfo *pCommandInfo, int ClientID);
|
void SendRconCmdAdd(const IConsole::CCommandInfo *pCommandInfo, int ClientID);
|
||||||
void SendRconCmdRem(const IConsole::CCommandInfo *pCommandInfo, int ClientID);
|
void SendRconCmdRem(const IConsole::CCommandInfo *pCommandInfo, int ClientID);
|
||||||
void UpdateClientRconCommands();
|
void UpdateClientRconCommands();
|
||||||
|
void SendMapListEntryAdd(const CMapListEntry *pMapListEntry, int ClientID);
|
||||||
|
void SendMapListEntryRem(const CMapListEntry *pMapListEntry, int ClientID);
|
||||||
|
void UpdateClientMapListEntries();
|
||||||
|
|
||||||
void ProcessClientPacket(CNetChunk *pPacket);
|
void ProcessClientPacket(CNetChunk *pPacket);
|
||||||
|
|
||||||
|
@ -228,6 +254,8 @@ public:
|
||||||
void InitRegister(CNetServer *pNetServer, IEngineMasterServer *pMasterServer, IConsole *pConsole);
|
void InitRegister(CNetServer *pNetServer, IEngineMasterServer *pMasterServer, IConsole *pConsole);
|
||||||
int Run();
|
int Run();
|
||||||
|
|
||||||
|
static int MapListEntryCallback(const char *pFilename, int IsDir, int DirType, void *pUser);
|
||||||
|
|
||||||
static void ConKick(IConsole::IResult *pResult, void *pUser);
|
static void ConKick(IConsole::IResult *pResult, void *pUser);
|
||||||
static void ConStatus(IConsole::IResult *pResult, void *pUser);
|
static void ConStatus(IConsole::IResult *pResult, void *pUser);
|
||||||
static void ConShutdown(IConsole::IResult *pResult, void *pUser);
|
static void ConShutdown(IConsole::IResult *pResult, void *pUser);
|
||||||
|
|
|
@ -356,6 +356,15 @@ void CConsole::PossibleCommands(const char *pStr, int FlagMask, bool Temp, FPoss
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CConsole::PossibleMaps(const char *pStr, FPossibleCallback pfnCallback, void *pUser)
|
||||||
|
{
|
||||||
|
for(CMapListEntryTemp *pMapEntry = m_pFirstMapEntry; pMapEntry; pMapEntry = pMapEntry->m_pNext)
|
||||||
|
{
|
||||||
|
if(str_find_nocase(pMapEntry->m_aName, pStr))
|
||||||
|
pfnCallback(pMapEntry->m_aName, pUser);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
CConsole::CCommand *CConsole::FindCommand(const char *pName, int FlagMask)
|
CConsole::CCommand *CConsole::FindCommand(const char *pName, int FlagMask)
|
||||||
{
|
{
|
||||||
for(CCommand *pCommand = m_pFirstCommand; pCommand; pCommand = pCommand->m_pNext)
|
for(CCommand *pCommand = m_pFirstCommand; pCommand; pCommand = pCommand->m_pNext)
|
||||||
|
@ -653,6 +662,10 @@ CConsole::CConsole(int FlagMask)
|
||||||
m_StoreCommands = true;
|
m_StoreCommands = true;
|
||||||
m_paStrokeStr[0] = "0";
|
m_paStrokeStr[0] = "0";
|
||||||
m_paStrokeStr[1] = "1";
|
m_paStrokeStr[1] = "1";
|
||||||
|
m_pTempMapListHeap = 0;
|
||||||
|
m_NumMapListEntries = 0;
|
||||||
|
m_pFirstMapEntry = 0;
|
||||||
|
m_pLastMapEntry = 0;
|
||||||
m_ExecutionQueue.Reset();
|
m_ExecutionQueue.Reset();
|
||||||
m_pFirstCommand = 0;
|
m_pFirstCommand = 0;
|
||||||
m_pFirstExec = 0;
|
m_pFirstExec = 0;
|
||||||
|
@ -864,6 +877,71 @@ void CConsole::DeregisterTempAll()
|
||||||
m_pRecycleList = 0;
|
m_pRecycleList = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CConsole::RegisterTempMap(const char *pName)
|
||||||
|
{
|
||||||
|
if(!m_pTempMapListHeap)
|
||||||
|
m_pTempMapListHeap = new CHeap();
|
||||||
|
CMapListEntryTemp *pEntry = (CMapListEntryTemp *)m_pTempMapListHeap->Allocate(sizeof(CMapListEntryTemp));
|
||||||
|
pEntry->m_pNext = 0;
|
||||||
|
pEntry->m_pPrev = m_pLastMapEntry;
|
||||||
|
if(pEntry->m_pPrev)
|
||||||
|
pEntry->m_pPrev->m_pNext = pEntry;
|
||||||
|
m_pLastMapEntry = pEntry;
|
||||||
|
if(!m_pFirstMapEntry)
|
||||||
|
m_pFirstMapEntry = pEntry;
|
||||||
|
str_copy(pEntry->m_aName, pName, TEMPMAP_NAME_LENGTH);
|
||||||
|
m_NumMapListEntries++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CConsole::DeregisterTempMap(const char *pName)
|
||||||
|
{
|
||||||
|
CMapListEntryTemp *pEntry = m_pFirstMapEntry;
|
||||||
|
|
||||||
|
while(pEntry)
|
||||||
|
{
|
||||||
|
if(str_comp_nocase(pName, pEntry->m_aName) == 0)
|
||||||
|
break;
|
||||||
|
pEntry = pEntry->m_pNext;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_NumMapListEntries--;
|
||||||
|
CHeap *pNewTempMapListHeap = new CHeap();
|
||||||
|
CMapListEntryTemp *pNewFirstEntry = 0;
|
||||||
|
CMapListEntryTemp *pNewLastEntry = 0;
|
||||||
|
int NewMapEntryNum = m_NumMapListEntries;
|
||||||
|
|
||||||
|
for(CMapListEntryTemp *pSrc = m_pFirstMapEntry; pSrc; pSrc = pSrc->m_pNext)
|
||||||
|
{
|
||||||
|
if(pSrc == pEntry)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
CMapListEntryTemp *pDst = (CMapListEntryTemp *)pNewTempMapListHeap->Allocate(sizeof(CMapListEntryTemp));
|
||||||
|
pDst->m_pNext = 0;
|
||||||
|
pDst->m_pPrev = m_pLastMapEntry;
|
||||||
|
if(pDst->m_pPrev)
|
||||||
|
pDst->m_pPrev->m_pNext = pDst;
|
||||||
|
m_pLastMapEntry = pDst;
|
||||||
|
if(!m_pFirstMapEntry)
|
||||||
|
m_pFirstMapEntry = pDst;
|
||||||
|
|
||||||
|
str_copy(pDst->m_aName, pSrc->m_aName, TEMPMAP_NAME_LENGTH);
|
||||||
|
}
|
||||||
|
|
||||||
|
delete m_pTempMapListHeap;
|
||||||
|
m_pTempMapListHeap = pNewTempMapListHeap;
|
||||||
|
m_pFirstMapEntry = pNewFirstEntry;
|
||||||
|
m_pLastMapEntry = pNewLastEntry;
|
||||||
|
m_NumMapListEntries = NewMapEntryNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CConsole::DeregisterTempMapAll()
|
||||||
|
{
|
||||||
|
m_pTempMapListHeap->Reset();
|
||||||
|
m_pFirstMapEntry = 0;
|
||||||
|
m_pLastMapEntry = 0;
|
||||||
|
m_NumMapListEntries = 0;
|
||||||
|
}
|
||||||
|
|
||||||
void CConsole::Con_Chain(IResult *pResult, void *pUserData)
|
void CConsole::Con_Chain(IResult *pResult, void *pUserData)
|
||||||
{
|
{
|
||||||
CChain *pInfo = (CChain *)pUserData;
|
CChain *pInfo = (CChain *)pUserData;
|
||||||
|
|
|
@ -57,7 +57,7 @@ class CConsole : public IConsole
|
||||||
static void ConToggle(IResult *pResult, void *pUser);
|
static void ConToggle(IResult *pResult, void *pUser);
|
||||||
static void ConToggleStroke(IResult *pResult, void *pUser);
|
static void ConToggleStroke(IResult *pResult, void *pUser);
|
||||||
static void ConModCommandAccess(IResult *pResult, void *pUser);
|
static void ConModCommandAccess(IResult *pResult, void *pUser);
|
||||||
static void ConModCommandStatus(IConsole::IResult *pResult, void *pUser);
|
static void ConModCommandStatus(IResult *pResult, void *pUser);
|
||||||
|
|
||||||
void ExecuteFileRecurse(const char *pFilename);
|
void ExecuteFileRecurse(const char *pFilename);
|
||||||
void ExecuteLineStroked(int Stroke, const char *pStr);
|
void ExecuteLineStroked(int Stroke, const char *pStr);
|
||||||
|
@ -154,6 +154,17 @@ class CConsole : public IConsole
|
||||||
void AddCommandSorted(CCommand *pCommand);
|
void AddCommandSorted(CCommand *pCommand);
|
||||||
CCommand *FindCommand(const char *pName, int FlagMask);
|
CCommand *FindCommand(const char *pName, int FlagMask);
|
||||||
|
|
||||||
|
struct CMapListEntryTemp {
|
||||||
|
CMapListEntryTemp *m_pPrev;
|
||||||
|
CMapListEntryTemp *m_pNext;
|
||||||
|
char m_aName[TEMPMAP_NAME_LENGTH];
|
||||||
|
};
|
||||||
|
|
||||||
|
CHeap *m_pTempMapListHeap;
|
||||||
|
int m_NumMapListEntries;
|
||||||
|
CMapListEntryTemp *m_pFirstMapEntry;
|
||||||
|
CMapListEntryTemp *m_pLastMapEntry;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CConsole(int FlagMask);
|
CConsole(int FlagMask);
|
||||||
~CConsole();
|
~CConsole();
|
||||||
|
@ -161,12 +172,16 @@ public:
|
||||||
virtual const CCommandInfo *FirstCommandInfo(int AccessLevel, int FlagMask) const;
|
virtual const CCommandInfo *FirstCommandInfo(int AccessLevel, int FlagMask) const;
|
||||||
virtual const CCommandInfo *GetCommandInfo(const char *pName, int FlagMask, bool Temp);
|
virtual const CCommandInfo *GetCommandInfo(const char *pName, int FlagMask, bool Temp);
|
||||||
virtual void PossibleCommands(const char *pStr, int FlagMask, bool Temp, FPossibleCallback pfnCallback, void *pUser);
|
virtual void PossibleCommands(const char *pStr, int FlagMask, bool Temp, FPossibleCallback pfnCallback, void *pUser);
|
||||||
|
virtual void PossibleMaps(const char *pStr, FPossibleCallback pfnCallback, void *pUser);
|
||||||
|
|
||||||
virtual void ParseArguments(int NumArgs, const char **ppArguments);
|
virtual void ParseArguments(int NumArgs, const char **ppArguments);
|
||||||
virtual void Register(const char *pName, const char *pParams, int Flags, FCommandCallback pfnFunc, void *pUser, const char *pHelp);
|
virtual void Register(const char *pName, const char *pParams, int Flags, FCommandCallback pfnFunc, void *pUser, const char *pHelp);
|
||||||
virtual void RegisterTemp(const char *pName, const char *pParams, int Flags, const char *pHelp);
|
virtual void RegisterTemp(const char *pName, const char *pParams, int Flags, const char *pHelp);
|
||||||
virtual void DeregisterTemp(const char *pName);
|
virtual void DeregisterTemp(const char *pName);
|
||||||
virtual void DeregisterTempAll();
|
virtual void DeregisterTempAll();
|
||||||
|
virtual void RegisterTempMap(const char *pName);
|
||||||
|
virtual void DeregisterTempMap(const char *pName);
|
||||||
|
virtual void DeregisterTempMapAll();
|
||||||
virtual void Chain(const char *pName, FChainCommandCallback pfnChainFunc, void *pUser);
|
virtual void Chain(const char *pName, FChainCommandCallback pfnChainFunc, void *pUser);
|
||||||
virtual void StoreCommands(bool Store);
|
virtual void StoreCommands(bool Store);
|
||||||
|
|
||||||
|
|
|
@ -70,6 +70,9 @@ enum
|
||||||
NETMSG_PING,
|
NETMSG_PING,
|
||||||
NETMSG_PING_REPLY,
|
NETMSG_PING_REPLY,
|
||||||
NETMSG_ERROR,
|
NETMSG_ERROR,
|
||||||
|
|
||||||
|
NETMSG_MAPLIST_ENTRY_ADD,// todo 0.8: move up
|
||||||
|
NETMSG_MAPLIST_ENTRY_REM,
|
||||||
};
|
};
|
||||||
|
|
||||||
// this should be revised
|
// this should be revised
|
||||||
|
|
|
@ -47,6 +47,9 @@ CGameConsole::CInstance::CInstance(int Type)
|
||||||
else
|
else
|
||||||
m_CompletionFlagmask = CFGFLAG_SERVER;
|
m_CompletionFlagmask = CFGFLAG_SERVER;
|
||||||
|
|
||||||
|
m_aCompletionMapBuffer[0] = 0;
|
||||||
|
m_CompletionMapChosen = -1;
|
||||||
|
|
||||||
m_aCompletionBuffer[0] = 0;
|
m_aCompletionBuffer[0] = 0;
|
||||||
m_CompletionChosen = -1;
|
m_CompletionChosen = -1;
|
||||||
m_CompletionRenderOffset = 0.0f;
|
m_CompletionRenderOffset = 0.0f;
|
||||||
|
@ -93,6 +96,27 @@ void CGameConsole::CInstance::PossibleCommandsCompleteCallback(const char *pStr,
|
||||||
pInstance->m_CompletionEnumerationCount++;
|
pInstance->m_CompletionEnumerationCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CGameConsole::CInstance::PossibleMapsCompleteCallback(const char *pStr, void *pUser)
|
||||||
|
{
|
||||||
|
CGameConsole::CInstance *pInstance = (CGameConsole::CInstance *)pUser;
|
||||||
|
if(pInstance->m_CompletionMapChosen == pInstance->m_CompletionMapEnumerationCount)
|
||||||
|
{
|
||||||
|
// get command
|
||||||
|
char aBuf[512] = { 0 };
|
||||||
|
const char *pSrc = pInstance->GetString();
|
||||||
|
unsigned i = 0;
|
||||||
|
for(; i < sizeof(aBuf) - 2 && *pSrc && *pSrc != ' '; i++, pSrc++)
|
||||||
|
aBuf[i] = *pSrc;
|
||||||
|
aBuf[i++] = ' ';
|
||||||
|
aBuf[i] = 0;
|
||||||
|
|
||||||
|
// add mapname to current command
|
||||||
|
str_append(aBuf, pStr, sizeof(aBuf));
|
||||||
|
pInstance->m_Input.Set(aBuf);
|
||||||
|
}
|
||||||
|
pInstance->m_CompletionMapEnumerationCount++;
|
||||||
|
}
|
||||||
|
|
||||||
void CGameConsole::CInstance::OnInput(IInput::CEvent Event)
|
void CGameConsole::CInstance::OnInput(IInput::CEvent Event)
|
||||||
{
|
{
|
||||||
bool Handled = false;
|
bool Handled = false;
|
||||||
|
@ -159,6 +183,22 @@ void CGameConsole::CInstance::OnInput(IInput::CEvent Event)
|
||||||
m_pGameConsole->m_pConsole->PossibleCommands(m_aCompletionBuffer, m_CompletionFlagmask, m_Type != CGameConsole::CONSOLETYPE_LOCAL &&
|
m_pGameConsole->m_pConsole->PossibleCommands(m_aCompletionBuffer, m_CompletionFlagmask, m_Type != CGameConsole::CONSOLETYPE_LOCAL &&
|
||||||
m_pGameConsole->Client()->RconAuthed() && m_pGameConsole->Client()->UseTempRconCommands(), PossibleCommandsCompleteCallback, this);
|
m_pGameConsole->Client()->RconAuthed() && m_pGameConsole->Client()->UseTempRconCommands(), PossibleCommandsCompleteCallback, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// maplist completion
|
||||||
|
if(str_comp_nocase_num(GetString(), "sv_map ", 7) == 0 && m_Type != CGameConsole::CONSOLETYPE_LOCAL)
|
||||||
|
{
|
||||||
|
m_CompletionMapChosen++;
|
||||||
|
m_CompletionMapEnumerationCount = 0;
|
||||||
|
m_pGameConsole->m_pConsole->PossibleMaps(m_aCompletionMapBuffer, PossibleMapsCompleteCallback, this);
|
||||||
|
|
||||||
|
// handle wrapping
|
||||||
|
if(m_CompletionMapEnumerationCount && m_CompletionMapChosen >= m_CompletionMapEnumerationCount)
|
||||||
|
{
|
||||||
|
m_CompletionMapChosen %= m_CompletionMapEnumerationCount;
|
||||||
|
m_CompletionMapEnumerationCount = 0;
|
||||||
|
m_pGameConsole->m_pConsole->PossibleMaps(m_aCompletionMapBuffer, PossibleMapsCompleteCallback, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(Event.m_Key == KEY_PAGEUP)
|
else if(Event.m_Key == KEY_PAGEUP)
|
||||||
|
@ -182,6 +222,12 @@ void CGameConsole::CInstance::OnInput(IInput::CEvent Event)
|
||||||
{
|
{
|
||||||
m_CompletionChosen = -1;
|
m_CompletionChosen = -1;
|
||||||
str_copy(m_aCompletionBuffer, m_Input.GetString(), sizeof(m_aCompletionBuffer));
|
str_copy(m_aCompletionBuffer, m_Input.GetString(), sizeof(m_aCompletionBuffer));
|
||||||
|
|
||||||
|
if(str_comp_nocase_num(GetString(), "sv_map ", 7) == 0)
|
||||||
|
{
|
||||||
|
m_CompletionMapChosen = -1;
|
||||||
|
str_copy(m_aCompletionMapBuffer, &m_Input.GetString()[7], sizeof(m_aCompletionBuffer));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// find the current command
|
// find the current command
|
||||||
|
|
|
@ -23,15 +23,18 @@ class CGameConsole : public CComponent
|
||||||
|
|
||||||
CLineInput m_Input;
|
CLineInput m_Input;
|
||||||
int m_Type;
|
int m_Type;
|
||||||
int m_CompletionEnumerationCount;
|
|
||||||
int m_BacklogActPage;
|
int m_BacklogActPage;
|
||||||
|
|
||||||
public:
|
|
||||||
CGameConsole *m_pGameConsole;
|
CGameConsole *m_pGameConsole;
|
||||||
|
|
||||||
|
char m_aCompletionMapBuffer[128];
|
||||||
|
int m_CompletionMapChosen;
|
||||||
|
int m_CompletionMapEnumerationCount;
|
||||||
|
|
||||||
char m_aCompletionBuffer[128];
|
char m_aCompletionBuffer[128];
|
||||||
int m_CompletionChosen;
|
int m_CompletionChosen;
|
||||||
int m_CompletionFlagmask;
|
int m_CompletionFlagmask;
|
||||||
|
int m_CompletionEnumerationCount;
|
||||||
float m_CompletionRenderOffset;
|
float m_CompletionRenderOffset;
|
||||||
|
|
||||||
bool m_IsCommand;
|
bool m_IsCommand;
|
||||||
|
@ -52,6 +55,7 @@ class CGameConsole : public CComponent
|
||||||
|
|
||||||
const char *GetString() const { return m_Input.GetString(); }
|
const char *GetString() const { return m_Input.GetString(); }
|
||||||
static void PossibleCommandsCompleteCallback(const char *pStr, void *pUser);
|
static void PossibleCommandsCompleteCallback(const char *pStr, void *pUser);
|
||||||
|
static void PossibleMapsCompleteCallback(const char *pStr, void *pUser);
|
||||||
};
|
};
|
||||||
|
|
||||||
class IConsole *m_pConsole;
|
class IConsole *m_pConsole;
|
||||||
|
|
Loading…
Reference in a new issue