Add sv_multiplayer_maxtempentities support

This commit is contained in:
maxime1907
2021-07-13 04:46:09 +02:00
parent 5f6b07205f
commit 8af19144f5
3 changed files with 224 additions and 219 deletions
+5
View File
@@ -31,6 +31,11 @@ CopyFiles('addons/sourcemod/gamedata', 'addons/sourcemod/gamedata',
[ 'ssf.games.txt' ] [ 'ssf.games.txt' ]
) )
# AutoLoad
CopyFiles('addons/sourcemod/extensions', 'addons/sourcemod/extensions',
[ 'sendsnapshotfixer.autoload' ]
)
# Copy binaries. # Copy binaries.
for cxx_task in Extension.extensions: for cxx_task in Extension.extensions:
builder.AddCopy(cxx_task.binary, folder_map['addons/sourcemod/extensions']) builder.AddCopy(cxx_task.binary, folder_map['addons/sourcemod/extensions'])
+238 -238
View File
@@ -42,153 +42,153 @@
class CFrameSnapshot; class CFrameSnapshot;
class CClientFrame; class CClientFrame;
#define NETMSG_TYPE_BITS 6 // must be 2^NETMSG_TYPE_BITS > SVC_LASTMSG // #define NETMSG_TYPE_BITS 6 // must be 2^NETMSG_TYPE_BITS > SVC_LASTMSG
#define NET_MAX_PAYLOAD 4000 // #define NET_MAX_PAYLOAD 4000
#define svc_Sounds 17 // starts playing sound // #define svc_Sounds 17 // starts playing sound
#define DECLARE_BASE_MESSAGE( msgtype ) \ // #define DECLARE_BASE_MESSAGE( msgtype ) \
public: \ // public: \
bool ReadFromBuffer( bf_read &buffer ); \ // bool ReadFromBuffer( bf_read &buffer ); \
bool WriteToBuffer( bf_write &buffer ); \ // bool WriteToBuffer( bf_write &buffer ); \
const char *ToString() const; \ // const char *ToString() const; \
int GetType() const { return msgtype; } \ // int GetType() const { return msgtype; } \
const char *GetName() const { return #msgtype;}\ // const char *GetName() const { return #msgtype;}\
#define DECLARE_SVC_MESSAGE( name ) \ // #define DECLARE_SVC_MESSAGE( name ) \
DECLARE_BASE_MESSAGE( svc_##name ); \ // DECLARE_BASE_MESSAGE( svc_##name ); \
IServerMessageHandler *m_pMessageHandler;\ // IServerMessageHandler *m_pMessageHandler;\
bool Process() { return m_pMessageHandler->Process##name( this ); }\ // bool Process() { return m_pMessageHandler->Process##name( this ); }\
class INetChannelInfo // class INetChannelInfo
{ // {
public: // public:
enum { // enum {
GENERIC = 0, // must be first and is default group // GENERIC = 0, // must be first and is default group
LOCALPLAYER, // bytes for local player entity update // LOCALPLAYER, // bytes for local player entity update
OTHERPLAYERS, // bytes for other players update // OTHERPLAYERS, // bytes for other players update
ENTITIES, // all other entity bytes // ENTITIES, // all other entity bytes
SOUNDS, // game sounds // SOUNDS, // game sounds
EVENTS, // event messages // EVENTS, // event messages
USERMESSAGES, // user messages // USERMESSAGES, // user messages
ENTMESSAGES, // entity messages // ENTMESSAGES, // entity messages
VOICE, // voice data // VOICE, // voice data
STRINGTABLE, // a stringtable update // STRINGTABLE, // a stringtable update
MOVE, // client move cmds // MOVE, // client move cmds
STRINGCMD, // string command // STRINGCMD, // string command
SIGNON, // various signondata // SIGNON, // various signondata
TOTAL, // must be last and is not a real group // TOTAL, // must be last and is not a real group
}; // };
}; // };
class INetMessage // class INetMessage
{ // {
public: // public:
virtual ~INetMessage() {}; // virtual ~INetMessage() {};
// Use these to setup who can hear whose voice. // // Use these to setup who can hear whose voice.
// Pass in client indices (which are their ent indices - 1). // // Pass in client indices (which are their ent indices - 1).
virtual void SetNetChannel(INetChannel * netchan) = 0; // netchannel this message is from/for // virtual void SetNetChannel(INetChannel * netchan) = 0; // netchannel this message is from/for
virtual void SetReliable( bool state ) = 0; // set to true if it's a reliable message // virtual void SetReliable( bool state ) = 0; // set to true if it's a reliable message
virtual bool Process( void ) = 0; // calles the recently set handler to process this message // virtual bool Process( void ) = 0; // calles the recently set handler to process this message
virtual bool ReadFromBuffer( bf_read &buffer ) = 0; // returns true if parsing was OK // virtual bool ReadFromBuffer( bf_read &buffer ) = 0; // returns true if parsing was OK
virtual bool WriteToBuffer( bf_write &buffer ) = 0; // returns true if writing was OK // virtual bool WriteToBuffer( bf_write &buffer ) = 0; // returns true if writing was OK
virtual bool IsReliable( void ) const = 0; // true, if message needs reliable handling // virtual bool IsReliable( void ) const = 0; // true, if message needs reliable handling
virtual int GetType( void ) const = 0; // returns module specific header tag eg svc_serverinfo // virtual int GetType( void ) const = 0; // returns module specific header tag eg svc_serverinfo
virtual int GetGroup( void ) const = 0; // returns net message group of this message // virtual int GetGroup( void ) const = 0; // returns net message group of this message
virtual const char *GetName( void ) const = 0; // returns network message name, eg "svc_serverinfo" // virtual const char *GetName( void ) const = 0; // returns network message name, eg "svc_serverinfo"
virtual INetChannel *GetNetChannel( void ) const = 0; // virtual INetChannel *GetNetChannel( void ) const = 0;
virtual const char *ToString( void ) const = 0; // returns a human readable string about message content // virtual const char *ToString( void ) const = 0; // returns a human readable string about message content
}; // };
class CNetMessage : public INetMessage // class CNetMessage : public INetMessage
{ // {
public: // public:
CNetMessage() { m_bReliable = true; // CNetMessage() { m_bReliable = true;
m_NetChannel = NULL; } // m_NetChannel = NULL; }
virtual ~CNetMessage() {}; // virtual ~CNetMessage() {};
virtual int GetGroup() const { return INetChannelInfo::GENERIC; } // virtual int GetGroup() const { return INetChannelInfo::GENERIC; }
INetChannel *GetNetChannel() const { return m_NetChannel; } // INetChannel *GetNetChannel() const { return m_NetChannel; }
virtual void SetReliable( bool state) {m_bReliable = state;}; // virtual void SetReliable( bool state) {m_bReliable = state;};
virtual bool IsReliable() const { return m_bReliable; }; // virtual bool IsReliable() const { return m_bReliable; };
virtual void SetNetChannel(INetChannel * netchan) { m_NetChannel = netchan; } // virtual void SetNetChannel(INetChannel * netchan) { m_NetChannel = netchan; }
virtual bool Process() { Assert( 0 ); return false; }; // no handler set // virtual bool Process() { Assert( 0 ); return false; }; // no handler set
protected: // protected:
bool m_bReliable; // true if message should be send reliable // bool m_bReliable; // true if message should be send reliable
INetChannel *m_NetChannel; // netchannel this message is from/for // INetChannel *m_NetChannel; // netchannel this message is from/for
}; // };
class SVC_Sounds : public CNetMessage // class SVC_Sounds : public CNetMessage
{ // {
DECLARE_SVC_MESSAGE( Sounds ); // DECLARE_SVC_MESSAGE( Sounds );
int GetGroup() const { return INetChannelInfo::SOUNDS; } // int GetGroup() const { return INetChannelInfo::SOUNDS; }
SVC_Sounds() : CNetMessage() // SVC_Sounds() : CNetMessage()
{ // {
} // }
~SVC_Sounds() // ~SVC_Sounds()
{ // {
} // }
public: // public:
bool m_bReliableSound; // bool m_bReliableSound;
int m_nNumSounds; // int m_nNumSounds;
int m_nLength; // int m_nLength;
bf_read m_DataIn; // bf_read m_DataIn;
bf_write m_DataOut; // bf_write m_DataOut;
}; // };
class CBaseClient : public IGameEventListener2, public IClient class CBaseClient : public IGameEventListener2, public IClient
{ {
}; };
class CGameClient: public CBaseClient // class CGameClient: public CBaseClient
{ // {
public: // public:
CUtlVector<SoundInfo_t> m_Sounds; // game sounds // CUtlVector<SoundInfo_t> m_Sounds; // game sounds
}; // };
bool SVC_Sounds::WriteToBuffer( bf_write &buffer ) // bool SVC_Sounds::WriteToBuffer( bf_write &buffer )
{ // {
m_nLength = m_DataOut.GetNumBitsWritten(); // m_nLength = m_DataOut.GetNumBitsWritten();
buffer.WriteUBitLong( GetType(), NETMSG_TYPE_BITS ); // buffer.WriteUBitLong( GetType(), NETMSG_TYPE_BITS );
Assert( m_nNumSounds > 0 ); // Assert( m_nNumSounds > 0 );
if ( m_bReliableSound ) // if ( m_bReliableSound )
{ // {
// as single sound message is 32 bytes long maximum // // as single sound message is 32 bytes long maximum
buffer.WriteOneBit( 1 ); // buffer.WriteOneBit( 1 );
buffer.WriteUBitLong( m_nLength, 8 ); // buffer.WriteUBitLong( m_nLength, 8 );
} // }
else // else
{ // {
// a bunch of unreliable messages // // a bunch of unreliable messages
buffer.WriteOneBit( 0 ); // buffer.WriteOneBit( 0 );
buffer.WriteUBitLong( m_nNumSounds, 8 ); // buffer.WriteUBitLong( m_nNumSounds, 8 );
buffer.WriteUBitLong( m_nLength, 16 ); // buffer.WriteUBitLong( m_nLength, 16 );
} // }
return buffer.WriteBits( m_DataOut.GetData(), m_nLength ); // return buffer.WriteBits( m_DataOut.GetData(), m_nLength );
} // }
SSF g_SSF; /**< Global singleton for extension's main interface */ SSF g_SSF; /**< Global singleton for extension's main interface */
@@ -199,116 +199,116 @@ CGlobalVars *gpGlobals = NULL;
CDetour *g_Detour_CBaseClient__SendSnapshot = NULL; CDetour *g_Detour_CBaseClient__SendSnapshot = NULL;
CDetour *g_Detour_CBaseServer__WriteTempEntities = NULL; CDetour *g_Detour_CBaseServer__WriteTempEntities = NULL;
CDetour *g_Detour_CGameClient__FillSoundsMessage = NULL; // CDetour *g_Detour_CGameClient__FillSoundsMessage = NULL;
CDetour *g_Detour_CGameClient__WriteGameSounds = NULL; // CDetour *g_Detour_CGameClient__WriteGameSounds = NULL;
ConVar *g_SvSSFLog = CreateConVar("sv_ssf_log", "0", FCVAR_NOTIFY, "Log ssf debug print statements."); ConVar *g_SvSSFLog = CreateConVar("sv_ssf_log", "0", FCVAR_NOTIFY, "Log ssf debug print statements.");
ConVar *g_sv_multiplayer_maxtempentities = CreateConVar("sv_multiplayer_maxtempentities", "64"); ConVar *g_sv_multiplayer_maxtempentities = CreateConVar("sv_multiplayer_maxtempentities", "64");
ConVar *g_sv_multiplayer_maxsounds = CreateConVar("sv_multiplayer_sounds", "32"); // ConVar *g_sv_multiplayer_maxsounds = CreateConVar("sv_multiplayer_sounds", "32");
ConVar *g_sv_sound_discardextraunreliable = CreateConVar( "sv_sound_discardextraunreliable", "1" ); // ConVar *g_sv_sound_discardextraunreliable = CreateConVar( "sv_sound_discardextraunreliable", "1" );
int Custom_CGameClient__FillSoundsMessage(CGameClient *pGameClient, SVC_Sounds &msg) // int Custom_CGameClient__FillSoundsMessage(CGameClient *pGameClient, SVC_Sounds &msg)
{
int nMaxSounds = pGameClient->GetServer()->IsMultiplayer() ? g_sv_multiplayer_maxsounds->GetInt() : 255;
int i, count = pGameClient->m_Sounds.Count();
if (g_SvSSFLog->GetBool())
{
g_pSM->LogMessage(myself, "SSF:CGameClient__FillSoundsMessage maxsounds before: %d, count: %d", nMaxSounds, pGameClient->m_Sounds.Count());
}
// Discard events if we have too many to signal with 8 bits
if ( count > nMaxSounds )
count = nMaxSounds;
// Nothing to send
if ( !count )
return 0;
SoundInfo_t defaultSound; defaultSound.SetDefault();
SoundInfo_t *pDeltaSound = &defaultSound;
msg.m_nNumSounds = count;
msg.m_bReliableSound = false;
msg.SetReliable( false );
if (g_SvSSFLog->GetBool())
{
g_pSM->LogMessage(myself, "SSF:CGameClient__FillSoundsMessage getnumbitsleft: %d", msg.m_DataOut.GetNumBitsLeft());
}
Assert( msg.m_DataOut.GetNumBitsLeft() > 0 );
for ( i = 0 ; i < count; i++ )
{
SoundInfo_t &sound = pGameClient->m_Sounds[ i ];
sound.WriteDelta( pDeltaSound, msg.m_DataOut );
pDeltaSound = &pGameClient->m_Sounds[ i ];
}
// remove added events from list
if ( g_sv_sound_discardextraunreliable->GetBool() )
{
if ( pGameClient->m_Sounds.Count() != count )
{
DevMsg( 2, "Warning! Dropped %i unreliable sounds for client %s.\n" , pGameClient->m_Sounds.Count() - count, pGameClient->GetClientName() );
}
pGameClient->m_Sounds.RemoveAll();
}
else
{
int remove = pGameClient->m_Sounds.Count() - ( count + nMaxSounds );
if ( remove > 0 )
{
DevMsg( 2, "Warning! Dropped %i unreliable sounds for client %s.\n" , remove, pGameClient->GetClientName() );
count+= remove;
}
if ( count > 0 )
{
pGameClient->m_Sounds.RemoveMultiple( 0, count );
}
}
if (g_SvSSFLog->GetBool())
{
g_pSM->LogMessage(myself, "SSF:CGameClient__FillSoundsMessage maxsounds after: %d count: %d, NumSounds: %d", nMaxSounds, pGameClient->m_Sounds.Count(), msg.m_nNumSounds);
}
Assert( pGameClient->m_Sounds.Count() <= nMaxSounds ); // keep ev_max temp ent for next update
return msg.m_nNumSounds;
}
DETOUR_DECL_MEMBER1(CGameClient__FillSoundsMessage, int, SVC_Sounds &, msg)
{
CGameClient *pGameClient = (CGameClient *)this;
int nResult = Custom_CGameClient__FillSoundsMessage(pGameClient, msg);
RETURN_META_VALUE(MRES_SUPERCEDE, nResult);
}
DETOUR_DECL_MEMBER1(CGameClient__WriteGameSounds, void, bf_write, &buf)
{
CGameClient *pGameClient = (CGameClient *)this;
if ( pGameClient->m_Sounds.Count() <= 0 )
return;
char data[NET_MAX_PAYLOAD];
SVC_Sounds msg;
msg.m_DataOut.StartWriting( data, sizeof(data) );
msg.SetReliable( false );
int nSoundCount = Custom_CGameClient__FillSoundsMessage( pGameClient, msg );
msg.WriteToBuffer( buf );
// if ( pGameClient->IsTracing() )
// { // {
// pGameClient->TraceNetworkData( buf, "Sounds [count=%d]", nSoundCount ); // int nMaxSounds = pGameClient->GetServer()->IsMultiplayer() ? g_sv_multiplayer_maxsounds->GetInt() : 255;
// int i, count = pGameClient->m_Sounds.Count();
// if (g_SvSSFLog->GetBool())
// {
// g_pSM->LogMessage(myself, "SSF:CGameClient__FillSoundsMessage maxsounds before: %d, count: %d", nMaxSounds, pGameClient->m_Sounds.Count());
// }
// // Discard events if we have too many to signal with 8 bits
// if ( count > nMaxSounds )
// count = nMaxSounds;
// // Nothing to send
// if ( !count )
// return 0;
// SoundInfo_t defaultSound; defaultSound.SetDefault();
// SoundInfo_t *pDeltaSound = &defaultSound;
// msg.m_nNumSounds = count;
// msg.m_bReliableSound = false;
// msg.SetReliable( false );
// if (g_SvSSFLog->GetBool())
// {
// g_pSM->LogMessage(myself, "SSF:CGameClient__FillSoundsMessage getnumbitsleft: %d", msg.m_DataOut.GetNumBitsLeft());
// }
// Assert( msg.m_DataOut.GetNumBitsLeft() > 0 );
// for ( i = 0 ; i < count; i++ )
// {
// SoundInfo_t &sound = pGameClient->m_Sounds[ i ];
// sound.WriteDelta( pDeltaSound, msg.m_DataOut );
// pDeltaSound = &pGameClient->m_Sounds[ i ];
// }
// // remove added events from list
// if ( g_sv_sound_discardextraunreliable->GetBool() )
// {
// if ( pGameClient->m_Sounds.Count() != count )
// {
// DevMsg( 2, "Warning! Dropped %i unreliable sounds for client %s.\n" , pGameClient->m_Sounds.Count() - count, pGameClient->GetClientName() );
// }
// pGameClient->m_Sounds.RemoveAll();
// }
// else
// {
// int remove = pGameClient->m_Sounds.Count() - ( count + nMaxSounds );
// if ( remove > 0 )
// {
// DevMsg( 2, "Warning! Dropped %i unreliable sounds for client %s.\n" , remove, pGameClient->GetClientName() );
// count+= remove;
// }
// if ( count > 0 )
// {
// pGameClient->m_Sounds.RemoveMultiple( 0, count );
// }
// }
// if (g_SvSSFLog->GetBool())
// {
// g_pSM->LogMessage(myself, "SSF:CGameClient__FillSoundsMessage maxsounds after: %d count: %d, NumSounds: %d", nMaxSounds, pGameClient->m_Sounds.Count(), msg.m_nNumSounds);
// }
// Assert( pGameClient->m_Sounds.Count() <= nMaxSounds ); // keep ev_max temp ent for next update
// return msg.m_nNumSounds;
// }
// DETOUR_DECL_MEMBER1(CGameClient__FillSoundsMessage, int, SVC_Sounds &, msg)
// {
// CGameClient *pGameClient = (CGameClient *)this;
// int nResult = Custom_CGameClient__FillSoundsMessage(pGameClient, msg);
// RETURN_META_VALUE(MRES_SUPERCEDE, nResult);
// }
// DETOUR_DECL_MEMBER1(CGameClient__WriteGameSounds, void, bf_write, &buf)
// {
// CGameClient *pGameClient = (CGameClient *)this;
// if ( pGameClient->m_Sounds.Count() <= 0 )
// return;
// char data[NET_MAX_PAYLOAD];
// SVC_Sounds msg;
// msg.m_DataOut.StartWriting( data, sizeof(data) );
// msg.SetReliable( false );
// int nSoundCount = Custom_CGameClient__FillSoundsMessage( pGameClient, msg );
// msg.WriteToBuffer( buf );
// // if ( pGameClient->IsTracing() )
// // {
// // pGameClient->TraceNetworkData( buf, "Sounds [count=%d]", nSoundCount );
// // }
// } // }
}
DETOUR_DECL_MEMBER5(CBaseServer__WriteTempEntities, void, CBaseClient *, client, CFrameSnapshot *, pCurrentSnapshot, CFrameSnapshot *, pLastSnapshot, bf_write &, buf, int, ev_max) DETOUR_DECL_MEMBER5(CBaseServer__WriteTempEntities, void, CBaseClient *, client, CFrameSnapshot *, pCurrentSnapshot, CFrameSnapshot *, pLastSnapshot, bf_write &, buf, int, ev_max)
{ {
@@ -385,21 +385,21 @@ bool SSF::SDK_OnLoad(char *error, size_t maxlen, bool late)
} }
g_Detour_CBaseServer__WriteTempEntities->EnableDetour(); g_Detour_CBaseServer__WriteTempEntities->EnableDetour();
g_Detour_CGameClient__FillSoundsMessage = DETOUR_CREATE_MEMBER(CGameClient__FillSoundsMessage, "CGameClient__FillSoundsMessage"); // g_Detour_CGameClient__FillSoundsMessage = DETOUR_CREATE_MEMBER(CGameClient__FillSoundsMessage, "CGameClient__FillSoundsMessage");
if(!g_Detour_CGameClient__FillSoundsMessage) // if(!g_Detour_CGameClient__FillSoundsMessage)
{ // {
snprintf(error, maxlen, "Failed to detour CGameClient__FillSoundsMessage.\n"); // snprintf(error, maxlen, "Failed to detour CGameClient__FillSoundsMessage.\n");
return false; // return false;
} // }
g_Detour_CGameClient__FillSoundsMessage->EnableDetour(); // g_Detour_CGameClient__FillSoundsMessage->EnableDetour();
g_Detour_CGameClient__WriteGameSounds = DETOUR_CREATE_MEMBER(CGameClient__WriteGameSounds, "CGameClient__WriteGameSounds"); // g_Detour_CGameClient__WriteGameSounds = DETOUR_CREATE_MEMBER(CGameClient__WriteGameSounds, "CGameClient__WriteGameSounds");
if(!g_Detour_CGameClient__WriteGameSounds) // if(!g_Detour_CGameClient__WriteGameSounds)
{ // {
snprintf(error, maxlen, "Failed to detour CGameClient__WriteGameSounds.\n"); // snprintf(error, maxlen, "Failed to detour CGameClient__WriteGameSounds.\n");
return false; // return false;
} // }
g_Detour_CGameClient__WriteGameSounds->EnableDetour(); // g_Detour_CGameClient__WriteGameSounds->EnableDetour();
AutoExecConfig(g_pCVar, true); AutoExecConfig(g_pCVar, true);
@@ -420,17 +420,17 @@ void SSF::SDK_OnUnload()
g_Detour_CBaseServer__WriteTempEntities = NULL; g_Detour_CBaseServer__WriteTempEntities = NULL;
} }
if(g_Detour_CGameClient__FillSoundsMessage) // if(g_Detour_CGameClient__FillSoundsMessage)
{ // {
g_Detour_CGameClient__FillSoundsMessage->Destroy(); // g_Detour_CGameClient__FillSoundsMessage->Destroy();
g_Detour_CGameClient__FillSoundsMessage = NULL; // g_Detour_CGameClient__FillSoundsMessage = NULL;
} // }
if(g_Detour_CGameClient__WriteGameSounds) // if(g_Detour_CGameClient__WriteGameSounds)
{ // {
g_Detour_CGameClient__WriteGameSounds->Destroy(); // g_Detour_CGameClient__WriteGameSounds->Destroy();
g_Detour_CGameClient__WriteGameSounds = NULL; // g_Detour_CGameClient__WriteGameSounds = NULL;
} // }
gameconfs->CloseGameConfigFile(g_pGameConf); gameconfs->CloseGameConfigFile(g_pGameConf);
} }