mirror of
https://github.com/rehlds/metamod-r.git
synced 2025-01-27 22:17:54 +03:00
Finished rewriting of mreg code
Debug macro replaced to inline function
This commit is contained in:
parent
be24b08896
commit
ccea6516cb
@ -1,5 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#define MM_PRE_HOOK
|
||||||
|
#define MM_POST_HOOK
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
P_PRE, // plugin function called before gamedll
|
P_PRE, // plugin function called before gamedll
|
||||||
|
@ -315,6 +315,10 @@ void CSimpleJmp::naked_main()
|
|||||||
}*/
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CJit::CJit() : m_callback_allocator(static_allocator::mp_rwx), m_tramp_allocator(static_allocator::mp_rwx)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
size_t CJit::compile_callback(jitdata_t* jitdata)
|
size_t CJit::compile_callback(jitdata_t* jitdata)
|
||||||
{
|
{
|
||||||
if (!is_hook_needed(jitdata)) {
|
if (!is_hook_needed(jitdata)) {
|
||||||
@ -326,7 +330,7 @@ size_t CJit::compile_callback(jitdata_t* jitdata)
|
|||||||
|
|
||||||
auto code = callback.GetCode();
|
auto code = callback.GetCode();
|
||||||
auto codeSize = callback.GetCodeSize();
|
auto codeSize = callback.GetCodeSize();
|
||||||
auto ptr = m_allocator.allocate(codeSize);
|
auto ptr = m_callback_allocator.allocate(codeSize);
|
||||||
|
|
||||||
return (size_t)memcpy(ptr, code, codeSize);
|
return (size_t)memcpy(ptr, code, codeSize);
|
||||||
}
|
}
|
||||||
@ -338,14 +342,19 @@ size_t CJit::compile_tramp(size_t ptr_to_func/*, size_t hook, size_t hook_time*/
|
|||||||
|
|
||||||
auto code = jmp.GetCode();
|
auto code = jmp.GetCode();
|
||||||
auto codeSize = jmp.GetCodeSize();
|
auto codeSize = jmp.GetCodeSize();
|
||||||
auto ptr = m_static_allocator.allocate(codeSize);
|
auto ptr = m_tramp_allocator.allocate(codeSize);
|
||||||
|
|
||||||
return (size_t)memcpy(ptr, code, codeSize);
|
return (size_t)memcpy(ptr, code, codeSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CJit::clear_callbacks()
|
void CJit::clear_callbacks()
|
||||||
{
|
{
|
||||||
m_allocator.deallocate_all();
|
m_callback_allocator.deallocate_all();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CJit::clear_tramps()
|
||||||
|
{
|
||||||
|
m_tramp_allocator.deallocate_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CJit::is_hook_needed(jitdata_t* jitdata)
|
bool CJit::is_hook_needed(jitdata_t* jitdata)
|
||||||
|
@ -80,16 +80,18 @@ bool is_varargs(ret_t (*)(t_args..., ...))
|
|||||||
class CJit
|
class CJit
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
CJit();
|
||||||
size_t compile_callback(jitdata_t* jitdata);
|
size_t compile_callback(jitdata_t* jitdata);
|
||||||
size_t compile_tramp(size_t ptr_to_func/*, size_t hook, size_t hook_time*/);
|
size_t compile_tramp(size_t ptr_to_func/*, size_t hook, size_t hook_time*/);
|
||||||
void clear_callbacks();
|
void clear_callbacks();
|
||||||
|
void clear_tramps();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static bool is_hook_needed(jitdata_t* jitdata);
|
static bool is_hook_needed(jitdata_t* jitdata);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
execmem_allocator m_allocator;
|
static_allocator m_callback_allocator;
|
||||||
execmem_allocator m_static_allocator;
|
static_allocator m_tramp_allocator;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern CJit g_jit;
|
extern CJit g_jit;
|
||||||
|
@ -54,7 +54,7 @@ bool MConfig::set(option_t* setp, const char* setstr)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
*optval = Q_atoi(setstr);
|
*optval = Q_atoi(setstr);
|
||||||
META_DEBUG(3, ("set config int: %s = %d", setp->name, *optval));
|
META_DEBUG(3, "set config int: %s = %d", setp->name, *optval);
|
||||||
break;
|
break;
|
||||||
case CF_BOOL:
|
case CF_BOOL:
|
||||||
if (is_yes(setstr))
|
if (is_yes(setstr))
|
||||||
|
@ -12,17 +12,17 @@ NEW_DLL_FUNCTIONS sNewFunctionTable;
|
|||||||
NEW_DLL_FUNCTIONS sNewFunctionTable_jit;
|
NEW_DLL_FUNCTIONS sNewFunctionTable_jit;
|
||||||
NEW_DLL_FUNCTIONS *pHookedNewDllFunctions = &sNewFunctionTable;
|
NEW_DLL_FUNCTIONS *pHookedNewDllFunctions = &sNewFunctionTable;
|
||||||
|
|
||||||
void mm_ClientConnect(edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[ 128 ] )
|
void MM_PRE_HOOK EXT_FUNC mm_ClientConnect(edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[128] )
|
||||||
{
|
{
|
||||||
g_players.clear_player_cvar_query(pEntity);
|
g_players.clear_player_cvar_query(pEntity);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mm_ClientDisconnect(edict_t *pEntity)
|
void MM_PRE_HOOK EXT_FUNC mm_ClientDisconnect(edict_t *pEntity)
|
||||||
{
|
{
|
||||||
g_players.clear_player_cvar_query(pEntity);
|
g_players.clear_player_cvar_query(pEntity);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mm_ClientCommand(edict_t *pEntity)
|
void MM_PRE_HOOK mm_ClientCommand(edict_t *pEntity)
|
||||||
{
|
{
|
||||||
if (!strcmp(CMD_ARGV(0), "meta")) {
|
if (!strcmp(CMD_ARGV(0), "meta")) {
|
||||||
client_meta(pEntity);
|
client_meta(pEntity);
|
||||||
@ -147,7 +147,7 @@ compile_data_t g_newdllfunc_cdata[] =
|
|||||||
// GetAPI or not..
|
// GetAPI or not..
|
||||||
C_DLLEXPORT int GetEntityAPI(DLL_FUNCTIONS *pFunctionTable, int interfaceVersion)
|
C_DLLEXPORT int GetEntityAPI(DLL_FUNCTIONS *pFunctionTable, int interfaceVersion)
|
||||||
{
|
{
|
||||||
META_DEBUG(3, ("called: GetEntityAPI; version=%d", interfaceVersion));
|
META_DEBUG(3, "called: GetEntityAPI; version=%d", interfaceVersion);
|
||||||
if (!pFunctionTable)
|
if (!pFunctionTable)
|
||||||
{
|
{
|
||||||
META_ERROR("GetEntityAPI called with null pFunctionTable");
|
META_ERROR("GetEntityAPI called with null pFunctionTable");
|
||||||
@ -165,7 +165,7 @@ C_DLLEXPORT int GetEntityAPI(DLL_FUNCTIONS *pFunctionTable, int interfaceVersion
|
|||||||
|
|
||||||
C_DLLEXPORT int GetEntityAPI2(DLL_FUNCTIONS *pFunctionTable, int *interfaceVersion)
|
C_DLLEXPORT int GetEntityAPI2(DLL_FUNCTIONS *pFunctionTable, int *interfaceVersion)
|
||||||
{
|
{
|
||||||
META_DEBUG(3, ("called: GetEntityAPI2; version=%d", *interfaceVersion));
|
META_DEBUG(3, "called: GetEntityAPI2; version=%d", *interfaceVersion);
|
||||||
|
|
||||||
if (!pFunctionTable)
|
if (!pFunctionTable)
|
||||||
{
|
{
|
||||||
@ -186,7 +186,7 @@ C_DLLEXPORT int GetEntityAPI2(DLL_FUNCTIONS *pFunctionTable, int *interfaceVersi
|
|||||||
|
|
||||||
C_DLLEXPORT int GetNewDLLFunctions(NEW_DLL_FUNCTIONS *pNewFunctionTable, int *interfaceVersion)
|
C_DLLEXPORT int GetNewDLLFunctions(NEW_DLL_FUNCTIONS *pNewFunctionTable, int *interfaceVersion)
|
||||||
{
|
{
|
||||||
META_DEBUG(6, ("called: GetNewDLLFunctions; version=%d", *interfaceVersion));
|
META_DEBUG(6, "called: GetNewDLLFunctions; version=%d", *interfaceVersion);
|
||||||
#if 0 // ~dvander - but then you can't use cvar querying on many mods...
|
#if 0 // ~dvander - but then you can't use cvar querying on many mods...
|
||||||
// Don't provide these functions to engine if gamedll doesn't provide
|
// Don't provide these functions to engine if gamedll doesn't provide
|
||||||
// them. Otherwise, we're in the position of having to provide answers
|
// them. Otherwise, we're in the position of having to provide answers
|
||||||
|
@ -3,28 +3,28 @@
|
|||||||
#define CDATA_ENG_H(x, p, h) CDATA_ENTRY(enginefuncs_t, x, p, size_t(h))
|
#define CDATA_ENG_H(x, p, h) CDATA_ENTRY(enginefuncs_t, x, p, size_t(h))
|
||||||
#define CDATA_ENG(x) CDATA_ENTRY(enginefuncs_t, x, P_PRE, 0u)
|
#define CDATA_ENG(x) CDATA_ENTRY(enginefuncs_t, x, P_PRE, 0u)
|
||||||
|
|
||||||
meta_enginefuncs_t meta_engfuncs; // static addresses for gamedll
|
meta_enginefuncs_t meta_engfuncs; // static trampolines to dynamic callbacks (for gamedll)
|
||||||
meta_enginefuncs_t meta_engfuncs_jit; // dynamic jit callbacks
|
meta_enginefuncs_t meta_engfuncs_jit; // dynamic jit callbacks
|
||||||
|
|
||||||
void mm_QueryClientCvarValue(const edict_t* pEdict, const char* cvarName)
|
void MM_PRE_HOOK mm_QueryClientCvarValue(const edict_t* pEdict, const char* cvarName)
|
||||||
{
|
{
|
||||||
g_players.set_player_cvar_query(pEdict, cvarName);
|
g_players.set_player_cvar_query(pEdict, cvarName);
|
||||||
}
|
}
|
||||||
|
|
||||||
// int -> void
|
// int -> void
|
||||||
void mm_RegUserMsg(const char* pszName, int iSize)
|
void MM_POST_HOOK mm_RegUserMsg(const char* pszName, int iSize)
|
||||||
{
|
{
|
||||||
// Add the msgid, name, and size to our saved list, if we haven't already.
|
// Add the msgid, name, and size to our saved list, if we haven't already.
|
||||||
auto imsgid = *(int *)(g_metaGlobals.status == MRES_OVERRIDE ? g_metaGlobals.override_ret : g_metaGlobals.orig_ret);
|
auto imsgid = *(int *)(g_metaGlobals.status == MRES_OVERRIDE ? g_metaGlobals.override_ret : g_metaGlobals.orig_ret);
|
||||||
auto nmsg = g_regMsgs->find(imsgid);
|
auto nmsg = g_regMsgs->find(imsgid);
|
||||||
|
|
||||||
if (nmsg) {
|
if (nmsg) {
|
||||||
if (!strcmp(pszName, nmsg->name))
|
if (!Q_strcmp(pszName, nmsg->getname()))
|
||||||
// This name/msgid pair was already registered.
|
// This name/msgid pair was already registered.
|
||||||
META_DEBUG(3, ("user message registered again: name=%s, msgid=%d", pszName, imsgid));
|
META_DEBUG(3, "user message registered again: name=%s, msgid=%d", pszName, imsgid);
|
||||||
else
|
else
|
||||||
// This msgid was previously used by a different message name.
|
// This msgid was previously used by a different message name.
|
||||||
META_ERROR("user message id reused: msgid=%d, oldname=%s, newname=%s", imsgid, nmsg->name, pszName);
|
META_ERROR("user message id reused: msgid=%d, oldname=%s, newname=%s", imsgid, nmsg->getname(), pszName);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
g_regMsgs->add(pszName, imsgid, iSize);
|
g_regMsgs->add(pszName, imsgid, iSize);
|
||||||
|
@ -11,11 +11,11 @@
|
|||||||
extern cvar_t meta_debug;
|
extern cvar_t meta_debug;
|
||||||
|
|
||||||
template<typename ...t_args>
|
template<typename ...t_args>
|
||||||
void META_DEBUG(int level, t_args... args)
|
void META_DEBUG(int level, const char* fmt, t_args... args)
|
||||||
{
|
{
|
||||||
if (meta_debug.value < level)
|
if (meta_debug.value < level)
|
||||||
return;
|
return;
|
||||||
ALERT(at_logged, "[META] (debug:%i) %s\n", level, args...);
|
ALERT(at_logged, "[META] (debug:%i) %s\n", level, args...); // TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
void META_CONS(const char *fmt, ...);
|
void META_CONS(const char *fmt, ...);
|
||||||
|
@ -391,11 +391,11 @@ bool MPluginList::ini_startup()
|
|||||||
{
|
{
|
||||||
if (pmatch->pfspecific >= plist[n].pfspecific)
|
if (pmatch->pfspecific >= plist[n].pfspecific)
|
||||||
{
|
{
|
||||||
META_DEBUG(1, ("ini: Skipping plugin, line %d of %s: plugin with higher platform specific level already exists. (%d >= %d)", ln, inifile, pmatch->pfspecific, plist[n].pfspecific));
|
META_DEBUG(1, "ini: Skipping plugin, line %d of %s: plugin with higher platform specific level already exists. (%d >= %d)", ln, inifile, pmatch->pfspecific, plist[n].pfspecific);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
META_DEBUG(1, ("ini: Plugin in line %d overrides existing plugin with lower platform specific level %d, ours %d", ln, pmatch->pfspecific, plist[n].pfspecific));
|
META_DEBUG(1, "ini: Plugin in line %d overrides existing plugin with lower platform specific level %d, ours %d", ln, pmatch->pfspecific, plist[n].pfspecific);
|
||||||
int _index = pmatch->index;
|
int _index = pmatch->index;
|
||||||
Q_memset(pmatch, 0, sizeof(MPlugin));
|
Q_memset(pmatch, 0, sizeof(MPlugin));
|
||||||
pmatch->index = _index;
|
pmatch->index = _index;
|
||||||
@ -462,19 +462,19 @@ bool MPluginList::ini_refresh()
|
|||||||
{
|
{
|
||||||
if (pl_found->pfspecific >= pl_temp.pfspecific)
|
if (pl_found->pfspecific >= pl_temp.pfspecific)
|
||||||
{
|
{
|
||||||
META_DEBUG(1, ("ini: Skipping plugin, line %d of %s: plugin with higher platform specific level already exists. (%d >= %d)", ln, inifile, pl_found->pfspecific, pl_temp.pfspecific));
|
META_DEBUG(1, "ini: Skipping plugin, line %d of %s: plugin with higher platform specific level already exists. (%d >= %d)", ln, inifile, pl_found->pfspecific, pl_temp.pfspecific);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (PA_LOAD == pl_found->action)
|
if (PA_LOAD == pl_found->action)
|
||||||
{
|
{
|
||||||
META_DEBUG(1, ("ini: Plugin in line %d overrides loading of plugin with lower platform specific level %d, ours %d", ln, pl_found->pfspecific, pl_temp.pfspecific));
|
META_DEBUG(1, "ini: Plugin in line %d overrides loading of plugin with lower platform specific level %d, ours %d", ln, pl_found->pfspecific, pl_temp.pfspecific);
|
||||||
int _index = pl_found->index;
|
int _index = pl_found->index;
|
||||||
Q_memset(pl_found, 0, sizeof(MPlugin));
|
Q_memset(pl_found, 0, sizeof(MPlugin));
|
||||||
pl_found->index = _index;
|
pl_found->index = _index;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
META_DEBUG(1, ("ini: Plugin in line %d should override existing plugin with lower platform specific level %d, ours %d. Unable to comply.", ln, pl_found->pfspecific, pl_temp.pfspecific));
|
META_DEBUG(1, "ini: Plugin in line %d should override existing plugin with lower platform specific level %d, ours %d. Unable to comply.", ln, pl_found->pfspecific, pl_temp.pfspecific);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -946,7 +946,8 @@ bool MPlugin::attach(PLUG_LOADTIME now)
|
|||||||
if (!engine_table) engine_table = (meta_enginefuncs_t *)calloc(1, sizeof(meta_enginefuncs_t));
|
if (!engine_table) engine_table = (meta_enginefuncs_t *)calloc(1, sizeof(meta_enginefuncs_t));
|
||||||
if (meta_table.pfnGetEngineFunctions(engine_table, &iface_vers)) {
|
if (meta_table.pfnGetEngineFunctions(engine_table, &iface_vers)) {
|
||||||
do {
|
do {
|
||||||
if (meta_debug.value < 3) break; else (*g_engfuncs.pfnAlertMessage)(at_logged, "[META] (debug:%d) %s\n", 3, UTIL_VarArgs("dll: Plugin '%s': Found %s", desc, "GetEngineFunctions"));
|
if (meta_debug.value < 3) break;
|
||||||
|
else (*g_engfuncs.pfnAlertMessage)(at_logged, "[META] (debug:%d) %s\n", 3, UTIL_VarArgs("dll: Plugin '%s': Found %s", desc, "GetEngineFunctions"));
|
||||||
}
|
}
|
||||||
while (0);
|
while (0);
|
||||||
}
|
}
|
||||||
@ -1412,7 +1413,7 @@ bool MPlugin::newer_file()
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
file_time = st.st_ctime > st.st_mtime ? st.st_ctime : st.st_mtime;
|
file_time = st.st_ctime > st.st_mtime ? st.st_ctime : st.st_mtime;
|
||||||
META_DEBUG(5, ("newer_file? file=%s; load=%d, file=%d; ctime=%d, mtime=%d", file, time_loaded, file_time, st.st_ctime, st.st_mtime));
|
META_DEBUG(5, "newer_file? file=%s; load=%d, file=%d; ctime=%d, mtime=%d", file, time_loaded, file_time, st.st_ctime, st.st_mtime);
|
||||||
if (file_time > time_loaded)
|
if (file_time > time_loaded)
|
||||||
return true;
|
return true;
|
||||||
else
|
else
|
||||||
|
@ -1,26 +1,31 @@
|
|||||||
#include "precompiled.h"
|
#include "precompiled.h"
|
||||||
|
|
||||||
MRegCmd::MRegCmd(char* cmd_name, REG_CMD_FN cmd_handler, MPlugin* cmd_plugin) : pfnCmd(cmd_handler), status(RG_VALID), plugid(cmd_plugin->index)
|
MRegCmd::MRegCmd(char* cmd_name, REG_CMD_FN cmd_handler, MPlugin* cmd_plugin) : m_pfunction(cmd_handler), m_status(RG_VALID), m_plugid(cmd_plugin->index)
|
||||||
{
|
{
|
||||||
name = _strdup(name);
|
m_name = _strdup(m_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MRegCmd::call() const
|
bool MRegCmd::call() const
|
||||||
{
|
{
|
||||||
pfnCmd();
|
m_pfunction();
|
||||||
return status != RG_INVALID;
|
return m_status != RG_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MRegCmd::disable()
|
void MRegCmd::disable()
|
||||||
{
|
{
|
||||||
pfnCmd = [](){};
|
m_pfunction = [](){};
|
||||||
plugid = 0;
|
m_plugid = 0;
|
||||||
status = RG_INVALID;
|
m_status = RG_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* MRegCmd::getname() const
|
char* MRegCmd::getname() const
|
||||||
{
|
{
|
||||||
return name;
|
return m_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
REG_CMD_FN MRegCmd::gethandler() const
|
||||||
|
{
|
||||||
|
return m_pfunction;
|
||||||
}
|
}
|
||||||
|
|
||||||
MRegCmdList::MRegCmdList() : m_list()
|
MRegCmdList::MRegCmdList() : m_list()
|
||||||
@ -29,10 +34,10 @@ MRegCmdList::MRegCmdList() : m_list()
|
|||||||
|
|
||||||
MRegCmd *MRegCmdList::find(const char *name) const
|
MRegCmd *MRegCmdList::find(const char *name) const
|
||||||
{
|
{
|
||||||
for (auto icmd : m_list)
|
for (auto reg : m_list)
|
||||||
{
|
{
|
||||||
if (!Q_stricmp(icmd->name, name))
|
if (!Q_stricmp(reg->m_name, name))
|
||||||
return icmd;
|
return reg;
|
||||||
}
|
}
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -40,23 +45,23 @@ MRegCmd *MRegCmdList::find(const char *name) const
|
|||||||
|
|
||||||
MRegCmd *MRegCmdList::add(char *addname, REG_CMD_FN cmd_handler, MPlugin* cmd_plugin)
|
MRegCmd *MRegCmdList::add(char *addname, REG_CMD_FN cmd_handler, MPlugin* cmd_plugin)
|
||||||
{
|
{
|
||||||
auto icmd = new MRegCmd(addname, cmd_handler, cmd_plugin);
|
auto reg = new MRegCmd(addname, cmd_handler, cmd_plugin);
|
||||||
m_list.push_back(icmd);
|
m_list.push_back(reg);
|
||||||
return icmd;
|
return reg;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MRegCmdList::remove(char* cmd_name)
|
void MRegCmdList::remove(char* cmd_name)
|
||||||
{
|
{
|
||||||
for (auto it = m_list.begin(), end = m_list.end(); it != end; ++it) {
|
for (auto it = m_list.begin(), end = m_list.end(); it != end; ++it) {
|
||||||
auto icmd = *it;
|
auto reg = *it;
|
||||||
|
|
||||||
if (!Q_stricmp(icmd->name, cmd_name)) {
|
if (!Q_stricmp(reg->m_name, cmd_name)) {
|
||||||
if (g_RehldsFuncs) {
|
if (g_RehldsFuncs) {
|
||||||
g_RehldsFuncs->Cmd_RemoveCmd(cmd_name);
|
g_RehldsFuncs->Cmd_RemoveCmd(cmd_name);
|
||||||
m_list.erase(it);
|
m_list.erase(it);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
icmd->disable();
|
reg->disable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -66,15 +71,15 @@ void MRegCmdList::remove(char* cmd_name)
|
|||||||
void MRegCmdList::remove(int owner_plugin_id)
|
void MRegCmdList::remove(int owner_plugin_id)
|
||||||
{
|
{
|
||||||
for (auto it = m_list.begin(), end = m_list.end(); it != end; ++it) {
|
for (auto it = m_list.begin(), end = m_list.end(); it != end; ++it) {
|
||||||
auto icmd = *it;
|
auto reg = *it;
|
||||||
|
|
||||||
if (icmd->plugid == owner_plugin_id) {
|
if (reg->m_plugid == owner_plugin_id) {
|
||||||
if (g_RehldsFuncs) {
|
if (g_RehldsFuncs) {
|
||||||
g_RehldsFuncs->Cmd_RemoveCmd(icmd->name);
|
g_RehldsFuncs->Cmd_RemoveCmd(reg->m_name);
|
||||||
m_list.erase(it);
|
m_list.erase(it);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
icmd->disable();
|
reg->disable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -83,17 +88,17 @@ void MRegCmdList::remove(int owner_plugin_id)
|
|||||||
// List all the registered commands.
|
// List all the registered commands.
|
||||||
void MRegCmdList::show() const
|
void MRegCmdList::show() const
|
||||||
{
|
{
|
||||||
int n = 0, a = 0;
|
int total_count = 0, valid_count = 0;
|
||||||
char bplug[18 + 1]; // +1 for term null
|
char bplug[18 + 1]; // +1 for term null
|
||||||
|
|
||||||
META_CONS("Registered plugin commands:");
|
META_CONS("Registered plugin commands:");
|
||||||
META_CONS(" %*s %-*s %-s", WIDTH_MAX_REG, "", sizeof bplug - 1, "plugin", "command");
|
META_CONS(" %*s %-*s %-s", WIDTH_MAX_REG, "", sizeof bplug - 1, "plugin", "command");
|
||||||
|
|
||||||
for (auto icmd : m_list)
|
for (auto reg : m_list)
|
||||||
{
|
{
|
||||||
if (icmd->status == RG_VALID)
|
if (reg->m_status == RG_VALID)
|
||||||
{
|
{
|
||||||
auto iplug = g_plugins->find(icmd->plugid);
|
auto iplug = g_plugins->find(reg->m_plugid);
|
||||||
|
|
||||||
Q_strncpy(bplug, iplug ? iplug->desc : "(unknown)", sizeof bplug - 1);
|
Q_strncpy(bplug, iplug ? iplug->desc : "(unknown)", sizeof bplug - 1);
|
||||||
bplug[sizeof bplug - 1] = '\0';
|
bplug[sizeof bplug - 1] = '\0';
|
||||||
@ -104,136 +109,67 @@ void MRegCmdList::show() const
|
|||||||
bplug[sizeof bplug - 1] = '\0';
|
bplug[sizeof bplug - 1] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
META_CONS(" [%*d] %-*s %-s", WIDTH_MAX_REG, ++n, sizeof bplug - 1, bplug, icmd->name);
|
META_CONS(" [%*d] %-*s %-s", WIDTH_MAX_REG, ++total_count, sizeof bplug - 1, bplug, reg->m_name);
|
||||||
|
|
||||||
if (icmd->status == RG_VALID)
|
if (reg->m_status == RG_VALID)
|
||||||
a++;
|
valid_count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
META_CONS("%d commands, %d available", n, a);
|
META_CONS("%d commands, %d available", total_count, valid_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
// List all the registered commands for the given plugin id.
|
// List all the registered commands for the given plugin id.
|
||||||
void MRegCmdList::show(int plugin_id) const
|
void MRegCmdList::show(int plugin_id) const
|
||||||
{
|
{
|
||||||
int n = 0;
|
int total_count = 0;
|
||||||
|
|
||||||
META_CONS("Registered commands:");
|
META_CONS("Registered commands:");
|
||||||
for (auto icmd : m_list)
|
|
||||||
|
for (auto reg : m_list)
|
||||||
{
|
{
|
||||||
if (icmd->plugid != plugin_id)
|
if (reg->m_plugid != plugin_id)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
META_CONS(" %s", icmd->name);
|
META_CONS(" %s", reg->m_name);
|
||||||
n++;
|
total_count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
META_CONS("%d commands", n);
|
META_CONS("%d commands", total_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Init values. It would probably be more "proper" to use containers and
|
MRegCvar::MRegCvar(cvar_t* cv_ptr, MPlugin* cv_plugin) : m_cvar(cv_ptr), m_plugid(cv_plugin->index), m_status(RG_VALID)
|
||||||
// constructors, rather than arrays and init-functions.
|
|
||||||
void MRegCvar::init(int idx)
|
|
||||||
{
|
{
|
||||||
index = idx;
|
m_cvar = g_static_allocator.allocate<cvar_t>();
|
||||||
data = NULL;
|
m_cvar->name = _strdup(cv_ptr->name);
|
||||||
plugid = 0;
|
m_cvar->string = _strdup(cv_ptr->string);
|
||||||
status = RG_INVALID;
|
m_cvar->flags = cv_ptr->flags;
|
||||||
|
m_cvar->value = cv_ptr->value;
|
||||||
|
m_cvar->next = cv_ptr->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the cvar, copying values from given cvar.
|
cvar_t* MRegCvar::getcvar() const
|
||||||
// meta_errno values:
|
|
||||||
// - ME_ARGUMENT given cvar doesn't match this cvar
|
|
||||||
bool MRegCvar::set(cvar_t *src) const
|
|
||||||
{
|
{
|
||||||
if (Q_stricmp(src->name, data->name))
|
return m_cvar;
|
||||||
{
|
|
||||||
META_ERROR("Tried to set cvar with mismatched name; src=%s dst=%s", src->name, data->name);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Would like to free() existing string, but can't tell where it was
|
|
||||||
// allocated...
|
|
||||||
data->string = Q_strdup(src->string);
|
|
||||||
data->flags = src->flags;
|
|
||||||
data->value = src->value;
|
|
||||||
data->next = src->next;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
MRegCvarList::MRegCvarList()
|
MRegCvarList::MRegCvarList() : m_list()
|
||||||
: vlist(0), size(REG_CVAR_GROWSIZE), endlist(0)
|
|
||||||
{
|
{
|
||||||
vlist = (MRegCvar *)Q_malloc(size * sizeof(MRegCvar));
|
|
||||||
|
|
||||||
// initialize array
|
|
||||||
for (int i = 0; i < size; i++)
|
|
||||||
vlist[i].init(i + 1); // 1 - based
|
|
||||||
|
|
||||||
endlist = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the given cvar name to the list and return the instance. This only
|
MRegCvar *MRegCvarList::add(cvar_t* src, MPlugin* plugin)
|
||||||
// writes the "name" to the new cvar; other fields are written with
|
|
||||||
// cvar::set().
|
|
||||||
// meta_errno values:
|
|
||||||
// - ME_NOMEM couldn't alloc or realloc for various parts
|
|
||||||
MRegCvar *MRegCvarList::add(const char *addname)
|
|
||||||
{
|
{
|
||||||
MRegCvar *icvar;
|
MRegCvar *reg_cvar = new(g_static_allocator.allocate<MRegCvar>()) MRegCvar(src, plugin);
|
||||||
if (endlist == size)
|
m_list.push_back(reg_cvar);
|
||||||
{
|
return reg_cvar;
|
||||||
// grow array
|
|
||||||
int newsize = size + REG_CVAR_GROWSIZE;
|
|
||||||
|
|
||||||
META_DEBUG(6, ("Growing reg cvar list from %d to %d", size, newsize));
|
|
||||||
MRegCvar *temp = (MRegCvar *) realloc(vlist, newsize * sizeof(MRegCvar));
|
|
||||||
if (!temp)
|
|
||||||
{
|
|
||||||
META_ERROR("Couldn't grow registered cvar list to %d for '%s'; %s", newsize, addname, strerror(errno));
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
vlist = temp;
|
|
||||||
size = newsize;
|
|
||||||
// initialize new (unused) entries
|
|
||||||
for (int i = endlist; i < size; i++)
|
|
||||||
vlist[i].init(i + 1); // 1-based
|
|
||||||
}
|
|
||||||
|
|
||||||
icvar = &vlist[endlist];
|
|
||||||
|
|
||||||
// Malloc space for the cvar and cvar name, for two reasons:
|
|
||||||
// - Can't point to memory loc in plugin (another segv waiting to
|
|
||||||
// happen).
|
|
||||||
// - Can't point to memory in vlist which might get moved later by
|
|
||||||
// realloc (again, segv).
|
|
||||||
icvar->data = (cvar_t *)Q_malloc(sizeof(cvar_t));
|
|
||||||
if (!icvar->data)
|
|
||||||
{
|
|
||||||
META_ERROR("Couldn't malloc cvar for adding reg cvar name '%s': %s", addname, strerror(errno));
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
icvar->data->name = Q_strdup(addname);
|
|
||||||
if (!icvar->data->name)
|
|
||||||
{
|
|
||||||
META_ERROR("Couldn't Q_strdup for adding reg cvar name '%s': %s", addname, strerror(errno));
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
endlist++;
|
|
||||||
return icvar;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to find a registered cvar with the given name.
|
|
||||||
// meta_errno values:
|
|
||||||
// - ME_NOTFOUND couldn't find a matching cvar
|
|
||||||
MRegCvar *MRegCvarList::find(const char *findname)
|
MRegCvar *MRegCvarList::find(const char *findname)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < endlist; i++)
|
for (auto reg : m_list)
|
||||||
{
|
{
|
||||||
if (!_stricmp(vlist[i].data->name, findname))
|
if (!Q_stricmp(reg->m_cvar->name, findname))
|
||||||
return &vlist[i];
|
return reg;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -242,18 +178,12 @@ MRegCvar *MRegCvarList::find(const char *findname)
|
|||||||
// Disable any cvars belonging to the given plugin (by index id).
|
// Disable any cvars belonging to the given plugin (by index id).
|
||||||
void MRegCvarList::disable(int plugin_id) const
|
void MRegCvarList::disable(int plugin_id) const
|
||||||
{
|
{
|
||||||
int i;
|
for (auto reg : m_list)
|
||||||
MRegCvar *icvar;
|
|
||||||
for (i = 0; i < size; i++)
|
|
||||||
{
|
{
|
||||||
icvar = &vlist[i];
|
if (reg->m_plugid == plugin_id)
|
||||||
if (icvar->plugid == plugin_id)
|
|
||||||
{
|
{
|
||||||
icvar->status = RG_INVALID;
|
reg->m_status = RG_INVALID;
|
||||||
icvar->plugid = 0;
|
reg->m_plugid = 0;
|
||||||
// Decided not to do this, in order to keep pre-existing values
|
|
||||||
// after a plugin reload.
|
|
||||||
// CVAR_SET_STRING(icvar->data->name, "[metamod: cvar invalid; plugin unloaded]");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -261,29 +191,19 @@ void MRegCvarList::disable(int plugin_id) const
|
|||||||
// List all the registered cvars.
|
// List all the registered cvars.
|
||||||
void MRegCvarList::show() const
|
void MRegCvarList::show() const
|
||||||
{
|
{
|
||||||
int i, n = 0, a = 0;
|
int total_count = 0, valid_count = 0;
|
||||||
MRegCvar *icvar;
|
|
||||||
MPlugin *iplug;
|
|
||||||
char bplug[13 + 1], bname[20 + 1], bval[15 + 1]; // +1 for term null
|
char bplug[13 + 1], bname[20 + 1], bval[15 + 1]; // +1 for term null
|
||||||
|
|
||||||
META_CONS("Registered plugin cvars:");
|
META_CONS("Registered plugin cvars:");
|
||||||
META_CONS(" %*s %-*s %-*s %*s %s", WIDTH_MAX_REG, "", sizeof(bplug) - 1, "plugin", sizeof(bname) - 1, "cvar", sizeof(bval) - 1, "float value", "string value");
|
META_CONS(" %*s %-*s %-*s %*s %s", WIDTH_MAX_REG, "", sizeof bplug - 1, "plugin", sizeof bname - 1, "cvar", sizeof bval - 1, "float value", "string value");
|
||||||
for (i = 0; i < endlist; i++)
|
|
||||||
|
for (auto reg : m_list)
|
||||||
{
|
{
|
||||||
icvar = &vlist[i];
|
if (reg->m_status == RG_VALID)
|
||||||
if (icvar->status == RG_VALID)
|
|
||||||
{
|
{
|
||||||
iplug = g_plugins->find(icvar->plugid);
|
auto plug = g_plugins->find(reg->m_plugid);
|
||||||
if (iplug)
|
Q_strncpy(bplug, plug ? plug->desc : "(unknown)", sizeof bplug - 1);
|
||||||
{
|
bplug[sizeof bplug - 1] = '\0';
|
||||||
Q_strncpy(bplug, iplug->desc, sizeof bplug - 1);
|
|
||||||
bplug[sizeof bplug - 1] = '\0';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Q_strncpy(bplug, "(unknown)", sizeof bplug - 1);
|
|
||||||
bplug[sizeof bplug - 1] = '\0';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -291,127 +211,110 @@ void MRegCvarList::show() const
|
|||||||
bplug[sizeof bplug - 1] = '\0';
|
bplug[sizeof bplug - 1] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
Q_strncpy(bname, icvar->data->name, sizeof bname - 1);
|
Q_strncpy(bname, reg->m_cvar->name, sizeof bname - 1);
|
||||||
bname[sizeof bname - 1] = '\0';
|
bname[sizeof bname - 1] = '\0';
|
||||||
Q_snprintf(bval, sizeof(bval), "%f", icvar->data->value);
|
Q_snprintf(bval, sizeof bval, "%f", reg->m_cvar->value);
|
||||||
META_CONS(" [%*d] %-*s %-*s %*s %s", WIDTH_MAX_REG, icvar->index, sizeof(bplug) - 1, bplug, sizeof(bname) - 1, bname, sizeof(bval) - 1, bval, icvar->data->string);
|
META_CONS(" [%*d] %-*s %-*s %*s %s", WIDTH_MAX_REG, ++total_count, sizeof bplug - 1, bplug, sizeof bname - 1, bname, sizeof bval - 1, bval, reg->m_cvar->string);
|
||||||
|
|
||||||
if (icvar->status == RG_VALID)
|
if (reg->m_status == RG_VALID)
|
||||||
a++;
|
valid_count++;
|
||||||
|
|
||||||
n++;
|
|
||||||
}
|
}
|
||||||
META_CONS("%d cvars, %d available (%d allocated)", n, a, size);
|
|
||||||
|
META_CONS("%d cvars, %d available", total_count, valid_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
// List the registered cvars for the given plugin id.
|
// List the registered cvars for the given plugin id.
|
||||||
void MRegCvarList::show(int plugin_id) const
|
void MRegCvarList::show(int plugin_id) const
|
||||||
{
|
{
|
||||||
int n = 0;
|
int total_count = 0;
|
||||||
MRegCvar *icvar;
|
|
||||||
char bname[30 + 1], bval[15 + 1]; // +1 for term null
|
char bname[30 + 1], bval[15 + 1]; // +1 for term null
|
||||||
|
|
||||||
META_CONS("%-*s %*s %s", sizeof(bname) - 1, "Registered cvars:", sizeof(bval) - 1, "float value", "string value");
|
META_CONS("%-*s %*s %s", sizeof(bname) - 1, "Registered cvars:", sizeof bval - 1, "float value", "string value");
|
||||||
for (int i = 0; i < endlist; i++)
|
|
||||||
|
for (auto reg : m_list)
|
||||||
{
|
{
|
||||||
icvar = &vlist[i];
|
if (reg->m_plugid != plugin_id)
|
||||||
if (icvar->plugid != plugin_id)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Q_strncpy(bname, icvar->data->name, sizeof bname - 1);
|
Q_strncpy(bname, reg->m_cvar->name, sizeof bname - 1);
|
||||||
bname[sizeof bname - 1] = '\0';
|
bname[sizeof bname - 1] = '\0';
|
||||||
Q_snprintf(bval, sizeof(bval), "%f", icvar->data->value);
|
Q_snprintf(bval, sizeof(bval), "%f", reg->m_cvar->value);
|
||||||
META_CONS(" %-*s %*s %s", sizeof(bname) - 1, bname, sizeof(bval) - 1, bval, icvar->data->string);
|
META_CONS(" %-*s %*s %s", sizeof(bname) - 1, bname, sizeof(bval) - 1, bval, reg->m_cvar->string);
|
||||||
n++;
|
total_count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
META_CONS("%d cvars", n);
|
META_CONS("%d cvars", total_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Constructor
|
MRegMsg::MRegMsg(const char* name, int msgid, int size) : m_name(name), m_msgid(msgid), m_size(size)
|
||||||
MRegMsgList::MRegMsgList()
|
{
|
||||||
: size(MAX_REG_MSGS), endlist(0)
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* MRegMsg::getname() const
|
||||||
|
{
|
||||||
|
return m_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
int MRegMsg::getid() const
|
||||||
|
{
|
||||||
|
return m_msgid;
|
||||||
|
}
|
||||||
|
|
||||||
|
int MRegMsg::getsize() const
|
||||||
|
{
|
||||||
|
return m_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
MRegMsgList::MRegMsgList() : m_list()
|
||||||
{
|
{
|
||||||
// initialize array
|
|
||||||
Q_memset(mlist, 0, sizeof(mlist));
|
|
||||||
for (int i = 0; i < size; i++)
|
|
||||||
{
|
|
||||||
mlist[i].index = i + 1; // 1-based
|
|
||||||
}
|
|
||||||
|
|
||||||
endlist = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the given user msg the list and return the instance.
|
|
||||||
// meta_errno values:
|
|
||||||
// - ME_MAXREACHED reached max number of msgs allowed
|
|
||||||
MRegMsg *MRegMsgList::add(const char *addname, int addmsgid, int addsize)
|
MRegMsg *MRegMsgList::add(const char *addname, int addmsgid, int addsize)
|
||||||
{
|
{
|
||||||
if (endlist == size)
|
|
||||||
{
|
|
||||||
// all slots used
|
|
||||||
META_ERROR("Couldn't add registered msg '%s' to list; reached max msgs (%d)", addname, size);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
MRegMsg *imsg = &mlist[endlist];
|
|
||||||
endlist++;
|
|
||||||
|
|
||||||
// Copy msg data into empty slot.
|
// Copy msg data into empty slot.
|
||||||
// Note: 'addname' assumed to be a constant string allocated in the
|
// Note: 'addname' assumed to be a constant string allocated in the
|
||||||
// gamedll.
|
// gamedll.
|
||||||
imsg->name = addname;
|
auto msg = new(g_static_allocator.allocate<MRegMsg>()) MRegMsg(addname, addmsgid, addsize);
|
||||||
imsg->msgid = addmsgid;
|
m_list.push_back(msg);
|
||||||
imsg->size = addsize;
|
return msg;
|
||||||
|
|
||||||
return imsg;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to find a registered msg with the given name.
|
|
||||||
// meta_errno values:
|
|
||||||
// - ME_NOTFOUND couldn't find a matching cvar
|
|
||||||
MRegMsg *MRegMsgList::find(const char *findname)
|
MRegMsg *MRegMsgList::find(const char *findname)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < endlist; i++)
|
for (auto msg : m_list)
|
||||||
{
|
{
|
||||||
if (!Q_strcmp(mlist[i].name, findname))
|
if (!Q_strcmp(msg->m_name, findname))
|
||||||
return &mlist[i];
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to find a registered msg with the given msgid.
|
|
||||||
// meta_errno values:
|
|
||||||
// - ME_NOTFOUND couldn't find a matching cvar
|
|
||||||
MRegMsg *MRegMsgList::find(int findmsgid)
|
MRegMsg *MRegMsgList::find(int findmsgid)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < endlist; i++)
|
for (auto msg : m_list) {
|
||||||
{
|
if (msg->m_msgid == findmsgid)
|
||||||
if (mlist[i].msgid == findmsgid)
|
return msg;
|
||||||
return &mlist[i];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// List the registered usermsgs for the gamedll.
|
// List the registered usermsgs for the gamedll.
|
||||||
void MRegMsgList::show()
|
void MRegMsgList::show()
|
||||||
{
|
{
|
||||||
int i, n = 0;
|
int total_count = 0;
|
||||||
MRegMsg *imsg;
|
|
||||||
char bname[25 + 1]; // +1 for term null
|
char bname[25 + 1]; // +1 for term null
|
||||||
|
|
||||||
META_CONS("%-*s %5s %5s", sizeof(bname) - 1, "Game registered user msgs:", "msgid", "size");
|
META_CONS("%-*s %5s %5s", sizeof(bname) - 1, "Game registered user msgs:", "msgid", "size");
|
||||||
for (i = 0; i < endlist; i++)
|
|
||||||
{
|
for (auto msg : m_list) {
|
||||||
imsg = &mlist[i];
|
Q_strncpy(bname, msg->m_name, sizeof bname - 1);
|
||||||
|
|
||||||
Q_strncpy(bname, imsg->name, sizeof bname - 1);
|
|
||||||
bname[sizeof bname - 1] = '\0';
|
bname[sizeof bname - 1] = '\0';
|
||||||
META_CONS(" %-*s %3d %3d", sizeof(bname) - 1, bname, imsg->msgid, imsg->size);
|
META_CONS(" %-*s %3d %3d", sizeof(bname) - 1, bname, msg->m_msgid, msg->m_size);
|
||||||
n++;
|
total_count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
META_CONS("%d game user msgs", n);
|
META_CONS("%d game user msgs", total_count);
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,4 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "types_meta.h" // bool
|
|
||||||
|
|
||||||
// Number of entries to add to reglists when they need to grow. Typically
|
|
||||||
// more cvars than commands, so we grow them at different increments.
|
|
||||||
#define REG_CMD_GROWSIZE 32
|
|
||||||
#define REG_CVAR_GROWSIZE 64
|
|
||||||
|
|
||||||
// Width required to printf a Reg*List index number, for show() functions.
|
// Width required to printf a Reg*List index number, for show() functions.
|
||||||
// This used to correspond to the number of digits in MAX_REG, which was a
|
// This used to correspond to the number of digits in MAX_REG, which was a
|
||||||
@ -27,101 +21,97 @@ typedef void (*REG_CMD_FN)();
|
|||||||
class MPlugin;
|
class MPlugin;
|
||||||
|
|
||||||
// An individual registered function/command.
|
// An individual registered function/command.
|
||||||
class MRegCmd {
|
class MRegCmd
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
MRegCmd(char* cmd_name, REG_CMD_FN cmd_handler, MPlugin* cmd_plugin);
|
MRegCmd(char* cmd_name, REG_CMD_FN cmd_handler, MPlugin* cmd_plugin);
|
||||||
bool call() const; // try to call the function
|
bool call() const; // try to call the function
|
||||||
void disable();
|
void disable();
|
||||||
char* getname() const;
|
char* getname() const;
|
||||||
|
REG_CMD_FN gethandler() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
char *name; // space is malloc'd
|
char* m_name; // space is malloc'd
|
||||||
REG_CMD_FN pfnCmd; // pointer to the function
|
REG_CMD_FN m_pfunction; // pointer to the function
|
||||||
int plugid; // index id of corresponding plugin
|
int m_plugid; // index id of corresponding plugin
|
||||||
REG_STATUS status; // whether corresponding plugin is loaded
|
REG_STATUS m_status; // whether corresponding plugin is loaded
|
||||||
|
|
||||||
friend class MRegCmdList;
|
friend class MRegCmdList;
|
||||||
};
|
};
|
||||||
|
|
||||||
// A list of registered commands.
|
// A list of registered commands.
|
||||||
class MRegCmdList {
|
class MRegCmdList
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
MRegCmdList();
|
MRegCmdList();
|
||||||
|
MRegCmd *find(const char *name) const;
|
||||||
MRegCmd *find(const char *name) const; // find by MRegCmd->name
|
|
||||||
MRegCmd *add(char *name, REG_CMD_FN cmd_handler, MPlugin* cmd_plugin);
|
MRegCmd *add(char *name, REG_CMD_FN cmd_handler, MPlugin* cmd_plugin);
|
||||||
void remove(char* cmd_name);
|
void remove(char* cmd_name);
|
||||||
void remove(int owner_plugin_id); // change status to Invalid
|
void remove(int owner_plugin_id);
|
||||||
void show() const; // list all funcs to console
|
void show() const;
|
||||||
void show(int plugin_id) const; // list given plugin's funcs to console
|
void show(int plugin_id) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<MRegCmd *> m_list;
|
std::vector<MRegCmd *> m_list;
|
||||||
};
|
};
|
||||||
|
|
||||||
// An individual registered cvar.
|
// An individual registered cvar.
|
||||||
class MRegCvar {
|
class MRegCvar
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
friend class MRegCvarList;
|
MRegCvar(cvar_t* cv_ptr, MPlugin* cv_plugin);
|
||||||
|
cvar_t* getcvar() const;
|
||||||
cvar_t *data; // actual cvar structure, malloc'd
|
|
||||||
int plugid; // index id of corresponding plugin
|
|
||||||
REG_STATUS status; // whether corresponding plugin is loaded
|
|
||||||
|
|
||||||
void init(int idx); // init values, as not using constructors
|
|
||||||
bool set(cvar_t *src) const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int index; // 1-based
|
cvar_t* m_cvar;
|
||||||
|
int m_plugid;
|
||||||
|
REG_STATUS m_status;
|
||||||
|
|
||||||
|
friend class MRegCvarList;
|
||||||
};
|
};
|
||||||
|
|
||||||
// A list of registered cvars.
|
// A list of registered cvars.
|
||||||
class MRegCvarList {
|
class MRegCvarList
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
MRegCvarList();
|
MRegCvarList();
|
||||||
|
MRegCvar *add(cvar_t* src, MPlugin* plugin);
|
||||||
MRegCvar *add(const char *addname);
|
|
||||||
MRegCvar *find(const char *findname); // find by MRegCvar->data.name
|
MRegCvar *find(const char *findname); // find by MRegCvar->data.name
|
||||||
void disable(int plugin_id) const; // change status to Invalid
|
void disable(int plugin_id) const; // change status to Invalid
|
||||||
void show() const; // list all cvars to console
|
void show() const; // list all cvars to console
|
||||||
void show(int plugin_id) const; // list given plugin's cvars to console
|
void show(int plugin_id) const; // list given plugin's cvars to console
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MRegCvar *vlist; // malloc'd array of registered cvars
|
std::vector<MRegCvar *> m_list;
|
||||||
int size; // size of list, ie MAX_REG_CVARS
|
|
||||||
int endlist; // index of last used entry
|
|
||||||
// Private; to satisfy -Weffc++ "has pointer data members but does
|
|
||||||
// not override" copy/assignment constructor.
|
|
||||||
void operator=(const MRegCvarList &src);
|
|
||||||
MRegCvarList(const MRegCvarList &src);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// An individual registered user msg, from gamedll.
|
// An individual registered user msg, from gamedll.
|
||||||
class MRegMsg {
|
class MRegMsg
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
friend class MRegMsgList;
|
MRegMsg(const char* name, int msgid, int size);
|
||||||
|
const char* getname() const;
|
||||||
const char *name; // name, assumed constant string in gamedll
|
int getid() const;
|
||||||
int msgid; // msgid, assigned by engine
|
int getsize() const;
|
||||||
int size; // size, if given by gamedll
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int index; // 1-based
|
const char* m_name;
|
||||||
|
int m_msgid;
|
||||||
|
int m_size;
|
||||||
|
|
||||||
|
friend class MRegMsgList;
|
||||||
};
|
};
|
||||||
|
|
||||||
// A list of registered user msgs.
|
// A list of registered user msgs.
|
||||||
class MRegMsgList {
|
class MRegMsgList
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
MRegMsgList();
|
MRegMsgList();
|
||||||
|
|
||||||
MRegMsg *add(const char *addname, int addmsgid, int addsize);
|
MRegMsg *add(const char *addname, int addmsgid, int addsize);
|
||||||
MRegMsg *find(const char *findname);
|
MRegMsg *find(const char *findname);
|
||||||
MRegMsg *find(int findmsgid);
|
MRegMsg *find(int findmsgid);
|
||||||
void show(); // list all msgs to console
|
void show();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MRegMsg mlist[MAX_REG_MSGS]; // array of registered msgs
|
std::vector<MRegMsg *> m_list;
|
||||||
int size; // size of list, ie MAX_REG_MSGS
|
|
||||||
int endlist; // index of last used entry
|
|
||||||
};
|
};
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#include "precompiled.h"
|
#include "precompiled.h"
|
||||||
|
|
||||||
hudtextparms_t default_csay_tparms = {
|
static hudtextparms_t g_default_csay_tparms = {
|
||||||
-1, 0.25, // x, y
|
-1, 0.25, // x, y
|
||||||
2, // effect
|
2, // effect
|
||||||
0, 255, 0, 0, // r, g, b, a1
|
0, 255, 0, 0, // r, g, b, a1
|
||||||
@ -9,23 +9,81 @@ hudtextparms_t default_csay_tparms = {
|
|||||||
1 // channel
|
1 // channel
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const char* g_engine_msg_names[] =
|
||||||
|
{
|
||||||
|
"svc_bad",
|
||||||
|
"svc_nop",
|
||||||
|
"svc_disconnect",
|
||||||
|
"svc_event",
|
||||||
|
"svc_version",
|
||||||
|
"svc_setview",
|
||||||
|
"svc_sound",
|
||||||
|
"svc_time",
|
||||||
|
"svc_print",
|
||||||
|
"svc_stufftext",
|
||||||
|
"svc_setangle",
|
||||||
|
"svc_serverinfo",
|
||||||
|
"svc_lightstyle",
|
||||||
|
"svc_updateuserinfo",
|
||||||
|
"svc_deltadescription",
|
||||||
|
"svc_clientdata",
|
||||||
|
"svc_stopsound",
|
||||||
|
"svc_pings",
|
||||||
|
"svc_particle",
|
||||||
|
"svc_damage",
|
||||||
|
"svc_spawnstatic",
|
||||||
|
"svc_event_reliable",
|
||||||
|
"svc_spawnbaseline",
|
||||||
|
"svc_temp_entity",
|
||||||
|
"svc_setpause",
|
||||||
|
"svc_signonnum",
|
||||||
|
"svc_centerprint",
|
||||||
|
"svc_killedmonster",
|
||||||
|
"svc_foundsecret",
|
||||||
|
"svc_spawnstaticsound",
|
||||||
|
"svc_intermission",
|
||||||
|
"svc_finale",
|
||||||
|
"svc_cdtrack",
|
||||||
|
"svc_restore",
|
||||||
|
"svc_cutscene",
|
||||||
|
"svc_weaponanim",
|
||||||
|
"svc_decalname",
|
||||||
|
"svc_roomtype",
|
||||||
|
"svc_addangle",
|
||||||
|
"svc_newusermsg",
|
||||||
|
"svc_packetentities",
|
||||||
|
"svc_deltapacketentities",
|
||||||
|
"svc_choke",
|
||||||
|
"svc_resourcelist",
|
||||||
|
"svc_newmovevars",
|
||||||
|
"svc_resourcerequest",
|
||||||
|
"svc_customization",
|
||||||
|
"svc_crosshairangle",
|
||||||
|
"svc_soundfade",
|
||||||
|
"svc_filetxferfailed",
|
||||||
|
"svc_hltv",
|
||||||
|
"svc_director",
|
||||||
|
"svc_voiceinit",
|
||||||
|
"svc_voicedata",
|
||||||
|
"svc_sendextrainfo",
|
||||||
|
"svc_timescale",
|
||||||
|
"svc_resourcelocation",
|
||||||
|
"svc_sendcvarvalue",
|
||||||
|
"svc_sendcvarvalue2"
|
||||||
|
};
|
||||||
|
|
||||||
// Log to console; newline added.
|
// Log to console; newline added.
|
||||||
void EXT_FUNC mutil_LogConsole(plid_t plid, const char *fmt, ...)
|
void EXT_FUNC mutil_LogConsole(plid_t plid, const char *fmt, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
|
||||||
char buf[MAX_LOGMSG_LEN];
|
char buf[MAX_LOGMSG_LEN];
|
||||||
unsigned int len;
|
|
||||||
|
|
||||||
|
va_list ap;
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
Q_vsnprintf(buf, sizeof(buf), fmt, ap);
|
size_t len = Q_vsnprintf(buf, sizeof buf - 1, fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
// end msg with newline
|
buf[len] = '\n';
|
||||||
len = Q_strlen(buf);
|
buf[len + 1] = '\0';
|
||||||
if (len < sizeof(buf) - 2) // -1 null, -1 for newline
|
|
||||||
Q_strcat(buf, "\n");
|
|
||||||
else
|
|
||||||
buf[len - 1] = '\n';
|
|
||||||
|
|
||||||
SERVER_PRINT(buf);
|
SERVER_PRINT(buf);
|
||||||
}
|
}
|
||||||
@ -33,44 +91,43 @@ void EXT_FUNC mutil_LogConsole(plid_t plid, const char *fmt, ...)
|
|||||||
// Log regular message to logs; newline added.
|
// Log regular message to logs; newline added.
|
||||||
void EXT_FUNC mutil_LogMessage(plid_t plid, const char *fmt, ...)
|
void EXT_FUNC mutil_LogMessage(plid_t plid, const char *fmt, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
|
||||||
char buf[MAX_LOGMSG_LEN];
|
char buf[MAX_LOGMSG_LEN];
|
||||||
plugin_info_t *plinfo = (plugin_info_t *)plid;
|
|
||||||
|
|
||||||
|
va_list ap;
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
Q_vsnprintf(buf, sizeof(buf), fmt, ap);
|
Q_vsnprintf(buf, sizeof buf, fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
ALERT(at_logged, "[%s] %s\n", plinfo->logtag, buf);
|
|
||||||
|
ALERT(at_logged, "[%s] %s\n", plid->logtag, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Log an error message to logs; newline added.
|
// Log an error message to logs; newline added.
|
||||||
void EXT_FUNC mutil_LogError(plid_t plid, const char *fmt, ...)
|
void EXT_FUNC mutil_LogError(plid_t plid, const char *fmt, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
|
||||||
char buf[MAX_LOGMSG_LEN];
|
char buf[MAX_LOGMSG_LEN];
|
||||||
plugin_info_t *plinfo = (plugin_info_t *)plid;
|
|
||||||
|
|
||||||
|
va_list ap;
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
Q_vsnprintf(buf, sizeof(buf), fmt, ap);
|
Q_vsnprintf(buf, sizeof buf, fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
ALERT(at_logged, "[%s] ERROR: %s\n", plinfo->logtag, buf);
|
|
||||||
|
ALERT(at_logged, "[%s] ERROR: %s\n", plid->logtag, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Log a message only if cvar "developer" set; newline added.
|
// Log a message only if cvar "developer" set; newline added.
|
||||||
void EXT_FUNC mutil_LogDeveloper(plid_t plid, const char* fmt, ...)
|
void EXT_FUNC mutil_LogDeveloper(plid_t plid, const char* fmt, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
|
||||||
char buf[MAX_LOGMSG_LEN];
|
char buf[MAX_LOGMSG_LEN];
|
||||||
plugin_info_t* plinfo;
|
|
||||||
|
|
||||||
if ((int) CVAR_GET_FLOAT("developer") == 0)
|
if ((int)CVAR_GET_FLOAT("developer") == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
plinfo = (plugin_info_t *)plid;
|
va_list ap;
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
Q_vsnprintf(buf, sizeof(buf), fmt, ap);
|
Q_vsnprintf(buf, sizeof buf, fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
ALERT(at_logged, "[%s] dev: %s\n", plinfo->logtag, buf);
|
|
||||||
|
ALERT(at_logged, "[%s] dev: %s\n", plid->logtag, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Print message on center of all player's screens. Uses default text
|
// Print message on center of all player's screens. Uses default text
|
||||||
@ -79,7 +136,7 @@ void EXT_FUNC mutil_CenterSay(plid_t plid, const char* fmt, ...)
|
|||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
mutil_CenterSayVarargs(plid, default_csay_tparms, fmt, ap);
|
mutil_CenterSayVarargs(plid, g_default_csay_tparms, fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,18 +154,18 @@ void EXT_FUNC mutil_CenterSayParms(plid_t plid, hudtextparms_t tparms, const cha
|
|||||||
void EXT_FUNC mutil_CenterSayVarargs(plid_t plid, hudtextparms_t tparms, const char* fmt, va_list ap)
|
void EXT_FUNC mutil_CenterSayVarargs(plid_t plid, hudtextparms_t tparms, const char* fmt, va_list ap)
|
||||||
{
|
{
|
||||||
char buf[MAX_LOGMSG_LEN];
|
char buf[MAX_LOGMSG_LEN];
|
||||||
int n;
|
Q_vsnprintf(buf, sizeof buf, fmt, ap);
|
||||||
edict_t *pEntity;
|
|
||||||
|
|
||||||
Q_vsnprintf(buf, sizeof(buf), fmt, ap);
|
|
||||||
|
|
||||||
mutil_LogMessage(plid, "(centersay) %s", buf);
|
mutil_LogMessage(plid, "(centersay) %s", buf);
|
||||||
for (n = 1; n <= gpGlobals->maxClients; n++)
|
|
||||||
|
for (int n = 1; n <= gpGlobals->maxClients; n++)
|
||||||
{
|
{
|
||||||
pEntity = INDEXENT(n);
|
auto pEntity = INDEXENT(n);
|
||||||
|
|
||||||
if (FNullEnt(pEntity) || pEntity->free)
|
if (FNullEnt(pEntity) || pEntity->free)
|
||||||
continue;
|
continue;
|
||||||
//META_UTIL_HudMessage(pEntity, tparms, buf); // TODO
|
|
||||||
|
UTIL_HudMessage(pEntity, tparms, buf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,16 +174,16 @@ void EXT_FUNC mutil_CenterSayVarargs(plid_t plid, hudtextparms_t tparms, const c
|
|||||||
// Jussi Kivilinna.
|
// Jussi Kivilinna.
|
||||||
qboolean EXT_FUNC mutil_CallGameEntity(plid_t plid, const char *entStr, entvars_t *pev)
|
qboolean EXT_FUNC mutil_CallGameEntity(plid_t plid, const char *entStr, entvars_t *pev)
|
||||||
{
|
{
|
||||||
plugin_info_t *plinfo = (plugin_info_t *)plid;
|
META_DEBUG(8, ("Looking up game entity '%s' for plugin '%s'", entStr, plid->name));
|
||||||
META_DEBUG(8, ("Looking up game entity '%s' for plugin '%s'", entStr, plinfo->name));
|
|
||||||
ENTITY_FN pfnEntity = (ENTITY_FN)GameDLL.sys_module.getsym(entStr);
|
ENTITY_FN pfnEntity = (ENTITY_FN)GameDLL.sys_module.getsym(entStr);
|
||||||
|
|
||||||
if (!pfnEntity)
|
if (!pfnEntity)
|
||||||
{
|
{
|
||||||
META_ERROR("Couldn't find game entity '%s' in game DLL '%s' for plugin '%s'", entStr, GameDLL.name, plinfo->name);
|
META_ERROR("Couldn't find game entity '%s' in game DLL '%s' for plugin '%s'", entStr, GameDLL.name, plid->name);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
META_DEBUG(7, ("Calling game entity '%s' for plugin '%s'", entStr, plinfo->name));
|
META_DEBUG(7, ("Calling game entity '%s' for plugin '%s'", entStr, plid->name));
|
||||||
(*pfnEntity)(pev);
|
(*pfnEntity)(pev);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -135,18 +192,24 @@ qboolean EXT_FUNC mutil_CallGameEntity(plid_t plid, const char *entStr, entvars_
|
|||||||
// msgname, and return remaining info about it (msgid, size).
|
// msgname, and return remaining info about it (msgid, size).
|
||||||
int EXT_FUNC mutil_GetUserMsgID(plid_t plid, const char* msgname, int* size)
|
int EXT_FUNC mutil_GetUserMsgID(plid_t plid, const char* msgname, int* size)
|
||||||
{
|
{
|
||||||
plugin_info_t *plinfo = (plugin_info_t *)plid;
|
META_DEBUG(8, "Looking up usermsg name '%s' for plugin '%s'", msgname, plid->name);
|
||||||
META_DEBUG(8, ("Looking up usermsg name '%s' for plugin '%s'", msgname, plinfo->name));
|
|
||||||
|
|
||||||
MRegMsg *umsg = g_regMsgs->find(msgname);
|
MRegMsg *umsg = g_regMsgs->find(msgname);
|
||||||
|
|
||||||
if (umsg)
|
if (umsg)
|
||||||
{
|
{
|
||||||
if (size)
|
if (size) *size = umsg->getsize();
|
||||||
*size = umsg->size;
|
return umsg->getid();
|
||||||
return umsg->msgid;
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
return 0;
|
for (int n = 1; n < arraysize(g_engine_msg_names); n++) {
|
||||||
|
if (!strcmp(msgname, g_engine_msg_names[n])) {
|
||||||
|
if (size) *size = -1;
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find a usermsg, registered by the gamedll, with the corresponding
|
// Find a usermsg, registered by the gamedll, with the corresponding
|
||||||
@ -154,59 +217,39 @@ int EXT_FUNC mutil_GetUserMsgID(plid_t plid, const char* msgname, int* size)
|
|||||||
const char* EXT_FUNC mutil_GetUserMsgName(plid_t plid, int msgid, int *size)
|
const char* EXT_FUNC mutil_GetUserMsgName(plid_t plid, int msgid, int *size)
|
||||||
{
|
{
|
||||||
plugin_info_t *plinfo = (plugin_info_t *)plid;
|
plugin_info_t *plinfo = (plugin_info_t *)plid;
|
||||||
META_DEBUG(8, ("Looking up usermsg id '%d' for plugin '%s'", msgid, plinfo->name));
|
META_DEBUG(8, "Looking up usermsg id '%d' for plugin '%s'", msgid, plinfo->name);
|
||||||
|
|
||||||
// Guess names for any built-in g_engine messages mentioned in the SDK;
|
// Guess names for any built-in g_engine messages mentioned in the SDK;
|
||||||
// from dlls/util.h.
|
// from dlls/util.h.
|
||||||
if (msgid < 64)
|
if (msgid < arraysize(g_engine_msg_names))
|
||||||
{
|
{
|
||||||
switch (msgid)
|
if (size) *size = -1;
|
||||||
{
|
return g_engine_msg_names[msgid];
|
||||||
case SVC_TEMPENTITY:
|
|
||||||
if (size) *size = -1;
|
|
||||||
return "tempentity?";
|
|
||||||
case SVC_INTERMISSION:
|
|
||||||
if (size) *size = -1;
|
|
||||||
return "intermission?";
|
|
||||||
case SVC_CDTRACK:
|
|
||||||
if (size) *size = -1;
|
|
||||||
return "cdtrack?";
|
|
||||||
case SVC_WEAPONANIM:
|
|
||||||
if (size) *size = -1;
|
|
||||||
return "weaponanim?";
|
|
||||||
case SVC_ROOMTYPE:
|
|
||||||
if (size) *size = -1;
|
|
||||||
return "roomtype?";
|
|
||||||
case SVC_DIRECTOR:
|
|
||||||
if (size) *size = -1;
|
|
||||||
return "director?";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MRegMsg *umsg = g_regMsgs->find(msgid);
|
MRegMsg *umsg = g_regMsgs->find(msgid);
|
||||||
|
|
||||||
if (umsg)
|
if (umsg)
|
||||||
{
|
{
|
||||||
if (size)
|
if (size) *size = umsg->getsize();
|
||||||
*size = umsg->size;
|
|
||||||
// 'name' is assumed to be a constant string, allocated in the
|
// 'name' is assumed to be a constant string, allocated in the
|
||||||
// gamedll.
|
// gamedll.
|
||||||
return umsg->name;
|
return umsg->getname();
|
||||||
}
|
}
|
||||||
else
|
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the full path of the plugin's loaded dll/so file.
|
// Return the full path of the plugin's loaded dll/so file.
|
||||||
const char* EXT_FUNC mutil_GetPluginPath(plid_t plid)
|
const char* EXT_FUNC mutil_GetPluginPath(plid_t plid)
|
||||||
{
|
{
|
||||||
static char buf[PATH_MAX ];
|
static char buf[PATH_MAX];
|
||||||
MPlugin *plug;
|
|
||||||
|
|
||||||
plug = g_plugins->find(plid);
|
auto plug = g_plugins->find(plid);
|
||||||
if (!plug)
|
if (!plug)
|
||||||
{
|
{
|
||||||
META_ERROR("GetPluginPath: couldn't find plugin '%s'", plid->name);
|
META_ERROR("GetPluginPath: couldn't find plugin '%s'", plid->name);
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Q_strncpy(buf, plug->pathname, sizeof buf - 1);
|
Q_strncpy(buf, plug->pathname, sizeof buf - 1);
|
||||||
@ -219,6 +262,7 @@ const char* EXT_FUNC mutil_GetGameInfo(plid_t plid, ginfo_t type)
|
|||||||
{
|
{
|
||||||
static char buf[MAX_STRBUF_LEN];
|
static char buf[MAX_STRBUF_LEN];
|
||||||
const char *cp;
|
const char *cp;
|
||||||
|
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case GINFO_NAME:
|
case GINFO_NAME:
|
||||||
@ -241,7 +285,7 @@ const char* EXT_FUNC mutil_GetGameInfo(plid_t plid, ginfo_t type)
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
META_ERROR("GetGameInfo: invalid request '%d' from plugin '%s'", type, plid->name);
|
META_ERROR("GetGameInfo: invalid request '%d' from plugin '%s'", type, plid->name);
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Q_strncpy(buf, cp, sizeof buf - 1);
|
Q_strncpy(buf, cp, sizeof buf - 1);
|
||||||
@ -251,39 +295,41 @@ const char* EXT_FUNC mutil_GetGameInfo(plid_t plid, ginfo_t type)
|
|||||||
|
|
||||||
int EXT_FUNC mutil_LoadMetaPlugin(plid_t plid, const char* fname, PLUG_LOADTIME now, void **plugin_handle)
|
int EXT_FUNC mutil_LoadMetaPlugin(plid_t plid, const char* fname, PLUG_LOADTIME now, void **plugin_handle)
|
||||||
{
|
{
|
||||||
MPlugin *pl_loaded;
|
|
||||||
if (!fname)
|
if (!fname)
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(pl_loaded = g_plugins->plugin_addload(plid, fname, now)))
|
auto pl_loaded = g_plugins->plugin_addload(plid, fname, now);
|
||||||
|
|
||||||
|
if (!pl_loaded)
|
||||||
{
|
{
|
||||||
if (plugin_handle)
|
if (plugin_handle)
|
||||||
*plugin_handle = nullptr;
|
*plugin_handle = nullptr;
|
||||||
|
|
||||||
return 1;
|
return 1; // TODO: WTF
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (plugin_handle)
|
if (plugin_handle)
|
||||||
*plugin_handle = (void *)pl_loaded->sys_module.gethandle();
|
*plugin_handle = (void *)pl_loaded->sys_module.gethandle();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int EXT_FUNC mutil_UnloadMetaPlugin(plid_t plid, const char *fname, PLUG_LOADTIME now, PL_UNLOAD_REASON reason)
|
int EXT_FUNC mutil_UnloadMetaPlugin(plid_t plid, const char *fname, PLUG_LOADTIME now, PL_UNLOAD_REASON reason)
|
||||||
{
|
{
|
||||||
MPlugin *findp = nullptr;
|
MPlugin *findp;
|
||||||
int pindex;
|
|
||||||
char *endptr;
|
|
||||||
|
|
||||||
if (!fname)
|
if (!fname)
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
pindex = strtol(fname, &endptr, 10);
|
char *endptr;
|
||||||
|
int pindex = strtol(fname, &endptr, 10);
|
||||||
|
|
||||||
if (*fname != '\0' && *endptr == '\0')
|
if (*fname != '\0' && *endptr == '\0')
|
||||||
findp = g_plugins->find(pindex);
|
findp = g_plugins->find(pindex);
|
||||||
else
|
else
|
||||||
@ -300,14 +346,14 @@ int EXT_FUNC mutil_UnloadMetaPlugin(plid_t plid, const char *fname, PLUG_LOADTIM
|
|||||||
|
|
||||||
int EXT_FUNC mutil_UnloadMetaPluginByHandle(plid_t plid, void *plugin_handle, PLUG_LOADTIME now, PL_UNLOAD_REASON reason)
|
int EXT_FUNC mutil_UnloadMetaPluginByHandle(plid_t plid, void *plugin_handle, PLUG_LOADTIME now, PL_UNLOAD_REASON reason)
|
||||||
{
|
{
|
||||||
MPlugin *findp;
|
|
||||||
|
|
||||||
if (!plugin_handle)
|
if (!plugin_handle)
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(findp = g_plugins->find((module_handle_t)plugin_handle)))
|
auto findp = g_plugins->find((module_handle_t)plugin_handle);
|
||||||
|
|
||||||
|
if (!findp)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (findp->plugin_unload(plid, now, reason))
|
if (findp->plugin_unload(plid, now, reason))
|
||||||
|
@ -146,50 +146,3 @@ const char* str_os_error()
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Determine whether the given memory location is valid (ie whether we
|
|
||||||
// should expect to be able to reference strings or functions at this
|
|
||||||
// location without segfaulting).
|
|
||||||
#if defined(linux) || defined(__APPLE__)
|
|
||||||
// Simulate this with dladdr. I'm not convinced this will be as generally
|
|
||||||
// applicable as the native windows routine below, but it should do what
|
|
||||||
// we need it for in this particular situation.
|
|
||||||
// meta_errno values:
|
|
||||||
// - ME_NOTFOUND couldn't find a matching sharedlib for this ptr
|
|
||||||
bool IS_VALID_PTR(void *memptr)
|
|
||||||
{
|
|
||||||
Dl_info dli;
|
|
||||||
Q_memset(&dli, 0, sizeof(dli));
|
|
||||||
if (dladdr(memptr, &dli))
|
|
||||||
return true;
|
|
||||||
else
|
|
||||||
RETURN_ERRNO(false, ME_NOTFOUND);
|
|
||||||
}
|
|
||||||
#elif defined(_WIN32)
|
|
||||||
// Use the native windows routine IsBadCodePtr.
|
|
||||||
// meta_errno values:
|
|
||||||
// - ME_BADMEMPTR not a valid memory pointer
|
|
||||||
bool IS_VALID_PTR(void *memptr)
|
|
||||||
{
|
|
||||||
if (IsBadCodePtr((FARPROC) memptr))
|
|
||||||
return false;
|
|
||||||
else
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
#endif // _WIN32
|
|
||||||
|
|
||||||
// This used to be OS-dependent, as it used a SEGV signal handler under
|
|
||||||
// linux, but that was removed because (a) it masked legitimate segfaults
|
|
||||||
// in plugin commands and produced confusing output ("plugin has been
|
|
||||||
// unloaded", when really it segfaultd), and (b) wasn't necessary since
|
|
||||||
// IS_VALID_PTR() should cover the situation.
|
|
||||||
bool os_safe_call(REG_CMD_FN pfn)
|
|
||||||
{
|
|
||||||
// try and see if this is a valid memory location
|
|
||||||
if (!IS_VALID_PTR((void *)pfn))
|
|
||||||
// meta_errno should be already set in is_valid_ptr()
|
|
||||||
return false;
|
|
||||||
|
|
||||||
pfn();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
@ -40,11 +40,6 @@ private:
|
|||||||
uintptr_t m_size;
|
uintptr_t m_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool IS_VALID_PTR(void *memptr);
|
|
||||||
|
|
||||||
// Attempt to call the given function pointer, without segfaulting.
|
|
||||||
bool os_safe_call(REG_CMD_FN pfn);
|
|
||||||
|
|
||||||
// Windows doesn't have an strtok_r() routine, so we write our own.
|
// Windows doesn't have an strtok_r() routine, so we write our own.
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#define strtok_r(s, delim, ptrptr) mm_strtok_r(s, delim, ptrptr)
|
#define strtok_r(s, delim, ptrptr) mm_strtok_r(s, delim, ptrptr)
|
||||||
|
@ -32,24 +32,17 @@ void EXT_FUNC meta_AddServerCommand(char *cmd_name, void (*function)())
|
|||||||
|
|
||||||
META_DEBUG(4, ("called: meta_AddServerCommand; cmd_name=%s, function=%d, plugin=%s", cmd_name, function, plug ? plug->file : "unknown"));
|
META_DEBUG(4, ("called: meta_AddServerCommand; cmd_name=%s, function=%d, plugin=%s", cmd_name, function, plug ? plug->file : "unknown"));
|
||||||
|
|
||||||
// try to find which plugin is registering this command
|
|
||||||
if (!plug) {
|
if (!plug) {
|
||||||
META_ERROR("Failed to find memloc for regcmd '%s'", cmd_name);
|
META_ERROR("Failed to find memloc for regcmd '%s'", cmd_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
// See if this command was previously registered, ie a "reloaded" plugin.
|
// See if this command was previously registered, ie a "reloaded" plugin.
|
||||||
auto icmd = g_regCmds->find(cmd_name);
|
auto cmd = g_regCmds->find(cmd_name);
|
||||||
if (!icmd)
|
if (!cmd)
|
||||||
{
|
{
|
||||||
// If not found, add.
|
// If not found, add.
|
||||||
icmd = g_regCmds->add(cmd_name, function, plug);
|
cmd = g_regCmds->add(cmd_name, function, plug);
|
||||||
if (!icmd)
|
REG_SVR_COMMAND(cmd->getname(), g_RehldsFuncs ? cmd->gethandler() : meta_command_handler);
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only register if not previously registered..
|
|
||||||
REG_SVR_COMMAND(icmd->getname(), meta_command_handler);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,43 +61,24 @@ void EXT_FUNC meta_AddServerCommand(char *cmd_name, void (*function)())
|
|||||||
// it will fail to work properly.
|
// it will fail to work properly.
|
||||||
void EXT_FUNC meta_CVarRegister(cvar_t *pCvar)
|
void EXT_FUNC meta_CVarRegister(cvar_t *pCvar)
|
||||||
{
|
{
|
||||||
MPlugin *iplug = g_plugins->find_memloc(pCvar);
|
MPlugin *plug = g_plugins->find_memloc(pCvar);
|
||||||
|
|
||||||
META_DEBUG(4, ("called: meta_CVarRegister; name=%s", pCvar->name));
|
META_DEBUG(4, "called: meta_CVarRegister; name=%s", pCvar->name);
|
||||||
|
|
||||||
// try to find which plugin is registering this cvar
|
// try to find which plugin is registering this cvar
|
||||||
if (!iplug)
|
if (!plug)
|
||||||
{
|
{
|
||||||
META_DEBUG(1, ("Failed to find memloc for regcvar '%s'", pCvar->name));
|
META_DEBUG(1, "Failed to find memloc for regcvar '%s'", pCvar->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
// See if this cvar was previously registered, ie a "reloaded" plugin.
|
// See if this cvar was previously registered, ie a "reloaded" plugin.
|
||||||
auto icvar = g_regCvars->find(pCvar->name);
|
auto reg = g_regCvars->find(pCvar->name);
|
||||||
if (!icvar)
|
|
||||||
|
if (!reg)
|
||||||
{
|
{
|
||||||
// If not found, add.
|
reg = g_regCvars->add(pCvar, plug);
|
||||||
icvar = g_regCvars->add(pCvar->name);
|
CVAR_REGISTER(reg->getcvar());
|
||||||
if (!icvar)
|
|
||||||
{
|
|
||||||
// error details logged in add()
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reset to given value
|
|
||||||
icvar->set(pCvar);
|
|
||||||
CVAR_REGISTER(icvar->data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note: if not a new cvar, then we don't set the values, and just keep
|
|
||||||
// the pre-existing value.
|
|
||||||
icvar->status = RG_VALID;
|
|
||||||
|
|
||||||
// Store which plugin this is for, if we know. Use '0' for unknown
|
|
||||||
// plugin, as plugin index starts at 1.
|
|
||||||
if (iplug)
|
|
||||||
icvar->plugid = iplug->index;
|
|
||||||
else
|
|
||||||
icvar->plugid = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Replacement for engine routine RegUserMsg; called by plugins. Rather
|
// Replacement for engine routine RegUserMsg; called by plugins. Rather
|
||||||
|
@ -12,17 +12,72 @@ char *UTIL_VarArgs(char *format, ...)
|
|||||||
return string;
|
return string;
|
||||||
}
|
}
|
||||||
|
|
||||||
// UTIL_LogPrintf - Prints a logged message to console.
|
short FixedSigned16(float value, float scale)
|
||||||
// Preceded by LOG: ( timestamp ) < message >
|
|
||||||
void UTIL_LogPrintf(char *fmt, ...)
|
|
||||||
{
|
{
|
||||||
va_list argptr;
|
int output;
|
||||||
char string[1024];
|
|
||||||
|
|
||||||
va_start(argptr, fmt);
|
output = (int)(value * scale);
|
||||||
Q_vsnprintf(string, sizeof(string), fmt, argptr);
|
|
||||||
va_end(argptr);
|
|
||||||
|
|
||||||
// Print to server console
|
if (output > 32767)
|
||||||
ALERT(at_logged, "%s", string);
|
output = 32767;
|
||||||
|
|
||||||
|
if (output < -32768)
|
||||||
|
output = -32768;
|
||||||
|
|
||||||
|
return (short)output;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned short FixedUnsigned16(float value, float scale)
|
||||||
|
{
|
||||||
|
int output;
|
||||||
|
|
||||||
|
output = (int)(value * scale);
|
||||||
|
if (output < 0)
|
||||||
|
output = 0;
|
||||||
|
if (output > 0xFFFF)
|
||||||
|
output = 0xFFFF;
|
||||||
|
|
||||||
|
return (unsigned short)output;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UTIL_HudMessage(edict_t *pEntity, const hudtextparms_t &textparms, const char *pMessage)
|
||||||
|
{
|
||||||
|
if (FNullEnt(pEntity) || pEntity->free)
|
||||||
|
return;
|
||||||
|
|
||||||
|
MESSAGE_BEGIN(MSG_ONE, SVC_TEMPENTITY, NULL, pEntity);
|
||||||
|
WRITE_BYTE(TE_TEXTMESSAGE);
|
||||||
|
WRITE_BYTE(textparms.channel & 0xFF);
|
||||||
|
|
||||||
|
WRITE_SHORT(FixedSigned16(textparms.x, 1 << 13));
|
||||||
|
WRITE_SHORT(FixedSigned16(textparms.y, 1 << 13));
|
||||||
|
WRITE_BYTE(textparms.effect);
|
||||||
|
|
||||||
|
WRITE_BYTE(textparms.r1);
|
||||||
|
WRITE_BYTE(textparms.g1);
|
||||||
|
WRITE_BYTE(textparms.b1);
|
||||||
|
WRITE_BYTE(textparms.a1);
|
||||||
|
|
||||||
|
WRITE_BYTE(textparms.r2);
|
||||||
|
WRITE_BYTE(textparms.g2);
|
||||||
|
WRITE_BYTE(textparms.b2);
|
||||||
|
WRITE_BYTE(textparms.a2);
|
||||||
|
|
||||||
|
WRITE_SHORT(FixedUnsigned16(textparms.fadeinTime, 1 << 8));
|
||||||
|
WRITE_SHORT(FixedUnsigned16(textparms.fadeoutTime, 1 << 8));
|
||||||
|
WRITE_SHORT(FixedUnsigned16(textparms.holdTime, 1 << 8));
|
||||||
|
|
||||||
|
if (textparms.effect == 2)
|
||||||
|
WRITE_SHORT(FixedUnsigned16(textparms.fxTime, 1 << 8));
|
||||||
|
|
||||||
|
if (strlen(pMessage) < 512) {
|
||||||
|
WRITE_STRING(pMessage);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
char tmp[512];
|
||||||
|
strncpy(tmp, pMessage, sizeof tmp - 1);
|
||||||
|
tmp[sizeof tmp - 1] = 0;
|
||||||
|
WRITE_STRING(tmp);
|
||||||
|
}
|
||||||
|
MESSAGE_END();
|
||||||
}
|
}
|
||||||
|
@ -12,3 +12,5 @@
|
|||||||
// defined.
|
// defined.
|
||||||
#include "enginecallbacks.h"
|
#include "enginecallbacks.h"
|
||||||
#include <util.h>
|
#include <util.h>
|
||||||
|
|
||||||
|
void UTIL_HudMessage(edict_t *pEntity, const hudtextparms_t &textparms, const char *pMessage);
|
||||||
|
@ -35,24 +35,24 @@ C_DLLEXPORT int Server_GetBlendingInterface(int version,
|
|||||||
// "Couldn't get server .dll studio model blending interface. Version
|
// "Couldn't get server .dll studio model blending interface. Version
|
||||||
// mismatch?", but this will only show in "developer" (-dev) mode.
|
// mismatch?", but this will only show in "developer" (-dev) mode.
|
||||||
|
|
||||||
META_DEBUG(6, ("called: Server_GetBlendingInterface; version=%d", version));
|
META_DEBUG(6, "called: Server_GetBlendingInterface; version=%d", version);
|
||||||
if (missing)
|
if (missing)
|
||||||
{
|
{
|
||||||
META_DEBUG(6, ("Skipping Server_GetBlendingInterface; was previously found missing"));
|
META_DEBUG(6, "Skipping Server_GetBlendingInterface; was previously found missing");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (!getblend)
|
if (!getblend)
|
||||||
{
|
{
|
||||||
META_DEBUG(6, ("Looking up Server_GetBlendingInterface"));
|
META_DEBUG(6, "Looking up Server_GetBlendingInterface");
|
||||||
getblend = (GETBLENDAPI_FN)GameDLL.sys_module.getsym("Server_GetBlendingInterface");
|
getblend = (GETBLENDAPI_FN)GameDLL.sys_module.getsym("Server_GetBlendingInterface");
|
||||||
}
|
}
|
||||||
if (!getblend)
|
if (!getblend)
|
||||||
{
|
{
|
||||||
META_DEBUG(6, ("Couldn't find Server_GetBlendingInterface in game DLL '%s': %s", GameDLL.name, "function not found"));
|
META_DEBUG(6, "Couldn't find Server_GetBlendingInterface in game DLL '%s': %s", GameDLL.name, "function not found");
|
||||||
missing = 1;
|
missing = 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
META_DEBUG(6, ("Calling Server_GetBlendingInterface"));
|
META_DEBUG(6, "Calling Server_GetBlendingInterface");
|
||||||
return (getblend)(version, ppinterface, pstudio, rotationmatrix, bonetransform);
|
return getblend(version, ppinterface, pstudio, rotationmatrix, bonetransform);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
#include "precompiled.h"
|
#include "precompiled.h"
|
||||||
|
|
||||||
|
static_allocator g_static_allocator(static_allocator::mp_readwrite);
|
||||||
|
|
||||||
bool is_yes(const char* str)
|
bool is_yes(const char* str)
|
||||||
{
|
{
|
||||||
return !Q_strcmp(str, "true") || !Q_strcmp(str, "yes") || !Q_strcmp(str, "1");
|
return !Q_strcmp(str, "true") || !Q_strcmp(str, "yes") || !Q_strcmp(str, "1");
|
||||||
@ -20,7 +22,12 @@ const char* LOCALINFO(char* key)
|
|||||||
return ENTITY_KEYVALUE(NULL, key);
|
return ENTITY_KEYVALUE(NULL, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
char* execmem_allocator::allocate(const size_t n)
|
static_allocator::static_allocator(memory_protection protection) : m_protection(protection)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
char* static_allocator::allocate(const size_t n)
|
||||||
{
|
{
|
||||||
if (!m_pages.size() || m_used + n > Pagesize)
|
if (!m_pages.size() || m_used + n > Pagesize)
|
||||||
allocate_page();
|
allocate_page();
|
||||||
@ -30,7 +37,13 @@ char* execmem_allocator::allocate(const size_t n)
|
|||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void execmem_allocator::deallocate_all()
|
char* static_allocator::strdup(const char* string)
|
||||||
|
{
|
||||||
|
size_t len = strlen(string) + 1;
|
||||||
|
return (char *)memcpy(allocate(len), string, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
void static_allocator::deallocate_all()
|
||||||
{
|
{
|
||||||
for (auto page : m_pages)
|
for (auto page : m_pages)
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
@ -42,12 +55,12 @@ void execmem_allocator::deallocate_all()
|
|||||||
m_pages.clear();
|
m_pages.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t execmem_allocator::memoryUsed() const
|
size_t static_allocator::memory_used() const
|
||||||
{
|
{
|
||||||
return (m_pages.size() - 1) * Pagesize + m_used;
|
return (m_pages.size() - 1) * Pagesize + m_used;
|
||||||
}
|
}
|
||||||
|
|
||||||
void execmem_allocator::allocate_page()
|
void static_allocator::allocate_page()
|
||||||
{
|
{
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
auto page = VirtualAlloc(NULL, Pagesize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
|
auto page = VirtualAlloc(NULL, Pagesize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
|
||||||
|
@ -1,11 +1,34 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
class execmem_allocator
|
template <typename T, size_t N>
|
||||||
|
char(&ArraySizeHelper(T(&array)[N]))[N];
|
||||||
|
#define arraysize(array) (sizeof(ArraySizeHelper(array)))
|
||||||
|
|
||||||
|
class static_allocator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
enum memory_protection : uint8
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
mp_readwrite = PAGE_READWRITE,
|
||||||
|
mp_rwx = PAGE_EXECUTE_READWRITE
|
||||||
|
#else
|
||||||
|
mp_readwrite = PROT_READ | PROT_WRITE,
|
||||||
|
mp_rwx = PROT_READ | PROT_WRITE | PROT_EXEC
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
static_allocator(memory_protection protection);
|
||||||
char* allocate(const size_t n);
|
char* allocate(const size_t n);
|
||||||
|
char* strdup(const char* string);
|
||||||
void deallocate_all();
|
void deallocate_all();
|
||||||
size_t memoryUsed() const;
|
size_t memory_used() const;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
T* allocate()
|
||||||
|
{
|
||||||
|
return (T *)allocate(sizeof(T));
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void allocate_page();
|
void allocate_page();
|
||||||
@ -17,8 +40,11 @@ private:
|
|||||||
|
|
||||||
size_t m_used = 0;
|
size_t m_used = 0;
|
||||||
std::vector<void *> m_pages;
|
std::vector<void *> m_pages;
|
||||||
|
memory_protection m_protection;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern static_allocator g_static_allocator;
|
||||||
|
|
||||||
bool is_yes(const char* str);
|
bool is_yes(const char* str);
|
||||||
bool is_no(const char* str);
|
bool is_no(const char* str);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user