mirror of
https://github.com/rehlds/rehlds.git
synced 2024-12-27 23:25:45 +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:
|
||||
//
|
||||
@ -70,8 +70,6 @@ typedef unsigned char BYTE;
|
||||
typedef unsigned char byte;
|
||||
typedef unsigned short word;
|
||||
|
||||
#include "string_t.h"
|
||||
|
||||
typedef float vec_t;
|
||||
|
||||
|
||||
|
@ -48,14 +48,25 @@ public:
|
||||
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)
|
||||
template<typename t_ret, typename ...t_args>
|
||||
class IHookChainRegistry {
|
||||
public:
|
||||
typedef t_ret(*hookfunc_t)(IHookChain<t_ret, t_args...>*, t_args...);
|
||||
|
||||
virtual void registerHook(hookfunc_t hook) = 0;
|
||||
virtual void unregisterHook(hookfunc_t hook) = 0;
|
||||
virtual void registerHook(hookfunc_t hook, int pri = HC_PRIORITY_DEFAULT) = 0;
|
||||
virtual void unregisterHook(hookfunc_t hook, int pri = HC_PRIORITY_DEFAULT) = 0;
|
||||
};
|
||||
|
||||
// Hook chain registry(for hooks [un]registration)
|
||||
@ -64,6 +75,6 @@ class IVoidHookChainRegistry {
|
||||
public:
|
||||
typedef void(*hookfunc_t)(IVoidHookChain<t_args...>*, t_args...);
|
||||
|
||||
virtual void registerHook(hookfunc_t hook) = 0;
|
||||
virtual void unregisterHook(hookfunc_t hook) = 0;
|
||||
virtual void registerHook(hookfunc_t hook, int pri = HC_PRIORITY_DEFAULT) = 0;
|
||||
virtual void unregisterHook(hookfunc_t hook, int pri = HC_PRIORITY_DEFAULT) = 0;
|
||||
};
|
||||
|
@ -34,7 +34,7 @@
|
||||
#include "interface.h"
|
||||
#include "model.h"
|
||||
|
||||
#define REHLDS_API_VERSION_MAJOR 2
|
||||
#define REHLDS_API_VERSION_MAJOR 3
|
||||
#define REHLDS_API_VERSION_MINOR 13
|
||||
|
||||
//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;
|
||||
}
|
||||
|
||||
void AbstractHookChainRegistry::addHook(void* hookFunc) {
|
||||
void AbstractHookChainRegistry::addHook(void* hookFunc, int priority) {
|
||||
if (m_NumHooks >= MAX_HOOKS_IN_CHAIN) {
|
||||
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
|
||||
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;
|
||||
int bestMatch = -1;
|
||||
|
||||
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) {
|
||||
origfunc_t origfunc = (origfunc_t)m_OriginalFunc;
|
||||
origfunc(args...);
|
||||
m_OriginalFunc(args...);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -104,11 +103,12 @@ private:
|
||||
class AbstractHookChainRegistry {
|
||||
protected:
|
||||
void* m_Hooks[MAX_HOOKS_IN_CHAIN + 1]; // +1 for null
|
||||
int m_Priorities[MAX_HOOKS_IN_CHAIN + 1];
|
||||
int m_NumHooks;
|
||||
|
||||
protected:
|
||||
void addHook(void* hookFunc);
|
||||
void removeHook(void* hookFunc);
|
||||
void addHook(void* hookFunc, int priority);
|
||||
void removeHook(void* hookFunc, int priority);
|
||||
|
||||
public:
|
||||
AbstractHookChainRegistry();
|
||||
@ -127,11 +127,11 @@ public:
|
||||
return chain.callNext(args...);
|
||||
}
|
||||
|
||||
virtual void registerHook(hookfunc_t hook) {
|
||||
addHook((void*)hook);
|
||||
virtual void registerHook(hookfunc_t hook, int priority) {
|
||||
addHook((void*)hook, priority);
|
||||
}
|
||||
virtual void unregisterHook(hookfunc_t hook) {
|
||||
removeHook((void*)hook);
|
||||
virtual void unregisterHook(hookfunc_t hook, int priority) {
|
||||
removeHook((void*)hook, priority);
|
||||
}
|
||||
};
|
||||
|
||||
@ -148,11 +148,11 @@ public:
|
||||
chain.callNext(args...);
|
||||
}
|
||||
|
||||
virtual void registerHook(hookfunc_t hook) {
|
||||
addHook((void*)hook);
|
||||
virtual void registerHook(hookfunc_t hook, int priority) {
|
||||
addHook((void*)hook, priority);
|
||||
}
|
||||
|
||||
virtual void unregisterHook(hookfunc_t hook) {
|
||||
removeHook((void*)hook);
|
||||
virtual void unregisterHook(hookfunc_t hook, int priority) {
|
||||
removeHook((void*)hook, priority);
|
||||
}
|
||||
};
|
||||
|
@ -36,11 +36,9 @@ struct plugin_api_t
|
||||
std::vector<plugin_api_t *> g_PluginApis;
|
||||
|
||||
plugin_api_t* FindPluginApiByName(const char *name) {
|
||||
for (auto it = g_PluginApis.begin(), end = g_PluginApis.end(); it != end; ++it) {
|
||||
auto api = *it;
|
||||
|
||||
if (!strcmp(api->name, name)) {
|
||||
return api;
|
||||
for (auto pl : g_PluginApis) {
|
||||
if (!strcmp(pl->name, name)) {
|
||||
return pl;
|
||||
}
|
||||
}
|
||||
|
||||
@ -147,7 +145,9 @@ void EXT_FUNC Rehlds_RegisterPluginApi(const char *name, void *impl) {
|
||||
|
||||
if (!api) {
|
||||
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);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user