Core now detects and handles a changed maxplayers value (bug 2537 and bug 2758)
This commit is contained in:
parent
4517031861
commit
f4dba84ae5
@ -68,6 +68,15 @@ SH_DECL_HOOK1_void(IServerGameClients, ClientCommand, SH_NOATTRIB, 0, edict_t *)
|
|||||||
SH_DECL_HOOK1_void(IServerGameClients, ClientSettingsChanged, SH_NOATTRIB, 0, edict_t *);
|
SH_DECL_HOOK1_void(IServerGameClients, ClientSettingsChanged, SH_NOATTRIB, 0, edict_t *);
|
||||||
SH_DECL_HOOK3_void(IServerGameDLL, ServerActivate, SH_NOATTRIB, 0, edict_t *, int, int);
|
SH_DECL_HOOK3_void(IServerGameDLL, ServerActivate, SH_NOATTRIB, 0, edict_t *, int, int);
|
||||||
|
|
||||||
|
#if defined ORANGEBOX_BUILD
|
||||||
|
SH_DECL_EXTERN1_void(ConCommand, Dispatch, SH_NOATTRIB, false, const CCommand &);
|
||||||
|
#else
|
||||||
|
extern bool __SourceHook_FHAddConCommandDispatch(void *,bool,class fastdelegate::FastDelegate0<void>);
|
||||||
|
extern bool __SourceHook_FHRemoveConCommandDispatch(void *,bool,class fastdelegate::FastDelegate0<void>);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ConCommand *maxplayersCmd = NULL;
|
||||||
|
|
||||||
class KickPlayerTimer : public ITimedEvent
|
class KickPlayerTimer : public ITimedEvent
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -137,6 +146,32 @@ void PlayerManager::OnSourceModAllInitialized()
|
|||||||
|
|
||||||
m_bIsListenServer = !engine->IsDedicatedServer();
|
m_bIsListenServer = !engine->IsDedicatedServer();
|
||||||
m_ListenClient = 0;
|
m_ListenClient = 0;
|
||||||
|
|
||||||
|
g_ConVarManager.AddConVarChangeListener("tv_enable", this);
|
||||||
|
|
||||||
|
ConCommandBase *pBase = icvar->GetCommands();
|
||||||
|
ConCommand *pCmd = NULL;
|
||||||
|
while (pBase)
|
||||||
|
{
|
||||||
|
if (strcmp(pBase->GetName(), "maxplayers") == 0)
|
||||||
|
{
|
||||||
|
/* Don't want to return convar with same name */
|
||||||
|
if (!pBase->IsCommand())
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
pCmd = (ConCommand *)pBase;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pBase = const_cast<ConCommandBase *>(pBase->GetNext());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pCmd != NULL)
|
||||||
|
{
|
||||||
|
SH_ADD_HOOK_STATICFUNC(ConCommand, Dispatch, pCmd, CmdMaxplayersCallback, true);
|
||||||
|
maxplayersCmd = pCmd;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlayerManager::OnSourceModShutdown()
|
void PlayerManager::OnSourceModShutdown()
|
||||||
@ -165,6 +200,13 @@ void PlayerManager::OnSourceModShutdown()
|
|||||||
g_Forwards.ReleaseForward(PostAdminFilter);
|
g_Forwards.ReleaseForward(PostAdminFilter);
|
||||||
|
|
||||||
delete [] m_Players;
|
delete [] m_Players;
|
||||||
|
|
||||||
|
g_ConVarManager.RemoveConVarChangeListener("tv_enable", this);
|
||||||
|
|
||||||
|
if (maxplayersCmd != NULL)
|
||||||
|
{
|
||||||
|
SH_REMOVE_HOOK_STATICFUNC(ConCommand, Dispatch, maxplayersCmd, CmdMaxplayersCallback, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfigResult PlayerManager::OnSourceModConfigChanged(const char *key,
|
ConfigResult PlayerManager::OnSourceModConfigChanged(const char *key,
|
||||||
@ -202,11 +244,11 @@ void PlayerManager::OnServerActivate(edict_t *pEdictList, int edictCount, int cl
|
|||||||
/* Initialize all players */
|
/* Initialize all players */
|
||||||
m_maxClients = clientMax;
|
m_maxClients = clientMax;
|
||||||
m_PlayerCount = 0;
|
m_PlayerCount = 0;
|
||||||
m_Players = new CPlayer[m_maxClients + 1];
|
m_Players = new CPlayer[ABSOLUTE_PLAYER_LIMIT + 1];
|
||||||
m_AuthQueue = new unsigned int[m_maxClients + 1];
|
m_AuthQueue = new unsigned int[ABSOLUTE_PLAYER_LIMIT + 1];
|
||||||
m_FirstPass = true;
|
m_FirstPass = true;
|
||||||
|
|
||||||
memset(m_AuthQueue, 0, sizeof(unsigned int) * (m_maxClients + 1));
|
memset(m_AuthQueue, 0, sizeof(unsigned int) * (ABSOLUTE_PLAYER_LIMIT + 1));
|
||||||
|
|
||||||
g_NumPlayersToAuth = &m_AuthQueue[0];
|
g_NumPlayersToAuth = &m_AuthQueue[0];
|
||||||
}
|
}
|
||||||
@ -1203,6 +1245,68 @@ void PlayerManager::ProcessCommandTarget(cmd_target_info_t *info)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PlayerManager::OnConVarChanged( ConVar *pConVar, const char *oldValue, float flOldValue )
|
||||||
|
{
|
||||||
|
if (pConVar->GetBool() && !atoi(oldValue))
|
||||||
|
{
|
||||||
|
MaxPlayersChanged(gpGlobals->maxClients + 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MaxPlayersChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlayerManager::OnSourceModMaxPlayersChanged( int newvalue )
|
||||||
|
{
|
||||||
|
m_maxClients = newvalue;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlayerManager::MaxPlayersChanged( int newvalue /*= -1*/ )
|
||||||
|
{
|
||||||
|
if (newvalue == -1)
|
||||||
|
{
|
||||||
|
newvalue = gpGlobals->maxClients;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newvalue == MaxClients())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Notify the rest of core */
|
||||||
|
SMGlobalClass *pBase = SMGlobalClass::head;
|
||||||
|
while (pBase)
|
||||||
|
{
|
||||||
|
pBase->OnSourceModMaxPlayersChanged(newvalue);
|
||||||
|
pBase = pBase->m_pGlobalClassNext;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Notify Extensions */
|
||||||
|
List<IClientListener *>::iterator iter;
|
||||||
|
IClientListener *pListener = NULL;
|
||||||
|
for (iter=m_hooks.begin(); iter!=m_hooks.end(); iter++)
|
||||||
|
{
|
||||||
|
pListener = (*iter);
|
||||||
|
if (pListener->GetClientListenerVersion() >= 8)
|
||||||
|
{
|
||||||
|
pListener->OnMaxPlayersChanged(newvalue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined ORANGEBOX_BUILD
|
||||||
|
void CmdMaxplayersCallback(const CCommand &command)
|
||||||
|
{
|
||||||
|
#else
|
||||||
|
void CmdMaxplayersCallback()
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
g_Players.MaxPlayersChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*******************
|
/*******************
|
||||||
*** PLAYER CODE ***
|
*** PLAYER CODE ***
|
||||||
*******************/
|
*******************/
|
||||||
|
@ -41,6 +41,7 @@
|
|||||||
#include <sh_string.h>
|
#include <sh_string.h>
|
||||||
#include <sh_list.h>
|
#include <sh_list.h>
|
||||||
#include <sh_vector.h>
|
#include <sh_vector.h>
|
||||||
|
#include "ConVarManager.h"
|
||||||
|
|
||||||
using namespace SourceHook;
|
using namespace SourceHook;
|
||||||
|
|
||||||
@ -110,7 +111,8 @@ private:
|
|||||||
|
|
||||||
class PlayerManager :
|
class PlayerManager :
|
||||||
public SMGlobalClass,
|
public SMGlobalClass,
|
||||||
public IPlayerManager
|
public IPlayerManager,
|
||||||
|
public IConVarChangeListener
|
||||||
{
|
{
|
||||||
friend class CPlayer;
|
friend class CPlayer;
|
||||||
public:
|
public:
|
||||||
@ -121,6 +123,7 @@ public: //SMGlobalClass
|
|||||||
void OnSourceModShutdown();
|
void OnSourceModShutdown();
|
||||||
void OnSourceModLevelEnd();
|
void OnSourceModLevelEnd();
|
||||||
ConfigResult OnSourceModConfigChanged(const char *key, const char *value, ConfigSource source, char *error, size_t maxlength);
|
ConfigResult OnSourceModConfigChanged(const char *key, const char *value, ConfigSource source, char *error, size_t maxlength);
|
||||||
|
void OnSourceModMaxPlayersChanged(int newvalue);
|
||||||
public:
|
public:
|
||||||
CPlayer *GetPlayerByIndex(int client) const;
|
CPlayer *GetPlayerByIndex(int client) const;
|
||||||
void RunAuthChecks();
|
void RunAuthChecks();
|
||||||
@ -153,6 +156,8 @@ public: //IPlayerManager
|
|||||||
void RegisterCommandTargetProcessor(ICommandTargetProcessor *pHandler);
|
void RegisterCommandTargetProcessor(ICommandTargetProcessor *pHandler);
|
||||||
void UnregisterCommandTargetProcessor(ICommandTargetProcessor *pHandler);
|
void UnregisterCommandTargetProcessor(ICommandTargetProcessor *pHandler);
|
||||||
void ProcessCommandTarget(cmd_target_info_t *info);
|
void ProcessCommandTarget(cmd_target_info_t *info);
|
||||||
|
public: // IConVarChangeListener
|
||||||
|
void OnConVarChanged(ConVar *pConVar, const char *oldValue, float flOldValue);
|
||||||
public:
|
public:
|
||||||
inline int MaxClients()
|
inline int MaxClients()
|
||||||
{
|
{
|
||||||
@ -172,6 +177,7 @@ public:
|
|||||||
void RecheckAnyAdmins();
|
void RecheckAnyAdmins();
|
||||||
unsigned int GetReplyTo();
|
unsigned int GetReplyTo();
|
||||||
unsigned int SetReplyTo(unsigned int reply);
|
unsigned int SetReplyTo(unsigned int reply);
|
||||||
|
void MaxPlayersChanged(int newvalue = -1);
|
||||||
private:
|
private:
|
||||||
void OnServerActivate(edict_t *pEdictList, int edictCount, int clientMax);
|
void OnServerActivate(edict_t *pEdictList, int edictCount, int clientMax);
|
||||||
void InvalidatePlayer(CPlayer *pPlayer);
|
void InvalidatePlayer(CPlayer *pPlayer);
|
||||||
@ -198,6 +204,12 @@ private:
|
|||||||
int m_ListenClient;
|
int m_ListenClient;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if defined ORANGEBOX_BUILD
|
||||||
|
void CmdMaxplayersCallback(const CCommand &command);
|
||||||
|
#else
|
||||||
|
void CmdMaxplayersCallback();
|
||||||
|
#endif
|
||||||
|
|
||||||
extern PlayerManager g_Players;
|
extern PlayerManager g_Players;
|
||||||
extern bool g_OnMapStarted;
|
extern bool g_OnMapStarted;
|
||||||
extern const unsigned int *g_NumPlayersToAuth;
|
extern const unsigned int *g_NumPlayersToAuth;
|
||||||
|
@ -74,6 +74,7 @@ class SMGlobalClass
|
|||||||
friend class SourceModBase;
|
friend class SourceModBase;
|
||||||
friend class CoreConfig;
|
friend class CoreConfig;
|
||||||
friend class CExtensionManager;
|
friend class CExtensionManager;
|
||||||
|
friend class PlayerManager;
|
||||||
public:
|
public:
|
||||||
SMGlobalClass();
|
SMGlobalClass();
|
||||||
public:
|
public:
|
||||||
@ -167,6 +168,15 @@ public:
|
|||||||
virtual void OnSourceModIdentityDropped(IdentityToken_t *pToken)
|
virtual void OnSourceModIdentityDropped(IdentityToken_t *pToken)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Called when the server maxplayers changes
|
||||||
|
*
|
||||||
|
* @param newvalue New maxplayers value.
|
||||||
|
*/
|
||||||
|
virtual void OnSourceModMaxPlayersChanged(int newvalue)
|
||||||
|
{
|
||||||
|
}
|
||||||
private:
|
private:
|
||||||
SMGlobalClass *m_pGlobalClassNext;
|
SMGlobalClass *m_pGlobalClassNext;
|
||||||
static SMGlobalClass *head;
|
static SMGlobalClass *head;
|
||||||
|
@ -93,7 +93,7 @@ unsigned int TopMenu::CalcMemUsage()
|
|||||||
|
|
||||||
size += m_Config.strings.GetMemTable()->MemUsage();
|
size += m_Config.strings.GetMemTable()->MemUsage();
|
||||||
size += (m_Config.cats.size() * sizeof(int));
|
size += (m_Config.cats.size() * sizeof(int));
|
||||||
size += (sizeof(topmenu_player_t) * m_max_clients);
|
size += (sizeof(topmenu_player_t) * (ABSOLUTE_PLAYER_LIMIT + 1));
|
||||||
size += (m_SortedCats.size() * sizeof(unsigned int));
|
size += (m_SortedCats.size() * sizeof(unsigned int));
|
||||||
size += (m_UnsortedCats.size() * sizeof(unsigned int));
|
size += (m_UnsortedCats.size() * sizeof(unsigned int));
|
||||||
size += (m_Categories.size() * (sizeof(topmenu_category_t *) + sizeof(topmenu_category_t)));
|
size += (m_Categories.size() * (sizeof(topmenu_category_t *) + sizeof(topmenu_category_t)));
|
||||||
@ -904,8 +904,8 @@ void TopMenu::SortCategoriesIfNeeded()
|
|||||||
void TopMenu::CreatePlayers(int max_clients)
|
void TopMenu::CreatePlayers(int max_clients)
|
||||||
{
|
{
|
||||||
m_max_clients = max_clients;
|
m_max_clients = max_clients;
|
||||||
m_clients = (topmenu_player_t *)malloc(sizeof(topmenu_player_t) * (max_clients + 1));
|
m_clients = (topmenu_player_t *)malloc(sizeof(topmenu_player_t) * (ABSOLUTE_PLAYER_LIMIT + 1));
|
||||||
memset(m_clients, 0, sizeof(topmenu_player_t) * (max_clients + 1));
|
memset(m_clients, 0, sizeof(topmenu_player_t) * (ABSOLUTE_PLAYER_LIMIT + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
void TopMenu::TearDownClient(topmenu_player_t *player)
|
void TopMenu::TearDownClient(topmenu_player_t *player)
|
||||||
@ -1100,6 +1100,11 @@ unsigned int TopMenu::FindCategory(const char *name)
|
|||||||
return obj->object_id;
|
return obj->object_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TopMenu::OnMaxPlayersChanged( int newvalue )
|
||||||
|
{
|
||||||
|
m_max_clients = newvalue;
|
||||||
|
}
|
||||||
|
|
||||||
int _SortObjectNamesDescending(const void *ptr1, const void *ptr2)
|
int _SortObjectNamesDescending(const void *ptr1, const void *ptr2)
|
||||||
{
|
{
|
||||||
obj_by_name_t *obj1 = (obj_by_name_t *)ptr1;
|
obj_by_name_t *obj1 = (obj_by_name_t *)ptr1;
|
||||||
|
@ -42,6 +42,8 @@
|
|||||||
using namespace SourceHook;
|
using namespace SourceHook;
|
||||||
using namespace SourceMod;
|
using namespace SourceMod;
|
||||||
|
|
||||||
|
#define ABSOLUTE_PLAYER_LIMIT 255 // not 256, so we can send the limit as a byte
|
||||||
|
|
||||||
struct config_category_t
|
struct config_category_t
|
||||||
{
|
{
|
||||||
int name;
|
int name;
|
||||||
@ -162,6 +164,7 @@ private:
|
|||||||
void OnClientDisconnected(int client);
|
void OnClientDisconnected(int client);
|
||||||
void OnServerActivated(int max_clients);
|
void OnServerActivated(int max_clients);
|
||||||
bool OnIdentityRemoval(IdentityToken_t *owner);
|
bool OnIdentityRemoval(IdentityToken_t *owner);
|
||||||
|
void OnMaxPlayersChanged(int newvalue);
|
||||||
private:
|
private:
|
||||||
config_root_t m_Config; /* Configuration from file */
|
config_root_t m_Config; /* Configuration from file */
|
||||||
topmenu_player_t *m_clients; /* Client array */
|
topmenu_player_t *m_clients; /* Client array */
|
||||||
|
@ -117,3 +117,13 @@ void TopMenuManager::DestroyTopMenu(ITopMenu *topmenu)
|
|||||||
|
|
||||||
delete pMenu;
|
delete pMenu;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TopMenuManager::OnMaxPlayersChanged( int newvalue )
|
||||||
|
{
|
||||||
|
List<TopMenu *>::iterator iter;
|
||||||
|
|
||||||
|
for (iter = m_TopMenus.begin(); iter != m_TopMenus.end(); iter++)
|
||||||
|
{
|
||||||
|
(*iter)->OnMaxPlayersChanged(newvalue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -58,6 +58,7 @@ public:
|
|||||||
void OnClientDisconnected(int client);
|
void OnClientDisconnected(int client);
|
||||||
void OnServerActivated(int max_clients);
|
void OnServerActivated(int max_clients);
|
||||||
void OnPluginUnloaded(IPlugin *plugin);
|
void OnPluginUnloaded(IPlugin *plugin);
|
||||||
|
void OnMaxPlayersChanged(int newvalue);
|
||||||
private:
|
private:
|
||||||
List<TopMenu *> m_TopMenus;
|
List<TopMenu *> m_TopMenus;
|
||||||
};
|
};
|
||||||
|
@ -41,7 +41,7 @@
|
|||||||
#include <IAdminSystem.h>
|
#include <IAdminSystem.h>
|
||||||
|
|
||||||
#define SMINTERFACE_PLAYERMANAGER_NAME "IPlayerManager"
|
#define SMINTERFACE_PLAYERMANAGER_NAME "IPlayerManager"
|
||||||
#define SMINTERFACE_PLAYERMANAGER_VERSION 7
|
#define SMINTERFACE_PLAYERMANAGER_VERSION 8
|
||||||
|
|
||||||
struct edict_t;
|
struct edict_t;
|
||||||
class IPlayerInfo;
|
class IPlayerInfo;
|
||||||
@ -301,6 +301,15 @@ namespace SourceMod
|
|||||||
virtual void OnClientPostAdminCheck(int client)
|
virtual void OnClientPostAdminCheck(int client)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Notifies the extension that the maxplayers value has changed
|
||||||
|
*
|
||||||
|
* @param newvalue New maxplayers value.
|
||||||
|
*/
|
||||||
|
virtual void OnMaxPlayersChanged(int newvalue)
|
||||||
|
{
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#define COMMAND_FILTER_ALIVE (1<<0) /**< Only allow alive players */
|
#define COMMAND_FILTER_ALIVE (1<<0) /**< Only allow alive players */
|
||||||
|
Loading…
Reference in New Issue
Block a user