/**
* vim: set ts=4 :
* =============================================================================
* SendVar Proxy Manager
* Copyright (C) 2011-2019 Afronanny & AlliedModders community. All rights reserved.
* =============================================================================
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, version 3.0, as published by the
* Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see .
*
* As a special exception, AlliedModders LLC gives you permission to link the
* code of this program (as well as its derivative works) to "Half-Life 2," the
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
* by the Valve Corporation. You must obey the GNU General Public License in
* all respects for all other code used. Additionally, AlliedModders LLC grants
* this exception to all derivative works. AlliedModders LLC defines further
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
* or .
*
* Version: $Id$
*/
#ifndef _EXTENSION_H_INC_
#define _EXTENSION_H_INC_
/*
TODO:
Implement interface:
Add common function for prop change hooks
Add remove listeners for prop change hooks
*/
#include "smsdk_ext.h"
#include
#include
#include "convar.h"
#include "dt_send.h"
#include "server_class.h"
#include "ISendProxy.h"
#include
#include
#include
#include
#define GET_CONVAR(name) \
name = g_pCVar->FindVar(#name); \
if (name == nullptr) { \
if (error != nullptr && maxlen != 0) { \
ismm->Format(error, maxlen, "Could not find ConVar: " #name); \
} \
return false; \
}
class IServerGameEnts;
void GlobalProxy(const SendProp *pProp, const void *pStructBase, const void* pData, DVariant *pOut, int iElement, int objectID);
void GlobalProxyGamerules(const SendProp *pProp, const void *pStructBase, const void* pData, DVariant *pOut, int iElement, int objectID);
bool IsPropValid(SendProp *, PropType);
char * strncpynull(char * pDestination, const char * pSource, size_t szCount);
struct ListenerCallbackInfo
{
IExtension * m_pExt;
IExtensionInterface * m_pExtAPI;
ISendProxyUnhookListener * m_pCallBack;
};
struct CallBackInfo
{
CallBackInfo() = default;
CallBackInfo(const CallBackInfo & rObj) = default;
CallBackInfo(CallBackInfo && rObj) = default;
CallBackInfo & operator=(const CallBackInfo & rObj) = default;
CallBackInfo & operator=(CallBackInfo && rObj) = default;
~CallBackInfo() = default;
void * pOwner; //Pointer to plugin context or IExtension *
void * pCallback;
CallBackType iCallbackType;
};
struct SendPropHook
{
SendPropHook() = default;
SendPropHook(const SendPropHook & rObj) = default;
SendPropHook(SendPropHook && rObj) = default;
SendPropHook &operator=(SendPropHook &&) = default;
SendPropHook &operator=(const SendPropHook &) = default;
~SendPropHook() = default;
CallBackInfo sCallbackInfo;
SendProp * pVar;
edict_t * pEnt;
SendVarProxyFn pRealProxy;
int objectID;
PropType propType;
int Offset;
int Element{0};
std::vector vListeners;
bool per_client = false;
};
struct SendPropHookGamerules
{
SendPropHookGamerules() = default;
SendPropHookGamerules(const SendPropHookGamerules & rObj) = default;
SendPropHookGamerules(SendPropHookGamerules && rObj) = default;
SendPropHookGamerules &operator=(SendPropHookGamerules &&) = default;
SendPropHookGamerules &operator=(const SendPropHookGamerules &) = default;
~SendPropHookGamerules() = default;
CallBackInfo sCallbackInfo;
SendProp * pVar;
SendVarProxyFn pRealProxy;
PropType propType;
int Element{0};
std::vector vListeners;
bool per_client = false;
};
struct dumbvec_t
{
dumbvec_t() = default;
dumbvec_t(const dumbvec_t &) = default;
dumbvec_t(dumbvec_t &&) = default;
dumbvec_t &operator=(const dumbvec_t &) = default;
dumbvec_t &operator=(dumbvec_t &&) = default;
float &operator[](int i) { return value[i]; }
const float &operator[](int i) const { return value[i]; }
dumbvec_t &operator=(const Vector &vec) {
value[0] = vec.x;
value[1] = vec.y;
value[2] = vec.z;
return *this;
}
bool operator==(const Vector &vec) {
return value[0] == vec.x &&
value[1] == vec.y &&
value[2] == vec.z;
}
bool operator!=(const Vector &vec) {
return value[0] != vec.x &&
value[1] != vec.y &&
value[2] != vec.z;
}
float value[3];
};
struct PropChangeHook
{
PropChangeHook() = default;
PropChangeHook(const PropChangeHook & rObj) = default;
PropChangeHook(PropChangeHook && rObj) = default;
PropChangeHook &operator=(PropChangeHook &&) = default;
PropChangeHook &operator=(const PropChangeHook &) = default;
~PropChangeHook() = default;
union //unfortunately we MUST use union instead of std::variant cuz we should prevent libstdc++ linking in linux =|
{
int iLastValue{0};
float flLastValue;
dumbvec_t vecLastValue;
char cLastValue[4096];
};
SendProp * pVar;
PropType propType;
unsigned int Offset;
int objectID;
int Element{0};
std::vector vCallbacksInfo;
};
struct PropChangeHookGamerules
{
PropChangeHookGamerules() = default;
PropChangeHookGamerules(const PropChangeHookGamerules & rObj) = default;
PropChangeHookGamerules(PropChangeHookGamerules && rObj) = default;
PropChangeHookGamerules &operator=(PropChangeHookGamerules &&) = default;
PropChangeHookGamerules &operator=(const PropChangeHookGamerules &) = default;
~PropChangeHookGamerules() = default;
union //unfortunately we MUST use union instead of std::variant cuz we should prevent libstdc++ linking in linux =|
{
int iLastValue{0};
float flLastValue;
dumbvec_t vecLastValue;
char cLastValue[4096];
};
SendProp * pVar;
PropType propType;
unsigned int Offset;
int Element{0};
std::vector vCallbacksInfo;
};
extern std::vector g_Hooks;
extern std::vector g_HooksGamerules;
extern std::vector g_ChangeHooks;
extern std::vector g_ChangeHooksGamerules;
class SendProxyManager :
public SDKExtension,
public IPluginsListener,
public ISMEntityListener
{
public: //sm
virtual bool SDK_OnLoad(char * error, size_t maxlength, bool late);
virtual void SDK_OnUnload();
virtual void SDK_OnAllLoaded();
virtual void OnCoreMapEnd();
virtual void OnCoreMapStart(edict_t *, int, int);
public: //other
virtual void OnPluginUnloaded(IPlugin * plugin);
//returns true upon success
bool AddHookToList(SendPropHook &&hook);
bool AddHookToListGamerules(SendPropHookGamerules &&hook);
//returns false if prop type not supported or entity is invalid
bool AddChangeHookToList(PropChangeHook &&sHook, CallBackInfo &&pInfo);
bool AddChangeHookToListGamerules(PropChangeHookGamerules &&sHook, CallBackInfo &&pInfo);
bool UnhookProxy(const SendPropHook &hook);
bool UnhookProxyGamerules(const SendPropHookGamerules &hook);
bool UnhookChange(PropChangeHook &hook, const CallBackInfo &pInfo);
bool UnhookChangeGamerules(PropChangeHookGamerules &hook, const CallBackInfo &pInfo);
virtual int GetClientCount() const;
public: // ISMEntityListener
virtual void OnEntityDestroyed(CBaseEntity * pEntity);
public:
#if defined SMEXT_CONF_METAMOD
virtual bool SDK_OnMetamodLoad(ISmmAPI * ismm, char * error, size_t maxlen, bool late);
//virtual bool SDK_OnMetamodUnload(char *error, size_t maxlength);
//virtual bool SDK_OnMetamodPauseChange(bool paused, char *error, size_t maxlength);
#endif
};
extern SendProxyManager g_SendProxyManager;
extern IServerGameEnts * gameents;
extern const char * g_szGameRulesProxy;
constexpr int g_iEdictCount = 2048; //default value, we do not need to get it manually cuz it is constant
extern ISDKTools * g_pSDKTools;
extern void * g_pGameRules;
#endif // _EXTENSION_H_INC_