mirror of
https://github.com/rehlds/rehlds.git
synced 2024-12-28 15:45:46 +03:00
Added features of priority for hookchains
Remove useless string_t.h Update the major version
This commit is contained in:
parent
e819b1370a
commit
9a168ff37d
@ -1,4 +1,4 @@
|
|||||||
//========= Copyright © 1996-2001, Valve LLC, All rights reserved. ============
|
//========= Copyright © 1996-2001, Valve LLC, All rights reserved. ============
|
||||||
//
|
//
|
||||||
// Purpose:
|
// Purpose:
|
||||||
//
|
//
|
||||||
@ -70,8 +70,6 @@ typedef unsigned char BYTE;
|
|||||||
typedef unsigned char byte;
|
typedef unsigned char byte;
|
||||||
typedef unsigned short word;
|
typedef unsigned short word;
|
||||||
|
|
||||||
#include "string_t.h"
|
|
||||||
|
|
||||||
typedef float vec_t;
|
typedef float vec_t;
|
||||||
|
|
||||||
|
|
||||||
|
@ -48,14 +48,25 @@ public:
|
|||||||
virtual void callOriginal(t_args... args) = 0;
|
virtual void callOriginal(t_args... args) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Specifies priorities for hooks call order in the chain.
|
||||||
|
// For equal priorities first registered hook will be called first.
|
||||||
|
enum HookChainPriority : int
|
||||||
|
{
|
||||||
|
HC_PRIORITY_UNINTERRUPTABLE = 255, // Hook will be called before other hooks.
|
||||||
|
HC_PRIORITY_HIGH = 192, // Hook will be called before hooks with default priority.
|
||||||
|
HC_PRIORITY_DEFAULT = 128, // Default hook call priority.
|
||||||
|
HC_PRIORITY_MEDIUM = 64, // Hook will be called after hooks with default priority.
|
||||||
|
HC_PRIORITY_LOW = 0, // Hook will be called after all other hooks.
|
||||||
|
};
|
||||||
|
|
||||||
// Hook chain registry(for hooks [un]registration)
|
// Hook chain registry(for hooks [un]registration)
|
||||||
template<typename t_ret, typename ...t_args>
|
template<typename t_ret, typename ...t_args>
|
||||||
class IHookChainRegistry {
|
class IHookChainRegistry {
|
||||||
public:
|
public:
|
||||||
typedef t_ret(*hookfunc_t)(IHookChain<t_ret, t_args...>*, t_args...);
|
typedef t_ret(*hookfunc_t)(IHookChain<t_ret, t_args...>*, t_args...);
|
||||||
|
|
||||||
virtual void registerHook(hookfunc_t hook) = 0;
|
virtual void registerHook(hookfunc_t hook, int pri = HC_PRIORITY_DEFAULT) = 0;
|
||||||
virtual void unregisterHook(hookfunc_t hook) = 0;
|
virtual void unregisterHook(hookfunc_t hook, int pri = HC_PRIORITY_DEFAULT) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Hook chain registry(for hooks [un]registration)
|
// Hook chain registry(for hooks [un]registration)
|
||||||
@ -64,6 +75,6 @@ class IVoidHookChainRegistry {
|
|||||||
public:
|
public:
|
||||||
typedef void(*hookfunc_t)(IVoidHookChain<t_args...>*, t_args...);
|
typedef void(*hookfunc_t)(IVoidHookChain<t_args...>*, t_args...);
|
||||||
|
|
||||||
virtual void registerHook(hookfunc_t hook) = 0;
|
virtual void registerHook(hookfunc_t hook, int pri = HC_PRIORITY_DEFAULT) = 0;
|
||||||
virtual void unregisterHook(hookfunc_t hook) = 0;
|
virtual void unregisterHook(hookfunc_t hook, int pri = HC_PRIORITY_DEFAULT) = 0;
|
||||||
};
|
};
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
#include "interface.h"
|
#include "interface.h"
|
||||||
#include "model.h"
|
#include "model.h"
|
||||||
|
|
||||||
#define REHLDS_API_VERSION_MAJOR 2
|
#define REHLDS_API_VERSION_MAJOR 3
|
||||||
#define REHLDS_API_VERSION_MINOR 13
|
#define REHLDS_API_VERSION_MINOR 13
|
||||||
|
|
||||||
//Steam_NotifyClientConnect hook
|
//Steam_NotifyClientConnect hook
|
||||||
|
@ -1,106 +0,0 @@
|
|||||||
//========= Copyright (c) 1996-2002, Valve LLC, All rights reserved. ==========
|
|
||||||
//
|
|
||||||
// Purpose: Defines the more complete set of operations on the string_t defined
|
|
||||||
// These should be used instead of direct manipulation to allow more
|
|
||||||
// flexibility in future ports or optimization.
|
|
||||||
//
|
|
||||||
// $NoKeywords: $
|
|
||||||
//=============================================================================
|
|
||||||
|
|
||||||
#ifndef STRING_T_H
|
|
||||||
#define STRING_T_H
|
|
||||||
|
|
||||||
#if defined( _WIN32 )
|
|
||||||
#pragma once
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "osconfig.h"
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#ifndef NO_STRING_T
|
|
||||||
|
|
||||||
#ifdef WEAK_STRING_T
|
|
||||||
|
|
||||||
typedef int valve_string_t;
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// Purpose: The correct way to specify the NULL string as a constant.
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
#define NULL_STRING 0
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// Purpose: Given a string_t, make a C string. By convention the result string
|
|
||||||
// pointer should be considered transient and should not be stored.
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
#define STRING( offset ) ( ( offset ) ? reinterpret_cast<const char *>( offset ) : "" )
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// Purpose: Given a C string, obtain a string_t
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
#define MAKE_STRING( str ) ( ( *str != 0 ) ? reinterpret_cast<int>( str ) : 0 )
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
#else // Strong string_t
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
struct valve_string_t
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
bool operator!() const { return (pszValue == NULL); }
|
|
||||||
bool operator==(const valve_string_t &rhs) const { return (pszValue == rhs.pszValue); }
|
|
||||||
bool operator!=(const valve_string_t &rhs) const { return (pszValue != rhs.pszValue); }
|
|
||||||
|
|
||||||
const char *ToCStr() const { return (pszValue) ? pszValue : ""; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
const char *pszValue;
|
|
||||||
};
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
struct castable_string_t : public valve_string_t // string_t is used in unions, hence, no constructor allowed
|
|
||||||
{
|
|
||||||
castable_string_t() { pszValue = NULL; }
|
|
||||||
castable_string_t(const char *pszFrom) { pszValue = (*pszFrom != 0) ? pszFrom : 0; }
|
|
||||||
};
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// Purpose: The correct way to specify the NULL string as a constant.
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
#define NULL_STRING castable_string_t()
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// Purpose: Given a string_t, make a C string. By convention the result string
|
|
||||||
// pointer should be considered transient and should not be stored.
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
#define STRING( string_t_obj ) (string_t_obj).ToCStr()
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// Purpose: Given a C string, obtain a string_t
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
#define MAKE_STRING( c_str ) castable_string_t( c_str )
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#else // NO_STRING_T
|
|
||||||
|
|
||||||
typedef const char *string_t;
|
|
||||||
#define NULL_STRING 0
|
|
||||||
#define STRING( c_str ) ( c_str )
|
|
||||||
#define MAKE_STRING( c_str ) ( c_str )
|
|
||||||
|
|
||||||
#endif // NO_STRING_T
|
|
||||||
|
|
||||||
//=============================================================================
|
|
||||||
|
|
||||||
#endif // STRING_T_H
|
|
@ -25,28 +25,57 @@ AbstractHookChainRegistry::AbstractHookChainRegistry()
|
|||||||
m_NumHooks = 0;
|
m_NumHooks = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AbstractHookChainRegistry::addHook(void* hookFunc) {
|
void AbstractHookChainRegistry::addHook(void* hookFunc, int priority) {
|
||||||
if (m_NumHooks >= MAX_HOOKS_IN_CHAIN) {
|
if (m_NumHooks >= MAX_HOOKS_IN_CHAIN) {
|
||||||
rehlds_syserror("MAX_HOOKS_IN_CHAIN limit hit");
|
rehlds_syserror("MAX_HOOKS_IN_CHAIN limit hit");
|
||||||
}
|
}
|
||||||
|
|
||||||
m_Hooks[m_NumHooks++] = hookFunc;
|
for (int i = 0; i < MAX_HOOKS_IN_CHAIN; i++)
|
||||||
|
{
|
||||||
|
if (m_Hooks[i] && priority <= m_Priorities[i])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
auto swapHookFunc = m_Hooks[i];
|
||||||
|
auto swapPriority = m_Priorities[i];
|
||||||
|
|
||||||
|
m_Hooks[i] = hookFunc;
|
||||||
|
m_Priorities[i] = priority;
|
||||||
|
|
||||||
|
hookFunc = swapHookFunc;
|
||||||
|
priority = swapPriority;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_NumHooks++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AbstractHookChainRegistry::removeHook(void* hookFunc) {
|
void AbstractHookChainRegistry::removeHook(void* hookFunc, int priority) {
|
||||||
|
|
||||||
// erase hook
|
int bestMatch = -1;
|
||||||
for (int i = 0; i < m_NumHooks; i++) {
|
|
||||||
if (hookFunc == m_Hooks[i]) {
|
|
||||||
if (--m_NumHooks != i)
|
|
||||||
{
|
|
||||||
Q_memmove(&m_Hooks[i], &m_Hooks[i + 1], (m_NumHooks - i) * sizeof(m_Hooks[0]));
|
|
||||||
m_Hooks[m_NumHooks] = NULL;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
m_Hooks[i] = NULL;
|
|
||||||
|
|
||||||
return;
|
// Search for matching hook func address and priority or at least address match
|
||||||
|
for (int i = 0; i < m_NumHooks; i++)
|
||||||
|
{
|
||||||
|
if (hookFunc == m_Hooks[i])
|
||||||
|
{
|
||||||
|
bestMatch = i;
|
||||||
|
if (m_Priorities[i] == priority)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (bestMatch >= 0)
|
||||||
|
{
|
||||||
|
// erase hook
|
||||||
|
--m_NumHooks;
|
||||||
|
|
||||||
|
if (m_NumHooks != bestMatch)
|
||||||
|
{
|
||||||
|
Q_memmove(&m_Hooks[bestMatch], &m_Hooks[bestMatch + 1], (m_NumHooks - bestMatch) * sizeof(m_Hooks[0]));
|
||||||
|
Q_memmove(&m_Priorities[bestMatch], &m_Priorities[bestMatch + 1], (m_NumHooks - bestMatch) * sizeof(m_Priorities[0]));
|
||||||
|
|
||||||
|
m_Hooks[m_NumHooks] = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
m_Hooks[bestMatch] = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -92,8 +92,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void callOriginal(t_args... args) {
|
virtual void callOriginal(t_args... args) {
|
||||||
origfunc_t origfunc = (origfunc_t)m_OriginalFunc;
|
m_OriginalFunc(args...);
|
||||||
origfunc(args...);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -104,11 +103,12 @@ private:
|
|||||||
class AbstractHookChainRegistry {
|
class AbstractHookChainRegistry {
|
||||||
protected:
|
protected:
|
||||||
void* m_Hooks[MAX_HOOKS_IN_CHAIN + 1]; // +1 for null
|
void* m_Hooks[MAX_HOOKS_IN_CHAIN + 1]; // +1 for null
|
||||||
|
int m_Priorities[MAX_HOOKS_IN_CHAIN + 1];
|
||||||
int m_NumHooks;
|
int m_NumHooks;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void addHook(void* hookFunc);
|
void addHook(void* hookFunc, int priority);
|
||||||
void removeHook(void* hookFunc);
|
void removeHook(void* hookFunc, int priority);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AbstractHookChainRegistry();
|
AbstractHookChainRegistry();
|
||||||
@ -127,11 +127,11 @@ public:
|
|||||||
return chain.callNext(args...);
|
return chain.callNext(args...);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void registerHook(hookfunc_t hook) {
|
virtual void registerHook(hookfunc_t hook, int priority) {
|
||||||
addHook((void*)hook);
|
addHook((void*)hook, priority);
|
||||||
}
|
}
|
||||||
virtual void unregisterHook(hookfunc_t hook) {
|
virtual void unregisterHook(hookfunc_t hook, int priority) {
|
||||||
removeHook((void*)hook);
|
removeHook((void*)hook, priority);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -148,11 +148,11 @@ public:
|
|||||||
chain.callNext(args...);
|
chain.callNext(args...);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void registerHook(hookfunc_t hook) {
|
virtual void registerHook(hookfunc_t hook, int priority) {
|
||||||
addHook((void*)hook);
|
addHook((void*)hook, priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void unregisterHook(hookfunc_t hook) {
|
virtual void unregisterHook(hookfunc_t hook, int priority) {
|
||||||
removeHook((void*)hook);
|
removeHook((void*)hook, priority);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -36,11 +36,9 @@ struct plugin_api_t
|
|||||||
std::vector<plugin_api_t *> g_PluginApis;
|
std::vector<plugin_api_t *> g_PluginApis;
|
||||||
|
|
||||||
plugin_api_t* FindPluginApiByName(const char *name) {
|
plugin_api_t* FindPluginApiByName(const char *name) {
|
||||||
for (auto it = g_PluginApis.begin(), end = g_PluginApis.end(); it != end; ++it) {
|
for (auto pl : g_PluginApis) {
|
||||||
auto api = *it;
|
if (!strcmp(pl->name, name)) {
|
||||||
|
return pl;
|
||||||
if (!strcmp(api->name, name)) {
|
|
||||||
return api;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,7 +145,9 @@ void EXT_FUNC Rehlds_RegisterPluginApi(const char *name, void *impl) {
|
|||||||
|
|
||||||
if (!api) {
|
if (!api) {
|
||||||
api = new plugin_api_t;
|
api = new plugin_api_t;
|
||||||
strncpy(api->name, name, sizeof api->name - 1);
|
Q_strncpy(api->name, name, sizeof api->name - 1);
|
||||||
|
api->name[sizeof api->name - 1] = '\0';
|
||||||
|
|
||||||
g_PluginApis.push_back(api);
|
g_PluginApis.push_back(api);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user