mirror of
https://github.com/rehlds/rehlds.git
synced 2025-02-28 14:31:17 +03:00
Implemented features of priority for hookchains
This commit is contained in:
parent
9e54d85c1c
commit
1bf56b26dd
@ -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,13 +48,24 @@ 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 registerHook(hookfunc_t hook, int priority = HC_PRIORITY_DEFAULT) = 0;
|
||||
virtual void unregisterHook(hookfunc_t hook) = 0;
|
||||
};
|
||||
|
||||
@ -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 registerHook(hookfunc_t hook, int priority = HC_PRIORITY_DEFAULT) = 0;
|
||||
virtual void unregisterHook(hookfunc_t hook) = 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
|
@ -22,25 +22,49 @@
|
||||
AbstractHookChainRegistry::AbstractHookChainRegistry()
|
||||
{
|
||||
Q_memset(m_Hooks, 0, sizeof(m_Hooks));
|
||||
Q_memset(m_Priorities, 0, sizeof(m_Priorities));
|
||||
|
||||
m_NumHooks = 0;
|
||||
}
|
||||
|
||||
void AbstractHookChainRegistry::addHook(void* hookFunc) {
|
||||
void AbstractHookChainRegistry::addHook(void* hookFunc, int priority) {
|
||||
for (int i = 0; i < MAX_HOOKS_IN_CHAIN; i++)
|
||||
{
|
||||
if (m_Hooks[i] == hookFunc)
|
||||
return;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (m_NumHooks >= MAX_HOOKS_IN_CHAIN) {
|
||||
rehlds_syserror("MAX_HOOKS_IN_CHAIN limit hit");
|
||||
}
|
||||
|
||||
m_Hooks[m_NumHooks++] = hookFunc;
|
||||
m_NumHooks++;
|
||||
}
|
||||
|
||||
void AbstractHookChainRegistry::removeHook(void* hookFunc) {
|
||||
|
||||
// erase hook
|
||||
for (int i = 0; i < m_NumHooks; i++) {
|
||||
if (hookFunc == m_Hooks[i]) {
|
||||
if (--m_NumHooks != i)
|
||||
for (int i = 0; i < m_NumHooks; i++)
|
||||
{
|
||||
--m_NumHooks;
|
||||
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]));
|
||||
Q_memmove(&m_Priorities[i], &m_Priorities[i + 1], (m_NumHooks - i) * sizeof(m_Priorities[0]));
|
||||
m_Hooks[m_NumHooks] = NULL;
|
||||
}
|
||||
else
|
||||
|
@ -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,10 +103,11 @@ 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 addHook(void* hookFunc, int priority);
|
||||
void removeHook(void* hookFunc);
|
||||
|
||||
public:
|
||||
@ -127,8 +127,8 @@ 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);
|
||||
@ -148,8 +148,8 @@ 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) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user