2
0
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:
s1lentq 2016-10-25 22:44:49 +07:00
parent e819b1370a
commit 9a168ff37d
7 changed files with 78 additions and 146 deletions

View File

@ -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;

View File

@ -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;
};

View File

@ -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

View File

@ -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

View File

@ -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;
}
}

View File

@ -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);
}
};

View File

@ -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);
}