csgo-2018-source/game/shared/usermessages.h
2021-07-24 21:11:47 -07:00

177 lines
4.2 KiB
C++

//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#ifndef USERMESSAGES_H
#define USERMESSAGES_H
#ifdef _WIN32
#pragma once
#endif
#include <utldict.h>
#include <utlvector.h>
#include <bitbuf.h>
#include <utldelegate.h>
#include "shareddefs.h"
#include "networksystem/inetworksystem.h"
// eliminates a conflict with TYPE_BOOL in OSX
#ifdef TYPE_BOOL
#undef TYPE_BOOL
#endif
#include "cstrike15_usermessages.pb.h"
//-----------------------------------------------------------------------------
class IUserMessageBinder;
//-----------------------------------------------------------------------------
// Purpose: Interface for registering and dispatching usermessages
// Shred code creates same ordered list on client/server
//-----------------------------------------------------------------------------
class CUserMessages
{
public:
CUserMessages();
~CUserMessages();
bool DispatchUserMessage( int msg_type, int32 nPassthroughFlags, int size, const void *msg );
void BindMessage( IUserMessageBinder *pMessageBinder );
bool UnbindMessage( IUserMessageBinder *pMessageBinder );
private:
typedef CCopyableUtlVector< IUserMessageBinder * > UserMessageBinderVec_t;
typedef CUtlMap< int, CCopyableUtlVectorFixed< UserMessageBinderVec_t, MAX_SPLITSCREEN_PLAYERS > > UserMessageHandlerMap_t;
UserMessageHandlerMap_t m_UserMessageBinderMap;
};
extern CUserMessages *UserMessages();
//-----------------------------------------------------------------------------
class IUserMessageBinder
{
public:
virtual ~IUserMessageBinder() = 0;
virtual int GetType() const = 0;
virtual ::google::protobuf::Message *Parse( int32 nPassthroughFlags, const void *msg, int size, bool &bSilentIgnore ) = 0;
virtual bool Invoke( ::google::protobuf::Message const *msg ) = 0;
virtual const CUtlAbstractDelegate &GetAbstractDelegate() = 0;
};
//-----------------------------------------------------------------------------
class CUserMessageBinder
{
public:
CUserMessageBinder()
: m_pBind( NULL )
{
}
~CUserMessageBinder()
{
delete m_pBind;
}
template< int msgType, typename PB_OBJECT_TYPE >
void Bind( CUtlDelegate< bool ( const PB_OBJECT_TYPE & obj ) > handler )
{
delete m_pBind;
m_pBind = new BindParams< msgType, PB_OBJECT_TYPE, 0 >( handler );
}
template< int msgType, typename PB_OBJECT_TYPE >
void BindRealtimePassthrough( CUtlDelegate< bool( const PB_OBJECT_TYPE & obj ) > handler )
{
delete m_pBind;
m_pBind = new BindParams< msgType, PB_OBJECT_TYPE, 1 >( handler );
}
void Unbind()
{
if ( m_pBind )
{
delete m_pBind;
m_pBind = NULL;
}
}
bool IsBound() const
{
return m_pBind != NULL;
}
private:
template< int msgType, typename PB_OBJECT_TYPE, int32 nExpectedPassthroughInReplay >
struct BindParams : public IUserMessageBinder
{
BindParams( CUtlDelegate< bool ( PB_OBJECT_TYPE const &msg ) > handler )
: m_handler( handler )
{
UserMessages()->BindMessage( this );
}
virtual ~BindParams()
{
UserMessages()->UnbindMessage( this );
}
virtual int GetType() const
{
return msgType;
}
virtual ::google::protobuf::Message *Parse( int32 nPassthroughFlags, const void *msg, int size, bool &bSilentIgnore ) OVERRIDE
{
if ( size < 0 || size > NET_MAX_PAYLOAD )
{
return NULL;
}
extern int CL_GetHltvReplayDelay();
if ( CL_GetHltvReplayDelay() )
{
if ( nPassthroughFlags != nExpectedPassthroughInReplay )
{
// this is a wrong timeline message. Ignore it.
bSilentIgnore = true;
return NULL;
}
}
::google::protobuf::Message *pMsg = new PB_OBJECT_TYPE();
if ( !pMsg->ParseFromArray( msg, size ) )
{
delete pMsg;
return NULL;
}
return pMsg;
}
virtual bool Invoke( ::google::protobuf::Message const *msg )
{
if ( msg )
{
return m_handler( static_cast< PB_OBJECT_TYPE const & >( *msg ) );
}
return false;
}
virtual const CUtlAbstractDelegate &GetAbstractDelegate()
{
return m_handler.GetAbstractDelegate();
}
CUtlDelegate< bool ( PB_OBJECT_TYPE const &obj ) > m_handler;
};
IUserMessageBinder *m_pBind;
};
#endif // USERMESSAGES_H