Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f5933d181e | ||
|
|
246aa90f4d |
@@ -30,7 +30,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "PlayerManager.h"
|
#include "PlayerManager.h"
|
||||||
#include "sourcemod.h"
|
|
||||||
#include "IAdminSystem.h"
|
#include "IAdminSystem.h"
|
||||||
#include "ConCmdManager.h"
|
#include "ConCmdManager.h"
|
||||||
#include "MenuStyle_Valve.h"
|
#include "MenuStyle_Valve.h"
|
||||||
@@ -93,12 +92,6 @@ SH_DECL_EXTERN1_void(ConCommand, Dispatch, SH_NOATTRIB, false, const CCommand &)
|
|||||||
#else
|
#else
|
||||||
SH_DECL_EXTERN0_void(ConCommand, Dispatch, SH_NOATTRIB, false);
|
SH_DECL_EXTERN0_void(ConCommand, Dispatch, SH_NOATTRIB, false);
|
||||||
#endif
|
#endif
|
||||||
SH_DECL_HOOK2_void(IVEngineServer, ClientPrintf, SH_NOATTRIB, 0, edict_t *, const char *);
|
|
||||||
|
|
||||||
static void PrintfBuffer_FrameAction(void *data)
|
|
||||||
{
|
|
||||||
g_Players.OnPrintfFrameAction(reinterpret_cast<unsigned int>(data));
|
|
||||||
}
|
|
||||||
|
|
||||||
ConCommand *maxplayersCmd = NULL;
|
ConCommand *maxplayersCmd = NULL;
|
||||||
|
|
||||||
@@ -179,7 +172,6 @@ void PlayerManager::OnSourceModAllInitialized()
|
|||||||
#elif SOURCE_ENGINE > SE_EYE // 2013/orangebox, but not original orangebox.
|
#elif SOURCE_ENGINE > SE_EYE // 2013/orangebox, but not original orangebox.
|
||||||
SH_ADD_HOOK(IServerGameDLL, SetServerHibernation, gamedll, SH_MEMBER(this, &PlayerManager::OnServerHibernationUpdate), true);
|
SH_ADD_HOOK(IServerGameDLL, SetServerHibernation, gamedll, SH_MEMBER(this, &PlayerManager::OnServerHibernationUpdate), true);
|
||||||
#endif
|
#endif
|
||||||
SH_ADD_HOOK(IVEngineServer, ClientPrintf, engine, SH_MEMBER(this, &PlayerManager::OnClientPrintf), false);
|
|
||||||
|
|
||||||
sharesys->AddInterface(NULL, this);
|
sharesys->AddInterface(NULL, this);
|
||||||
|
|
||||||
@@ -233,7 +225,6 @@ void PlayerManager::OnSourceModShutdown()
|
|||||||
#elif SOURCE_ENGINE > SE_EYE // 2013/orangebox, but not original orangebox.
|
#elif SOURCE_ENGINE > SE_EYE // 2013/orangebox, but not original orangebox.
|
||||||
SH_REMOVE_HOOK(IServerGameDLL, SetServerHibernation, gamedll, SH_MEMBER(this, &PlayerManager::OnServerHibernationUpdate), true);
|
SH_REMOVE_HOOK(IServerGameDLL, SetServerHibernation, gamedll, SH_MEMBER(this, &PlayerManager::OnServerHibernationUpdate), true);
|
||||||
#endif
|
#endif
|
||||||
SH_REMOVE_HOOK(IVEngineServer, ClientPrintf, engine, SH_MEMBER(this, &PlayerManager::OnClientPrintf), false);
|
|
||||||
|
|
||||||
/* Release forwards */
|
/* Release forwards */
|
||||||
forwardsys->ReleaseForward(m_clconnect);
|
forwardsys->ReleaseForward(m_clconnect);
|
||||||
@@ -855,88 +846,6 @@ void PlayerManager::OnClientDisconnect_Post(edict_t *pEntity)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlayerManager::OnClientPrintf(edict_t *pEdict, const char *szMsg)
|
|
||||||
{
|
|
||||||
int client = IndexOfEdict(pEdict);
|
|
||||||
|
|
||||||
CPlayer &player = m_Players[client];
|
|
||||||
if (!player.IsConnected())
|
|
||||||
RETURN_META(MRES_IGNORED);
|
|
||||||
|
|
||||||
INetChannel *pNetChan = static_cast<INetChannel *>(engine->GetPlayerNetInfo(client));
|
|
||||||
if (pNetChan == NULL)
|
|
||||||
RETURN_META(MRES_IGNORED);
|
|
||||||
|
|
||||||
size_t nMsgLen = strlen(szMsg);
|
|
||||||
#if SOURCE_ENGINE == SE_EPISODEONE
|
|
||||||
static const int nNumBitsWritten = 0;
|
|
||||||
#else
|
|
||||||
int nNumBitsWritten = pNetChan->GetNumBitsWritten(false); // SVC_Print uses unreliable netchan
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// if the msg is bigger than allowed then just let it fail
|
|
||||||
if (nMsgLen + 1 >= SVC_Print_BufferSize) // +1 for NETMSG_TYPE_BITS
|
|
||||||
RETURN_META(MRES_IGNORED);
|
|
||||||
|
|
||||||
// enqueue msgs if we'd overflow the SVC_Print buffer (+7 as ceil)
|
|
||||||
if (!player.m_PrintfBuffer.empty() || (nNumBitsWritten + NETMSG_TYPE_BITS + 7) / 8 + nMsgLen >= SVC_Print_BufferSize)
|
|
||||||
{
|
|
||||||
// Don't send any more messages for this player until the buffer is empty.
|
|
||||||
// Queue up a gameframe hook to empty the buffer (if we haven't already)
|
|
||||||
if (player.m_PrintfBuffer.empty())
|
|
||||||
g_SourceMod.AddFrameAction(PrintfBuffer_FrameAction, (void *)(uintptr_t)player.GetSerial());
|
|
||||||
|
|
||||||
player.m_PrintfBuffer.append(szMsg);
|
|
||||||
|
|
||||||
RETURN_META(MRES_SUPERCEDE);
|
|
||||||
}
|
|
||||||
|
|
||||||
RETURN_META(MRES_IGNORED);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PlayerManager::OnPrintfFrameAction(unsigned int serial)
|
|
||||||
{
|
|
||||||
int client = GetClientFromSerial(serial);
|
|
||||||
CPlayer &player = m_Players[client];
|
|
||||||
if (!player.IsConnected())
|
|
||||||
{
|
|
||||||
player.ClearNetchannelQueue();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
INetChannel *pNetChan = static_cast<INetChannel *>(engine->GetPlayerNetInfo(client));
|
|
||||||
if (pNetChan == NULL)
|
|
||||||
{
|
|
||||||
player.ClearNetchannelQueue();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (!player.m_PrintfBuffer.empty())
|
|
||||||
{
|
|
||||||
#if SOURCE_ENGINE == SE_EPISODEONE
|
|
||||||
static const int nNumBitsWritten = 0;
|
|
||||||
#else
|
|
||||||
int nNumBitsWritten = pNetChan->GetNumBitsWritten(false); // SVC_Print uses unreliable netchan
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ke::AString &string = player.m_PrintfBuffer.front();
|
|
||||||
|
|
||||||
// stop if we'd overflow the SVC_Print buffer (+7 as ceil)
|
|
||||||
if ((nNumBitsWritten + NETMSG_TYPE_BITS + 7) / 8 + string.length() >= SVC_Print_BufferSize)
|
|
||||||
break;
|
|
||||||
|
|
||||||
SH_CALL(engine, &IVEngineServer::ClientPrintf)(player.m_pEdict, string.chars());
|
|
||||||
|
|
||||||
player.m_PrintfBuffer.popFront();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!player.m_PrintfBuffer.empty())
|
|
||||||
{
|
|
||||||
// continue processing it on the next gameframe as buffer is not empty
|
|
||||||
g_SourceMod.AddFrameAction(PrintfBuffer_FrameAction, (void *)(uintptr_t)player.GetSerial());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClientConsolePrint(edict_t *e, const char *fmt, ...)
|
void ClientConsolePrint(edict_t *e, const char *fmt, ...)
|
||||||
{
|
{
|
||||||
char buffer[512];
|
char buffer[512];
|
||||||
@@ -2236,13 +2145,6 @@ void CPlayer::Disconnect()
|
|||||||
#if SOURCE_ENGINE == SE_CSGO
|
#if SOURCE_ENGINE == SE_CSGO
|
||||||
m_LanguageCookie = InvalidQueryCvarCookie;
|
m_LanguageCookie = InvalidQueryCvarCookie;
|
||||||
#endif
|
#endif
|
||||||
ClearNetchannelQueue();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CPlayer::ClearNetchannelQueue(void)
|
|
||||||
{
|
|
||||||
while (!m_PrintfBuffer.empty())
|
|
||||||
m_PrintfBuffer.popFront();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPlayer::SetName(const char *name)
|
void CPlayer::SetName(const char *name)
|
||||||
|
|||||||
@@ -43,7 +43,6 @@
|
|||||||
#include <sh_list.h>
|
#include <sh_list.h>
|
||||||
#include <sh_vector.h>
|
#include <sh_vector.h>
|
||||||
#include <am-string.h>
|
#include <am-string.h>
|
||||||
#include <am-deque.h>
|
|
||||||
#include "ConVarManager.h"
|
#include "ConVarManager.h"
|
||||||
|
|
||||||
#include <steam/steamclientpublic.h>
|
#include <steam/steamclientpublic.h>
|
||||||
@@ -124,7 +123,6 @@ private:
|
|||||||
bool IsAuthStringValidated();
|
bool IsAuthStringValidated();
|
||||||
bool SetEngineString();
|
bool SetEngineString();
|
||||||
bool SetCSteamID();
|
bool SetCSteamID();
|
||||||
void ClearNetchannelQueue(void);
|
|
||||||
private:
|
private:
|
||||||
bool m_IsConnected = false;
|
bool m_IsConnected = false;
|
||||||
bool m_IsInGame = false;
|
bool m_IsInGame = false;
|
||||||
@@ -154,7 +152,6 @@ private:
|
|||||||
#if SOURCE_ENGINE == SE_CSGO
|
#if SOURCE_ENGINE == SE_CSGO
|
||||||
QueryCvarCookie_t m_LanguageCookie = InvalidQueryCvarCookie;
|
QueryCvarCookie_t m_LanguageCookie = InvalidQueryCvarCookie;
|
||||||
#endif
|
#endif
|
||||||
ke::Deque<ke::AString> m_PrintfBuffer;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class PlayerManager :
|
class PlayerManager :
|
||||||
@@ -193,8 +190,6 @@ public:
|
|||||||
void OnClientSettingsChanged(edict_t *pEntity);
|
void OnClientSettingsChanged(edict_t *pEntity);
|
||||||
//void OnClientSettingsChanged_Pre(edict_t *pEntity);
|
//void OnClientSettingsChanged_Pre(edict_t *pEntity);
|
||||||
void OnServerHibernationUpdate(bool bHibernating);
|
void OnServerHibernationUpdate(bool bHibernating);
|
||||||
void OnClientPrintf(edict_t *pEdict, const char *szMsg);
|
|
||||||
void OnPrintfFrameAction(unsigned int serial);
|
|
||||||
public: //IPlayerManager
|
public: //IPlayerManager
|
||||||
void AddClientListener(IClientListener *listener);
|
void AddClientListener(IClientListener *listener);
|
||||||
void RemoveClientListener(IClientListener *listener);
|
void RemoveClientListener(IClientListener *listener);
|
||||||
@@ -272,9 +267,6 @@ private:
|
|||||||
int m_SourceTVUserId;
|
int m_SourceTVUserId;
|
||||||
int m_ReplayUserId;
|
int m_ReplayUserId;
|
||||||
bool m_bInCCKVHook;
|
bool m_bInCCKVHook;
|
||||||
private:
|
|
||||||
static const int NETMSG_TYPE_BITS = 5; // SVC_Print overhead for netmsg type
|
|
||||||
static const int SVC_Print_BufferSize = 2048 - 1; // -1 for terminating \0
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#if SOURCE_ENGINE >= SE_ORANGEBOX
|
#if SOURCE_ENGINE >= SE_ORANGEBOX
|
||||||
|
|||||||
@@ -112,6 +112,7 @@ IServerTools *servertools = NULL;
|
|||||||
|
|
||||||
// global hooks and forwards
|
// global hooks and forwards
|
||||||
IForward *g_pOnEntityCreated = NULL;
|
IForward *g_pOnEntityCreated = NULL;
|
||||||
|
IForward *g_pOnEntitySpawned = NULL;
|
||||||
IForward *g_pOnEntityDestroyed = NULL;
|
IForward *g_pOnEntityDestroyed = NULL;
|
||||||
|
|
||||||
#ifdef GAMEDESC_CAN_CHANGE
|
#ifdef GAMEDESC_CAN_CHANGE
|
||||||
@@ -252,6 +253,7 @@ bool SDKHooks::SDK_OnLoad(char *error, size_t maxlength, bool late)
|
|||||||
plsys->AddPluginsListener(&g_Interface);
|
plsys->AddPluginsListener(&g_Interface);
|
||||||
|
|
||||||
g_pOnEntityCreated = forwards->CreateForward("OnEntityCreated", ET_Ignore, 2, NULL, Param_Cell, Param_String);
|
g_pOnEntityCreated = forwards->CreateForward("OnEntityCreated", ET_Ignore, 2, NULL, Param_Cell, Param_String);
|
||||||
|
g_pOnEntitySpawned = forwards->CreateForward("OnEntitySpawned", ET_Ignore, 2, NULL, Param_Cell, Param_String);
|
||||||
g_pOnEntityDestroyed = forwards->CreateForward("OnEntityDestroyed", ET_Ignore, 1, NULL, Param_Cell);
|
g_pOnEntityDestroyed = forwards->CreateForward("OnEntityDestroyed", ET_Ignore, 1, NULL, Param_Cell);
|
||||||
#ifdef GAMEDESC_CAN_CHANGE
|
#ifdef GAMEDESC_CAN_CHANGE
|
||||||
g_pOnGetGameNameDescription = forwards->CreateForward("OnGetGameDescription", ET_Hook, 2, NULL, Param_String);
|
g_pOnGetGameNameDescription = forwards->CreateForward("OnGetGameDescription", ET_Hook, 2, NULL, Param_String);
|
||||||
@@ -344,6 +346,7 @@ void SDKHooks::SDK_OnUnload()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
forwards->ReleaseForward(g_pOnEntityCreated);
|
forwards->ReleaseForward(g_pOnEntityCreated);
|
||||||
|
forwards->ReleaseForward(g_pOnEntitySpawned);
|
||||||
forwards->ReleaseForward(g_pOnEntityDestroyed);
|
forwards->ReleaseForward(g_pOnEntityDestroyed);
|
||||||
#ifdef GAMEDESC_CAN_CHANGE
|
#ifdef GAMEDESC_CAN_CHANGE
|
||||||
forwards->ReleaseForward(g_pOnGetGameNameDescription);
|
forwards->ReleaseForward(g_pOnGetGameNameDescription);
|
||||||
@@ -420,6 +423,7 @@ void SDKHooks::OnClientPutInServer(int client)
|
|||||||
CBaseEntity *pPlayer = gamehelpers->ReferenceToEntity(client);
|
CBaseEntity *pPlayer = gamehelpers->ReferenceToEntity(client);
|
||||||
|
|
||||||
HandleEntityCreated(pPlayer, client, gamehelpers->EntityToReference(pPlayer));
|
HandleEntityCreated(pPlayer, client, gamehelpers->EntityToReference(pPlayer));
|
||||||
|
HandleEntitySpawned(pPlayer, client, gamehelpers->EntityToReference(pPlayer));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SDKHooks::OnClientDisconnecting(int client)
|
void SDKHooks::OnClientDisconnecting(int client)
|
||||||
@@ -879,6 +883,27 @@ void SDKHooks::OnEntityCreated(CBaseEntity *pEntity)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SDKHooks::OnEntitySpawned(CBaseEntity *pEntity)
|
||||||
|
{
|
||||||
|
// Call OnEntitySpawned forward
|
||||||
|
int ref = gamehelpers->EntityToReference(pEntity);
|
||||||
|
int index = gamehelpers->ReferenceToIndex(ref);
|
||||||
|
|
||||||
|
// This can be -1 for player ents before any players have connected
|
||||||
|
if ((unsigned)index == INVALID_EHANDLE_INDEX || (index > 0 && index <= playerhelpers->GetMaxClients()))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!IsEntityIndexInRange(index))
|
||||||
|
{
|
||||||
|
g_pSM->LogError(myself, "SDKHooks::OnEntitySpawned - Got entity index out of range (%d)", index);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
HandleEntitySpawned(pEntity, index, ref);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef GAMEDESC_CAN_CHANGE
|
#ifdef GAMEDESC_CAN_CHANGE
|
||||||
const char *SDKHooks::Hook_GetGameDescription()
|
const char *SDKHooks::Hook_GetGameDescription()
|
||||||
{
|
{
|
||||||
@@ -1791,6 +1816,32 @@ void SDKHooks::HandleEntityCreated(CBaseEntity *pEntity, int index, cell_t ref)
|
|||||||
m_EntityCache[index] = ref;
|
m_EntityCache[index] = ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SDKHooks::HandleEntitySpawned(CBaseEntity *pEntity, int index, cell_t ref)
|
||||||
|
{
|
||||||
|
if (g_pOnEntitySpawned->GetFunctionCount() || m_EntListeners.size())
|
||||||
|
{
|
||||||
|
cell_t bcompatRef = gamehelpers->EntityToBCompatRef(pEntity);
|
||||||
|
const char *pName = gamehelpers->GetEntityClassname(pEntity);
|
||||||
|
if (!pName)
|
||||||
|
pName = "";
|
||||||
|
|
||||||
|
// Send OnEntitySpawned to SM listeners
|
||||||
|
for (SourceHook::List<ISMEntityListener *>::iterator iter = m_EntListeners.begin(); iter != m_EntListeners.end(); iter++)
|
||||||
|
{
|
||||||
|
ISMEntityListener *pListener = (*iter);
|
||||||
|
pListener->OnEntitySpawned(pEntity, pName);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call OnEntitySpawned forward
|
||||||
|
if (g_pOnEntitySpawned->GetFunctionCount())
|
||||||
|
{
|
||||||
|
g_pOnEntitySpawned->PushCell(bcompatRef);
|
||||||
|
g_pOnEntitySpawned->PushString(pName);
|
||||||
|
g_pOnEntitySpawned->Execute(NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void SDKHooks::HandleEntityDeleted(CBaseEntity *pEntity)
|
void SDKHooks::HandleEntityDeleted(CBaseEntity *pEntity)
|
||||||
{
|
{
|
||||||
cell_t bcompatRef = gamehelpers->EntityToBCompatRef(pEntity);
|
cell_t bcompatRef = gamehelpers->EntityToBCompatRef(pEntity);
|
||||||
|
|||||||
@@ -238,6 +238,7 @@ public: // IFeatureProvider
|
|||||||
|
|
||||||
public: // IEntityListener
|
public: // IEntityListener
|
||||||
virtual void OnEntityCreated(CBaseEntity *pEntity);
|
virtual void OnEntityCreated(CBaseEntity *pEntity);
|
||||||
|
virtual void OnEntitySpawned(CBaseEntity *pEntity);
|
||||||
virtual void OnEntityDeleted(CBaseEntity *pEntity);
|
virtual void OnEntityDeleted(CBaseEntity *pEntity);
|
||||||
|
|
||||||
public: // IClientListener
|
public: // IClientListener
|
||||||
@@ -330,6 +331,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void HandleEntityCreated(CBaseEntity *pEntity, int index, cell_t ref);
|
void HandleEntityCreated(CBaseEntity *pEntity, int index, cell_t ref);
|
||||||
|
void HandleEntitySpawned(CBaseEntity *pEntity, int index, cell_t ref);
|
||||||
void HandleEntityDeleted(CBaseEntity *pEntity);
|
void HandleEntityDeleted(CBaseEntity *pEntity);
|
||||||
void Unhook(CBaseEntity *pEntity);
|
void Unhook(CBaseEntity *pEntity);
|
||||||
void Unhook(IPluginContext *pContext);
|
void Unhook(IPluginContext *pContext);
|
||||||
|
|||||||
@@ -333,6 +333,14 @@ typeset SDKHookCB
|
|||||||
*/
|
*/
|
||||||
forward void OnEntityCreated(int entity, const char[] classname);
|
forward void OnEntityCreated(int entity, const char[] classname);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When an entity is spawned
|
||||||
|
*
|
||||||
|
* @param entity Entity index
|
||||||
|
* @param classname Class name
|
||||||
|
*/
|
||||||
|
forward void OnEntitySpawned(int entity, const char[] classname);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When an entity is destroyed
|
* When an entity is destroyed
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -36,7 +36,7 @@
|
|||||||
#include <IShareSys.h>
|
#include <IShareSys.h>
|
||||||
|
|
||||||
#define SMINTERFACE_SDKHOOKS_NAME "ISDKHooks"
|
#define SMINTERFACE_SDKHOOKS_NAME "ISDKHooks"
|
||||||
#define SMINTERFACE_SDKHOOKS_VERSION 1
|
#define SMINTERFACE_SDKHOOKS_VERSION 2
|
||||||
|
|
||||||
class CBaseEntity;
|
class CBaseEntity;
|
||||||
|
|
||||||
@@ -71,6 +71,16 @@ namespace SourceMod
|
|||||||
virtual void OnEntityDestroyed(CBaseEntity *pEntity)
|
virtual void OnEntityDestroyed(CBaseEntity *pEntity)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief When an entity is spawned
|
||||||
|
*
|
||||||
|
* @param pEntity CBaseEntity entity.
|
||||||
|
* @param classname Entity classname.
|
||||||
|
*/
|
||||||
|
virtual void OnEntitySpawned(CBaseEntity *pEntity, const char *classname)
|
||||||
|
{
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user