diff --git a/metamod/msvc/metamod.vcxproj b/metamod/msvc/metamod.vcxproj index 43928b0..13e8991 100644 --- a/metamod/msvc/metamod.vcxproj +++ b/metamod/msvc/metamod.vcxproj @@ -12,20 +12,17 @@ {02832A39-E902-46B7-8D47-911C37CF41B0} - metamod - Win32Proj + + DynamicLibrary - v120_xp - MultiByte - true + v120 DynamicLibrary - v120_xp - NotSet + v120 @@ -38,239 +35,164 @@ - <_ProjectFileVersion>12.0.30501.0 - - - $(SolutionDir)$(Configuration)\ - $(Configuration)\ - true - $(ProjectName)_mm - - - $(SolutionDir)$(Configuration)\ - $(Configuration)\ - false - $(ProjectName)_mm + <_ProjectFileVersion>10.0.40219.1 + false + AllRules.ruleset + + + AllRules.ruleset + + Disabled $(ProjectDir)\..\;$(ProjectDir)\..\src;$(ProjectDir)\..\version;$(ProjectDir)\..\include;$(ProjectDir)\..\include\common;$(ProjectDir)\..\include\dlls;$(ProjectDir)\..\include\engine;$(ProjectDir)\..\include\game_shared;$(ProjectDir)\..\include\pm_shared;$(ProjectDir)\..\include\public;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_WINDOWS;_USRDLL;METAMOD_EXPORTS;_CRT_SECURE_NO_DEPRECATE;__METAMOD_BUILD__;__BUILD_FAST_METAMOD__;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL + METAMOD_CORE;WIN32;_DEBUG;_WINDOWS;_USRDLL;METAMOD_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + MultiThreadedDebug Use + .\debug/metamod.pch + .\debug/asm/ + .\debug/obj/ + .\debug/inf/ Level3 - ProgramDatabase + true + true + EditAndContinue + Default precompiled.h - metamod.def + .\debug/metamod.dll + true + .\metamod.def true - Windows + .\debug/inf/metamod.pdb + .\debug/metamod.lib MachineX86 - %(AdditionalDependencies) + false - - IF EXIST "$(ProjectDir)PostBuild.bat" (CALL "$(ProjectDir)PostBuild.bat" "$(TargetDir)" "$(TargetName)" "$(TargetExt)" "$(ProjectDir)") - - - Automatic deployment script - - - IF EXIST "$(ProjectDir)PreBuild.bat" (CALL "$(ProjectDir)PreBuild.bat" "$(ProjectDir)..\version\" "$(ProjectDir)..\") - - - Setup version from Git revision - - - echo Empty Action - - - Force build to run Pre-Build event - + + _DEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\debug/metamod.tlb + + + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + MaxSpeed + OnlyExplicitInline $(ProjectDir)\..\;$(ProjectDir)\..\src;$(ProjectDir)\..\version;$(ProjectDir)\..\include;$(ProjectDir)\..\include\common;$(ProjectDir)\..\include\dlls;$(ProjectDir)\..\include\engine;$(ProjectDir)\..\include\game_shared;$(ProjectDir)\..\include\pm_shared;$(ProjectDir)\..\include\public;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_WINDOWS;_USRDLL;METAMOD_EXPORTS;_CRT_SECURE_NO_DEPRECATE;__METAMOD_BUILD__;__BUILD_FAST_METAMOD__;%(PreprocessorDefinitions) + METAMOD_CORE;WIN32;NDEBUG;_WINDOWS;_USRDLL;METAMOD_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true MultiThreaded + true Use + .\release/metamod.pch + .\release/ + .\release/obj/ + .\release/inf/ Level3 - ProgramDatabase + true + true Default - StreamingSIMDExtensions2 precompiled.h - Full - true - Windows - true - true + .\release/metamod.dll + true + .\metamod.def + .\release/inf/metamod.pdb + .\release/metamod.lib MachineX86 - %(AdditionalDependencies) - metamod.def + false - - echo Empty Action - - - Force build to run Pre-Build event - - - IF EXIST "$(ProjectDir)PostBuild.bat" (CALL "$(ProjectDir)PostBuild.bat" "$(TargetDir)" "$(TargetName)" "$(TargetExt)" "$(ProjectDir)") - - - Automatic deployment script - - - IF EXIST "$(ProjectDir)PreBuild.bat" (CALL "$(ProjectDir)PreBuild.bat" "$(ProjectDir)..\version\" "$(ProjectDir)..\") - - - Setup version from Git revision - + + NDEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\release/metamod.tlb + + + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + - - Use - precompiled.h - - - Use - precompiled.h - - - Use - precompiled.h - - - Use - precompiled.h - - - Use - precompiled.h - - - Use - precompiled.h - - - Use - precompiled.h - - - Use - precompiled.h - - - Use - precompiled.h - - - Use - precompiled.h - - - Use - precompiled.h - - - Use - precompiled.h - - - Use - precompiled.h - - - Use - precompiled.h - - - Use - precompiled.h - - - Use - precompiled.h - - - Use - precompiled.h - - - Use - precompiled.h - - - Use - precompiled.h - - - Use - precompiled.h - + + + + + + + + + + + + + + + + + + - Create - precompiled.h Create + Create - - Use - precompiled.h - - - Use - precompiled.h - - - Use - precompiled.h - + + + + + + - - - - - - - - - + + - - + + - + - - - + + + + diff --git a/metamod/msvc/metamod.vcxproj.filters b/metamod/msvc/metamod.vcxproj.filters index 85328ef..4a24278 100644 --- a/metamod/msvc/metamod.vcxproj.filters +++ b/metamod/msvc/metamod.vcxproj.filters @@ -2,18 +2,15 @@ - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + {a2511622-7e99-4c67-845f-0751105c3bde} + cpp;c;cxx;rc;def;r;odl;idl;hpj;bat - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav + {dfc6c7bb-cea4-43c5-bb1b-b8145cf93dd5} + ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe - - Source Files - Source Files @@ -35,7 +32,10 @@ Source Files - + + Source Files + + Source Files @@ -65,10 +65,7 @@ Source Files - - Source Files - - + Source Files @@ -77,42 +74,26 @@ Source Files + + Source Files + Source Files - + + Source Files + + Source Files - - Resource Files - - - - - Resource Files - - - - - Source Files - - - Source Files - - - Source Files - Source Files Source Files - - Source Files - Source Files @@ -131,10 +112,10 @@ Source Files - + Source Files - + Source Files @@ -152,10 +133,10 @@ Source Files - + Source Files - + Source Files @@ -164,35 +145,47 @@ Source Files + + Source Files + Source Files Source Files - - Source Files - Source Files - - Source Files - Source Files - + Source Files - + Source Files Source Files + + Source Files + Source Files + + Source Files + + + Source Files + + + Source Files + + + Source Files + \ No newline at end of file diff --git a/metamod/src/api_hook.cpp b/metamod/src/api_hook.cpp deleted file mode 100644 index a7d99e0..0000000 --- a/metamod/src/api_hook.cpp +++ /dev/null @@ -1,654 +0,0 @@ -#include "precompiled.h" - -// getting pointer with table index is faster than with if-else -const void **api_tables[3] = { - (const void **)&Engine.funcs, - (const void **)&GameDLL.funcs.dllapi_table, - (const void **)&GameDLL.funcs.newapi_table -}; - -const void **api_info_tables[3] = { - (const void **)&engine_info, - (const void **)&dllapi_info, - (const void **)&newapi_info -}; - -// Safety check for metamod-bot-plugin bugfix. -// engine_api->pfnRunPlayerMove calls dllapi-functions before it returns. -// This causes problems with bots running as metamod plugins, because -// metamod assumed that PublicMetaGlobals is free to be used. -// With call_count we can fix this by backuping up PublicMetaGlobals if -// it's already being used. -unsigned int call_count = 0; - -// get function pointer from api table by function pointer offset -inline void *get_api_function(const void * api_table, unsigned int func_offset) -{ - return *(void**)((unsigned long)api_table + func_offset); -} - -// get data pointer from api_info table by function offset -inline const api_info_t *get_api_info(enum_api_t api, unsigned int api_info_offset) -{ - return (const api_info_t *)((unsigned long)api_info_tables[api] + api_info_offset); -} - -// simplified 'void' version of main hook function -void main_hook_function_void(unsigned int api_info_offset, enum_api_t api, unsigned int func_offset, const void *packed_args) -{ - const api_info_t *api_info; - int i; - META_RES mres, status, prev_mres; - MPlugin *iplug; - void *pfn_routine; - int loglevel; - const void *api_table; - meta_globals_t backup_meta_globals[1]; - - // passing offset from api wrapper function makes code faster/smaller - api_info = get_api_info(api, api_info_offset); - - // Fix bug with metamod-bot-plugins. - if (call_count++ > 0) - { - // Backup PublicMetaGlobals. - backup_meta_globals[0] = PublicMetaGlobals; - } - - // Setup - loglevel=api_info->loglevel; - mres = MRES_UNSET; - status = MRES_UNSET; - prev_mres = MRES_UNSET; - pfn_routine = NULL; - // Pre plugin functions - prev_mres = MRES_UNSET; - for (i = 0; i < Plugins->endlist; i++) - { - iplug = &Plugins->plist[i]; - if (iplug->status != PL_RUNNING) - continue; - - api_table = iplug->get_api_table(api); - if (!api_table) - { - // plugin doesn't provide this api table - continue; - } - - pfn_routine = get_api_function(api_table, func_offset); - if (!pfn_routine) - { - // plugin doesn't provide this function - continue; - } - - // initialize PublicMetaGlobals - PublicMetaGlobals.mres = MRES_UNSET; - PublicMetaGlobals.prev_mres = prev_mres; - PublicMetaGlobals.status = status; - - // call plugin - META_DEBUG(loglevel, ("Calling %s:%s()", iplug->file, api_info->name)); - api_info->api_caller(pfn_routine, packed_args); - API_UNPAUSE_TSC_TRACKING(); - - // plugin's result code - mres = PublicMetaGlobals.mres; - if (mres > status) - status = mres; - - // save this for successive plugins to see - prev_mres = mres; - if (mres == MRES_UNSET) - { - META_WARNING("Plugin didn't set meta_result: %s:%s()", iplug->file, api_info->name); - } - } - - call_count--; - - // Api call - if (status != MRES_SUPERCEDE) - { - // get api table - api_table = *api_tables[api]; - - if (api_table) - { - pfn_routine = get_api_function(api_table, func_offset); - if (pfn_routine) - { - META_DEBUG(loglevel, ("Calling %s:%s()", (api == e_api_engine) ? "engine" : GameDLL.file, api_info->name)); - api_info->api_caller(pfn_routine, packed_args); - API_UNPAUSE_TSC_TRACKING(); - } - else - { - // don't complain for NULL routines in NEW_DLL_FUNCTIONS - if (api != e_api_newapi) - { - META_WARNING("Couldn't find api call: %s:%s", (api==e_api_engine) ? "engine" : GameDLL.file, api_info->name); - } - status = MRES_UNSET; - } - } - else - { - // don't complain for NULL NEW_DLL_FUNCTIONS-table - if (api != e_api_newapi) - { - META_DEBUG(loglevel, ("No api table defined for api call: %s:%s", (api == e_api_engine) ? "engine" : GameDLL.file, api_info->name)); - } - status = MRES_UNSET; - } - } - else - META_DEBUG(loglevel, ("Skipped (supercede) %s:%s()", (api == e_api_engine) ? "engine" : GameDLL.file, api_info->name)); - - call_count++; - - // Post plugin functions - prev_mres = MRES_UNSET; - for (i = 0; i < Plugins->endlist; i++) - { - iplug=&Plugins->plist[i]; - - if (iplug->status != PL_RUNNING) - continue; - - api_table = iplug->get_api_post_table(api); - if (!api_table) - { - // plugin doesn't provide this api table - continue; - } - - pfn_routine = get_api_function(api_table, func_offset); - if (!pfn_routine) - { - // plugin doesn't provide this function - continue; - } - - // initialize PublicMetaGlobals - PublicMetaGlobals.mres = MRES_UNSET; - PublicMetaGlobals.prev_mres = prev_mres; - PublicMetaGlobals.status = status; - - // call plugin - META_DEBUG(loglevel, ("Calling %s:%s_Post()", iplug->file, api_info->name)); - api_info->api_caller(pfn_routine, packed_args); - API_UNPAUSE_TSC_TRACKING(); - - // plugin's result code - mres = PublicMetaGlobals.mres; - if (mres > status) - status = mres; - - // save this for successive plugins to see - prev_mres = mres; - - if (mres == MRES_UNSET) - META_WARNING("Plugin didn't set meta_result: %s:%s_Post()", iplug->file, api_info->name); - else if (mres == MRES_SUPERCEDE) - META_WARNING("MRES_SUPERCEDE not valid in Post functions: %s:%s_Post()", iplug->file, api_info->name); - } - - if (--call_count>0) - { - // Restore backup - PublicMetaGlobals = backup_meta_globals[0]; - } -} - -// full return typed version of main hook function -void *main_hook_function(const class_ret_t ret_init, unsigned int api_info_offset, enum_api_t api, unsigned int func_offset, const void *packed_args) -{ - const api_info_t *api_info; - int i; - META_RES mres, status, prev_mres; - MPlugin *iplug; - void *pfn_routine; - int loglevel; - const void *api_table; - meta_globals_t backup_meta_globals[1]; - - // passing offset from api wrapper function makes code faster/smaller - api_info = get_api_info(api, api_info_offset); - - // Fix bug with metamod-bot-plugins. - if (call_count++ > 0) - { - // Backup PublicMetaGlobals. - backup_meta_globals[0] = PublicMetaGlobals; - } - - // Return class setup - class_ret_t dllret = ret_init; - class_ret_t override_ret = ret_init; - class_ret_t pub_override_ret = ret_init; - class_ret_t orig_ret = ret_init; - class_ret_t pub_orig_ret = ret_init; - - // Setup - loglevel = api_info->loglevel; - mres = MRES_UNSET; - status = MRES_UNSET; - prev_mres = MRES_UNSET; - pfn_routine = nullptr; - - //Pre plugin functions - prev_mres = MRES_UNSET; - for (i = 0; i < Plugins->endlist; i++) - { - iplug = &Plugins->plist[i]; - - if (iplug->status != PL_RUNNING) - continue; - - api_table = iplug->get_api_table(api); - if (!api_table) - { - // plugin doesn't provide this api table - continue; - } - - pfn_routine = get_api_function(api_table, func_offset); - if (!pfn_routine) - { - // plugin doesn't provide this function - continue; - } - - // initialize PublicMetaGlobals - PublicMetaGlobals.mres = MRES_UNSET; - PublicMetaGlobals.prev_mres = prev_mres; - PublicMetaGlobals.status = status; - pub_orig_ret = orig_ret; - PublicMetaGlobals.orig_ret = pub_orig_ret.getptr(); - if (status == MRES_SUPERCEDE) - { - pub_override_ret = override_ret; - PublicMetaGlobals.override_ret = pub_override_ret.getptr(); - } - - // call plugin - META_DEBUG(loglevel, ("Calling %s:%s()", iplug->file, api_info->name)); - dllret = class_ret_t(api_info->api_caller(pfn_routine, packed_args)); - API_UNPAUSE_TSC_TRACKING(); - - // plugin's result code - mres = PublicMetaGlobals.mres; - if (mres > status) - status = mres; - - // save this for successive plugins to see - prev_mres = mres; - - if (mres == MRES_SUPERCEDE) - { - pub_override_ret = dllret; - override_ret = dllret; - } - else if (mres == MRES_UNSET) - { - META_WARNING("Plugin didn't set meta_result: %s:%s()", iplug->file, api_info->name); - } - } - - call_count--; - - // Api call - if (status != MRES_SUPERCEDE) - { - // get api table - api_table = *api_tables[api]; - - if (api_table) - { - pfn_routine = get_api_function(api_table, func_offset); - if (pfn_routine) - { - META_DEBUG(loglevel, ("Calling %s:%s()", (api == e_api_engine) ? "engine" : GameDLL.file, api_info->name)); - dllret = class_ret_t(api_info->api_caller(pfn_routine, packed_args)); - API_UNPAUSE_TSC_TRACKING(); - orig_ret = dllret; - } - else - { - // don't complain for NULL routines in NEW_DLL_FUNCTIONS - if (api != e_api_newapi) - { - META_WARNING("Couldn't find api call: %s:%s", (api == e_api_engine) ? "engine" : GameDLL.file, api_info->name); - } - status = MRES_UNSET; - } - } else { - // don't complain for NULL NEW_DLL_FUNCTIONS-table - if (api != e_api_newapi) - { - META_DEBUG(loglevel, ("No api table defined for api call: %s:%s", (api==e_api_engine) ? "engine" : GameDLL.file, api_info->name)); - } - status = MRES_UNSET; - } - } - else - { - META_DEBUG(loglevel, ("Skipped (supercede) %s:%s()", (api == e_api_engine) ? "engine" : GameDLL.file, api_info->name)); - orig_ret = override_ret; - pub_orig_ret = override_ret; - PublicMetaGlobals.orig_ret = pub_orig_ret.getptr(); - } - - call_count++; - - // Pre plugin functions - prev_mres = MRES_UNSET; - for (i = 0; i < Plugins->endlist; i++) - { - iplug = &Plugins->plist[i]; - - if (iplug->status != PL_RUNNING) - continue; - - api_table = iplug->get_api_post_table(api); - if (!api_table) - { - //plugin doesn't provide this api table - continue; - } - - pfn_routine = get_api_function(api_table, func_offset); - if (!pfn_routine) - { - // plugin doesn't provide this function - continue; - } - - // initialize PublicMetaGlobals - PublicMetaGlobals.mres = MRES_UNSET; - PublicMetaGlobals.prev_mres = prev_mres; - PublicMetaGlobals.status = status; - pub_orig_ret = orig_ret; - - PublicMetaGlobals.orig_ret = pub_orig_ret.getptr(); - if (status == MRES_OVERRIDE) - { - pub_override_ret = override_ret; - PublicMetaGlobals.override_ret = pub_override_ret.getptr(); - } - - // call plugin - META_DEBUG(loglevel, ("Calling %s:%s_Post()", iplug->file, api_info->name)); - dllret = class_ret_t(api_info->api_caller(pfn_routine, packed_args)); - API_UNPAUSE_TSC_TRACKING(); - - // plugin's result code - mres = PublicMetaGlobals.mres; - if (mres > status) - status = mres; - - // save this for successive plugins to see - prev_mres = mres; - - if (mres == MRES_OVERRIDE) - { - pub_override_ret = dllret; - override_ret = dllret; - } - else if (mres == MRES_UNSET) - { - META_WARNING("Plugin didn't set meta_result: %s:%s_Post()", iplug->file, api_info->name); - } - else if (mres == MRES_SUPERCEDE) - { - META_WARNING("MRES_SUPERCEDE not valid in Post functions: %s:%s_Post()", iplug->file, api_info->name); - } - } - - if (--call_count > 0) - { - // Restore backup - PublicMetaGlobals = backup_meta_globals[0]; - } - - // return value is passed through ret_init! - if (status != MRES_OVERRIDE) - { - return *(void**)orig_ret.getptr(); - } - else - { - META_DEBUG(loglevel, ("Returning (override) %s()", api_info->name)); - return *(void**)override_ret.getptr(); - } -} - -// Macros for creating api caller functions -#define BEGIN_API_CALLER_FUNC(ret_type, args_type_code) \ - void *_COMBINE4(api_caller_, ret_type, _args_, args_type_code)(const void * func, const void * packed_args) { \ - _COMBINE2(pack_args_type_, args_type_code) *p UNUSED = (_COMBINE2(pack_args_type_, args_type_code) *)packed_args; -#define END_API_CALLER_FUNC(ret_t, args_t, args) \ - API_PAUSE_TSC_TRACKING(); \ - return *(void **)class_ret_t((*((ret_t (*) args_t)func)) args).getptr(); \ - } -#define END_API_CALLER_FUNC_void(args_t, args) \ - API_PAUSE_TSC_TRACKING(); \ - return (*((void* (*) args_t)func)) args; \ - } - -// API function callers. - -BEGIN_API_CALLER_FUNC(void, ipV) -END_API_CALLER_FUNC_void((int, const void *, ...), (p->i1, p->p1, p->str)) - -BEGIN_API_CALLER_FUNC(void, 2pV) -END_API_CALLER_FUNC_void((const void *, const void *, ...), (p->p1, p->p2, p->str)) - -BEGIN_API_CALLER_FUNC(void, void) -END_API_CALLER_FUNC_void((), ()) - -BEGIN_API_CALLER_FUNC(ptr, void) -END_API_CALLER_FUNC(void*, (), ()) - -BEGIN_API_CALLER_FUNC(int, void) -END_API_CALLER_FUNC(int, (), ()) - -BEGIN_API_CALLER_FUNC(float, void) -END_API_CALLER_FUNC(float, (), ()) - -BEGIN_API_CALLER_FUNC(float, 2f) -END_API_CALLER_FUNC(float, (float, float), (p->f1, p->f2)) - -BEGIN_API_CALLER_FUNC(void, 2i) -END_API_CALLER_FUNC_void((int, int), (p->i1, p->i2)); - -BEGIN_API_CALLER_FUNC(int, 2i) -END_API_CALLER_FUNC(int, (int, int), (p->i1, p->i2)); - -BEGIN_API_CALLER_FUNC(void, 2i2p) -END_API_CALLER_FUNC_void((int, int, const void *, const void *), (p->i1, p->i2, p->p1, p->p2)); - -BEGIN_API_CALLER_FUNC(void, 2i2pi2p) -END_API_CALLER_FUNC_void((int, int, const void *, const void *, int, const void *, const void *), (p->i1, p->i2, p->p1, p->p2, p->i3, p->p3, p->p4)); - -BEGIN_API_CALLER_FUNC(void, 2p) -END_API_CALLER_FUNC_void((const void *, const void *), (p->p1, p->p2)); - -BEGIN_API_CALLER_FUNC(ptr, 2p) -END_API_CALLER_FUNC(void*, (const void *, const void *), (p->p1, p->p2)); - -BEGIN_API_CALLER_FUNC(int, 2p) -END_API_CALLER_FUNC(int, (const void *, const void *), (p->p1, p->p2)); - -BEGIN_API_CALLER_FUNC(void, 2p2f) -END_API_CALLER_FUNC_void((const void *, const void *, float, float), (p->p1, p->p2, p->f1, p->f2)); - -BEGIN_API_CALLER_FUNC(void, 2p2i2p) -END_API_CALLER_FUNC_void((const void *, const void *, int, int, const void *, const void *), (p->p1, p->p2, p->i1, p->i2, p->p3, p->p4)); - -BEGIN_API_CALLER_FUNC(void, 2p3fus2uc) -END_API_CALLER_FUNC_void((const void *, const void *, float, float, float, unsigned short, unsigned char, unsigned char), (p->p1, p->p2, p->f1, p->f2, p->f3, p->us1, p->uc1, p->uc2)); - -BEGIN_API_CALLER_FUNC(ptr, 2pf) -END_API_CALLER_FUNC(void*, (const void *, const void *, float), (p->p1, p->p2, p->f1)); - -BEGIN_API_CALLER_FUNC(void, 2pfi) -END_API_CALLER_FUNC_void((const void *, const void *, float, int), (p->p1, p->p2, p->f1, p->i1)); - -BEGIN_API_CALLER_FUNC(void, 2pi) -END_API_CALLER_FUNC_void((const void *, const void *, int), (p->p1, p->p2, p->i1)); - -BEGIN_API_CALLER_FUNC(int, 2pi) -END_API_CALLER_FUNC(int, (const void *, const void *, int), (p->p1, p->p2, p->i1)); - -BEGIN_API_CALLER_FUNC(void, 2pui) -END_API_CALLER_FUNC_void((const void *, const void *, unsigned int), (p->p1, p->p2, p->ui1)); - -BEGIN_API_CALLER_FUNC(void, 2pi2p) -END_API_CALLER_FUNC_void((const void *, const void *, int, const void *, const void *), (p->p1, p->p2, p->i1, p->p3, p->p4)); - -BEGIN_API_CALLER_FUNC(void, 2pif2p) -END_API_CALLER_FUNC_void((const void *, const void *, int, float, const void *, const void *), (p->p1, p->p2, p->i1, p->f1, p->p3, p->p4)); - -BEGIN_API_CALLER_FUNC(int, 3i) -END_API_CALLER_FUNC(int, (int, int, int), (p->i1, p->i2, p->i3)); - -BEGIN_API_CALLER_FUNC(void, 3p) -END_API_CALLER_FUNC_void((const void *, const void *, const void *), (p->p1, p->p2, p->p3)); - -BEGIN_API_CALLER_FUNC(ptr, 3p) -END_API_CALLER_FUNC(void*, (const void *, const void *, const void *), (p->p1, p->p2, p->p3)); - -BEGIN_API_CALLER_FUNC(int, 3p) -END_API_CALLER_FUNC(int, (const void *, const void *, const void *), (p->p1, p->p2, p->p3)); - -BEGIN_API_CALLER_FUNC(void, 3p2f2i) -END_API_CALLER_FUNC_void((const void *, const void *, const void *, float, float, int, int), (p->p1, p->p2, p->p3, p->f1, p->f2, p->i1, p->i2)); - -BEGIN_API_CALLER_FUNC(int, 3pi2p) -END_API_CALLER_FUNC(int, (const void *, const void *, const void *, int, const void *, const void *), (p->p1, p->p2, p->p3, p->i1, p->p4, p->p5)); - -BEGIN_API_CALLER_FUNC(void, 4p) -END_API_CALLER_FUNC_void((const void *, const void *, const void *, const void *), (p->p1, p->p2, p->p3, p->p4)); - -BEGIN_API_CALLER_FUNC(int, 4p) -END_API_CALLER_FUNC(int, (const void *, const void *, const void *, const void *), (p->p1, p->p2, p->p3, p->p4)); - -BEGIN_API_CALLER_FUNC(void, 4pi) -END_API_CALLER_FUNC_void((const void *, const void *, const void *, const void *, int), (p->p1, p->p2, p->p3, p->p4, p->i1)); - -BEGIN_API_CALLER_FUNC(int, 4pi) -END_API_CALLER_FUNC(int, (const void *, const void *, const void *, const void *, int), (p->p1, p->p2, p->p3, p->p4, p->i1)); - -BEGIN_API_CALLER_FUNC(void, f) -END_API_CALLER_FUNC_void((float), (p->f1)); - -BEGIN_API_CALLER_FUNC(void, i) -END_API_CALLER_FUNC_void((int), (p->i1)); - -BEGIN_API_CALLER_FUNC(int, i) -END_API_CALLER_FUNC(int, (int), (p->i1)); - -BEGIN_API_CALLER_FUNC(ptr, i) -END_API_CALLER_FUNC(void*, (int), (p->i1)); - -BEGIN_API_CALLER_FUNC(uint, ui) -END_API_CALLER_FUNC(unsigned int, (unsigned int), (p->ui1)); - -BEGIN_API_CALLER_FUNC(ptr, ui) -END_API_CALLER_FUNC(void*, (unsigned int), (p->ui1)); - -BEGIN_API_CALLER_FUNC(ulong, ul) -END_API_CALLER_FUNC(unsigned long, (unsigned long), (p->ul1)); - -BEGIN_API_CALLER_FUNC(void, i2p) -END_API_CALLER_FUNC_void((int, const void *, const void *), (p->i1, p->p1, p->p2)); - -BEGIN_API_CALLER_FUNC(int, i2p) -END_API_CALLER_FUNC(int, (int, const void *, const void *), (p->i1, p->p1, p->p2)); - -BEGIN_API_CALLER_FUNC(void, i3p) -END_API_CALLER_FUNC_void((int, const void *, const void *, const void *), (p->i1, p->p1, p->p2, p->p3)); - -BEGIN_API_CALLER_FUNC(void, ip) -END_API_CALLER_FUNC_void((int, const void *), (p->i1, p->p1)); - -BEGIN_API_CALLER_FUNC(ushort, ip) -END_API_CALLER_FUNC(unsigned short, (int, const void *), (p->i1, p->p1)); - -BEGIN_API_CALLER_FUNC(int, ip) -END_API_CALLER_FUNC(int, (int, const void *), (p->i1, p->p1)); - -BEGIN_API_CALLER_FUNC(void, ipusf2p2f4i) -END_API_CALLER_FUNC_void((int, const void *, unsigned short, float, const void *, const void *, float, float, int, int, int, int), (p->i1, p->p1, p->us1, p->f1, p->p2, p->p3, p->f2, p->f3, p->i2, p->i3, p->i4, p->i5)); - -BEGIN_API_CALLER_FUNC(void, p) -END_API_CALLER_FUNC_void((const void *), (p->p1)); - -BEGIN_API_CALLER_FUNC(ptr, p) -END_API_CALLER_FUNC(void*, (const void *), (p->p1)); - -BEGIN_API_CALLER_FUNC(char, p) -END_API_CALLER_FUNC(char, (const void *), (p->p1)); - -BEGIN_API_CALLER_FUNC(int, p) -END_API_CALLER_FUNC(int, (const void *), (p->p1)); - -BEGIN_API_CALLER_FUNC(uint, p) -END_API_CALLER_FUNC(unsigned int, (const void *), (p->p1)); - -BEGIN_API_CALLER_FUNC(float, p) -END_API_CALLER_FUNC(float, (const void *), (p->p1)); - -BEGIN_API_CALLER_FUNC(void, p2f) -END_API_CALLER_FUNC_void((const void *, float, float), (p->p1, p->f1, p->f2)); - -BEGIN_API_CALLER_FUNC(int, p2fi) -END_API_CALLER_FUNC(int, (const void *, float, float, int), (p->p1, p->f1, p->f2, p->i1)); - -BEGIN_API_CALLER_FUNC(void, p2i) -END_API_CALLER_FUNC_void((const void *, int, int), (p->p1, p->i1, p->i2)); - -BEGIN_API_CALLER_FUNC(void, p3i) -END_API_CALLER_FUNC_void((const void *, int, int, int), (p->p1, p->i1, p->i2, p->i3)); - -BEGIN_API_CALLER_FUNC(void, p4i) -END_API_CALLER_FUNC_void((const void *, int, int, int, int), (p->p1, p->i1, p->i2, p->i3, p->i4)); - -BEGIN_API_CALLER_FUNC(void, puc) -END_API_CALLER_FUNC_void((const void *, unsigned char), (p->p1, p->uc1)); - -BEGIN_API_CALLER_FUNC(void, pf) -END_API_CALLER_FUNC_void((const void *, float), (p->p1, p->f1)); - -BEGIN_API_CALLER_FUNC(void, pfp) -END_API_CALLER_FUNC_void((const void *, float, const void *), (p->p1, p->f1, p->p2)); - -BEGIN_API_CALLER_FUNC(void, pi) -END_API_CALLER_FUNC_void((const void *, int), (p->p1, p->i1)); - -BEGIN_API_CALLER_FUNC(ptr, pi) -END_API_CALLER_FUNC(void*, (const void *, int), (p->p1, p->i1)); - -BEGIN_API_CALLER_FUNC(int, pi) -END_API_CALLER_FUNC(int, (const void *, int), (p->p1, p->i1)); - -BEGIN_API_CALLER_FUNC(void, pi2p) -END_API_CALLER_FUNC_void((const void *, int, const void *, const void *), (p->p1, p->i1, p->p2, p->p3)); - -BEGIN_API_CALLER_FUNC(int, pi2p2ip) -END_API_CALLER_FUNC(int, (const void *, int, const void *, const void *, int, int, const void *), (p->p1, p->i1, p->p2, p->p3, p->i2, p->i3, p->p4)); - -BEGIN_API_CALLER_FUNC(void, pip) -END_API_CALLER_FUNC_void((const void *, int, const void *), (p->p1, p->i1, p->p2)); - -BEGIN_API_CALLER_FUNC(ptr, pip) -END_API_CALLER_FUNC(void*, (const void *, int, const void *), (p->p1, p->i1, p->p2)); - -BEGIN_API_CALLER_FUNC(void, pip2f2i) -END_API_CALLER_FUNC_void((const void *, int, const void *, float, float, int, int), (p->p1, p->i1, p->p2, p->f1, p->f2, p->i2, p->i3)); - -BEGIN_API_CALLER_FUNC(void, pip2f4i2p) -END_API_CALLER_FUNC_void((const void *, int, const void *, float, float, int, int, int, int, const void *, const void *), (p->p1, p->i1, p->p2, p->f1, p->f2, p->i2, p->i3, p->i4, p->i5, p->p3, p->p4)); diff --git a/metamod/src/api_hook.h b/metamod/src/api_hook.h deleted file mode 100644 index 5734e5e..0000000 --- a/metamod/src/api_hook.h +++ /dev/null @@ -1,360 +0,0 @@ -#pragma once - -#include "ret_type.h" -#include "api_info.h" - -// Compine 4 parts for single name -#define _COMBINE4(w,x,y,z) w##x##y##z -#define _COMBINE2(x,y) x##y - -// simplified 'void' version of main hook function -void main_hook_function_void(unsigned int api_info_offset, enum_api_t api, unsigned int func_offset, const void *packed_args); - -// full return typed version of main hook function -void *main_hook_function(const class_ret_t ret_init, unsigned int api_info_offset, enum_api_t api, unsigned int func_offset, const void *packed_args); - -// API function args structures/classes -#define API_PACK_ARGS(type, args)\ - _COMBINE2(pack_args_type_, type) packed_args args; - -#define PACK_ARGS_CLASS_HEADER(type, constructor_args)\ - class _COMBINE2(pack_args_type_, type): public class_metamod_new {\ - public: inline _COMBINE2(pack_args_type_, type) constructor_args - -#define PACK_ARGS_END }; - -#define VOID_ARG 0 - -PACK_ARGS_CLASS_HEADER(void, (int)) {}; -PACK_ARGS_END - -PACK_ARGS_CLASS_HEADER(i, (int _i1)): i1(_i1) {}; - int i1; -PACK_ARGS_END - -PACK_ARGS_CLASS_HEADER(2i, (int _i1, int _i2)): i1(_i1), i2(_i2) {}; - int i1,i2; -PACK_ARGS_END - -PACK_ARGS_CLASS_HEADER(3i, (int _i1, int _i2, int _i3)): i1(_i1), i2(_i2), i3(_i3) {}; - int i1,i2,i3; -PACK_ARGS_END - -PACK_ARGS_CLASS_HEADER(ui, (unsigned int _ui1)): ui1(_ui1) {}; - unsigned int ui1; -PACK_ARGS_END - -PACK_ARGS_CLASS_HEADER(ul, (unsigned long _ul1)): ul1(_ul1) {}; - unsigned long ul1; -PACK_ARGS_END - -PACK_ARGS_CLASS_HEADER(f, (float _f1)): f1(_f1) {}; - float f1; -PACK_ARGS_END - -PACK_ARGS_CLASS_HEADER(2f, (float _f1, float _f2)): f1(_f1), f2(_f2) {}; - float f1,f2; -PACK_ARGS_END - -PACK_ARGS_CLASS_HEADER(p, (const void *_p1)): p1(_p1) {}; - const void *p1; -PACK_ARGS_END - -PACK_ARGS_CLASS_HEADER(2p, (const void *_p1, const void *_p2)): p1(_p1), p2(_p2) {}; - const void *p1,*p2; -PACK_ARGS_END - -PACK_ARGS_CLASS_HEADER(3p, (const void *_p1, const void *_p2, const void *_p3)): p1(_p1), p2(_p2), p3(_p3) {}; - const void *p1,*p2,*p3; -PACK_ARGS_END - -PACK_ARGS_CLASS_HEADER(4p, (const void *_p1, const void *_p2, const void *_p3, const void *_p4)): p1(_p1), p2(_p2), p3(_p3), p4(_p4) {}; - const void *p1,*p2,*p3,*p4; -PACK_ARGS_END - -PACK_ARGS_CLASS_HEADER(2pV, (const void *_p1, const void *_p2, const void *_str)): p1(_p1), p2(_p2), str(_str) {}; - const void *p1,*p2,*str; -PACK_ARGS_END - -PACK_ARGS_CLASS_HEADER(ipV, (int _i1, const void *_p1, const void *_str)): i1(_i1), p1(_p1), str(_str) {}; - int i1; - const void *p1,*str; -PACK_ARGS_END - -PACK_ARGS_CLASS_HEADER(2i2p, (int _i1, int _i2, const void *_p1, const void *_p2)): i1(_i1), i2(_i2), p1(_p1), p2(_p2) {}; - int i1,i2; - const void *p1,*p2; -PACK_ARGS_END - -PACK_ARGS_CLASS_HEADER(2p2f, (const void *_p1, const void *_p2, float _f1, float _f2)): p1(_p1), p2(_p2), f1(_f1), f2(_f2) {}; - const void *p1,*p2; - float f1,f2; -PACK_ARGS_END - -PACK_ARGS_CLASS_HEADER(2p2i2p, (const void *_p1, const void *_p2, int _i1, int _i2, const void *_p3, const void *_p4)): p1(_p1), p2(_p2), i1(_i1), i2(_i2), p3(_p3), p4(_p4) {}; - const void *p1,*p2; - int i1,i2; - const void *p3,*p4; -PACK_ARGS_END - -PACK_ARGS_CLASS_HEADER(2p3fus2uc, (const void *_p1, const void *_p2, float _f1, float _f2, float _f3, unsigned short _us1, unsigned char _uc1, unsigned char _uc2)): p1(_p1), p2(_p2), f1(_f1), f2(_f2), f3(_f3), us1(_us1), uc1(_uc1), uc2(_uc2) {}; - const void *p1,*p2; - float f1,f2,f3; - unsigned int us1; - unsigned int uc1,uc2; -PACK_ARGS_END - -PACK_ARGS_CLASS_HEADER(2pf, (const void *_p1, const void *_p2, float _f1)): p1(_p1), p2(_p2), f1(_f1) {}; - const void *p1,*p2; - float f1; -PACK_ARGS_END - -PACK_ARGS_CLASS_HEADER(2pfi, (const void *_p1, const void *_p2, float _f1, int _i1)): p1(_p1), p2(_p2), f1(_f1), i1(_i1) {}; - const void *p1,*p2; - float f1; - int i1; -PACK_ARGS_END - -PACK_ARGS_CLASS_HEADER(2pi, (const void *_p1, const void *_p2, int _i1)): p1(_p1), p2(_p2), i1(_i1) {}; - const void *p1,*p2; - int i1; -PACK_ARGS_END - -PACK_ARGS_CLASS_HEADER(2pi2p, (const void *_p1, const void *_p2, int _i1, const void *_p3, const void *_p4)): p1(_p1), p2(_p2), i1(_i1), p3(_p3), p4(_p4) {}; - const void *p1,*p2; - int i1; - const void *p3,*p4; -PACK_ARGS_END - -PACK_ARGS_CLASS_HEADER(2pif2p, (const void *_p1, const void *_p2, int _i1, float _f1, const void *_p3, const void *_p4)): p1(_p1), p2(_p2), i1(_i1), f1(_f1), p3(_p3), p4(_p4) {}; - const void *p1,*p2; - int i1; - float f1; - const void *p3,*p4; -PACK_ARGS_END - -PACK_ARGS_CLASS_HEADER(3p2f2i, (const void *_p1, const void *_p2, const void *_p3, float _f1, float _f2, int _i1, int _i2)): p1(_p1), p2(_p2), p3(_p3), f1(_f1), f2(_f2), i1(_i1), i2(_i2) {}; - const void *p1,*p2,*p3; - float f1,f2; - int i1,i2; -PACK_ARGS_END - -PACK_ARGS_CLASS_HEADER(3pi2p, (const void *_p1, const void *_p2, const void *_p3, int _i1, const void *_p4, const void *_p5)): p1(_p1), p2(_p2), p3(_p3), i1(_i1), p4(_p4), p5(_p5) {}; - const void *p1,*p2,*p3; - int i1; - const void *p4,*p5; -PACK_ARGS_END - -PACK_ARGS_CLASS_HEADER(i3p, (int _i1, const void *_p1, const void *_p2, const void *_p3)): i1(_i1), p1(_p1), p2(_p2), p3(_p3) {}; - int i1; - const void *p1,*p2,*p3; -PACK_ARGS_END - -PACK_ARGS_CLASS_HEADER(ip, (int _i1, const void *_p1)): i1(_i1), p1(_p1) {}; - int i1; - const void *p1; -PACK_ARGS_END - -PACK_ARGS_CLASS_HEADER(ipusf2p2f4i, (int _i1, const void *_p1, unsigned short _us1, float _f1, const void *_p2, const void *_p3, float _f2, float _f3, int _i2, int _i3, int _i4, int _i5)): i1(_i1), p1(_p1), us1(_us1), f1(_f1), p2(_p2), p3(_p3), f2(_f2), f3(_f3), i2(_i2), i3(_i3), i4(_i4), i5(_i5) {}; - int i1; - const void *p1; - unsigned int us1; - float f1; - const void *p2,*p3; - float f2,f3; - int i2,i3,i4,i5; -PACK_ARGS_END - -PACK_ARGS_CLASS_HEADER(3pi, (const void *_p1, const void *_p2, const void *_p3, int _i1)): p1(_p1), p2(_p2), p3(_p3), i1(_i1) {}; - const void *p1,*p2,*p3; - int i1; -PACK_ARGS_END - -PACK_ARGS_CLASS_HEADER(4pi, (const void *_p1, const void *_p2, const void *_p3, const void *_p4, int _i1)): p1(_p1), p2(_p2), p3(_p3), p4(_p4), i1(_i1) {}; - const void *p1,*p2,*p3,*p4; - int i1; -PACK_ARGS_END - -PACK_ARGS_CLASS_HEADER(pf, (const void *_p1, float _f1)): p1(_p1), f1(_f1) {}; - const void *p1; - float f1; -PACK_ARGS_END - -PACK_ARGS_CLASS_HEADER(pfp, (const void *_p1, float _f1, const void *_p2)): p1(_p1), f1(_f1), p2(_p2) {}; - const void *p1; - float f1; - const void *p2; -PACK_ARGS_END - -PACK_ARGS_CLASS_HEADER(pi, (const void *_p1, int _i1)): p1(_p1), i1(_i1) {}; - const void *p1; - int i1; -PACK_ARGS_END - -PACK_ARGS_CLASS_HEADER(pi2p, (const void *_p1, int _i1, const void *_p2, const void *_p3)): p1(_p1), i1(_i1), p2(_p2), p3(_p3) {}; - const void *p1; - int i1; - const void *p2, *p3; -PACK_ARGS_END - -PACK_ARGS_CLASS_HEADER(pip, (const void *_p1, int _i1, const void *_p2)): p1(_p1), i1(_i1), p2(_p2) {}; - const void *p1; - int i1; - const void *p2; -PACK_ARGS_END - -PACK_ARGS_CLASS_HEADER(pip2f2i, (const void *_p1, int _i1, const void *_p2, float _f1, float _f2, int _i2, int _i3)): p1(_p1), i1(_i1), p2(_p2), f1(_f1), f2(_f2), i2(_i2), i3(_i3) {}; - const void *p1; - int i1; - const void *p2; - float f1,f2; - int i2,i3; -PACK_ARGS_END - -PACK_ARGS_CLASS_HEADER(pip2f4i2p, (const void *_p1, int _i1, const void *_p2, float _f1, float _f2, int _i2, int _i3, int _i4, int _i5, const void *_p3, const void *_p4)): p1(_p1), i1(_i1), p2(_p2), f1(_f1), f2(_f2), i2(_i2), i3(_i3), i4(_i4), i5(_i5), p3(_p3), p4(_p4) {}; - const void *p1; - int i1; - const void *p2; - float f1,f2; - int i2,i3,i4,i5; - const void *p3,*p4; -PACK_ARGS_END - -PACK_ARGS_CLASS_HEADER(puc, (const void *_p1, unsigned char _uc1)): p1(_p1), uc1(_uc1) {}; - const void *p1; - unsigned int uc1; -PACK_ARGS_END - -PACK_ARGS_CLASS_HEADER(2i2pi2p, (int _i1, int _i2, const void *_p1, const void *_p2, int _i3, const void *_p3, const void *_p4)): i1(_i1), i2(_i2), p1(_p1), p2(_p2), i3(_i3), p3(_p3), p4(_p4) {}; - int i1,i2; - const void *p1,*p2; - int i3; - const void *p3,*p4; -PACK_ARGS_END - -PACK_ARGS_CLASS_HEADER(2pui, (const void *_p1, const void *_p2, unsigned int _ui1)): p1(_p1), p2(_p2), ui1(_ui1) {}; - const void *p1,*p2; - unsigned int ui1; -PACK_ARGS_END - -PACK_ARGS_CLASS_HEADER(i2p, (int _i1, const void *_p1, const void *_p2)): i1(_i1), p1(_p1), p2(_p2) {}; - int i1; - const void *p1,*p2; -PACK_ARGS_END - -PACK_ARGS_CLASS_HEADER(p2f, (const void *_p1, float _f1, float _f2)): p1(_p1), f1(_f1), f2(_f2) {}; - const void *p1; - float f1,f2; -PACK_ARGS_END - -PACK_ARGS_CLASS_HEADER(p2fi, (const void *_p1, float _f1, float _f2, int _i1)): p1(_p1), f1(_f1), f2(_f2), i1(_i1) {}; - const void *p1; - float f1,f2; - int i1; -PACK_ARGS_END - -PACK_ARGS_CLASS_HEADER(p2i, (const void *_p1, int _i1, int _i2)): p1(_p1), i1(_i1), i2(_i2) {}; - const void *p1; - int i1,i2; -PACK_ARGS_END - -PACK_ARGS_CLASS_HEADER(p3i, (const void *_p1, int _i1, int _i2, int _i3)): p1(_p1), i1(_i1), i2(_i2), i3(_i3) {}; - const void *p1; - int i1,i2,i3; -PACK_ARGS_END - -PACK_ARGS_CLASS_HEADER(p4i, (const void *_p1, int _i1, int _i2, int _i3, int _i4)): p1(_p1), i1(_i1), i2(_i2), i3(_i3), i4(_i4) {}; - const void *p1; - int i1,i2,i3,i4; -PACK_ARGS_END - -PACK_ARGS_CLASS_HEADER(pi2p2ip, (const void *_p1, int _i1, const void *_p2, const void *_p3, int _i2, int _i3, const void *_p4)): p1(_p1), i1(_i1), p2(_p2), p3(_p3), i2(_i2), i3(_i3), p4(_p4) {}; - const void *p1; - int i1; - const void *p2,*p3; - int i2,i3; - const void *p4; -PACK_ARGS_END - -// -// API function callers. -// -#ifdef __METAMOD_BUILD__ - #define EXTERN_API_CALLER_FUNCTION(ret_type, args_code) \ - void *_COMBINE4(api_caller_, ret_type, _args_, args_code)(const void * func, const void * packed_args) -#else - #define EXTERN_API_CALLER_FUNCTION(ret_type, args_code) \ - static const api_caller_func_t _COMBINE4(api_caller_, ret_type, _args_, args_code) = (api_caller_func_t)0 -#endif - -EXTERN_API_CALLER_FUNCTION(void, ipV); -EXTERN_API_CALLER_FUNCTION(void, 2pV); -EXTERN_API_CALLER_FUNCTION(void, void); -EXTERN_API_CALLER_FUNCTION(ptr, void); -EXTERN_API_CALLER_FUNCTION(int, void); -EXTERN_API_CALLER_FUNCTION(float, void); -EXTERN_API_CALLER_FUNCTION(float, 2f); -EXTERN_API_CALLER_FUNCTION(void, 2i); -EXTERN_API_CALLER_FUNCTION(int, 2i); -EXTERN_API_CALLER_FUNCTION(void, 2i2p); -EXTERN_API_CALLER_FUNCTION(void, 2i2pi2p); -EXTERN_API_CALLER_FUNCTION(void, 2p); -EXTERN_API_CALLER_FUNCTION(ptr, 2p); -EXTERN_API_CALLER_FUNCTION(int, 2p); -EXTERN_API_CALLER_FUNCTION(void, 2p2f); -EXTERN_API_CALLER_FUNCTION(void, 2p2i2p); -EXTERN_API_CALLER_FUNCTION(void, 2p3fus2uc); -EXTERN_API_CALLER_FUNCTION(ptr, 2pf); -EXTERN_API_CALLER_FUNCTION(void, 2pfi); -EXTERN_API_CALLER_FUNCTION(void, 2pi); -EXTERN_API_CALLER_FUNCTION(int, 2pi); -EXTERN_API_CALLER_FUNCTION(void, 2pui); -EXTERN_API_CALLER_FUNCTION(void, 2pi2p); -EXTERN_API_CALLER_FUNCTION(void, 2pif2p); -EXTERN_API_CALLER_FUNCTION(int, 3i); -EXTERN_API_CALLER_FUNCTION(void, 3p); -EXTERN_API_CALLER_FUNCTION(ptr, 3p); -EXTERN_API_CALLER_FUNCTION(int, 3p); -EXTERN_API_CALLER_FUNCTION(void, 3p2f2i); -EXTERN_API_CALLER_FUNCTION(int, 3pi2p); -EXTERN_API_CALLER_FUNCTION(void, 4p); -EXTERN_API_CALLER_FUNCTION(int, 4p); -EXTERN_API_CALLER_FUNCTION(void, 4pi); -EXTERN_API_CALLER_FUNCTION(int, 4pi); -EXTERN_API_CALLER_FUNCTION(void, f); -EXTERN_API_CALLER_FUNCTION(void, i); -EXTERN_API_CALLER_FUNCTION(ptr, i); -EXTERN_API_CALLER_FUNCTION(int, i); -EXTERN_API_CALLER_FUNCTION(ptr, ui); -EXTERN_API_CALLER_FUNCTION(uint, ui); -EXTERN_API_CALLER_FUNCTION(ulong, ul); -EXTERN_API_CALLER_FUNCTION(void, i2p); -EXTERN_API_CALLER_FUNCTION(int, i2p); -EXTERN_API_CALLER_FUNCTION(void, i3p); -EXTERN_API_CALLER_FUNCTION(void, ip); -EXTERN_API_CALLER_FUNCTION(ushort, ip); -EXTERN_API_CALLER_FUNCTION(int, ip); -EXTERN_API_CALLER_FUNCTION(void, ipusf2p2f4i); -EXTERN_API_CALLER_FUNCTION(void, p); -EXTERN_API_CALLER_FUNCTION(ptr, p); -EXTERN_API_CALLER_FUNCTION(char, p); -EXTERN_API_CALLER_FUNCTION(int, p); -EXTERN_API_CALLER_FUNCTION(uint, p); -EXTERN_API_CALLER_FUNCTION(float, p); -EXTERN_API_CALLER_FUNCTION(void, p2f); -EXTERN_API_CALLER_FUNCTION(int, p2fi); -EXTERN_API_CALLER_FUNCTION(void, p2i); -EXTERN_API_CALLER_FUNCTION(void, p3i); -EXTERN_API_CALLER_FUNCTION(void, p4i); -EXTERN_API_CALLER_FUNCTION(void, puc); -EXTERN_API_CALLER_FUNCTION(void, pf); -EXTERN_API_CALLER_FUNCTION(void, pfp); -EXTERN_API_CALLER_FUNCTION(void, pi); -EXTERN_API_CALLER_FUNCTION(ptr, pi); -EXTERN_API_CALLER_FUNCTION(int, pi); -EXTERN_API_CALLER_FUNCTION(void, pi2p); -EXTERN_API_CALLER_FUNCTION(int, pi2p2ip); -EXTERN_API_CALLER_FUNCTION(void, pip); -EXTERN_API_CALLER_FUNCTION(ptr, pip); -EXTERN_API_CALLER_FUNCTION(void, pip2f2i); -EXTERN_API_CALLER_FUNCTION(void, pip2f4i2p); diff --git a/metamod/src/api_info.cpp b/metamod/src/api_info.cpp index 5805c21..810f470 100644 --- a/metamod/src/api_info.cpp +++ b/metamod/src/api_info.cpp @@ -1,234 +1,272 @@ +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// api_info.cpp - info for api routines + +/* + * Copyright (c) 2001-2003 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game g_engine ("HL + * g_engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL g_engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + #include "precompiled.h" // trace flag, loglevel, name -const dllapi_info_t dllapi_info = { - { mFALSE, 3, api_caller_void_args_void, "GameDLLInit" }, // pfnGameInit - { mFALSE, 10, api_caller_int_args_p, "DispatchSpawn" }, // pfnSpawn - { mFALSE, 16, api_caller_void_args_p, "DispatchThink" }, // pfnThink - { mFALSE, 9, api_caller_void_args_2p, "DispatchUse" }, // pfnUse - { mFALSE, 11, api_caller_void_args_2p, "DispatchTouch" }, // pfnTouch - { mFALSE, 9, api_caller_void_args_2p, "DispatchBlocked" }, // pfnBlocked - { mFALSE, 10, api_caller_void_args_2p, "DispatchKeyValue" }, // pfnKeyValue - { mFALSE, 9, api_caller_void_args_2p, "DispatchSave" }, // pfnSave - { mFALSE, 9, api_caller_int_args_2pi, "DispatchRestore" }, // pfnRestore - { mFALSE, 20, api_caller_void_args_p, "DispatchObjectCollsionBox" }, // pfnSetAbsBox - { mFALSE, 9, api_caller_void_args_4pi, "SaveWriteFields" }, // pfnSaveWriteFields - { mFALSE, 9, api_caller_void_args_4pi, "SaveReadFields" }, // pfnSaveReadFields - { mFALSE, 9, api_caller_void_args_p, "SaveGlobalState" }, // pfnSaveGlobalState - { mFALSE, 9, api_caller_void_args_p, "RestoreGlobalState" }, // pfnRestoreGlobalState - { mFALSE, 9, api_caller_void_args_void, "ResetGlobalState" }, // pfnResetGlobalState - { mFALSE, 3, api_caller_int_args_4p, "ClientConnect" }, // pfnClientConnect - { mFALSE, 3, api_caller_void_args_p, "ClientDisconnect" }, // pfnClientDisconnect - { mFALSE, 3, api_caller_void_args_p, "ClientKill" }, // pfnClientKill - { mFALSE, 3, api_caller_void_args_p, "ClientPutInServer" }, // pfnClientPutInServer - { mFALSE, 9, api_caller_void_args_p, "ClientCommand" }, // pfnClientCommand - { mFALSE, 11, api_caller_void_args_2p, "ClientUserInfoChanged" }, // pfnClientUserInfoChanged - { mFALSE, 3, api_caller_void_args_p2i, "ServerActivate" }, // pfnServerActivate - { mFALSE, 3, api_caller_void_args_void, "ServerDeactivate" }, // pfnServerDeactivate - { mFALSE, 14, api_caller_void_args_p, "PlayerPreThink" }, // pfnPlayerPreThink - { mFALSE, 14, api_caller_void_args_p, "PlayerPostThink" }, // pfnPlayerPostThink - { mFALSE, 18, api_caller_void_args_void, "StartFrame" }, // pfnStartFrame - { mFALSE, 9, api_caller_void_args_void, "ParmsNewLevel" }, // pfnParmsNewLevel - { mFALSE, 9, api_caller_void_args_void, "ParmsChangeLevel" }, // pfnParmsChangeLevel - { mFALSE, 9, api_caller_ptr_args_void, "GetGameDescription" }, // pfnGetGameDescription - { mFALSE, 9, api_caller_void_args_2p, "PlayerCustomization" }, // pfnPlayerCustomization - { mFALSE, 9, api_caller_void_args_p, "SpectatorConnect" }, // pfnSpectatorConnect - { mFALSE, 9, api_caller_void_args_p, "SpectatorDisconnect" }, // pfnSpectatorDisconnect - { mFALSE, 9, api_caller_void_args_p, "SpectatorThink" }, // pfnSpectatorThink - { mFALSE, 3, api_caller_void_args_p, "Sys_Error" }, // pfnSys_Error - { mFALSE, 13, api_caller_void_args_pi, "PM_Move" }, // pfnPM_Move - { mFALSE, 9, api_caller_void_args_p, "PM_Init" }, // pfnPM_Init - { mFALSE, 9, api_caller_char_args_p, "PM_FindTextureType" }, // pfnPM_FindTextureType - { mFALSE, 12, api_caller_void_args_4p, "SetupVisibility" }, // pfnSetupVisibility - { mFALSE, 12, api_caller_void_args_pip, "UpdateClientData" }, // pfnUpdateClientData - { mFALSE, 16, api_caller_int_args_pi2p2ip, "AddToFullPack" }, // pfnAddToFullPack - { mFALSE, 9, api_caller_void_args_2i2pi2p, "CreateBaseline" }, // pfnCreateBaseline - { mFALSE, 9, api_caller_void_args_void, "RegisterEncoders" }, // pfnRegisterEncoders - { mFALSE, 9, api_caller_int_args_2p, "GetWeaponData" }, // pfnGetWeaponData - { mFALSE, 15, api_caller_void_args_2pui, "CmdStart" }, // pfnCmdStart - { mFALSE, 15, api_caller_void_args_p, "CmdEnd" }, // pfnCmdEnd - { mFALSE, 9, api_caller_int_args_4p, "ConnectionlessPacket" }, // pfnConnectionlessPacket - { mFALSE, 9, api_caller_int_args_i2p, "GetHullBounds" }, // pfnGetHullBounds - { mFALSE, 9, api_caller_void_args_void, "CreateInstancedBaselines" }, // pfnCreateInstancedBaselines - { mFALSE, 3, api_caller_int_args_3p, "InconsistentFile" }, // pfnInconsistentFile - { mFALSE, 20, api_caller_int_args_void, "AllowLagCompensation" }, // pfnAllowLagCompensation - - { mFALSE, 0, nullptr, nullptr }, +dllapi_info_t dllapi_info = { + { mFALSE, 3, "GameDLLInit" }, // pfnGameInit + { mFALSE, 10, "DispatchSpawn" }, // pfnSpawn + { mFALSE, 16, "DispatchThink" }, // pfnThink + { mFALSE, 9, "DispatchUse" }, // pfnUse + { mFALSE, 11, "DispatchTouch" }, // pfnTouch + { mFALSE, 9, "DispatchBlocked" }, // pfnBlocked + { mFALSE, 10, "DispatchKeyValue" }, // pfnKeyValue + { mFALSE, 9, "DispatchSave" }, // pfnSave + { mFALSE, 9, "DispatchRestore" }, // pfnRestore + { mFALSE, 20, "DispatchObjectCollsionBox" }, // pfnSetAbsBox + { mFALSE, 9, "SaveWriteFields" }, // pfnSaveWriteFields + { mFALSE, 9, "SaveReadFields" }, // pfnSaveReadFields + { mFALSE, 9, "SaveGlobalState" }, // pfnSaveGlobalState + { mFALSE, 9, "RestoreGlobalState" }, // pfnRestoreGlobalState + { mFALSE, 9, "ResetGlobalState" }, // pfnResetGlobalState + { mFALSE, 3, "ClientConnect" }, // pfnClientConnect + { mFALSE, 3, "ClientDisconnect" }, // pfnClientDisconnect + { mFALSE, 3, "ClientKill" }, // pfnClientKill + { mFALSE, 3, "ClientPutInServer" }, // pfnClientPutInServer + { mFALSE, 9, "ClientCommand" }, // pfnClientCommand + { mFALSE, 11, "ClientUserInfoChanged" }, // pfnClientUserInfoChanged + { mFALSE, 3, "ServerActivate" }, // pfnServerActivate + { mFALSE, 3, "ServerDeactivate" }, // pfnServerDeactivate + { mFALSE, 14, "PlayerPreThink" }, // pfnPlayerPreThink + { mFALSE, 14, "PlayerPostThink" }, // pfnPlayerPostThink + { mFALSE, 18, "StartFrame" }, // pfnStartFrame + { mFALSE, 9, "ParmsNewLevel" }, // pfnParmsNewLevel + { mFALSE, 9, "ParmsChangeLevel" }, // pfnParmsChangeLevel + { mFALSE, 9, "GetGameDescription" }, // pfnGetGameDescription + { mFALSE, 9, "PlayerCustomization" }, // pfnPlayerCustomization + { mFALSE, 9, "SpectatorConnect" }, // pfnSpectatorConnect + { mFALSE, 9, "SpectatorDisconnect" }, // pfnSpectatorDisconnect + { mFALSE, 9, "SpectatorThink" }, // pfnSpectatorThink + { mFALSE, 3, "Sys_Error" }, // pfnSys_Error + { mFALSE, 13, "PM_Move" }, // pfnPM_Move + { mFALSE, 9, "PM_Init" }, // pfnPM_Init + { mFALSE, 9, "PM_FindTextureType" }, // pfnPM_FindTextureType + { mFALSE, 12, "SetupVisibility" }, // pfnSetupVisibility + { mFALSE, 12, "UpdateClientData" }, // pfnUpdateClientData + { mFALSE, 16, "AddToFullPack" }, // pfnAddToFullPack + { mFALSE, 9, "CreateBaseline" }, // pfnCreateBaseline + { mFALSE, 9, "RegisterEncoders" }, // pfnRegisterEncoders + { mFALSE, 9, "GetWeaponData" }, // pfnGetWeaponData + { mFALSE, 15, "CmdStart" }, // pfnCmdStart + { mFALSE, 15, "CmdEnd" }, // pfnCmdEnd + { mFALSE, 9, "ConnectionlessPacket" }, // pfnConnectionlessPacket + { mFALSE, 9, "GetHullBounds" }, // pfnGetHullBounds + { mFALSE, 9, "CreateInstancedBaselines" }, // pfnCreateInstancedBaselines + { mFALSE, 3, "InconsistentFile" }, // pfnInconsistentFile + { mFALSE, 20, "AllowLagCompensation" }, // pfnAllowLagCompensation + { mFALSE, 0, NULL }, }; -const newapi_info_t newapi_info = { - { mFALSE, 16, api_caller_void_args_p, "OnFreeEntPrivateData" }, // pfnOnFreeEntPrivateData - { mFALSE, 3, api_caller_void_args_void, "GameShutdown" }, // pfnGameShutdown - { mFALSE, 14, api_caller_int_args_2p, "ShouldCollide" }, // pfnShouldCollide - { mFALSE, 3, api_caller_void_args_2p, "CvarValue" }, // pfnCvarValue - { mFALSE, 3, api_caller_void_args_pi2p, "CvarValue2" }, // pfnCvarValue2 - - { mFALSE, 0, nullptr, nullptr }, +newapi_info_t newapi_info = { + { mFALSE, 16, "OnFreeEntPrivateData" }, // pfnOnFreeEntPrivateData + { mFALSE, 3, "GameShutdown" }, // pfnGameShutdown + { mFALSE, 14, "ShouldCollide" }, // pfnShouldCollide + // Added 2005-08-11 (no SDK update) + { mFALSE, 3, "CvarValue" }, // pfnCvarValue + // Added 2005-11-22 (no SDK update) + { mFALSE, 3, "CvarValue2" }, // pfnCvarValue2 + { mFALSE, 0, NULL }, }; -const engine_info_t engine_info = { - { mFALSE, 13, api_caller_int_args_p, "PrecacheModel" }, // pfnPrecacheModel - { mFALSE, 13, api_caller_int_args_p, "PrecacheSound" }, // pfnPrecacheSound - { mFALSE, 18, api_caller_void_args_2p, "SetModel" }, // pfnSetModel - { mFALSE, 34, api_caller_int_args_p, "ModelIndex" }, // pfnModelIndex - { mFALSE, 10, api_caller_int_args_i, "ModelFrames" }, // pfnModelFrames - { mFALSE, 14, api_caller_void_args_3p, "SetSize" }, // pfnSetSize - { mFALSE, 9, api_caller_void_args_2p, "ChangeLevel" }, // pfnChangeLevel - { mFALSE, 9, api_caller_void_args_p, "GetSpawnParms" }, // pfnGetSpawnParms - { mFALSE, 9, api_caller_void_args_p, "SaveSpawnParms" }, // pfnSaveSpawnParms - { mFALSE, 9, api_caller_float_args_p, "VecToYaw" }, // pfnVecToYaw - { mFALSE, 14, api_caller_void_args_2p, "VecToAngles" }, // pfnVecToAngles - { mFALSE, 9, api_caller_void_args_2pfi, "MoveToOrigin" }, // pfnMoveToOrigin - { mFALSE, 9, api_caller_void_args_p, "ChangeYaw" }, // pfnChangeYaw - { mFALSE, 9, api_caller_void_args_p, "ChangePitch" }, // pfnChangePitch - { mFALSE, 32, api_caller_ptr_args_3p, "FindEntityByString" }, // pfnFindEntityByString - { mFALSE, 9, api_caller_int_args_p, "GetEntityIllum" }, // pfnGetEntityIllum - { mFALSE, 9, api_caller_ptr_args_2pf, "FindEntityInSphere" }, // pfnFindEntityInSphere - { mFALSE, 19, api_caller_ptr_args_p, "FindClientInPVS" }, // pfnFindClientInPVS - { mFALSE, 9, api_caller_ptr_args_p, "EntitiesInPVS" }, // pfnEntitiesInPVS - { mFALSE, 40, api_caller_void_args_p, "MakeVectors" }, // pfnMakeVectors - { mFALSE, 9, api_caller_void_args_4p, "AngleVectors" }, // pfnAngleVectors - { mFALSE, 13, api_caller_ptr_args_void, "CreateEntity" }, // pfnCreateEntity - { mFALSE, 13, api_caller_void_args_p, "RemoveEntity" }, // pfnRemoveEntity - { mFALSE, 13, api_caller_ptr_args_i, "CreateNamedEntity" }, // pfnCreateNamedEntity - { mFALSE, 9, api_caller_void_args_p, "MakeStatic" }, // pfnMakeStatic - { mFALSE, 9, api_caller_int_args_p, "EntIsOnFloor" }, // pfnEntIsOnFloor - { mFALSE, 9, api_caller_int_args_p, "DropToFloor" }, // pfnDropToFloor - { mFALSE, 9, api_caller_int_args_p2fi, "WalkMove" }, // pfnWalkMove - { mFALSE, 14, api_caller_void_args_2p, "SetOrigin" }, // pfnSetOrigin - { mFALSE, 12, api_caller_void_args_pip2f2i, "EmitSound" }, // pfnEmitSound - { mFALSE, 12, api_caller_void_args_3p2f2i, "EmitAmbientSound" }, // pfnEmitAmbientSound - { mFALSE, 20, api_caller_void_args_2pi2p, "TraceLine" }, // pfnTraceLine - { mFALSE, 9, api_caller_void_args_3p, "TraceToss" }, // pfnTraceToss - { mFALSE, 9, api_caller_int_args_3pi2p, "TraceMonsterHull" }, // pfnTraceMonsterHull - { mFALSE, 9, api_caller_void_args_2p2i2p, "TraceHull" }, // pfnTraceHull - { mFALSE, 9, api_caller_void_args_2pi2p, "TraceModel" }, // pfnTraceModel - { mFALSE, 15, api_caller_ptr_args_3p, "TraceTexture" }, // pfnTraceTexture // CS: when moving - { mFALSE, 9, api_caller_void_args_2pif2p, "TraceSphere" }, // pfnTraceSphere - { mFALSE, 9, api_caller_void_args_pfp, "GetAimVector" }, // pfnGetAimVector - { mFALSE, 9, api_caller_void_args_p, "ServerCommand" }, // pfnServerCommand - { mFALSE, 9, api_caller_void_args_void, "ServerExecute" }, // pfnServerExecute - { mFALSE, 11, api_caller_void_args_2pV, "engClientCommand" }, // pfnClientCommand // d'oh, ClientCommand in dllapi too - { mFALSE, 9, api_caller_void_args_2p2f, "ParticleEffect" }, // pfnParticleEffect - { mFALSE, 9, api_caller_void_args_ip, "LightStyle" }, // pfnLightStyle - { mFALSE, 9, api_caller_int_args_p, "DecalIndex" }, // pfnDecalIndex - { mFALSE, 15, api_caller_int_args_p, "PointContents" }, // pfnPointContents // CS: when moving - { mFALSE, 22, api_caller_void_args_2i2p, "MessageBegin" }, // pfnMessageBegin - { mFALSE, 22, api_caller_void_args_void, "MessageEnd" }, // pfnMessageEnd - { mFALSE, 30, api_caller_void_args_i, "WriteByte" }, // pfnWriteByte - { mFALSE, 23, api_caller_void_args_i, "WriteChar" }, // pfnWriteChar - { mFALSE, 24, api_caller_void_args_i, "WriteShort" }, // pfnWriteShort - { mFALSE, 23, api_caller_void_args_i, "WriteLong" }, // pfnWriteLong - { mFALSE, 23, api_caller_void_args_f, "WriteAngle" }, // pfnWriteAngle - { mFALSE, 23, api_caller_void_args_f, "WriteCoord" }, // pfnWriteCoord - { mFALSE, 25, api_caller_void_args_p, "WriteString" }, // pfnWriteString - { mFALSE, 23, api_caller_void_args_i, "WriteEntity" }, // pfnWriteEntity - { mFALSE, 9, api_caller_void_args_p, "CVarRegister" }, // pfnCVarRegister - { mFALSE, 21, api_caller_float_args_p, "CVarGetFloat" }, // pfnCVarGetFloat - { mFALSE, 9, api_caller_ptr_args_p, "CVarGetString" }, // pfnCVarGetString - { mFALSE, 10, api_caller_void_args_pf, "CVarSetFloat" }, // pfnCVarSetFloat - { mFALSE, 9, api_caller_void_args_2p, "CVarSetString" }, // pfnCVarSetString - { mFALSE, 15, api_caller_void_args_ipV, "AlertMessage" }, // pfnAlertMessage - { mFALSE, 17, api_caller_void_args_2pV, "EngineFprintf" }, // pfnEngineFprintf - { mFALSE, 14, api_caller_ptr_args_pi, "PvAllocEntPrivateData" }, // pfnPvAllocEntPrivateData - { mFALSE, 9, api_caller_ptr_args_p, "PvEntPrivateData" }, // pfnPvEntPrivateData - { mFALSE, 9, api_caller_void_args_p, "FreeEntPrivateData" }, // pfnFreeEntPrivateData - { mFALSE, 9, api_caller_ptr_args_i, "SzFromIndex" }, // pfnSzFromIndex - { mFALSE, 10, api_caller_int_args_p, "AllocString" }, // pfnAllocString - { mFALSE, 9, api_caller_ptr_args_p, "GetVarsOfEnt" }, // pfnGetVarsOfEnt - { mFALSE, 14, api_caller_ptr_args_i, "PEntityOfEntOffset" }, // pfnPEntityOfEntOffset - { mFALSE, 19, api_caller_int_args_p, "EntOffsetOfPEntity" }, // pfnEntOffsetOfPEntity - { mFALSE, 14, api_caller_int_args_p, "IndexOfEdict" }, // pfnIndexOfEdict - { mFALSE, 17, api_caller_ptr_args_i, "PEntityOfEntIndex" }, // pfnPEntityOfEntIndex - { mFALSE, 9, api_caller_ptr_args_p, "FindEntityByVars" }, // pfnFindEntityByVars - { mFALSE, 14, api_caller_ptr_args_p, "GetModelPtr" }, // pfnGetModelPtr - { mFALSE, 9, api_caller_int_args_pi, "RegUserMsg" }, // pfnRegUserMsg - { mFALSE, 9, api_caller_void_args_pf, "AnimationAutomove" }, // pfnAnimationAutomove - { mFALSE, 9, api_caller_void_args_pi2p, "GetBonePosition" }, // pfnGetBonePosition - { mFALSE, 9, api_caller_uint_args_p, "FunctionFromName" }, // pfnFunctionFromName - { mFALSE, 9, api_caller_ptr_args_ui, "NameForFunction" }, // pfnNameForFunction - { mFALSE, 9, api_caller_void_args_pip, "ClientPrintf" }, // pfnClientPrintf - { mFALSE, 9, api_caller_void_args_p, "ServerPrint" }, // pfnServerPrint - { mFALSE, 13, api_caller_ptr_args_void, "Cmd_Args" }, // pfnCmd_Args - { mFALSE, 13, api_caller_ptr_args_i, "Cmd_Argv" }, // pfnCmd_Argv - { mFALSE, 13, api_caller_int_args_void, "Cmd_Argc" }, // pfnCmd_Argc - { mFALSE, 9, api_caller_void_args_pi2p, "GetAttachment" }, // pfnGetAttachment - { mFALSE, 9, api_caller_void_args_p, "CRC32_Init" }, // pfnCRC32_Init - { mFALSE, 9, api_caller_void_args_2pi, "CRC32_ProcessBuffer" }, // pfnCRC32_ProcessBuffer - { mFALSE, 9, api_caller_void_args_puc, "CRC32_ProcessByte" }, // pfnCRC32_ProcessByte - { mFALSE, 9, api_caller_ulong_args_ul, "CRC32_Final" }, // pfnCRC32_Final - { mFALSE, 16, api_caller_int_args_2i, "RandomLong" }, // pfnRandomLong - { mFALSE, 14, api_caller_float_args_2f, "RandomFloat" }, // pfnRandomFloat // CS: when firing - { mFALSE, 14, api_caller_void_args_2p, "SetView" }, // pfnSetView - { mFALSE, 9, api_caller_float_args_void, "Time" }, // pfnTime - { mFALSE, 9, api_caller_void_args_p2f, "CrosshairAngle" }, // pfnCrosshairAngle - { mFALSE, 10, api_caller_ptr_args_2p, "LoadFileForMe" }, // pfnLoadFileForMe - { mFALSE, 10, api_caller_void_args_p, "FreeFile" }, // pfnFreeFile - { mFALSE, 9, api_caller_void_args_p, "EndSection" }, // pfnEndSection - { mFALSE, 9, api_caller_int_args_3p, "CompareFileTime" }, // pfnCompareFileTime - { mFALSE, 9, api_caller_void_args_p, "GetGameDir" }, // pfnGetGameDir - { mFALSE, 9, api_caller_void_args_p, "Cvar_RegisterVariable" }, // pfnCvar_RegisterVariable - { mFALSE, 9, api_caller_void_args_p4i, "FadeClientVolume" }, // pfnFadeClientVolume - { mFALSE, 14, api_caller_void_args_pf, "SetClientMaxspeed" }, // pfnSetClientMaxspeed - { mFALSE, 9, api_caller_ptr_args_p, "CreateFakeClient" }, // pfnCreateFakeClient - { mFALSE, 9, api_caller_void_args_2p3fus2uc, "RunPlayerMove" }, // pfnRunPlayerMove - { mFALSE, 9, api_caller_int_args_void, "NumberOfEntities" }, // pfnNumberOfEntities - { mFALSE, 17, api_caller_ptr_args_p, "GetInfoKeyBuffer" }, // pfnGetInfoKeyBuffer - { mFALSE, 13, api_caller_ptr_args_2p, "InfoKeyValue" }, // pfnInfoKeyValue - { mFALSE, 9, api_caller_void_args_3p, "SetKeyValue" }, // pfnSetKeyValue - { mFALSE, 12, api_caller_void_args_i3p, "SetClientKeyValue" }, // pfnSetClientKeyValue - { mFALSE, 9, api_caller_int_args_p, "IsMapValid" }, // pfnIsMapValid - { mFALSE, 9, api_caller_void_args_p3i, "StaticDecal" }, // pfnStaticDecal - { mFALSE, 9, api_caller_int_args_p, "PrecacheGeneric" }, // pfnPrecacheGeneric - { mFALSE, 10, api_caller_int_args_p, "GetPlayerUserId" }, // pfnGetPlayerUserId - { mFALSE, 9, api_caller_void_args_pip2f4i2p, "BuildSoundMsg" }, // pfnBuildSoundMsg - { mFALSE, 9, api_caller_int_args_void, "IsDedicatedServer" }, // pfnIsDedicatedServer - { mFALSE, 9, api_caller_ptr_args_p, "CVarGetPointer" }, // pfnCVarGetPointer - { mFALSE, 9, api_caller_uint_args_p, "GetPlayerWONId" }, // pfnGetPlayerWONId - { mFALSE, 9, api_caller_void_args_2p, "Info_RemoveKey" }, // pfnInfo_RemoveKey - { mFALSE, 15, api_caller_ptr_args_2p, "GetPhysicsKeyValue" }, // pfnGetPhysicsKeyValue - { mFALSE, 14, api_caller_void_args_3p, "SetPhysicsKeyValue" }, // pfnSetPhysicsKeyValue - { mFALSE, 15, api_caller_ptr_args_p, "GetPhysicsInfoString" }, // pfnGetPhysicsInfoString - { mFALSE, 13, api_caller_ushort_args_ip, "PrecacheEvent" }, // pfnPrecacheEvent - { mFALSE, 9, api_caller_void_args_ipusf2p2f4i,"PlaybackEvent" }, // pfnPlaybackEvent - { mFALSE, 31, api_caller_ptr_args_p, "SetFatPVS" }, // pfnSetFatPVS - { mFALSE, 31, api_caller_ptr_args_p, "SetFatPAS" }, // pfnSetFatPAS - { mFALSE, 50, api_caller_int_args_2p, "CheckVisibility" }, // pfnCheckVisibility - { mFALSE, 37, api_caller_void_args_2p, "DeltaSetField" }, // pfnDeltaSetField - { mFALSE, 38, api_caller_void_args_2p, "DeltaUnsetField" }, // pfnDeltaUnsetField - { mFALSE, 9, api_caller_void_args_2p, "DeltaAddEncoder" }, // pfnDeltaAddEncoder - { mFALSE, 45, api_caller_int_args_void, "GetCurrentPlayer" }, // pfnGetCurrentPlayer - { mFALSE, 14, api_caller_int_args_p, "CanSkipPlayer" }, // pfnCanSkipPlayer - { mFALSE, 9, api_caller_int_args_2p, "DeltaFindField" }, // pfnDeltaFindField - { mFALSE, 37, api_caller_void_args_pi, "DeltaSetFieldByIndex" }, // pfnDeltaSetFieldByIndex - { mFALSE, 38, api_caller_void_args_pi, "DeltaUnsetFieldByIndex" }, // pfnDeltaUnsetFieldByIndex - { mFALSE, 9, api_caller_void_args_2i, "SetGroupMask" }, // pfnSetGroupMask - { mFALSE, 9, api_caller_int_args_ip, "engCreateInstancedBaseline" }, // pfnCreateInstancedBaseline // d'oh, CreateInstancedBaseline in dllapi too - { mFALSE, 9, api_caller_void_args_2p, "Cvar_DirectSet" }, // pfnCvar_DirectSet - { mFALSE, 9, api_caller_void_args_i3p, "ForceUnmodified" }, // pfnForceUnmodified - { mFALSE, 9, api_caller_void_args_3p, "GetPlayerStats" }, // pfnGetPlayerStats - { mFALSE, 3, api_caller_void_args_2p, "AddServerCommand" }, // pfnAddServerCommand - - { mFALSE, 9, api_caller_int_args_2i, "Voice_GetClientListening" }, // Voice_GetClientListening - { mFALSE, 9, api_caller_int_args_3i, "Voice_SetClientListening" }, // Voice_SetClientListening - { mFALSE, 9, api_caller_ptr_args_p, "GetPlayerAuthId" }, // pfnGetPlayerAuthId - - { mFALSE, 30, api_caller_ptr_args_2p, "SequenceGet" }, // pfnSequenceGet - { mFALSE, 30, api_caller_ptr_args_pip, "SequencePickSentence" }, // pfnSequencePickSentence - { mFALSE, 30, api_caller_int_args_p, "GetFileSize" }, // pfnGetFileSize - { mFALSE, 30, api_caller_uint_args_p, "GetApproxWavePlayLen" }, // pfnGetApproxWavePlayLen - { mFALSE, 30, api_caller_int_args_void, "IsCareerMatch" }, // pfnIsCareerMatch - { mFALSE, 30, api_caller_int_args_p, "GetLocalizedStringLength" }, // pfnGetLocalizedStringLength - { mFALSE, 30, api_caller_void_args_i, "RegisterTutorMessageShown" }, // pfnRegisterTutorMessageShown - { mFALSE, 30, api_caller_int_args_i, "GetTimesTutorMessageShown" }, // pfnGetTimesTutorMessageShown - { mFALSE, 30, api_caller_void_args_pi, "ProcessTutorMessageDecayBuffer" }, // pfnProcessTutorMessageDecayBuffer - { mFALSE, 30, api_caller_void_args_pi, "ConstructTutorMessageDecayBuffer" }, // pfnConstructTutorMessageDecayBuffer - { mFALSE, 9, api_caller_void_args_void, "ResetTutorMessageDecayData" }, // pfnResetTutorMessageDecayData - - { mFALSE, 3, api_caller_void_args_2p, "QueryClientCvarValue" }, // pfnQueryClientCvarValue - { mFALSE, 3, api_caller_void_args_2pi, "QueryClientCvarValue2" }, // pfnQueryClientCvarValue2 - { mFALSE, 8, api_caller_int_args_2p, "CheckParm" }, // pfnEngCheckParm - +engine_info_t engine_info = { + { mFALSE, 13, "PrecacheModel" }, // pfnPrecacheModel + { mFALSE, 13, "PrecacheSound" }, // pfnPrecacheSound + { mFALSE, 18, "SetModel" }, // pfnSetModel + { mFALSE, 34, "ModelIndex" }, // pfnModelIndex + { mFALSE, 10, "ModelFrames" }, // pfnModelFrames + { mFALSE, 14, "SetSize" }, // pfnSetSize + { mFALSE, 9, "ChangeLevel" }, // pfnChangeLevel + { mFALSE, 9, "GetSpawnParms" }, // pfnGetSpawnParms + { mFALSE, 9, "SaveSpawnParms" }, // pfnSaveSpawnParms + { mFALSE, 9, "VecToYaw" }, // pfnVecToYaw + { mFALSE, 14, "VecToAngles" }, // pfnVecToAngles + { mFALSE, 9, "MoveToOrigin" }, // pfnMoveToOrigin + { mFALSE, 9, "ChangeYaw" }, // pfnChangeYaw + { mFALSE, 9, "ChangePitch" }, // pfnChangePitch + { mFALSE, 32, "FindEntityByString" }, // pfnFindEntityByString + { mFALSE, 9, "GetEntityIllum" }, // pfnGetEntityIllum + { mFALSE, 9, "FindEntityInSphere" }, // pfnFindEntityInSphere + { mFALSE, 19, "FindClientInPVS" }, // pfnFindClientInPVS + { mFALSE, 9, "EntitiesInPVS" }, // pfnEntitiesInPVS + { mFALSE, 40, "MakeVectors" }, // pfnMakeVectors + { mFALSE, 9, "AngleVectors" }, // pfnAngleVectors + { mFALSE, 13, "CreateEntity" }, // pfnCreateEntity + { mFALSE, 13, "RemoveEntity" }, // pfnRemoveEntity + { mFALSE, 13, "CreateNamedEntity" }, // pfnCreateNamedEntity + { mFALSE, 9, "MakeStatic" }, // pfnMakeStatic + { mFALSE, 9, "EntIsOnFloor" }, // pfnEntIsOnFloor + { mFALSE, 9, "DropToFloor" }, // pfnDropToFloor + { mFALSE, 9, "WalkMove" }, // pfnWalkMove + { mFALSE, 14, "SetOrigin" }, // pfnSetOrigin + { mFALSE, 12, "EmitSound" }, // pfnEmitSound + { mFALSE, 12, "EmitAmbientSound" }, // pfnEmitAmbientSound + { mFALSE, 20, "TraceLine" }, // pfnTraceLine + { mFALSE, 9, "TraceToss" }, // pfnTraceToss + { mFALSE, 9, "TraceMonsterHull" }, // pfnTraceMonsterHull + { mFALSE, 9, "TraceHull" }, // pfnTraceHull + { mFALSE, 9, "TraceModel" }, // pfnTraceModel + { mFALSE, 15, "TraceTexture" }, // pfnTraceTexture // CS: when moving + { mFALSE, 9, "TraceSphere" }, // pfnTraceSphere + { mFALSE, 9, "GetAimVector" }, // pfnGetAimVector + { mFALSE, 9, "ServerCommand" }, // pfnServerCommand + { mFALSE, 9, "ServerExecute" }, // pfnServerExecute + { mFALSE, 11, "engClientCommand" }, // pfnClientCommand // d'oh, ClientCommand in dllapi too + { mFALSE, 9, "ParticleEffect" }, // pfnParticleEffect + { mFALSE, 9, "LightStyle" }, // pfnLightStyle + { mFALSE, 9, "DecalIndex" }, // pfnDecalIndex + { mFALSE, 15, "PointContents" }, // pfnPointContents // CS: when moving + { mFALSE, 22, "MessageBegin" }, // pfnMessageBegin + { mFALSE, 22, "MessageEnd" }, // pfnMessageEnd + { mFALSE, 30, "WriteByte" }, // pfnWriteByte + { mFALSE, 23, "WriteChar" }, // pfnWriteChar + { mFALSE, 24, "WriteShort" }, // pfnWriteShort + { mFALSE, 23, "WriteLong" }, // pfnWriteLong + { mFALSE, 23, "WriteAngle" }, // pfnWriteAngle + { mFALSE, 23, "WriteCoord" }, // pfnWriteCoord + { mFALSE, 25, "WriteString" }, // pfnWriteString + { mFALSE, 23, "WriteEntity" }, // pfnWriteEntity + { mFALSE, 9, "CVarRegister" }, // pfnCVarRegister + { mFALSE, 21, "CVarGetFloat" }, // pfnCVarGetFloat + { mFALSE, 9, "CVarGetString" }, // pfnCVarGetString + { mFALSE, 10, "CVarSetFloat" }, // pfnCVarSetFloat + { mFALSE, 9, "CVarSetString" }, // pfnCVarSetString + { mFALSE, 15, "AlertMessage" }, // pfnAlertMessage + { mFALSE, 17, "EngineFprintf" }, // pfnEngineFprintf + { mFALSE, 14, "PvAllocEntPrivateData" }, // pfnPvAllocEntPrivateData + { mFALSE, 9, "PvEntPrivateData" }, // pfnPvEntPrivateData + { mFALSE, 9, "FreeEntPrivateData" }, // pfnFreeEntPrivateData + { mFALSE, 9, "SzFromIndex" }, // pfnSzFromIndex + { mFALSE, 10, "AllocString" }, // pfnAllocString + { mFALSE, 9, "GetVarsOfEnt" }, // pfnGetVarsOfEnt + { mFALSE, 14, "PEntityOfEntOffset" }, // pfnPEntityOfEntOffset + { mFALSE, 19, "EntOffsetOfPEntity" }, // pfnEntOffsetOfPEntity + { mFALSE, 14, "IndexOfEdict" }, // pfnIndexOfEdict + { mFALSE, 17, "PEntityOfEntIndex" }, // pfnPEntityOfEntIndex + { mFALSE, 9, "FindEntityByVars" }, // pfnFindEntityByVars + { mFALSE, 14, "GetModelPtr" }, // pfnGetModelPtr + { mFALSE, 9, "RegUserMsg" }, // pfnRegUserMsg + { mFALSE, 9, "AnimationAutomove" }, // pfnAnimationAutomove + { mFALSE, 9, "GetBonePosition" }, // pfnGetBonePosition + { mFALSE, 9, "FunctionFromName" }, // pfnFunctionFromName + { mFALSE, 9, "NameForFunction" }, // pfnNameForFunction + { mFALSE, 9, "ClientPrintf" }, // pfnClientPrintf + { mFALSE, 9, "ServerPrint" }, // pfnServerPrint + { mFALSE, 13, "Cmd_Args" }, // pfnCmd_Args + { mFALSE, 13, "Cmd_Argv" }, // pfnCmd_Argv + { mFALSE, 13, "Cmd_Argc" }, // pfnCmd_Argc + { mFALSE, 9, "GetAttachment" }, // pfnGetAttachment + { mFALSE, 9, "CRC32_Init" }, // pfnCRC32_Init + { mFALSE, 9, "CRC32_ProcessBuffer" }, // pfnCRC32_ProcessBuffer + { mFALSE, 9, "CRC32_ProcessByte" }, // pfnCRC32_ProcessByte + { mFALSE, 9, "CRC32_Final" }, // pfnCRC32_Final + { mFALSE, 16, "RandomLong" }, // pfnRandomLong + { mFALSE, 14, "RandomFloat" }, // pfnRandomFloat // CS: when firing + { mFALSE, 14, "SetView" }, // pfnSetView + { mFALSE, 9, "Time" }, // pfnTime + { mFALSE, 9, "CrosshairAngle" }, // pfnCrosshairAngle + { mFALSE, 10, "LoadFileForMe" }, // pfnLoadFileForMe + { mFALSE, 10, "FreeFile" }, // pfnFreeFile + { mFALSE, 9, "EndSection" }, // pfnEndSection + { mFALSE, 9, "CompareFileTime" }, // pfnCompareFileTime + { mFALSE, 9, "GetGameDir" }, // pfnGetGameDir + { mFALSE, 9, "Cvar_RegisterVariable" }, // pfnCvar_RegisterVariable + { mFALSE, 9, "FadeClientVolume" }, // pfnFadeClientVolume + { mFALSE, 14, "SetClientMaxspeed" }, // pfnSetClientMaxspeed + { mFALSE, 9, "CreateFakeClient" }, // pfnCreateFakeClient + { mFALSE, 9, "RunPlayerMove" }, // pfnRunPlayerMove + { mFALSE, 9, "NumberOfEntities" }, // pfnNumberOfEntities + { mFALSE, 17, "GetInfoKeyBuffer" }, // pfnGetInfoKeyBuffer + { mFALSE, 13, "InfoKeyValue" }, // pfnInfoKeyValue + { mFALSE, 9, "SetKeyValue" }, // pfnSetKeyValue + { mFALSE, 12, "SetClientKeyValue" }, // pfnSetClientKeyValue + { mFALSE, 9, "IsMapValid" }, // pfnIsMapValid + { mFALSE, 9, "StaticDecal" }, // pfnStaticDecal + { mFALSE, 9, "PrecacheGeneric" }, // pfnPrecacheGeneric + { mFALSE, 10, "GetPlayerUserId" }, // pfnGetPlayerUserId + { mFALSE, 9, "BuildSoundMsg" }, // pfnBuildSoundMsg + { mFALSE, 9, "IsDedicatedServer" }, // pfnIsDedicatedServer + { mFALSE, 9, "CVarGetPointer" }, // pfnCVarGetPointer + { mFALSE, 9, "GetPlayerWONId" }, // pfnGetPlayerWONId + { mFALSE, 9, "Info_RemoveKey" }, // pfnInfo_RemoveKey + { mFALSE, 15, "GetPhysicsKeyValue" }, // pfnGetPhysicsKeyValue + { mFALSE, 14, "SetPhysicsKeyValue" }, // pfnSetPhysicsKeyValue + { mFALSE, 15, "GetPhysicsInfoString" }, // pfnGetPhysicsInfoString + { mFALSE, 13, "PrecacheEvent" }, // pfnPrecacheEvent + { mFALSE, 9, "PlaybackEvent" }, // pfnPlaybackEvent + { mFALSE, 31, "SetFatPVS" }, // pfnSetFatPVS + { mFALSE, 31, "SetFatPAS" }, // pfnSetFatPAS + { mFALSE, 50, "CheckVisibility" }, // pfnCheckVisibility + { mFALSE, 37, "DeltaSetField" }, // pfnDeltaSetField + { mFALSE, 38, "DeltaUnsetField" }, // pfnDeltaUnsetField + { mFALSE, 9, "DeltaAddEncoder" }, // pfnDeltaAddEncoder + { mFALSE, 45, "GetCurrentPlayer" }, // pfnGetCurrentPlayer + { mFALSE, 14, "CanSkipPlayer" }, // pfnCanSkipPlayer + { mFALSE, 9, "DeltaFindField" }, // pfnDeltaFindField + { mFALSE, 37, "DeltaSetFieldByIndex" }, // pfnDeltaSetFieldByIndex + { mFALSE, 38, "DeltaUnsetFieldByIndex" }, // pfnDeltaUnsetFieldByIndex + { mFALSE, 9, "SetGroupMask" }, // pfnSetGroupMask + { mFALSE, 9, "engCreateInstancedBaseline" }, // pfnCreateInstancedBaseline // d'oh, CreateInstancedBaseline in dllapi too + { mFALSE, 9, "Cvar_DirectSet" }, // pfnCvar_DirectSet + { mFALSE, 9, "ForceUnmodified" }, // pfnForceUnmodified + { mFALSE, 9, "GetPlayerStats" }, // pfnGetPlayerStats + { mFALSE, 3, "AddServerCommand" }, // pfnAddServerCommand + // Added in SDK 2.2: + { mFALSE, 9, "Voice_GetClientListening" }, // Voice_GetClientListening + { mFALSE, 9, "Voice_SetClientListening" }, // Voice_SetClientListening + // Added for HL 1109 (no SDK update): + { mFALSE, 9, "GetPlayerAuthId" }, // pfnGetPlayerAuthId + // Added 2003-11-10 (no SDK update): + { mFALSE, 30, "SequenceGet" }, // pfnSequenceGet + { mFALSE, 30, "SequencePickSentence" }, // pfnSequencePickSentence + { mFALSE, 30, "GetFileSize" }, // pfnGetFileSize + { mFALSE, 30, "GetApproxWavePlayLen" }, // pfnGetApproxWavePlayLen + { mFALSE, 30, "IsCareerMatch" }, // pfnIsCareerMatch + { mFALSE, 30, "GetLocalizedStringLength" }, // pfnGetLocalizedStringLength + { mFALSE, 30, "RegisterTutorMessageShown" }, // pfnRegisterTutorMessageShown + { mFALSE, 30, "GetTimesTutorMessageShown" }, // pfnGetTimesTutorMessageShown + { mFALSE, 30, "ProcessTutorMessageDecayBuffer" }, // pfnProcessTutorMessageDecayBuffer + { mFALSE, 30, "ConstructTutorMessageDecayBuffer" }, // pfnConstructTutorMessageDecayBuffer + { mFALSE, 9, "ResetTutorMessageDecayData" }, // pfnResetTutorMessageDecayData + // Added 2005-08-11 (no SDK update) + { mFALSE, 3, "QueryClientCvarValue" }, //pfnQueryClientCvarValue + // Added 2005-11-22 (no SDK update) + { mFALSE, 3, "QueryClientCvarValue2" }, //pfnQueryClientCvarValue2 + // Added 2009-06-17 (no SDK update) + { mFALSE, 8, "CheckParm" }, //pfnCheckParm // end - { mFALSE, 0, nullptr, nullptr }, + { mFALSE, 0, NULL }, }; diff --git a/metamod/src/api_info.h b/metamod/src/api_info.h index 88dbdcb..da6d7ea 100644 --- a/metamod/src/api_info.h +++ b/metamod/src/api_info.h @@ -1,33 +1,58 @@ -#pragma once +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// api_info.h - structures to store info about api routines + +/* + * Copyright (c) 2001-2003 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game g_engine ("HL + * g_engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL g_engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + +#ifndef API_INFO_H +#define API_INFO_H #include "types_meta.h" // mBOOL -#include "ret_type.h" + #define P_PRE 0 // plugin function called before gamedll #define P_POST 1 // plugin function called after gamedll -// API selector -enum enum_api_t -{ - e_api_engine = 0, - e_api_dllapi, - e_api_newapi, -}; -// API caller function prototype -typedef void *(*api_caller_func_t)(const void *func, const void *packed_args); +typedef struct api_info_s { + mBOOL trace; // if true, log info about this function + int loglevel; // level at which to log info about this function + const char *name; // string representation of function name +} api_info_t; -struct api_info_t -{ - mBOOL trace; // if true, log info about this function - int loglevel; // level at which to log info about this function - api_caller_func_t api_caller; // argument format/type for single-main-hook-function optimization - const char *name; // string representation of function name -}; // DLL api functions -struct dllapi_info_t -{ +typedef struct dllapi_info_s { api_info_t pfnGameInit; api_info_t pfnSpawn; api_info_t pfnThink; @@ -78,27 +103,25 @@ struct dllapi_info_t api_info_t pfnCreateInstancedBaselines; api_info_t pfnInconsistentFile; api_info_t pfnAllowLagCompensation; - - // end api_info_t END; -}; +} dllapi_info_t; + // "New" api functions -struct newapi_info_t -{ +typedef struct newapi_info_s { api_info_t pfnOnFreeEntPrivateData; api_info_t pfnGameShutdown; api_info_t pfnShouldCollide; + // Added 2005/08/11 (no SDK update) api_info_t pfnCvarValue; + // Added 2005/11/22 (no SDK update) api_info_t pfnCvarValue2; - - // end api_info_t END; -}; +} newapi_info_t; -// Engine functions -struct engine_info_t -{ + +// g_engine functions +typedef struct engine_info_s { api_info_t pfnPrecacheModel; api_info_t pfnPrecacheSound; api_info_t pfnSetModel; @@ -240,9 +263,12 @@ struct engine_info_t api_info_t pfnForceUnmodified; api_info_t pfnGetPlayerStats; api_info_t pfnAddServerCommand; + // Added in SDK 2.2: api_info_t pfnVoice_GetClientListening; api_info_t pfnVoice_SetClientListening; + // Added for HL 1109 (no SDK update): api_info_t pfnGetPlayerAuthId; + // Added 2003/11/10 (no SDK update): api_info_t pfnSequenceGet; api_info_t pfnSequencePickSentence; api_info_t pfnGetFileSize; @@ -254,14 +280,19 @@ struct engine_info_t api_info_t pfnProcessTutorMessageDecayBuffer; api_info_t pfnConstructTutorMessageDecayBuffer; api_info_t pfnResetTutorMessageDecayData; + // Added 2005/08/11 (no SDK update) api_info_t pfnQueryClientCvarValue; + // Added 2005/11/22 (no SDK update) api_info_t pfnQueryClientCvarValue2; + // Added 2009/06/17 (no SDK update) api_info_t pfnEngCheckParm; - // end api_info_t END; -}; +} engine_info_t; -extern const dllapi_info_t dllapi_info; -extern const newapi_info_t newapi_info; -extern const engine_info_t engine_info; + +extern dllapi_info_t dllapi_info; +extern newapi_info_t newapi_info; +extern engine_info_t engine_info; + +#endif /* API_INFO_H */ diff --git a/metamod/src/commands_meta.cpp b/metamod/src/commands_meta.cpp index f6cf84a..6e16bbc 100644 --- a/metamod/src/commands_meta.cpp +++ b/metamod/src/commands_meta.cpp @@ -1,104 +1,117 @@ +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// commands_meta.cpp - implementation of various console commands + +/* +* Copyright (c) 2001-2004 Will Day +* +* This file is part of Metamod. +* +* Metamod is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by the +* Free Software Foundation; either version 2 of the License, or (at +* your option) any later version. +* +* Metamod is distributed in the hope that it will be useful, but +* WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with Metamod; if not, write to the Free Software Foundation, +* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +* +* In addition, as a special exception, the author gives permission to +* link the code of this program with the Half-Life Game g_engine ("HL +* g_engine") and Modified Game Libraries ("MODs") developed by Valve, +* L.L.C ("Valve"). You must obey the GNU General Public License in all +* respects for all of the code used other than the HL g_engine and MODs +* from Valve. If you modify this file, you may extend this exception +* to your version of the file, but you are not obligated to do so. If +* you do not wish to do so, delete this exception statement from your +* version. +* +*/ + #include "precompiled.h" -#ifdef META_PERFMON - -long double total_tsc = 0; -unsigned long long count_tsc = 0; -unsigned long long active_tsc = 0; -unsigned long long min_tsc = 0; - -void cmd_meta_tsc() +struct metacmd_t { - if (!count_tsc) - return; + const char* name; + void (*handler)(); +}; - META_CONS(" "); - META_CONS(" count_tsc: %.0f", (double)count_tsc); - META_CONS(" mean_tsc: %.1f", (double)(total_tsc / count_tsc)); - META_CONS(" min_tsc: %.0f", (double)min_tsc); -} - -void cmd_meta_reset_tsc() +metacmd_t g_meta_cmds[] = { - total_tsc = 0; - count_tsc = 0; - min_tsc = 0; -} -#endif + {"version", cmd_meta_version}, + {"gpl", cmd_meta_gpl}, + {"refresh", cmd_meta_refresh}, + {"list", cmd_meta_pluginlist}, + {"cmds", cmd_meta_cmdlist}, + {"cvars", cmd_meta_cvarlist}, + {"game", cmd_meta_game}, + {"config", cmd_meta_config}, + // arguments: existing plugin(s) + {"pause", []() { cmd_doplug(PC_PAUSE); }}, + {"unpause", []() { cmd_doplug(PC_UNPAUSE); }}, + {"unload", []() { cmd_doplug(PC_UNLOAD); }}, + {"force_unload", []() { cmd_doplug(PC_FORCE_UNLOAD); }}, + {"reload", []() { cmd_doplug(PC_RELOAD); }}, + {"retry", []() { cmd_doplug(PC_RETRY); }}, + {"clear", []() { cmd_doplug(PC_CLEAR); }}, + {"info", []() { cmd_doplug(PC_INFO); }}, + {"require", []() { cmd_doplug(PC_REQUIRE); }}, + // arguments: filename, description + {"load", cmd_meta_load}, +}; // Register commands and cvars. void meta_register_cmdcvar() { CVAR_REGISTER(&meta_debug); CVAR_REGISTER(&meta_version); - meta_debug_value = (int)meta_debug.value; - REG_SVR_COMMAND("meta", svr_meta); + REG_SVR_COMMAND("meta", server_meta); } // Parse "meta" console command. -void svr_meta() +void server_meta(void) { - const char *cmd = CMD_ARGV(1); + const char* cmd = CMD_ARGV(1); -#define PARSE_KEY(key, func, ...)\ - if (!Q_stricmp(cmd, key)) {\ - func(__VA_ARGS__);\ - return;\ + for (auto& meta_cmd : g_meta_cmds) { + if (!strcmp(cmd, meta_cmd.name)) { + meta_cmd.handler(); + return; + } } - PARSE_KEY("version", cmd_meta_version); - PARSE_KEY("gpl", cmd_meta_gpl); - PARSE_KEY("refresh", cmd_meta_refresh); - PARSE_KEY("list", cmd_meta_pluginlist); - PARSE_KEY("cmds", cmd_meta_cmdlist); - PARSE_KEY("cvars", cmd_meta_cvarlist); - PARSE_KEY("game", cmd_meta_game); - PARSE_KEY("config", cmd_meta_config); - - PARSE_KEY("pause", cmd_doplug, PC_PAUSE); - PARSE_KEY("unpause", cmd_doplug, PC_UNPAUSE); - PARSE_KEY("unload", cmd_doplug, PC_UNPAUSE); - PARSE_KEY("force_unload", cmd_doplug, PC_FORCE_UNLOAD); - PARSE_KEY("reload", cmd_doplug, PC_RELOAD); - PARSE_KEY("retry", cmd_doplug, PC_RETRY); - PARSE_KEY("clear", cmd_doplug, PC_CLEAR); - PARSE_KEY("info", cmd_doplug, PC_INFO); - PARSE_KEY("require", cmd_doplug, PC_REQUIRE); - - PARSE_KEY("load", cmd_meta_load) - -#ifdef META_PERFMON - PARSE_KEY("tsc", cmd_meta_tsc); - PARSE_KEY("reset_tsc", cmd_meta_reset_tsc); -#endif - - // unrecognized META_CONS("Unrecognized meta command: %s", cmd); cmd_meta_usage(); } // Parse "meta" client command. -void client_meta(edict_t *pEntity) +void client_meta(edict_t* pEntity) { - const char *cmd = CMD_ARGV(1); + const char* cmd = CMD_ARGV(1); + META_LOG("ClientCommand 'meta %s' from player '%s'", CMD_ARGS(), STRING(pEntity->v.netname)); // arguments: none - if (!Q_strcmp(cmd, "version")) + if (!strcmp(cmd, "version")) client_meta_version(pEntity); - - else if (!Q_strcmp(cmd, "list")) + else if (!strcmp(cmd, "list")) client_meta_pluginlist(pEntity); - else - { + // unrecognized + else { META_CLIENT(pEntity, "Unrecognized meta command: %s", cmd); client_meta_usage(pEntity); - return; } } // Print usage for "meta" console command. -void cmd_meta_usage() { +void cmd_meta_usage(void) +{ META_CONS("usage: meta []"); META_CONS("valid commands are:"); META_CONS(" version - display metamod version info"); @@ -121,7 +134,7 @@ void cmd_meta_usage() { } // Print usage for "meta" client command. -void client_meta_usage(edict_t *pEntity) +void client_meta_usage(edict_t* pEntity) { META_CLIENT(pEntity, "usage: meta []"); META_CLIENT(pEntity, "valid commands are:"); @@ -130,38 +143,37 @@ void client_meta_usage(edict_t *pEntity) } // "meta version" console command. -void cmd_meta_version() +void cmd_meta_version(void) { - if (CMD_ARGC() != 2) - { + if (CMD_ARGC() != 2) { META_CONS("usage: meta version"); return; } - - META_CONS("Metamod v%s, API (%s)", APP_VERSION_STRD, META_INTERFACE_VERSION); - META_CONS("Metamod build: " __TIME__ " " __DATE__ " (" APP_VERSION_STRD ")"); - META_CONS("Metamod from: " APP_COMMITS_URL APP_COMMIT_ID " " APP_COMMIT_AUTHOR ""); + META_CONS("%s v%s %s (%s)", VNAME, VVERSION, VDATE, META_INTERFACE_VERSION); + META_CONS("by %s", VAUTHOR); + META_CONS(" %s", VURL); + META_CONS("compiled: %s %s (%s)", COMPILE_TIME, COMPILE_TZONE, OPT_TYPE); } // "meta version" client command. -void client_meta_version(edict_t *pEntity) +void client_meta_version(edict_t* pEntity) { - if (CMD_ARGC() != 2) - { + if (CMD_ARGC() != 2) { META_CLIENT(pEntity, "usage: meta version"); return; } - - META_CONS("Metamod v%s, API (%s)", APP_VERSION_STRD, META_INTERFACE_VERSION); - META_CONS("Metamod build: " __TIME__ " " __DATE__ " (" APP_VERSION_STRD ")"); - META_CONS("Metamod from: " APP_COMMITS_URL APP_COMMIT_ID " " APP_COMMIT_AUTHOR ""); + META_CLIENT(pEntity, "%s v%s %s (%s)", VNAME, VVERSION, VDATE, META_INTERFACE_VERSION); + META_CLIENT(pEntity, "by %s", VAUTHOR); + META_CLIENT(pEntity, " %s", VURL); + META_CLIENT(pEntity, "compiled: %s %s (%s)", COMPILE_TIME, COMPILE_TZONE, OPT_TYPE); + META_CLIENT(pEntity, "ifvers: %s", META_INTERFACE_VERSION); } // "meta gpl" console command. -void cmd_meta_gpl() +void cmd_meta_gpl(void) { - META_CONS("Metamod version " __TIME__ " " __DATE__); - META_CONS("Copyright (c) 2001-2016 Will Day (modification ReHLDS Team)"); + META_CONS("%s version %s %s", VNAME, VVERSION, VDATE); + META_CONS("Copyright (c) 2001-%s Will Day ", COPYRIGHT_YEAR); META_CONS(""); META_CONS(" Metamod is free software; you can redistribute it and/or"); META_CONS(" modify it under the terms of the GNU General Public License"); @@ -181,10 +193,10 @@ void cmd_meta_gpl() META_CONS(" "); META_CONS(" In addition, as a special exception, the author gives"); META_CONS(" permission to link the code of this program with the"); - META_CONS(" Half-Life Game Engine (\"HL Engine\") and Modified Game"); + META_CONS(" Half-Life Game g_engine (\"HL g_engine\") and Modified Game"); META_CONS(" Libraries (\"MODs\") developed by Valve, L.L.C (\"Valve\")."); META_CONS(" You must obey the GNU General Public License in all"); - META_CONS(" respects for all of the code used other than the HL Engine"); + META_CONS(" respects for all of the code used other than the HL g_engine"); META_CONS(" and MODs from Valve. If you modify this file, you may"); META_CONS(" extend this exception to your version of the file, but you"); META_CONS(" are not obligated to do so. If you do not wish to do so,"); @@ -192,97 +204,84 @@ void cmd_meta_gpl() } // "meta game" console command. -void cmd_meta_game() +void cmd_meta_game(void) { - if (CMD_ARGC() != 2) - { + if (CMD_ARGC() != 2) { META_CONS("usage: meta game"); return; } - META_CONS("GameDLL info:"); META_CONS(" name: %s", GameDLL.name); META_CONS(" desc: %s", GameDLL.desc); META_CONS(" gamedir: %s", GameDLL.gamedir); META_CONS(" dll file: %s", GameDLL.file); META_CONS("dll pathname: %s", GameDLL.pathname); - RegMsgs->show(); + g_regMsgs->show(); } // "meta refresh" console command. -void cmd_meta_refresh() +void cmd_meta_refresh(void) { - if (CMD_ARGC() != 2) - { + if (CMD_ARGC() != 2) { META_CONS("usage: meta refresh"); return; } META_LOG("Refreshing the plugins on demand..."); - if (Plugins->refresh(PT_ANYTIME) != mTRUE) - { + + if (g_plugins->refresh(PT_ANYTIME) != mTRUE) { META_LOG("Refresh failed."); } } // "meta list" console command. -void cmd_meta_pluginlist() +void cmd_meta_pluginlist(void) { - if (CMD_ARGC() != 2) - { + if (CMD_ARGC() != 2) { META_CONS("usage: meta list"); return; } - - Plugins->show(); + g_plugins->show(0); } // "meta list" client command. -void client_meta_pluginlist(edict_t *pEntity) +void client_meta_pluginlist(edict_t* pEntity) { - if (CMD_ARGC() != 2) - { + if (CMD_ARGC() != 2) { META_CLIENT(pEntity, "usage: meta list"); return; } - - Plugins->show_client(pEntity); + g_plugins->show_client(pEntity); } // "meta cmds" console command. -void cmd_meta_cmdlist() +void cmd_meta_cmdlist(void) { - if (CMD_ARGC() != 2) - { + if (CMD_ARGC() != 2) { META_CONS("usage: meta cmds"); return; } - - RegCmds->show(); + g_regCmds->show(); } // "meta cvars" console command. -void cmd_meta_cvarlist() +void cmd_meta_cvarlist(void) { - if (CMD_ARGC() != 2) - { + if (CMD_ARGC() != 2) { META_CONS("usage: meta cvars"); return; } - - RegCvars->show(); + g_regCvars->show(); } // "meta config" console command. -void cmd_meta_config() +void cmd_meta_config(void) { - if (CMD_ARGC() != 2) - { + if (CMD_ARGC() != 2) { META_CONS("usage: meta cvars"); return; } - - Config->show(); + g_config->show(); } // gamedir/filename @@ -298,101 +297,107 @@ void cmd_meta_config() // path_i386.so, path_i486.so, etc // "meta load" console command. -void cmd_meta_load() +void cmd_meta_load(void) { int argc = CMD_ARGC(); + if (argc < 3) { META_CONS("usage: meta load []"); META_CONS(" where is an identifier used to locate the plugin file."); META_CONS(" The system will look for a number of files based on this name, including:"); META_CONS(" name"); -#ifdef _WIN32 - META_CONS(" name.dll"); - META_CONS(" name_mm.dll"); - META_CONS(" mm_name.dll"); -#else +#ifdef linux META_CONS(" name.so"); META_CONS(" name_mm.so"); META_CONS(" name_MM.so"); META_CONS(" mm_name.so"); -#endif - + META_CONS(" name_i386.so"); + META_CONS(" name_i686.so"); +#elif defined(__APPLE__) + META_CONS(" name.dylib"); + META_CONS(" name_mm.dylib"); + META_CONS(" mm_name.dylib"); +#elif defined(_WIN32) + META_CONS(" name.dll"); + META_CONS(" name_mm.dll"); + META_CONS(" mm_name.dll"); +#endif /* linux */ META_CONS(" in a number of directories, including:"); META_CONS(" "); META_CONS(" /dlls"); META_CONS(" "); return; } - const char *args = CMD_ARGS(); + + const char* args = CMD_ARGS(); // cmd_addload() handles all the feedback to the console.. - Plugins->cmd_addload(args); + g_plugins->cmd_addload(args); } // Handle various console commands that refer to a known/loaded plugin. void cmd_doplug(PLUG_CMD pcmd) { - MPlugin *findp; int argc = CMD_ARGC(); - const char *cmd = CMD_ARGV(1); + const char* cmd = CMD_ARGV(1); - if (argc < 3) - { + if (argc < 3) { META_CONS("usage: meta %s [ ...]", cmd); META_CONS(" where can be either the plugin index #"); META_CONS(" or a non-ambiguous prefix string matching name, desc, file, or logtag"); return; } - // i=2 to skip first arg, as that's the "cmd" - for (int i = 2; i < argc; i++) - { - const char *arg = CMD_ARGV(i); + for (int i = 2; i < argc; i++) { + const char* arg = CMD_ARGV(i); + MPlugin* findp; + char* endptr; // try to match plugin id first - char *endptr; - int pindex = strtol(arg, &endptr, 10); - - if (*arg && !*endptr) - findp = Plugins->find(pindex); + long pindex = strtol(arg, &endptr, 10); + if (*arg != '\0' && *endptr == '\0') + findp = g_plugins->find(pindex); // else try to match some string (prefix) else - findp = Plugins->find_match(arg); + findp = g_plugins->find_match(arg); // Require that: // - specified plugin was found in the list of current plugins // - plugin successfully loaded and began running // Otherwise, print error and exit. - if (pcmd == PC_REQUIRE) - { - if (findp && findp->status >= PL_RUNNING) - { + if (pcmd == PC_REQUIRE) { + if (findp && findp->status >= PL_RUNNING) { META_DEBUG(3, ("Required plugin '%s' found loaded and running.", arg)); return; } // Output to both places, because we don't want the admin // to miss this.. - if (!findp && meta_errno == ME_NOTUNIQ) - { + if (!findp && meta_errno == ME_NOTUNIQ) { META_ERROR("Unique match for required plugin '%s' was not found! Exiting.", arg); META_CONS("\nERROR: Unique match for required plugin '%s' was not found! Exiting.\n", arg); } - else if (!findp) - { + else if (!findp) { META_ERROR("Required plugin '%s' was not found! Exiting.", arg); META_CONS("\nERROR: Required plugin '%s' was not found! Exiting.\n", arg); } - else - { + else { META_ERROR("Required plugin '%s' did not load successfully! (status=%s) Exiting.", arg, findp->str_status(ST_SIMPLE)); META_CONS("\nERROR: Required plugin '%s' did not load successfully! (status=%s) Exiting.\n", arg, findp->str_status(ST_SIMPLE)); } - // Allow chance to read the message, before any window closes. - do_exit(1); + sleep(1); +#ifdef linux + // Argh, "quit" appears to segfault the server under linux; I + // was unable to determine why. + exit(1); +#else + // Argh, and exit() appears to generate an "Application Error" + // under MSVC. Interestingly, both seem to work fine with + // mingw32. + SERVER_COMMAND("quit\n"); +#endif /* not linux */ } - if (!findp) - { + if (!findp) { if (meta_errno == ME_NOTUNIQ) META_CONS("Couldn't find unique plugin matching '%s'", arg); else @@ -400,48 +405,39 @@ void cmd_doplug(PLUG_CMD pcmd) return; } - switch (pcmd) - { - case PC_PAUSE: + if (pcmd == PC_PAUSE) { if (findp->pause()) META_CONS("Paused plugin '%s'", findp->desc); else META_CONS("Pause failed for plugin '%s'", findp->desc); - break; - case PC_UNPAUSE: + } + else if (pcmd == PC_UNPAUSE) { if (findp->unpause()) META_CONS("Unpaused plugin '%s'", findp->desc); else META_CONS("Unpause failed for plugin '%s'", findp->desc); - break; - case PC_UNLOAD: - { + } + else if (pcmd == PC_UNLOAD) { findp->action = PA_UNLOAD; - if (findp->unload(PT_ANYTIME, PNL_COMMAND, PNL_COMMAND)) - { + if (findp->unload(PT_ANYTIME, PNL_COMMAND, PNL_COMMAND)) { META_CONS("Unloaded plugin '%s'", findp->desc); - Plugins->show(); + g_plugins->show(0); } else if (meta_errno == ME_DELAYED) META_CONS("Unload delayed for plugin '%s'", findp->desc); else META_CONS("Unload failed for plugin '%s'", findp->desc); - break; } - case PC_FORCE_UNLOAD: - { + else if (pcmd == PC_FORCE_UNLOAD) { findp->action = PA_UNLOAD; - if (findp->unload(PT_ANYTIME, PNL_CMD_FORCED, PNL_CMD_FORCED)) - { + if (findp->unload(PT_ANYTIME, PNL_CMD_FORCED, PNL_CMD_FORCED)) { META_CONS("Forced unload plugin '%s'", findp->desc); - Plugins->show(); + g_plugins->show(0); } else META_CONS("Forced unload failed for plugin '%s'", findp->desc); - break; } - case PC_RELOAD: - { + else if (pcmd == PC_RELOAD) { findp->action = PA_RELOAD; if (findp->reload(PT_ANYTIME, PNL_COMMAND)) META_CONS("Reloaded plugin '%s'", findp->desc); @@ -451,31 +447,26 @@ void cmd_doplug(PLUG_CMD pcmd) META_CONS("Reload not allowed for plugin '%s' now, only allowed %s", findp->desc, findp->str_loadable(SL_ALLOWED)); else META_CONS("Reload failed for plugin '%s'", findp->desc); - break; } - case PC_RETRY: + else if (pcmd == PC_RETRY) { if (findp->retry(PT_ANYTIME, PNL_COMMAND)) META_CONS("Retry succeeded for plugin '%s'", findp->desc); else META_CONS("Retry failed for plugin '%s'", findp->desc); - break; - case PC_CLEAR: - if (!findp->clear()) - { - META_CONS("Clear failed for plugin '%s'", findp->desc); - return; + } + else if (pcmd == PC_CLEAR) { + if (findp->clear()) { + META_CONS("Cleared failed plugin '%s' from list", findp->desc); + g_plugins->show(0); } - - META_CONS("Cleared failed plugin '%s' from list", findp->desc); - Plugins->show(); - break; - case PC_INFO: + else + META_CONS("Clear failed for plugin '%s'", findp->desc); + } + else if (pcmd == PC_INFO) findp->show(); - break; - default: - META_WARNING("Unexpected plug_cmd: %d", pcmd); + else { + META_ERROR("Unexpected plug_cmd: %d", pcmd); META_CONS("Command failed; see log"); - break; } } } diff --git a/metamod/src/commands_meta.h b/metamod/src/commands_meta.h index 8801d8b..53b9bac 100644 --- a/metamod/src/commands_meta.h +++ b/metamod/src/commands_meta.h @@ -1,11 +1,47 @@ -#pragma once +// vi: set ts=4 sw=4 : +// vim: set tw=75 : -#include "types_meta.h" +// commands_meta.h - prototypes for console commands + +/* + * Copyright (c) 2001-2003 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game g_engine ("HL + * g_engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL g_engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + +#ifndef COMMANDS_META_H +#define COMMANDS_META_H + +#include "types_meta.h" // mBOOL // Flags to use for meta_cmd_doplug(), to operate on existing plugins; note // "load" operates on a non-existing plugin thus isn't included here. -enum PLUG_CMD -{ +typedef enum { PC_NULL = 0, PC_PAUSE, // pause the plugin PC_UNPAUSE, // unpause the plugin @@ -16,24 +52,24 @@ enum PLUG_CMD PC_CLEAR, // remove a failed plugin from the list PC_FORCE_UNLOAD, // forcibly unload the plugin PC_REQUIRE, // require that this plugin is loaded/running -}; +} PLUG_CMD; void meta_register_cmdcvar(); -void svr_meta(); // only hidden because called from outside! +void server_meta(void); -void cmd_meta_usage(); -void cmd_meta_version(); -void cmd_meta_gpl(); +void cmd_meta_usage(void); +void cmd_meta_version(void); +void cmd_meta_gpl(void); -void cmd_meta_game(); -void cmd_meta_refresh(); -void cmd_meta_load(); +void cmd_meta_game(void); +void cmd_meta_refresh(void); +void cmd_meta_load(void); -void cmd_meta_pluginlist(); -void cmd_meta_cmdlist(); -void cmd_meta_cvarlist(); -void cmd_meta_config(); +void cmd_meta_pluginlist(void); +void cmd_meta_cmdlist(void); +void cmd_meta_cvarlist(void); +void cmd_meta_config(void); void cmd_doplug(PLUG_CMD pcmd); @@ -41,4 +77,5 @@ void client_meta(edict_t *pEntity); void client_meta_usage(edict_t *pEntity); void client_meta_version(edict_t *pEntity); void client_meta_pluginlist(edict_t *pEntity); -void client_meta_aybabtu(edict_t *pEntity); + +#endif /* COMMANDS_META_H */ diff --git a/metamod/src/conf_meta.cpp b/metamod/src/conf_meta.cpp index c577d42..4ac4629 100644 --- a/metamod/src/conf_meta.cpp +++ b/metamod/src/conf_meta.cpp @@ -1,75 +1,104 @@ +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// conf_meta.cpp - configfile reading routines + +/* + * Copyright (c) 2001-2003 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game g_engine ("HL + * g_engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL g_engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + #include "precompiled.h" -MConfig::MConfig() - : list(nullptr), filename(nullptr), debuglevel(0), plugins_file(nullptr), exec_cfg(nullptr) +MConfig::MConfig() : list(NULL), filename(NULL), debuglevel(0), gamedll(NULL), plugins_file(NULL), exec_cfg(NULL) { } // Initialize default values from the stored options struct. Has to happen // _after_ constructor, so that all the fields are allocated (d'oh). -void MConfig::init(option_t *global_options) +void MConfig::init(option_t* global_options) { - option_t *optp; - list=global_options; - for (optp=list; optp->name; optp++) + list = global_options; + for (auto optp = list; optp->name; optp++) set(optp, optp->init); } -option_t *MConfig::find(const char *lookup) +option_t* MConfig::find(const char* lookup) const { - option_t *optp; + for (auto optp = list; optp->name; optp++) + if (!strcmp(optp->name, lookup)) { + return optp; + } - for (optp = list; optp->name && Q_strcmp(optp->name, lookup); optp++); - - if (optp->name) - return optp; - else - RETURN_ERRNO(nullptr, ME_NOTFOUND); + RETURN_ERRNO(NULL, ME_NOTFOUND); } -mBOOL MConfig::set(const char *key, const char *value) +mBOOL MConfig::set(const char* key, const char* value) { - option_t *optp; - optp=find(key); + option_t* optp = find(key); + if (optp) return set(optp, value); - else - RETURN_ERRNO(mFALSE, ME_NOTFOUND); + + RETURN_ERRNO(mFALSE, ME_NOTFOUND); } -mBOOL MConfig::set(option_t *setp, const char *setstr) +mBOOL MConfig::set(option_t* setp, const char* setstr) { - char pathbuf[PATH_MAX]; - int *optval = (int *) setp->dest; - char **optstr = (char **) setp->dest; + char pathbuf[PATH_MAX ]; + int* optval = (int *) setp->dest; + char** optstr = (char **) setp->dest; + // cvar_t *optcvar = (cvar_t *) setp->dest; + // SETOPT_FN optcmd = (SETOPT_FN) setp->dest; if (!setstr) return mTRUE; - switch (setp->type) - { + switch (setp->type) { case CF_INT: - if (!isdigit(setstr[0])) - { - META_WARNING("option '%s' invalid format '%s'", setp->name, setstr); + if (!isdigit(setstr[0])) { + META_ERROR("option '%s' invalid format '%s'", setp->name, setstr); RETURN_ERRNO(mFALSE, ME_FORMAT); } - - *optval = Q_atoi(setstr); + *optval = atoi(setstr); META_DEBUG(3, ("set config int: %s = %d", setp->name, *optval)); break; case CF_BOOL: - if (!Q_stricmp(setstr, "true") || !Q_stricmp(setstr, "yes") || !Q_strcmp(setstr, "1")) - { - *optval = 1; + if (is_yes(setstr)) { + *optval = TRUE; } - else if (!Q_stricmp(setstr, "false") || !Q_stricmp(setstr, "no") || !Q_strcmp(setstr, "0")) - { - *optval = 0; + else if (is_no(setstr)) { + *optval = FALSE; } - else - { - META_WARNING("option '%s' invalid format '%s'", setp->name, setstr); + else { + META_ERROR("option '%s' invalid format '%s'", setp->name, + setstr); RETURN_ERRNO(mFALSE, ME_FORMAT); } META_DEBUG(3, ("set config bool: %s = %s", setp->name, *optval ? "true" : "false")); @@ -77,33 +106,41 @@ mBOOL MConfig::set(option_t *setp, const char *setstr) case CF_STR: if (*optstr) free(*optstr); - *optstr = Q_strdup(setstr); + *optstr = _strdup(setstr); META_DEBUG(3, ("set config string: %s = %s", setp->name, *optstr)); break; case CF_PATH: if (*optstr) free(*optstr); - full_gamedir_path(setstr, pathbuf); - *optstr = Q_strdup(pathbuf); + *optstr = _strdup(pathbuf); META_DEBUG(3, ("set config path: %s = %s", setp->name, *optstr)); break; - +#if 0 + case CF_CVAR: + CVAR_SET_STRING(optcvar->name, setstr); + META_DEBUG(3, ("set config cvar: %s = %s", optcvar->name, setstr)); + break; + case CF_CMD: + optcmd(setp->name, setstr); + META_DEBUG(3, ("set config command: %s, %s", + optcvar->name, setstr)); + break; +#endif default: - META_WARNING("unrecognized config type '%d'", setp->type); + META_ERROR("unrecognized config type '%d'", setp->type); RETURN_ERRNO(mFALSE, ME_ARGUMENT); } - - return mTRUE; + return (mTRUE); } -mBOOL MConfig::load(const char *fn) +mBOOL MConfig::load(const char* fn) { - FILE *fp; - char loadfile[PATH_MAX]; + FILE* fp; + char loadfile[PATH_MAX ]; char line[MAX_CONF_LEN]; char *optname, *optval; - option_t *optp; + option_t* optp; int ln; // Make full pathname (from gamedir if relative, collapse "..", @@ -111,80 +148,76 @@ mBOOL MConfig::load(const char *fn) full_gamedir_path(fn, loadfile); fp = fopen(loadfile, "r"); - if (!fp) - { - META_WARNING("unable to open config file '%s': %s", loadfile, strerror(errno)); + if (!fp) { + META_ERROR("unable to open config file '%s': %s", loadfile, + strerror(errno)); RETURN_ERRNO(mFALSE, ME_NOFILE); } META_DEBUG(2, ("Loading from config file: %s", loadfile)); - for (ln = 1; !feof(fp) && fgets(line, sizeof(line), fp); ln++) - { - if (line[0] == '#' || line[0] == ';') + for (ln = 1; !feof(fp) && fgets(line, sizeof(line), fp); ln++) { + if (line[0] == '#') continue; - - if (!Q_strncmp(line, "//", 2)) + if (line[0] == ';') continue; - - if (!(optname = strtok(line, " \t\r\n"))) - { - META_WARNING("'%s' line %d: bad config format: missing option", loadfile, ln); + if (strnmatch(line, "//", 2)) + continue; + if (!(optname = strtok(line, " \t\r\n"))) { + META_ERROR("'%s' line %d: bad config format: missing option", + loadfile, ln); + continue; + } + if (!(optval = strtok(NULL, "\r\n"))) { + META_ERROR("'%s' line %d: bad config format: missing value", + loadfile, ln); continue; } - if (!(optval = strtok(NULL, "\r\n"))) - { - META_WARNING("'%s' line %d: bad config format: missing value", loadfile, ln); + if (!(optp = find(optname))) { + META_ERROR("'%s' line %d: unknown option name '%s'", + loadfile, ln, optname); continue; } - if (!(optp = find(optname))) - { - META_WARNING("'%s' line %d: unknown option name '%s'", loadfile, ln, optname); - continue; - } - - if (!set(optp, optval)) - { - META_WARNING("'%s' line %d: unable to set option '%s' value '%s'", loadfile, ln, optname, optval); + if (!set(optp, optval)) { + META_ERROR("'%s' line %d: unable to set option '%s' value '%s'", + loadfile, ln, optname, optval); continue; } } - - filename = strdup(loadfile); + filename = _strdup(loadfile); fclose(fp); - - return mTRUE; + return (mTRUE); } -void MConfig::show() +void MConfig::show(void) const { - option_t *optp; + META_CONS("Config options from localinfo and %s:", filename); - if (filename) - META_CONS("%s and %s:", "Config options from localinfo", filename); - else - META_CONS("%s:", "Config options from localinfo"); - - for (optp = list; optp->name; optp++) - { - int *optval = (int *)optp->dest; - char **optstr = (char **)optp->dest; + for (auto optp = list; optp->name; optp++) { + int* optval = (int *) optp->dest; + char** optstr = (char **) optp->dest; // cvar_t *optcvar = (cvar_t *) optp->dest; // SETOPT_FN optcmd = (SETOPT_FN) optp->dest; - - switch (optp->type) - { + switch (optp->type) { case CF_INT: - META_CONS(" %-20s\t%d\n", optp->name, *optval); + printf(" %-20s\t%d\n", optp->name, *optval); break; case CF_BOOL: - META_CONS(" %-20s\t%s\n", optp->name, *optval ? "true" : "false"); + printf(" %-20s\t%s\n", optp->name, *optval ? "true" : "false"); break; case CF_STR: case CF_PATH: - META_CONS(" %-20s\t%s\n", optp->name, *optstr ? *optstr : ""); + printf(" %-20s\t%s\n", optp->name, *optstr ? *optstr : ""); break; +#if 0 + case CF_CVAR: + printf(" %-20s\tstores in: %s\n", optp->name, optcvar->name); + break; + case CF_CMD: + printf(" %-20s\tparsed by: %d\n", optp->name, (int) optcmd); + break; +#endif case CF_NONE: break; } diff --git a/metamod/src/conf_meta.h b/metamod/src/conf_meta.h index ab6e40f..7da3354 100644 --- a/metamod/src/conf_meta.h +++ b/metamod/src/conf_meta.h @@ -1,53 +1,96 @@ -#pragma once +// vi: set ts=4 sw=4 : +// vim: set tw=75 : -#include "types_meta.h" -#include "new_baseclass.h" +// conf_meta.h - configfile reading + +// Modeled after mutt/init.[ch]. + +/* + * Copyright (c) 2001-2003 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game g_engine ("HL + * g_engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL g_engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + +#ifndef CONF_META_H +#define CONF_META_H + +#include "types_meta.h" // mBOOL // Max length of line in config file. #define MAX_CONF_LEN 1024 // Supported config value-types. -enum cf_type_t -{ - CF_NONE = 0, +typedef enum { + CF_NONE=0, CF_INT, CF_BOOL, CF_STR, CF_PATH, +#if 0 + CF_CVAR, + CF_CMD, +#endif +} cf_type_t; + +typedef mBOOL (*SETOPT_FN) (char *key, char *value); + +typedef struct option_s { + const char *name; // option name + cf_type_t type; // option type + void *dest; // addr of destination variable, or handler function + const char *init; // initial value, as a string, just as config file would +} option_t; + +class MConfig { + private: + // data + option_t *list; + char *filename; + // functions + option_t *find(const char *lookup) const; + static mBOOL set(option_t *setp, const char *value); + // Private; to satisfy -Weffc++ "has pointer data members but does + // not override" copy/assignment constructor. + void operator=(const MConfig &src); + MConfig(const MConfig &src); + public: + // contructor + MConfig(void); + // data + int debuglevel; // to use for meta_debug + char *gamedll; // string if specified in config.ini + char *plugins_file; // ie metamod.ini, plugins.ini + char *exec_cfg; // ie metaexec.cfg, exec.cfg + // functions + void init(option_t *global_options); + mBOOL load(const char *filename); + mBOOL set(const char *key, const char *value); + void show(void) const; }; -struct option_t -{ - char *name; // option name - cf_type_t type; // option type - void *dest; // addr of destination variable, or handler function - char *init; // initial value, as a string, just as config file would -}; - -class MConfig: public class_metamod_new { -public: - // contructor - MConfig(); - // data - int debuglevel; // to use for meta_debug - char *plugins_file; // ie metamod.ini, plugins.ini - char *exec_cfg; // ie metaexec.cfg, exec.cfg - int clientmeta; // control 'meta' client-command - // functions - void init(option_t *global_options); - mBOOL load(const char *filename); - mBOOL set(const char *key, const char *value); - void show(); - -private: - // data - option_t *list; - char *filename; - // functions - option_t *find(const char *lookup); - mBOOL set(option_t *setp, const char *value); - // Private; to satisfy -Weffc++ "has pointer data members but does - // not override" copy/assignment constructor. - void operator=(const MConfig &src); - MConfig(const MConfig &src); -}; +#endif /* CONF_META_H */ diff --git a/metamod/src/dllapi.cpp b/metamod/src/dllapi.cpp index 3bb790e..2deac6e 100644 --- a/metamod/src/dllapi.cpp +++ b/metamod/src/dllapi.cpp @@ -1,179 +1,177 @@ +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// dllapi.cpp - implementation of Half-Life DLL routines + +/* + * Copyright (c) 2001-2003 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game g_engine ("HL + * g_engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL g_engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + #include "precompiled.h" // Original DLL routines, functions returning "void". -#define META_DLLAPI_HANDLE_void(FN_TYPE, pfnName, pack_args_type, pfn_args) \ - API_START_TSC_TRACKING(); \ - API_PACK_ARGS(pack_args_type, pfn_args); \ - main_hook_function_void(offsetof(dllapi_info_t, pfnName), e_api_dllapi, offsetof(DLL_FUNCTIONS, pfnName), &packed_args); \ - API_END_TSC_TRACKING() +#define META_DLLAPI_HANDLE_void(FN_TYPE, pfnName, pfn_args) \ + SETUP_API_CALLS_void(FN_TYPE, pfnName, dllapi_info); \ + CALL_PLUGIN_API_void(P_PRE, pfnName, pfn_args, dllapi_table); \ + CALL_GAME_API_void(pfnName, pfn_args, dllapi_table); \ + CALL_PLUGIN_API_void(P_POST, pfnName, pfn_args, dllapi_post_table); // Original DLL routines, functions returning an actual value. -#define META_DLLAPI_HANDLE(ret_t, ret_init, FN_TYPE, pfnName, pack_args_type, pfn_args) \ - API_START_TSC_TRACKING(); \ - API_PACK_ARGS(pack_args_type, pfn_args); \ - class_ret_t ret_val(main_hook_function(class_ret_t((ret_t)ret_init), offsetof(dllapi_info_t, pfnName), e_api_dllapi, offsetof(DLL_FUNCTIONS, pfnName), &packed_args)); \ - API_END_TSC_TRACKING() +#define META_DLLAPI_HANDLE(ret_t, ret_init, FN_TYPE, pfnName, pfn_args) \ + SETUP_API_CALLS(ret_t, ret_init, FN_TYPE, pfnName, dllapi_info); \ + CALL_PLUGIN_API(P_PRE, ret_init, pfnName, pfn_args, MRES_SUPERCEDE, dllapi_table); \ + CALL_GAME_API(pfnName, pfn_args, dllapi_table); \ + CALL_PLUGIN_API(P_POST, ret_init, pfnName, pfn_args, MRES_OVERRIDE, dllapi_post_table); + // The "new" api routines (just 3 right now), functions returning "void". -#define META_NEWAPI_HANDLE_void(FN_TYPE, pfnName, pack_args_type, pfn_args) \ - API_START_TSC_TRACKING(); \ - API_PACK_ARGS(pack_args_type, pfn_args); \ - main_hook_function_void(offsetof(newapi_info_t, pfnName), e_api_newapi, offsetof(NEW_DLL_FUNCTIONS, pfnName), &packed_args); \ - API_END_TSC_TRACKING() +#define META_NEWAPI_HANDLE_void(FN_TYPE, pfnName, pfn_args) \ + SETUP_API_CALLS_void(FN_TYPE, pfnName, newapi_info); \ + CALL_PLUGIN_API_void(P_PRE, pfnName, pfn_args, newapi_table); \ + CALL_GAME_API_void(pfnName, pfn_args, newapi_table); \ + CALL_PLUGIN_API_void(P_POST, pfnName, pfn_args, newapi_post_table); // The "new" api routines (just 3 right now), functions returning an actual value. -#define META_NEWAPI_HANDLE(ret_t, ret_init, FN_TYPE, pfnName, pack_args_type, pfn_args) \ - API_START_TSC_TRACKING(); \ - API_PACK_ARGS(pack_args_type, pfn_args); \ - class_ret_t ret_val(main_hook_function(class_ret_t((ret_t)ret_init), offsetof(newapi_info_t, pfnName), e_api_newapi, offsetof(NEW_DLL_FUNCTIONS, pfnName), &packed_args)); \ - API_END_TSC_TRACKING() +#define META_NEWAPI_HANDLE(ret_t, ret_init, FN_TYPE, pfnName, pfn_args) \ + SETUP_API_CALLS(ret_t, ret_init, FN_TYPE, pfnName, newapi_info); \ + CALL_PLUGIN_API(P_PRE, ret_init, pfnName, pfn_args, MRES_SUPERCEDE, newapi_table); \ + CALL_GAME_API(pfnName, pfn_args, newapi_table); \ + CALL_PLUGIN_API(P_POST, ret_init, pfnName, pfn_args, MRES_OVERRIDE, newapi_post_table); -void mm_GameDLLInit() -{ - META_DLLAPI_HANDLE_void(FN_GAMEINIT, pfnGameInit, void, (VOID_ARG)); +// From SDK dlls/game.cpp: +void mm_GameDLLInit(void) { + META_DLLAPI_HANDLE_void(FN_GAMEINIT, pfnGameInit, ()); RETURN_API_void(); } -int mm_DispatchSpawn(edict_t *pent) -{ +// From SDK dlls/cbase.cpp: +int mm_DispatchSpawn(edict_t *pent) { // 0==Success, -1==Failure ? - META_DLLAPI_HANDLE(int, 0, FN_DISPATCHSPAWN, pfnSpawn, p, (pent)); - RETURN_API(int); + META_DLLAPI_HANDLE(int, 0, FN_DISPATCHSPAWN, pfnSpawn, (pent)); + RETURN_API(); } - -void mm_DispatchThink(edict_t *pent) -{ - META_DLLAPI_HANDLE_void(FN_DISPATCHTHINK, pfnThink, p, (pent)); +void mm_DispatchThink(edict_t *pent) { + META_DLLAPI_HANDLE_void(FN_DISPATCHTHINK, pfnThink, (pent)); RETURN_API_void(); } - -void mm_DispatchUse(edict_t *pentUsed, edict_t *pentOther) -{ - META_DLLAPI_HANDLE_void(FN_DISPATCHUSE, pfnUse, 2p, (pentUsed, pentOther)); +void mm_DispatchUse(edict_t *pentUsed, edict_t *pentOther) { + META_DLLAPI_HANDLE_void(FN_DISPATCHUSE, pfnUse, (pentUsed, pentOther)); RETURN_API_void(); } - -void mm_DispatchTouch(edict_t *pentTouched, edict_t *pentOther) -{ - META_DLLAPI_HANDLE_void(FN_DISPATCHTOUCH, pfnTouch, 2p, (pentTouched, pentOther)); +void mm_DispatchTouch(edict_t *pentTouched, edict_t *pentOther) { + META_DLLAPI_HANDLE_void(FN_DISPATCHTOUCH, pfnTouch, (pentTouched, pentOther)); RETURN_API_void(); } - -void mm_DispatchBlocked(edict_t *pentBlocked, edict_t *pentOther) -{ - META_DLLAPI_HANDLE_void(FN_DISPATCHBLOCKED, pfnBlocked, 2p, (pentBlocked, pentOther)); +void mm_DispatchBlocked(edict_t *pentBlocked, edict_t *pentOther) { + META_DLLAPI_HANDLE_void(FN_DISPATCHBLOCKED, pfnBlocked, (pentBlocked, pentOther)); RETURN_API_void(); } - -void mm_DispatchKeyValue(edict_t *pentKeyvalue, KeyValueData *pkvd) -{ - META_DLLAPI_HANDLE_void(FN_DISPATCHKEYVALUE, pfnKeyValue, 2p, (pentKeyvalue, pkvd)); +void mm_DispatchKeyValue(edict_t *pentKeyvalue, KeyValueData *pkvd) { + META_DLLAPI_HANDLE_void(FN_DISPATCHKEYVALUE, pfnKeyValue, (pentKeyvalue, pkvd)); RETURN_API_void(); } - -void mm_DispatchSave(edict_t *pent, SAVERESTOREDATA *pSaveData) -{ - META_DLLAPI_HANDLE_void(FN_DISPATCHSAVE, pfnSave, 2p, (pent, pSaveData)); +void mm_DispatchSave(edict_t *pent, SAVERESTOREDATA *pSaveData) { + META_DLLAPI_HANDLE_void(FN_DISPATCHSAVE, pfnSave, (pent, pSaveData)); RETURN_API_void(); } - -int mm_DispatchRestore(edict_t *pent, SAVERESTOREDATA *pSaveData, int globalEntity) -{ +int mm_DispatchRestore(edict_t *pent, SAVERESTOREDATA *pSaveData, int globalEntity) { // 0==Success, -1==Failure ? - META_DLLAPI_HANDLE(int, 0, FN_DISPATCHRESTORE, pfnRestore, 2pi, (pent, pSaveData, globalEntity)); - RETURN_API(int); + META_DLLAPI_HANDLE(int, 0, FN_DISPATCHRESTORE, pfnRestore, (pent, pSaveData, globalEntity)); + RETURN_API(); } - -void mm_DispatchObjectCollsionBox(edict_t *pent) -{ - META_DLLAPI_HANDLE_void(FN_DISPATCHOBJECTCOLLISIONBOX, pfnSetAbsBox, p, (pent)); +void mm_DispatchObjectCollsionBox(edict_t *pent) { + META_DLLAPI_HANDLE_void(FN_DISPATCHOBJECTCOLLISIONBOX, pfnSetAbsBox, (pent)); + RETURN_API_void(); +} +void mm_SaveWriteFields(SAVERESTOREDATA *pSaveData, const char *pname, void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCount) { + META_DLLAPI_HANDLE_void(FN_SAVEWRITEFIELDS, pfnSaveWriteFields, (pSaveData, pname, pBaseData, pFields, fieldCount)); + RETURN_API_void(); +} +void mm_SaveReadFields(SAVERESTOREDATA *pSaveData, const char *pname, void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCount) { + META_DLLAPI_HANDLE_void(FN_SAVEREADFIELDS, pfnSaveReadFields, (pSaveData, pname, pBaseData, pFields, fieldCount)); RETURN_API_void(); } -void mm_SaveWriteFields(SAVERESTOREDATA *pSaveData, const char *pname, void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCount) -{ - META_DLLAPI_HANDLE_void(FN_SAVEWRITEFIELDS, pfnSaveWriteFields, 4pi, (pSaveData, pname, pBaseData, pFields, fieldCount)); +// From SDK dlls/world.cpp: +void mm_SaveGlobalState(SAVERESTOREDATA *pSaveData) { + META_DLLAPI_HANDLE_void(FN_SAVEGLOBALSTATE, pfnSaveGlobalState, (pSaveData)); + RETURN_API_void(); +} +void mm_RestoreGlobalState(SAVERESTOREDATA *pSaveData) { + META_DLLAPI_HANDLE_void(FN_RESTOREGLOBALSTATE, pfnRestoreGlobalState, (pSaveData)); + RETURN_API_void(); +} +void mm_ResetGlobalState(void) { + META_DLLAPI_HANDLE_void(FN_RESETGLOBALSTATE, pfnResetGlobalState, ()); RETURN_API_void(); } -void mm_SaveReadFields(SAVERESTOREDATA *pSaveData, const char *pname, void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCount) -{ - META_DLLAPI_HANDLE_void(FN_SAVEREADFIELDS, pfnSaveReadFields, 4pi, (pSaveData, pname, pBaseData, pFields, fieldCount)); - RETURN_API_void(); -} - -void mm_SaveGlobalState(SAVERESTOREDATA *pSaveData) -{ - META_DLLAPI_HANDLE_void(FN_SAVEGLOBALSTATE, pfnSaveGlobalState, p, (pSaveData)); - RETURN_API_void(); -} - -void mm_RestoreGlobalState(SAVERESTOREDATA *pSaveData) -{ - META_DLLAPI_HANDLE_void(FN_RESTOREGLOBALSTATE, pfnRestoreGlobalState, p, (pSaveData)); - RETURN_API_void(); -} - -void mm_ResetGlobalState() -{ - META_DLLAPI_HANDLE_void(FN_RESETGLOBALSTATE, pfnResetGlobalState, void, (VOID_ARG)); - RETURN_API_void(); -} - -qboolean mm_ClientConnect(edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[128]) -{ +// From SDK dlls/client.cpp: +BOOL mm_ClientConnect(edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[ 128 ] ) { g_Players.clear_player_cvar_query(pEntity); - META_DLLAPI_HANDLE(qboolean, TRUE, FN_CLIENTCONNECT, pfnClientConnect, 4p, (pEntity, pszName, pszAddress, szRejectReason)); - RETURN_API(qboolean); + META_DLLAPI_HANDLE(BOOL, TRUE, FN_CLIENTCONNECT, pfnClientConnect, (pEntity, pszName, pszAddress, szRejectReason)); + RETURN_API(); } - -void mm_ClientDisconnect(edict_t *pEntity) -{ +void mm_ClientDisconnect(edict_t *pEntity) { g_Players.clear_player_cvar_query(pEntity); - META_DLLAPI_HANDLE_void(FN_CLIENTDISCONNECT, pfnClientDisconnect, p, (pEntity)); + META_DLLAPI_HANDLE_void(FN_CLIENTDISCONNECT, pfnClientDisconnect, (pEntity)); RETURN_API_void(); } - -void mm_ClientKill(edict_t *pEntity) -{ - META_DLLAPI_HANDLE_void(FN_CLIENTKILL, pfnClientKill, p, (pEntity)); +void mm_ClientKill(edict_t *pEntity) { + META_DLLAPI_HANDLE_void(FN_CLIENTKILL, pfnClientKill, (pEntity)); RETURN_API_void(); } - -void mm_ClientPutInServer(edict_t *pEntity) -{ - META_DLLAPI_HANDLE_void(FN_CLIENTPUTINSERVER, pfnClientPutInServer, p, (pEntity)); +void mm_ClientPutInServer(edict_t *pEntity) { + META_DLLAPI_HANDLE_void(FN_CLIENTPUTINSERVER, pfnClientPutInServer, (pEntity)); RETURN_API_void(); } - -void mm_ClientCommand(edict_t *pEntity) -{ - if (Config->clientmeta && !Q_strcmp(CMD_ARGV(0), "meta")) -{ +void mm_ClientCommand(edict_t *pEntity) { + if(!strcmp(CMD_ARGV(0), "meta")) { client_meta(pEntity); } - META_DLLAPI_HANDLE_void(FN_CLIENTCOMMAND, pfnClientCommand, p, (pEntity)); + META_DLLAPI_HANDLE_void(FN_CLIENTCOMMAND, pfnClientCommand, (pEntity)); RETURN_API_void(); } - -void mm_ClientUserInfoChanged(edict_t *pEntity, char *infobuffer) -{ - META_DLLAPI_HANDLE_void(FN_CLIENTUSERINFOCHANGED, pfnClientUserInfoChanged, 2p, (pEntity, infobuffer)); +void mm_ClientUserInfoChanged(edict_t *pEntity, char *infobuffer) { + META_DLLAPI_HANDLE_void(FN_CLIENTUSERINFOCHANGED, pfnClientUserInfoChanged, (pEntity, infobuffer)); RETURN_API_void(); } - -void mm_ServerActivate(edict_t *pEdictList, int edictCount, int clientMax) -{ - META_DLLAPI_HANDLE_void(FN_SERVERACTIVATE, pfnServerActivate, p2i, (pEdictList, edictCount, clientMax)); +void mm_ServerActivate(edict_t *pEdictList, int edictCount, int clientMax) { + META_DLLAPI_HANDLE_void(FN_SERVERACTIVATE, pfnServerActivate, (pEdictList, edictCount, clientMax)); RETURN_API_void(); } - -void mm_ServerDeactivate() -{ - META_DLLAPI_HANDLE_void(FN_SERVERDEACTIVATE, pfnServerDeactivate, void, (VOID_ARG)); +void mm_ServerDeactivate(void) { + META_DLLAPI_HANDLE_void(FN_SERVERDEACTIVATE, pfnServerDeactivate, ()); // Update loaded plugins. Look for new plugins in inifile, as well as - // any plugins waiting for a changelevel to load. + // any plugins waiting for a changelevel to load. // // This is done in ServerDeactivate rather than Activate, as the latter // isn't actually the first routine to be called on a new map. In @@ -185,269 +183,224 @@ void mm_ServerDeactivate() // from the previous map. It's also called right before shutdown, // which means whenever hlds quits, it'll reload the plugins just // before it exits, which is rather silly, but oh well. - Plugins->refresh(PT_CHANGELEVEL); - Plugins->unpause_all(); - // Plugins->retry_all(PT_CHANGELEVEL); + g_plugins->refresh(PT_CHANGELEVEL); + g_plugins->unpause_all(); + // g_plugins->retry_all(PT_CHANGELEVEL); g_Players.clear_all_cvar_queries(); requestid_counter = 0; RETURN_API_void(); } - -void mm_PlayerPreThink(edict_t *pEntity) -{ - META_DLLAPI_HANDLE_void(FN_PLAYERPRETHINK, pfnPlayerPreThink, p, (pEntity)); +void mm_PlayerPreThink(edict_t *pEntity) { + META_DLLAPI_HANDLE_void(FN_PLAYERPRETHINK, pfnPlayerPreThink, (pEntity)); + RETURN_API_void(); +} +void mm_PlayerPostThink(edict_t *pEntity) { + META_DLLAPI_HANDLE_void(FN_PLAYERPOSTTHINK, pfnPlayerPostThink, (pEntity)); + RETURN_API_void(); +} +void mm_StartFrame(void) { + META_DLLAPI_HANDLE_void(FN_STARTFRAME, pfnStartFrame, ()); + RETURN_API_void(); +} +void mm_ParmsNewLevel(void) { + META_DLLAPI_HANDLE_void(FN_PARMSNEWLEVEL, pfnParmsNewLevel, ()); + RETURN_API_void(); +} +void mm_ParmsChangeLevel(void) { + META_DLLAPI_HANDLE_void(FN_PARMSCHANGELEVEL, pfnParmsChangeLevel, ()); + RETURN_API_void(); +} +const char *mm_GetGameDescription(void) { + META_DLLAPI_HANDLE(const char *, NULL, FN_GETGAMEDESCRIPTION, pfnGetGameDescription, ()); + RETURN_API(); +} +void mm_PlayerCustomization(edict_t *pEntity, customization_t *pCust) { + META_DLLAPI_HANDLE_void(FN_PLAYERCUSTOMIZATION, pfnPlayerCustomization, (pEntity, pCust)); + RETURN_API_void(); +} +void mm_SpectatorConnect(edict_t *pEntity) { + META_DLLAPI_HANDLE_void(FN_SPECTATORCONNECT, pfnSpectatorConnect, (pEntity)); + RETURN_API_void(); +} +void mm_SpectatorDisconnect(edict_t *pEntity) { + META_DLLAPI_HANDLE_void(FN_SPECTATORDISCONNECT, pfnSpectatorDisconnect, (pEntity)); + RETURN_API_void(); +} +void mm_SpectatorThink(edict_t *pEntity) { + META_DLLAPI_HANDLE_void(FN_SPECTATORTHINK, pfnSpectatorThink, (pEntity)); + RETURN_API_void(); +} +void mm_Sys_Error(const char *error_string) { + META_DLLAPI_HANDLE_void(FN_SYS_ERROR, pfnSys_Error, (error_string)); RETURN_API_void(); } -void mm_PlayerPostThink(edict_t *pEntity) -{ - META_DLLAPI_HANDLE_void(FN_PLAYERPOSTTHINK, pfnPlayerPostThink, p, (pEntity)); +// From SDK pm_shared/pm_shared.c: +void mm_PM_Move (struct playermove_s *ppmove, int server) { + META_DLLAPI_HANDLE_void(FN_PM_MOVE, pfnPM_Move, (ppmove, server)); + RETURN_API_void(); +} +void mm_PM_Init(struct playermove_s *ppmove) { + META_DLLAPI_HANDLE_void(FN_PM_INIT, pfnPM_Init, (ppmove)); + RETURN_API_void(); +} +char mm_PM_FindTextureType(char *name) { + META_DLLAPI_HANDLE(char, '\0', FN_PM_FINDTEXTURETYPE, pfnPM_FindTextureType, (name)); + RETURN_API(); +} + +// From SDK dlls/client.cpp: +void mm_SetupVisibility(edict_t *pViewEntity, edict_t *pClient, unsigned char **pvs, unsigned char **pas) { + META_DLLAPI_HANDLE_void(FN_SETUPVISIBILITY, pfnSetupVisibility, (pViewEntity, pClient, pvs, pas)); + RETURN_API_void(); +} +void mm_UpdateClientData (const struct edict_s *ent, int sendweapons, struct clientdata_s *cd) { + META_DLLAPI_HANDLE_void(FN_UPDATECLIENTDATA, pfnUpdateClientData, (ent, sendweapons, cd)); + RETURN_API_void(); +} +int mm_AddToFullPack(struct entity_state_s *state, int e, edict_t *ent, edict_t *host, int hostflags, int player, unsigned char *pSet) { + META_DLLAPI_HANDLE(int, 0, FN_ADDTOFULLPACK, pfnAddToFullPack, (state, e, ent, host, hostflags, player, pSet)); + RETURN_API(); +} +void mm_CreateBaseline(int player, int eindex, struct entity_state_s *baseline, struct edict_s *entity, int playermodelindex, vec3_t player_mins, vec3_t player_maxs) { + META_DLLAPI_HANDLE_void(FN_CREATEBASELINE, pfnCreateBaseline, (player, eindex, baseline, entity, playermodelindex, player_mins, player_maxs)); + RETURN_API_void(); +} +void mm_RegisterEncoders(void) { + META_DLLAPI_HANDLE_void(FN_REGISTERENCODERS, pfnRegisterEncoders, ()); + RETURN_API_void(); +} +int mm_GetWeaponData(struct edict_s *player, struct weapon_data_s *info) { + META_DLLAPI_HANDLE(int, 0, FN_GETWEAPONDATA, pfnGetWeaponData, (player, info)); + RETURN_API(); +} +void mm_CmdStart(const edict_t *player, const struct usercmd_s *cmd, unsigned int random_seed) { + META_DLLAPI_HANDLE_void(FN_CMDSTART, pfnCmdStart, (player, cmd, random_seed)); + RETURN_API_void(); +} +void mm_CmdEnd (const edict_t *player) { + META_DLLAPI_HANDLE_void(FN_CMDEND, pfnCmdEnd, (player)); + RETURN_API_void(); +} +int mm_ConnectionlessPacket(const struct netadr_s *net_from, const char *args, char *response_buffer, int *response_buffer_size) { + META_DLLAPI_HANDLE(int, 0, FN_CONNECTIONLESSPACKET, pfnConnectionlessPacket, (net_from, args, response_buffer, response_buffer_size)); + RETURN_API(); +} +int mm_GetHullBounds(int hullnumber, float *mins, float *maxs) { + META_DLLAPI_HANDLE(int, 0, FN_GETHULLBOUNDS, pfnGetHullBounds, (hullnumber, mins, maxs)); + RETURN_API(); +} +void mm_CreateInstancedBaselines (void) { + META_DLLAPI_HANDLE_void(FN_CREATEINSTANCEDBASELINES, pfnCreateInstancedBaselines, ()); + RETURN_API_void(); +} +int mm_InconsistentFile(const edict_t *player, const char *filename, char *disconnect_message) { + META_DLLAPI_HANDLE(int, 0, FN_INCONSISTENTFILE, pfnInconsistentFile, (player, filename, disconnect_message)); + RETURN_API(); +} +int mm_AllowLagCompensation(void) { + META_DLLAPI_HANDLE(int, 0, FN_ALLOWLAGCOMPENSATION, pfnAllowLagCompensation, ()); + RETURN_API(); +} + + +// New API functions +// From SDK ? +void mm_OnFreeEntPrivateData(edict_t *pEnt) { + META_NEWAPI_HANDLE_void(FN_ONFREEENTPRIVATEDATA, pfnOnFreeEntPrivateData, (pEnt)); + RETURN_API_void(); +} +void mm_GameShutdown(void) { + META_NEWAPI_HANDLE_void(FN_GAMESHUTDOWN, pfnGameShutdown, ()); + RETURN_API_void(); +} +int mm_ShouldCollide(edict_t *pentTouched, edict_t *pentOther) { + META_NEWAPI_HANDLE(int, 1, FN_SHOULDCOLLIDE, pfnShouldCollide, (pentTouched, pentOther)); + RETURN_API(); +} +// Added 2005-08-11 (no SDK update) +void mm_CvarValue(const edict_t *pEdict, const char *value) { + g_Players.clear_player_cvar_query(pEdict); + META_NEWAPI_HANDLE_void(FN_CVARVALUE, pfnCvarValue, (pEdict, value)); RETURN_API_void(); } -void mm_StartFrame() -{ - meta_debug_value = (int)meta_debug.value; - - META_DLLAPI_HANDLE_void(FN_STARTFRAME, pfnStartFrame, void, (VOID_ARG)); +//Added 2005-11-22 (no SDK update) +void mm_CvarValue2(const edict_t *pEdict, int requestID, const char *cvarName, const char *value) { + META_NEWAPI_HANDLE_void(FN_CVARVALUE2, pfnCvarValue2, (pEdict, requestID, cvarName, value)); RETURN_API_void(); } -void mm_ParmsNewLevel() +// From SDK dlls/cbase.cpp: +// "(wd)" indicates my comments on the functions +static DLL_FUNCTIONS sFunctionTable = { - META_DLLAPI_HANDLE_void(FN_PARMSNEWLEVEL, pfnParmsNewLevel, void, (VOID_ARG)); - RETURN_API_void(); -} + mm_GameDLLInit, //! pfnGameInit() Initialize the game (one-time call after loading of game .dll) + mm_DispatchSpawn, //! pfnSpawn() + mm_DispatchThink, //! pfnThink() + mm_DispatchUse, //! pfnUse() + mm_DispatchTouch, //! pfnTouch() + mm_DispatchBlocked, //! pfnBlocked() + mm_DispatchKeyValue, //! pfnKeyValue() + mm_DispatchSave, //! pfnSave() + mm_DispatchRestore, //! pfnRestore() + mm_DispatchObjectCollsionBox, //! pfnSetAbsBox() -void mm_ParmsChangeLevel() -{ - META_DLLAPI_HANDLE_void(FN_PARMSCHANGELEVEL, pfnParmsChangeLevel, void, (VOID_ARG)); - RETURN_API_void(); -} + mm_SaveWriteFields, //! pfnSaveWriteFields() + mm_SaveReadFields, //! pfnSaveReadFields() -const char *mm_GetGameDescription() -{ - META_DLLAPI_HANDLE(const char *, NULL, FN_GETGAMEDESCRIPTION, pfnGetGameDescription, void, (VOID_ARG)); - RETURN_API(const char *); -} + mm_SaveGlobalState, //! pfnSaveGlobalState() + mm_RestoreGlobalState, //! pfnRestoreGlobalState() + mm_ResetGlobalState, //! pfnResetGlobalState() -void mm_PlayerCustomization(edict_t *pEntity, customization_t *pCust) -{ - META_DLLAPI_HANDLE_void(FN_PLAYERCUSTOMIZATION, pfnPlayerCustomization, 2p, (pEntity, pCust)); - RETURN_API_void(); -} + mm_ClientConnect, //! pfnClientConnect() (wd) Client has connected + mm_ClientDisconnect, //! pfnClientDisconnect() (wd) Player has left the game + mm_ClientKill, //! pfnClientKill() (wd) Player has typed "kill" + mm_ClientPutInServer, //! pfnClientPutInServer() (wd) Client is entering the game + mm_ClientCommand, //! pfnClientCommand() (wd) Player has sent a command (typed, or from a bind) + mm_ClientUserInfoChanged, //! pfnClientUserInfoChanged() (wd) Client has updated their setinfo structure + mm_ServerActivate, //! pfnServerActivate() (wd) Server is starting a new map + mm_ServerDeactivate, //! pfnServerDeactivate() (wd) Server is leaving the map (shutdown, or changelevel); SDK2 -void mm_SpectatorConnect(edict_t *pEntity) -{ - META_DLLAPI_HANDLE_void(FN_SPECTATORCONNECT, pfnSpectatorConnect, p, (pEntity)); - RETURN_API_void(); -} + mm_PlayerPreThink, //! pfnPlayerPreThink() + mm_PlayerPostThink, //! pfnPlayerPostThink() -void mm_SpectatorDisconnect(edict_t *pEntity) -{ - META_DLLAPI_HANDLE_void(FN_SPECTATORDISCONNECT, pfnSpectatorDisconnect, p, (pEntity)); - RETURN_API_void(); -} + mm_StartFrame, //! pfnStartFrame() + mm_ParmsNewLevel, //! pfnParmsNewLevel() + mm_ParmsChangeLevel, //! pfnParmsChangeLevel() -void mm_SpectatorThink(edict_t *pEntity) -{ - META_DLLAPI_HANDLE_void(FN_SPECTATORTHINK, pfnSpectatorThink, p, (pEntity)); - RETURN_API_void(); -} + mm_GetGameDescription, //! pfnGetGameDescription() Returns string describing current .dll. E.g. "TeamFotrress 2", "Half-Life" + mm_PlayerCustomization, //! pfnPlayerCustomization() Notifies .dll of new customization for player. -void mm_Sys_Error(const char *error_string) -{ - META_DLLAPI_HANDLE_void(FN_SYS_ERROR, pfnSys_Error, p, (error_string)); - RETURN_API_void(); -} + mm_SpectatorConnect, //! pfnSpectatorConnect() Called when spectator joins server + mm_SpectatorDisconnect, //! pfnSpectatorDisconnect() Called when spectator leaves the server + mm_SpectatorThink, //! pfnSpectatorThink() Called when spectator sends a command packet (usercmd_t) -void mm_PM_Move(struct playermove_s *ppmove, int server) -{ - META_DLLAPI_HANDLE_void(FN_PM_MOVE, pfnPM_Move, pi, (ppmove, server)); - RETURN_API_void(); -} + mm_Sys_Error, //! pfnSys_Error() Notify game .dll that engine is going to shut down. Allows mod authors to set a breakpoint. SDK2 -void mm_PM_Init(struct playermove_s *ppmove) -{ - META_DLLAPI_HANDLE_void(FN_PM_INIT, pfnPM_Init, p, (ppmove)); - RETURN_API_void(); -} + mm_PM_Move, //! pfnPM_Move() (wd) SDK2 + mm_PM_Init, //! pfnPM_Init() Server version of player movement initialization; (wd) SDK2 + mm_PM_FindTextureType, //! pfnPM_FindTextureType() (wd) SDK2 -char mm_PM_FindTextureType(char *name) -{ - META_DLLAPI_HANDLE(const char, '\0', FN_PM_FINDTEXTURETYPE, pfnPM_FindTextureType, p, (name)); - RETURN_API(const char); -} - -void mm_SetupVisibility(edict_t *pViewEntity, edict_t *pClient, unsigned char **pvs, unsigned char **pas) -{ - META_DLLAPI_HANDLE_void(FN_SETUPVISIBILITY, pfnSetupVisibility, 4p, (pViewEntity, pClient, pvs, pas)); - RETURN_API_void(); -} - -void mm_UpdateClientData(const struct edict_s *ent, int sendweapons, struct clientdata_s *cd) -{ - META_DLLAPI_HANDLE_void(FN_UPDATECLIENTDATA, pfnUpdateClientData, pip, (ent, sendweapons, cd)); - RETURN_API_void(); -} - -int mm_AddToFullPack(struct entity_state_s *state, int e, edict_t *ent, edict_t *host, int hostflags, int player, unsigned char *pSet) -{ - META_DLLAPI_HANDLE(int, 0, FN_ADDTOFULLPACK, pfnAddToFullPack, pi2p2ip, (state, e, ent, host, hostflags, player, pSet)); - RETURN_API(int); -} - -void mm_CreateBaseline(int player, int eindex, struct entity_state_s *baseline, struct edict_s *entity, int playermodelindex, vec3_t player_mins, vec3_t player_maxs) -{ - META_DLLAPI_HANDLE_void(FN_CREATEBASELINE, pfnCreateBaseline, 2i2pi2p, (player, eindex, baseline, entity, playermodelindex, (float*)player_mins, (float*)player_maxs)); - RETURN_API_void(); -} - -void mm_RegisterEncoders() -{ - META_DLLAPI_HANDLE_void(FN_REGISTERENCODERS, pfnRegisterEncoders, void, (VOID_ARG)); - RETURN_API_void(); -} - -int mm_GetWeaponData(struct edict_s *player, struct weapon_data_s *info) -{ - META_DLLAPI_HANDLE(int, 0, FN_GETWEAPONDATA, pfnGetWeaponData, 2p, (player, info)); - RETURN_API(int); -} - -void mm_CmdStart(const edict_t *player, const struct usercmd_s *cmd, unsigned int random_seed) -{ - META_DLLAPI_HANDLE_void(FN_CMDSTART, pfnCmdStart, 2pui, (player, cmd, random_seed)); - RETURN_API_void(); -} - -void mm_CmdEnd(const edict_t *player) -{ - META_DLLAPI_HANDLE_void(FN_CMDEND, pfnCmdEnd, p, (player)); - RETURN_API_void(); -} - -int mm_ConnectionlessPacket(const struct netadr_s *net_from, const char *args, char *response_buffer, int *response_buffer_size) -{ - META_DLLAPI_HANDLE(int, 0, FN_CONNECTIONLESSPACKET, pfnConnectionlessPacket, 4p, (net_from, args, response_buffer, response_buffer_size)); - RETURN_API(int); -} - -int mm_GetHullBounds(int hullnumber, float *mins, float *maxs) -{ - META_DLLAPI_HANDLE(int, 0, FN_GETHULLBOUNDS, pfnGetHullBounds, i2p, (hullnumber, mins, maxs)); - RETURN_API(int); -} - -void mm_CreateInstancedBaselines() -{ - META_DLLAPI_HANDLE_void(FN_CREATEINSTANCEDBASELINES, pfnCreateInstancedBaselines, void, (VOID_ARG)); - RETURN_API_void(); -} - -int mm_InconsistentFile(const edict_t *player, const char *filename, char *disconnect_message) -{ - META_DLLAPI_HANDLE(int, 0, FN_INCONSISTENTFILE, pfnInconsistentFile, 3p, (player, filename, disconnect_message)); - RETURN_API(int); -} - -int mm_AllowLagCompensation() -{ - META_DLLAPI_HANDLE(int, 0, FN_ALLOWLAGCOMPENSATION, pfnAllowLagCompensation, void, (VOID_ARG)); - RETURN_API(int); -} - -void mm_OnFreeEntPrivateData(edict_t *pEnt) -{ - META_NEWAPI_HANDLE_void(FN_ONFREEENTPRIVATEDATA, pfnOnFreeEntPrivateData, p, (pEnt)); - RETURN_API_void(); -} - -void mm_GameShutdown() -{ - META_NEWAPI_HANDLE_void(FN_GAMESHUTDOWN, pfnGameShutdown, void, (VOID_ARG)); - RETURN_API_void(); -} - -int mm_ShouldCollide(edict_t *pentTouched, edict_t *pentOther) -{ - META_NEWAPI_HANDLE(int, 1, FN_SHOULDCOLLIDE, pfnShouldCollide, 2p, (pentTouched, pentOther)); - RETURN_API(int); -} - -void mm_CvarValue(const edict_t *pEnt, const char *value) -{ - g_Players.clear_player_cvar_query(pEnt); - META_NEWAPI_HANDLE_void(FN_CVARVALUE, pfnCvarValue, 2p, (pEnt, value)); - - RETURN_API_void(); -} - -void mm_CvarValue2(const edict_t *pEnt, int requestID, const char *cvarName, const char *value) -{ - META_NEWAPI_HANDLE_void(FN_CVARVALUE2, pfnCvarValue2, pi2p, (pEnt, requestID, cvarName, value)); - - RETURN_API_void(); -} - -DLL_FUNCTIONS gFunctionTable = -{ - mm_GameDLLInit, // pfnGameInit() Initialize the game (one-time call after loading of game .dll) - mm_DispatchSpawn, // pfnSpawn() - mm_DispatchThink, // pfnThink() - mm_DispatchUse, // pfnUse() - mm_DispatchTouch, // pfnTouch() - mm_DispatchBlocked, // pfnBlocked() - mm_DispatchKeyValue, // pfnKeyValue() - mm_DispatchSave, // pfnSave() - mm_DispatchRestore, // pfnRestore() - mm_DispatchObjectCollsionBox, // pfnSetAbsBox() - mm_SaveWriteFields, // pfnSaveWriteFields() - mm_SaveReadFields, // pfnSaveReadFields() - mm_SaveGlobalState, // pfnSaveGlobalState() - mm_RestoreGlobalState, // pfnRestoreGlobalState() - mm_ResetGlobalState, // pfnResetGlobalState() - mm_ClientConnect, // pfnClientConnect() (wd) Client has connected - mm_ClientDisconnect, // pfnClientDisconnect() (wd) Player has left the game - mm_ClientKill, // pfnClientKill() (wd) Player has typed "kill" - mm_ClientPutInServer, // pfnClientPutInServer() (wd) Client is entering the game - mm_ClientCommand, // pfnClientCommand() (wd) Player has sent a command (typed, or from a bind) - mm_ClientUserInfoChanged, // pfnClientUserInfoChanged() (wd) Client has updated their setinfo structure - mm_ServerActivate, // pfnServerActivate() (wd) Server is starting a new map - mm_ServerDeactivate, // pfnServerDeactivate() (wd) Server is leaving the map (shutdown, or changelevel); SDK2 - mm_PlayerPreThink, // pfnPlayerPreThink() - mm_PlayerPostThink, // pfnPlayerPostThink() - mm_StartFrame, // pfnStartFrame() - mm_ParmsNewLevel, // pfnParmsNewLevel() - mm_ParmsChangeLevel, // pfnParmsChangeLevel() - mm_GetGameDescription, // pfnGetGameDescription() Returns string describing current .dll. E.g. "TeamFotrress 2", "Half-Life" - mm_PlayerCustomization, // pfnPlayerCustomization() Notifies .dll of new customization for player. - mm_SpectatorConnect, // pfnSpectatorConnect() Called when spectator joins server - mm_SpectatorDisconnect, // pfnSpectatorDisconnect() Called when spectator leaves the server - mm_SpectatorThink, // pfnSpectatorThink() Called when spectator sends a command packet (usercmd_t) - mm_Sys_Error, // pfnSys_Error() Notify game .dll that engine is going to shut down. Allows mod authors to set a breakpoint. SDK2 - mm_PM_Move, // pfnPM_Move() (wd) SDK2 - mm_PM_Init, // pfnPM_Init() Server version of player movement initialization; (wd) SDK2 - mm_PM_FindTextureType, // pfnPM_FindTextureType() (wd) SDK2 - mm_SetupVisibility, // pfnSetupVisibility() Set up PVS and PAS for networking for this client; (wd) SDK2 - mm_UpdateClientData, // pfnUpdateClientData() Set up data sent only to specific client; (wd) SDK2 - mm_AddToFullPack, // pfnAddToFullPack() (wd) SDK2 - mm_CreateBaseline, // pfnCreateBaseline() Tweak entity baseline for network encoding, allows setup of player baselines, too.; (wd) SDK2 - mm_RegisterEncoders, // pfnRegisterEncoders() Callbacks for network encoding; (wd) SDK2 - mm_GetWeaponData, // pfnGetWeaponData() (wd) SDK2 - mm_CmdStart, // pfnCmdStart() (wd) SDK2 - mm_CmdEnd, // pfnCmdEnd() (wd) SDK2 - mm_ConnectionlessPacket, // pfnConnectionlessPacket() (wd) SDK2 - mm_GetHullBounds, // pfnGetHullBounds() (wd) SDK2 - mm_CreateInstancedBaselines, // pfnCreateInstancedBaselines() (wd) SDK2 - mm_InconsistentFile, // pfnInconsistentFile() (wd) SDK2 - mm_AllowLagCompensation, // pfnAllowLagCompensation() (wd) SDK2 + mm_SetupVisibility, //! pfnSetupVisibility() Set up PVS and PAS for networking for this client; (wd) SDK2 + mm_UpdateClientData, //! pfnUpdateClientData() Set up data sent only to specific client; (wd) SDK2 + mm_AddToFullPack, //! pfnAddToFullPack() (wd) SDK2 + mm_CreateBaseline, //! pfnCreateBaseline() Tweak entity baseline for network encoding, allows setup of player baselines, too.; (wd) SDK2 + mm_RegisterEncoders, //! pfnRegisterEncoders() Callbacks for network encoding; (wd) SDK2 + mm_GetWeaponData, //! pfnGetWeaponData() (wd) SDK2 + mm_CmdStart, //! pfnCmdStart() (wd) SDK2 + mm_CmdEnd, //! pfnCmdEnd() (wd) SDK2 + mm_ConnectionlessPacket, //! pfnConnectionlessPacket() (wd) SDK2 + mm_GetHullBounds, //! pfnGetHullBounds() (wd) SDK2 + mm_CreateInstancedBaselines, //! pfnCreateInstancedBaselines() (wd) SDK2 + mm_InconsistentFile, //! pfnInconsistentFile() (wd) SDK2 + mm_AllowLagCompensation, //! pfnAllowLagCompensation() (wd) SDK2 }; -DLL_FUNCTIONS *g_pHookedDllFunctions = &gFunctionTable; +DLL_FUNCTIONS *pHookedDllFunctions = &sFunctionTable; // It's not clear what the difference is between GetAPI and GetAPI2; they -// both appear to return the exact same function table. +// both appear to return the exact same function table. // // Only one of them appears to be ever called, though. If the DLL provides // GetAPI2, the engine/hlds will call that, and will not call GetAPI. If @@ -461,44 +414,49 @@ DLL_FUNCTIONS *g_pHookedDllFunctions = &gFunctionTable; // // It's unclear whether a DLL coded under SDK2 needs to provide the older // GetAPI or not.. + C_DLLEXPORT int GetEntityAPI(DLL_FUNCTIONS *pFunctionTable, int interfaceVersion) { META_DEBUG(3, ("called: GetEntityAPI; version=%d", interfaceVersion)); - if (!pFunctionTable || metamod_not_loaded) - { - META_WARNING("GetEntityAPI called with null pFunctionTable"); - return FALSE; + if(!pFunctionTable) { + META_ERROR("GetEntityAPI called with null pFunctionTable"); + return(FALSE); } - else if (interfaceVersion != INTERFACE_VERSION) - { - META_WARNING("GetEntityAPI version mismatch; requested=%d ours=%d", interfaceVersion, INTERFACE_VERSION); - return FALSE; + else if(interfaceVersion != INTERFACE_VERSION) { + META_ERROR("GetEntityAPI version mismatch; requested=%d ours=%d", interfaceVersion, INTERFACE_VERSION); + return(FALSE); } - Q_memcpy(pFunctionTable, &gFunctionTable, sizeof(DLL_FUNCTIONS)); - return TRUE; + + memcpy(pFunctionTable, &sFunctionTable, sizeof(DLL_FUNCTIONS)); + + + return(TRUE); } C_DLLEXPORT int GetEntityAPI2(DLL_FUNCTIONS *pFunctionTable, int *interfaceVersion) { META_DEBUG(3, ("called: GetEntityAPI2; version=%d", *interfaceVersion)); - if (!pFunctionTable || metamod_not_loaded) - { - META_WARNING("GetEntityAPI2 called with null pFunctionTable"); - return FALSE; + + if(!pFunctionTable) { + META_ERROR("GetEntityAPI2 called with null pFunctionTable"); + return(FALSE); } - else if (*interfaceVersion != INTERFACE_VERSION) - { - META_WARNING("GetEntityAPI2 version mismatch; requested=%d ours=%d", *interfaceVersion, INTERFACE_VERSION); - // Tell engine what version we had, so it can figure out who is out of date. + else if(*interfaceVersion != INTERFACE_VERSION) { + META_ERROR("GetEntityAPI2 version mismatch; requested=%d ours=%d", *interfaceVersion, INTERFACE_VERSION); + //! Tell engine what version we had, so it can figure out who is out of date. *interfaceVersion = INTERFACE_VERSION; - return FALSE; + return(FALSE); } - Q_memcpy(pFunctionTable, &gFunctionTable, sizeof(DLL_FUNCTIONS)); - return TRUE; + + memcpy(pFunctionTable, &sFunctionTable, sizeof(DLL_FUNCTIONS)); + + + return(TRUE); } + // I could find _no_ documentation or examples for the intended use of // NEW_DLL_FUNCTIONS. I wouldn't have even _known_ about the // GetNewDLLFunctions() function except for the reference in Adminmod.. It @@ -509,42 +467,47 @@ C_DLLEXPORT int GetEntityAPI2(DLL_FUNCTIONS *pFunctionTable, int *interfaceVersi // appending new functions to the GetAPI table/interface. // // Interestingly, it appears to be called by the engine _before_ GetAPI. -meta_new_dll_functions_t sNewFunctionTable( - &mm_OnFreeEntPrivateData, // pfnOnFreeEntPrivateData() Called right before the object's memory is freed. Calls its destructor. - &mm_GameShutdown, // pfnGameShutdown() - &mm_ShouldCollide, // pfnShouldCollide() - &mm_CvarValue, // pfnCvarValue() - &mm_CvarValue2 // pfnCvarValue2() + +static meta_new_dll_functions_t sNewFunctionTable ( + &mm_OnFreeEntPrivateData, //! pfnOnFreeEntPrivateData() Called right before the object's memory is freed. Calls its destructor. + &mm_GameShutdown, //! pfnGameShutdown() + &mm_ShouldCollide, //! pfnShouldCollide() + // Added 2005-08-11 (no SDK update) + &mm_CvarValue, //! pfnCvarValue() (fz) Obsolete! Use mm_CvarValue2 instead + // Added 2005-11-22 (no SDK update) + &mm_CvarValue2 //! pfnCvarValue2() (fz) When pfnQueryClientCvarValue2() completes it will call + //! pfnCvarValue2() with the request ID supplied earlier, the name of + //! the cvar requested and the value of that cvar. ); -NEW_DLL_FUNCTIONS *g_pHookedNewDllFunctions = &sNewFunctionTable; -C_DLLEXPORT int GetNewDLLFunctions(NEW_DLL_FUNCTIONS *pNewFunctionTable, int *interfaceVersion) +NEW_DLL_FUNCTIONS *pHookedNewDllFunctions = &sNewFunctionTable; + +C_DLLEXPORT int GetNewDLLFunctions(NEW_DLL_FUNCTIONS *pNewFunctionTable, int *interfaceVersion) { META_DEBUG(6, ("called: GetNewDLLFunctions; version=%d", *interfaceVersion)); - #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 // them. Otherwise, we're in the position of having to provide answers // we can't necessarily provide (for instance, ShouldCollide())... - if (!GameDLL.funcs.newapi_table) - return FALSE; + if(!GameDLL.funcs.newapi_table) + return(FALSE); #endif - if (!pNewFunctionTable) - { + if(!pNewFunctionTable) { META_ERROR("GetNewDLLFunctions called with null pNewFunctionTable"); - return FALSE; + return(FALSE); } - else if (*interfaceVersion != NEW_DLL_FUNCTIONS_VERSION) - { + else if(*interfaceVersion != NEW_DLL_FUNCTIONS_VERSION) { META_ERROR("GetNewDLLFunctions version mismatch; requested=%d ours=%d", *interfaceVersion, NEW_DLL_FUNCTIONS_VERSION); - - // Tell engine what version we had, so it can figure out who is out of date. + //! Tell engine what version we had, so it can figure out who is out of date. *interfaceVersion = NEW_DLL_FUNCTIONS_VERSION; - return FALSE; + return(FALSE); } sNewFunctionTable.copy_to(pNewFunctionTable); - return TRUE; + + + return(TRUE); } + diff --git a/metamod/src/dllapi.h b/metamod/src/dllapi.h index afce58d..f1967ef 100644 --- a/metamod/src/dllapi.h +++ b/metamod/src/dllapi.h @@ -1,3 +1,39 @@ +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// dllapi.h - prototypes and typedefs for Half-Life DLL API routines + +/* + * Copyright (c) 2001-2003 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game g_engine ("HL + * g_engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL g_engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + #ifndef DLLAPI_H #define DLLAPI_H @@ -18,6 +54,77 @@ C_DLLEXPORT int GetEntityAPI2( DLL_FUNCTIONS *pFunctionTable, int *interfaceVers // From Adminmod dll.cpp: C_DLLEXPORT int GetNewDLLFunctions( NEW_DLL_FUNCTIONS *pNewFunctionTable, int *interfaceVersion ); + +// From SDK dlls/game.h: +extern void mm_GameDLLInit( void ); + +// From SDK dlls/cbase.h: +extern int mm_DispatchSpawn( edict_t *pent ); +extern void mm_DispatchThink( edict_t *pent ); +extern void mm_DispatchUse( edict_t *pentUsed, edict_t *pentOther ); +extern void mm_DispatchTouch( edict_t *pentTouched, edict_t *pentOther ); +extern void mm_DispatchBlocked( edict_t *pentBlocked, edict_t *pentOther ); +extern void mm_DispatchKeyValue( edict_t *pentKeyvalue, KeyValueData *pkvd ); +extern void mm_DispatchSave( edict_t *pent, SAVERESTOREDATA *pSaveData ); +extern int mm_DispatchRestore( edict_t *pent, SAVERESTOREDATA *pSaveData, int globalEntity ); +extern void mm_DispatchObjectCollisionBox( edict_t *pent ); +extern void mm_SaveWriteFields( SAVERESTOREDATA *pSaveData, const char *pname, void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCount ); +extern void mm_SaveReadFields( SAVERESTOREDATA *pSaveData, const char *pname, void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCount ); +extern void mm_SaveGlobalState( SAVERESTOREDATA *pSaveData ); +extern void mm_RestoreGlobalState( SAVERESTOREDATA *pSaveData ); +extern void mm_ResetGlobalState( void ); + +// From SDK dlls/client.h: +extern BOOL mm_ClientConnect( edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[ 128 ] ); +extern void mm_ClientDisconnect( edict_t *pEntity ); +extern void mm_ClientKill( edict_t *pEntity ); +extern void mm_ClientPutInServer( edict_t *pEntity ); +extern void mm_ClientCommand( edict_t *pEntity ); +extern void mm_ClientUserInfoChanged( edict_t *pEntity, char *infobuffer ); +extern void mm_ServerActivate( edict_t *pEdictList, int edictCount, int clientMax ); +extern void mm_ServerDeactivate( void ); +extern void mm_PlayerPreThink( edict_t *pEntity ); +extern void mm_PlayerPostThink( edict_t *pEntity ); +extern void mm_StartFrame( void ); +extern void mm_ParmsNewLevel( void ); +extern void mm_ParmsChangeLevel( void ); +extern const char *mm_GetGameDescription( void ); +extern void mm_PlayerCustomization( edict_t *pEntity, customization_t *pCust ); +extern void mm_SpectatorConnect ( edict_t *pEntity ); +extern void mm_SpectatorDisconnect ( edict_t *pEntity ); +extern void mm_SpectatorThink ( edict_t *pEntity ); +extern void mm_Sys_Error( const char *error_string ); + +// From SDK pm_shared/pm_shared.h: +extern void mm_PM_Move ( struct playermove_s *ppmove, int server ); +extern void mm_PM_Init ( struct playermove_s *ppmove ); +extern char mm_PM_FindTextureType ( const char *name ); + +// From SDK dlls/client.h: +extern void mm_SetupVisibility( edict_t *pViewEntity, edict_t *pClient, unsigned char **pvs, unsigned char **pas ); +extern void mm_UpdateClientData ( const struct edict_s *ent, int sendweapons, struct clientdata_s *cd ); +extern int mm_AddToFullPack( struct entity_state_s *state, int e, edict_t *ent, edict_t *host, int hostflags, int player, unsigned char *pSet ); +extern void mm_CreateBaseline( int player, int eindex, struct entity_state_s *baseline, struct edict_s *entity, int playermodelindex, vec3_t player_mins, vec3_t player_maxs ); +extern void mm_RegisterEncoders( void ); +extern int mm_GetWeaponData( struct edict_s *player, struct weapon_data_s *info ); +extern void mm_CmdStart( const edict_t *player, const struct usercmd_s *cmd, unsigned int random_seed ); +extern void mm_CmdEnd ( const edict_t *player ); +extern int mm_ConnectionlessPacket( const struct netadr_s *net_from, const char *args, char *response_buffer, int *response_buffer_size ); +extern int mm_GetHullBounds( int hullnumber, float *mins, float *maxs ); +extern void mm_CreateInstancedBaselines ( void ); +extern int mm_InconsistentFile( const edict_t *player, const char *filename, char *disconnect_message ); +extern int mm_AllowLagCompensation( void ); + +// No example from SDK... +extern void mm_OnFreeEntPrivateData(edict_t pEnt); +extern void mm_GameShutdown(void); +extern int mm_ShouldCollide(edict_t *pentTouched, edict_t *pentOther); +//Added 2005-08-11 (no SDK update) +extern void mm_CvarValue(const edict_t *pEnt, const char *value); //! Obsolete! Use mm_CvarValue2 instead +//Added 2005-11-22 (no SDK update) +extern void mm_CvarValue2(const edict_t *pEnt, int requestID, const char *cvarName, const char *value); + + // Typedefs for the above functions: typedef void (*FN_GAMEINIT) ( void ); @@ -36,7 +143,7 @@ typedef void (*FN_SAVEGLOBALSTATE) ( SAVERESTOREDATA *pSaveData ); typedef void (*FN_RESTOREGLOBALSTATE) ( SAVERESTOREDATA *pSaveData ); typedef void (*FN_RESETGLOBALSTATE) ( void ); -typedef qboolean (*FN_CLIENTCONNECT) ( edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[128]); +typedef BOOL (*FN_CLIENTCONNECT) ( edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[ 128 ] ); typedef void (*FN_CLIENTDISCONNECT) ( edict_t *pEntity ); typedef void (*FN_CLIENTKILL) ( edict_t *pEntity ); typedef void (*FN_CLIENTPUTINSERVER) ( edict_t *pEntity ); @@ -58,7 +165,7 @@ typedef void (*FN_SYS_ERROR) ( const char *error_string ); typedef void (*FN_PM_MOVE) ( struct playermove_s *ppmove, int server ); typedef void (*FN_PM_INIT) ( struct playermove_s *ppmove ); -typedef char (*FN_PM_FINDTEXTURETYPE) ( const char *name ); +typedef char (*FN_PM_FINDTEXTURETYPE) ( char *name ); typedef void (*FN_SETUPVISIBILITY) ( edict_t *pViewEntity, edict_t *pClient, unsigned char **pvs, unsigned char **pas ); typedef void (*FN_UPDATECLIENTDATA) ( const struct edict_s *ent, int sendweapons, struct clientdata_s *cd ); @@ -75,11 +182,11 @@ typedef int (*FN_INCONSISTENTFILE) ( const edict_t *player, const char *filename typedef int (*FN_ALLOWLAGCOMPENSATION) ( void ); typedef void (*FN_ONFREEENTPRIVATEDATA) (edict_t *pEnt); -typedef void (*FN_GAMESHUTDOWN) (); +typedef void (*FN_GAMESHUTDOWN) (void); typedef int (*FN_SHOULDCOLLIDE) (edict_t *pentTouched, edict_t *pentOther); -// Added 2005/08/11 (no SDK update): -typedef void (*FN_CVARVALUE)(const edict_t *pEnt, const char *value); -// Added 2005/11/21 (no SDK update): +//Added 2005-08-11 (no SDK update) +typedef void (*FN_CVARVALUE)(const edict_t *pEnt, const char *value); //! Obsolete! Use FN_CVARVALUE2 instead +//Added 2005-11-22 (no SDK update) typedef void (*FN_CVARVALUE2)(const edict_t *pEnt, int requestID, const char *cvarName, const char *value); #endif /* DLLAPI_H */ diff --git a/metamod/src/engine_api.cpp b/metamod/src/engine_api.cpp index 6b2653a..599f9c9 100644 --- a/metamod/src/engine_api.cpp +++ b/metamod/src/engine_api.cpp @@ -1,1069 +1,881 @@ +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// engine_api.cpp - implementation of Half-Life engine functions + +/* + * Copyright (c) 2001-2003 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game g_engine ("HL + * g_engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL g_engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + #include "precompiled.h" -// Engine routines, functions returning "void". -#define META_ENGINE_HANDLE_void(FN_TYPE, pfnName, pack_args_type, pfn_args) \ - API_START_TSC_TRACKING(); \ - API_PACK_ARGS(pack_args_type, pfn_args); \ - main_hook_function_void(offsetof(engine_info_t, pfnName), e_api_engine, offsetof(enginefuncs_t, pfnName), &packed_args); \ - API_END_TSC_TRACKING() +// g_engine routines, functions returning "void". +#define META_ENGINE_HANDLE_void(FN_TYPE, pfnName, pfn_args) \ + SETUP_API_CALLS_void(FN_TYPE, pfnName, engine_info); \ + CALL_PLUGIN_API_void(P_PRE, pfnName, pfn_args, engine_table); \ + CALL_ENGINE_API_void(pfnName, pfn_args); \ + CALL_PLUGIN_API_void(P_POST, pfnName, pfn_args, engine_post_table); -// Engine routines, functions returning an actual value. -#define META_ENGINE_HANDLE(ret_t, ret_init, FN_TYPE, pfnName, pack_args_type, pfn_args) \ - API_START_TSC_TRACKING(); \ - API_PACK_ARGS(pack_args_type, pfn_args); \ - class_ret_t ret_val(main_hook_function(class_ret_t((ret_t)ret_init), offsetof(engine_info_t, pfnName), e_api_engine, offsetof(enginefuncs_t, pfnName), &packed_args)); \ - API_END_TSC_TRACKING() +// g_engine routines, functions returning an actual value. +#define META_ENGINE_HANDLE(ret_t, ret_init, FN_TYPE, pfnName, pfn_args) \ + SETUP_API_CALLS(ret_t, ret_init, FN_TYPE, pfnName, engine_info); \ + CALL_PLUGIN_API(P_PRE, ret_init, pfnName, pfn_args, MRES_SUPERCEDE, engine_table); \ + CALL_ENGINE_API(pfnName, pfn_args); \ + CALL_PLUGIN_API(P_POST, ret_init, pfnName, pfn_args, MRES_OVERRIDE, engine_post_table); -// For varargs functions -#ifndef DO_NOT_FIX_VARARG_ENGINE_API_WARPERS - #define MAKE_FORMATED_STRING(szFmt) \ - char strbuf[MAX_STRBUF_LEN]; \ - char *buf = strbuf; \ - { \ - int len; \ - va_list vargs; \ - va_start(vargs, szFmt); \ - len = safe_vsnprintf(strbuf, sizeof(strbuf), szFmt, vargs); \ - va_end(vargs); \ - if ((unsigned)len >= sizeof(strbuf)) { \ - buf = (char *)malloc(len + 1); \ - if (buf) { \ - va_start(vargs, szFmt); \ - safevoid_vsnprintf(buf, len + 1, szFmt, vargs); \ - va_end(vargs); \ - } else { \ - buf = strbuf; \ - } \ - } \ - } - #define CLEAN_FORMATED_STRING() \ - if (buf != strbuf) \ - free(buf); + +// g_engine routines, printf-style functions returning "void". +#define META_ENGINE_HANDLE_void_varargs(FN_TYPE, pfnName, pfn_arg, fmt_arg) \ + SETUP_API_CALLS_void(FN_TYPE, pfnName, engine_info); \ + char buf[MAX_STRBUF_LEN]; \ + va_list ap; \ + META_DEBUG(loglevel, ("In %s: fmt=%s", pfn_string, fmt_arg)); \ + va_start(ap, fmt_arg); \ + vsnprintf(buf, sizeof(buf), fmt_arg, ap); \ + va_end(ap); \ + CALL_PLUGIN_API_void(P_PRE, pfnName, (pfn_arg, "%s", buf), engine_table); \ + CALL_ENGINE_API_void(pfnName, (pfn_arg, "%s", buf)); \ + CALL_PLUGIN_API_void(P_POST, pfnName, (pfn_arg, "%s", buf), engine_post_table); + +// g_engine routines, printf-style functions returning an actual value. +#define META_ENGINE_HANDLE_varargs(ret_t, ret_init, FN_TYPE, pfnName, pfn_arg, fmt_arg) \ + SETUP_API_CALLS(ret_t, ret_init, FN_TYPE, pfnName, engine_info); \ + char buf[MAX_STRBUF_LEN]; \ + va_list ap; \ + META_DEBUG(loglevel, ("In %s: fmt=%s", pfn_string, fmt_arg)); \ + va_start(ap, fmt_arg); \ + vsnprintf(buf, sizeof(buf), fmt_arg, ap); \ + va_end(ap); \ + CALL_PLUGIN_API(P_PRE, ret_init, pfnName, (pfn_arg, "%s", buf), MRES_SUPERCEDE, engine_table); \ + CALL_ENGINE_API(pfnName, (pfn_arg, "%s", buf)); \ + CALL_PLUGIN_API(P_POST, ret_init, pfnName, (pfn_arg, "%s", buf), MRES_OVERRIDE, engine_post_table); + + +int mm_PrecacheModel(const char *s) { + META_ENGINE_HANDLE(int, 0, FN_PRECACHEMODEL, pfnPrecacheModel, (s)); + RETURN_API() +} +int mm_PrecacheSound(const char *s) { + META_ENGINE_HANDLE(int, 0, FN_PRECACHESOUND, pfnPrecacheSound, (s)); + RETURN_API() +} +void mm_SetModel(edict_t *e, const char *m) { + META_ENGINE_HANDLE_void(FN_SETMODEL, pfnSetModel, (e, m)); + RETURN_API_void() +} +int mm_ModelIndex(const char *m) { + META_ENGINE_HANDLE(int, 0, FN_MODELINDEX, pfnModelIndex, (m)); + RETURN_API() +} +int mm_ModelFrames(int modelIndex) { + META_ENGINE_HANDLE(int, 0, FN_MODELFRAMES, pfnModelFrames, (modelIndex)); + RETURN_API() +} + +void mm_SetSize(edict_t *e, const float *rgflMin, const float *rgflMax) { + META_ENGINE_HANDLE_void(FN_SETSIZE, pfnSetSize, (e, rgflMin, rgflMax)); + RETURN_API_void() +} +void mm_ChangeLevel(const char *s1, const char *s2) { + META_ENGINE_HANDLE_void(FN_CHANGELEVEL, pfnChangeLevel, (s1, s2)); + RETURN_API_void() +} +void mm_GetSpawnParms(edict_t *ent) { + META_ENGINE_HANDLE_void(FN_GETSPAWNPARMS, pfnGetSpawnParms, (ent)); + RETURN_API_void() +} +void mm_SaveSpawnParms(edict_t *ent) { + META_ENGINE_HANDLE_void(FN_SAVESPAWNPARMS, pfnSaveSpawnParms, (ent)); + RETURN_API_void() +} + +float mm_VecToYaw(const float *rgflVector) { + META_ENGINE_HANDLE(float, 0.0, FN_VECTOYAW, pfnVecToYaw, (rgflVector)); + RETURN_API() +} +void mm_VecToAngles(const float *rgflVectorIn, float *rgflVectorOut) { + META_ENGINE_HANDLE_void(FN_VECTOANGLES, pfnVecToAngles, (rgflVectorIn, rgflVectorOut)); + RETURN_API_void() +} +void mm_MoveToOrigin(edict_t *ent, const float *pflGoal, float dist, int iMoveType) { + META_ENGINE_HANDLE_void(FN_MOVETOORIGIN, pfnMoveToOrigin, (ent, pflGoal, dist, iMoveType)); + RETURN_API_void() +} +void mm_ChangeYaw(edict_t *ent) { + META_ENGINE_HANDLE_void(FN_CHANGEYAW, pfnChangeYaw, (ent)); + RETURN_API_void() +} +void mm_ChangePitch(edict_t *ent) { + META_ENGINE_HANDLE_void(FN_CHANGEPITCH, pfnChangePitch, (ent)); + RETURN_API_void() +} + +edict_t *mm_FindEntityByString(edict_t *pEdictStartSearchAfter, const char *pszField, const char *pszValue) { + META_ENGINE_HANDLE(edict_t *, NULL, FN_FINDENTITYBYSTRING, pfnFindEntityByString, (pEdictStartSearchAfter, pszField, pszValue)); + RETURN_API() +} +int mm_GetEntityIllum(edict_t *pEnt) { + META_ENGINE_HANDLE(int, 0, FN_GETENTITYILLUM, pfnGetEntityIllum, (pEnt)); + RETURN_API() +} +edict_t *mm_FindEntityInSphere(edict_t *pEdictStartSearchAfter, const float *org, float rad) { + META_ENGINE_HANDLE(edict_t *, NULL, FN_FINDENTITYINSPHERE, pfnFindEntityInSphere, (pEdictStartSearchAfter, org, rad)); + RETURN_API() +} +edict_t *mm_FindClientInPVS(edict_t *pEdict) { + META_ENGINE_HANDLE(edict_t *, NULL, FN_FINDCLIENTINPVS, pfnFindClientInPVS, (pEdict)); + RETURN_API() +} +edict_t *mm_EntitiesInPVS(edict_t *pplayer) { + META_ENGINE_HANDLE(edict_t *, NULL, FN_ENTITIESINPVS, pfnEntitiesInPVS, (pplayer)); + RETURN_API() +} + +void mm_MakeVectors(const float *rgflVector) { + META_ENGINE_HANDLE_void(FN_MAKEVECTORS, pfnMakeVectors, (rgflVector)); + RETURN_API_void() +} +void mm_AngleVectors(const float *rgflVector, float *forward, float *right, float *up) { + META_ENGINE_HANDLE_void(FN_ANGLEVECTORS, pfnAngleVectors, (rgflVector, forward, right, up)); + RETURN_API_void() +} + +edict_t *mm_CreateEntity(void) { + META_ENGINE_HANDLE(edict_t *, NULL, FN_CREATEENTITY, pfnCreateEntity, ()); + RETURN_API() +} +void mm_RemoveEntity(edict_t *e) { + META_ENGINE_HANDLE_void(FN_REMOVEENTITY, pfnRemoveEntity, (e)); + RETURN_API_void() +} +edict_t *mm_CreateNamedEntity(int className) { + META_ENGINE_HANDLE(edict_t *, NULL, FN_CREATENAMEDENTITY, pfnCreateNamedEntity, (className)); + RETURN_API() +} + +void mm_MakeStatic(edict_t *ent) { + META_ENGINE_HANDLE_void(FN_MAKESTATIC, pfnMakeStatic, (ent)); + RETURN_API_void() +} +int mm_EntIsOnFloor(edict_t *e) { + META_ENGINE_HANDLE(int, 0, FN_ENTISONFLOOR, pfnEntIsOnFloor, (e)); + RETURN_API() +} +int mm_DropToFloor(edict_t *e) { + META_ENGINE_HANDLE(int, 0, FN_DROPTOFLOOR, pfnDropToFloor, (e)); + RETURN_API() +} + +int mm_WalkMove(edict_t *ent, float yaw, float dist, int iMode) { + META_ENGINE_HANDLE(int, 0, FN_WALKMOVE, pfnWalkMove, (ent, yaw, dist, iMode)); + RETURN_API() +} +void mm_SetOrigin(edict_t *e, const float *rgflOrigin) { + META_ENGINE_HANDLE_void(FN_SETORIGIN, pfnSetOrigin, (e, rgflOrigin)); + RETURN_API_void() +} + +void mm_EmitSound(edict_t *entity, int channel, const char *sample, /*int*/float volume, float attenuation, int fFlags, int pitch) { + META_ENGINE_HANDLE_void(FN_EMITSOUND, pfnEmitSound, (entity, channel, sample, volume, attenuation, fFlags, pitch)); + RETURN_API_void() +} +void mm_EmitAmbientSound(edict_t *entity, float *pos, const char *samp, float vol, float attenuation, int fFlags, int pitch) { + META_ENGINE_HANDLE_void(FN_EMITAMBIENTSOUND, pfnEmitAmbientSound, (entity, pos, samp, vol, attenuation, fFlags, pitch)); + RETURN_API_void() +} + +void mm_TraceLine(const float *v1, const float *v2, int fNoMonsters, edict_t *pentToSkip, TraceResult *ptr) { + META_ENGINE_HANDLE_void(FN_TRACELINE, pfnTraceLine, (v1, v2, fNoMonsters, pentToSkip, ptr)); + RETURN_API_void() +} +void mm_TraceToss(edict_t *pent, edict_t *pentToIgnore, TraceResult *ptr) { + META_ENGINE_HANDLE_void(FN_TRACETOSS, pfnTraceToss, (pent, pentToIgnore, ptr)); + RETURN_API_void() +} +int mm_TraceMonsterHull(edict_t *pEdict, const float *v1, const float *v2, int fNoMonsters, edict_t *pentToSkip, TraceResult *ptr) { + META_ENGINE_HANDLE(int, 0, FN_TRACEMONSTERHULL, pfnTraceMonsterHull, (pEdict, v1, v2, fNoMonsters, pentToSkip, ptr)); + RETURN_API() +} +void mm_TraceHull(const float *v1, const float *v2, int fNoMonsters, int hullNumber, edict_t *pentToSkip, TraceResult *ptr) { + META_ENGINE_HANDLE_void(FN_TRACEHULL, pfnTraceHull, (v1, v2, fNoMonsters, hullNumber, pentToSkip, ptr)); + RETURN_API_void() +} +void mm_TraceModel(const float *v1, const float *v2, int hullNumber, edict_t *pent, TraceResult *ptr) { + META_ENGINE_HANDLE_void(FN_TRACEMODEL, pfnTraceModel, (v1, v2, hullNumber, pent, ptr)); + RETURN_API_void() +} +const char *mm_TraceTexture(edict_t *pTextureEntity, const float *v1, const float *v2 ) { + META_ENGINE_HANDLE(const char *, NULL, FN_TRACETEXTURE, pfnTraceTexture, (pTextureEntity, v1, v2)); + RETURN_API() +} +void mm_TraceSphere(const float *v1, const float *v2, int fNoMonsters, float radius, edict_t *pentToSkip, TraceResult *ptr) { + META_ENGINE_HANDLE_void(FN_TRACESPHERE, pfnTraceSphere, (v1, v2, fNoMonsters, radius, pentToSkip, ptr)); + RETURN_API_void() +} +void mm_GetAimVector(edict_t *ent, float speed, float *rgflReturn) { + META_ENGINE_HANDLE_void(FN_GETAIMVECTOR, pfnGetAimVector, (ent, speed, rgflReturn)); + RETURN_API_void() +} + +void mm_ServerCommand(char *str) { + META_ENGINE_HANDLE_void(FN_SERVERCOMMAND, pfnServerCommand, (str)); + RETURN_API_void() +} +void mm_ServerExecute(void) { + META_ENGINE_HANDLE_void(FN_SERVEREXECUTE, pfnServerExecute, ()); + RETURN_API_void() +} +void mm_engClientCommand(edict_t *pEdict, char *szFmt, ...) { + META_ENGINE_HANDLE_void_varargs(FN_CLIENTCOMMAND_ENG, pfnClientCommand, pEdict, szFmt); + RETURN_API_void() +} + +void mm_ParticleEffect(const float *org, const float *dir, float color, float count) { + META_ENGINE_HANDLE_void(FN_PARTICLEEFFECT, pfnParticleEffect, (org, dir, color, count)); + RETURN_API_void() +} +void mm_LightStyle(int style, char *val) { + META_ENGINE_HANDLE_void(FN_LIGHTSTYLE, pfnLightStyle, (style, val)); + RETURN_API_void() +} +int mm_DecalIndex(const char *name) { + META_ENGINE_HANDLE(int, 0, FN_DECALINDEX, pfnDecalIndex, (name)); + RETURN_API() +} +int mm_PointContents(const float *rgflVector) { + META_ENGINE_HANDLE(int, 0, FN_POINTCONTENTS, pfnPointContents, (rgflVector)); + RETURN_API() +} + +void mm_MessageBegin(int msg_dest, int msg_type, const float *pOrigin, edict_t *ed) { + META_ENGINE_HANDLE_void(FN_MESSAGEBEGIN, pfnMessageBegin, (msg_dest, msg_type, pOrigin, ed)); + RETURN_API_void() +} +void mm_MessageEnd(void) { + META_ENGINE_HANDLE_void(FN_MESSAGEEND, pfnMessageEnd, ()); + RETURN_API_void() +} + +void mm_WriteByte(int iValue) { + META_ENGINE_HANDLE_void(FN_WRITEBYTE, pfnWriteByte, (iValue)); + RETURN_API_void() +} +void mm_WriteChar(int iValue) { + META_ENGINE_HANDLE_void(FN_WRITECHAR, pfnWriteChar, (iValue)); + RETURN_API_void() +} +void mm_WriteShort(int iValue) { + META_ENGINE_HANDLE_void(FN_WRITESHORT, pfnWriteShort, (iValue)); + RETURN_API_void() +} +void mm_WriteLong(int iValue) { + META_ENGINE_HANDLE_void(FN_WRITELONG, pfnWriteLong, (iValue)); + RETURN_API_void() +} +void mm_WriteAngle(float flValue) { + META_ENGINE_HANDLE_void(FN_WRITEANGLE, pfnWriteAngle, (flValue)); + RETURN_API_void() +} +void mm_WriteCoord(float flValue) { + META_ENGINE_HANDLE_void(FN_WRITECOORD, pfnWriteCoord, (flValue)); + RETURN_API_void() +} +void mm_WriteString(const char *sz) { + META_ENGINE_HANDLE_void(FN_WRITESTRING, pfnWriteString, (sz)); + RETURN_API_void() +} +void mm_WriteEntity(int iValue) { + META_ENGINE_HANDLE_void(FN_WRITEENTITY, pfnWriteEntity, (iValue)); + RETURN_API_void() +} + +void mm_CVarRegister(cvar_t *pCvar) { + META_ENGINE_HANDLE_void(FN_CVARREGISTER, pfnCVarRegister, (pCvar)); + RETURN_API_void() +} +float mm_CVarGetFloat(const char *szVarName) { + META_ENGINE_HANDLE(float, 0.0, FN_CVARGETFLOAT, pfnCVarGetFloat, (szVarName)); + RETURN_API() +} +const char *mm_CVarGetString(const char *szVarName) { + META_ENGINE_HANDLE(const char *, NULL, FN_CVARGETSTRING, pfnCVarGetString, (szVarName)); + RETURN_API() +} +void mm_CVarSetFloat(const char *szVarName, float flValue) { + META_ENGINE_HANDLE_void(FN_CVARSETFLOAT, pfnCVarSetFloat, (szVarName, flValue)); + RETURN_API_void() +} +void mm_CVarSetString(const char *szVarName, const char *szValue) { + META_ENGINE_HANDLE_void(FN_CVARSETSTRING, pfnCVarSetString, (szVarName, szValue)); + RETURN_API_void() +} + +void mm_AlertMessage(ALERT_TYPE atype, const char *szFmt, ...) { +#ifndef UNFINISHED + META_ENGINE_HANDLE_void_varargs(FN_ALERTMESSAGE, pfnAlertMessage, atype, szFmt); +#else /* UNFINISHED */ + // Expand macro, since we need to do extra work here. + + // usual setup + SETUP_API_CALLS_void(FN_ALERTMESSAGE, pfnAlertMessage, engine_info); + char buf[MAX_STRBUF_LEN]; + va_list ap; + int len; + char *qmsg; + META_DEBUG(loglevel, ("In %s: fmt=%s", pfn_string, szFmt)); + va_start(ap, szFmt); + len=vsnprintf(buf, sizeof(buf), szFmt, ap) + 1; + va_end(ap); + // pass logmsg string to log parsing thread + /// qmsg=_strdup(buf); + qmsg=(char *) malloc(len * sizeof(char)); + if(!qmsg) + META_ERROR("malloc failed for logmsg to thread queue"); + else { + STRNCPY(qmsg, buf, len); + LogQueue->push(qmsg); + } + // usual passing to plugins/engine + CALL_PLUGIN_API_void(P_PRE, pfnAlertMessage, (atype, "%s", buf), engine_table); + CALL_ENGINE_API_void(pfnAlertMessage, (atype, "%s", buf)); + CALL_PLUGIN_API_void(P_POST, pfnAlertMessage, (atype, "%s", buf), engine_post_table); +#endif /* UNFINISHED */ + + // usual return. + RETURN_API_void() +} +#ifdef HLSDK_3_2_OLD_EIFACE +void mm_EngineFprintf(FILE *pfile, const char *szFmt, ...) { #else - #define MAKE_FORMATED_STRING(szFmt) \ - char buf[MAX_STRBUF_LEN]; \ - va_list ap; \ - va_start(ap, szFmt); \ - safevoid_vsnprintf(buf, sizeof(buf), szFmt, ap); \ - va_end(ap); - - #define CLEAN_FORMATED_STRING() +void mm_EngineFprintf(void *pfile, const char *szFmt, ...) { #endif - -// Engine routines, printf-style functions returning "void". -#define META_ENGINE_HANDLE_void_varargs(FN_TYPE, pfnName, pack_args_type, pfn_arg, fmt_arg) \ - MAKE_FORMATED_STRING(fmt_arg); \ - API_START_TSC_TRACKING(); \ - META_DEBUG(engine_info.pfnName.loglevel, ("In %s: fmt=%s", engine_info.pfnName.name, fmt_arg)); \ - API_PACK_ARGS(pack_args_type, (pfn_arg, "%s", buf)); \ - main_hook_function_void(offsetof(engine_info_t, pfnName), e_api_engine, offsetof(enginefuncs_t, pfnName), &packed_args); \ - API_END_TSC_TRACKING() \ - CLEAN_FORMATED_STRING() - -// Engine routines, printf-style functions returning an actual value. -#define META_ENGINE_HANDLE_varargs(ret_t, ret_init, FN_TYPE, pfnName, pack_args_type, pfn_arg, fmt_arg) \ - MAKE_FORMATED_STRING(fmt_arg); \ - API_START_TSC_TRACKING(); \ - META_DEBUG(engine_info.pfnName.loglevel, ("In %s: fmt=%s", engine_info.pfnName.name, fmt_arg)); \ - API_PACK_ARGS(pack_args_type, (pfn_arg, "%s", buf)); \ - class_ret_t ret_val(main_hook_function(class_ret_t((ret_t)ret_init), offsetof(engine_info_t, pfnName), e_api_engine, offsetof(enginefuncs_t, pfnName), &packed_args)); \ - API_END_TSC_TRACKING() \ - CLEAN_FORMATED_STRING() - - -int mm_PrecacheModel(const char *s) -{ - META_ENGINE_HANDLE(int, 0, FN_PRECACHEMODEL, pfnPrecacheModel, p, (s)); - RETURN_API(int) -} - -int mm_PrecacheSound(const char *s) -{ - META_ENGINE_HANDLE(int, 0, FN_PRECACHESOUND, pfnPrecacheSound, p, (s)); - RETURN_API(int) -} - -void mm_SetModel(edict_t *e, const char *m) -{ - META_ENGINE_HANDLE_void(FN_SETMODEL, pfnSetModel, 2p, (e, m)); + META_ENGINE_HANDLE_void_varargs(FN_ENGINEFPRINTF, pfnEngineFprintf, pfile, szFmt); RETURN_API_void() } -int mm_ModelIndex(const char *m) -{ - META_ENGINE_HANDLE(int, 0, FN_MODELINDEX, pfnModelIndex, p, (m)); - RETURN_API(int) +#ifdef HLSDK_3_2_OLD_EIFACE +void *mm_PvAllocEntPrivateData(edict_t *pEdict, long cb) { +#else +void *mm_PvAllocEntPrivateData(edict_t *pEdict, int32 cb) { +#endif + META_ENGINE_HANDLE(void *, NULL, FN_PVALLOCENTPRIVATEDATA, pfnPvAllocEntPrivateData, (pEdict, cb)); + RETURN_API() } - -int mm_ModelFrames(int modelIndex) -{ - META_ENGINE_HANDLE(int, 0, FN_MODELFRAMES, pfnModelFrames, i, (modelIndex)); - RETURN_API(int) +void *mm_PvEntPrivateData(edict_t *pEdict) { + META_ENGINE_HANDLE(void *, NULL, FN_PVENTPRIVATEDATA, pfnPvEntPrivateData, (pEdict)); + RETURN_API() } - -void mm_SetSize(edict_t *e, const float *rgflMin, const float *rgflMax) -{ - META_ENGINE_HANDLE_void(FN_SETSIZE, pfnSetSize, 3p, (e, rgflMin, rgflMax)); +void mm_FreeEntPrivateData(edict_t *pEdict) { + META_ENGINE_HANDLE_void(FN_FREEENTPRIVATEDATA, pfnFreeEntPrivateData, (pEdict)); RETURN_API_void() } -void mm_ChangeLevel(const char *s1, const char *s2) -{ - META_ENGINE_HANDLE_void(FN_CHANGELEVEL, pfnChangeLevel, 2p, (s1, s2)); - RETURN_API_void() +const char *mm_SzFromIndex(int iString) { + META_ENGINE_HANDLE(const char *, NULL, FN_SZFROMINDEX, pfnSzFromIndex, (iString)); + RETURN_API() } - -void mm_GetSpawnParms(edict_t *ent) -{ - META_ENGINE_HANDLE_void(FN_GETSPAWNPARMS, pfnGetSpawnParms, p, (ent)); - RETURN_API_void() -} - -void mm_SaveSpawnParms(edict_t *ent) -{ - META_ENGINE_HANDLE_void(FN_SAVESPAWNPARMS, pfnSaveSpawnParms, p, (ent)); - RETURN_API_void() -} - -float mm_VecToYaw(const float *rgflVector) -{ - META_ENGINE_HANDLE(float, 0.0, FN_VECTOYAW, pfnVecToYaw, p, (rgflVector)); - RETURN_API(float) -} - -void mm_VecToAngles(const float *rgflVectorIn, float *rgflVectorOut) -{ - META_ENGINE_HANDLE_void(FN_VECTOANGLES, pfnVecToAngles, 2p, (rgflVectorIn, rgflVectorOut)); - RETURN_API_void() -} - -void mm_MoveToOrigin(edict_t *ent, const float *pflGoal, float dist, int iMoveType) -{ - META_ENGINE_HANDLE_void(FN_MOVETOORIGIN, pfnMoveToOrigin, 2pfi, (ent, pflGoal, dist, iMoveType)); - RETURN_API_void() -} - -void mm_ChangeYaw(edict_t *ent) -{ - META_ENGINE_HANDLE_void(FN_CHANGEYAW, pfnChangeYaw, p, (ent)); - RETURN_API_void() -} - -void mm_ChangePitch(edict_t *ent) -{ - META_ENGINE_HANDLE_void(FN_CHANGEPITCH, pfnChangePitch, p, (ent)); - RETURN_API_void() -} - -edict_t *mm_FindEntityByString(edict_t *pEdictStartSearchAfter, const char *pszField, const char *pszValue) -{ - META_ENGINE_HANDLE(edict_t *, NULL, FN_FINDENTITYBYSTRING, pfnFindEntityByString, 3p, (pEdictStartSearchAfter, pszField, pszValue)); - RETURN_API(edict_t *) -} - -int mm_GetEntityIllum(edict_t *pEnt) -{ - META_ENGINE_HANDLE(int, 0, FN_GETENTITYILLUM, pfnGetEntityIllum, p, (pEnt)); - RETURN_API(int) -} - -edict_t *mm_FindEntityInSphere(edict_t *pEdictStartSearchAfter, const float *org, float rad) -{ - META_ENGINE_HANDLE(edict_t *, NULL, FN_FINDENTITYINSPHERE, pfnFindEntityInSphere, 2pf, (pEdictStartSearchAfter, org, rad)); - RETURN_API(edict_t *) -} - -edict_t *mm_FindClientInPVS(edict_t *pEdict) -{ - META_ENGINE_HANDLE(edict_t *, NULL, FN_FINDCLIENTINPVS, pfnFindClientInPVS, p, (pEdict)); - RETURN_API(edict_t *) -} - -edict_t *mm_EntitiesInPVS(edict_t *pplayer) -{ - META_ENGINE_HANDLE(edict_t *, NULL, FN_ENTITIESINPVS, pfnEntitiesInPVS, p, (pplayer)); - RETURN_API(edict_t *) -} - -void mm_MakeVectors(const float *rgflVector) -{ - META_ENGINE_HANDLE_void(FN_MAKEVECTORS, pfnMakeVectors, p, (rgflVector)); - RETURN_API_void() -} - -void mm_AngleVectors(const float *rgflVector, float *forward, float *right, float *up) -{ - META_ENGINE_HANDLE_void(FN_ANGLEVECTORS, pfnAngleVectors, 4p, (rgflVector, forward, right, up)); - RETURN_API_void() -} - -edict_t *mm_CreateEntity() -{ - META_ENGINE_HANDLE(edict_t *, NULL, FN_CREATEENTITY, pfnCreateEntity, void, (VOID_ARG)); - RETURN_API(edict_t *) -} - -void mm_RemoveEntity(edict_t *e) -{ - META_ENGINE_HANDLE_void(FN_REMOVEENTITY, pfnRemoveEntity, p, (e)); - RETURN_API_void() -} - -edict_t *mm_CreateNamedEntity(int className) -{ - META_ENGINE_HANDLE(edict_t *, NULL, FN_CREATENAMEDENTITY, pfnCreateNamedEntity, i, (className)); - RETURN_API(edict_t *) +int mm_AllocString(const char *szValue) { + META_ENGINE_HANDLE(int, 0, FN_ALLOCSTRING, pfnAllocString, (szValue)); + RETURN_API() } -void mm_MakeStatic(edict_t *ent) -{ - META_ENGINE_HANDLE_void(FN_MAKESTATIC, pfnMakeStatic, p, (ent)); - RETURN_API_void() +struct entvars_s *mm_GetVarsOfEnt(edict_t *pEdict) { + META_ENGINE_HANDLE(struct entvars_s *, NULL, FN_GETVARSOFENT, pfnGetVarsOfEnt, (pEdict)); + RETURN_API() } - -int mm_EntIsOnFloor(edict_t *e) -{ - META_ENGINE_HANDLE(int, 0, FN_ENTISONFLOOR, pfnEntIsOnFloor, p, (e)); - RETURN_API(int) +edict_t *mm_PEntityOfEntOffset(int iEntOffset) { + META_ENGINE_HANDLE(edict_t *, NULL, FN_PENTITYOFENTOFFSET, pfnPEntityOfEntOffset, (iEntOffset)); + RETURN_API() } - -int mm_DropToFloor(edict_t *e) -{ - META_ENGINE_HANDLE(int, 0, FN_DROPTOFLOOR, pfnDropToFloor, p, (e)); - RETURN_API(int) +int mm_EntOffsetOfPEntity(const edict_t *pEdict) { + META_ENGINE_HANDLE(int, 0, FN_ENTOFFSETOFPENTITY, pfnEntOffsetOfPEntity, (pEdict)); + RETURN_API() } - -int mm_WalkMove(edict_t *ent, float yaw, float dist, int iMode) -{ - META_ENGINE_HANDLE(int, 0, FN_WALKMOVE, pfnWalkMove, p2fi, (ent, yaw, dist, iMode)); - RETURN_API(int) +int mm_IndexOfEdict(const edict_t *pEdict) { + META_ENGINE_HANDLE(int, 0, FN_INDEXOFEDICT, pfnIndexOfEdict, (pEdict)); + RETURN_API() } - -void mm_SetOrigin(edict_t *e, const float *rgflOrigin) -{ - META_ENGINE_HANDLE_void(FN_SETORIGIN, pfnSetOrigin, 2p, (e, rgflOrigin)); - RETURN_API_void() +edict_t *mm_PEntityOfEntIndex(int iEntIndex) { + META_ENGINE_HANDLE(edict_t *, NULL, FN_PENTITYOFENTINDEX, pfnPEntityOfEntIndex, (iEntIndex)); + RETURN_API() } - -void mm_EmitSound(edict_t *entity, int channel, const char *sample, float volume, float attenuation, int fFlags, int pitch) -{ - META_ENGINE_HANDLE_void(FN_EMITSOUND, pfnEmitSound, pip2f2i, (entity, channel, sample, volume, attenuation, fFlags, pitch)); - RETURN_API_void() -} - -void mm_EmitAmbientSound(edict_t *entity, float *pos, const char *samp, float vol, float attenuation, int fFlags, int pitch) -{ - META_ENGINE_HANDLE_void(FN_EMITAMBIENTSOUND, pfnEmitAmbientSound, 3p2f2i, (entity, pos, samp, vol, attenuation, fFlags, pitch)); - RETURN_API_void() -} - -void mm_TraceLine(const float *v1, const float *v2, int fNoMonsters, edict_t *pentToSkip, TraceResult *ptr) -{ - META_ENGINE_HANDLE_void(FN_TRACELINE, pfnTraceLine, 2pi2p, (v1, v2, fNoMonsters, pentToSkip, ptr)); - RETURN_API_void() -} - -void mm_TraceToss(edict_t *pent, edict_t *pentToIgnore, TraceResult *ptr) -{ - META_ENGINE_HANDLE_void(FN_TRACETOSS, pfnTraceToss, 3p, (pent, pentToIgnore, ptr)); - RETURN_API_void() -} - -int mm_TraceMonsterHull(edict_t *pEdict, const float *v1, const float *v2, int fNoMonsters, edict_t *pentToSkip, TraceResult *ptr) -{ - META_ENGINE_HANDLE(int, 0, FN_TRACEMONSTERHULL, pfnTraceMonsterHull, 3pi2p, (pEdict, v1, v2, fNoMonsters, pentToSkip, ptr)); - RETURN_API(int) -} - -void mm_TraceHull(const float *v1, const float *v2, int fNoMonsters, int hullNumber, edict_t *pentToSkip, TraceResult *ptr) -{ - META_ENGINE_HANDLE_void(FN_TRACEHULL, pfnTraceHull, 2p2i2p, (v1, v2, fNoMonsters, hullNumber, pentToSkip, ptr)); - RETURN_API_void() -} - -void mm_TraceModel(const float *v1, const float *v2, int hullNumber, edict_t *pent, TraceResult *ptr) -{ - META_ENGINE_HANDLE_void(FN_TRACEMODEL, pfnTraceModel, 2pi2p, (v1, v2, hullNumber, pent, ptr)); - RETURN_API_void() -} - -const char *mm_TraceTexture(edict_t *pTextureEntity, const float *v1, const float *v2) -{ - META_ENGINE_HANDLE(const char *, NULL, FN_TRACETEXTURE, pfnTraceTexture, 3p, (pTextureEntity, v1, v2)); - RETURN_API(const char *) -} - -void mm_TraceSphere(const float *v1, const float *v2, int fNoMonsters, float radius, edict_t *pentToSkip, TraceResult *ptr) -{ - META_ENGINE_HANDLE_void(FN_TRACESPHERE, pfnTraceSphere, 2pif2p, (v1, v2, fNoMonsters, radius, pentToSkip, ptr)); - RETURN_API_void() -} - -void mm_GetAimVector(edict_t *ent, float speed, float *rgflReturn) -{ - META_ENGINE_HANDLE_void(FN_GETAIMVECTOR, pfnGetAimVector, pfp, (ent, speed, rgflReturn)); - RETURN_API_void() -} - -void mm_ServerCommand(char *str) -{ - META_ENGINE_HANDLE_void(FN_SERVERCOMMAND, pfnServerCommand, p, (str)); - RETURN_API_void() -} - -void mm_ServerExecute() -{ - META_ENGINE_HANDLE_void(FN_SERVEREXECUTE, pfnServerExecute, void, (VOID_ARG)); - RETURN_API_void() -} - -void mm_engClientCommand(edict_t *pEdict, char *szFmt, ...) -{ - META_ENGINE_HANDLE_void_varargs(FN_CLIENTCOMMAND_ENG, pfnClientCommand, 2pV, pEdict, szFmt); - RETURN_API_void() -} - -void mm_ParticleEffect(const float *org, const float *dir, float color, float count) -{ - META_ENGINE_HANDLE_void(FN_PARTICLEEFFECT, pfnParticleEffect, 2p2f, (org, dir, color, count)); - RETURN_API_void() -} - -void mm_LightStyle(int style, char *val) -{ - META_ENGINE_HANDLE_void(FN_LIGHTSTYLE, pfnLightStyle, ip, (style, val)); - RETURN_API_void() +edict_t *mm_FindEntityByVars(struct entvars_s *pvars) { + META_ENGINE_HANDLE(edict_t *, NULL, FN_FINDENTITYBYVARS, pfnFindEntityByVars, (pvars)); + RETURN_API() } - -int mm_DecalIndex(const char *name) -{ - META_ENGINE_HANDLE(int, 0, FN_DECALINDEX, pfnDecalIndex, p, (name)); - RETURN_API(int) -} - -int mm_PointContents(const float *rgflVector) -{ - META_ENGINE_HANDLE(int, 0, FN_POINTCONTENTS, pfnPointContents, p, (rgflVector)); - RETURN_API(int) -} - -void mm_MessageBegin(int msg_dest, int msg_type, const float *pOrigin, edict_t *ed) -{ - META_ENGINE_HANDLE_void(FN_MESSAGEBEGIN, pfnMessageBegin, 2i2p, (msg_dest, msg_type, pOrigin, ed)); - RETURN_API_void() -} - -void mm_MessageEnd() -{ - META_ENGINE_HANDLE_void(FN_MESSAGEEND, pfnMessageEnd, void, (VOID_ARG)); - RETURN_API_void() -} - -void mm_WriteByte(int iValue) -{ - META_ENGINE_HANDLE_void(FN_WRITEBYTE, pfnWriteByte, i, (iValue)); - RETURN_API_void() -} - -void mm_WriteChar(int iValue) -{ - META_ENGINE_HANDLE_void(FN_WRITECHAR, pfnWriteChar, i, (iValue)); - RETURN_API_void() -} - -void mm_WriteShort(int iValue) -{ - META_ENGINE_HANDLE_void(FN_WRITESHORT, pfnWriteShort, i, (iValue)); - RETURN_API_void() -} - -void mm_WriteLong(int iValue) -{ - META_ENGINE_HANDLE_void(FN_WRITELONG, pfnWriteLong, i, (iValue)); - RETURN_API_void() -} - -void mm_WriteAngle(float flValue) -{ - META_ENGINE_HANDLE_void(FN_WRITEANGLE, pfnWriteAngle, f, (flValue)); - RETURN_API_void() -} - -void mm_WriteCoord(float flValue) -{ - META_ENGINE_HANDLE_void(FN_WRITECOORD, pfnWriteCoord, f, (flValue)); - RETURN_API_void() -} - -void mm_WriteString(const char *sz) -{ - META_ENGINE_HANDLE_void(FN_WRITESTRING, pfnWriteString, p, (sz)); - RETURN_API_void() -} - -void mm_WriteEntity(int iValue) -{ - META_ENGINE_HANDLE_void(FN_WRITEENTITY, pfnWriteEntity, i, (iValue)); - RETURN_API_void() -} - -void mm_CVarRegister(cvar_t *pCvar) -{ - META_ENGINE_HANDLE_void(FN_CVARREGISTER, pfnCVarRegister, p, (pCvar)); - RETURN_API_void() -} - -float mm_CVarGetFloat(const char *szVarName) -{ - META_ENGINE_HANDLE(float, 0.0, FN_CVARGETFLOAT, pfnCVarGetFloat, p, (szVarName)); - RETURN_API(float) -} - -const char *mm_CVarGetString(const char *szVarName) -{ - META_ENGINE_HANDLE(const char *, NULL, FN_CVARGETSTRING, pfnCVarGetString, p, (szVarName)); - RETURN_API(const char *) -} - -void mm_CVarSetFloat(const char *szVarName, float flValue) -{ - META_ENGINE_HANDLE_void(FN_CVARSETFLOAT, pfnCVarSetFloat, pf, (szVarName, flValue)); - - meta_debug_value = (int)meta_debug.value; - - RETURN_API_void() -} - -void mm_CVarSetString(const char *szVarName, const char *szValue) -{ - META_ENGINE_HANDLE_void(FN_CVARSETSTRING, pfnCVarSetString, 2p, (szVarName, szValue)); - - meta_debug_value = (int)meta_debug.value; - - RETURN_API_void() -} - -void mm_AlertMessage(ALERT_TYPE atype, const char *szFmt, ...) -{ - META_ENGINE_HANDLE_void_varargs(FN_ALERTMESSAGE, pfnAlertMessage, ipV, atype, szFmt); - RETURN_API_void() -} - -void mm_EngineFprintf(void *pfile, const char *szFmt, ...) -{ - META_ENGINE_HANDLE_void_varargs(FN_ENGINEFPRINTF, pfnEngineFprintf, 2pV, pfile, szFmt); - RETURN_API_void() -} - -void *mm_PvAllocEntPrivateData(edict_t *pEdict, int32 cb) -{ - META_ENGINE_HANDLE(void *, NULL, FN_PVALLOCENTPRIVATEDATA, pfnPvAllocEntPrivateData, pi, (pEdict, cb)); - RETURN_API(void *) -} - -void *mm_PvEntPrivateData(edict_t *pEdict) -{ - META_ENGINE_HANDLE(void *, NULL, FN_PVENTPRIVATEDATA, pfnPvEntPrivateData, p, (pEdict)); - RETURN_API(void *) -} - -void mm_FreeEntPrivateData(edict_t *pEdict) -{ - META_ENGINE_HANDLE_void(FN_FREEENTPRIVATEDATA, pfnFreeEntPrivateData, p, (pEdict)); - RETURN_API_void() -} - -const char *mm_SzFromIndex(int iString) -{ - META_ENGINE_HANDLE(const char *, NULL, FN_SZFROMINDEX, pfnSzFromIndex, i, (iString)); - RETURN_API(const char *) -} - -int mm_AllocString(const char *szValue) -{ - META_ENGINE_HANDLE(int, 0, FN_ALLOCSTRING, pfnAllocString, p, (szValue)); - RETURN_API(int) -} - -struct entvars_s *mm_GetVarsOfEnt(edict_t *pEdict) -{ - META_ENGINE_HANDLE(struct entvars_s *, NULL, FN_GETVARSOFENT, pfnGetVarsOfEnt, p, (pEdict)); - RETURN_API(struct entvars_s *) -} - -edict_t *mm_PEntityOfEntOffset(int iEntOffset) -{ - META_ENGINE_HANDLE(edict_t *, NULL, FN_PENTITYOFENTOFFSET, pfnPEntityOfEntOffset, i, (iEntOffset)); - RETURN_API(edict_t *) -} - -int mm_EntOffsetOfPEntity(const edict_t *pEdict) -{ - META_ENGINE_HANDLE(int, 0, FN_ENTOFFSETOFPENTITY, pfnEntOffsetOfPEntity, p, (pEdict)); - RETURN_API(int) -} - -int mm_IndexOfEdict(const edict_t *pEdict) -{ - META_ENGINE_HANDLE(int, 0, FN_INDEXOFEDICT, pfnIndexOfEdict, p, (pEdict)); - RETURN_API(int) -} - -edict_t *mm_PEntityOfEntIndex(int iEntIndex) -{ - META_ENGINE_HANDLE(edict_t *, NULL, FN_PENTITYOFENTINDEX, pfnPEntityOfEntIndex, i, (iEntIndex)); - RETURN_API(edict_t *) -} - -edict_t *mm_FindEntityByVars(struct entvars_s *pvars) -{ - META_ENGINE_HANDLE(edict_t *, NULL, FN_FINDENTITYBYVARS, pfnFindEntityByVars, p, (pvars)); - RETURN_API(edict_t *) -} - -void *mm_GetModelPtr(edict_t *pEdict) -{ - META_ENGINE_HANDLE(void *, NULL, FN_GETMODELPTR, pfnGetModelPtr, p, (pEdict)); - RETURN_API(void *) +void *mm_GetModelPtr(edict_t *pEdict) { + META_ENGINE_HANDLE(void *, NULL, FN_GETMODELPTR, pfnGetModelPtr, (pEdict)); + RETURN_API() } -int mm_RegUserMsg(const char *pszName, int iSize) -{ +int mm_RegUserMsg(const char *pszName, int iSize) { int imsgid; MRegMsg *nmsg=NULL; - META_ENGINE_HANDLE(int, 0, FN_REGUSERMSG, pfnRegUserMsg, pi, (pszName, iSize)); + META_ENGINE_HANDLE(int, 0, FN_REGUSERMSG, pfnRegUserMsg, (pszName, iSize)); // Expand the macro, since we need to do extra work. - /// RETURN_API(int) - imsgid = GET_RET_CLASS(ret_val, int); - + /// RETURN_API() + if (--CALL_API_count>0) + /*Restore backup*/ + PublicMetaGlobals = backup_meta_globals; + if(status==MRES_OVERRIDE) { + META_DEBUG(loglevel, ("Returning (override) %s()", pfn_string)); + imsgid=override_ret; + } + else + imsgid=orig_ret; // Add the msgid, name, and size to our saved list, if we haven't // already. - nmsg=RegMsgs->find(imsgid); - if (nmsg) -{ - if (FStrEq(pszName, nmsg->name)) + nmsg=g_regMsgs->find(imsgid); + if(nmsg) { + if(FStrEq(pszName, nmsg->name)) // This name/msgid pair was already registered. META_DEBUG(3, ("user message registered again: name=%s, msgid=%d", pszName, imsgid)); else // This msgid was previously used by a different message name. - META_WARNING("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->name, pszName); } else - RegMsgs->add(pszName, imsgid, iSize); - - return imsgid; + g_regMsgs->add(pszName, imsgid, iSize); + return(imsgid); } -void mm_AnimationAutomove(const edict_t *pEdict, float flTime) -{ - META_ENGINE_HANDLE_void(FN_ANIMATIONAUTOMOVE, pfnAnimationAutomove, pf, (pEdict, flTime)); +void mm_AnimationAutomove(const edict_t *pEdict, float flTime) { + META_ENGINE_HANDLE_void(FN_ANIMATIONAUTOMOVE, pfnAnimationAutomove, (pEdict, flTime)); + RETURN_API_void() +} +void mm_GetBonePosition(const edict_t *pEdict, int iBone, float *rgflOrigin, float *rgflAngles ) { + META_ENGINE_HANDLE_void(FN_GETBONEPOSITION, pfnGetBonePosition, (pEdict, iBone, rgflOrigin, rgflAngles)); RETURN_API_void() } -void mm_GetBonePosition(const edict_t *pEdict, int iBone, float *rgflOrigin, float *rgflAngles) -{ - META_ENGINE_HANDLE_void(FN_GETBONEPOSITION, pfnGetBonePosition, pi2p, (pEdict, iBone, rgflOrigin, rgflAngles)); - RETURN_API_void() +#ifdef HLSDK_3_2_OLD_EIFACE +unsigned long mm_FunctionFromName( const char *pName ) { + META_ENGINE_HANDLE(unsigned long, 0, FN_FUNCTIONFROMNAME, pfnFunctionFromName, (pName)); +#else +uint32 mm_FunctionFromName( const char *pName ) { + META_ENGINE_HANDLE(uint32, 0, FN_FUNCTIONFROMNAME, pfnFunctionFromName, (pName)); +#endif + RETURN_API() } - -uint32 mm_FunctionFromName(const char *pName) -{ - META_ENGINE_HANDLE(uint32, 0, FN_FUNCTIONFROMNAME, pfnFunctionFromName, p, (pName)); - RETURN_API(uint32) -} - -const char *mm_NameForFunction(uint32 function) -{ - META_ENGINE_HANDLE(const char *, NULL, FN_NAMEFORFUNCTION, pfnNameForFunction, ui, (function)); - RETURN_API(const char *) +#ifdef HLSDK_3_2_OLD_EIFACE +const char *mm_NameForFunction( unsigned long function ) { +#else +const char *mm_NameForFunction( uint32 function ) { +#endif + META_ENGINE_HANDLE(const char *, NULL, FN_NAMEFORFUNCTION, pfnNameForFunction, (function)); + RETURN_API() } //! JOHN: engine callbacks so game DLL can print messages to individual clients -void mm_ClientPrintf(edict_t *pEdict, PRINT_TYPE ptype, const char *szMsg) -{ - META_ENGINE_HANDLE_void(FN_CLIENTPRINTF, pfnClientPrintf, pip, (pEdict, ptype, szMsg)); +void mm_ClientPrintf( edict_t *pEdict, PRINT_TYPE ptype, const char *szMsg ) { + META_ENGINE_HANDLE_void(FN_CLIENTPRINTF, pfnClientPrintf, (pEdict, ptype, szMsg)); RETURN_API_void() } - -void mm_ServerPrint(const char *szMsg) -{ - META_ENGINE_HANDLE_void(FN_SERVERPRINT, pfnServerPrint, p, (szMsg)); +void mm_ServerPrint( const char *szMsg ) { + META_ENGINE_HANDLE_void(FN_SERVERPRINT, pfnServerPrint, (szMsg)); RETURN_API_void() } //! these 3 added so game DLL can easily access client 'cmd' strings -const char *mm_Cmd_Args(void) -{ - META_ENGINE_HANDLE(const char *, NULL, FN_CMD_ARGS, pfnCmd_Args, void, (VOID_ARG)); - RETURN_API(const char *) +const char *mm_Cmd_Args( void ) { + META_ENGINE_HANDLE(const char *, NULL, FN_CMD_ARGS, pfnCmd_Args, ()); + RETURN_API() +} +const char *mm_Cmd_Argv( int argc ) { + META_ENGINE_HANDLE(const char *, NULL, FN_CMD_ARGV, pfnCmd_Argv, (argc)); + RETURN_API() +} +int mm_Cmd_Argc( void ) { + META_ENGINE_HANDLE(int, 0, FN_CMD_ARGC, pfnCmd_Argc, ()); + RETURN_API() } -const char *mm_Cmd_Argv(int argc) -{ - META_ENGINE_HANDLE(const char *, NULL, FN_CMD_ARGV, pfnCmd_Argv, i, (argc)); - RETURN_API(const char *) -} - -int mm_Cmd_Argc(void) -{ - META_ENGINE_HANDLE(int, 0, FN_CMD_ARGC, pfnCmd_Argc, void, (VOID_ARG)); - RETURN_API(int) -} - -void mm_GetAttachment(const edict_t *pEdict, int iAttachment, float *rgflOrigin, float *rgflAngles) -{ - META_ENGINE_HANDLE_void(FN_GETATTACHMENT, pfnGetAttachment, pi2p, (pEdict, iAttachment, rgflOrigin, rgflAngles)); +void mm_GetAttachment(const edict_t *pEdict, int iAttachment, float *rgflOrigin, float *rgflAngles ) { + META_ENGINE_HANDLE_void(FN_GETATTACHMENT, pfnGetAttachment, (pEdict, iAttachment, rgflOrigin, rgflAngles)); RETURN_API_void() } -void mm_CRC32_Init(CRC32_t *pulCRC) -{ - META_ENGINE_HANDLE_void(FN_CRC32_INIT, pfnCRC32_Init, p, (pulCRC)); +void mm_CRC32_Init(CRC32_t *pulCRC) { + META_ENGINE_HANDLE_void(FN_CRC32_INIT, pfnCRC32_Init, (pulCRC)); + RETURN_API_void() +} +void mm_CRC32_ProcessBuffer(CRC32_t *pulCRC, void *p, int len) { + META_ENGINE_HANDLE_void(FN_CRC32_PROCESSBUFFER, pfnCRC32_ProcessBuffer, (pulCRC, p, len)); + RETURN_API_void() +} +void mm_CRC32_ProcessByte(CRC32_t *pulCRC, unsigned char ch) { + META_ENGINE_HANDLE_void(FN_CRC32_PROCESSBYTE, pfnCRC32_ProcessByte, (pulCRC, ch)); + RETURN_API_void() +} +CRC32_t mm_CRC32_Final(CRC32_t pulCRC) { + META_ENGINE_HANDLE(CRC32_t, 0, FN_CRC32_FINAL, pfnCRC32_Final, (pulCRC)); + RETURN_API() +} + +#ifdef HLSDK_3_2_OLD_EIFACE +long mm_RandomLong(long lLow, long lHigh) { + META_ENGINE_HANDLE(long, 0, FN_RANDOMLONG, pfnRandomLong, (lLow, lHigh)); +#else +int32 mm_RandomLong(int32 lLow, int32 lHigh) { + META_ENGINE_HANDLE(int32, 0, FN_RANDOMLONG, pfnRandomLong, (lLow, lHigh)); +#endif + RETURN_API() +} +float mm_RandomFloat(float flLow, float flHigh) { + META_ENGINE_HANDLE(float, 0.0, FN_RANDOMFLOAT, pfnRandomFloat, (flLow, flHigh)); + RETURN_API() +} + +void mm_SetView(const edict_t *pClient, const edict_t *pViewent ) { + META_ENGINE_HANDLE_void(FN_SETVIEW, pfnSetView, (pClient, pViewent)); + RETURN_API_void() +} +float mm_Time( void ) { + META_ENGINE_HANDLE(float, 0.0, FN_TIME, pfnTime, ()); + RETURN_API() +} +void mm_CrosshairAngle(const edict_t *pClient, float pitch, float yaw) { + META_ENGINE_HANDLE_void(FN_CROSSHAIRANGLE, pfnCrosshairAngle, (pClient, pitch, yaw)); RETURN_API_void() } -void mm_CRC32_ProcessBuffer(CRC32_t *pulCRC, void *p, int len) -{ - META_ENGINE_HANDLE_void(FN_CRC32_PROCESSBUFFER, pfnCRC32_ProcessBuffer, 2pi, (pulCRC, p, len)); - RETURN_API_void() +byte * mm_LoadFileForMe(char *filename, int *pLength) { + META_ENGINE_HANDLE(byte *, NULL, FN_LOADFILEFORME, pfnLoadFileForMe, (filename, pLength)); + RETURN_API() } - -void mm_CRC32_ProcessByte(CRC32_t *pulCRC, unsigned char ch) -{ - META_ENGINE_HANDLE_void(FN_CRC32_PROCESSBYTE, pfnCRC32_ProcessByte, puc, (pulCRC, ch)); - RETURN_API_void() -} - -CRC32_t mm_CRC32_Final(CRC32_t pulCRC) -{ - META_ENGINE_HANDLE(CRC32_t, 0, FN_CRC32_FINAL, pfnCRC32_Final, ul, (pulCRC)); - RETURN_API(CRC32_t) -} - -int32 mm_RandomLong(int32 lLow, int32 lHigh) -{ - META_ENGINE_HANDLE(int32, 0, FN_RANDOMLONG, pfnRandomLong, 2i, (lLow, lHigh)); - RETURN_API(int32) -} - -float mm_RandomFloat(float flLow, float flHigh) -{ - META_ENGINE_HANDLE(float, 0.0, FN_RANDOMFLOAT, pfnRandomFloat, 2f, (flLow, flHigh)); - RETURN_API(float) -} - -void mm_SetView(const edict_t *pClient, const edict_t *pViewent) -{ - META_ENGINE_HANDLE_void(FN_SETVIEW, pfnSetView, 2p, (pClient, pViewent)); - RETURN_API_void() -} - -float mm_Time(void) -{ - META_ENGINE_HANDLE(float, 0.0, FN_TIME, pfnTime, void, (VOID_ARG)); - RETURN_API(float) -} - -void mm_CrosshairAngle(const edict_t *pClient, float pitch, float yaw) -{ - META_ENGINE_HANDLE_void(FN_CROSSHAIRANGLE, pfnCrosshairAngle, p2f, (pClient, pitch, yaw)); - RETURN_API_void() -} - -byte *mm_LoadFileForMe(char *filename, int *pLength) -{ - META_ENGINE_HANDLE(byte *, NULL, FN_LOADFILEFORME, pfnLoadFileForMe, 2p, (filename, pLength)); - RETURN_API(byte *) -} - -void mm_FreeFile(void *buffer) -{ - META_ENGINE_HANDLE_void(FN_FREEFILE, pfnFreeFile, p, (buffer)); +void mm_FreeFile(void *buffer) { + META_ENGINE_HANDLE_void(FN_FREEFILE, pfnFreeFile, (buffer)); RETURN_API_void() } //! trigger_endsection -void mm_EndSection(const char *pszSectionName) -{ - META_ENGINE_HANDLE_void(FN_ENDSECTION, pfnEndSection, p, (pszSectionName)); +void mm_EndSection(const char *pszSectionName) { + META_ENGINE_HANDLE_void(FN_ENDSECTION, pfnEndSection, (pszSectionName)); RETURN_API_void() } - -int mm_CompareFileTime(char *filename1, char *filename2, int *iCompare) -{ - META_ENGINE_HANDLE(int, 0, FN_COMPAREFILETIME, pfnCompareFileTime, 3p, (filename1, filename2, iCompare)); - RETURN_API(int) +int mm_CompareFileTime(char *filename1, char *filename2, int *iCompare) { + META_ENGINE_HANDLE(int, 0, FN_COMPAREFILETIME, pfnCompareFileTime, (filename1, filename2, iCompare)); + RETURN_API() } - -void mm_GetGameDir(char *szGetGameDir) -{ - META_ENGINE_HANDLE_void(FN_GETGAMEDIR, pfnGetGameDir, p, (szGetGameDir)); +void mm_GetGameDir(char *szGetGameDir) { + META_ENGINE_HANDLE_void(FN_GETGAMEDIR, pfnGetGameDir, (szGetGameDir)); RETURN_API_void() } - -void mm_Cvar_RegisterVariable(cvar_t *variable) -{ - META_ENGINE_HANDLE_void(FN_CVAR_REGISTERVARIABLE, pfnCvar_RegisterVariable, p, (variable)); +void mm_Cvar_RegisterVariable(cvar_t *variable) { + META_ENGINE_HANDLE_void(FN_CVAR_REGISTERVARIABLE, pfnCvar_RegisterVariable, (variable)); RETURN_API_void() } - -void mm_FadeClientVolume(const edict_t *pEdict, int fadePercent, int fadeOutSeconds, int holdTime, int fadeInSeconds) -{ - META_ENGINE_HANDLE_void(FN_FADECLIENTVOLUME, pfnFadeClientVolume, p4i, (pEdict, fadePercent, fadeOutSeconds, holdTime, fadeInSeconds)); +void mm_FadeClientVolume(const edict_t *pEdict, int fadePercent, int fadeOutSeconds, int holdTime, int fadeInSeconds) { + META_ENGINE_HANDLE_void(FN_FADECLIENTVOLUME, pfnFadeClientVolume, (pEdict, fadePercent, fadeOutSeconds, holdTime, fadeInSeconds)); RETURN_API_void() } - -void mm_SetClientMaxspeed(edict_t *pEdict, float fNewMaxspeed) -{ - META_ENGINE_HANDLE_void(FN_SETCLIENTMAXSPEED, pfnSetClientMaxspeed, pf, (pEdict, fNewMaxspeed)); +void mm_SetClientMaxspeed(edict_t *pEdict, float fNewMaxspeed) { + META_ENGINE_HANDLE_void(FN_SETCLIENTMAXSPEED, pfnSetClientMaxspeed, (pEdict, fNewMaxspeed)); RETURN_API_void() } - //! returns NULL if fake client can't be created -edict_t *mm_CreateFakeClient(const char *netname) -{ - META_ENGINE_HANDLE(edict_t *, NULL, FN_CREATEFAKECLIENT, pfnCreateFakeClient, p, (netname)); - RETURN_API(edict_t *) +edict_t * mm_CreateFakeClient(const char *netname) { + META_ENGINE_HANDLE(edict_t *, NULL, FN_CREATEFAKECLIENT, pfnCreateFakeClient, (netname)); + RETURN_API() } - -void mm_RunPlayerMove(edict_t *fakeclient, const float *viewangles, float forwardmove, float sidemove, float upmove, unsigned short buttons, byte impulse, byte msec) -{ - META_ENGINE_HANDLE_void(FN_RUNPLAYERMOVE, pfnRunPlayerMove, 2p3fus2uc, (fakeclient, viewangles, forwardmove, sidemove, upmove, buttons, impulse, msec)); +void mm_RunPlayerMove(edict_t *fakeclient, const float *viewangles, float forwardmove, float sidemove, float upmove, unsigned short buttons, byte impulse, byte msec ) { + META_ENGINE_HANDLE_void(FN_RUNPLAYERMOVE, pfnRunPlayerMove, (fakeclient, viewangles, forwardmove, sidemove, upmove, buttons, impulse, msec)); RETURN_API_void() } - -int mm_NumberOfEntities() -{ - META_ENGINE_HANDLE(int, 0, FN_NUMBEROFENTITIES, pfnNumberOfEntities, void, (VOID_ARG)); - RETURN_API(int) +int mm_NumberOfEntities(void) { + META_ENGINE_HANDLE(int, 0, FN_NUMBEROFENTITIES, pfnNumberOfEntities, ()); + RETURN_API() } //! passing in NULL gets the serverinfo -char *mm_GetInfoKeyBuffer(edict_t *e) -{ - META_ENGINE_HANDLE(char *, NULL, FN_GETINFOKEYBUFFER, pfnGetInfoKeyBuffer, p, (e)); - RETURN_API(char *) +char *mm_GetInfoKeyBuffer(edict_t *e) { + META_ENGINE_HANDLE(char *, NULL, FN_GETINFOKEYBUFFER, pfnGetInfoKeyBuffer, (e)); + RETURN_API() } - -char *mm_InfoKeyValue(char *infobuffer, const char *key) -{ - META_ENGINE_HANDLE(char *, NULL, FN_INFOKEYVALUE, pfnInfoKeyValue, 2p, (infobuffer, key)); - RETURN_API(char *) +char *mm_InfoKeyValue(char *infobuffer, const char *key) { + META_ENGINE_HANDLE(char *, NULL, FN_INFOKEYVALUE, pfnInfoKeyValue, (infobuffer, key)); + RETURN_API() } - -void mm_SetKeyValue(char *infobuffer, const char *key, const char *value) -{ - META_ENGINE_HANDLE_void(FN_SETKEYVALUE, pfnSetKeyValue, 3p, (infobuffer, key, value)); +void mm_SetKeyValue(char *infobuffer, const char *key, const char *value) { + META_ENGINE_HANDLE_void(FN_SETKEYVALUE, pfnSetKeyValue, (infobuffer, key, value)); + RETURN_API_void() +} +void mm_SetClientKeyValue(int clientIndex, char *infobuffer, const char *key, const char *value) { + META_ENGINE_HANDLE_void(FN_SETCLIENTKEYVALUE, pfnSetClientKeyValue, (clientIndex, infobuffer, key, value)); RETURN_API_void() } -void mm_SetClientKeyValue(int clientIndex, char *infobuffer, const char *key, const char *value) -{ - META_ENGINE_HANDLE_void(FN_SETCLIENTKEYVALUE, pfnSetClientKeyValue, i3p, (clientIndex, infobuffer, key, value)); +int mm_IsMapValid(char *filename) { + META_ENGINE_HANDLE(int, 0, FN_ISMAPVALID, pfnIsMapValid, (filename)); + RETURN_API() +} +void mm_StaticDecal( const float *origin, int decalIndex, int entityIndex, int modelIndex ) { + META_ENGINE_HANDLE_void(FN_STATICDECAL, pfnStaticDecal, (origin, decalIndex, entityIndex, modelIndex)); RETURN_API_void() } - -int mm_IsMapValid(char *filename) -{ - META_ENGINE_HANDLE(int, 0, FN_ISMAPVALID, pfnIsMapValid, p, (filename)); - RETURN_API(int) +int mm_PrecacheGeneric(char *s) { + META_ENGINE_HANDLE(int, 0, FN_PRECACHEGENERIC, pfnPrecacheGeneric, (s)); + RETURN_API() } - -void mm_StaticDecal(const float *origin, int decalIndex, int entityIndex, int modelIndex) -{ - META_ENGINE_HANDLE_void(FN_STATICDECAL, pfnStaticDecal, p3i, (origin, decalIndex, entityIndex, modelIndex)); - RETURN_API_void() -} - -int mm_PrecacheGeneric(char *s) -{ - META_ENGINE_HANDLE(int, 0, FN_PRECACHEGENERIC, pfnPrecacheGeneric, p, (s)); - RETURN_API(int) -} - //! returns the server assigned userid for this player. useful for logging frags, etc. returns -1 if the edict couldn't be found in the list of clients -int mm_GetPlayerUserId(edict_t *e) -{ - META_ENGINE_HANDLE(int, 0, FN_GETPLAYERUSERID, pfnGetPlayerUserId, p, (e)); - RETURN_API(int) +int mm_GetPlayerUserId(edict_t *e ) { + META_ENGINE_HANDLE(int, 0, FN_GETPLAYERUSERID, pfnGetPlayerUserId, (e)); + RETURN_API() } - -void mm_BuildSoundMsg(edict_t *entity, int channel, const char *sample, float volume, float attenuation, int fFlags, int pitch, int msg_dest, int msg_type, const float *pOrigin, edict_t *ed) +void mm_BuildSoundMsg(edict_t *entity, int channel, const char *sample, /*int*/float volume, float attenuation, int fFlags, int pitch, int msg_dest, int msg_type, const float *pOrigin, edict_t *ed) { - META_ENGINE_HANDLE_void(FN_BUILDSOUNDMSG, pfnBuildSoundMsg, pip2f4i2p, (entity, channel, sample, volume, attenuation, fFlags, pitch, msg_dest, msg_type, pOrigin, ed)); + META_ENGINE_HANDLE_void(FN_BUILDSOUNDMSG, pfnBuildSoundMsg, (entity, channel, sample, volume, attenuation, fFlags, pitch, msg_dest, msg_type, pOrigin, ed)); RETURN_API_void() } - //! is this a dedicated server? -int mm_IsDedicatedServer() -{ - META_ENGINE_HANDLE(int, 0, FN_ISDEDICATEDSERVER, pfnIsDedicatedServer, void, (VOID_ARG)); - RETURN_API(int) +int mm_IsDedicatedServer(void) { + META_ENGINE_HANDLE(int, 0, FN_ISDEDICATEDSERVER, pfnIsDedicatedServer, ()); + RETURN_API() } - -cvar_t *mm_CVarGetPointer(const char *szVarName) -{ - META_ENGINE_HANDLE(cvar_t *, NULL, FN_CVARGETPOINTER, pfnCVarGetPointer, p, (szVarName)); - RETURN_API(cvar_t *) +cvar_t *mm_CVarGetPointer(const char *szVarName) { + META_ENGINE_HANDLE(cvar_t *, NULL, FN_CVARGETPOINTER, pfnCVarGetPointer, (szVarName)); + RETURN_API() } - //! returns the server assigned WONid for this player. useful for logging frags, etc. returns -1 if the edict couldn't be found in the list of clients -unsigned int mm_GetPlayerWONId(edict_t *e) -{ - META_ENGINE_HANDLE(unsigned int, 0, FN_GETPLAYERWONID, pfnGetPlayerWONId, p, (e)); - RETURN_API(unsigned int) +unsigned int mm_GetPlayerWONId(edict_t *e) { + META_ENGINE_HANDLE(unsigned int, 0, FN_GETPLAYERWONID, pfnGetPlayerWONId, (e)); + RETURN_API() } //! YWB 8/1/99 TFF Physics additions -void mm_Info_RemoveKey(char *s, const char *key) +void mm_Info_RemoveKey( char *s, const char *key ) { + META_ENGINE_HANDLE_void(FN_INFO_REMOVEKEY, pfnInfo_RemoveKey, (s, key)); + RETURN_API_void() +} +const char *mm_GetPhysicsKeyValue( const edict_t *pClient, const char *key ) { + META_ENGINE_HANDLE(const char *, NULL, FN_GETPHYSICSKEYVALUE, pfnGetPhysicsKeyValue, (pClient, key)); + RETURN_API() +} +void mm_SetPhysicsKeyValue( const edict_t *pClient, const char *key, const char *value ) { + META_ENGINE_HANDLE_void(FN_SETPHYSICSKEYVALUE, pfnSetPhysicsKeyValue, (pClient, key, value)); + RETURN_API_void() +} +const char *mm_GetPhysicsInfoString( const edict_t *pClient ) { + META_ENGINE_HANDLE(const char *, NULL, FN_GETPHYSICSINFOSTRING, pfnGetPhysicsInfoString, (pClient)); + RETURN_API() +} +unsigned short mm_PrecacheEvent( int type, const char *psz ) { + META_ENGINE_HANDLE(unsigned short, 0, FN_PRECACHEEVENT, pfnPrecacheEvent, (type, psz)); + RETURN_API() +} +void mm_PlaybackEvent( int flags, const edict_t *pInvoker, unsigned short eventindex, float delay, float *origin, float *angles, float fparam1, float fparam2, int iparam1, int iparam2, int bparam1, int bparam2 ) { - META_ENGINE_HANDLE_void(FN_INFO_REMOVEKEY, pfnInfo_RemoveKey, 2p, (s, key)); + META_ENGINE_HANDLE_void(FN_PLAYBACKEVENT, pfnPlaybackEvent, (flags, pInvoker, eventindex, delay, origin, angles, fparam1, fparam2, iparam1, iparam2, bparam1, bparam2)); RETURN_API_void() } -const char *mm_GetPhysicsKeyValue(const edict_t *pClient, const char *key) -{ - META_ENGINE_HANDLE(const char *, NULL, FN_GETPHYSICSKEYVALUE, pfnGetPhysicsKeyValue, 2p, (pClient, key)); - RETURN_API(const char *) +unsigned char *mm_SetFatPVS( float *org ) { + META_ENGINE_HANDLE(unsigned char *, 0, FN_SETFATPVS, pfnSetFatPVS, (org)); + RETURN_API() +} +unsigned char *mm_SetFatPAS( float *org ) { + META_ENGINE_HANDLE(unsigned char *, 0, FN_SETFATPAS, pfnSetFatPAS, (org)); + RETURN_API() } -void mm_SetPhysicsKeyValue(const edict_t *pClient, const char *key, const char *value) -{ - META_ENGINE_HANDLE_void(FN_SETPHYSICSKEYVALUE, pfnSetPhysicsKeyValue, 3p, (pClient, key, value)); +int mm_CheckVisibility( edict_t *entity, unsigned char *pset ) { + META_ENGINE_HANDLE(int, 0, FN_CHECKVISIBILITY, pfnCheckVisibility, (entity, pset)); + RETURN_API() +} + +void mm_DeltaSetField( struct delta_s *pFields, const char *fieldname ) { + META_ENGINE_HANDLE_void(FN_DELTASETFIELD, pfnDeltaSetField, (pFields, fieldname)); + RETURN_API_void() +} +void mm_DeltaUnsetField( struct delta_s *pFields, const char *fieldname ) { + META_ENGINE_HANDLE_void(FN_DELTAUNSETFIELD, pfnDeltaUnsetField, (pFields, fieldname)); + RETURN_API_void() +} +void mm_DeltaAddEncoder( char *name, void (*conditionalencode)( struct delta_s *pFields, const unsigned char *from, const unsigned char *to ) ) { + META_ENGINE_HANDLE_void(FN_DELTAADDENCODER, pfnDeltaAddEncoder, (name, conditionalencode)); + RETURN_API_void() +} +int mm_GetCurrentPlayer( void ) { + META_ENGINE_HANDLE(int, 0, FN_GETCURRENTPLAYER, pfnGetCurrentPlayer, ()); + RETURN_API() +} +int mm_CanSkipPlayer( const edict_t *player ) { + META_ENGINE_HANDLE(int, 0, FN_CANSKIPPLAYER, pfnCanSkipPlayer, (player)); + RETURN_API() +} +int mm_DeltaFindField( struct delta_s *pFields, const char *fieldname ) { + META_ENGINE_HANDLE(int, 0, FN_DELTAFINDFIELD, pfnDeltaFindField, (pFields, fieldname)); + RETURN_API() +} +void mm_DeltaSetFieldByIndex( struct delta_s *pFields, int fieldNumber ) { + META_ENGINE_HANDLE_void(FN_DELTASETFIELDBYINDEX, pfnDeltaSetFieldByIndex, (pFields, fieldNumber)); + RETURN_API_void() +} +void mm_DeltaUnsetFieldByIndex( struct delta_s *pFields, int fieldNumber ) { + META_ENGINE_HANDLE_void(FN_DELTAUNSETFIELDBYINDEX, pfnDeltaUnsetFieldByIndex, (pFields, fieldNumber)); RETURN_API_void() } -const char *mm_GetPhysicsInfoString(const edict_t *pClient) -{ - META_ENGINE_HANDLE(const char *, NULL, FN_GETPHYSICSINFOSTRING, pfnGetPhysicsInfoString, p, (pClient)); - RETURN_API(const char *) -} - -unsigned short mm_PrecacheEvent(int type, const char *psz) -{ - META_ENGINE_HANDLE(unsigned short, 0, FN_PRECACHEEVENT, pfnPrecacheEvent, ip, (type, psz)); - RETURN_API(unsigned short) -} - -void mm_PlaybackEvent(int flags, const edict_t *pInvoker, unsigned short eventindex, float delay, float *origin, float *angles, float fparam1, float fparam2, int iparam1, int iparam2, int bparam1, int bparam2) -{ - META_ENGINE_HANDLE_void(FN_PLAYBACKEVENT, pfnPlaybackEvent, ipusf2p2f4i, (flags, pInvoker, eventindex, delay, origin, angles, fparam1, fparam2, iparam1, iparam2, bparam1, bparam2)); +void mm_SetGroupMask( int mask, int op ) { + META_ENGINE_HANDLE_void(FN_SETGROUPMASK, pfnSetGroupMask, (mask, op)); RETURN_API_void() } -unsigned char *mm_SetFatPVS(float *org) -{ - META_ENGINE_HANDLE(unsigned char *, 0, FN_SETFATPVS, pfnSetFatPVS, p, (org)); - RETURN_API(unsigned char *) +int mm_engCreateInstancedBaseline( int classname, struct entity_state_s *baseline ) { + META_ENGINE_HANDLE(int, 0, FN_CREATEINSTANCEDBASELINE, pfnCreateInstancedBaseline, (classname, baseline)); + RETURN_API() } - -unsigned char *mm_SetFatPAS(float *org) -{ - META_ENGINE_HANDLE(unsigned char *, 0, FN_SETFATPAS, pfnSetFatPAS, p, (org)); - RETURN_API(unsigned char *) -} - -int mm_CheckVisibility(edict_t *entity, unsigned char *pset) -{ - META_ENGINE_HANDLE(int, 0, FN_CHECKVISIBILITY, pfnCheckVisibility, 2p, (entity, pset)); - RETURN_API(int) -} - -void mm_DeltaSetField(struct delta_s *pFields, const char *fieldname) -{ - META_ENGINE_HANDLE_void(FN_DELTASETFIELD, pfnDeltaSetField, 2p, (pFields, fieldname)); - RETURN_API_void() -} - -void mm_DeltaUnsetField(struct delta_s *pFields, const char *fieldname) -{ - META_ENGINE_HANDLE_void(FN_DELTAUNSETFIELD, pfnDeltaUnsetField, 2p, (pFields, fieldname)); - RETURN_API_void() -} - -void mm_DeltaAddEncoder(char *name, void (*conditionalencode)(struct delta_s *pFields, const unsigned char *from, const unsigned char *to)) -{ - META_ENGINE_HANDLE_void(FN_DELTAADDENCODER, pfnDeltaAddEncoder, 2p, (name, (void*)conditionalencode)); - RETURN_API_void() -} - -int mm_GetCurrentPlayer(void) -{ - META_ENGINE_HANDLE(int, 0, FN_GETCURRENTPLAYER, pfnGetCurrentPlayer, void, (VOID_ARG)); - RETURN_API(int) -} - -int mm_CanSkipPlayer(const edict_t *player) -{ - META_ENGINE_HANDLE(int, 0, FN_CANSKIPPLAYER, pfnCanSkipPlayer, p, (player)); - RETURN_API(int) -} - -int mm_DeltaFindField(struct delta_s *pFields, const char *fieldname) -{ - META_ENGINE_HANDLE(int, 0, FN_DELTAFINDFIELD, pfnDeltaFindField, 2p, (pFields, fieldname)); - RETURN_API(int) -} - -void mm_DeltaSetFieldByIndex(struct delta_s *pFields, int fieldNumber) -{ - META_ENGINE_HANDLE_void(FN_DELTASETFIELDBYINDEX, pfnDeltaSetFieldByIndex, pi, (pFields, fieldNumber)); - RETURN_API_void() -} - -void mm_DeltaUnsetFieldByIndex(struct delta_s *pFields, int fieldNumber) -{ - META_ENGINE_HANDLE_void(FN_DELTAUNSETFIELDBYINDEX, pfnDeltaUnsetFieldByIndex, pi, (pFields, fieldNumber)); - RETURN_API_void() -} - -void mm_SetGroupMask(int mask, int op) -{ - META_ENGINE_HANDLE_void(FN_SETGROUPMASK, pfnSetGroupMask, 2i, (mask, op)); - RETURN_API_void() -} - -int mm_engCreateInstancedBaseline(int classname, struct entity_state_s *baseline) -{ - META_ENGINE_HANDLE(int, 0, FN_CREATEINSTANCEDBASELINE, pfnCreateInstancedBaseline, ip, (classname, baseline)); - RETURN_API(int) -} - -void mm_Cvar_DirectSet(struct cvar_s *var, const char *value) -{ - META_ENGINE_HANDLE_void(FN_CVAR_DIRECTSET, pfnCvar_DirectSet, 2p, (var, value)); - - meta_debug_value = (int)meta_debug.value; - +void mm_Cvar_DirectSet( struct cvar_s *var, const char *value ) { + META_ENGINE_HANDLE_void(FN_CVAR_DIRECTSET, pfnCvar_DirectSet, (var, value)); RETURN_API_void() } //! Forces the client and server to be running with the same version of the specified file -//!(e.g., a player model). +//!( e.g., a player model ). //! Calling this has no effect in single player -void mm_ForceUnmodified(FORCE_TYPE type, float *mins, float *maxs, const char *filename) -{ - META_ENGINE_HANDLE_void(FN_FORCEUNMODIFIED, pfnForceUnmodified, i3p, (type, mins, maxs, filename)); +void mm_ForceUnmodified( FORCE_TYPE type, float *mins, float *maxs, const char *filename ) { + META_ENGINE_HANDLE_void(FN_FORCEUNMODIFIED, pfnForceUnmodified, (type, mins, maxs, filename)); RETURN_API_void() } -void mm_GetPlayerStats(const edict_t *pClient, int *ping, int *packet_loss) -{ - META_ENGINE_HANDLE_void(FN_GETPLAYERSTATS, pfnGetPlayerStats, 3p, (pClient, ping, packet_loss)); +void mm_GetPlayerStats( const edict_t *pClient, int *ping, int *packet_loss ) { + META_ENGINE_HANDLE_void(FN_GETPLAYERSTATS, pfnGetPlayerStats, (pClient, ping, packet_loss)); RETURN_API_void() } -void mm_AddServerCommand(char *cmd_name, void (*function) ()) -{ - META_ENGINE_HANDLE_void(FN_ADDSERVERCOMMAND, pfnAddServerCommand, 2p, (cmd_name, (void*)function)); +void mm_AddServerCommand( char *cmd_name, void (*function) (void) ) { + META_ENGINE_HANDLE_void(FN_ADDSERVERCOMMAND, pfnAddServerCommand, (cmd_name, function)); RETURN_API_void() } +// Added in SDK 2.2: + //! For voice communications, set which clients hear eachother. //! NOTE: these functions take player entity indices (starting at 1). -qboolean mm_Voice_GetClientListening(int iReceiver, int iSender) -{ - META_ENGINE_HANDLE(qboolean, false, FN_VOICE_GETCLIENTLISTENING, pfnVoice_GetClientListening, 2i, (iReceiver, iSender)); - RETURN_API(qboolean) +qboolean mm_Voice_GetClientListening(int iReceiver, int iSender) { + META_ENGINE_HANDLE(qboolean, false, FN_VOICE_GETCLIENTLISTENING, pfnVoice_GetClientListening, (iReceiver, iSender)); + RETURN_API() +} +qboolean mm_Voice_SetClientListening(int iReceiver, int iSender, qboolean bListen) { + META_ENGINE_HANDLE(qboolean, false, FN_VOICE_SETCLIENTLISTENING, pfnVoice_SetClientListening, (iReceiver, iSender, bListen)); + RETURN_API() } -qboolean mm_Voice_SetClientListening(int iReceiver, int iSender, qboolean bListen) -{ - META_ENGINE_HANDLE(qboolean, false, FN_VOICE_SETCLIENTLISTENING, pfnVoice_SetClientListening, 3i, (iReceiver, iSender, bListen)); - RETURN_API(qboolean) +// Added for HL 1109 (no SDK update): + +const char *mm_GetPlayerAuthId(edict_t *e) { + META_ENGINE_HANDLE(const char *, NULL, FN_GETPLAYERAUTHID, pfnGetPlayerAuthId, (e)); + RETURN_API() } -const char *mm_GetPlayerAuthId(edict_t *e) -{ - META_ENGINE_HANDLE(const char *, NULL, FN_GETPLAYERAUTHID, pfnGetPlayerAuthId, p, (e)); - RETURN_API(const char *) +// Added 2003-11-10 (no SDK update): + +sequenceEntry_s *mm_SequenceGet(const char *fileName, const char *entryName) { + META_ENGINE_HANDLE(sequenceEntry_s *, NULL, FN_SEQUENCEGET, pfnSequenceGet, (fileName, entryName)); + RETURN_API() } -sequenceEntry_s *mm_SequenceGet(const char *fileName, const char *entryName) -{ - META_ENGINE_HANDLE(sequenceEntry_s *, NULL, FN_SEQUENCEGET, pfnSequenceGet, 2p, (fileName, entryName)); - RETURN_API(sequenceEntry_s *) +sentenceEntry_s *mm_SequencePickSentence(const char *groupName, int pickMethod, int *picked) { + META_ENGINE_HANDLE(sentenceEntry_s *, NULL, FN_SEQUENCEPICKSENTENCE, pfnSequencePickSentence, (groupName, pickMethod, picked)); + RETURN_API() } -sentenceEntry_s *mm_SequencePickSentence(const char *groupName, int pickMethod, int *picked) -{ - META_ENGINE_HANDLE(sentenceEntry_s *, NULL, FN_SEQUENCEPICKSENTENCE, pfnSequencePickSentence, pip, (groupName, pickMethod, picked)); - RETURN_API(sentenceEntry_s *) +int mm_GetFileSize(char *filename) { + META_ENGINE_HANDLE(int, 0, FN_GETFILESIZE, pfnGetFileSize, (filename)); + RETURN_API() } -int mm_GetFileSize(char *filename) -{ - META_ENGINE_HANDLE(int, 0, FN_GETFILESIZE, pfnGetFileSize, p, (filename)); - RETURN_API(int) +unsigned int mm_GetApproxWavePlayLen(const char *filepath) { + META_ENGINE_HANDLE(unsigned int, 0, FN_GETAPPROXWAVEPLAYLEN, pfnGetApproxWavePlayLen, (filepath)); + RETURN_API() } -unsigned int mm_GetApproxWavePlayLen(const char *filepath) -{ - META_ENGINE_HANDLE(unsigned int, 0, FN_GETAPPROXWAVEPLAYLEN, pfnGetApproxWavePlayLen, p, (filepath)); - RETURN_API(unsigned int) +int mm_IsCareerMatch(void) { + META_ENGINE_HANDLE(int, 0, FN_ISCAREERMATCH, pfnIsCareerMatch, ()); + RETURN_API() } -int mm_IsCareerMatch() -{ - META_ENGINE_HANDLE(int, 0, FN_ISCAREERMATCH, pfnIsCareerMatch, void, (VOID_ARG)); - RETURN_API(int) +int mm_GetLocalizedStringLength(const char *label) { + META_ENGINE_HANDLE(int, 0, FN_GETLOCALIZEDSTRINGLENGTH, pfnGetLocalizedStringLength, (label)); + RETURN_API() } -int mm_GetLocalizedStringLength(const char *label) -{ - META_ENGINE_HANDLE(int, 0, FN_GETLOCALIZEDSTRINGLENGTH, pfnGetLocalizedStringLength, p, (label)); - RETURN_API(int) -} - -void mm_RegisterTutorMessageShown(int mid) -{ - META_ENGINE_HANDLE_void(FN_REGISTERTUTORMESSAGESHOWN, pfnRegisterTutorMessageShown, i, (mid)); +void mm_RegisterTutorMessageShown(int mid) { + META_ENGINE_HANDLE_void(FN_REGISTERTUTORMESSAGESHOWN, pfnRegisterTutorMessageShown, (mid)); RETURN_API_void() } -int mm_GetTimesTutorMessageShown(int mid) -{ - META_ENGINE_HANDLE(int, 0, FN_GETTIMESTUTORMESSAGESHOWN, pfnGetTimesTutorMessageShown, i, (mid)); - RETURN_API(int) +int mm_GetTimesTutorMessageShown(int mid) { + META_ENGINE_HANDLE(int, 0, FN_GETTIMESTUTORMESSAGESHOWN, pfnGetTimesTutorMessageShown, (mid)); + RETURN_API() } -void mm_ProcessTutorMessageDecayBuffer(int *buffer, int bufferLength) -{ - META_ENGINE_HANDLE_void(FN_PROCESSTUTORMESSAGEDECAYBUFFER, pfnProcessTutorMessageDecayBuffer, pi, (buffer, bufferLength)); +void mm_ProcessTutorMessageDecayBuffer(int *buffer, int bufferLength) { + META_ENGINE_HANDLE_void(FN_PROCESSTUTORMESSAGEDECAYBUFFER, pfnProcessTutorMessageDecayBuffer, (buffer, bufferLength)); RETURN_API_void() } -void mm_ConstructTutorMessageDecayBuffer(int *buffer, int bufferLength) -{ - META_ENGINE_HANDLE_void(FN_CONSTRUCTTUTORMESSAGEDECAYBUFFER, pfnConstructTutorMessageDecayBuffer, pi, (buffer, bufferLength)); +void mm_ConstructTutorMessageDecayBuffer(int *buffer, int bufferLength) { + META_ENGINE_HANDLE_void(FN_CONSTRUCTTUTORMESSAGEDECAYBUFFER, pfnConstructTutorMessageDecayBuffer, (buffer, bufferLength)); RETURN_API_void() } -void mm_ResetTutorMessageDecayData() -{ - META_ENGINE_HANDLE_void(FN_RESETTUTORMESSAGEDECAYDATA, pfnResetTutorMessageDecayData, void, (VOID_ARG)); +void mm_ResetTutorMessageDecayData(void) { + META_ENGINE_HANDLE_void(FN_RESETTUTORMESSAGEDECAYDATA, pfnResetTutorMessageDecayData, ()); RETURN_API_void() } -void mm_QueryClientCvarValue(const edict_t *player, const char *cvarName) +//Added 2005-08-11 (no SDK update) +void mm_QueryClientCvarValue(const edict_t *pEdict, const char *cvarName) { - META_ENGINE_HANDLE_void(FN_QUERYCLIENTCVARVALUE, pfnQueryClientCvarValue, 2p, (player, cvarName)); - RETURN_API_void() + g_Players.set_player_cvar_query(pEdict, cvarName); + + META_ENGINE_HANDLE_void(FN_QUERYCLIENTCVARVALUE, pfnQueryClientCvarValue, (pEdict, cvarName)); + RETURN_API_void(); } -void mm_QueryClientCvarValue2(const edict_t *player, const char *cvarName, int requestID) +//Added 2005-11-22 (no SDK update) +void mm_QueryClientCvarValue2(const edict_t *pEdict, const char *cvarName, int requestId) { - META_ENGINE_HANDLE_void(FN_QUERYCLIENTCVARVALUE2, pfnQueryClientCvarValue2, 2pi, (player, cvarName, requestID)); - RETURN_API_void() + META_ENGINE_HANDLE_void(FN_QUERYCLIENTCVARVALUE2, pfnQueryClientCvarValue2, (pEdict, cvarName, requestId)); + RETURN_API_void(); } -int mm_EngCheckParm(const char *pchCmdLineToken, char **pchNextVal) +//Added 2009-06-17 (no SDK update) +int mm_EngCheckParm(const char *pchCmdLineToken, char **ppnext) { - META_ENGINE_HANDLE(int, 0, FN_ENGCHECKPARM, pfnEngCheckParm, 2p, (pchCmdLineToken, pchNextVal)); - RETURN_API(int) + META_ENGINE_HANDLE(int, 0, FN_CHECKPARM, pfnEngCheckParm, (pchCmdLineToken, ppnext)); + RETURN_API(); } -meta_enginefuncs_t meta_engfuncs( +enginefuncs_t _engfuncs = { &mm_PrecacheModel, // pfnPrecacheModel() &mm_PrecacheSound, // pfnPrecacheSound() &mm_SetModel, // pfnSetModel() @@ -1081,10 +893,10 @@ meta_enginefuncs_t meta_engfuncs( &mm_ChangeYaw, // pfnChangeYaw() &mm_ChangePitch, // pfnChangePitch() - &mm_FindEntityByString, // pfnFindEntityByString() + &mm_FindEntityByString, // pfnFindEntityByString() &mm_GetEntityIllum, // pfnGetEntityIllum() - &mm_FindEntityInSphere, // pfnFindEntityInSphere() - &mm_FindClientInPVS, // pfnFindClientInPVS() + &mm_FindEntityInSphere, // pfnFindEntityInSphere() + &mm_FindClientInPVS, // pfnFindClientInPVS() &mm_EntitiesInPVS, // pfnEntitiesInPVS() &mm_MakeVectors, // pfnMakeVectors() @@ -1092,7 +904,7 @@ meta_enginefuncs_t meta_engfuncs( &mm_CreateEntity, // pfnCreateEntity() &mm_RemoveEntity, // pfnRemoveEntity() - &mm_CreateNamedEntity, // pfnCreateNamedEntity() + &mm_CreateNamedEntity, // pfnCreateNamedEntity() &mm_MakeStatic, // pfnMakeStatic() &mm_EntIsOnFloor, // pfnEntIsOnFloor() @@ -1102,11 +914,11 @@ meta_enginefuncs_t meta_engfuncs( &mm_SetOrigin, // pfnSetOrigin() &mm_EmitSound, // pfnEmitSound() - &mm_EmitAmbientSound, // pfnEmitAmbientSound() + &mm_EmitAmbientSound, // pfnEmitAmbientSound() &mm_TraceLine, // pfnTraceLine() &mm_TraceToss, // pfnTraceToss() - &mm_TraceMonsterHull, // pfnTraceMonsterHull() + &mm_TraceMonsterHull, // pfnTraceMonsterHull() &mm_TraceHull, // pfnTraceHull() &mm_TraceModel, // pfnTraceModel() &mm_TraceTexture, // pfnTraceTexture() @@ -1115,7 +927,7 @@ meta_enginefuncs_t meta_engfuncs( &mm_ServerCommand, // pfnServerCommand() &mm_ServerExecute, // pfnServerExecute() - &mm_engClientCommand, // pfnClientCommand() // D'oh, ClientCommand in dllapi too. + &mm_engClientCommand, // pfnClientCommand() // D'oh, ClientCommand in dllapi too. &mm_ParticleEffect, // pfnParticleEffect() &mm_LightStyle, // pfnLightStyle() @@ -1143,124 +955,138 @@ meta_enginefuncs_t meta_engfuncs( &mm_AlertMessage, // pfnAlertMessage() &mm_EngineFprintf, // pfnEngineFprintf() - &mm_PvAllocEntPrivateData, // pfnPvAllocEntPrivateData() - &mm_PvEntPrivateData, // pfnPvEntPrivateData() - &mm_FreeEntPrivateData, // pfnFreeEntPrivateData() + &mm_PvAllocEntPrivateData, // pfnPvAllocEntPrivateData() + &mm_PvEntPrivateData, // pfnPvEntPrivateData() + &mm_FreeEntPrivateData, // pfnFreeEntPrivateData() &mm_SzFromIndex, // pfnSzFromIndex() &mm_AllocString, // pfnAllocString() &mm_GetVarsOfEnt, // pfnGetVarsOfEnt() - &mm_PEntityOfEntOffset, // pfnPEntityOfEntOffset() - &mm_EntOffsetOfPEntity, // pfnEntOffsetOfPEntity() + &mm_PEntityOfEntOffset, // pfnPEntityOfEntOffset() + &mm_EntOffsetOfPEntity, // pfnEntOffsetOfPEntity() &mm_IndexOfEdict, // pfnIndexOfEdict() - &mm_PEntityOfEntIndex, // pfnPEntityOfEntIndex() - &mm_FindEntityByVars, // pfnFindEntityByVars() + &mm_PEntityOfEntIndex, // pfnPEntityOfEntIndex() + &mm_FindEntityByVars, // pfnFindEntityByVars() &mm_GetModelPtr, // pfnGetModelPtr() &mm_RegUserMsg, // pfnRegUserMsg() - &mm_AnimationAutomove, // pfnAnimationAutomove() - &mm_GetBonePosition, // pfnGetBonePosition() + &mm_AnimationAutomove, // pfnAnimationAutomove() + &mm_GetBonePosition, // pfnGetBonePosition() - &mm_FunctionFromName, // pfnFunctionFromName() - &mm_NameForFunction, // pfnNameForFunction() + &mm_FunctionFromName, // pfnFunctionFromName() + &mm_NameForFunction, // pfnNameForFunction() &mm_ClientPrintf, // pfnClientPrintf() //! JOHN: engine callbacks so game DLL can print messages to individual clients &mm_ServerPrint, // pfnServerPrint() - &mm_Cmd_Args, // pfnCmd_Args() //! these 3 added - &mm_Cmd_Argv, // pfnCmd_Argv() //! so game DLL can easily + &mm_Cmd_Args, // pfnCmd_Args() //! these 3 added + &mm_Cmd_Argv, // pfnCmd_Argv() //! so game DLL can easily &mm_Cmd_Argc, // pfnCmd_Argc() //! access client 'cmd' strings &mm_GetAttachment, // pfnGetAttachment() &mm_CRC32_Init, // pfnCRC32_Init() - &mm_CRC32_ProcessBuffer, // pfnCRC32_ProcessBuffer() - &mm_CRC32_ProcessByte, // pfnCRC32_ProcessByte() + &mm_CRC32_ProcessBuffer, // pfnCRC32_ProcessBuffer() + &mm_CRC32_ProcessByte, // pfnCRC32_ProcessByte() &mm_CRC32_Final, // pfnCRC32_Final() &mm_RandomLong, // pfnRandomLong() &mm_RandomFloat, // pfnRandomFloat() &mm_SetView, // pfnSetView() - &mm_Time, // pfnTime() + &mm_Time, // pfnTime() &mm_CrosshairAngle, // pfnCrosshairAngle() &mm_LoadFileForMe, // pfnLoadFileForMe() &mm_FreeFile, // pfnFreeFile() &mm_EndSection, // pfnEndSection() //! trigger_endsection - &mm_CompareFileTime, // pfnCompareFileTime() + &mm_CompareFileTime, // pfnCompareFileTime() &mm_GetGameDir, // pfnGetGameDir() - &mm_Cvar_RegisterVariable, // pfnCvar_RegisterVariable() - &mm_FadeClientVolume, // pfnFadeClientVolume() - &mm_SetClientMaxspeed, // pfnSetClientMaxspeed() - &mm_CreateFakeClient, // pfnCreateFakeClient() //! returns NULL if fake client can't be created + &mm_Cvar_RegisterVariable, // pfnCvar_RegisterVariable() + &mm_FadeClientVolume, // pfnFadeClientVolume() + &mm_SetClientMaxspeed, // pfnSetClientMaxspeed() + &mm_CreateFakeClient, // pfnCreateFakeClient() //! returns NULL if fake client can't be created &mm_RunPlayerMove, // pfnRunPlayerMove() - &mm_NumberOfEntities, // pfnNumberOfEntities() + &mm_NumberOfEntities, // pfnNumberOfEntities() - &mm_GetInfoKeyBuffer, // pfnGetInfoKeyBuffer() //! passing in NULL gets the serverinfo + &mm_GetInfoKeyBuffer, // pfnGetInfoKeyBuffer() //! passing in NULL gets the serverinfo &mm_InfoKeyValue, // pfnInfoKeyValue() &mm_SetKeyValue, // pfnSetKeyValue() - &mm_SetClientKeyValue, // pfnSetClientKeyValue() + &mm_SetClientKeyValue, // pfnSetClientKeyValue() &mm_IsMapValid, // pfnIsMapValid() &mm_StaticDecal, // pfnStaticDecal() - &mm_PrecacheGeneric, // pfnPrecacheGeneric() - &mm_GetPlayerUserId, // pfnGetPlayerUserId() //! returns the server assigned userid for this player. + &mm_PrecacheGeneric, // pfnPrecacheGeneric() + &mm_GetPlayerUserId, // pfnGetPlayerUserId() //! returns the server assigned userid for this player. &mm_BuildSoundMsg, // pfnBuildSoundMsg() - &mm_IsDedicatedServer, // pfnIsDedicatedServer() //! is this a dedicated server? + &mm_IsDedicatedServer, // pfnIsDedicatedServer() //! is this a dedicated server? &mm_CVarGetPointer, // pfnCVarGetPointer() &mm_GetPlayerWONId, // pfnGetPlayerWONId() //! returns the server assigned WONid for this player. //! YWB 8/1/99 TFF Physics additions &mm_Info_RemoveKey, // pfnInfo_RemoveKey() - &mm_GetPhysicsKeyValue, // pfnGetPhysicsKeyValue() - &mm_SetPhysicsKeyValue, // pfnSetPhysicsKeyValue() - &mm_GetPhysicsInfoString, // pfnGetPhysicsInfoString() + &mm_GetPhysicsKeyValue, // pfnGetPhysicsKeyValue() + &mm_SetPhysicsKeyValue, // pfnSetPhysicsKeyValue() + &mm_GetPhysicsInfoString, // pfnGetPhysicsInfoString() &mm_PrecacheEvent, // pfnPrecacheEvent() &mm_PlaybackEvent, // pfnPlaybackEvent() + &mm_SetFatPVS, // pfnSetFatPVS() &mm_SetFatPAS, // pfnSetFatPAS() - &mm_CheckVisibility, // pfnCheckVisibility() + + &mm_CheckVisibility, // pfnCheckVisibility() + &mm_DeltaSetField, // pfnDeltaSetField() - &mm_DeltaUnsetField, // pfnDeltaUnsetField() - &mm_DeltaAddEncoder, // pfnDeltaAddEncoder() - &mm_GetCurrentPlayer, // pfnGetCurrentPlayer() + &mm_DeltaUnsetField, // pfnDeltaUnsetField() + &mm_DeltaAddEncoder, // pfnDeltaAddEncoder() + &mm_GetCurrentPlayer, // pfnGetCurrentPlayer() &mm_CanSkipPlayer, // pfnCanSkipPlayer() &mm_DeltaFindField, // pfnDeltaFindField() - &mm_DeltaSetFieldByIndex, // pfnDeltaSetFieldByIndex() - &mm_DeltaUnsetFieldByIndex, // pfnDeltaUnsetFieldByIndex() + &mm_DeltaSetFieldByIndex, // pfnDeltaSetFieldByIndex() + &mm_DeltaUnsetFieldByIndex, // pfnDeltaUnsetFieldByIndex() &mm_SetGroupMask, // pfnSetGroupMask() - &mm_engCreateInstancedBaseline, // pfnCreateInstancedBaseline() // D'oh, CreateInstancedBaseline in dllapi too. + &mm_engCreateInstancedBaseline, // pfnCreateInstancedBaseline() // D'oh, CreateInstancedBaseline in dllapi too. &mm_Cvar_DirectSet, // pfnCvar_DirectSet() - &mm_ForceUnmodified, // pfnForceUnmodified() + &mm_ForceUnmodified, // pfnForceUnmodified() + &mm_GetPlayerStats, // pfnGetPlayerStats() - &mm_AddServerCommand, // pfnAddServerCommand() + &mm_AddServerCommand, // pfnAddServerCommand() - &mm_Voice_GetClientListening, // pfnVoice_GetClientListening() - &mm_Voice_SetClientListening, // pfnVoice_SetClientListening() + // Added in SDK 2l2: + &mm_Voice_GetClientListening, // pfnVoice_GetClientListening() + &mm_Voice_SetClientListening, // pfnVoice_SetClientListening() + // Added for HL 1109 (no SDK update): &mm_GetPlayerAuthId, // pfnGetPlayerAuthId() - &mm_SequenceGet, // pfnSequenceGet() - &mm_SequencePickSentence, // pfnSequencePickSentence() - &mm_GetFileSize, // pfnGetFileSize() - &mm_GetApproxWavePlayLen, // pfnGetApproxWavePlayLen() - &mm_IsCareerMatch, // pfnIsCareerMatch() + // Added 2003-11-10 (no SDK update): + &mm_SequenceGet, // pfnSequenceGet() + &mm_SequencePickSentence, // pfnSequencePickSentence() + &mm_GetFileSize, // pfnGetFileSize() + &mm_GetApproxWavePlayLen, // pfnGetApproxWavePlayLen() + &mm_IsCareerMatch, // pfnIsCareerMatch() &mm_GetLocalizedStringLength, // pfnGetLocalizedStringLength() - &mm_RegisterTutorMessageShown, // pfnRegisterTutorMessageShown() - &mm_GetTimesTutorMessageShown, // pfnGetTimesTutorMessageShown() + &mm_RegisterTutorMessageShown, // pfnRegisterTutorMessageShown() + &mm_GetTimesTutorMessageShown, // pfnGetTimesTutorMessageShown() &mm_ProcessTutorMessageDecayBuffer, // pfnProcessTutorMessageDecayBuffer() &mm_ConstructTutorMessageDecayBuffer, // pfnConstructTutorMessageDecayBuffer() &mm_ResetTutorMessageDecayData, // pfnResetTutorMessageDecayData() + //Added 2005-08-11 (no SDK update) &mm_QueryClientCvarValue, // pfnQueryClientCvarValue() + + //Added 2005-11-22 (no SDK update) &mm_QueryClientCvarValue2, // pfnQueryClientCvarValue2() - &mm_EngCheckParm // pfnEngCheckParm() -); + + // Added 2009-06-17 (no SDK update) + &mm_EngCheckParm // pfnCheckParm() +}; + +meta_enginefuncs_t meta_engfuncs(&_engfuncs); diff --git a/metamod/src/engine_api.h b/metamod/src/engine_api.h index 9177379..a8e8c21 100644 --- a/metamod/src/engine_api.h +++ b/metamod/src/engine_api.h @@ -1,7 +1,46 @@ -#pragma once +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// engine_api.h - prototypes and typedefs for Half-Life engine functions + +/* + * Copyright (c) 2001-2003 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game g_engine ("HL + * g_engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL g_engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + +#ifndef ENGINE_API_H +#define ENGINE_API_H + +#include // Plugin's GetEngineFunctions, called by metamod. -typedef int (*GET_ENGINE_FUNCTIONS_FN)(enginefuncs_t *pengfuncsFromEngine, int *interfaceVersion); +typedef int (*GET_ENGINE_FUNCTIONS_FN) (enginefuncs_t *pengfuncsFromEngine, int *interfaceVersion); // According to SDK engine/eiface.h: //! enginefuncs_t @@ -10,169 +49,420 @@ typedef int (*GET_ENGINE_FUNCTIONS_FN)(enginefuncs_t *pengfuncsFromEngine, int * // Protect against other projects which use this include file but use the // normal enginefuncs_t type for their meta_engfuncs. -#ifdef __METAMOD_BUILD__ -#include "meta_eiface.h" // meta_enginefuncs_t +#ifdef METAMOD_CORE +# include "meta_eiface.h" // meta_enginefuncs_t extern meta_enginefuncs_t meta_engfuncs; #else extern enginefuncs_t meta_engfuncs; #endif +// From SDK engine/eiface.h: +extern int mm_PrecacheModel(const char *s); +extern int mm_PrecacheSound(const char *s); +extern void mm_SetModel(edict_t *e, const char *m); +extern int mm_ModelIndex(const char *m); +extern int mm_ModelFrames(int modelIndex); + +extern void mm_SetSize(edict_t *e, const float *rgflMin, const float *rgflMax); +extern void mm_ChangeLevel(const char *s1, const char *s2); +extern void mm_GetSpawnParms(edict_t *ent); +extern void mm_SaveSpawnParms(edict_t *ent); + +extern float mm_VecToYaw(const float *rgflVector); +extern void mm_VecToAngles(const float *rgflVectorIn, float *rgflVectorOut); +extern void mm_MoveToOrigin(edict_t *ent, const float *pflGoal, float dist, int iMoveType); +extern void mm_ChangeYaw(edict_t *ent); +extern void mm_ChangePitch(edict_t *ent); + +extern edict_t *mm_FindEntityByString(edict_t *pEdictStartSearchAfter, const char *pszField, const char *pszValue); +extern int mm_GetEntityIllum(edict_t *pEnt); +extern edict_t *mm_FindEntityInSphere(edict_t *pEdictStartSearchAfter, const float *org, float rad); +extern edict_t *mm_FindClientInPVS(edict_t *pEdict); +extern edict_t *mm_EntitiesInPVS(edict_t *pplayer); + +extern void mm_MakeVectors(const float *rgflVector); +extern void mm_AngleVectors(const float *rgflVector, float *forward, float *right, float *up); + +extern edict_t *mm_CreateEntity(void); +extern void mm_RemoveEntity(edict_t *e); +extern edict_t *mm_CreateNamedEntity(int className); + +extern void mm_MakeStatic(edict_t *ent); +extern int mm_EntIsOnFloor(edict_t *e); +extern int mm_DropToFloor(edict_t *e); + +extern int mm_WalkMove(edict_t *ent, float yaw, float dist, int iMode); +extern void mm_SetOrigin(edict_t *e, const float *rgflOrigin); + +extern void mm_EmitSound(edict_t *entity, int channel, const char *sample, /*int*/float volume, float attenuation, int fFlags, int pitch); +extern void mm_EmitAmbientSound(edict_t *entity, float *pos, const char *samp, float vol, float attenuation, int fFlags, int pitch); + +extern void mm_TraceLine(const float *v1, const float *v2, int fNoMonsters, edict_t *pentToSkip, TraceResult *ptr); +extern void mm_TraceToss(edict_t *pent, edict_t *pentToIgnore, TraceResult *ptr); +extern int mm_TraceMonsterHull(edict_t *pEdict, const float *v1, const float *v2, int fNoMonsters, edict_t *pentToSkip, TraceResult *ptr); +extern void mm_TraceHull(const float *v1, const float *v2, int fNoMonsters, int hullNumber, edict_t *pentToSkip, TraceResult *ptr); +extern void mm_TraceModel(const float *v1, const float *v2, int hullNumber, edict_t *pent, TraceResult *ptr); +extern const char *mm_TraceTexture(edict_t *pTextureEntity, const float *v1, const float *v2 ); +extern void mm_TraceSphere(const float *v1, const float *v2, int fNoMonsters, float radius, edict_t *pentToSkip, TraceResult *ptr); +extern void mm_GetAimVector(edict_t *ent, float speed, float *rgflReturn); + +extern void mm_ServerCommand(const char *str); +extern void mm_ServerExecute(void); +extern void ClientCommand(edict_t *pEdict, const char *szFmt, ...); + +extern void mm_ParticleEffect(const float *org, const float *dir, float color, float count); +extern void mm_LightStyle(int style, const char *val); +extern int mm_DecalIndex(const char *name); +extern int mm_PointContents(const float *rgflVector); + +extern void mm_MessageBegin(int msg_dest, int msg_type, const float *pOrigin, edict_t *ed); +extern void mm_MessageEnd(void); + +extern void mm_WriteByte(int iValue); +extern void mm_WriteChar(int iValue); +extern void mm_WriteShort(int iValue); +extern void mm_WriteLong(int iValue); +extern void mm_WriteAngle(float flValue); +extern void mm_WriteCoord(float flValue); +extern void mm_WriteString(const char *sz); +extern void mm_WriteEntity(int iValue); + +extern void mm_CVarRegister(cvar_t *pCvar); +extern float mm_CVarGetFloat(const char *szVarName); +extern const char* mm_CVarGetString(const char *szVarName); +extern void mm_CVarSetFloat(const char *szVarName, float flValue); +extern void mm_CVarSetString(const char *szVarName, const char *szValue); + +extern void mm_AlertMessage(ALERT_TYPE atype, const char *szFmt, ...); +#ifdef HLSDK_3_2_OLD_EIFACE +extern void mm_EngineFprintf(FILE *pfile, const char *szFmt, ...); +#else +extern void mm_EngineFprintf(void *pfile, const char *szFmt, ...); +#endif + +#ifdef HLSDK_3_2_OLD_EIFACE +extern void *mm_PvAllocEntPrivateData(edict_t *pEdict, long cb); +#else +extern void *mm_PvAllocEntPrivateData(edict_t *pEdict, int32 cb); +#endif +extern void *mm_PvEntPrivateData(edict_t *pEdict); +extern void mm_FreeEntPrivateData(edict_t *pEdict); + +extern const char *mm_SzFromIndex(int iString); +extern int mm_AllocString(const char *szValue); + +extern struct entvars_s *mm_GetVarsOfEnt(edict_t *pEdict); +extern edict_t *mm_PEntityOfEntOffset(int iEntOffset); +extern int mm_EntOffsetOfPEntity(const edict_t *pEdict); +extern int mm_IndexOfEdict(const edict_t *pEdict); +extern edict_t *mm_PEntityOfEntIndex(int iEntIndex); +extern edict_t *mm_FindEntityByVars(struct entvars_s *pvars); +extern void *mm_GetModelPtr(edict_t *pEdict); + +extern int mm_RegUserMsg(const char *pszName, int iSize); + +extern void mm_AnimationAutomove(const edict_t *pEdict, float flTime); +extern void mm_GetBonePosition(const edict_t *pEdict, int iBone, float *rgflOrigin, float *rgflAngles ); + +#ifdef HLSDK_3_2_OLD_EIFACE +extern unsigned long mm_FunctionFromName( const char *pName ); +extern const char *mm_NameForFunction( unsigned long function ); +#else +extern uint32 mm_FunctionFromName( const char *pName ); +extern const char *mm_NameForFunction( uint32 function ); +#endif + +extern void mm_ClientPrintf( edict_t *pEdict, PRINT_TYPE ptype, const char *szMsg ); //! JOHN: engine callbacks so game DLL can print messages to individual clients +extern void mm_ServerPrint( const char *szMsg ); + +extern const char *mm_Cmd_Args( void ); //! these 3 added +extern const char *mm_Cmd_Argv( int argc ); //! so game DLL can easily +extern int mm_Cmd_Argc( void ); //! access client 'cmd' strings + +extern void mm_GetAttachment(const edict_t *pEdict, int iAttachment, float *rgflOrigin, float *rgflAngles ); + +extern void mm_CRC32_Init(CRC32_t *pulCRC); +extern void mm_CRC32_ProcessBuffer(CRC32_t *pulCRC, void *p, int len); +extern void mm_CRC32_ProcessByte(CRC32_t *pulCRC, unsigned char ch); +extern CRC32_t mm_CRC32_Final(CRC32_t pulCRC); + +#ifdef HLSDK_3_2_OLD_EIFACE +extern long mm_RandomLong(long lLow, long lHigh); +#else +extern int32 mm_RandomLong(int32 lLow, int32 lHigh); +#endif +extern float mm_RandomFloat(float flLow, float flHigh); + +extern void mm_SetView(const edict_t *pClient, const edict_t *pViewent ); +extern float mm_Time( void ); +extern void mm_CrosshairAngle(const edict_t *pClient, float pitch, float yaw); + +extern byte * mm_LoadFileForMe(const char *filename, int *pLength); +extern void mm_FreeFile(void *buffer); + +extern void mm_EndSection(const char *pszSectionName); //! trigger_endsection +extern int mm_CompareFileTime(char *filename1, char *filename2, int *iCompare); +extern void mm_GetGameDir(char *szGetGameDir); +extern void mm_Cvar_RegisterVariable(cvar_t *variable); +extern void mm_FadeClientVolume(const edict_t *pEdict, int fadePercent, int fadeOutSeconds, int holdTime, int fadeInSeconds); +extern void mm_SetClientMaxspeed(const edict_t *pEdict, float fNewMaxspeed); +extern edict_t * mm_CreateFakeClient(const char *netname); //! returns NULL if fake client can't be created +extern void mm_RunPlayerMove(edict_t *fakeclient, const float *viewangles, float forwardmove, float sidemove, float upmove, unsigned short buttons, byte impulse, byte msec ); +extern int mm_NumberOfEntities(void); + +extern char *mm_GetInfoKeyBuffer(edict_t *e); //! passing in NULL gets the serverinfo +extern char *mm_InfoKeyValue(char *infobuffer, const char *key); +extern void mm_SetKeyValue(char *infobuffer, const char *key, const char *value); +extern void mm_SetClientKeyValue(int clientIndex, char *infobuffer, const char *key, const char *value); + +extern int mm_IsMapValid(char *filename); +extern void mm_StaticDecal( const float *origin, int decalIndex, int entityIndex, int modelIndex ); +extern int mm_PrecacheGeneric(const char *s); +extern int mm_GetPlayerUserId(edict_t *e ); //! returns the server assigned userid for this player. useful for logging frags, etc. returns -1 if the edict couldn't be found in the list of clients +extern void mm_BuildSoundMsg(edict_t *entity, int channel, const char *sample, /*int*/float volume, float attenuation, int fFlags, int pitch, int msg_dest, int msg_type, const float *pOrigin, edict_t *ed); +extern int mm_IsDedicatedServer(void);//! is this a dedicated server? +extern cvar_t *mm_CVarGetPointer(const char *szVarName); +extern unsigned int mm_GetPlayerWONId(edict_t *e); //! returns the server assigned WONid for this player. useful for logging frags, etc. returns -1 if the edict couldn't be found in the list of clients + +//! YWB 8/1/99 TFF Physics additions +extern void mm_Info_RemoveKey( char *s, const char *key ); +extern const char *mm_GetPhysicsKeyValue( const edict_t *pClient, const char *key ); +extern void mm_SetPhysicsKeyValue( const edict_t *pClient, const char *key, const char *value ); +extern const char *mm_GetPhysicsInfoString( const edict_t *pClient ); +extern unsigned short mm_PrecacheEvent( int type, const char *psz ); +extern void mm_PlaybackEvent( int flags, const edict_t *pInvoker, unsigned short eventindex, float delay, float *origin, float *angles, float fparam1, float fparam2, int iparam1, int iparam2, int bparam1, int bparam2 ); + +extern unsigned char *mm_SetFatPVS( float *org ); +extern unsigned char *mm_SetFatPAS( float *org ); + +extern int mm_CheckVisibility( edict_t *entity, unsigned char *pset ); + +extern void mm_DeltaSetField( struct delta_s *pFields, const char *fieldname ); +extern void mm_DeltaUnsetField( struct delta_s *pFields, const char *fieldname ); +extern void mm_DeltaAddEncoder( const char *name, void (*conditionalencode)( struct delta_s *pFields, const unsigned char *from, const unsigned char *to ) ); +extern int mm_GetCurrentPlayer( void ); +extern int mm_CanSkipPlayer( const edict_t *player ); +extern int mm_DeltaFindField( struct delta_s *pFields, const char *fieldname ); +extern void mm_DeltaSetFieldByIndex( struct delta_s *pFields, int fieldNumber ); +extern void mm_DeltaUnsetFieldByIndex( struct delta_s *pFields, int fieldNumber ); + +extern void mm_SetGroupMask( int mask, int op ); + +extern int CreateInstancedBaseline( int classname, struct entity_state_s *baseline ); +extern void mm_Cvar_DirectSet( struct cvar_s *var, const char *value ); + +//! Forces the client and server to be running with the same version of the specified file +//!( e.g., a player model ). +//! Calling this has no effect in single player +extern void mm_ForceUnmodified( FORCE_TYPE type, float *mins, float *maxs, const char *filename ); + +extern void mm_GetPlayerStats( const edict_t *pClient, int *ping, int *packet_loss ); + +extern void mm_AddServerCommand( const char *cmd_name, void (*function) (void) ); +// Added in SDK 2.2: +extern qboolean mm_Voice_GetClientListening(int iReceiver, int iSender); +extern qboolean mm_Voice_SetClientListening(int iReceiver, int iSender, qboolean bListen); +// Added for HL 1109 (no SDK update): +extern const char *mm_pfnGetPlayerAuthId(edict_t *e); +// Added 2003-11-10 (no SDK update): +extern sequenceEntry_s * mm_SequenceGet(const char* fileName, const char* entryName); +extern sentenceEntry_s * mm_SequencePickSentence(const char* groupName, int pickMethod, int *picked); +extern int mm_GetFileSize(const char *filename); +extern unsigned int mm_GetApproxWavePlayLen(const char *filepath); +extern int mm_IsCareerMatch(void); +extern int mm_GetLocalizedStringLength(const char *label); +extern void mm_RegisterTutorMessageShown(int mid); +extern int mm_GetTimesTutorMessageShown(int mid); +extern void mm_ProcessTutorMessageDecayBuffer(int *buffer, int bufferLength); +extern void mm_ConstructTutorMessageDecayBuffer(int *buffer, int bufferLength); +extern void mm_ResetTutorMessageDecayData(void); +//Added 2005-08-11 (no SDK update) +extern void mm_QueryClientCvarValue(const edict_t *pEdict, const char *cvarName); //! Obsolete! Use mm_QueryClientCvarValue2 instead +//Added 2005-11-22 (no SDK update) +extern void mm_QueryClientCvarValue2(const edict_t *pEdict, const char *cvarName, int requestID); +//Added 2009-06-17 (no SDK update) +extern int mm_EngCheckParm(const char *pchCmdLineToken, char **ppnext); + + // Typedefs for the above functions: -typedef int (*FN_PRECACHEMODEL)(char* s); -typedef int (*FN_PRECACHESOUND)(char* s); -typedef void (*FN_SETMODEL)(edict_t *e, const char *m); -typedef int (*FN_MODELINDEX)(const char *m); -typedef int (*FN_MODELFRAMES)(int modelIndex); -typedef void (*FN_SETSIZE)(edict_t *e, const float *rgflMin, const float *rgflMax); -typedef void (*FN_CHANGELEVEL)(char *s1, char *s2); -typedef void (*FN_GETSPAWNPARMS)(edict_t *ent); -typedef void (*FN_SAVESPAWNPARMS)(edict_t *ent); -typedef float (*FN_VECTOYAW)(const float *rgflVector); -typedef void (*FN_VECTOANGLES)(const float *rgflVectorIn, float *rgflVectorOut); -typedef void (*FN_MOVETOORIGIN)(edict_t *ent, const float *pflGoal, float dist, int iMoveType); -typedef void (*FN_CHANGEYAW)(edict_t *ent); -typedef void (*FN_CHANGEPITCH)(edict_t *ent); -typedef edict_t *(*FN_FINDENTITYBYSTRING)(edict_t *pEdictStartSearchAfter, const char *pszField, const char *pszValue); -typedef int (*FN_GETENTITYILLUM)(edict_t *pEnt); -typedef edict_t *(*FN_FINDENTITYINSPHERE)(edict_t *pEdictStartSearchAfter, const float *org, float rad); -typedef edict_t *(*FN_FINDCLIENTINPVS)(edict_t *pEdict); -typedef edict_t *(*FN_ENTITIESINPVS)(edict_t *pplayer); -typedef void (*FN_MAKEVECTORS)(const float *rgflVector); -typedef void (*FN_ANGLEVECTORS)(const float *rgflVector, float *forward, float *right, float *up); -typedef edict_t *(*FN_CREATEENTITY)(); -typedef void (*FN_REMOVEENTITY)(edict_t *e); -typedef edict_t *(*FN_CREATENAMEDENTITY)(int className); -typedef void (*FN_MAKESTATIC)(edict_t *ent); -typedef int (*FN_ENTISONFLOOR)(edict_t *e); -typedef int (*FN_DROPTOFLOOR)(edict_t *e); -typedef int (*FN_WALKMOVE)(edict_t *ent, float yaw, float dist, int iMode); -typedef void (*FN_SETORIGIN)(edict_t *e, const float *rgflOrigin); -typedef void (*FN_EMITSOUND)(edict_t *entity, int channel, const char *sample, /*int*/float volume, float attenuation, int fFlags, int pitch); -typedef void (*FN_EMITAMBIENTSOUND)(edict_t *entity, float *pos, const char *samp, float vol, float attenuation, int fFlags, int pitch); -typedef void (*FN_TRACELINE)(const float *v1, const float *v2, int fNoMonsters, edict_t *pentToSkip, TraceResult *ptr); -typedef void (*FN_TRACETOSS)(edict_t *pent, edict_t *pentToIgnore, TraceResult *ptr); -typedef int (*FN_TRACEMONSTERHULL)(edict_t *pEdict, const float *v1, const float *v2, int fNoMonsters, edict_t *pentToSkip, TraceResult *ptr); -typedef void (*FN_TRACEHULL)(const float *v1, const float *v2, int fNoMonsters, int hullNumber, edict_t *pentToSkip, TraceResult *ptr); -typedef void (*FN_TRACEMODEL)(const float *v1, const float *v2, int hullNumber, edict_t *pent, TraceResult *ptr); -typedef const char *(*FN_TRACETEXTURE)(edict_t *pTextureEntity, const float *v1, const float *v2); -typedef void (*FN_TRACESPHERE)(const float *v1, const float *v2, int fNoMonsters, float radius, edict_t *pentToSkip, TraceResult *ptr); -typedef void (*FN_GETAIMVECTOR)(edict_t *ent, float speed, float *rgflReturn); -typedef void (*FN_SERVERCOMMAND)(char *str); -typedef void (*FN_SERVEREXECUTE)(); -typedef void (*FN_CLIENTCOMMAND_ENG)(edict_t *pEdict, char *szFmt, ...); -typedef void (*FN_PARTICLEEFFECT)(const float *org, const float *dir, float color, float count); -typedef void (*FN_LIGHTSTYLE)(int style, char *val); -typedef int (*FN_DECALINDEX)(const char *name); -typedef int (*FN_POINTCONTENTS)(const float *rgflVector); -typedef void (*FN_MESSAGEBEGIN)(int msg_dest, int msg_type, const float *pOrigin, edict_t *ed); -typedef void (*FN_MESSAGEEND)(); -typedef void (*FN_WRITEBYTE)(int iValue); -typedef void (*FN_WRITECHAR)(int iValue); -typedef void (*FN_WRITESHORT)(int iValue); -typedef void (*FN_WRITELONG)(int iValue); -typedef void (*FN_WRITEANGLE)(float flValue); -typedef void (*FN_WRITECOORD)(float flValue); -typedef void (*FN_WRITESTRING)(const char *sz); -typedef void (*FN_WRITEENTITY)(int iValue); -typedef void (*FN_CVARREGISTER)(cvar_t *pCvar); -typedef float (*FN_CVARGETFLOAT)(const char *szVarName); -typedef const char *(*FN_CVARGETSTRING)(const char *szVarName); -typedef void (*FN_CVARSETFLOAT)(const char *szVarName, float flValue); -typedef void (*FN_CVARSETSTRING)(const char *szVarName, const char *szValue); -typedef void (*FN_ALERTMESSAGE)(ALERT_TYPE atype, char *szFmt, ...); -typedef void (*FN_ENGINEFPRINTF)(void *pfile, char *szFmt, ...); -typedef void *(*FN_PVALLOCENTPRIVATEDATA)(edict_t *pEdict, int32 cb); -typedef void *(*FN_PVENTPRIVATEDATA)(edict_t *pEdict); -typedef void (*FN_FREEENTPRIVATEDATA)(edict_t *pEdict); -typedef const char *(*FN_SZFROMINDEX)(int iString); -typedef int (*FN_ALLOCSTRING)(const char *szValue); -typedef struct entvars_s *(*FN_GETVARSOFENT)(edict_t *pEdict); -typedef edict_t *(*FN_PENTITYOFENTOFFSET)(int iEntOffset); -typedef int (*FN_ENTOFFSETOFPENTITY)(const edict_t *pEdict); -typedef int (*FN_INDEXOFEDICT)(const edict_t *pEdict); -typedef edict_t *(*FN_PENTITYOFENTINDEX)(int iEntIndex); -typedef edict_t *(*FN_FINDENTITYBYVARS)(struct entvars_s *pvars); -typedef void *(*FN_GETMODELPTR)(edict_t *pEdict); -typedef int (*FN_REGUSERMSG)(const char *pszName, int iSize); -typedef void (*FN_ANIMATIONAUTOMOVE)(const edict_t *pEdict, float flTime); -typedef void (*FN_GETBONEPOSITION)(const edict_t *pEdict, int iBone, float *rgflOrigin, float *rgflAngles); -typedef uint32 (*FN_FUNCTIONFROMNAME)(const char *pName); -typedef const char *(*FN_NAMEFORFUNCTION)(uint32 function); -typedef void (*FN_CLIENTPRINTF)(edict_t *pEdict, PRINT_TYPE ptype, const char *szMsg); -typedef void (*FN_SERVERPRINT)(const char *szMsg); -typedef const char *(*FN_CMD_ARGS)(); -typedef const char *(*FN_CMD_ARGV)(int argc); -typedef int (*FN_CMD_ARGC)(); -typedef void (*FN_GETATTACHMENT)(const edict_t *pEdict, int iAttachment, float *rgflOrigin, float *rgflAngles); -typedef void (*FN_CRC32_INIT)(CRC32_t *pulCRC); -typedef void (*FN_CRC32_PROCESSBUFFER)(CRC32_t *pulCRC, void *p, int len); -typedef void (*FN_CRC32_PROCESSBYTE)(CRC32_t *pulCRC, unsigned char ch); -typedef CRC32_t (*FN_CRC32_FINAL)(CRC32_t pulCRC); -typedef int32 (*FN_RANDOMLONG)(int32 lLow, int32 lHigh); -typedef float (*FN_RANDOMFLOAT)(float flLow, float flHigh); -typedef void (*FN_SETVIEW)(const edict_t *pClient, const edict_t *pViewent); -typedef float (*FN_TIME)(); -typedef void (*FN_CROSSHAIRANGLE)(const edict_t *pClient, float pitch, float yaw); -typedef byte *(*FN_LOADFILEFORME)(char *filename, int *pLength); -typedef void (*FN_FREEFILE)(void *buffer); -typedef void (*FN_ENDSECTION)(const char *pszSectionName); -typedef int (*FN_COMPAREFILETIME)(char *filename1, char *filename2, int *iCompare); -typedef void (*FN_GETGAMEDIR)(char *szGetGameDir); -typedef void (*FN_CVAR_REGISTERVARIABLE)(cvar_t *variable); -typedef void (*FN_FADECLIENTVOLUME)(const edict_t *pEdict, int fadePercent, int fadeOutSeconds, int holdTime, int fadeInSeconds); -typedef void (*FN_SETCLIENTMAXSPEED)(const edict_t *pEdict, float fNewMaxspeed); -typedef edict_t *(*FN_CREATEFAKECLIENT)(const char *netname); -typedef void (*FN_RUNPLAYERMOVE)(edict_t *fakeclient, const float *viewangles, float forwardmove, float sidemove, float upmove, unsigned short buttons, byte impulse, byte msec); -typedef int (*FN_NUMBEROFENTITIES)(); -typedef char *(*FN_GETINFOKEYBUFFER)(edict_t *e); -typedef char *(*FN_INFOKEYVALUE)(char *infobuffer, char *key); -typedef void (*FN_SETKEYVALUE)(char *infobuffer, char *key, char *value); -typedef void (*FN_SETCLIENTKEYVALUE)(int clientIndex, char *infobuffer, char *key, char *value); -typedef int (*FN_ISMAPVALID)(char *filename); -typedef void (*FN_STATICDECAL)(const float *origin, int decalIndex, int entityIndex, int modelIndex); -typedef int (*FN_PRECACHEGENERIC)(char *s); -typedef int (*FN_GETPLAYERUSERID)(edict_t *e); -typedef void (*FN_BUILDSOUNDMSG)(edict_t *entity, int channel, const char *sample, /*int*/float volume, float attenuation, int fFlags, int pitch, int msg_dest, int msg_type, const float *pOrigin, edict_t *ed); -typedef int (*FN_ISDEDICATEDSERVER)(); -typedef cvar_t *(*FN_CVARGETPOINTER)(const char *szVarName); -typedef unsigned int (*FN_GETPLAYERWONID)(edict_t *e); -typedef void (*FN_INFO_REMOVEKEY)(char *s, const char *key); -typedef const char *(*FN_GETPHYSICSKEYVALUE)(const edict_t *pClient, const char *key); -typedef void (*FN_SETPHYSICSKEYVALUE)(const edict_t *pClient, const char *key, const char *value); -typedef const char *(*FN_GETPHYSICSINFOSTRING)(const edict_t *pClient); -typedef unsigned short (*FN_PRECACHEEVENT)(int type, const char *psz); -typedef void (*FN_PLAYBACKEVENT)(int flags, const edict_t *pInvoker, unsigned short eventindex, float delay, float *origin, float *angles, float fparam1, float fparam2, int iparam1, int iparam2, int bparam1, int bparam2); -typedef unsigned char *(*FN_SETFATPVS)(float *org); -typedef unsigned char *(*FN_SETFATPAS)(float *org); -typedef int (*FN_CHECKVISIBILITY)(const edict_t *entity, unsigned char *pset); -typedef void (*FN_DELTASETFIELD)(struct delta_s *pFields, const char *fieldname); -typedef void (*FN_DELTAUNSETFIELD)(struct delta_s *pFields, const char *fieldname); -typedef void (*FN_DELTAADDENCODER)(char *name, void (*conditionalencode)(struct delta_s *pFields, const unsigned char *from, const unsigned char *to)); -typedef int (*FN_GETCURRENTPLAYER)(); -typedef int (*FN_CANSKIPPLAYER)(const edict_t *player); -typedef int (*FN_DELTAFINDFIELD)(struct delta_s *pFields, const char *fieldname); -typedef void (*FN_DELTASETFIELDBYINDEX)(struct delta_s *pFields, int fieldNumber); -typedef void (*FN_DELTAUNSETFIELDBYINDEX)(struct delta_s *pFields, int fieldNumber); -typedef void (*FN_SETGROUPMASK)(int mask, int op); -typedef int (*FN_CREATEINSTANCEDBASELINE)(int classname, struct entity_state_s *baseline); -typedef void (*FN_CVAR_DIRECTSET)(struct cvar_s *var, char *value); -typedef void (*FN_FORCEUNMODIFIED)(FORCE_TYPE type, float *mins, float *maxs, const char *filename); -typedef void (*FN_GETPLAYERSTATS)(const edict_t *pClient, int *ping, int *packet_loss); -typedef void (*FN_ADDSERVERCOMMAND)(char *cmd_name, void (*function)()); -typedef qboolean (*FN_VOICE_GETCLIENTLISTENING)(int iReceiver, int iSender); -typedef qboolean (*FN_VOICE_SETCLIENTLISTENING)(int iReceiver, int iSender, qboolean bListen); -typedef const char *(*FN_GETPLAYERAUTHID)(edict_t *e); -typedef sequenceEntry_s *(*FN_SEQUENCEGET)(const char* fileName, const char* entryName); -typedef sentenceEntry_s *(*FN_SEQUENCEPICKSENTENCE)(const char* groupName, int pickMethod, int *picked); -typedef int (*FN_GETFILESIZE)(char *filename); -typedef unsigned int (*FN_GETAPPROXWAVEPLAYLEN)(const char *filepath); -typedef int (*FN_ISCAREERMATCH)(); -typedef int (*FN_GETLOCALIZEDSTRINGLENGTH)(const char *label); -typedef void (*FN_REGISTERTUTORMESSAGESHOWN)(int mid); -typedef int (*FN_GETTIMESTUTORMESSAGESHOWN)(int mid); -typedef void (*FN_PROCESSTUTORMESSAGEDECAYBUFFER)(int *buffer, int bufferLength); -typedef void (*FN_CONSTRUCTTUTORMESSAGEDECAYBUFFER)(int *buffer, int bufferLength); -typedef void (*FN_RESETTUTORMESSAGEDECAYDATA)(); -typedef void (*FN_QUERYCLIENTCVARVALUE)(const edict_t *player, const char *cvarName); -typedef void (*FN_QUERYCLIENTCVARVALUE2)(const edict_t *player, const char *cvarName, int requestID); -typedef void (*FN_ENGCHECKPARM)(const char *pchCmdLineToken, char **pchNextVal); + +typedef int (*FN_PRECACHEMODEL) (const char* s); +typedef int (*FN_PRECACHESOUND) (const char* s); +typedef void (*FN_SETMODEL) (edict_t *e, const char *m); +typedef int (*FN_MODELINDEX) (const char *m); +typedef int (*FN_MODELFRAMES) (int modelIndex); +typedef void (*FN_SETSIZE) (edict_t *e, const float *rgflMin, const float *rgflMax); +typedef void (*FN_CHANGELEVEL) (const char *s1, const char *s2); +typedef void (*FN_GETSPAWNPARMS) (edict_t *ent); +typedef void (*FN_SAVESPAWNPARMS) (edict_t *ent); +typedef float (*FN_VECTOYAW) (const float *rgflVector); +typedef void (*FN_VECTOANGLES) (const float *rgflVectorIn, float *rgflVectorOut); +typedef void (*FN_MOVETOORIGIN) (edict_t *ent, const float *pflGoal, float dist, int iMoveType); +typedef void (*FN_CHANGEYAW) (edict_t *ent); +typedef void (*FN_CHANGEPITCH) (edict_t *ent); +typedef edict_t * (*FN_FINDENTITYBYSTRING) (edict_t *pEdictStartSearchAfter, const char *pszField, const char *pszValue); +typedef int (*FN_GETENTITYILLUM) (edict_t *pEnt); +typedef edict_t * (*FN_FINDENTITYINSPHERE) (edict_t *pEdictStartSearchAfter, const float *org, float rad); +typedef edict_t * (*FN_FINDCLIENTINPVS) (edict_t *pEdict); +typedef edict_t * (*FN_ENTITIESINPVS) (edict_t *pplayer); +typedef void (*FN_MAKEVECTORS) (const float *rgflVector); +typedef void (*FN_ANGLEVECTORS) (const float *rgflVector, float *forward, float *right, float *up); +typedef edict_t * (*FN_CREATEENTITY) (void); +typedef void (*FN_REMOVEENTITY) (edict_t *e); +typedef edict_t * (*FN_CREATENAMEDENTITY) (int className); +typedef void (*FN_MAKESTATIC) (edict_t *ent); +typedef int (*FN_ENTISONFLOOR) (edict_t *e); +typedef int (*FN_DROPTOFLOOR) (edict_t *e); +typedef int (*FN_WALKMOVE) (edict_t *ent, float yaw, float dist, int iMode); +typedef void (*FN_SETORIGIN) (edict_t *e, const float *rgflOrigin); +typedef void (*FN_EMITSOUND) (edict_t *entity, int channel, const char *sample, /*int*/float volume, float attenuation, int fFlags, int pitch); +typedef void (*FN_EMITAMBIENTSOUND) (edict_t *entity, float *pos, const char *samp, float vol, float attenuation, int fFlags, int pitch); +typedef void (*FN_TRACELINE) (const float *v1, const float *v2, int fNoMonsters, edict_t *pentToSkip, TraceResult *ptr); +typedef void (*FN_TRACETOSS) (edict_t *pent, edict_t *pentToIgnore, TraceResult *ptr); +typedef int (*FN_TRACEMONSTERHULL) (edict_t *pEdict, const float *v1, const float *v2, int fNoMonsters, edict_t *pentToSkip, TraceResult *ptr); +typedef void (*FN_TRACEHULL) (const float *v1, const float *v2, int fNoMonsters, int hullNumber, edict_t *pentToSkip, TraceResult *ptr); +typedef void (*FN_TRACEMODEL) (const float *v1, const float *v2, int hullNumber, edict_t *pent, TraceResult *ptr); +typedef const char * (*FN_TRACETEXTURE) (edict_t *pTextureEntity, const float *v1, const float *v2 ); +typedef void (*FN_TRACESPHERE) (const float *v1, const float *v2, int fNoMonsters, float radius, edict_t *pentToSkip, TraceResult *ptr); +typedef void (*FN_GETAIMVECTOR) (edict_t *ent, float speed, float *rgflReturn); +typedef void (*FN_SERVERCOMMAND) (char *str); +typedef void (*FN_SERVEREXECUTE) (void); +typedef void (*FN_CLIENTCOMMAND_ENG) (edict_t *pEdict, char *szFmt, ...); +typedef void (*FN_PARTICLEEFFECT) (const float *org, const float *dir, float color, float count); +typedef void (*FN_LIGHTSTYLE) (int style, char *val); +typedef int (*FN_DECALINDEX) (const char *name); +typedef int (*FN_POINTCONTENTS) (const float *rgflVector); +typedef void (*FN_MESSAGEBEGIN) (int msg_dest, int msg_type, const float *pOrigin, edict_t *ed); +typedef void (*FN_MESSAGEEND) (void); +typedef void (*FN_WRITEBYTE) (int iValue); +typedef void (*FN_WRITECHAR) (int iValue); +typedef void (*FN_WRITESHORT) (int iValue); +typedef void (*FN_WRITELONG) (int iValue); +typedef void (*FN_WRITEANGLE) (float flValue); +typedef void (*FN_WRITECOORD) (float flValue); +typedef void (*FN_WRITESTRING) (const char *sz); +typedef void (*FN_WRITEENTITY) (int iValue); +typedef void (*FN_CVARREGISTER) (cvar_t *pCvar); +typedef float (*FN_CVARGETFLOAT) (const char *szVarName); +typedef const char * (*FN_CVARGETSTRING) (const char *szVarName); +typedef void (*FN_CVARSETFLOAT) (const char *szVarName, float flValue); +typedef void (*FN_CVARSETSTRING) (const char *szVarName, const char *szValue); +typedef void (*FN_ALERTMESSAGE) (ALERT_TYPE atype, const char *szFmt, ...); +#ifdef HLSDK_3_2_OLD_EIFACE +typedef void (*FN_ENGINEFPRINTF) (FILE *pfile, const char *szFmt, ...); +typedef void * (*FN_PVALLOCENTPRIVATEDATA) (edict_t *pEdict, long cb); +#else +typedef void (*FN_ENGINEFPRINTF) (void *pfile, const char *szFmt, ...); +typedef void * (*FN_PVALLOCENTPRIVATEDATA) (edict_t *pEdict, int32 cb); +#endif +typedef void * (*FN_PVENTPRIVATEDATA) (edict_t *pEdict); +typedef void (*FN_FREEENTPRIVATEDATA) (edict_t *pEdict); +typedef const char * (*FN_SZFROMINDEX) (int iString); +typedef int (*FN_ALLOCSTRING) (const char *szValue); +typedef struct entvars_s * (*FN_GETVARSOFENT) (edict_t *pEdict); +typedef edict_t * (*FN_PENTITYOFENTOFFSET) (int iEntOffset); +typedef int (*FN_ENTOFFSETOFPENTITY) (const edict_t *pEdict); +typedef int (*FN_INDEXOFEDICT) (const edict_t *pEdict); +typedef edict_t * (*FN_PENTITYOFENTINDEX) (int iEntIndex); +typedef edict_t * (*FN_FINDENTITYBYVARS) (struct entvars_s *pvars); +typedef void * (*FN_GETMODELPTR) (edict_t *pEdict); +typedef int (*FN_REGUSERMSG) (const char *pszName, int iSize); +typedef void (*FN_ANIMATIONAUTOMOVE) (const edict_t *pEdict, float flTime); +typedef void (*FN_GETBONEPOSITION) (const edict_t *pEdict, int iBone, float *rgflOrigin, float *rgflAngles ); +#ifdef HLSDK_3_2_OLD_EIFACE +typedef unsigned long (*FN_FUNCTIONFROMNAME) ( const char *pName ); +typedef const char * (*FN_NAMEFORFUNCTION) ( unsigned long function ); +#else +typedef uint32 (*FN_FUNCTIONFROMNAME) ( const char *pName ); +typedef const char * (*FN_NAMEFORFUNCTION) ( uint32 function ); +#endif +typedef void (*FN_CLIENTPRINTF) ( edict_t *pEdict, PRINT_TYPE ptype, const char *szMsg ); +typedef void (*FN_SERVERPRINT) ( const char *szMsg ); +typedef const char * (*FN_CMD_ARGS) ( void ); +typedef const char * (*FN_CMD_ARGV) ( int argc ); +typedef int (*FN_CMD_ARGC) ( void ); +typedef void (*FN_GETATTACHMENT) (const edict_t *pEdict, int iAttachment, float *rgflOrigin, float *rgflAngles ); +typedef void (*FN_CRC32_INIT) (CRC32_t *pulCRC); +typedef void (*FN_CRC32_PROCESSBUFFER) (CRC32_t *pulCRC, void *p, int len); +typedef void (*FN_CRC32_PROCESSBYTE) (CRC32_t *pulCRC, unsigned char ch); +typedef CRC32_t (*FN_CRC32_FINAL) (CRC32_t pulCRC); +#ifdef HLSDK_3_2_OLD_EIFACE +typedef long (*FN_RANDOMLONG) (long lLow, long lHigh); +#else +typedef int32 (*FN_RANDOMLONG) (int32 lLow, int32 lHigh); +#endif +typedef float (*FN_RANDOMFLOAT) (float flLow, float flHigh); +typedef void (*FN_SETVIEW) (const edict_t *pClient, const edict_t *pViewent ); +typedef float (*FN_TIME) ( void ); +typedef void (*FN_CROSSHAIRANGLE) (const edict_t *pClient, float pitch, float yaw); +typedef byte * (*FN_LOADFILEFORME) (char *filename, int *pLength); +typedef void (*FN_FREEFILE) (void *buffer); +typedef void (*FN_ENDSECTION) (const char *pszSectionName); +typedef int (*FN_COMPAREFILETIME) (char *filename1, char *filename2, int *iCompare); +typedef void (*FN_GETGAMEDIR) (char *szGetGameDir); +typedef void (*FN_CVAR_REGISTERVARIABLE) (cvar_t *variable); +typedef void (*FN_FADECLIENTVOLUME) (const edict_t *pEdict, int fadePercent, int fadeOutSeconds, int holdTime, int fadeInSeconds); +typedef void (*FN_SETCLIENTMAXSPEED) (edict_t *pEdict, float fNewMaxspeed); +typedef edict_t * (*FN_CREATEFAKECLIENT) (const char *netname); +typedef void (*FN_RUNPLAYERMOVE) (edict_t *fakeclient, const float *viewangles, float forwardmove, float sidemove, float upmove, unsigned short buttons, byte impulse, byte msec ); +typedef int (*FN_NUMBEROFENTITIES) (void); +typedef char * (*FN_GETINFOKEYBUFFER) (edict_t *e); +typedef char * (*FN_INFOKEYVALUE) (char *infobuffer, const char *key); +typedef void (*FN_SETKEYVALUE) (char *infobuffer, const char *key, const char *value); +typedef void (*FN_SETCLIENTKEYVALUE) (int clientIndex, char *infobuffer, const char *key, const char *value); +typedef int (*FN_ISMAPVALID) (char *filename); +typedef void (*FN_STATICDECAL) ( const float *origin, int decalIndex, int entityIndex, int modelIndex ); +typedef int (*FN_PRECACHEGENERIC) (char *s); +typedef int (*FN_GETPLAYERUSERID) (edict_t *e ); +typedef void (*FN_BUILDSOUNDMSG) (edict_t *entity, int channel, const char *sample, /*int*/float volume, float attenuation, int fFlags, int pitch, int msg_dest, int msg_type, const float *pOrigin, edict_t *ed); +typedef int (*FN_ISDEDICATEDSERVER) (void); +typedef cvar_t * (*FN_CVARGETPOINTER) (const char *szVarName); +typedef unsigned int (*FN_GETPLAYERWONID) (edict_t *e); +typedef void (*FN_INFO_REMOVEKEY) ( char *s, const char *key ); +typedef const char * (*FN_GETPHYSICSKEYVALUE) ( const edict_t *pClient, const char *key ); +typedef void (*FN_SETPHYSICSKEYVALUE) ( const edict_t *pClient, const char *key, const char *value ); +typedef const char * (*FN_GETPHYSICSINFOSTRING) ( const edict_t *pClient ); +typedef unsigned short (*FN_PRECACHEEVENT) ( int type, const char *psz ); +typedef void (*FN_PLAYBACKEVENT) ( int flags, const edict_t *pInvoker, unsigned short eventindex, float delay, float *origin, float *angles, float fparam1, float fparam2, int iparam1, int iparam2, int bparam1, int bparam2 ); +typedef unsigned char * (*FN_SETFATPVS) ( float *org ); +typedef unsigned char * (*FN_SETFATPAS) ( float *org ); +typedef int (*FN_CHECKVISIBILITY) ( edict_t *entity, unsigned char *pset ); +typedef void (*FN_DELTASETFIELD) ( struct delta_s *pFields, const char *fieldname ); +typedef void (*FN_DELTAUNSETFIELD) ( struct delta_s *pFields, const char *fieldname ); +typedef void (*FN_DELTAADDENCODER) ( char *name, void (*conditionalencode)( struct delta_s *pFields, const unsigned char *from, const unsigned char *to ) ); +typedef int (*FN_GETCURRENTPLAYER) ( void ); +typedef int (*FN_CANSKIPPLAYER) ( const edict_t *player ); +typedef int (*FN_DELTAFINDFIELD) ( struct delta_s *pFields, const char *fieldname ); +typedef void (*FN_DELTASETFIELDBYINDEX) ( struct delta_s *pFields, int fieldNumber ); +typedef void (*FN_DELTAUNSETFIELDBYINDEX) ( struct delta_s *pFields, int fieldNumber ); +typedef void (*FN_SETGROUPMASK) ( int mask, int op ); +typedef int (*FN_CREATEINSTANCEDBASELINE) ( int classname, struct entity_state_s *baseline ); +typedef void (*FN_CVAR_DIRECTSET) ( struct cvar_s *var, const char *value ); +typedef void (*FN_FORCEUNMODIFIED) ( FORCE_TYPE type, float *mins, float *maxs, const char *filename ); +typedef void (*FN_GETPLAYERSTATS) ( const edict_t *pClient, int *ping, int *packet_loss ); +typedef void (*FN_ADDSERVERCOMMAND) ( char *cmd_name, void (*function) (void) ); +// Added in SDK 2.2: +typedef qboolean (*FN_VOICE_GETCLIENTLISTENING) (int iReceiver, int iSender); +typedef qboolean (*FN_VOICE_SETCLIENTLISTENING) (int iReceiver, int iSender, qboolean bListen); +// Added for HL 1109 (no SDK update): +typedef const char * (*FN_GETPLAYERAUTHID) (edict_t *e); +// Added 2003-11-10 (no SDK update): +typedef sequenceEntry_s * (*FN_SEQUENCEGET) (const char* fileName, const char* entryName); +typedef sentenceEntry_s * (*FN_SEQUENCEPICKSENTENCE) (const char* groupName, int pickMethod, int *picked); +typedef int (*FN_GETFILESIZE) (char *filename); +typedef unsigned int (*FN_GETAPPROXWAVEPLAYLEN) (const char *filepath); +typedef int (*FN_ISCAREERMATCH) (void); +typedef int (*FN_GETLOCALIZEDSTRINGLENGTH) (const char *label); +typedef void (*FN_REGISTERTUTORMESSAGESHOWN) (int mid); +typedef int (*FN_GETTIMESTUTORMESSAGESHOWN) (int mid); +typedef void (*FN_PROCESSTUTORMESSAGEDECAYBUFFER) (int *buffer, int bufferLength); +typedef void (*FN_CONSTRUCTTUTORMESSAGEDECAYBUFFER) (int *buffer, int bufferLength); +typedef void (*FN_RESETTUTORMESSAGEDECAYDATA) (void); +//Added 2005-08-11 (no SDK update) +typedef void (*FN_QUERYCLIENTCVARVALUE)(const edict_t *pEdict, const char *cvarName); //! Obsolete! Use FN_QUERYCLIENTCVARVALUE2 instead +//Added 2005-11-22 (no SDK update) +typedef void (*FN_QUERYCLIENTCVARVALUE2)(const edict_t *pEdict, const char *cvarName, int requestID); +//Added 2009-06-17 (no SDK update) +typedef int (*FN_CHECKPARM)(const char *pchCmdLineToken, char **ppnext); + +#endif /* ENGINE_API_H */ diff --git a/metamod/src/engine_t.h b/metamod/src/engine_t.h index 1d958b9..235fa1e 100644 --- a/metamod/src/engine_t.h +++ b/metamod/src/engine_t.h @@ -1,34 +1,54 @@ -#pragma once +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// engine_t.h - The engine_t type + +/* + * Copyright (c) 2001-2006 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game g_engine ("HL + * g_engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL g_engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + +#ifndef MM_ENGINE_T_H +#define MM_ENGINE_T_H #include "eiface.h" // engfuncs_t, globalvars_t // Our structure for storing engine references. struct engine_t { - engine_t(); - engine_t(const engine_t&); - engine_t& operator=(const engine_t&); + engine_t() : funcs(NULL), globals(NULL), pl_funcs(NULL) {} - enginefuncs_t *funcs; // engine funcs - globalvars_t *globals; // engine globals - enginefuncs_t *pl_funcs; // "modified" eng funcs we give to plugins + enginefuncs_t *funcs; // engine funcs + globalvars_t *globals; // engine globals + enginefuncs_t *pl_funcs; // "modified" eng funcs we give to plugins }; -inline engine_t::engine_t() - : funcs(NULL), globals(NULL), pl_funcs(NULL) -{ -} +extern engine_t g_engine; -inline engine_t::engine_t(const engine_t& _rhs) - : funcs(_rhs.funcs), globals(_rhs.globals), pl_funcs(_rhs.pl_funcs) -{ -} +#endif /* MM_ENGINE_T_H */ -inline engine_t& engine_t::operator=(const engine_t& _rhs) -{ - funcs = _rhs.funcs; - globals = _rhs.globals; - pl_funcs = _rhs.pl_funcs; - return *this; -} - -extern engine_t Engine; diff --git a/metamod/src/enginecallbacks.h b/metamod/src/enginecallbacks.h index 8b8ec23..5eb38bd 100644 --- a/metamod/src/enginecallbacks.h +++ b/metamod/src/enginecallbacks.h @@ -23,10 +23,10 @@ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * In addition, as a special exception, the author gives permission to - * link the code of this program with the Half-Life Game Engine ("HL - * Engine") and Modified Game Libraries ("MODs") developed by Valve, + * link the code of this program with the Half-Life Game g_engine ("HL + * g_engine") and Modified Game Libraries ("MODs") developed by Valve, * L.L.C ("Valve"). You must obey the GNU General Public License in all - * respects for all of the code used other than the HL Engine and MODs + * respects for all of the code used other than the HL g_engine and MODs * from Valve. If you modify this file, you may extend this exception * to your version of the file, but you are not obligated to do so. If * you do not wish to do so, delete this exception statement from your @@ -47,30 +47,30 @@ // "hack" our way around that by using a flag METAMOD_CORE which is set // when compiling Metamod proper. -#ifdef __METAMOD_BUILD__ -#include "meta_eiface.h" // HL_enginefuncs_t +#ifdef METAMOD_CORE +# include "meta_eiface.h" // HL_enginefuncs_t // Use a #define to bend the enginefuncs_t type to our HL_enginefuncs_t // type instead as we now use that for the global object g_engfuncs. -#define enginefuncs_t HL_enginefuncs_t +# define enginefuncs_t HL_enginefuncs_t #endif /* METAMOD_CORE */ #include // ALERT, etc -#ifdef __METAMOD_BUILD__ -#undef enginefuncs_t +#ifdef METAMOD_CORE +# undef enginefuncs_t #endif /* METAMOD_CORE */ // Also, create some additional macros for engine callback functions, which // weren't in SDK dlls/enginecallbacks.h but probably should have been. -#define GET_INFOKEYBUFFER (*g_engfuncs.pfnGetInfoKeyBuffer) -#define INFOKEY_VALUE (*g_engfuncs.pfnInfoKeyValue) -#define SET_CLIENT_KEYVALUE (*g_engfuncs.pfnSetClientKeyValue) -#define REG_SVR_COMMAND (*g_engfuncs.pfnAddServerCommand) -#define SERVER_PRINT (*g_engfuncs.pfnServerPrint) -#define SET_SERVER_KEYVALUE (*g_engfuncs.pfnSetKeyValue) -#define QUERY_CLIENT_CVAR_VALUE (*g_engfuncs.pfnQueryClientCvarValue) +#define GET_INFOKEYBUFFER (*g_engfuncs.pfnGetInfoKeyBuffer) +#define INFOKEY_VALUE (*g_engfuncs.pfnInfoKeyValue) +#define SET_CLIENT_KEYVALUE (*g_engfuncs.pfnSetClientKeyValue) +#define REG_SVR_COMMAND (*g_engfuncs.pfnAddServerCommand) +#define SERVER_PRINT (*g_engfuncs.pfnServerPrint) +#define SET_SERVER_KEYVALUE (*g_engfuncs.pfnSetKeyValue) +#define QUERY_CLIENT_CVAR_VALUE (*g_engfuncs.pfnQueryClientCvarValue) #define QUERY_CLIENT_CVAR_VALUE2 (*g_engfuncs.pfnQueryClientCvarValue2) diff --git a/metamod/src/game_support.cpp b/metamod/src/game_support.cpp index 04e4f2f..9eb5053 100644 --- a/metamod/src/game_support.cpp +++ b/metamod/src/game_support.cpp @@ -1,81 +1,109 @@ +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// game_support.cpp - info to recognize different HL mod "games" + +/* + * Copyright (c) 2001-2013 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game g_engine ("HL + * g_engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL g_engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + #include "precompiled.h" // Adapted from adminmod h_export.cpp: //! this structure contains a list of supported mods and their dlls names -//! To add support for another mod add an entry here, and add all the +//! To add support for another mod add an entry here, and add all the //! exported entities to link_func.cpp -const game_modinfo_t known_games[] = { - // name/gamedir linux_so win_dll desc +game_modlist_t known_games = { + // name/gamedir linux_so win_dll osx_dylib desc // // Previously enumerated in this sourcefile, the list is now kept in a - // separate file, generated based on game information stored in a + // separate file, generated based on game information stored in a // convenient db. - { "cstrike", "cs.so", "mp.dll", "Counter-Strike" }, - { "czero", "cs.so", "mp.dll", "Counter-Strike:Condition Zero" }, + // +#include "games.h" + // End of list terminator: - { NULL, NULL, NULL, NULL } + {NULL, NULL, NULL, NULL, NULL} }; // Find a modinfo corresponding to the given game name. -inline const game_modinfo_t *lookup_game(const char *name) +game_modinfo_t* lookup_game(const char* name) { - for (auto& known : known_games) - { - if (known.name && Q_stricmp(known.name, name)) - return &known; + for (int i = 0; known_games[i].name; i++) { + auto imod = &known_games[i]; + if (strcasematch(imod->name, name)) + return imod; } - // no match found - return nullptr; + return NULL; } -// Installs gamedll from Steam cache -mBOOL install_gamedll(char *from, const char *to) +mBOOL install_gamedll(char* from, const char* to) { int length_in; int length_out; - if (!from) - return mFALSE; + if (NULL == from) return mFALSE; + if (NULL == to) to = from; - if (!to) - to = from; - - byte *cachefile = LOAD_FILE_FOR_ME(from, &length_in); + byte* cachefile = LOAD_FILE_FOR_ME(from, &length_in); // If the file seems to exist in the cache. - if (cachefile) - { + if (NULL != cachefile) { + int fd = open(to, O_WRONLY | O_CREAT | O_EXCL | O_BINARY, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); - if (fd < 0) - { - META_DEBUG(3, ("Installing gamedll from cache: Failed to create file %s: %s", to, strerror(errno)) ); + if (fd < 0) { + META_DEBUG(3, ("Installing gamedll from cache: Failed to create file %s: %s\n", to, strerror(errno)) ); FREE_FILE(cachefile); return mFALSE; } - length_out=write(fd, cachefile, length_in); + length_out = write(fd, cachefile, length_in); FREE_FILE(cachefile); close(fd); // Writing the file was not successfull - if (length_out != length_in) - { - META_DEBUG(3,("Installing gamedll from chache: Failed to write all %d bytes to file, only %d written: %s", length_in, length_out, strerror(errno))); - + if (length_out != length_in) { + META_DEBUG(3,("Installing gamedll from cache: Failed to write all %d bytes to file, only %d written: %s\n", + length_in, length_out, strerror(errno)) ); // Let's not leave a mess but clean up nicely. - if (length_out >= 0) - unlink(to); - + if (length_out >= 0) _unlink(to); return mFALSE; } - META_LOG("Installed gamedll %s from cache.", to); + META_LOG("Installed gamedll %s from cache.\n", to); + } - else - { - META_DEBUG(3, ("Failed to install gamedll from cache: file %s not found in cache.", from)); + else { + META_DEBUG(3, ("Failed to install gamedll from cache: file %s not found in cache.\n", from) ); return mFALSE; } @@ -83,64 +111,167 @@ mBOOL install_gamedll(char *from, const char *to) } // Set all the fields in the gamedll struct, - based either on an entry in -// known_games matching the current gamedir, or on one specified manually +// known_games matching the current gamedir, or on one specified manually // by the server admin. // // meta_errno values: // - ME_NOTFOUND couldn't recognize game -mBOOL setup_gamedll(gamedll_t *gamedll) +mBOOL setup_gamedll(gamedll_t* gamedll) { - const game_modinfo_t *known; - const char *knownfn = nullptr; + static char override_desc_buf[256]; + game_modinfo_t* known; + const char* cp; + const char* knownfn = 0; + const char* usedfn = 0; + char* strippedfn = 0; + bool override = false; // Check for old-style "metagame.ini" file and complain. if (valid_gamedir_file(OLD_GAMEDLL_TXT)) - { - META_WARNING("File '%s' is no longer supported; instead, specify override gamedll in %s or with '+localinfo mm_gamedll '", OLD_GAMEDLL_TXT, CONFIG_INI); - } + META_ERROR("File '%s' is no longer supported; instead, specify override gamedll in %s or with '+localinfo mm_gamedll '", OLD_GAMEDLL_TXT, CONFIG_INI); // First, look for a known game, based on gamedir. - if ((known = lookup_game(gamedll->name))) - { + if ((known = lookup_game(gamedll->name))) { #ifdef _WIN32 - knownfn = known->win_dll; + knownfn = _strdup(known->win_dll); +#elif defined(linux) + knownfn=_strdup(known->linux_so); +#elif defined(__APPLE__) + knownfn=_strdup(known->osx_dylib); #else - knownfn = known->linux_so; -#endif +#error "OS unrecognized" +#endif /* _WIN32 */ + } - META_DEBUG(4, ("Checking for old version game DLL name '%s'.\n", knownfn)); - safevoid_snprintf(gamedll->pathname, sizeof(gamedll->pathname), "dlls/%s", knownfn); + // Neither override nor auto-detect found a gamedll. + if (!known && !g_config->gamedll) + RETURN_ERRNO(mFALSE, ME_NOTFOUND); - // Check if the gamedll file exists. If not, try to install it from the cache. - if (!valid_gamedir_file(gamedll->pathname)) - { - safevoid_snprintf(gamedll->real_pathname, sizeof(gamedll->real_pathname), "%s/dlls/%s", gamedll->gamedir, knownfn); - install_gamedll(gamedll->pathname, gamedll->real_pathname); + // Use override-dll if specified. + if (g_config->gamedll) { + strncpy(gamedll->pathname, g_config->gamedll, sizeof gamedll->pathname - 1); + gamedll->pathname[sizeof gamedll->pathname - 1] = '\0'; + override = true; + + // If the path is relative, the gamedll file will be missing and + // it might be found in the cache file. + if (!is_absolute_path(gamedll->pathname)) { + // I abuse the real_pathname member here to pass a full pathname to + // the install_gamedll function. I am somewhat opposed to be pushing + // another MAX_PATH sized array on the stack, that's why. + snprintf(gamedll->real_pathname, sizeof(gamedll->real_pathname), "%s/%s", gamedll->gamedir, gamedll->pathname); + // If we could successfully install the gamedll from the cache we + // rectify the pathname to be a full pathname. + if (install_gamedll(gamedll->pathname, gamedll->real_pathname)) { + strncpy(gamedll->pathname, gamedll->real_pathname, sizeof gamedll->pathname - 1); + gamedll->pathname[sizeof gamedll->pathname - 1] = '\0'; + } } } - else - { - // Neither known-list found a gamedll. - RETURN_ERRNO(mFALSE, ME_NOTFOUND); + // Else use Auto-detect dll. + else { +#ifdef linux + // The engine changed game dll lookup behaviour in that it strips + // anything after the last '_' from the name and tries to load the + // resulting name. The DSO names were changed and do not have the + // '_i386' part in them anymore, so cs_i386.so became cs.so. We + // have to adapt to that and try to load the DSO name without the + // '_*' part first, to see if we have a new version file available. + + strippedfn = _strdup(knownfn); + + char *loc = strrchr(strippedfn, '_'); + + // A small safety net here: make sure that we are dealing with + // a file name at least four characters long and ending in + // '.so'. This way we can be sure that we can safely overwrite + // anything from the '_' on with '.so'. + int size = 0; + const char *ext; + if(0 != loc) { + size = strlen(strippedfn); + ext = strippedfn + (size - 3); + } + + if(0 != loc && size > 3 && 0 == _stricmp(ext, ".so")) { + + strcpy(loc, ".so"); + META_DEBUG(4, ("Checking for new version game DLL name '%s'.\n", strippedfn) ); + + // Again, as above, I abuse the real_pathname member to store the full pathname + // and the pathname member to store the relative name to pass it to the + // install_gamedll function to save stack space. They are going + // to get overwritten later on, so that's ok. + snprintf(gamedll->pathname, sizeof(gamedll->pathname), "dlls/%s", + strippedfn); + // Check if the gamedll file exists. If not, try to install it from + // the cache. + mBOOL ok = mTRUE; + if(!valid_gamedir_file(gamedll->pathname)) { + snprintf(gamedll->real_pathname, sizeof(gamedll->real_pathname), "%s/dlls/%s", + gamedll->gamedir, strippedfn); + ok = install_gamedll(gamedll->pathname, gamedll->real_pathname); + } + if(ok) usedfn = strippedfn; + } + else { + META_DEBUG(4, ("Known game DLL name does not qualify for checking for a stripped version, skipping: '%s'.\n", + strippedfn) ); + } +#endif /* linux */ + + // If no file to be used was found, try the old known DLL file + // name. + if (0 == usedfn) { + META_DEBUG(4, ("Checking for old version game DLL name '%s'.\n", knownfn) ); + snprintf(gamedll->pathname, sizeof(gamedll->pathname), "dlls/%s", knownfn); + // Check if the gamedll file exists. If not, try to install it from + // the cache. + if (!valid_gamedir_file(gamedll->pathname)) { + snprintf(gamedll->real_pathname, sizeof(gamedll->real_pathname), "%s/dlls/%s", + gamedll->gamedir, knownfn); + install_gamedll(gamedll->pathname, gamedll->real_pathname); + } + usedfn = knownfn; + } + + // Now make an absolute path + snprintf(gamedll->pathname, sizeof(gamedll->pathname), "%s/dlls/%s", + gamedll->gamedir, usedfn); } - - safevoid_snprintf(gamedll->pathname, sizeof(gamedll->pathname), "%s/dlls/%s", gamedll->gamedir, knownfn); - // get filename from pathname - char *cp = Q_strrchr(gamedll->pathname, '/'); - if (cp) - cp++; - else - cp = gamedll->pathname; - + cp = strrchr(gamedll->pathname, '/'); + if (cp) cp++; + else cp = gamedll->pathname; gamedll->file = cp; - Q_strncpy(gamedll->real_pathname, gamedll->pathname, sizeof(gamedll->real_pathname) - 1); - gamedll->real_pathname[sizeof(gamedll->real_pathname) - 1] = '\0'; + // If found, store also the supposed "real" dll path based on the + // gamedir, in case it differs from the "override" dll path. + if (known && override) + snprintf(gamedll->real_pathname, sizeof(gamedll->real_pathname), + "%s/dlls/%s", gamedll->gamedir, usedfn); + else { // !known or !override + strncpy(gamedll->real_pathname, gamedll->pathname, sizeof gamedll->real_pathname - 1); + gamedll->real_pathname[sizeof gamedll->pathname - 1] = '\0'; + } - gamedll->desc = known->desc; - META_LOG("Recognized game '%s'; using dllfile '%s'", gamedll->name, gamedll->file); + if (override) { + // generate a desc + snprintf(override_desc_buf, sizeof(override_desc_buf), + "%s (override)", gamedll->file); + gamedll->desc = override_desc_buf; + // log result + META_LOG("Overriding game '%s' with dllfile '%s'", gamedll->name, + gamedll->file); + } + else { + gamedll->desc = known->desc; + META_LOG("Recognized game '%s'; using dllfile '%s'", gamedll->name, + gamedll->file); + } - return mTRUE; + if (0 != strippedfn) free(strippedfn); + + return (mTRUE); } diff --git a/metamod/src/game_support.h b/metamod/src/game_support.h index 04978a5..8523d43 100644 --- a/metamod/src/game_support.h +++ b/metamod/src/game_support.h @@ -1,15 +1,56 @@ -#pragma once +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// game_support.h - structures for supporting different HL mod "games" + +/* + * Copyright (c) 2001-2003 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game g_engine ("HL + * g_engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL g_engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + +#ifndef GAME_SUPPORT_H +#define GAME_SUPPORT_H #include "types_meta.h" // mBOOL #include "metamod.h" // gamedll_t // Information we have about each game/mod DLL. -struct game_modinfo_t { - const char *name; // name (the game dir) +typedef struct game_modinfo_s { + const char *name; // name (the game dir) const char *linux_so; // filename of linux shared lib const char *win_dll; // filename of win32 dll - const char *desc; // our long-name description -}; + const char *osx_dylib; // filename os osx dylib + const char *desc; // our long-name description +} game_modinfo_t; -const game_modinfo_t *lookup_game(const char *name); +typedef game_modinfo_t game_modlist_t[]; +game_modinfo_t *lookup_game(const char *name); mBOOL setup_gamedll(gamedll_t *gamedll); + +#endif /* GAME_SUPPORT_H */ diff --git a/metamod/src/games.h b/metamod/src/games.h new file mode 100644 index 0000000..a5773e5 --- /dev/null +++ b/metamod/src/games.h @@ -0,0 +1,131 @@ +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// games.h - list of supported game mods and their data + +/* + * Copyright (c) 2001-2008 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game Engine ("HL + * Engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL Engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + +// This list is now kept in a separate file to facilitate generating the +// list from game data stored in a convenient db. + +#ifdef __amd64__ +# define MODARCH "_amd64" +#else +# define MODARCH "_i386" +#endif + +{"action", "ahl"MODARCH".so", "ahl.dll", "none", "Action Half-Life"}, +{"ag", "ag"MODARCH".so", "ag.dll", "none", "Adrenaline Gamer Steam"}, +{"ag3", "hl"MODARCH".so", "hl.dll", "none", "Adrenalinegamer 3.x"}, +{"aghl", "ag"MODARCH".so", "ag.dll", "none", "Adrenalinegamer 4.x"}, +{"arg", "arg"MODARCH".so", "hl.dll", "none", "Arg!"}, +{"asheep", "hl"MODARCH".so", "hl.dll", "none", "Azure Sheep"}, +{"bg", "bg"MODARCH".so", "bg.dll", "none", "The Battle Grounds"}, +{"bot", "bot"MODARCH".so", "bot.dll", "none", "Bot"}, +{"brainbread", "bb"MODARCH".so", "bb.dll", "none", "Brain Bread"}, +{"bumpercars", "hl"MODARCH".so", "hl.dll", "none", "Bumper Cars"}, +{"buzzybots", "bb"MODARCH".so", "bb.dll", "none", "BuzzyBots"}, +{"cs13", "cs"MODARCH".so", "mp.dll", "none", "Counter-Strike 1.3"}, +{"cstrike", "cs"MODARCH".so", "mp.dll", "cs.dylib", "Counter-Strike"}, +{"csv15", "cs"MODARCH".so", "mp.dll", "none", "CS 1.5 for Steam"}, +{"czero", "cs"MODARCH".so", "mp.dll", "cs.dylib", "Counter-Strike:Condition Zero"}, +{"dcrisis", "dc"MODARCH".so", "dc.dll", "none", "Desert Crisis"}, +{"dmc", "dmc"MODARCH".so", "dmc.dll", "dmc.dylib", "Deathmatch Classic"}, +{"dod", "dod"MODARCH".so", "dod.dll", "dod.dylib", "Day of Defeat"}, +{"dpb", "pb.i386.so", "pb.dll", "none", "Digital Paintball"}, +{"dragonmodz", "hl"MODARCH".so", "mp.dll", "none", "Dragon Mod Z"}, +{"esf", "hl"MODARCH".so", "hl.dll", "none", "Earth's Special Forces"}, +{"existence", "ex"MODARCH".so", "existence.dll", "none", "Existence"}, +{"firearms", "fa"MODARCH".so", "firearms.dll", "none", "Firearms"}, +{"firearms25", "fa"MODARCH".so", "firearms.dll", "none", "Retro Firearms"}, +{"freeze", "mp"MODARCH".so", "mp.dll", "none", "Freeze"}, +{"frontline", "front"MODARCH".so", "frontline.dll", "none", "Frontline Force"}, +{"gangstawars", "gangsta"MODARCH".so", "gwars27.dll", "none", "Gangsta Wars"}, +{"gangwars", "mp"MODARCH".so", "mp.dll", "none", "Gangwars"}, +{"gearbox", "opfor"MODARCH".so", "opfor.dll", "opfor.dylib", "Opposing Force"}, +{"globalwarfare", "gw"MODARCH".so", "mp.dll", "none", "Global Warfare"}, +{"goldeneye", "golden"MODARCH".so", "mp.dll", "none", "Goldeneye"}, +{"hl15we", "hl"MODARCH".so", "hl.dll", "none", "Half-Life 1.5: Weapon Edition"}, +{"hlrally", "hlr"MODARCH".so", "hlrally.dll", "none", "HL-Rally"}, +{"holywars", "hl"MODARCH".so", "holywars.dll", "none", "Holy Wars"}, +{"hostileintent", "hl"MODARCH".so", "hl.dll", "none", "Hostile Intent"}, +{"ios", "ios"MODARCH".so", "ios.dll", "none", "International Online Soccer"}, +{"judgedm", "judge"MODARCH".so", "mp.dll", "none", "Judgement"}, +{"kanonball", "hl"MODARCH".so", "kanonball.dll", "none", "Kanonball"}, +{"monkeystrike", "ms"MODARCH".so", "monkey.dll", "none", "Monkeystrike"}, +{"MorbidPR", "morbid"MODARCH".so", "morbid.dll", "none", "Morbid Inclination"}, +{"movein", "hl"MODARCH".so", "hl.dll", "none", "Move In!"}, +{"ns", "ns"MODARCH".so", "ns.dll", "none", "Natural Selection"}, +{"nsp", "ns"MODARCH".so", "ns.dll", "none", "Natural Selection Beta"}, +{"oel", "hl"MODARCH".so", "hl.dll", "none", "OeL Half-Life"}, +{"og", "og"MODARCH".so", "og.dll", "none", "Over Ground"}, +{"ol", "ol"MODARCH".so", "hl.dll", "none", "Outlawsmod"}, +{"ops1942", "spirit"MODARCH".so", "spirit.dll", "none", "Operations 1942"}, +{"osjb", "osjb"MODARCH".so", "jail.dll", "none", "Open-Source Jailbreak"}, +{"outbreak", "none", "hl.dll", "none", "Out Break"}, +{"oz", "mp"MODARCH".so", "mp.dll", "none", "Oz Deathmatch"}, +{"paintball", "pb"MODARCH".so", "mp.dll", "none", "Paintball"}, +{"penemy", "pe"MODARCH".so", "pe.dll", "none", "Public Enemy"}, +{"phineas", "phineas"MODARCH".so", "phineas.dll", "none", "Phineas Bot"}, +{"ponreturn", "ponr"MODARCH".so", "mp.dll", "none", "Point of No Return"}, +{"pvk", "hl"MODARCH".so", "hl.dll", "none", "Pirates, Vikings and Knights"}, +{"rc2", "rc2"MODARCH".so", "rc2.dll", "none", "Rocket Crowbar 2"}, +{"retrocs", "rcs"MODARCH".so", "rcs.dll", "none", "Retro Counter-Strike"}, +{"rewolf", "hl"MODARCH".so", "gunman.dll", "none", "Gunman Chronicles"}, +{"ricochet", "ricochet"MODARCH".so", "mp.dll", "ricochet.dylib", "Ricochet"}, +{"rockcrowbar", "rc"MODARCH".so", "rc.dll", "none", "Rocket Crowbar"}, +{"rspecies", "hl"MODARCH".so", "hl.dll", "none", "Rival Species"}, +{"scihunt", "shunt.so", "shunt.dll", "none", "Scientist Hunt"}, +{"sdmmod", "sdmmod"MODARCH".so", "sdmmod.dll", "none", "Special Death Match"}, +{"Ship", "ship"MODARCH".so", "ship.dll", "none", "The Ship"}, +{"si", "si"MODARCH".so", "si.dll", "none", "Science & Industry"}, +{"snow", "snow"MODARCH".so", "snow.dll", "none", "Snow-War"}, +{"stargatetc", "hl"MODARCH".so", "hl.dll", "none", "StargateTC"}, +{"svencoop", "hl"MODARCH".so", "hl.dll", "none", "Sven Coop"}, +{"swarm", "swarm"MODARCH".so", "swarm.dll", "none", "Swarm"}, +{"tfc", "tfc"MODARCH".so", "tfc.dll", "tfc.dylib", "Team Fortress Classic"}, +{"thewastes", "thewastes"MODARCH".so", "thewastes.dll", "none", "The Wastes"}, +{"timeless", "pt"MODARCH".so", "timeless.dll", "none", "Project Timeless"}, +{"tod", "hl"MODARCH".so", "hl.dll", "none", "Tour of Duty"}, +{"trainhunters", "th"MODARCH".so", "th.dll", "none", "Train Hunters"}, +{"trevenge", "trevenge.so", "trevenge.dll", "none", "The Terrorist Revenge"}, +{"TS", "ts"MODARCH".so", "mp.dll", "none", "The Specialists"}, +{"tt", "tt"MODARCH".so", "tt.dll", "none", "The Trenches"}, +{"underworld", "uw"MODARCH".so", "uw.dll", "none", "Underworld Bloodline"}, +{"valve", "hl"MODARCH".so", "hl.dll", "hl.dylib", "Half-Life Deathmatch"}, +{"vs", "vs"MODARCH".so", "mp.dll", "none", "VampireSlayer"}, +{"wantedhl", "hl"MODARCH".so", "wanted.dll", "none", "Wanted!"}, +{"wasteland", "whl_linux.so", "mp.dll", "none", "Wasteland"}, +{"weapon_wars", "ww"MODARCH".so", "hl.dll", "none", "Weapon Wars"}, +{"wizwars", "mp"MODARCH".so", "hl.dll", "none", "Wizard Wars"}, +{"wormshl", "wormshl_i586.so", "wormshl.dll", "none", "WormsHL"}, +{"zp", "none", "mp.dll", "none", "Zombie Panic"}, diff --git a/metamod/src/h_export.cpp b/metamod/src/h_export.cpp index 6e5e580..9a6297d 100644 --- a/metamod/src/h_export.cpp +++ b/metamod/src/h_export.cpp @@ -1,66 +1,115 @@ +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// h_export.cpp - main exported DLL functionality + +// From SDK dlls/h_export.cpp: + +/*** +* +* Copyright (c) 1999, 2000 Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +/* + +===== h_export.cpp ======================================================== + + Entity classes exported by Halflife. + +*/ + #include "precompiled.h" +// From SDK dlls/h_export.cpp: + + #ifdef _WIN32 -// Required DLL entry point +//! Required DLL entry point // The above SDK comment indicates this routine is required, but the MSDN // documentation indicates it's actually optional. We keep it, though, for -// completeness. -// Note: 'extern "C"' needed for mingw compile. -extern "C" BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) +// completeness. +BOOL WINAPI DllMain(HINSTANCE /* hinstDLL */, DWORD fdwReason, LPVOID /* lpvReserved */) { if (fdwReason == DLL_PROCESS_ATTACH) { - metamod_handle = hinstDLL; + /* nothing */ } else if (fdwReason == DLL_PROCESS_DETACH) { /* nothing */ } - return TRUE; } -#else +#elif defined(linux) || defined(__APPLE__) // Linux routines to correspond to ATTACH and DETACH cases above. These // aren't required by linux, but are included here for completeness, and // just in case we come across a need to do something at dll load or // unload. -void _init() { - // called before dlopen() returns +// NOTE: These aren't actually called. Needs investigation. +void _init(void) { +// called before dlopen() returns } - -void _fini() { - // called before dlclose() returns +void _fini(void) { +// called before dlclose() returns } #endif -// Holds engine functionality callbacks +//! Holds engine functionality callbacks HL_enginefuncs_t g_engfuncs; -globalvars_t *gpGlobals; -engine_t Engine; +globalvars_t* gpGlobals; +engine_t g_engine; // Receive engine function table from engine. // // This appears to be the _first_ DLL routine called by the engine, so this // is where we hook to load all the other DLLs (game, plugins, etc), which // is actually all done in meta_startup(). -C_DLLEXPORT void WINAPI GiveFnptrsToDll(enginefuncs_t *pengfuncsFromEngine, globalvars_t *pGlobals) +void WINAPI GiveFnptrsToDll(enginefuncs_t* pengfuncsFromEngine, globalvars_t* pGlobals) { -#ifndef _WIN32 - metamod_handle = get_module_handle_of_memptr((void*)&g_engfuncs); -#endif - gpGlobals = pGlobals; - Engine.funcs = &g_engfuncs; - Engine.globals = pGlobals; + g_engine.funcs = &g_engfuncs; + g_engine.globals = pGlobals; g_engfuncs.initialise_interface(pengfuncsFromEngine); - - // NOTE: Have to call logging function _after_ initialising g_engfuncs, so + // NOTE! Have to call logging function _after_ initialising g_engfuncs, so // that g_engfuncs.pfnAlertMessage() can be resolved properly, heh. :) META_DEV("called: GiveFnptrsToDll"); - // Load plugins, load game dll. - if (!metamod_startup()) - { - metamod_not_loaded = 1; - } - return; + // Load plugins, load game dll. + metamod_startup(); } + +// Avoid linking to libstdc++ +#if defined(linux) +extern "C" void __cxa_pure_virtual(void) +{ +} + +void *operator new(size_t size) +{ + return malloc(size); +} + +void *operator new[](size_t size) +{ + return malloc(size); +} + +void operator delete(void *ptr) +{ + free(ptr); +} + +void operator delete[](void * ptr) +{ + free(ptr); +} +#endif + diff --git a/metamod/src/h_export.h b/metamod/src/h_export.h index 61e9d3b..24754fb 100644 --- a/metamod/src/h_export.h +++ b/metamod/src/h_export.h @@ -1,8 +1,49 @@ -#pragma once +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// h_export.h - prototypes for h_export.cpp + +/* + * Copyright (c) 2001-2003 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game g_engine ("HL + * g_engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL g_engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + +#ifndef H_EXPORT_H +#define H_EXPORT_H #include "osdep.h" // DLLEXPORT, WINAPI, etc // Our GiveFnptrsToDll, called by engine. -typedef void (WINAPI *GIVE_ENGINE_FUNCTIONS_FN) (enginefuncs_t *pengfuncsFromEngine, globalvars_t *pGlobals); +typedef void (WINAPI *GIVE_ENGINE_FUNCTIONS_FN) (enginefuncs_t + *pengfuncsFromEngine, globalvars_t *pGlobals); -C_DLLEXPORT void WINAPI GiveFnptrsToDll(enginefuncs_t *pengfuncsFromEngine, globalvars_t *pGlobals); +C_DLLEXPORT void WINAPI GiveFnptrsToDll(enginefuncs_t *pengfuncsFromEngine, + globalvars_t *pGlobals); + +#endif /* H_EXPORT_H */ diff --git a/metamod/src/info_name.h b/metamod/src/info_name.h new file mode 100644 index 0000000..fe128ad --- /dev/null +++ b/metamod/src/info_name.h @@ -0,0 +1,54 @@ +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// info_name.h - name, desc, author, etc + +/* + * Copyright (c) 2001-2013 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game Engine ("HL + * Engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL Engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + +#ifndef INFO_NAME_H +#define INFO_NAME_H + +#define VNAME "Metamod" +#define VAUTHOR "Will Day " +#define VURL "http://www.metamod.org/" + +#define COPYRIGHT_YEAR "2013" + +// Various strings for the Windows DLL Resources in res_meta.rc +#define RC_COMMENTS "Metamod allows running multiple mod-like plugin DLLs, to add functionality or change the behavior of the running HLDS game mod. See " VURL +#define RC_DESC "Metamod Half-Life MOD DLL" +#define RC_FILENAME "METAMOD.DLL" +#define RC_INTERNAL "METAMOD" +#define RC_COPYRIGHT "Copyright© 2001-" COPYRIGHT_YEAR " Will Day; GPL licensed" +#define RC_LICENSE "Licensed under the GNU General Public License" + +#endif /* INFO_NAME_H */ diff --git a/metamod/src/linkent.cpp b/metamod/src/linkent.cpp new file mode 100644 index 0000000..a28257b --- /dev/null +++ b/metamod/src/linkent.cpp @@ -0,0 +1,59 @@ +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// linkent.cpp - export entities from mod "games" back to the HL engine + +/* + * Copyright (c) 2001-2003 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game g_engine ("HL + * g_engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL g_engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + +#include "precompiled.h" + +// Function to perform common code of LINK_ENTITY_TO_GAME, rather than +// duplicating the code in ~2000 expanded macros. Based on code from Jussi +// Kivilinna . +void do_link_ent(ENTITY_FN *pfnEntity, int *missing, const char *entStr, entvars_t *pev) +{; + if(*missing) { + META_DEBUG(9, ("Skipping entity '%s'; was previously found missing", entStr)); + return; + } + if(!*pfnEntity) { + META_DEBUG(9, ("Looking up game entity '%s'", entStr)); + *pfnEntity = (ENTITY_FN) DLSYM(GameDLL.handle, entStr); + } + if(!*pfnEntity) { + META_ERROR("Couldn't find game entity '%s' in game DLL '%s': %s", entStr, GameDLL.name, DLERROR()); + *missing=1; + return; + } + META_DEBUG(8, ("Linking game entity '%s'", entStr)); + (*pfnEntity)(pev); +} diff --git a/metamod/src/linkent.h b/metamod/src/linkent.h index 479d732..a488136 100644 --- a/metamod/src/linkent.h +++ b/metamod/src/linkent.h @@ -1,11 +1,49 @@ -#pragma once +// vi: set ts=4 sw=4 : +// vim: set tw=75 : +// linkent.h - export entities from mod "games" back to the HL engine + +/* + * Copyright (c) 2001-2003 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game g_engine ("HL + * g_engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL g_engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + +#ifndef LINK_ENT_H +#define LINK_ENT_H + +#include // always + +#include "osdep.h" // DLLEXPORT, etc +#include "metamod.h" // GameDLL, etc #include "mlist.h" // MPluginList::find_match, etc -#include "mplugin.h" // MPlugin::info, etc -#include "log_meta.h" // META_DEBUG, etc - -//Initializes replacement code -int init_linkent_replacement(DLHANDLE moduleMetamod, DLHANDLE moduleGame); +#include "mplugin.h" // MPlugin::info, etc +#include "log_meta.h" // META_DEBUG, etc // Comments from SDK dlls/util.h: //! This is the glue that hooks .MAP entity class names to our CPP classes. @@ -16,6 +54,18 @@ int init_linkent_replacement(DLHANDLE moduleMetamod, DLHANDLE moduleGame); typedef void (*ENTITY_FN) (entvars_t *); +// Function to perform common code of LINK_ENTITY_TO_GAME. +void do_link_ent(ENTITY_FN *pfnEntity, int *missing, const char *entStr, + entvars_t *pev); + +#define LINK_ENTITY_TO_GAME(entityName) \ + C_DLLEXPORT void entityName(entvars_t *pev); \ + void entityName(entvars_t *pev) { \ + static ENTITY_FN pfnEntity = NULL; \ + static int missing=0; \ + do_link_ent(&pfnEntity, &missing, STRINGIZE(entityName, 0), pev); \ + } + // For now, we have to explicitly export functions for plugin entities, // just as for gamedll entities. Ideally, this could be generalized in // some manner, so that plugins can declare and use their own entities @@ -37,27 +87,29 @@ typedef void (*ENTITY_FN) (entvars_t *); const char *entStr; \ MPlugin *findp; \ entStr = STRINGIZE(entityName, 0); \ - if (missing) \ + if(missing) \ return; \ - if (!pfnEntity) { \ - if (!(findp=Plugins->find_match(pluginName))) { \ - META_WARNING("Couldn't find loaded plugin '%s' for plugin entity '%s'", pluginName, entStr); \ + if(!pfnEntity) { \ + if(!(findp=g_plugins->find_match(pluginName))) { \ + META_ERROR("Couldn't find loaded plugin '%s' for plugin entity '%s'", pluginName, entStr); \ missing=1; \ return; \ } \ - if (findp->info && findp->info->loadable != PT_STARTUP) { \ - META_WARNING("Can't link entity '%s' for plugin '%s'; loadable != startup: %s", entStr, pluginName, findp->str_loadable()); \ + if(findp->info && findp->info->loadable != PT_STARTUP) { \ + META_ERROR("Can't link entity '%s' for plugin '%s'; loadable != startup: %s", entStr, pluginName, findp->str_loadable()); \ missing=1; \ return; \ } \ META_DEBUG(9, ("Looking up plugin entity '%s'", entStr)); \ pfnEntity = (ENTITY_FN) DLSYM(findp->handle, entStr); \ } \ - if (!pfnEntity) { \ - META_WARNING("Couldn't find plugin entity '%s' in plugin DLL '%s'", entStr, findp->file); \ + if(!pfnEntity) { \ + META_ERROR("Couldn't find plugin entity '%s' in plugin DLL '%s'", entStr, findp->file); \ missing=1; \ return; \ } \ META_DEBUG(8, ("Linking plugin entity '%s'", entStr)); \ (*pfnEntity)(pev); \ } + +#endif /* LINK_ENT_H */ diff --git a/metamod/src/linkgame.cpp b/metamod/src/linkgame.cpp new file mode 100644 index 0000000..b3a7196 --- /dev/null +++ b/metamod/src/linkgame.cpp @@ -0,0 +1,3631 @@ +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// linkgame.cpp - export entities from mod "games" back to the HL engine + +/* + * Copyright (c) 2001-2013 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game g_engine ("HL + * g_engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL g_engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + +#include "precompiled.h" + +// Entity list for gamedlls adapted from adminmod linkfunc.cpp. + +// NOTE: This list of entities is automatically generated via the script +// "mklinkgame.sh". See the files in the directory "ents" for the actual +// list of entities. + +LINK_ENTITY_TO_GAME(AngleIMatrix); +LINK_ENTITY_TO_GAME(AngleMatrix); +LINK_ENTITY_TO_GAME(BALLS_airball); +LINK_ENTITY_TO_GAME(CTF_Map); +LINK_ENTITY_TO_GAME(CreateInterface); +LINK_ENTITY_TO_GAME(DLLClassName); +LINK_ENTITY_TO_GAME(DelayedUse); +LINK_ENTITY_TO_GAME(Electro_Bolt); +LINK_ENTITY_TO_GAME(FISHINGROD_bolt); +LINK_ENTITY_TO_GAME(FOOT_bolt); +LINK_ENTITY_TO_GAME(FlyingTomaHawk); +LINK_ENTITY_TO_GAME(GetChaseOrigin); +LINK_ENTITY_TO_GAME(IsoBomb); +LINK_ENTITY_TO_GAME(PythRound); +LINK_ENTITY_TO_GAME(RONINTeamScore); +LINK_ENTITY_TO_GAME(SA_Model); +LINK_ENTITY_TO_GAME(SCAVENGERTeamScore); +LINK_ENTITY_TO_GAME(Satelite__Laser); +LINK_ENTITY_TO_GAME(TSAmmoPack); +LINK_ENTITY_TO_GAME(TSWorldGun); +LINK_ENTITY_TO_GAME(TS_PowerUp); +LINK_ENTITY_TO_GAME(TS_bomb); +LINK_ENTITY_TO_GAME(USMCTeamScore); +LINK_ENTITY_TO_GAME(Zombie2Spit); +LINK_ENTITY_TO_GAME(_spit); +LINK_ENTITY_TO_GAME(_squadfix); +LINK_ENTITY_TO_GAME(acidgib); +LINK_ENTITY_TO_GAME(active_bomb); +LINK_ENTITY_TO_GAME(afterimage); +LINK_ENTITY_TO_GAME(aiscripted_sequence); +LINK_ENTITY_TO_GAME(ak74grenade); +LINK_ENTITY_TO_GAME(alien_slave_energy_ball); +LINK_ENTITY_TO_GAME(alien_slave_sapper); +LINK_ENTITY_TO_GAME(alienresourcetower); +LINK_ENTITY_TO_GAME(ambient_generic); +LINK_ENTITY_TO_GAME(ammo_0mm45); +LINK_ENTITY_TO_GAME(ammo_0mm50b); +LINK_ENTITY_TO_GAME(ammo_10mmbuckshot); +LINK_ENTITY_TO_GAME(ammo_10mmbuckshotbox); +LINK_ENTITY_TO_GAME(ammo_127mm); +LINK_ENTITY_TO_GAME(ammo_12g); +LINK_ENTITY_TO_GAME(ammo_1911clip); +LINK_ENTITY_TO_GAME(ammo_2mm); +LINK_ENTITY_TO_GAME(ammo_30cal); +LINK_ENTITY_TO_GAME(ammo_30mm); +LINK_ENTITY_TO_GAME(ammo_338Magnum); +LINK_ENTITY_TO_GAME(ammo_338magnum); +LINK_ENTITY_TO_GAME(ammo_357); +LINK_ENTITY_TO_GAME(ammo_357SIG); +LINK_ENTITY_TO_GAME(ammo_357sig); +LINK_ENTITY_TO_GAME(ammo_40glclip); +LINK_ENTITY_TO_GAME(ammo_40mm); +LINK_ENTITY_TO_GAME(ammo_44); +LINK_ENTITY_TO_GAME(ammo_45ACP); +LINK_ENTITY_TO_GAME(ammo_45acp); +LINK_ENTITY_TO_GAME(ammo_45cal); +LINK_ENTITY_TO_GAME(ammo_50AE); +LINK_ENTITY_TO_GAME(ammo_50ae); +LINK_ENTITY_TO_GAME(ammo_50cal); +LINK_ENTITY_TO_GAME(ammo_556); +LINK_ENTITY_TO_GAME(ammo_556AR); +LINK_ENTITY_TO_GAME(ammo_556Nato); +LINK_ENTITY_TO_GAME(ammo_556box); +LINK_ENTITY_TO_GAME(ammo_556nato); +LINK_ENTITY_TO_GAME(ammo_556natobox); +LINK_ENTITY_TO_GAME(ammo_57mm); +LINK_ENTITY_TO_GAME(ammo_5mm56); +LINK_ENTITY_TO_GAME(ammo_5mm7); +LINK_ENTITY_TO_GAME(ammo_762); +LINK_ENTITY_TO_GAME(ammo_762Magnum); +LINK_ENTITY_TO_GAME(ammo_762Nato); +LINK_ENTITY_TO_GAME(ammo_762mmbox); +LINK_ENTITY_TO_GAME(ammo_762nato); +LINK_ENTITY_TO_GAME(ammo_762x54); +LINK_ENTITY_TO_GAME(ammo_766mm); +LINK_ENTITY_TO_GAME(ammo_7mm62); +LINK_ENTITY_TO_GAME(ammo_86mm); +LINK_ENTITY_TO_GAME(ammo_8mm); +LINK_ENTITY_TO_GAME(ammo_9mm); +LINK_ENTITY_TO_GAME(ammo_9mmAR); +LINK_ENTITY_TO_GAME(ammo_9mmbox); +LINK_ENTITY_TO_GAME(ammo_9mmclip); +LINK_ENTITY_TO_GAME(ammo_AK47clip); +LINK_ENTITY_TO_GAME(ammo_ARgrenades); +LINK_ENTITY_TO_GAME(ammo_BALLS); +LINK_ENTITY_TO_GAME(ammo_CEnfield); +LINK_ENTITY_TO_GAME(ammo_Deagle); +LINK_ENTITY_TO_GAME(ammo_Dmissile); +LINK_ENTITY_TO_GAME(ammo_EnergyCells); +LINK_ENTITY_TO_GAME(ammo_FISHINGROD); +LINK_ENTITY_TO_GAME(ammo_FOOT); +LINK_ENTITY_TO_GAME(ammo_FTclip); +LINK_ENTITY_TO_GAME(ammo_GMauserG98); +LINK_ENTITY_TO_GAME(ammo_GluonCells); +LINK_ENTITY_TO_GAME(ammo_M16grenades); +LINK_ENTITY_TO_GAME(ammo_MicroFusionCells); +LINK_ENTITY_TO_GAME(ammo_NGgrenades); +LINK_ENTITY_TO_GAME(ammo_ShockCore); +LINK_ENTITY_TO_GAME(ammo_ShockGrenade); +LINK_ENTITY_TO_GAME(ammo_SunOfGod); +LINK_ENTITY_TO_GAME(ammo_WTELEPORTERgrenades); +LINK_ENTITY_TO_GAME(ammo_adrenaline); +LINK_ENTITY_TO_GAME(ammo_ak101); +LINK_ENTITY_TO_GAME(ammo_ak105); +LINK_ENTITY_TO_GAME(ammo_ak47); +LINK_ENTITY_TO_GAME(ammo_ak47clip); +LINK_ENTITY_TO_GAME(ammo_ak5); +LINK_ENTITY_TO_GAME(ammo_ak74); +LINK_ENTITY_TO_GAME(ammo_ak74clip); +LINK_ENTITY_TO_GAME(ammo_ak74grenades); +LINK_ENTITY_TO_GAME(ammo_anaconda); +LINK_ENTITY_TO_GAME(ammo_ar10clip); +LINK_ENTITY_TO_GAME(ammo_ar33clip); +LINK_ENTITY_TO_GAME(ammo_areaammo); +LINK_ENTITY_TO_GAME(ammo_aug); +LINK_ENTITY_TO_GAME(ammo_awm); +LINK_ENTITY_TO_GAME(ammo_awp); +LINK_ENTITY_TO_GAME(ammo_axes); +LINK_ENTITY_TO_GAME(ammo_bar); +LINK_ENTITY_TO_GAME(ammo_baretta); +LINK_ENTITY_TO_GAME(ammo_bazooka); +LINK_ENTITY_TO_GAME(ammo_beamgunclip); +LINK_ENTITY_TO_GAME(ammo_benelli); +LINK_ENTITY_TO_GAME(ammo_ber92f); +LINK_ENTITY_TO_GAME(ammo_ber93r); +LINK_ENTITY_TO_GAME(ammo_beretta); +LINK_ENTITY_TO_GAME(ammo_berettaclip); +LINK_ENTITY_TO_GAME(ammo_berrett82clip); +LINK_ENTITY_TO_GAME(ammo_bfg); +LINK_ENTITY_TO_GAME(ammo_bizon); +LINK_ENTITY_TO_GAME(ammo_boltrifle); +LINK_ENTITY_TO_GAME(ammo_bow); +LINK_ENTITY_TO_GAME(ammo_bren); +LINK_ENTITY_TO_GAME(ammo_brick); +LINK_ENTITY_TO_GAME(ammo_buckshot); +LINK_ENTITY_TO_GAME(ammo_buffalo); +LINK_ENTITY_TO_GAME(ammo_cannon); +LINK_ENTITY_TO_GAME(ammo_caseless); +LINK_ENTITY_TO_GAME(ammo_cell); +LINK_ENTITY_TO_GAME(ammo_cgrenade); +LINK_ENTITY_TO_GAME(ammo_chemical); +LINK_ENTITY_TO_GAME(ammo_cloaker); +LINK_ENTITY_TO_GAME(ammo_colt); +LINK_ENTITY_TO_GAME(ammo_colt45clip); +LINK_ENTITY_TO_GAME(ammo_coltgov); +LINK_ENTITY_TO_GAME(ammo_colts); +LINK_ENTITY_TO_GAME(ammo_concussion); +LINK_ENTITY_TO_GAME(ammo_cougarclip); +LINK_ENTITY_TO_GAME(ammo_cpc); +LINK_ENTITY_TO_GAME(ammo_crate); +LINK_ENTITY_TO_GAME(ammo_crossbow); +LINK_ENTITY_TO_GAME(ammo_d5kclip); +LINK_ENTITY_TO_GAME(ammo_dbshot); +LINK_ENTITY_TO_GAME(ammo_dd44clip); +LINK_ENTITY_TO_GAME(ammo_de50); +LINK_ENTITY_TO_GAME(ammo_deagle); +LINK_ENTITY_TO_GAME(ammo_deagleclip); +LINK_ENTITY_TO_GAME(ammo_deploygun); +LINK_ENTITY_TO_GAME(ammo_desert); +LINK_ENTITY_TO_GAME(ammo_dmlclip); +LINK_ENTITY_TO_GAME(ammo_doubleshotgun); +LINK_ENTITY_TO_GAME(ammo_dragunovclip); +LINK_ENTITY_TO_GAME(ammo_dsr1); +LINK_ENTITY_TO_GAME(ammo_dualberettas); +LINK_ENTITY_TO_GAME(ammo_dualscorpion); +LINK_ENTITY_TO_GAME(ammo_dyno); +LINK_ENTITY_TO_GAME(ammo_eagleclip); +LINK_ENTITY_TO_GAME(ammo_egonclip); +LINK_ENTITY_TO_GAME(ammo_el_standard); +LINK_ENTITY_TO_GAME(ammo_enfield); +LINK_ENTITY_TO_GAME(ammo_exploder); +LINK_ENTITY_TO_GAME(ammo_explogun); +LINK_ENTITY_TO_GAME(ammo_famas); +LINK_ENTITY_TO_GAME(ammo_famasclip); +LINK_ENTITY_TO_GAME(ammo_fg42); +LINK_ENTITY_TO_GAME(ammo_fiveseven); +LINK_ENTITY_TO_GAME(ammo_flameammo); +LINK_ENTITY_TO_GAME(ammo_flameclip); +LINK_ENTITY_TO_GAME(ammo_flashbang); +LINK_ENTITY_TO_GAME(ammo_fnfal); +LINK_ENTITY_TO_GAME(ammo_fnp90clip); +LINK_ENTITY_TO_GAME(ammo_frag); +LINK_ENTITY_TO_GAME(ammo_freezeclip); +LINK_ENTITY_TO_GAME(ammo_fuel); +LINK_ENTITY_TO_GAME(ammo_g11); +LINK_ENTITY_TO_GAME(ammo_g36); +LINK_ENTITY_TO_GAME(ammo_g36clip); +LINK_ENTITY_TO_GAME(ammo_g36e); +LINK_ENTITY_TO_GAME(ammo_g36k); +LINK_ENTITY_TO_GAME(ammo_g3a3); +LINK_ENTITY_TO_GAME(ammo_galil); +LINK_ENTITY_TO_GAME(ammo_garand); +LINK_ENTITY_TO_GAME(ammo_gatlinbox); +LINK_ENTITY_TO_GAME(ammo_gattlinggun); +LINK_ENTITY_TO_GAME(ammo_gaussclip); +LINK_ENTITY_TO_GAME(ammo_generic_american); +LINK_ENTITY_TO_GAME(ammo_generic_british); +LINK_ENTITY_TO_GAME(ammo_generic_german); +LINK_ENTITY_TO_GAME(ammo_gewehr); +LINK_ENTITY_TO_GAME(ammo_glock17); +LINK_ENTITY_TO_GAME(ammo_glock18); +LINK_ENTITY_TO_GAME(ammo_glockclip); +LINK_ENTITY_TO_GAME(ammo_goldpp7clip); +LINK_ENTITY_TO_GAME(ammo_gp25); +LINK_ENTITY_TO_GAME(ammo_greasegun); +LINK_ENTITY_TO_GAME(ammo_grenades); +LINK_ENTITY_TO_GAME(ammo_handcannon); +LINK_ENTITY_TO_GAME(ammo_helirockets); +LINK_ENTITY_TO_GAME(ammo_hellfire); +LINK_ENTITY_TO_GAME(ammo_hk21); +LINK_ENTITY_TO_GAME(ammo_hk33clip); +LINK_ENTITY_TO_GAME(ammo_hkmp5); +LINK_ENTITY_TO_GAME(ammo_isotope); +LINK_ENTITY_TO_GAME(ammo_jackhammer); +LINK_ENTITY_TO_GAME(ammo_javelins); +LINK_ENTITY_TO_GAME(ammo_k43); +LINK_ENTITY_TO_GAME(ammo_kar); +LINK_ENTITY_TO_GAME(ammo_kf7clip); +LINK_ENTITY_TO_GAME(ammo_knife); +LINK_ENTITY_TO_GAME(ammo_knives); +LINK_ENTITY_TO_GAME(ammo_launcher); +LINK_ENTITY_TO_GAME(ammo_lgclip); +LINK_ENTITY_TO_GAME(ammo_lgrenades); +LINK_ENTITY_TO_GAME(ammo_lightning); +LINK_ENTITY_TO_GAME(ammo_longbow); +LINK_ENTITY_TO_GAME(ammo_longslide); +LINK_ENTITY_TO_GAME(ammo_lrclip); +LINK_ENTITY_TO_GAME(ammo_luger); +LINK_ENTITY_TO_GAME(ammo_m11); +LINK_ENTITY_TO_GAME(ammo_m112); +LINK_ENTITY_TO_GAME(ammo_m134); +LINK_ENTITY_TO_GAME(ammo_m16); +LINK_ENTITY_TO_GAME(ammo_m16a2clip); +LINK_ENTITY_TO_GAME(ammo_m16clip); +LINK_ENTITY_TO_GAME(ammo_m1carbine); +LINK_ENTITY_TO_GAME(ammo_m2); +LINK_ENTITY_TO_GAME(ammo_m203); +LINK_ENTITY_TO_GAME(ammo_m249); +LINK_ENTITY_TO_GAME(ammo_m4); +LINK_ENTITY_TO_GAME(ammo_m40a1clip); +LINK_ENTITY_TO_GAME(ammo_m4a1); +LINK_ENTITY_TO_GAME(ammo_m4clip); +LINK_ENTITY_TO_GAME(ammo_m60); +LINK_ENTITY_TO_GAME(ammo_m60clip); +LINK_ENTITY_TO_GAME(ammo_m79); +LINK_ENTITY_TO_GAME(ammo_m82); +LINK_ENTITY_TO_GAME(ammo_mac); +LINK_ENTITY_TO_GAME(ammo_mac10); +LINK_ENTITY_TO_GAME(ammo_machinegun); +LINK_ENTITY_TO_GAME(ammo_markmusket); +LINK_ENTITY_TO_GAME(ammo_mc51); +LINK_ENTITY_TO_GAME(ammo_mf2clip); +LINK_ENTITY_TO_GAME(ammo_mg34); +LINK_ENTITY_TO_GAME(ammo_mg36); +LINK_ENTITY_TO_GAME(ammo_mg42); +LINK_ENTITY_TO_GAME(ammo_mindrayclip); +LINK_ENTITY_TO_GAME(ammo_minigunClip); +LINK_ENTITY_TO_GAME(ammo_minimissile); +LINK_ENTITY_TO_GAME(ammo_mk23); +LINK_ENTITY_TO_GAME(ammo_mossberg); +LINK_ENTITY_TO_GAME(ammo_mp40); +LINK_ENTITY_TO_GAME(ammo_mp44); +LINK_ENTITY_TO_GAME(ammo_mp5); +LINK_ENTITY_TO_GAME(ammo_mp5a2); +LINK_ENTITY_TO_GAME(ammo_mp5a4); +LINK_ENTITY_TO_GAME(ammo_mp5a5); +LINK_ENTITY_TO_GAME(ammo_mp5clip); +LINK_ENTITY_TO_GAME(ammo_mp5grenades); +LINK_ENTITY_TO_GAME(ammo_mp5k); +LINK_ENTITY_TO_GAME(ammo_mp5pdwclip); +LINK_ENTITY_TO_GAME(ammo_mp5sd); +LINK_ENTITY_TO_GAME(ammo_msg90); +LINK_ENTITY_TO_GAME(ammo_musketoon); +LINK_ENTITY_TO_GAME(ammo_nails); +LINK_ENTITY_TO_GAME(ammo_nato); +LINK_ENTITY_TO_GAME(ammo_nato308); +LINK_ENTITY_TO_GAME(ammo_natoclip); +LINK_ENTITY_TO_GAME(ammo_needle); +LINK_ENTITY_TO_GAME(ammo_nuke); +LINK_ENTITY_TO_GAME(ammo_null); +LINK_ENTITY_TO_GAME(ammo_p99); +LINK_ENTITY_TO_GAME(ammo_p99clip); +LINK_ENTITY_TO_GAME(ammo_pdw); +LINK_ENTITY_TO_GAME(ammo_phantomclip); +LINK_ENTITY_TO_GAME(ammo_piat); +LINK_ENTITY_TO_GAME(ammo_pistol); +LINK_ENTITY_TO_GAME(ammo_pistolet); +LINK_ENTITY_TO_GAME(ammo_pkm); +LINK_ENTITY_TO_GAME(ammo_pkmclip); +LINK_ENTITY_TO_GAME(ammo_powercell); +LINK_ENTITY_TO_GAME(ammo_pschreck); +LINK_ENTITY_TO_GAME(ammo_psg1); +LINK_ENTITY_TO_GAME(ammo_psg1clip); +LINK_ENTITY_TO_GAME(ammo_quad); +LINK_ENTITY_TO_GAME(ammo_railgun); +LINK_ENTITY_TO_GAME(ammo_rcp90clip); +LINK_ENTITY_TO_GAME(ammo_remington); +LINK_ENTITY_TO_GAME(ammo_rifleclip); +LINK_ENTITY_TO_GAME(ammo_rifleshot); +LINK_ENTITY_TO_GAME(ammo_rocket); +LINK_ENTITY_TO_GAME(ammo_rocketlauncher); +LINK_ENTITY_TO_GAME(ammo_rocketpistol); +LINK_ENTITY_TO_GAME(ammo_rockets); +LINK_ENTITY_TO_GAME(ammo_rpgclip); +LINK_ENTITY_TO_GAME(ammo_rs202m2); +LINK_ENTITY_TO_GAME(ammo_rs_grenade); +LINK_ENTITY_TO_GAME(ammo_rs_psi); +LINK_ENTITY_TO_GAME(ammo_ruger); +LINK_ENTITY_TO_GAME(ammo_sa80clip); +LINK_ENTITY_TO_GAME(ammo_saa); +LINK_ENTITY_TO_GAME(ammo_saiga); +LINK_ENTITY_TO_GAME(ammo_sako); +LINK_ENTITY_TO_GAME(ammo_satchels); +LINK_ENTITY_TO_GAME(ammo_sbarrelshot); +LINK_ENTITY_TO_GAME(ammo_scatterclip); +LINK_ENTITY_TO_GAME(ammo_scopedkar); +LINK_ENTITY_TO_GAME(ammo_shells); +LINK_ENTITY_TO_GAME(ammo_shot); +LINK_ENTITY_TO_GAME(ammo_shrapnel); +LINK_ENTITY_TO_GAME(ammo_sig245clip); +LINK_ENTITY_TO_GAME(ammo_silverpp7clip); +LINK_ENTITY_TO_GAME(ammo_sks); +LINK_ENTITY_TO_GAME(ammo_slugs); +LINK_ENTITY_TO_GAME(ammo_smg9); +LINK_ENTITY_TO_GAME(ammo_snUZI); +LINK_ENTITY_TO_GAME(ammo_sniper); +LINK_ENTITY_TO_GAME(ammo_spas12); +LINK_ENTITY_TO_GAME(ammo_spasclip); +LINK_ENTITY_TO_GAME(ammo_spellbook); +LINK_ENTITY_TO_GAME(ammo_spitcarb); +LINK_ENTITY_TO_GAME(ammo_spitclip); +LINK_ENTITY_TO_GAME(ammo_spore); +LINK_ENTITY_TO_GAME(ammo_spring); +LINK_ENTITY_TO_GAME(ammo_srifleclip); +LINK_ENTITY_TO_GAME(ammo_ssg3000); +LINK_ENTITY_TO_GAME(ammo_st_far); +LINK_ENTITY_TO_GAME(ammo_st_heavy); +LINK_ENTITY_TO_GAME(ammo_st_medium); +LINK_ENTITY_TO_GAME(ammo_st_short); +LINK_ENTITY_TO_GAME(ammo_st_special1); +LINK_ENTITY_TO_GAME(ammo_st_special2); +LINK_ENTITY_TO_GAME(ammo_sten); +LINK_ENTITY_TO_GAME(ammo_sterling); +LINK_ENTITY_TO_GAME(ammo_steyr_m40); +LINK_ENTITY_TO_GAME(ammo_stg24); +LINK_ENTITY_TO_GAME(ammo_stoner); +LINK_ENTITY_TO_GAME(ammo_stonerscope); +LINK_ENTITY_TO_GAME(ammo_stonersilencer); +LINK_ENTITY_TO_GAME(ammo_stormcell); +LINK_ENTITY_TO_GAME(ammo_stubcoolant); +LINK_ENTITY_TO_GAME(ammo_stumpbox); +LINK_ENTITY_TO_GAME(ammo_svd); +LINK_ENTITY_TO_GAME(ammo_swarm_xen_secondary); +LINK_ENTITY_TO_GAME(ammo_swarmprimary); +LINK_ENTITY_TO_GAME(ammo_swarmsecondary); +LINK_ENTITY_TO_GAME(ammo_synthol); +LINK_ENTITY_TO_GAME(ammo_tec9); +LINK_ENTITY_TO_GAME(ammo_thompson); +LINK_ENTITY_TO_GAME(ammo_tommy); +LINK_ENTITY_TO_GAME(ammo_tommygun); +LINK_ENTITY_TO_GAME(ammo_trigun); +LINK_ENTITY_TO_GAME(ammo_ump45); +LINK_ENTITY_TO_GAME(ammo_uranium235); +LINK_ENTITY_TO_GAME(ammo_uranium238); +LINK_ENTITY_TO_GAME(ammo_usp); +LINK_ENTITY_TO_GAME(ammo_uspclip); +LINK_ENTITY_TO_GAME(ammo_uzi); +LINK_ENTITY_TO_GAME(ammo_uziclip); +LINK_ENTITY_TO_GAME(ammo_veprclip); +LINK_ENTITY_TO_GAME(ammo_vomitclip); +LINK_ENTITY_TO_GAME(ammo_vulcan); +LINK_ENTITY_TO_GAME(ammo_wa2000); +LINK_ENTITY_TO_GAME(ammo_webley); +LINK_ENTITY_TO_GAME(ammo_whiskey); +LINK_ENTITY_TO_GAME(ammo_winchester); +LINK_ENTITY_TO_GAME(ammo_winchesterclip); +LINK_ENTITY_TO_GAME(ammo_xbolts); +LINK_ENTITY_TO_GAME(ammo_xm4); +LINK_ENTITY_TO_GAME(ammo_xm4slug); +LINK_ENTITY_TO_GAME(ammo_zmgclip); +LINK_ENTITY_TO_GAME(ammobox); +LINK_ENTITY_TO_GAME(antifric_timer); +LINK_ENTITY_TO_GAME(antifriction_grenade); +LINK_ENTITY_TO_GAME(arcade_points); +LINK_ENTITY_TO_GAME(armoury_entity); +LINK_ENTITY_TO_GAME(arms_dealer); +LINK_ENTITY_TO_GAME(arrow); +LINK_ENTITY_TO_GAME(asl_charge_flare); +LINK_ENTITY_TO_GAME(aura); +LINK_ENTITY_TO_GAME(authenticationmanager); +LINK_ENTITY_TO_GAME(autogl_gren); +LINK_ENTITY_TO_GAME(ball_launcher); +LINK_ENTITY_TO_GAME(ball_lightning); +LINK_ENTITY_TO_GAME(balle); +LINK_ENTITY_TO_GAME(banana); +LINK_ENTITY_TO_GAME(bankinterest); +LINK_ENTITY_TO_GAME(barneymine); +LINK_ENTITY_TO_GAME(base_drive_ent); +LINK_ENTITY_TO_GAME(basecurse); +LINK_ENTITY_TO_GAME(bb_ammo); +LINK_ENTITY_TO_GAME(bb_custommission); +LINK_ENTITY_TO_GAME(bb_equipment); +LINK_ENTITY_TO_GAME(bb_escape_final); +LINK_ENTITY_TO_GAME(bb_escape_radar); +LINK_ENTITY_TO_GAME(bb_escapeair); +LINK_ENTITY_TO_GAME(bb_funk); +LINK_ENTITY_TO_GAME(bb_healthkit); +LINK_ENTITY_TO_GAME(bb_mapmission); +LINK_ENTITY_TO_GAME(bb_mission_zone); +LINK_ENTITY_TO_GAME(bb_objective_item); +LINK_ENTITY_TO_GAME(bb_objectives); +LINK_ENTITY_TO_GAME(bb_spawn_player); +LINK_ENTITY_TO_GAME(bb_spawn_zombie); +LINK_ENTITY_TO_GAME(bb_tank); +LINK_ENTITY_TO_GAME(bb_waypoint); +LINK_ENTITY_TO_GAME(bb_zombie_player); +LINK_ENTITY_TO_GAME(bbody); +LINK_ENTITY_TO_GAME(beam); +LINK_ENTITY_TO_GAME(beam_attack); +LINK_ENTITY_TO_GAME(beamshot); +LINK_ENTITY_TO_GAME(bean); +LINK_ENTITY_TO_GAME(beanstalk); +LINK_ENTITY_TO_GAME(bfg10k); +LINK_ENTITY_TO_GAME(big_bang); +LINK_ENTITY_TO_GAME(big_disk); +LINK_ENTITY_TO_GAME(big_lance_proj); +LINK_ENTITY_TO_GAME(bird); +LINK_ENTITY_TO_GAME(black_hole); +LINK_ENTITY_TO_GAME(blade); +LINK_ENTITY_TO_GAME(blaster_beam); +LINK_ENTITY_TO_GAME(blaster_bolt); +LINK_ENTITY_TO_GAME(bmortar); +LINK_ENTITY_TO_GAME(bodyque); +LINK_ENTITY_TO_GAME(bone_follow); +LINK_ENTITY_TO_GAME(boolean_multisource); +LINK_ENTITY_TO_GAME(booty_it); +LINK_ENTITY_TO_GAME(bot); +LINK_ENTITY_TO_GAME(bot_waypoint); +LINK_ENTITY_TO_GAME(bouncy_bolt); +LINK_ENTITY_TO_GAME(bouncy_tripmine); +LINK_ENTITY_TO_GAME(bowie_bolt); +LINK_ENTITY_TO_GAME(bubgren); +LINK_ENTITY_TO_GAME(building_dispenser); +LINK_ENTITY_TO_GAME(building_sentrygun); +LINK_ENTITY_TO_GAME(building_sentrygun_base); +LINK_ENTITY_TO_GAME(building_teleporter); +LINK_ENTITY_TO_GAME(bullet); +LINK_ENTITY_TO_GAME(bumper_car_start); +LINK_ENTITY_TO_GAME(burning_attack); +LINK_ENTITY_TO_GAME(button_aiwallplug); +LINK_ENTITY_TO_GAME(button_target); +LINK_ENTITY_TO_GAME(calc_position); +LINK_ENTITY_TO_GAME(calc_ratio); +LINK_ENTITY_TO_GAME(calc_subvelocity); +LINK_ENTITY_TO_GAME(calc_velocity_path); +LINK_ENTITY_TO_GAME(calc_velocity_polar); +LINK_ENTITY_TO_GAME(candy); +LINK_ENTITY_TO_GAME(cannon_ball); +LINK_ENTITY_TO_GAME(capture_point); +LINK_ENTITY_TO_GAME(carried_book_team1); +LINK_ENTITY_TO_GAME(carried_book_team2); +LINK_ENTITY_TO_GAME(carried_flag_team1); +LINK_ENTITY_TO_GAME(carried_flag_team2); +LINK_ENTITY_TO_GAME(carry_resource); +LINK_ENTITY_TO_GAME(carry_scientist); +LINK_ENTITY_TO_GAME(ce_psi_01); +LINK_ENTITY_TO_GAME(ce_rocket_01); +LINK_ENTITY_TO_GAME(cflag); +LINK_ENTITY_TO_GAME(chain_hurter); +LINK_ENTITY_TO_GAME(charge); +LINK_ENTITY_TO_GAME(charged_bolt); +LINK_ENTITY_TO_GAME(chronoclip); +LINK_ENTITY_TO_GAME(cine_blood); +LINK_ENTITY_TO_GAME(clbaby); +LINK_ENTITY_TO_GAME(clmomma); +LINK_ENTITY_TO_GAME(cm_rocket_01); +LINK_ENTITY_TO_GAME(cocklebur); +LINK_ENTITY_TO_GAME(conc_charge); +LINK_ENTITY_TO_GAME(control_forklift); +LINK_ENTITY_TO_GAME(controller_charge_ball); +LINK_ENTITY_TO_GAME(controller_charged_ball); +LINK_ENTITY_TO_GAME(controller_energy_ball); +LINK_ENTITY_TO_GAME(controller_head_ball); +LINK_ENTITY_TO_GAME(controller_health_ball); +LINK_ENTITY_TO_GAME(controller_throw_ball); +LINK_ENTITY_TO_GAME(counter); +LINK_ENTITY_TO_GAME(crossbow_bolt); +LINK_ENTITY_TO_GAME(crowbar_rocket); +LINK_ENTITY_TO_GAME(crowbarang); +LINK_ENTITY_TO_GAME(crowd); +LINK_ENTITY_TO_GAME(ctb_point_one); +LINK_ENTITY_TO_GAME(ctb_point_two); +LINK_ENTITY_TO_GAME(ctc_capturepoint); +LINK_ENTITY_TO_GAME(ctc_chicken); +LINK_ENTITY_TO_GAME(ctf_blueflag); +LINK_ENTITY_TO_GAME(ctf_bluespawn); +LINK_ENTITY_TO_GAME(ctf_cloak); +LINK_ENTITY_TO_GAME(ctf_crowbar); +LINK_ENTITY_TO_GAME(ctf_cycle); +LINK_ENTITY_TO_GAME(ctf_flag); +LINK_ENTITY_TO_GAME(ctf_flag_follow_blue); +LINK_ENTITY_TO_GAME(ctf_flag_follow_red); +LINK_ENTITY_TO_GAME(ctf_flagzone); +LINK_ENTITY_TO_GAME(ctf_frag); +LINK_ENTITY_TO_GAME(ctf_hook); +LINK_ENTITY_TO_GAME(ctf_lowgrav); +LINK_ENTITY_TO_GAME(ctf_protect); +LINK_ENTITY_TO_GAME(ctf_redflag); +LINK_ENTITY_TO_GAME(ctf_redspawn); +LINK_ENTITY_TO_GAME(ctf_regen); +LINK_ENTITY_TO_GAME(ctf_rune); +LINK_ENTITY_TO_GAME(ctf_superglock); +LINK_ENTITY_TO_GAME(ctf_trap); +LINK_ENTITY_TO_GAME(ctf_vamp); +LINK_ENTITY_TO_GAME(curse_spawner); +LINK_ENTITY_TO_GAME(cust_11); +LINK_ENTITY_TO_GAME(cust_12); +LINK_ENTITY_TO_GAME(cust_13); +LINK_ENTITY_TO_GAME(cust_21); +LINK_ENTITY_TO_GAME(cust_22); +LINK_ENTITY_TO_GAME(cust_24); +LINK_ENTITY_TO_GAME(cust_25); +LINK_ENTITY_TO_GAME(cust_2GaussPistolSniper); +LINK_ENTITY_TO_GAME(cust_2MinigunCooled); +LINK_ENTITY_TO_GAME(cust_31); +LINK_ENTITY_TO_GAME(cust_33); +LINK_ENTITY_TO_GAME(cust_34); +LINK_ENTITY_TO_GAME(cust_41); +LINK_ENTITY_TO_GAME(cust_43); +LINK_ENTITY_TO_GAME(custom_precache); +LINK_ENTITY_TO_GAME(cycler); +LINK_ENTITY_TO_GAME(cycler_prdroid); +LINK_ENTITY_TO_GAME(cycler_sprite); +LINK_ENTITY_TO_GAME(cycler_weapon); +LINK_ENTITY_TO_GAME(cycler_wreckage); +LINK_ENTITY_TO_GAME(davespit); +LINK_ENTITY_TO_GAME(db_spawner); +LINK_ENTITY_TO_GAME(dc_info_objective); +LINK_ENTITY_TO_GAME(dc_info_objectposition); +LINK_ENTITY_TO_GAME(dc_object); +LINK_ENTITY_TO_GAME(dc_trigger_objectcapture); +LINK_ENTITY_TO_GAME(dc_trigger_reset); +LINK_ENTITY_TO_GAME(dc_trigger_team); +LINK_ENTITY_TO_GAME(deadcorpse); +LINK_ENTITY_TO_GAME(deal_columbian_start); +LINK_ENTITY_TO_GAME(deal_italian_start); +LINK_ENTITY_TO_GAME(deal_swat_start); +LINK_ENTITY_TO_GAME(dealer); +LINK_ENTITY_TO_GAME(death_ball); +LINK_ENTITY_TO_GAME(deathball); +LINK_ENTITY_TO_GAME(deathsoul); +LINK_ENTITY_TO_GAME(debris); +LINK_ENTITY_TO_GAME(decore_aicore); +LINK_ENTITY_TO_GAME(decore_asteroid); +LINK_ENTITY_TO_GAME(decore_baboon); +LINK_ENTITY_TO_GAME(decore_bodygib); +LINK_ENTITY_TO_GAME(decore_butterflyflock); +LINK_ENTITY_TO_GAME(decore_cactus); +LINK_ENTITY_TO_GAME(decore_cam); +LINK_ENTITY_TO_GAME(decore_corpse); +LINK_ENTITY_TO_GAME(decore_eagle); +LINK_ENTITY_TO_GAME(decore_explodable); +LINK_ENTITY_TO_GAME(decore_foot); +LINK_ENTITY_TO_GAME(decore_goldskull); +LINK_ENTITY_TO_GAME(decore_gutspile); +LINK_ENTITY_TO_GAME(decore_hatgib); +LINK_ENTITY_TO_GAME(decore_ice); +LINK_ENTITY_TO_GAME(decore_mushroom); +LINK_ENTITY_TO_GAME(decore_mushroom2); +LINK_ENTITY_TO_GAME(decore_nest); +LINK_ENTITY_TO_GAME(decore_pipes); +LINK_ENTITY_TO_GAME(decore_prickle); +LINK_ENTITY_TO_GAME(decore_pteradon); +LINK_ENTITY_TO_GAME(decore_scripted_boulder); +LINK_ENTITY_TO_GAME(decore_sittingtubemortar); +LINK_ENTITY_TO_GAME(decore_spacebebris); +LINK_ENTITY_TO_GAME(decore_swampplants); +LINK_ENTITY_TO_GAME(decore_torch); +LINK_ENTITY_TO_GAME(decore_torchflame); +LINK_ENTITY_TO_GAME(defensechamber); +LINK_ENTITY_TO_GAME(demoman_mine); +LINK_ENTITY_TO_GAME(detpack); +LINK_ENTITY_TO_GAME(dg_streak_spiral); +LINK_ENTITY_TO_GAME(disc); +LINK_ENTITY_TO_GAME(disc_arena); +LINK_ENTITY_TO_GAME(discarena); +LINK_ENTITY_TO_GAME(dispball); +LINK_ENTITY_TO_GAME(displacer_ball); +LINK_ENTITY_TO_GAME(dmgmirrorcurse); +LINK_ENTITY_TO_GAME(dmgscalecurse); +LINK_ENTITY_TO_GAME(dod_ammo); +LINK_ENTITY_TO_GAME(dod_ammo_depot); +LINK_ENTITY_TO_GAME(dod_camera); +LINK_ENTITY_TO_GAME(dod_capture_area); +LINK_ENTITY_TO_GAME(dod_control_point); +LINK_ENTITY_TO_GAME(dod_control_point_master); +LINK_ENTITY_TO_GAME(dod_location); +LINK_ENTITY_TO_GAME(dod_mapmarker); +LINK_ENTITY_TO_GAME(dod_object); +LINK_ENTITY_TO_GAME(dod_object_goal); +LINK_ENTITY_TO_GAME(dod_point_relay); +LINK_ENTITY_TO_GAME(dod_preround); +LINK_ENTITY_TO_GAME(dod_round_timer); +LINK_ENTITY_TO_GAME(dod_score_ent); +LINK_ENTITY_TO_GAME(dod_secondary); +LINK_ENTITY_TO_GAME(dod_stats); +LINK_ENTITY_TO_GAME(dod_trigger_sandbag); +LINK_ENTITY_TO_GAME(dove_flock); +LINK_ENTITY_TO_GAME(dove_flyer); +LINK_ENTITY_TO_GAME(dragonball); +LINK_ENTITY_TO_GAME(drive_agrunt); +LINK_ENTITY_TO_GAME(drive_agrunt_spawner); +LINK_ENTITY_TO_GAME(drive_apache); +LINK_ENTITY_TO_GAME(drive_apache_spawner); +LINK_ENTITY_TO_GAME(drive_asl); +LINK_ENTITY_TO_GAME(drive_assassin); +LINK_ENTITY_TO_GAME(drive_assassin_spawner); +LINK_ENTITY_TO_GAME(drive_bm); +LINK_ENTITY_TO_GAME(drive_bm_spawner); +LINK_ENTITY_TO_GAME(drive_bullsquid); +LINK_ENTITY_TO_GAME(drive_bullsquid_spawner); +LINK_ENTITY_TO_GAME(drive_chumtoad); +LINK_ENTITY_TO_GAME(drive_controller); +LINK_ENTITY_TO_GAME(drive_controller_spawner); +LINK_ENTITY_TO_GAME(drive_garg); +LINK_ENTITY_TO_GAME(drive_garg_spawner); +LINK_ENTITY_TO_GAME(drive_headcrab); +LINK_ENTITY_TO_GAME(drive_houndeye); +LINK_ENTITY_TO_GAME(drive_houndeye_spawner); +LINK_ENTITY_TO_GAME(drive_icky); +LINK_ENTITY_TO_GAME(drive_icky_spawner); +LINK_ENTITY_TO_GAME(drive_panth); +LINK_ENTITY_TO_GAME(drive_panth_spawner); +LINK_ENTITY_TO_GAME(drive_slave_spawner); +LINK_ENTITY_TO_GAME(drive_turret); +LINK_ENTITY_TO_GAME(drive_turret_spawner); +LINK_ENTITY_TO_GAME(drop_bomb); +LINK_ENTITY_TO_GAME(drunkcurse); +LINK_ENTITY_TO_GAME(drv_hvr_rocket); +LINK_ENTITY_TO_GAME(eagle_laser); +LINK_ENTITY_TO_GAME(effect_shield); +LINK_ENTITY_TO_GAME(egon_mirv); +LINK_ENTITY_TO_GAME(emp_cannister); +LINK_ENTITY_TO_GAME(emp_pulse); +LINK_ENTITY_TO_GAME(entity_botcam); +LINK_ENTITY_TO_GAME(entity_clustergod); +LINK_ENTITY_TO_GAME(entity_digitgod); +LINK_ENTITY_TO_GAME(entity_spawn_round); +LINK_ENTITY_TO_GAME(entity_spritegod); +LINK_ENTITY_TO_GAME(entity_volcanospew); +LINK_ENTITY_TO_GAME(env_ClusterExplosion); +LINK_ENTITY_TO_GAME(env_animsprite); +LINK_ENTITY_TO_GAME(env_beam); +LINK_ENTITY_TO_GAME(env_beamtrail); +LINK_ENTITY_TO_GAME(env_beverage); +LINK_ENTITY_TO_GAME(env_blood); +LINK_ENTITY_TO_GAME(env_blowercannon); +LINK_ENTITY_TO_GAME(env_bombglow); +LINK_ENTITY_TO_GAME(env_bubbles); +LINK_ENTITY_TO_GAME(env_customize); +LINK_ENTITY_TO_GAME(env_debris); +LINK_ENTITY_TO_GAME(env_decal); +LINK_ENTITY_TO_GAME(env_dlight); +LINK_ENTITY_TO_GAME(env_electrified_wire); +LINK_ENTITY_TO_GAME(env_elight); +LINK_ENTITY_TO_GAME(env_explosion); +LINK_ENTITY_TO_GAME(env_fade); +LINK_ENTITY_TO_GAME(env_fadeone); +LINK_ENTITY_TO_GAME(env_fire); +LINK_ENTITY_TO_GAME(env_flag); +LINK_ENTITY_TO_GAME(env_fog); +LINK_ENTITY_TO_GAME(env_footsteps); +LINK_ENTITY_TO_GAME(env_fountain); +LINK_ENTITY_TO_GAME(env_funnel); +LINK_ENTITY_TO_GAME(env_gamma); +LINK_ENTITY_TO_GAME(env_genewormcloud); +LINK_ENTITY_TO_GAME(env_genewormspawn); +LINK_ENTITY_TO_GAME(env_global); +LINK_ENTITY_TO_GAME(env_glow); +LINK_ENTITY_TO_GAME(env_laser); +LINK_ENTITY_TO_GAME(env_lensflare); +LINK_ENTITY_TO_GAME(env_lightning); +LINK_ENTITY_TO_GAME(env_message); +LINK_ENTITY_TO_GAME(env_model); +LINK_ENTITY_TO_GAME(env_mp3); +LINK_ENTITY_TO_GAME(env_music); +LINK_ENTITY_TO_GAME(env_particle); +LINK_ENTITY_TO_GAME(env_particleemitter); +LINK_ENTITY_TO_GAME(env_particles); +LINK_ENTITY_TO_GAME(env_particles_custom); +LINK_ENTITY_TO_GAME(env_particule); +LINK_ENTITY_TO_GAME(env_precip); +LINK_ENTITY_TO_GAME(env_push); +LINK_ENTITY_TO_GAME(env_quakefx); +LINK_ENTITY_TO_GAME(env_rain); +LINK_ENTITY_TO_GAME(env_render); +LINK_ENTITY_TO_GAME(env_rocketshooter); +LINK_ENTITY_TO_GAME(env_rope); +LINK_ENTITY_TO_GAME(env_sentence); +LINK_ENTITY_TO_GAME(env_shake); +LINK_ENTITY_TO_GAME(env_shockwave); +LINK_ENTITY_TO_GAME(env_shooter); +LINK_ENTITY_TO_GAME(env_sky); +LINK_ENTITY_TO_GAME(env_smoker); +LINK_ENTITY_TO_GAME(env_snow); +LINK_ENTITY_TO_GAME(env_sound); +LINK_ENTITY_TO_GAME(env_spark); +LINK_ENTITY_TO_GAME(env_spawnereffect); +LINK_ENTITY_TO_GAME(env_sprite); +LINK_ENTITY_TO_GAME(env_spriteshooter); +LINK_ENTITY_TO_GAME(env_spritetrain); +LINK_ENTITY_TO_GAME(env_state); +LINK_ENTITY_TO_GAME(env_sun); +LINK_ENTITY_TO_GAME(env_timer); +LINK_ENTITY_TO_GAME(env_vgui); +LINK_ENTITY_TO_GAME(env_warpball); +LINK_ENTITY_TO_GAME(env_weather); +LINK_ENTITY_TO_GAME(env_xenmaker); +LINK_ENTITY_TO_GAME(equipment_parachute); +LINK_ENTITY_TO_GAME(event_player_die); +LINK_ENTITY_TO_GAME(event_player_join); +LINK_ENTITY_TO_GAME(event_player_kill); +LINK_ENTITY_TO_GAME(event_player_leave); +LINK_ENTITY_TO_GAME(event_player_spawn); +LINK_ENTITY_TO_GAME(event_round_end); +LINK_ENTITY_TO_GAME(event_round_prestart); +LINK_ENTITY_TO_GAME(event_round_reset); +LINK_ENTITY_TO_GAME(event_round_start); +LINK_ENTITY_TO_GAME(event_team_die); +LINK_ENTITY_TO_GAME(event_team_win); +LINK_ENTITY_TO_GAME(explode_bolt); +LINK_ENTITY_TO_GAME(explodingattack); +LINK_ENTITY_TO_GAME(explosive_slug); +LINK_ENTITY_TO_GAME(external_cam); +LINK_ENTITY_TO_GAME(extra_ammo); +LINK_ENTITY_TO_GAME(fa_drop_zone); +LINK_ENTITY_TO_GAME(fa_parachute); +LINK_ENTITY_TO_GAME(fa_push_flag); +LINK_ENTITY_TO_GAME(fa_push_point); +LINK_ENTITY_TO_GAME(fa_sd_object); +LINK_ENTITY_TO_GAME(fa_team_goal); +LINK_ENTITY_TO_GAME(fa_team_item); +LINK_ENTITY_TO_GAME(fading_corpse); +LINK_ENTITY_TO_GAME(fev_cloud); +LINK_ENTITY_TO_GAME(fev_vial); +LINK_ENTITY_TO_GAME(final_flash); +LINK_ENTITY_TO_GAME(finish); +LINK_ENTITY_TO_GAME(fire_ball); +LINK_ENTITY_TO_GAME(fireanddie); +LINK_ENTITY_TO_GAME(firework); +LINK_ENTITY_TO_GAME(flag); +LINK_ENTITY_TO_GAME(flag_capture_point); +LINK_ENTITY_TO_GAME(flag_follow); +LINK_ENTITY_TO_GAME(flag_world); +LINK_ENTITY_TO_GAME(flak_bomb); +LINK_ENTITY_TO_GAME(flak_grenade); +LINK_ENTITY_TO_GAME(flak_shard); +LINK_ENTITY_TO_GAME(flakfrag); +LINK_ENTITY_TO_GAME(flame); +LINK_ENTITY_TO_GAME(flame_ball); +LINK_ENTITY_TO_GAME(flame_chunk); +LINK_ENTITY_TO_GAME(flamme); +LINK_ENTITY_TO_GAME(flare); +LINK_ENTITY_TO_GAME(flare_fire); +LINK_ENTITY_TO_GAME(flying_axe); +LINK_ENTITY_TO_GAME(flying_crowbar); +LINK_ENTITY_TO_GAME(fog); +LINK_ENTITY_TO_GAME(follow_ent); +LINK_ENTITY_TO_GAME(followbot); +LINK_ENTITY_TO_GAME(follower_basic); +LINK_ENTITY_TO_GAME(football); +LINK_ENTITY_TO_GAME(frag_grenade); +LINK_ENTITY_TO_GAME(freeze_beam); +LINK_ENTITY_TO_GAME(freeze_gel); +LINK_ENTITY_TO_GAME(freeze_grenade); +LINK_ENTITY_TO_GAME(freeze_timer); +LINK_ENTITY_TO_GAME(friction_timer); +LINK_ENTITY_TO_GAME(frostball); +LINK_ENTITY_TO_GAME(fruit_sacrifice_point_team_green); +LINK_ENTITY_TO_GAME(fruit_sacrifice_point_team_red); +LINK_ENTITY_TO_GAME(func_airstrike_area); +LINK_ENTITY_TO_GAME(func_ammoprovider); +LINK_ENTITY_TO_GAME(func_ammostripper); +LINK_ENTITY_TO_GAME(func_bankteller); +LINK_ENTITY_TO_GAME(func_base); +LINK_ENTITY_TO_GAME(func_bomb_target); +LINK_ENTITY_TO_GAME(func_breakable); +LINK_ENTITY_TO_GAME(func_breakpoints); +LINK_ENTITY_TO_GAME(func_button); +LINK_ENTITY_TO_GAME(func_buyzone); +LINK_ENTITY_TO_GAME(func_capture_area); +LINK_ENTITY_TO_GAME(func_capturepoint); +LINK_ENTITY_TO_GAME(func_clouds); +LINK_ENTITY_TO_GAME(func_conveyor); +LINK_ENTITY_TO_GAME(func_corruptsecurity); +LINK_ENTITY_TO_GAME(func_ctb); +LINK_ENTITY_TO_GAME(func_destroy_objective); +LINK_ENTITY_TO_GAME(func_disctoggle); +LINK_ENTITY_TO_GAME(func_door); +LINK_ENTITY_TO_GAME(func_door2); +LINK_ENTITY_TO_GAME(func_door_rotating); +LINK_ENTITY_TO_GAME(func_elevator); +LINK_ENTITY_TO_GAME(func_escapezone); +LINK_ENTITY_TO_GAME(func_friction); +LINK_ENTITY_TO_GAME(func_goal_zone); +LINK_ENTITY_TO_GAME(func_goalpoint); +LINK_ENTITY_TO_GAME(func_golem_body); +LINK_ENTITY_TO_GAME(func_golem_controls_attack); +LINK_ENTITY_TO_GAME(func_golem_controls_forward); +LINK_ENTITY_TO_GAME(func_golem_controls_left); +LINK_ENTITY_TO_GAME(func_golem_controls_right); +LINK_ENTITY_TO_GAME(func_golem_leftarm); +LINK_ENTITY_TO_GAME(func_golem_leftleg); +LINK_ENTITY_TO_GAME(func_golem_rightarm); +LINK_ENTITY_TO_GAME(func_golem_rightleg); +LINK_ENTITY_TO_GAME(func_grencatch); +LINK_ENTITY_TO_GAME(func_guntarget); +LINK_ENTITY_TO_GAME(func_healthcharger); +LINK_ENTITY_TO_GAME(func_hostage_rescue); +LINK_ENTITY_TO_GAME(func_illusionary); +LINK_ENTITY_TO_GAME(func_jail_breakable); +LINK_ENTITY_TO_GAME(func_jail_button); +LINK_ENTITY_TO_GAME(func_jail_door); +LINK_ENTITY_TO_GAME(func_jail_door_rotating); +LINK_ENTITY_TO_GAME(func_jail_pushable); +LINK_ENTITY_TO_GAME(func_jail_release); +LINK_ENTITY_TO_GAME(func_ladder); +LINK_ENTITY_TO_GAME(func_laddertype); +LINK_ENTITY_TO_GAME(func_land_transport); +LINK_ENTITY_TO_GAME(func_landtransport); +LINK_ENTITY_TO_GAME(func_modeltank); +LINK_ENTITY_TO_GAME(func_modelvehicle); +LINK_ENTITY_TO_GAME(func_modelvehiclemodel); +LINK_ENTITY_TO_GAME(func_monsterclip); +LINK_ENTITY_TO_GAME(func_mortar_field); +LINK_ENTITY_TO_GAME(func_music); +LINK_ENTITY_TO_GAME(func_needs); +LINK_ENTITY_TO_GAME(func_needs_boredom); +LINK_ENTITY_TO_GAME(func_needs_dirty); +LINK_ENTITY_TO_GAME(func_needs_drink); +LINK_ENTITY_TO_GAME(func_needs_eat); +LINK_ENTITY_TO_GAME(func_needs_fatigue); +LINK_ENTITY_TO_GAME(func_needs_lonely); +LINK_ENTITY_TO_GAME(func_needs_pee); +LINK_ENTITY_TO_GAME(func_needs_poo); +LINK_ENTITY_TO_GAME(func_nobuild); +LINK_ENTITY_TO_GAME(func_nogrenades); +LINK_ENTITY_TO_GAME(func_op4mortarcontroller); +LINK_ENTITY_TO_GAME(func_particle_system); +LINK_ENTITY_TO_GAME(func_pendulum); +LINK_ENTITY_TO_GAME(func_physics); +LINK_ENTITY_TO_GAME(func_pillageable); +LINK_ENTITY_TO_GAME(func_plat); +LINK_ENTITY_TO_GAME(func_plat_toggleremove); +LINK_ENTITY_TO_GAME(func_platrot); +LINK_ENTITY_TO_GAME(func_player_start); +LINK_ENTITY_TO_GAME(func_point); +LINK_ENTITY_TO_GAME(func_possesion); +LINK_ENTITY_TO_GAME(func_protect); +LINK_ENTITY_TO_GAME(func_pushable); +LINK_ENTITY_TO_GAME(func_rain); +LINK_ENTITY_TO_GAME(func_recharge); +LINK_ENTITY_TO_GAME(func_reset); +LINK_ENTITY_TO_GAME(func_resource); +LINK_ENTITY_TO_GAME(func_rot_button); +LINK_ENTITY_TO_GAME(func_rotating); +LINK_ENTITY_TO_GAME(func_searchlight); +LINK_ENTITY_TO_GAME(func_securityzone); +LINK_ENTITY_TO_GAME(func_seethrough); +LINK_ENTITY_TO_GAME(func_seethroughdoor); +LINK_ENTITY_TO_GAME(func_shine); +LINK_ENTITY_TO_GAME(func_sickbay_bed); +LINK_ENTITY_TO_GAME(func_sickbay_psych); +LINK_ENTITY_TO_GAME(func_snow); +LINK_ENTITY_TO_GAME(func_tank); +LINK_ENTITY_TO_GAME(func_tank_gauss); +LINK_ENTITY_TO_GAME(func_tank_of); +LINK_ENTITY_TO_GAME(func_tank_turret); +LINK_ENTITY_TO_GAME(func_tankbase); +LINK_ENTITY_TO_GAME(func_tankcannon); +LINK_ENTITY_TO_GAME(func_tankcontrols); +LINK_ENTITY_TO_GAME(func_tankcontrols_of); +LINK_ENTITY_TO_GAME(func_tankdrive); +LINK_ENTITY_TO_GAME(func_tankgib); +LINK_ENTITY_TO_GAME(func_tankgib_gib); +LINK_ENTITY_TO_GAME(func_tankgoauld); +LINK_ENTITY_TO_GAME(func_tanklaser); +LINK_ENTITY_TO_GAME(func_tanklaser_of); +LINK_ENTITY_TO_GAME(func_tankmg); +LINK_ENTITY_TO_GAME(func_tankmortar); +LINK_ENTITY_TO_GAME(func_tankmortar_of); +LINK_ENTITY_TO_GAME(func_tankrocket); +LINK_ENTITY_TO_GAME(func_tankrocket_of); +LINK_ENTITY_TO_GAME(func_tanktarget); +LINK_ENTITY_TO_GAME(func_tbutton); +LINK_ENTITY_TO_GAME(func_tech_breakable); +LINK_ENTITY_TO_GAME(func_trackautochange); +LINK_ENTITY_TO_GAME(func_trackchange); +LINK_ENTITY_TO_GAME(func_tracktrain); +LINK_ENTITY_TO_GAME(func_train); +LINK_ENTITY_TO_GAME(func_traincontrols); +LINK_ENTITY_TO_GAME(func_trenchcap1); +LINK_ENTITY_TO_GAME(func_trenchcap2); +LINK_ENTITY_TO_GAME(func_trenchcap3); +LINK_ENTITY_TO_GAME(func_trenchcap4); +LINK_ENTITY_TO_GAME(func_use); +LINK_ENTITY_TO_GAME(func_vehicle); +LINK_ENTITY_TO_GAME(func_vehiclecontrols); +LINK_ENTITY_TO_GAME(func_vehicletankcontrols); +LINK_ENTITY_TO_GAME(func_vine); +LINK_ENTITY_TO_GAME(func_vip_safetyzone); +LINK_ENTITY_TO_GAME(func_wall); +LINK_ENTITY_TO_GAME(func_wall_toggle); +LINK_ENTITY_TO_GAME(func_wardrobe); +LINK_ENTITY_TO_GAME(func_water); +LINK_ENTITY_TO_GAME(func_water_up); +LINK_ENTITY_TO_GAME(func_weaponcheck); +LINK_ENTITY_TO_GAME(func_weldable); +LINK_ENTITY_TO_GAME(func_wind); +LINK_ENTITY_TO_GAME(game_clock); +LINK_ENTITY_TO_GAME(game_counter); +LINK_ENTITY_TO_GAME(game_counter_set); +LINK_ENTITY_TO_GAME(game_end); +LINK_ENTITY_TO_GAME(game_endbattle); +LINK_ENTITY_TO_GAME(game_item); +LINK_ENTITY_TO_GAME(game_levelmusic); +LINK_ENTITY_TO_GAME(game_nuke); +LINK_ENTITY_TO_GAME(game_player_die); +LINK_ENTITY_TO_GAME(game_player_equip); +LINK_ENTITY_TO_GAME(game_player_hurt); +LINK_ENTITY_TO_GAME(game_player_message); +LINK_ENTITY_TO_GAME(game_player_team); +LINK_ENTITY_TO_GAME(game_playerdie); +LINK_ENTITY_TO_GAME(game_roundend); +LINK_ENTITY_TO_GAME(game_score); +LINK_ENTITY_TO_GAME(game_team_master); +LINK_ENTITY_TO_GAME(game_team_score); +LINK_ENTITY_TO_GAME(game_team_set); +LINK_ENTITY_TO_GAME(game_team_win); +LINK_ENTITY_TO_GAME(game_text); +LINK_ENTITY_TO_GAME(game_zone_pirscore); +LINK_ENTITY_TO_GAME(game_zone_player); +LINK_ENTITY_TO_GAME(game_zone_territory); +LINK_ENTITY_TO_GAME(game_zone_vikscore); +LINK_ENTITY_TO_GAME(gameclock); +LINK_ENTITY_TO_GAME(garg_hull); +LINK_ENTITY_TO_GAME(garg_stomp); +LINK_ENTITY_TO_GAME(gauss_becon); +LINK_ENTITY_TO_GAME(generic_model); +LINK_ENTITY_TO_GAME(getGlobalStunLevel); +LINK_ENTITY_TO_GAME(ghost); +LINK_ENTITY_TO_GAME(gibable_corpse); +LINK_ENTITY_TO_GAME(gibshooter); +LINK_ENTITY_TO_GAME(glock_gib); +LINK_ENTITY_TO_GAME(glock_stickygib); +LINK_ENTITY_TO_GAME(gluon); +LINK_ENTITY_TO_GAME(gluon2); +LINK_ENTITY_TO_GAME(gonarch_headcrabifier); +LINK_ENTITY_TO_GAME(gonomeguts); +LINK_ENTITY_TO_GAME(gonomespit); +LINK_ENTITY_TO_GAME(gr_shell); +LINK_ENTITY_TO_GAME(grapple_bolt); +LINK_ENTITY_TO_GAME(grapple_hook); +LINK_ENTITY_TO_GAME(grapple_tip); +LINK_ENTITY_TO_GAME(grappletongue); +LINK_ENTITY_TO_GAME(gravity_grenade); +LINK_ENTITY_TO_GAME(gren_projectile); +LINK_ENTITY_TO_GAME(gren_smoke); +LINK_ENTITY_TO_GAME(grenade); +LINK_ENTITY_TO_GAME(guard_info); +LINK_ENTITY_TO_GAME(guidedattack); +LINK_ENTITY_TO_GAME(gunmancycler); +LINK_ENTITY_TO_GAME(hallucgrenade); +LINK_ENTITY_TO_GAME(halo_base); +LINK_ENTITY_TO_GAME(hand_knife); +LINK_ENTITY_TO_GAME(he_charge_flare); +LINK_ENTITY_TO_GAME(he_eye_flare); +LINK_ENTITY_TO_GAME(headcrab_teather); +LINK_ENTITY_TO_GAME(hegrenade); +LINK_ENTITY_TO_GAME(hellfire); +LINK_ENTITY_TO_GAME(hi_bomb_zone); +LINK_ENTITY_TO_GAME(hi_button_load); +LINK_ENTITY_TO_GAME(hi_coop_tango); +LINK_ENTITY_TO_GAME(hi_fog); +LINK_ENTITY_TO_GAME(hi_global); +LINK_ENTITY_TO_GAME(hi_hostage); +LINK_ENTITY_TO_GAME(hi_hostage_rescue); +LINK_ENTITY_TO_GAME(hi_hostage_respawn); +LINK_ENTITY_TO_GAME(hi_nameposition); +LINK_ENTITY_TO_GAME(hi_objective); +LINK_ENTITY_TO_GAME(hi_objective_manager); +LINK_ENTITY_TO_GAME(hi_round_timer); +LINK_ENTITY_TO_GAME(hi_spawn_hostage); +LINK_ENTITY_TO_GAME(hi_spawn_nato); +LINK_ENTITY_TO_GAME(hi_spawn_observer); +LINK_ENTITY_TO_GAME(hi_spawn_tango); +LINK_ENTITY_TO_GAME(hlight); +LINK_ENTITY_TO_GAME(hltr_assaut_boutton); +LINK_ENTITY_TO_GAME(hltr_hostage); +LINK_ENTITY_TO_GAME(hltr_object); +LINK_ENTITY_TO_GAME(hltr_object_tombe); +LINK_ENTITY_TO_GAME(hltr_objectcapture); +LINK_ENTITY_TO_GAME(hltr_objectif); +LINK_ENTITY_TO_GAME(hltr_objectif_num); +LINK_ENTITY_TO_GAME(hltr_passant); +LINK_ENTITY_TO_GAME(hltr_spectator_start); +LINK_ENTITY_TO_GAME(hltr_turret); +LINK_ENTITY_TO_GAME(hltr_waypoint); +LINK_ENTITY_TO_GAME(holo_player); +LINK_ENTITY_TO_GAME(hologram_beak); +LINK_ENTITY_TO_GAME(hologram_damage); +LINK_ENTITY_TO_GAME(holywars_rocket); +LINK_ENTITY_TO_GAME(homing_balls); +LINK_ENTITY_TO_GAME(hornet); +LINK_ENTITY_TO_GAME(hospital); +LINK_ENTITY_TO_GAME(hostage_entity); +LINK_ENTITY_TO_GAME(hud_sprite); +LINK_ENTITY_TO_GAME(human_flashgrenade); +LINK_ENTITY_TO_GAME(hvr_blkop_rocket); +LINK_ENTITY_TO_GAME(hvr_rocket); +LINK_ENTITY_TO_GAME(i_p_t); +LINK_ENTITY_TO_GAME(i_t_g); +LINK_ENTITY_TO_GAME(i_t_t); +LINK_ENTITY_TO_GAME(i_w_g); +LINK_ENTITY_TO_GAME(i_w_t); +LINK_ENTITY_TO_GAME(iflame); +LINK_ENTITY_TO_GAME(impact_sprite); +LINK_ENTITY_TO_GAME(impail_arrow); +LINK_ENTITY_TO_GAME(impailer); +LINK_ENTITY_TO_GAME(impgren); +LINK_ENTITY_TO_GAME(implode_timer); +LINK_ENTITY_TO_GAME(in_shell); +LINK_ENTITY_TO_GAME(incendiary_rocket); +LINK_ENTITY_TO_GAME(indian_arrow); +LINK_ENTITY_TO_GAME(infect); +LINK_ENTITY_TO_GAME(info_Waterdetect); +LINK_ENTITY_TO_GAME(info_administrator); +LINK_ENTITY_TO_GAME(info_airstrike_node); +LINK_ENTITY_TO_GAME(info_alarm); +LINK_ENTITY_TO_GAME(info_alias); +LINK_ENTITY_TO_GAME(info_alien_return); +LINK_ENTITY_TO_GAME(info_alien_start); +LINK_ENTITY_TO_GAME(info_american_line); +LINK_ENTITY_TO_GAME(info_areadef); +LINK_ENTITY_TO_GAME(info_areamarker); +LINK_ENTITY_TO_GAME(info_ball_start); +LINK_ENTITY_TO_GAME(info_banana_green_capture); +LINK_ENTITY_TO_GAME(info_banana_red_capture); +LINK_ENTITY_TO_GAME(info_bananier); +LINK_ENTITY_TO_GAME(info_bg_detect); +LINK_ENTITY_TO_GAME(info_bigmomma); +LINK_ENTITY_TO_GAME(info_bomb_target); +LINK_ENTITY_TO_GAME(info_bone); +LINK_ENTITY_TO_GAME(info_bone_spawn); +LINK_ENTITY_TO_GAME(info_boobytrap); +LINK_ENTITY_TO_GAME(info_botlandmark); +LINK_ENTITY_TO_GAME(info_botnode); +LINK_ENTITY_TO_GAME(info_british_line); +LINK_ENTITY_TO_GAME(info_button_phonebooth); +LINK_ENTITY_TO_GAME(info_caisse_128); +LINK_ENTITY_TO_GAME(info_caisse_16); +LINK_ENTITY_TO_GAME(info_caisse_256); +LINK_ENTITY_TO_GAME(info_caisse_32); +LINK_ENTITY_TO_GAME(info_caisse_64); +LINK_ENTITY_TO_GAME(info_camera); +LINK_ENTITY_TO_GAME(info_cap_rules); +LINK_ENTITY_TO_GAME(info_checkpoint); +LINK_ENTITY_TO_GAME(info_chicken); +LINK_ENTITY_TO_GAME(info_chip); +LINK_ENTITY_TO_GAME(info_civ_start); +LINK_ENTITY_TO_GAME(info_compile_parameters); +LINK_ENTITY_TO_GAME(info_css); +LINK_ENTITY_TO_GAME(info_ctb_controller); +LINK_ENTITY_TO_GAME(info_ctfdetect); +LINK_ENTITY_TO_GAME(info_ctfspawn); +LINK_ENTITY_TO_GAME(info_ctfspawn_powerup); +LINK_ENTITY_TO_GAME(info_curtain); +LINK_ENTITY_TO_GAME(info_deathball_spawn); +LINK_ENTITY_TO_GAME(info_defaultammo); +LINK_ENTITY_TO_GAME(info_displacer_earth_target); +LINK_ENTITY_TO_GAME(info_displacer_xen_target); +LINK_ENTITY_TO_GAME(info_dm ); +LINK_ENTITY_TO_GAME(info_doddetect); +LINK_ENTITY_TO_GAME(info_dragonrider_spawn); +LINK_ENTITY_TO_GAME(info_draw_slayerswin); +LINK_ENTITY_TO_GAME(info_draw_vampireswin); +LINK_ENTITY_TO_GAME(info_drive_agrunt_spawn); +LINK_ENTITY_TO_GAME(info_drive_apache_spawn); +LINK_ENTITY_TO_GAME(info_drive_assassin_spawn); +LINK_ENTITY_TO_GAME(info_drive_bm_spawn); +LINK_ENTITY_TO_GAME(info_drive_bullsquid_spawn); +LINK_ENTITY_TO_GAME(info_drive_controller_spawn); +LINK_ENTITY_TO_GAME(info_drive_garg_spawn); +LINK_ENTITY_TO_GAME(info_drive_houndeye_spawn); +LINK_ENTITY_TO_GAME(info_drive_icky_spawn); +LINK_ENTITY_TO_GAME(info_drive_panth_spawn); +LINK_ENTITY_TO_GAME(info_drive_slave_spawn); +LINK_ENTITY_TO_GAME(info_drive_turret_spawn); +LINK_ENTITY_TO_GAME(info_elephant); +LINK_ENTITY_TO_GAME(info_elev_floor); +LINK_ENTITY_TO_GAME(info_escape_start); +LINK_ENTITY_TO_GAME(info_escape_target); +LINK_ENTITY_TO_GAME(info_evil_start); +LINK_ENTITY_TO_GAME(info_firearms_detect); +LINK_ENTITY_TO_GAME(info_firstround_spawn); +LINK_ENTITY_TO_GAME(info_flagspawn); +LINK_ENTITY_TO_GAME(info_flash); +LINK_ENTITY_TO_GAME(info_frontline); +LINK_ENTITY_TO_GAME(info_gameplay); +LINK_ENTITY_TO_GAME(info_gameplaylogic); +LINK_ENTITY_TO_GAME(info_gangsta_dm_start); +LINK_ENTITY_TO_GAME(info_goldeneye); +LINK_ENTITY_TO_GAME(info_good_start); +LINK_ENTITY_TO_GAME(info_group); +LINK_ENTITY_TO_GAME(info_gwGeneral_spawn); +LINK_ENTITY_TO_GAME(info_gwars_map); +LINK_ENTITY_TO_GAME(info_gwbriefing_spawn); +LINK_ENTITY_TO_GAME(info_gwinmap_spawn); +LINK_ENTITY_TO_GAME(info_gwplayer_spawn); +LINK_ENTITY_TO_GAME(info_gwwaiting_spawn); +LINK_ENTITY_TO_GAME(info_hlpaintctfdetect); +LINK_ENTITY_TO_GAME(info_hmctfdetect); +LINK_ENTITY_TO_GAME(info_hostage_rescue); +LINK_ENTITY_TO_GAME(info_hostage_safezone); +LINK_ENTITY_TO_GAME(info_human_return); +LINK_ENTITY_TO_GAME(info_human_start); +LINK_ENTITY_TO_GAME(info_initial_player_allies); +LINK_ENTITY_TO_GAME(info_initial_player_axis); +LINK_ENTITY_TO_GAME(info_intermission); +LINK_ENTITY_TO_GAME(info_italian_start); +LINK_ENTITY_TO_GAME(info_jail_start); +LINK_ENTITY_TO_GAME(info_join_autoassign); +LINK_ENTITY_TO_GAME(info_join_team); +LINK_ENTITY_TO_GAME(info_jumppad_target); +LINK_ENTITY_TO_GAME(info_jwhite_capture); +LINK_ENTITY_TO_GAME(info_jwhite_escape); +LINK_ENTITY_TO_GAME(info_jwhite_rescue); +LINK_ENTITY_TO_GAME(info_kb_deathmatch); +LINK_ENTITY_TO_GAME(info_lacrymo); +LINK_ENTITY_TO_GAME(info_landmark); +LINK_ENTITY_TO_GAME(info_landmine); +LINK_ENTITY_TO_GAME(info_leave_game); +LINK_ENTITY_TO_GAME(info_location); +LINK_ENTITY_TO_GAME(info_map_parameters); +LINK_ENTITY_TO_GAME(info_mapdetect); +LINK_ENTITY_TO_GAME(info_mapinfo); +LINK_ENTITY_TO_GAME(info_marguerite); +LINK_ENTITY_TO_GAME(info_marker); +LINK_ENTITY_TO_GAME(info_minefield); +LINK_ENTITY_TO_GAME(info_model); +LINK_ENTITY_TO_GAME(info_money_start); +LINK_ENTITY_TO_GAME(info_monkey_start_team_green); +LINK_ENTITY_TO_GAME(info_monkey_start_team_red); +LINK_ENTITY_TO_GAME(info_monster_return); +LINK_ENTITY_TO_GAME(info_monster_start); +LINK_ENTITY_TO_GAME(info_morbid); +LINK_ENTITY_TO_GAME(info_morbid_start); +LINK_ENTITY_TO_GAME(info_movewith); +LINK_ENTITY_TO_GAME(info_msdetect); +LINK_ENTITY_TO_GAME(info_multiple); +LINK_ENTITY_TO_GAME(info_next_map); +LINK_ENTITY_TO_GAME(info_node); +LINK_ENTITY_TO_GAME(info_node_air); +LINK_ENTITY_TO_GAME(info_nomines); +LINK_ENTITY_TO_GAME(info_null); +LINK_ENTITY_TO_GAME(info_objective); +LINK_ENTITY_TO_GAME(info_observer); +LINK_ENTITY_TO_GAME(info_observer_start); +LINK_ENTITY_TO_GAME(info_orientation); +LINK_ENTITY_TO_GAME(info_paintball); +LINK_ENTITY_TO_GAME(info_particles); +LINK_ENTITY_TO_GAME(info_physics); +LINK_ENTITY_TO_GAME(info_pitworm); +LINK_ENTITY_TO_GAME(info_pitworm_steam_lock); +LINK_ENTITY_TO_GAME(info_player_allies); +LINK_ENTITY_TO_GAME(info_player_american); +LINK_ENTITY_TO_GAME(info_player_attacker); +LINK_ENTITY_TO_GAME(info_player_axis); +LINK_ENTITY_TO_GAME(info_player_blue); +LINK_ENTITY_TO_GAME(info_player_british); +LINK_ENTITY_TO_GAME(info_player_coop); +LINK_ENTITY_TO_GAME(info_player_deadstart); +LINK_ENTITY_TO_GAME(info_player_deathmatch); +LINK_ENTITY_TO_GAME(info_player_deathmatch_reverse); +LINK_ENTITY_TO_GAME(info_player_defender); +LINK_ENTITY_TO_GAME(info_player_dm2); +LINK_ENTITY_TO_GAME(info_player_equip); +LINK_ENTITY_TO_GAME(info_player_goauld); +LINK_ENTITY_TO_GAME(info_player_jail); +LINK_ENTITY_TO_GAME(info_player_judge); +LINK_ENTITY_TO_GAME(info_player_knight); +LINK_ENTITY_TO_GAME(info_player_marine); +LINK_ENTITY_TO_GAME(info_player_nva_reenforcement); +LINK_ENTITY_TO_GAME(info_player_observer); +LINK_ENTITY_TO_GAME(info_player_perp); +LINK_ENTITY_TO_GAME(info_player_pirate); +LINK_ENTITY_TO_GAME(info_player_red); +LINK_ENTITY_TO_GAME(info_player_respawn); +LINK_ENTITY_TO_GAME(info_player_slayer); +LINK_ENTITY_TO_GAME(info_player_spectator); +LINK_ENTITY_TO_GAME(info_player_start); +LINK_ENTITY_TO_GAME(info_player_start_prox); +LINK_ENTITY_TO_GAME(info_player_start_reverse); +LINK_ENTITY_TO_GAME(info_player_team1); +LINK_ENTITY_TO_GAME(info_player_team2); +LINK_ENTITY_TO_GAME(info_player_team_at); +LINK_ENTITY_TO_GAME(info_player_team_bt); +LINK_ENTITY_TO_GAME(info_player_team_ce); +LINK_ENTITY_TO_GAME(info_player_team_cm); +LINK_ENTITY_TO_GAME(info_player_team_gf); +LINK_ENTITY_TO_GAME(info_player_team_iw); +LINK_ENTITY_TO_GAME(info_player_team_s); +LINK_ENTITY_TO_GAME(info_player_team_sm); +LINK_ENTITY_TO_GAME(info_player_team_st); +LINK_ENTITY_TO_GAME(info_player_team_we); +LINK_ENTITY_TO_GAME(info_player_teamspawn); +LINK_ENTITY_TO_GAME(info_player_torri); +LINK_ENTITY_TO_GAME(info_player_unas); +LINK_ENTITY_TO_GAME(info_player_usmc_reenforcement); +LINK_ENTITY_TO_GAME(info_player_vampire); +LINK_ENTITY_TO_GAME(info_player_viking); +LINK_ENTITY_TO_GAME(info_playerstart_blue); +LINK_ENTITY_TO_GAME(info_playerstart_red); +LINK_ENTITY_TO_GAME(info_pvk); +LINK_ENTITY_TO_GAME(info_radar_block); +LINK_ENTITY_TO_GAME(info_rescue_monster); +LINK_ENTITY_TO_GAME(info_rescue_point); +LINK_ENTITY_TO_GAME(info_reset); +LINK_ENTITY_TO_GAME(info_robot_return); +LINK_ENTITY_TO_GAME(info_robot_start); +LINK_ENTITY_TO_GAME(info_roundx_spawn); +LINK_ENTITY_TO_GAME(info_russian_start); +LINK_ENTITY_TO_GAME(info_sapin); +LINK_ENTITY_TO_GAME(info_scientist); +LINK_ENTITY_TO_GAME(info_scientist_dead); +LINK_ENTITY_TO_GAME(info_scientist_start); +LINK_ENTITY_TO_GAME(info_semi_null); +LINK_ENTITY_TO_GAME(info_sidetect); +LINK_ENTITY_TO_GAME(info_spawn_container); +LINK_ENTITY_TO_GAME(info_spectate); +LINK_ENTITY_TO_GAME(info_sprite); +LINK_ENTITY_TO_GAME(info_stadium); +LINK_ENTITY_TO_GAME(info_status); +LINK_ENTITY_TO_GAME(info_swat_start); +LINK_ENTITY_TO_GAME(info_target); +LINK_ENTITY_TO_GAME(info_team); +LINK_ENTITY_TO_GAME(info_team1_corner0); +LINK_ENTITY_TO_GAME(info_team1_corner1); +LINK_ENTITY_TO_GAME(info_team1_corner_player0); +LINK_ENTITY_TO_GAME(info_team1_corner_player1); +LINK_ENTITY_TO_GAME(info_team1_goalkick0); +LINK_ENTITY_TO_GAME(info_team1_goalkick1); +LINK_ENTITY_TO_GAME(info_team1_penalty_spot); +LINK_ENTITY_TO_GAME(info_team1_player1); +LINK_ENTITY_TO_GAME(info_team1_player10); +LINK_ENTITY_TO_GAME(info_team1_player11); +LINK_ENTITY_TO_GAME(info_team1_player2); +LINK_ENTITY_TO_GAME(info_team1_player3); +LINK_ENTITY_TO_GAME(info_team1_player4); +LINK_ENTITY_TO_GAME(info_team1_player5); +LINK_ENTITY_TO_GAME(info_team1_player6); +LINK_ENTITY_TO_GAME(info_team1_player7); +LINK_ENTITY_TO_GAME(info_team1_player8); +LINK_ENTITY_TO_GAME(info_team1_player9); +LINK_ENTITY_TO_GAME(info_team2_corner0); +LINK_ENTITY_TO_GAME(info_team2_corner1); +LINK_ENTITY_TO_GAME(info_team2_corner_player0); +LINK_ENTITY_TO_GAME(info_team2_corner_player1); +LINK_ENTITY_TO_GAME(info_team2_goalkick0); +LINK_ENTITY_TO_GAME(info_team2_goalkick1); +LINK_ENTITY_TO_GAME(info_team2_penalty_spot); +LINK_ENTITY_TO_GAME(info_team2_player1); +LINK_ENTITY_TO_GAME(info_team2_player10); +LINK_ENTITY_TO_GAME(info_team2_player11); +LINK_ENTITY_TO_GAME(info_team2_player2); +LINK_ENTITY_TO_GAME(info_team2_player3); +LINK_ENTITY_TO_GAME(info_team2_player4); +LINK_ENTITY_TO_GAME(info_team2_player5); +LINK_ENTITY_TO_GAME(info_team2_player6); +LINK_ENTITY_TO_GAME(info_team2_player7); +LINK_ENTITY_TO_GAME(info_team2_player8); +LINK_ENTITY_TO_GAME(info_team2_player9); +LINK_ENTITY_TO_GAME(info_team_base); +LINK_ENTITY_TO_GAME(info_team_ronin); +LINK_ENTITY_TO_GAME(info_team_scavenger); +LINK_ENTITY_TO_GAME(info_team_start); +LINK_ENTITY_TO_GAME(info_team_usmc); +LINK_ENTITY_TO_GAME(info_teamplaydetect); +LINK_ENTITY_TO_GAME(info_teamspawn); +LINK_ENTITY_TO_GAME(info_teleport_destination); +LINK_ENTITY_TO_GAME(info_texlights); +LINK_ENTITY_TO_GAME(info_tf_teamcheck); +LINK_ENTITY_TO_GAME(info_tf_teamset); +LINK_ENTITY_TO_GAME(info_tfdetect); +LINK_ENTITY_TO_GAME(info_tfgoal); +LINK_ENTITY_TO_GAME(info_tfgoal_timer); +LINK_ENTITY_TO_GAME(info_throw_in); +LINK_ENTITY_TO_GAME(info_transistor); +LINK_ENTITY_TO_GAME(info_transport_node); +LINK_ENTITY_TO_GAME(info_tt_gameplay); +LINK_ENTITY_TO_GAME(info_upko_start); +LINK_ENTITY_TO_GAME(info_usa_start); +LINK_ENTITY_TO_GAME(info_vgui_start); +LINK_ENTITY_TO_GAME(info_vip_start); +LINK_ENTITY_TO_GAME(info_wanteddetect); +LINK_ENTITY_TO_GAME(info_waypoint); +LINK_ENTITY_TO_GAME(info_ww_teamcheck); +LINK_ENTITY_TO_GAME(info_ww_teamset); +LINK_ENTITY_TO_GAME(info_wwdetect); +LINK_ENTITY_TO_GAME(info_wwgoal); +LINK_ENTITY_TO_GAME(info_wwgoal_timer); +LINK_ENTITY_TO_GAME(info_zone); +LINK_ENTITY_TO_GAME(info_zone_caisse); +LINK_ENTITY_TO_GAME(infodecal); +LINK_ENTITY_TO_GAME(inout_register); +LINK_ENTITY_TO_GAME(item_NVG); +LINK_ENTITY_TO_GAME(item_PowerShield); +LINK_ENTITY_TO_GAME(item_acme); +LINK_ENTITY_TO_GAME(item_airtank); +LINK_ENTITY_TO_GAME(item_ammo); +LINK_ENTITY_TO_GAME(item_ammoicon); +LINK_ENTITY_TO_GAME(item_ammopack); +LINK_ENTITY_TO_GAME(item_antidote); +LINK_ENTITY_TO_GAME(item_antidotee); +LINK_ENTITY_TO_GAME(item_antigrav); +LINK_ENTITY_TO_GAME(item_armor); +LINK_ENTITY_TO_GAME(item_armor1); +LINK_ENTITY_TO_GAME(item_armor2); +LINK_ENTITY_TO_GAME(item_armor3); +LINK_ENTITY_TO_GAME(item_armorInv); +LINK_ENTITY_TO_GAME(item_armour); +LINK_ENTITY_TO_GAME(item_artifact_envirosuit); +LINK_ENTITY_TO_GAME(item_artifact_invisibility); +LINK_ENTITY_TO_GAME(item_artifact_invulnerability); +LINK_ENTITY_TO_GAME(item_artifact_super_damage); +LINK_ENTITY_TO_GAME(item_assaultsuit); +LINK_ENTITY_TO_GAME(item_atde_object); +LINK_ENTITY_TO_GAME(item_autodoc); +LINK_ENTITY_TO_GAME(item_backpack); +LINK_ENTITY_TO_GAME(item_badge); +LINK_ENTITY_TO_GAME(item_bag1); +LINK_ENTITY_TO_GAME(item_bag2); +LINK_ENTITY_TO_GAME(item_banana); +LINK_ENTITY_TO_GAME(item_bandage); +LINK_ENTITY_TO_GAME(item_bandolier); +LINK_ENTITY_TO_GAME(item_baril); +LINK_ENTITY_TO_GAME(item_baril_bleu); +LINK_ENTITY_TO_GAME(item_baril_rouge); +LINK_ENTITY_TO_GAME(item_battery); +LINK_ENTITY_TO_GAME(item_beans); +LINK_ENTITY_TO_GAME(item_body); +LINK_ENTITY_TO_GAME(item_bonustime); +LINK_ENTITY_TO_GAME(item_bonustime2); +LINK_ENTITY_TO_GAME(item_bonustime3); +LINK_ENTITY_TO_GAME(item_book_team1); +LINK_ENTITY_TO_GAME(item_book_team2); +LINK_ENTITY_TO_GAME(item_bottle); +LINK_ENTITY_TO_GAME(item_briefcase); +LINK_ENTITY_TO_GAME(item_c4); +LINK_ENTITY_TO_GAME(item_cactus); +LINK_ENTITY_TO_GAME(item_caisse_arme); +LINK_ENTITY_TO_GAME(item_caisse_mega); +LINK_ENTITY_TO_GAME(item_caisse_outil); +LINK_ENTITY_TO_GAME(item_caisse_vie); +LINK_ENTITY_TO_GAME(item_canteen); +LINK_ENTITY_TO_GAME(item_capkey); +LINK_ENTITY_TO_GAME(item_cash); +LINK_ENTITY_TO_GAME(item_catalyst); +LINK_ENTITY_TO_GAME(item_cells); +LINK_ENTITY_TO_GAME(item_chainmail); +LINK_ENTITY_TO_GAME(item_chicken); +LINK_ENTITY_TO_GAME(item_claymore); +LINK_ENTITY_TO_GAME(item_cloak); +LINK_ENTITY_TO_GAME(item_cloaker); +LINK_ENTITY_TO_GAME(item_concussion); +LINK_ENTITY_TO_GAME(item_corpse); +LINK_ENTITY_TO_GAME(item_ctf_flag); +LINK_ENTITY_TO_GAME(item_ctfaccelerator); +LINK_ENTITY_TO_GAME(item_ctfbackpack); +LINK_ENTITY_TO_GAME(item_ctfbase); +LINK_ENTITY_TO_GAME(item_ctfflag); +LINK_ENTITY_TO_GAME(item_ctflongjump); +LINK_ENTITY_TO_GAME(item_ctfportablehev); +LINK_ENTITY_TO_GAME(item_ctfregeneration); +LINK_ENTITY_TO_GAME(item_dbldamage); +LINK_ENTITY_TO_GAME(item_dish); +LINK_ENTITY_TO_GAME(item_docbag); +LINK_ENTITY_TO_GAME(item_document); +LINK_ENTITY_TO_GAME(item_dragonball); +LINK_ENTITY_TO_GAME(item_dyno); +LINK_ENTITY_TO_GAME(item_dyno1); +LINK_ENTITY_TO_GAME(item_elixer); +LINK_ENTITY_TO_GAME(item_elixir); +LINK_ENTITY_TO_GAME(item_energy); +LINK_ENTITY_TO_GAME(item_flag); +LINK_ENTITY_TO_GAME(item_flag1); +LINK_ENTITY_TO_GAME(item_flag2); +LINK_ENTITY_TO_GAME(item_flag_atde); +LINK_ENTITY_TO_GAME(item_flag_blue); +LINK_ENTITY_TO_GAME(item_flag_center); +LINK_ENTITY_TO_GAME(item_flag_cf); +LINK_ENTITY_TO_GAME(item_flag_ctf); +LINK_ENTITY_TO_GAME(item_flag_red); +LINK_ENTITY_TO_GAME(item_flag_slayer); +LINK_ENTITY_TO_GAME(item_flag_team1); +LINK_ENTITY_TO_GAME(item_flag_team2); +LINK_ENTITY_TO_GAME(item_flag_vampire); +LINK_ENTITY_TO_GAME(item_flashbang); +LINK_ENTITY_TO_GAME(item_flashlight); +LINK_ENTITY_TO_GAME(item_food); +LINK_ENTITY_TO_GAME(item_frag); +LINK_ENTITY_TO_GAME(item_fruit); +LINK_ENTITY_TO_GAME(item_gascan); +LINK_ENTITY_TO_GAME(item_generic); +LINK_ENTITY_TO_GAME(item_genericammo); +LINK_ENTITY_TO_GAME(item_glass); +LINK_ENTITY_TO_GAME(item_grappin); +LINK_ENTITY_TO_GAME(item_head); +LINK_ENTITY_TO_GAME(item_health); +LINK_ENTITY_TO_GAME(item_healthkit); +LINK_ENTITY_TO_GAME(item_heavyarmor); +LINK_ENTITY_TO_GAME(item_herbs); +LINK_ENTITY_TO_GAME(item_highjump); +LINK_ENTITY_TO_GAME(item_holster); +LINK_ENTITY_TO_GAME(item_infjetpack); +LINK_ENTITY_TO_GAME(item_invincibility); +LINK_ENTITY_TO_GAME(item_invisibility); +LINK_ENTITY_TO_GAME(item_irnvg); +LINK_ENTITY_TO_GAME(item_jetpack); +LINK_ENTITY_TO_GAME(item_kevlar); +LINK_ENTITY_TO_GAME(item_knife); +LINK_ENTITY_TO_GAME(item_laser); +LINK_ENTITY_TO_GAME(item_leather); +LINK_ENTITY_TO_GAME(item_lgboiler); +LINK_ENTITY_TO_GAME(item_longjump); +LINK_ENTITY_TO_GAME(item_mask); +LINK_ENTITY_TO_GAME(item_medboiler); +LINK_ENTITY_TO_GAME(item_megavirus); +LINK_ENTITY_TO_GAME(item_metal); +LINK_ENTITY_TO_GAME(item_mine); +LINK_ENTITY_TO_GAME(item_money); +LINK_ENTITY_TO_GAME(item_moneycase); +LINK_ENTITY_TO_GAME(item_newspaper); +LINK_ENTITY_TO_GAME(item_nightvision); +LINK_ENTITY_TO_GAME(item_nuclearbomb); +LINK_ENTITY_TO_GAME(item_nuclearbombbutton); +LINK_ENTITY_TO_GAME(item_nuclearbombtimer); +LINK_ENTITY_TO_GAME(item_nvg); +LINK_ENTITY_TO_GAME(item_objective); +LINK_ENTITY_TO_GAME(item_papers); +LINK_ENTITY_TO_GAME(item_parachute); +LINK_ENTITY_TO_GAME(item_pickaxe); +LINK_ENTITY_TO_GAME(item_platemail); +LINK_ENTITY_TO_GAME(item_portableHEV); +LINK_ENTITY_TO_GAME(item_portableHealthkit); +LINK_ENTITY_TO_GAME(item_powerarmor); +LINK_ENTITY_TO_GAME(item_powerup); +LINK_ENTITY_TO_GAME(item_pt); +LINK_ENTITY_TO_GAME(item_quad); +LINK_ENTITY_TO_GAME(item_radio); +LINK_ENTITY_TO_GAME(item_random); +LINK_ENTITY_TO_GAME(item_regeneration); +LINK_ENTITY_TO_GAME(item_resource); +LINK_ENTITY_TO_GAME(item_rockets); +LINK_ENTITY_TO_GAME(item_scope); +LINK_ENTITY_TO_GAME(item_security); +LINK_ENTITY_TO_GAME(item_sensubeanbag); +LINK_ENTITY_TO_GAME(item_shells); +LINK_ENTITY_TO_GAME(item_shovel); +LINK_ENTITY_TO_GAME(item_silencer); +LINK_ENTITY_TO_GAME(item_silvercase); +LINK_ENTITY_TO_GAME(item_smboiler); +LINK_ENTITY_TO_GAME(item_sodacan); +LINK_ENTITY_TO_GAME(item_speedburst); +LINK_ENTITY_TO_GAME(item_spikes); +LINK_ENTITY_TO_GAME(item_stealth); +LINK_ENTITY_TO_GAME(item_steerribs); +LINK_ENTITY_TO_GAME(item_steerskull); +LINK_ENTITY_TO_GAME(item_stg24); +LINK_ENTITY_TO_GAME(item_suit); +LINK_ENTITY_TO_GAME(item_swarm_flag); +LINK_ENTITY_TO_GAME(item_tag); +LINK_ENTITY_TO_GAME(item_telegram); +LINK_ENTITY_TO_GAME(item_telegraphkey); +LINK_ENTITY_TO_GAME(item_teleport); +LINK_ENTITY_TO_GAME(item_tfgoal); +LINK_ENTITY_TO_GAME(item_thighpack); +LINK_ENTITY_TO_GAME(item_tombe_bleu); +LINK_ENTITY_TO_GAME(item_tombe_rouge); +LINK_ENTITY_TO_GAME(item_treasurechest); +LINK_ENTITY_TO_GAME(item_upgradevest); +LINK_ENTITY_TO_GAME(item_vengeance); +LINK_ENTITY_TO_GAME(item_vest); +LINK_ENTITY_TO_GAME(item_wagonwheel); +LINK_ENTITY_TO_GAME(item_weapon); +LINK_ENTITY_TO_GAME(item_wheelside); +LINK_ENTITY_TO_GAME(item_wwgoal); +LINK_ENTITY_TO_GAME(jail_execute); +LINK_ENTITY_TO_GAME(jail_team_master); +LINK_ENTITY_TO_GAME(jailer); +LINK_ENTITY_TO_GAME(javelin); +LINK_ENTITY_TO_GAME(judge); +LINK_ENTITY_TO_GAME(jumppad_sign); +LINK_ENTITY_TO_GAME(kamehameha); +LINK_ENTITY_TO_GAME(kb_fireworklauncher); +LINK_ENTITY_TO_GAME(killerrat); +LINK_ENTITY_TO_GAME(knife); +LINK_ENTITY_TO_GAME(knife_bolt); +LINK_ENTITY_TO_GAME(knife_throw); +LINK_ENTITY_TO_GAME(kotm_crown); +LINK_ENTITY_TO_GAME(kotm_hill); +LINK_ENTITY_TO_GAME(kwSpikeProjectile); +LINK_ENTITY_TO_GAME(lance_proj); +LINK_ENTITY_TO_GAME(laser_aimer); +LINK_ENTITY_TO_GAME(laser_dot); +LINK_ENTITY_TO_GAME(laser_spot); +LINK_ENTITY_TO_GAME(laserbolt); +LINK_ENTITY_TO_GAME(law_rocket); +LINK_ENTITY_TO_GAME(lc_init_ent); +LINK_ENTITY_TO_GAME(lc_respawner); +LINK_ENTITY_TO_GAME(lc_spawner); +LINK_ENTITY_TO_GAME(lcs_spawner); +LINK_ENTITY_TO_GAME(lflamme_fire); +LINK_ENTITY_TO_GAME(lgtng_ball); +LINK_ENTITY_TO_GAME(lifesoul); +LINK_ENTITY_TO_GAME(light); +LINK_ENTITY_TO_GAME(light_environment); +LINK_ENTITY_TO_GAME(light_glow); +LINK_ENTITY_TO_GAME(light_spot); +LINK_ENTITY_TO_GAME(lightfader); +LINK_ENTITY_TO_GAME(load_wpt); +LINK_ENTITY_TO_GAME(locus_alias); +LINK_ENTITY_TO_GAME(locus_beam); +LINK_ENTITY_TO_GAME(locus_variable); +LINK_ENTITY_TO_GAME(m203grenade); +LINK_ENTITY_TO_GAME(m61_grenade); +LINK_ENTITY_TO_GAME(m72_rocket); +LINK_ENTITY_TO_GAME(magicattack); +LINK_ENTITY_TO_GAME(maintainer_ent); +LINK_ENTITY_TO_GAME(mapClassName); +LINK_ENTITY_TO_GAME(mapobject_asiancar); +LINK_ENTITY_TO_GAME(mapobject_bluecar); +LINK_ENTITY_TO_GAME(mapobject_copcar); +LINK_ENTITY_TO_GAME(mapobject_jaguar); +LINK_ENTITY_TO_GAME(mapobject_npc_bum); +LINK_ENTITY_TO_GAME(mapobject_npc_bum1); +LINK_ENTITY_TO_GAME(mapobject_npc_bum2); +LINK_ENTITY_TO_GAME(mapobject_npc_bum3); +LINK_ENTITY_TO_GAME(mapobject_npc_crow); +LINK_ENTITY_TO_GAME(mapobject_npc_slavebot); +LINK_ENTITY_TO_GAME(mapobject_redcar); +LINK_ENTITY_TO_GAME(mapobject_zeppelin); +LINK_ENTITY_TO_GAME(marker); +LINK_ENTITY_TO_GAME(marker_flag); +LINK_ENTITY_TO_GAME(master_key); +LINK_ENTITY_TO_GAME(master_living); +LINK_ENTITY_TO_GAME(master_object_home); +LINK_ENTITY_TO_GAME(master_period); +LINK_ENTITY_TO_GAME(master_player); +LINK_ENTITY_TO_GAME(master_relay); +LINK_ENTITY_TO_GAME(master_round_active); +LINK_ENTITY_TO_GAME(master_round_start); +LINK_ENTITY_TO_GAME(master_secret); +LINK_ENTITY_TO_GAME(master_state); +LINK_ENTITY_TO_GAME(master_team); +LINK_ENTITY_TO_GAME(master_tech); +LINK_ENTITY_TO_GAME(mastertoggle); +LINK_ENTITY_TO_GAME(mazo); +LINK_ENTITY_TO_GAME(mazoold); +LINK_ENTITY_TO_GAME(medal); +LINK_ENTITY_TO_GAME(medevac); +LINK_ENTITY_TO_GAME(medivac); +LINK_ENTITY_TO_GAME(meteor_god); +LINK_ENTITY_TO_GAME(meteor_target); +LINK_ENTITY_TO_GAME(mi_capture_zone); +LINK_ENTITY_TO_GAME(mi_fail_objective); +LINK_ENTITY_TO_GAME(mi_func_fog); +LINK_ENTITY_TO_GAME(mi_grass); +LINK_ENTITY_TO_GAME(mi_model); +LINK_ENTITY_TO_GAME(mi_model_names); +LINK_ENTITY_TO_GAME(mi_model_static); +LINK_ENTITY_TO_GAME(mi_obj_icon); +LINK_ENTITY_TO_GAME(mi_obj_switch); +LINK_ENTITY_TO_GAME(mi_objective_attack); +LINK_ENTITY_TO_GAME(mi_objective_bomb); +LINK_ENTITY_TO_GAME(mi_objective_defend); +LINK_ENTITY_TO_GAME(mi_objective_destruct); +LINK_ENTITY_TO_GAME(mi_objective_extraction); +LINK_ENTITY_TO_GAME(mi_objective_hosrescue); +LINK_ENTITY_TO_GAME(mi_objective_hostage); +LINK_ENTITY_TO_GAME(mi_objective_observation); +LINK_ENTITY_TO_GAME(mi_objective_other); +LINK_ENTITY_TO_GAME(mi_objective_repair); +LINK_ENTITY_TO_GAME(mi_objective_team1); +LINK_ENTITY_TO_GAME(mi_objective_team2); +LINK_ENTITY_TO_GAME(mi_respawn); +LINK_ENTITY_TO_GAME(mi_set_objective); +LINK_ENTITY_TO_GAME(mi_set_respawn); +LINK_ENTITY_TO_GAME(mi_set_timer); +LINK_ENTITY_TO_GAME(mi_spawn_zone); +LINK_ENTITY_TO_GAME(mi_team_damage); +LINK_ENTITY_TO_GAME(mi_team_names); +LINK_ENTITY_TO_GAME(mi_team_push); +LINK_ENTITY_TO_GAME(mi_team_skins); +LINK_ENTITY_TO_GAME(mi_timer); +LINK_ENTITY_TO_GAME(mi_trigger_weather); +LINK_ENTITY_TO_GAME(mi_weather); +LINK_ENTITY_TO_GAME(mini_grunt); +LINK_ENTITY_TO_GAME(mini_rocket); +LINK_ENTITY_TO_GAME(mission_modifier); +LINK_ENTITY_TO_GAME(misterx); +LINK_ENTITY_TO_GAME(mode_relay); +LINK_ENTITY_TO_GAME(model_entity); +LINK_ENTITY_TO_GAME(molotov); +LINK_ENTITY_TO_GAME(momentary_door); +LINK_ENTITY_TO_GAME(momentary_jail_door); +LINK_ENTITY_TO_GAME(momentary_rot_button); +LINK_ENTITY_TO_GAME(monster_ShockTrooper_dead); +LINK_ENTITY_TO_GAME(monster_a10); +LINK_ENTITY_TO_GAME(monster_adrian); +LINK_ENTITY_TO_GAME(monster_adrian_dead); +LINK_ENTITY_TO_GAME(monster_alarm); +LINK_ENTITY_TO_GAME(monster_alien_babyvoltigore); +LINK_ENTITY_TO_GAME(monster_alien_controller); +LINK_ENTITY_TO_GAME(monster_alien_grunt); +LINK_ENTITY_TO_GAME(monster_alien_panther); +LINK_ENTITY_TO_GAME(monster_alien_slave); +LINK_ENTITY_TO_GAME(monster_alien_slave_dead); +LINK_ENTITY_TO_GAME(monster_alien_voltigore); +LINK_ENTITY_TO_GAME(monster_allied_barney); +LINK_ENTITY_TO_GAME(monster_allied_grunt); +LINK_ENTITY_TO_GAME(monster_alliedgrunt_dead); +LINK_ENTITY_TO_GAME(monster_annie); +LINK_ENTITY_TO_GAME(monster_annie_dead); +LINK_ENTITY_TO_GAME(monster_apache); +LINK_ENTITY_TO_GAME(monster_archer); +LINK_ENTITY_TO_GAME(monster_assassin_repel); +LINK_ENTITY_TO_GAME(monster_assassin_target); +LINK_ENTITY_TO_GAME(monster_axis_grunt); +LINK_ENTITY_TO_GAME(monster_axisgrunt_dead); +LINK_ENTITY_TO_GAME(monster_babycrab); +LINK_ENTITY_TO_GAME(monster_babygarg); +LINK_ENTITY_TO_GAME(monster_balllightning); +LINK_ENTITY_TO_GAME(monster_barnacle); +LINK_ENTITY_TO_GAME(monster_barney); +LINK_ENTITY_TO_GAME(monster_barney_dead); +LINK_ENTITY_TO_GAME(monster_barniel); +LINK_ENTITY_TO_GAME(monster_barniel_dead); +LINK_ENTITY_TO_GAME(monster_bbturret); +LINK_ENTITY_TO_GAME(monster_beak); +LINK_ENTITY_TO_GAME(monster_bear); +LINK_ENTITY_TO_GAME(monster_beartrap); +LINK_ENTITY_TO_GAME(monster_bigminer); +LINK_ENTITY_TO_GAME(monster_bigminer_dead); +LINK_ENTITY_TO_GAME(monster_bigmomma); +LINK_ENTITY_TO_GAME(monster_blkop_apache); +LINK_ENTITY_TO_GAME(monster_blkop_ospray); +LINK_ENTITY_TO_GAME(monster_blkop_osprey); +LINK_ENTITY_TO_GAME(monster_bloater); +LINK_ENTITY_TO_GAME(monster_bodypart); +LINK_ENTITY_TO_GAME(monster_bomb); +LINK_ENTITY_TO_GAME(monster_buffalo); +LINK_ENTITY_TO_GAME(monster_bullchicken); +LINK_ENTITY_TO_GAME(monster_bullsquid); +LINK_ENTITY_TO_GAME(monster_burnmine); +LINK_ENTITY_TO_GAME(monster_c4); +LINK_ENTITY_TO_GAME(monster_camera); +LINK_ENTITY_TO_GAME(monster_cat); +LINK_ENTITY_TO_GAME(monster_chicken); +LINK_ENTITY_TO_GAME(monster_chumtoad); +LINK_ENTITY_TO_GAME(monster_cine2_crispen); +LINK_ENTITY_TO_GAME(monster_cine2_dave); +LINK_ENTITY_TO_GAME(monster_cine2_hvyweapons); +LINK_ENTITY_TO_GAME(monster_cine2_masala); +LINK_ENTITY_TO_GAME(monster_cine2_nagatow); +LINK_ENTITY_TO_GAME(monster_cine2_scientist); +LINK_ENTITY_TO_GAME(monster_cine2_slave); +LINK_ENTITY_TO_GAME(monster_cine2_tiedcolonel); +LINK_ENTITY_TO_GAME(monster_cine2_townmex); +LINK_ENTITY_TO_GAME(monster_cine2_wtowna); +LINK_ENTITY_TO_GAME(monster_cine2_wtownb); +LINK_ENTITY_TO_GAME(monster_cine3_annie); +LINK_ENTITY_TO_GAME(monster_cine3_barney); +LINK_ENTITY_TO_GAME(monster_cine3_crispen); +LINK_ENTITY_TO_GAME(monster_cine3_dave); +LINK_ENTITY_TO_GAME(monster_cine3_hoss); +LINK_ENTITY_TO_GAME(monster_cine3_masala); +LINK_ENTITY_TO_GAME(monster_cine3_nagatow); +LINK_ENTITY_TO_GAME(monster_cine3_scientist); +LINK_ENTITY_TO_GAME(monster_cine3_tiedcolonel); +LINK_ENTITY_TO_GAME(monster_cine3_townmex); +LINK_ENTITY_TO_GAME(monster_cine3_wtowna); +LINK_ENTITY_TO_GAME(monster_cine3_wtownb); +LINK_ENTITY_TO_GAME(monster_cine_annie); +LINK_ENTITY_TO_GAME(monster_cine_barney); +LINK_ENTITY_TO_GAME(monster_cine_crispen); +LINK_ENTITY_TO_GAME(monster_cine_dave); +LINK_ENTITY_TO_GAME(monster_cine_hoss); +LINK_ENTITY_TO_GAME(monster_cine_masala); +LINK_ENTITY_TO_GAME(monster_cine_nagatow); +LINK_ENTITY_TO_GAME(monster_cine_panther); +LINK_ENTITY_TO_GAME(monster_cine_scientist); +LINK_ENTITY_TO_GAME(monster_cine_tiedcolonel); +LINK_ENTITY_TO_GAME(monster_cine_townmex); +LINK_ENTITY_TO_GAME(monster_cine_wtowna); +LINK_ENTITY_TO_GAME(monster_cine_wtownb); +LINK_ENTITY_TO_GAME(monster_civilian); +LINK_ENTITY_TO_GAME(monster_civilian_dead); +LINK_ENTITY_TO_GAME(monster_cleansuit_scientist); +LINK_ENTITY_TO_GAME(monster_cleansuit_scientist_dead); +LINK_ENTITY_TO_GAME(monster_cockroach); +LINK_ENTITY_TO_GAME(monster_colonel); +LINK_ENTITY_TO_GAME(monster_colonel_dead); +LINK_ENTITY_TO_GAME(monster_cow); +LINK_ENTITY_TO_GAME(monster_cowboy); +LINK_ENTITY_TO_GAME(monster_cowboy_dead); +LINK_ENTITY_TO_GAME(monster_cricket); +LINK_ENTITY_TO_GAME(monster_crispen); +LINK_ENTITY_TO_GAME(monster_crispen_dead); +LINK_ENTITY_TO_GAME(monster_critter); +LINK_ENTITY_TO_GAME(monster_darttrap); +LINK_ENTITY_TO_GAME(monster_dave); +LINK_ENTITY_TO_GAME(monster_dave_dead); +LINK_ENTITY_TO_GAME(monster_demo); +LINK_ENTITY_TO_GAME(monster_dog); +LINK_ENTITY_TO_GAME(monster_dragon); +LINK_ENTITY_TO_GAME(monster_dragonfly); +LINK_ENTITY_TO_GAME(monster_drillsergeant); +LINK_ENTITY_TO_GAME(monster_eagle); +LINK_ENTITY_TO_GAME(monster_eagle_flock); +LINK_ENTITY_TO_GAME(monster_endboss); +LINK_ENTITY_TO_GAME(monster_exp_alien_slave); +LINK_ENTITY_TO_GAME(monster_fakemedkit); +LINK_ENTITY_TO_GAME(monster_fgrunt_repel); +LINK_ENTITY_TO_GAME(monster_flag1); +LINK_ENTITY_TO_GAME(monster_flag2); +LINK_ENTITY_TO_GAME(monster_flag3); +LINK_ENTITY_TO_GAME(monster_flag4); +LINK_ENTITY_TO_GAME(monster_flashlight); +LINK_ENTITY_TO_GAME(monster_flyer); +LINK_ENTITY_TO_GAME(monster_flyer_flock); +LINK_ENTITY_TO_GAME(monster_furniture); +LINK_ENTITY_TO_GAME(monster_garbage); +LINK_ENTITY_TO_GAME(monster_gargantua); +LINK_ENTITY_TO_GAME(monster_gator); +LINK_ENTITY_TO_GAME(monster_generic); +LINK_ENTITY_TO_GAME(monster_generic_dead); +LINK_ENTITY_TO_GAME(monster_geneworm); +LINK_ENTITY_TO_GAME(monster_giantplant); +LINK_ENTITY_TO_GAME(monster_gman); +LINK_ENTITY_TO_GAME(monster_goat); +LINK_ENTITY_TO_GAME(monster_goblin); +LINK_ENTITY_TO_GAME(monster_gonome); +LINK_ENTITY_TO_GAME(monster_gonome_dead); +LINK_ENTITY_TO_GAME(monster_gordon); +LINK_ENTITY_TO_GAME(monster_gordon_dead); +LINK_ENTITY_TO_GAME(monster_gps); +LINK_ENTITY_TO_GAME(monster_grunt_ally_medic_dead); +LINK_ENTITY_TO_GAME(monster_grunt_ally_repel); +LINK_ENTITY_TO_GAME(monster_grunt_ally_torch_dead); +LINK_ENTITY_TO_GAME(monster_grunt_repel); +LINK_ENTITY_TO_GAME(monster_gunner_friendly); +LINK_ENTITY_TO_GAME(monster_hatchetfish); +LINK_ENTITY_TO_GAME(monster_headcrab); +LINK_ENTITY_TO_GAME(monster_helicopter); +LINK_ENTITY_TO_GAME(monster_hevbarn); +LINK_ENTITY_TO_GAME(monster_hevbarn_dead); +LINK_ENTITY_TO_GAME(monster_hevsuit_dead); +LINK_ENTITY_TO_GAME(monster_hfgrunt_dead); +LINK_ENTITY_TO_GAME(monster_hgrunt); +LINK_ENTITY_TO_GAME(monster_hgrunt_dead); +LINK_ENTITY_TO_GAME(monster_hgrunt_shotgun); +LINK_ENTITY_TO_GAME(monster_hiveback); +LINK_ENTITY_TO_GAME(monster_horse); +LINK_ENTITY_TO_GAME(monster_hoss); +LINK_ENTITY_TO_GAME(monster_hoss_dead); +LINK_ENTITY_TO_GAME(monster_hostage); +LINK_ENTITY_TO_GAME(monster_hostage_dead); +LINK_ENTITY_TO_GAME(monster_houndeye); +LINK_ENTITY_TO_GAME(monster_houndeye_dead); +LINK_ENTITY_TO_GAME(monster_human_assassin); +LINK_ENTITY_TO_GAME(monster_human_bandit); +LINK_ENTITY_TO_GAME(monster_human_chopper); +LINK_ENTITY_TO_GAME(monster_human_demoman); +LINK_ENTITY_TO_GAME(monster_human_friendly_grunt); +LINK_ENTITY_TO_GAME(monster_human_grunt); +LINK_ENTITY_TO_GAME(monster_human_grunt_ally); +LINK_ENTITY_TO_GAME(monster_human_grunt_ally_dead); +LINK_ENTITY_TO_GAME(monster_human_gunman); +LINK_ENTITY_TO_GAME(monster_human_medic_ally); +LINK_ENTITY_TO_GAME(monster_human_medic_ally_dead); +LINK_ENTITY_TO_GAME(monster_human_scientist); +LINK_ENTITY_TO_GAME(monster_human_spforce); +LINK_ENTITY_TO_GAME(monster_human_terror); +LINK_ENTITY_TO_GAME(monster_human_torch_ally); +LINK_ENTITY_TO_GAME(monster_human_torch_ally_dead); +LINK_ENTITY_TO_GAME(monster_human_unarmed); +LINK_ENTITY_TO_GAME(monster_hwgrunt); +LINK_ENTITY_TO_GAME(monster_hwgrunt_repel); +LINK_ENTITY_TO_GAME(monster_ichthyosaur); +LINK_ENTITY_TO_GAME(monster_implanted); +LINK_ENTITY_TO_GAME(monster_kaiewi); +LINK_ENTITY_TO_GAME(monster_kaiewi_dead); +LINK_ENTITY_TO_GAME(monster_kate); +LINK_ENTITY_TO_GAME(monster_kate_dead); +LINK_ENTITY_TO_GAME(monster_kid); +LINK_ENTITY_TO_GAME(monster_killerbabycrab); +LINK_ENTITY_TO_GAME(monster_largescorpion); +LINK_ENTITY_TO_GAME(monster_larve); +LINK_ENTITY_TO_GAME(monster_leech); +LINK_ENTITY_TO_GAME(monster_llama); +LINK_ENTITY_TO_GAME(monster_lrocket); +LINK_ENTITY_TO_GAME(monster_m2); +LINK_ENTITY_TO_GAME(monster_male_assassin); +LINK_ENTITY_TO_GAME(monster_manta); +LINK_ENTITY_TO_GAME(monster_masala); +LINK_ENTITY_TO_GAME(monster_masala_dead); +LINK_ENTITY_TO_GAME(monster_massassin_dead); +LINK_ENTITY_TO_GAME(monster_medic_ally_repel); +LINK_ENTITY_TO_GAME(monster_mexbandit); +LINK_ENTITY_TO_GAME(monster_mexbandit_dead); +LINK_ENTITY_TO_GAME(monster_microraptor); +LINK_ENTITY_TO_GAME(monster_mine); +LINK_ENTITY_TO_GAME(monster_miniturret); +LINK_ENTITY_TO_GAME(monster_missle); +LINK_ENTITY_TO_GAME(monster_monkey); +LINK_ENTITY_TO_GAME(monster_mortar); +LINK_ENTITY_TO_GAME(monster_morter); +LINK_ENTITY_TO_GAME(monster_mouton); +LINK_ENTITY_TO_GAME(monster_myself); +LINK_ENTITY_TO_GAME(monster_myself_dead); +LINK_ENTITY_TO_GAME(monster_nagatow); +LINK_ENTITY_TO_GAME(monster_nagatow_dead); +LINK_ENTITY_TO_GAME(monster_nihilanth); +LINK_ENTITY_TO_GAME(monster_op4loader); +LINK_ENTITY_TO_GAME(monster_osprey); +LINK_ENTITY_TO_GAME(monster_otis); +LINK_ENTITY_TO_GAME(monster_otis_dead); +LINK_ENTITY_TO_GAME(monster_ourano); +LINK_ENTITY_TO_GAME(monster_parachute); +LINK_ENTITY_TO_GAME(monster_parrot); +LINK_ENTITY_TO_GAME(monster_penguin); +LINK_ENTITY_TO_GAME(monster_penta); +LINK_ENTITY_TO_GAME(monster_pig); +LINK_ENTITY_TO_GAME(monster_pilot); +LINK_ENTITY_TO_GAME(monster_pipebomb); +LINK_ENTITY_TO_GAME(monster_pitdrone); +LINK_ENTITY_TO_GAME(monster_pitworm); +LINK_ENTITY_TO_GAME(monster_pitworm_up); +LINK_ENTITY_TO_GAME(monster_player); +LINK_ENTITY_TO_GAME(monster_poison); +LINK_ENTITY_TO_GAME(monster_powderkeg); +LINK_ENTITY_TO_GAME(monster_prisoner); +LINK_ENTITY_TO_GAME(monster_prop_apache); +LINK_ENTITY_TO_GAME(monster_proximity); +LINK_ENTITY_TO_GAME(monster_puma); +LINK_ENTITY_TO_GAME(monster_ramone); +LINK_ENTITY_TO_GAME(monster_ramone_repel); +LINK_ENTITY_TO_GAME(monster_raptor); +LINK_ENTITY_TO_GAME(monster_rat); +LINK_ENTITY_TO_GAME(monster_recruit); +LINK_ENTITY_TO_GAME(monster_replic); +LINK_ENTITY_TO_GAME(monster_replicateur); +LINK_ENTITY_TO_GAME(monster_replicator); +LINK_ENTITY_TO_GAME(monster_robogrunt); +LINK_ENTITY_TO_GAME(monster_robogrunt_dead); +LINK_ENTITY_TO_GAME(monster_robogrunt_repel); +LINK_ENTITY_TO_GAME(monster_robogruntrepel); +LINK_ENTITY_TO_GAME(monster_rustbattery); +LINK_ENTITY_TO_GAME(monster_rustbit); +LINK_ENTITY_TO_GAME(monster_rustbit_friendly); +LINK_ENTITY_TO_GAME(monster_rustflier); +LINK_ENTITY_TO_GAME(monster_rustgunr); +LINK_ENTITY_TO_GAME(monster_sarge_allies); +LINK_ENTITY_TO_GAME(monster_satchel); +LINK_ENTITY_TO_GAME(monster_scientist); +LINK_ENTITY_TO_GAME(monster_scientist_dead); +LINK_ENTITY_TO_GAME(monster_scorpion); +LINK_ENTITY_TO_GAME(monster_sentry); +LINK_ENTITY_TO_GAME(monster_sentry_mini); +LINK_ENTITY_TO_GAME(monster_sentryx); +LINK_ENTITY_TO_GAME(monster_sheep); +LINK_ENTITY_TO_GAME(monster_shockroach); +LINK_ENTITY_TO_GAME(monster_shocktrooper); +LINK_ENTITY_TO_GAME(monster_shocktrooper_repel); +LINK_ENTITY_TO_GAME(monster_shotgun); +LINK_ENTITY_TO_GAME(monster_sitting_civilian); +LINK_ENTITY_TO_GAME(monster_sitting_cleansuit_scientist); +LINK_ENTITY_TO_GAME(monster_sitting_colonel); +LINK_ENTITY_TO_GAME(monster_sitting_crispen); +LINK_ENTITY_TO_GAME(monster_sitting_dave); +LINK_ENTITY_TO_GAME(monster_sitting_masala); +LINK_ENTITY_TO_GAME(monster_sitting_nagatow); +LINK_ENTITY_TO_GAME(monster_sitting_scientist); +LINK_ENTITY_TO_GAME(monster_sitting_townmex); +LINK_ENTITY_TO_GAME(monster_sitting_twnwesta); +LINK_ENTITY_TO_GAME(monster_sitting_twnwestb); +LINK_ENTITY_TO_GAME(monster_sitting_villager); +LINK_ENTITY_TO_GAME(monster_skeleton); +LINK_ENTITY_TO_GAME(monster_skeleton_dead); +LINK_ENTITY_TO_GAME(monster_skelly); +LINK_ENTITY_TO_GAME(monster_skellydance); +LINK_ENTITY_TO_GAME(monster_skull); +LINK_ENTITY_TO_GAME(monster_skunk); +LINK_ENTITY_TO_GAME(monster_smallminer); +LINK_ENTITY_TO_GAME(monster_smallminer_dead); +LINK_ENTITY_TO_GAME(monster_snake); +LINK_ENTITY_TO_GAME(monster_snark); +LINK_ENTITY_TO_GAME(monster_spforce_dead); +LINK_ENTITY_TO_GAME(monster_spforce_repel); +LINK_ENTITY_TO_GAME(monster_sphere); +LINK_ENTITY_TO_GAME(monster_spider); +LINK_ENTITY_TO_GAME(monster_spiritdragon); +LINK_ENTITY_TO_GAME(monster_spiritwiz); +LINK_ENTITY_TO_GAME(monster_srocket); +LINK_ENTITY_TO_GAME(monster_super_snark); +LINK_ENTITY_TO_GAME(monster_tac); +LINK_ENTITY_TO_GAME(monster_tank); +LINK_ENTITY_TO_GAME(monster_target); +LINK_ENTITY_TO_GAME(monster_targetrocket); +LINK_ENTITY_TO_GAME(monster_tentacle); +LINK_ENTITY_TO_GAME(monster_tentaclemaw); +LINK_ENTITY_TO_GAME(monster_terror_dead); +LINK_ENTITY_TO_GAME(monster_terror_repel); +LINK_ENTITY_TO_GAME(monster_test); +LINK_ENTITY_TO_GAME(monster_thornbush); +LINK_ENTITY_TO_GAME(monster_tied_colonel); +LINK_ENTITY_TO_GAME(monster_torch_ally_repel); +LINK_ENTITY_TO_GAME(monster_tornado); +LINK_ENTITY_TO_GAME(monster_townmex); +LINK_ENTITY_TO_GAME(monster_townmex_dead); +LINK_ENTITY_TO_GAME(monster_trainingbot); +LINK_ENTITY_TO_GAME(monster_tripmine); +LINK_ENTITY_TO_GAME(monster_troop); +LINK_ENTITY_TO_GAME(monster_tube); +LINK_ENTITY_TO_GAME(monster_tube_embryo); +LINK_ENTITY_TO_GAME(monster_turret); +LINK_ENTITY_TO_GAME(monster_turretbase); +LINK_ENTITY_TO_GAME(monster_twnwesta); +LINK_ENTITY_TO_GAME(monster_twnwesta_dead); +LINK_ENTITY_TO_GAME(monster_twnwestb); +LINK_ENTITY_TO_GAME(monster_twnwestb_dead); +LINK_ENTITY_TO_GAME(monster_valve_turret); +LINK_ENTITY_TO_GAME(monster_villager); +LINK_ENTITY_TO_GAME(monster_villager_dead); +LINK_ENTITY_TO_GAME(monster_vortigaunt); +LINK_ENTITY_TO_GAME(monster_wizardclone); +LINK_ENTITY_TO_GAME(monster_wombat); +LINK_ENTITY_TO_GAME(monster_worker); +LINK_ENTITY_TO_GAME(monster_worker_dead); +LINK_ENTITY_TO_GAME(monster_wwmine); +LINK_ENTITY_TO_GAME(monster_xenome); +LINK_ENTITY_TO_GAME(monster_xenome_embryo); +LINK_ENTITY_TO_GAME(monster_zbarney); +LINK_ENTITY_TO_GAME(monster_zombie); +LINK_ENTITY_TO_GAME(monster_zombie2); +LINK_ENTITY_TO_GAME(monster_zombie_barney); +LINK_ENTITY_TO_GAME(monster_zombie_soldier); +LINK_ENTITY_TO_GAME(monster_zombie_soldier_dead); +LINK_ENTITY_TO_GAME(monstermaker); +LINK_ENTITY_TO_GAME(monsterpoint); +LINK_ENTITY_TO_GAME(monsterpoint_backup); +LINK_ENTITY_TO_GAME(mortar_shell); +LINK_ENTITY_TO_GAME(mortarshell); +LINK_ENTITY_TO_GAME(motion_manager); +LINK_ENTITY_TO_GAME(motion_thread); +LINK_ENTITY_TO_GAME(movementchamber); +LINK_ENTITY_TO_GAME(moving_camera); +LINK_ENTITY_TO_GAME(multi_alias); +LINK_ENTITY_TO_GAME(multi_gate_1); +LINK_ENTITY_TO_GAME(multi_gate_10); +LINK_ENTITY_TO_GAME(multi_gate_11); +LINK_ENTITY_TO_GAME(multi_gate_12); +LINK_ENTITY_TO_GAME(multi_gate_13); +LINK_ENTITY_TO_GAME(multi_gate_14); +LINK_ENTITY_TO_GAME(multi_gate_15); +LINK_ENTITY_TO_GAME(multi_gate_16); +LINK_ENTITY_TO_GAME(multi_gate_17); +LINK_ENTITY_TO_GAME(multi_gate_18); +LINK_ENTITY_TO_GAME(multi_gate_19); +LINK_ENTITY_TO_GAME(multi_gate_2); +LINK_ENTITY_TO_GAME(multi_gate_20); +LINK_ENTITY_TO_GAME(multi_gate_21); +LINK_ENTITY_TO_GAME(multi_gate_22); +LINK_ENTITY_TO_GAME(multi_gate_23); +LINK_ENTITY_TO_GAME(multi_gate_24); +LINK_ENTITY_TO_GAME(multi_gate_25); +LINK_ENTITY_TO_GAME(multi_gate_26); +LINK_ENTITY_TO_GAME(multi_gate_27); +LINK_ENTITY_TO_GAME(multi_gate_28); +LINK_ENTITY_TO_GAME(multi_gate_29); +LINK_ENTITY_TO_GAME(multi_gate_3); +LINK_ENTITY_TO_GAME(multi_gate_30); +LINK_ENTITY_TO_GAME(multi_gate_31); +LINK_ENTITY_TO_GAME(multi_gate_32); +LINK_ENTITY_TO_GAME(multi_gate_33); +LINK_ENTITY_TO_GAME(multi_gate_34); +LINK_ENTITY_TO_GAME(multi_gate_35); +LINK_ENTITY_TO_GAME(multi_gate_36); +LINK_ENTITY_TO_GAME(multi_gate_37); +LINK_ENTITY_TO_GAME(multi_gate_38); +LINK_ENTITY_TO_GAME(multi_gate_39); +LINK_ENTITY_TO_GAME(multi_gate_4); +LINK_ENTITY_TO_GAME(multi_gate_40); +LINK_ENTITY_TO_GAME(multi_gate_41); +LINK_ENTITY_TO_GAME(multi_gate_42); +LINK_ENTITY_TO_GAME(multi_gate_43); +LINK_ENTITY_TO_GAME(multi_gate_44); +LINK_ENTITY_TO_GAME(multi_gate_45); +LINK_ENTITY_TO_GAME(multi_gate_46); +LINK_ENTITY_TO_GAME(multi_gate_47); +LINK_ENTITY_TO_GAME(multi_gate_48); +LINK_ENTITY_TO_GAME(multi_gate_49); +LINK_ENTITY_TO_GAME(multi_gate_5); +LINK_ENTITY_TO_GAME(multi_gate_6); +LINK_ENTITY_TO_GAME(multi_gate_7); +LINK_ENTITY_TO_GAME(multi_gate_8); +LINK_ENTITY_TO_GAME(multi_gate_9); +LINK_ENTITY_TO_GAME(multi_manager); +LINK_ENTITY_TO_GAME(multi_watcher); +LINK_ENTITY_TO_GAME(multisource); +LINK_ENTITY_TO_GAME(my_monster); +LINK_ENTITY_TO_GAME(nail); +LINK_ENTITY_TO_GAME(neutrinobeam); +LINK_ENTITY_TO_GAME(nggrenade); +LINK_ENTITY_TO_GAME(nihilanth_energy_ball); +LINK_ENTITY_TO_GAME(node_viewer); +LINK_ENTITY_TO_GAME(node_viewer_fly); +LINK_ENTITY_TO_GAME(node_viewer_human); +LINK_ENTITY_TO_GAME(node_viewer_large); +LINK_ENTITY_TO_GAME(npc); +LINK_ENTITY_TO_GAME(npc_skrunk); +LINK_ENTITY_TO_GAME(nuclear_missile); +LINK_ENTITY_TO_GAME(nuke); +LINK_ENTITY_TO_GAME(nuke_rocket); +LINK_ENTITY_TO_GAME(object); +LINK_ENTITY_TO_GAME(object_beacon); +LINK_ENTITY_TO_GAME(object_follow); +LINK_ENTITY_TO_GAME(object_maker); +LINK_ENTITY_TO_GAME(object_superchip); +LINK_ENTITY_TO_GAME(offensechamber); +LINK_ENTITY_TO_GAME(ol_bell); +LINK_ENTITY_TO_GAME(ol_bluecapture); +LINK_ENTITY_TO_GAME(ol_blueflag); +LINK_ENTITY_TO_GAME(ol_bottle); +LINK_ENTITY_TO_GAME(ol_ctf_blueteam); +LINK_ENTITY_TO_GAME(ol_ctf_redteam); +LINK_ENTITY_TO_GAME(ol_furniture); +LINK_ENTITY_TO_GAME(ol_lantern); +LINK_ENTITY_TO_GAME(ol_redcapture); +LINK_ENTITY_TO_GAME(ol_redflag); +LINK_ENTITY_TO_GAME(ol_spitoon); +LINK_ENTITY_TO_GAME(old_rocket); +LINK_ENTITY_TO_GAME(oldbot); +LINK_ENTITY_TO_GAME(op4mortar); +LINK_ENTITY_TO_GAME(oz_logo); +LINK_ENTITY_TO_GAME(oz_rune); +LINK_ENTITY_TO_GAME(paintball); +LINK_ENTITY_TO_GAME(palm_tree); +LINK_ENTITY_TO_GAME(para_roundtimer); +LINK_ENTITY_TO_GAME(particle); +LINK_ENTITY_TO_GAME(particle_shooter); +LINK_ENTITY_TO_GAME(particle_weatherfx); +LINK_ENTITY_TO_GAME(path_corner); +LINK_ENTITY_TO_GAME(path_monster); +LINK_ENTITY_TO_GAME(path_track); +LINK_ENTITY_TO_GAME(pballblue); +LINK_ENTITY_TO_GAME(pballred); +LINK_ENTITY_TO_GAME(pe_escapezone); +LINK_ENTITY_TO_GAME(pe_light); +LINK_ENTITY_TO_GAME(pe_light_ref); +LINK_ENTITY_TO_GAME(pe_object_case); +LINK_ENTITY_TO_GAME(pe_object_htool); +LINK_ENTITY_TO_GAME(pe_objectclip); +LINK_ENTITY_TO_GAME(pe_radar_mark); +LINK_ENTITY_TO_GAME(pe_rain); +LINK_ENTITY_TO_GAME(pe_spawn_corps); +LINK_ENTITY_TO_GAME(pe_spawn_syndicate); +LINK_ENTITY_TO_GAME(pe_terminal); +LINK_ENTITY_TO_GAME(phase_pulse); +LINK_ENTITY_TO_GAME(phasegate); +LINK_ENTITY_TO_GAME(pickup_drive_agrunt); +LINK_ENTITY_TO_GAME(pickup_drive_apache); +LINK_ENTITY_TO_GAME(pickup_drive_assassin); +LINK_ENTITY_TO_GAME(pickup_drive_bm); +LINK_ENTITY_TO_GAME(pickup_drive_bullsquid); +LINK_ENTITY_TO_GAME(pickup_drive_controller); +LINK_ENTITY_TO_GAME(pickup_drive_garg); +LINK_ENTITY_TO_GAME(pickup_drive_houndeye); +LINK_ENTITY_TO_GAME(pickup_drive_icky); +LINK_ENTITY_TO_GAME(pickup_drive_panth); +LINK_ENTITY_TO_GAME(pickup_drive_slave); +LINK_ENTITY_TO_GAME(pickup_drive_turret); +LINK_ENTITY_TO_GAME(pineapple); +LINK_ENTITY_TO_GAME(pipe_bomb); +LINK_ENTITY_TO_GAME(pipebomb); +LINK_ENTITY_TO_GAME(pitdronespike); +LINK_ENTITY_TO_GAME(pitworm_gib); +LINK_ENTITY_TO_GAME(pitworm_gibshooter); +LINK_ENTITY_TO_GAME(plasma); +LINK_ENTITY_TO_GAME(plasma2); +LINK_ENTITY_TO_GAME(plasma_ball); +LINK_ENTITY_TO_GAME(player); +LINK_ENTITY_TO_GAME(player_beartrapstrip); +LINK_ENTITY_TO_GAME(player_corpse); +LINK_ENTITY_TO_GAME(player_flame); +LINK_ENTITY_TO_GAME(player_freeze); +LINK_ENTITY_TO_GAME(player_giveitems); +LINK_ENTITY_TO_GAME(player_glasses); +LINK_ENTITY_TO_GAME(player_helmet); +LINK_ENTITY_TO_GAME(player_loadsaved); +LINK_ENTITY_TO_GAME(player_respawn_zone); +LINK_ENTITY_TO_GAME(player_roach); +LINK_ENTITY_TO_GAME(player_speaker); +LINK_ENTITY_TO_GAME(player_togglehud); +LINK_ENTITY_TO_GAME(player_weaponship); +LINK_ENTITY_TO_GAME(player_weaponstrip); +LINK_ENTITY_TO_GAME(playerhornet); +LINK_ENTITY_TO_GAME(point_win); +LINK_ENTITY_TO_GAME(poison_injected); +LINK_ENTITY_TO_GAME(potatoc); +LINK_ENTITY_TO_GAME(power_bag); +LINK_ENTITY_TO_GAME(power_ballbag); +LINK_ENTITY_TO_GAME(power_coco); +LINK_ENTITY_TO_GAME(power_gloves); +LINK_ENTITY_TO_GAME(power_pogo); +LINK_ENTITY_TO_GAME(power_shield); +LINK_ENTITY_TO_GAME(power_shoes); +LINK_ENTITY_TO_GAME(powerstruggle); +LINK_ENTITY_TO_GAME(powerup_candy); +LINK_ENTITY_TO_GAME(proj_bird); +LINK_ENTITY_TO_GAME(proj_blaster); +LINK_ENTITY_TO_GAME(proj_bursatchel); +LINK_ENTITY_TO_GAME(proj_cocklebur); +LINK_ENTITY_TO_GAME(proj_comet); +LINK_ENTITY_TO_GAME(proj_doublemagicmissle); +LINK_ENTITY_TO_GAME(proj_dragonfire); +LINK_ENTITY_TO_GAME(proj_earthquakesatchel); +LINK_ENTITY_TO_GAME(proj_fireball); +LINK_ENTITY_TO_GAME(proj_firesatchel); +LINK_ENTITY_TO_GAME(proj_firespiral); +LINK_ENTITY_TO_GAME(proj_fissure); +LINK_ENTITY_TO_GAME(proj_flame); +LINK_ENTITY_TO_GAME(proj_flyingskull); +LINK_ENTITY_TO_GAME(proj_healhurtsatchel); +LINK_ENTITY_TO_GAME(proj_icepoke); +LINK_ENTITY_TO_GAME(proj_iceshard); +LINK_ENTITY_TO_GAME(proj_lightningcloud); +LINK_ENTITY_TO_GAME(proj_lightningsatchel); +LINK_ENTITY_TO_GAME(proj_magicmissle); +LINK_ENTITY_TO_GAME(proj_meteor); +LINK_ENTITY_TO_GAME(proj_mindmissle); +LINK_ENTITY_TO_GAME(proj_missile); +LINK_ENTITY_TO_GAME(proj_poisonsatchel); +LINK_ENTITY_TO_GAME(proj_rollingstone); +LINK_ENTITY_TO_GAME(proj_sporepod); +LINK_ENTITY_TO_GAME(proj_stone); +LINK_ENTITY_TO_GAME(proj_suctionsatchel); +LINK_ENTITY_TO_GAME(proj_tcrystal); +LINK_ENTITY_TO_GAME(proj_throwingbone); +LINK_ENTITY_TO_GAME(proj_toothsatchel); +LINK_ENTITY_TO_GAME(proj_whirlwind); +LINK_ENTITY_TO_GAME(proj_wyvern); +LINK_ENTITY_TO_GAME(promagcurse); +LINK_ENTITY_TO_GAME(pshield_det); +LINK_ENTITY_TO_GAME(pt_bomb_zone); +LINK_ENTITY_TO_GAME(pt_campaign_end); +LINK_ENTITY_TO_GAME(pt_change_attribute); +LINK_ENTITY_TO_GAME(pt_control_area); +LINK_ENTITY_TO_GAME(pt_defeat_victory); +LINK_ENTITY_TO_GAME(pt_entity_reset); +LINK_ENTITY_TO_GAME(pt_hostage); +LINK_ENTITY_TO_GAME(pt_mission_target); +LINK_ENTITY_TO_GAME(pt_model); +LINK_ENTITY_TO_GAME(pt_parachute_area); +LINK_ENTITY_TO_GAME(pt_rescue_zone); +LINK_ENTITY_TO_GAME(pt_round_info); +LINK_ENTITY_TO_GAME(pt_score_award); +LINK_ENTITY_TO_GAME(pt_startpoint); +LINK_ENTITY_TO_GAME(pt_timer); +LINK_ENTITY_TO_GAME(pt_toggle_respawnmode); +LINK_ENTITY_TO_GAME(pt_trigger_bomb); +LINK_ENTITY_TO_GAME(pt_trigger_loader); +LINK_ENTITY_TO_GAME(pt_trigger_zone); +LINK_ENTITY_TO_GAME(pulse); +LINK_ENTITY_TO_GAME(pulsefrag); +LINK_ENTITY_TO_GAME(punch_tripmine); +LINK_ENTITY_TO_GAME(push_point1); +LINK_ENTITY_TO_GAME(push_point2); +LINK_ENTITY_TO_GAME(push_point3); +LINK_ENTITY_TO_GAME(push_point4); +LINK_ENTITY_TO_GAME(push_point5); +LINK_ENTITY_TO_GAME(quake_nail); +LINK_ENTITY_TO_GAME(quake_rocket); +LINK_ENTITY_TO_GAME(race_controller); +LINK_ENTITY_TO_GAME(race_path); +LINK_ENTITY_TO_GAME(rage); +LINK_ENTITY_TO_GAME(rain_modify); +LINK_ENTITY_TO_GAME(rain_settings); +LINK_ENTITY_TO_GAME(random_ammo); +LINK_ENTITY_TO_GAME(random_speaker); +LINK_ENTITY_TO_GAME(random_trigger); +LINK_ENTITY_TO_GAME(random_weapon); +LINK_ENTITY_TO_GAME(redflag_follow); +LINK_ENTITY_TO_GAME(reetou_proj); +LINK_ENTITY_TO_GAME(remove_all_wpts); +LINK_ENTITY_TO_GAME(remove_wpt); +LINK_ENTITY_TO_GAME(resourcetower); +LINK_ENTITY_TO_GAME(respawn_chest); +LINK_ENTITY_TO_GAME(return_axe); +LINK_ENTITY_TO_GAME(reversecurse); +LINK_ENTITY_TO_GAME(rm_rocket); +LINK_ENTITY_TO_GAME(roach_charge); +LINK_ENTITY_TO_GAME(rocket_air_strike); +LINK_ENTITY_TO_GAME(rocket_croix); +LINK_ENTITY_TO_GAME(rocket_mine); +LINK_ENTITY_TO_GAME(rocket_napalm); +LINK_ENTITY_TO_GAME(rocket_phoenix); +LINK_ENTITY_TO_GAME(rocket_pigeon); +LINK_ENTITY_TO_GAME(rocket_snipe); +LINK_ENTITY_TO_GAME(rocketpistol_rocket); +LINK_ENTITY_TO_GAME(rope_sample); +LINK_ENTITY_TO_GAME(rope_segment); +LINK_ENTITY_TO_GAME(rpg7_rocket); +LINK_ENTITY_TO_GAME(rpg_rocket); +LINK_ENTITY_TO_GAME(rr_shell); +LINK_ENTITY_TO_GAME(rrp); +LINK_ENTITY_TO_GAME(rs_effect); +LINK_ENTITY_TO_GAME(rs_fog); +LINK_ENTITY_TO_GAME(rs_grenade); +LINK_ENTITY_TO_GAME(rs_if); +LINK_ENTITY_TO_GAME(rs_message); +LINK_ENTITY_TO_GAME(rs_particle_emitter); +LINK_ENTITY_TO_GAME(rs_roundend); +LINK_ENTITY_TO_GAME(rs_teamslot); +LINK_ENTITY_TO_GAME(rs_timer); +LINK_ENTITY_TO_GAME(rs_val); +LINK_ENTITY_TO_GAME(rs_victorypoints); +LINK_ENTITY_TO_GAME(sams_shower); +LINK_ENTITY_TO_GAME(sanity); +LINK_ENTITY_TO_GAME(satelite_laser); +LINK_ENTITY_TO_GAME(save_wpt); +LINK_ENTITY_TO_GAME(scan); +LINK_ENTITY_TO_GAME(scatterattack); +LINK_ENTITY_TO_GAME(scattersplit); +LINK_ENTITY_TO_GAME(sci_spawner); +LINK_ENTITY_TO_GAME(scientist_mine); +LINK_ENTITY_TO_GAME(scientistbomb); +LINK_ENTITY_TO_GAME(score_multiplier); +LINK_ENTITY_TO_GAME(scoreboard); +LINK_ENTITY_TO_GAME(scripted); +LINK_ENTITY_TO_GAME(scripted_action); +LINK_ENTITY_TO_GAME(scripted_sentence); +LINK_ENTITY_TO_GAME(scripted_sequence); +LINK_ENTITY_TO_GAME(scripted_tanksequence); +LINK_ENTITY_TO_GAME(scripted_trainsequence); +LINK_ENTITY_TO_GAME(sdcurse); +LINK_ENTITY_TO_GAME(secondary_point); +LINK_ENTITY_TO_GAME(securitymanager); +LINK_ENTITY_TO_GAME(sell_ak101); +LINK_ENTITY_TO_GAME(sell_ak47); +LINK_ENTITY_TO_GAME(sell_baretta); +LINK_ENTITY_TO_GAME(sell_beretta); +LINK_ENTITY_TO_GAME(sell_dblshot); +LINK_ENTITY_TO_GAME(sell_dbshot); +LINK_ENTITY_TO_GAME(sell_glock17); +LINK_ENTITY_TO_GAME(sell_longslide); +LINK_ENTITY_TO_GAME(sell_mac); +LINK_ENTITY_TO_GAME(sell_mac10); +LINK_ENTITY_TO_GAME(sell_molotov_cocktail); +LINK_ENTITY_TO_GAME(sell_mossberg); +LINK_ENTITY_TO_GAME(sell_psg1); +LINK_ENTITY_TO_GAME(sell_steyr_m40); +LINK_ENTITY_TO_GAME(sell_tec9); +LINK_ENTITY_TO_GAME(sell_tommy); +LINK_ENTITY_TO_GAME(sell_tommygun); +LINK_ENTITY_TO_GAME(sell_uzi); +LINK_ENTITY_TO_GAME(sensorychamber); +LINK_ENTITY_TO_GAME(sgvortex); +LINK_ENTITY_TO_GAME(shell_bazooka); +LINK_ENTITY_TO_GAME(shell_piat); +LINK_ENTITY_TO_GAME(shell_pschreck); +LINK_ENTITY_TO_GAME(shenlong); +LINK_ENTITY_TO_GAME(shipAI_shipmate); +LINK_ENTITY_TO_GAME(shock); +LINK_ENTITY_TO_GAME(shockH); +LINK_ENTITY_TO_GAME(shock_beam); +LINK_ENTITY_TO_GAME(shockcore); +LINK_ENTITY_TO_GAME(shotgun_crate); +LINK_ENTITY_TO_GAME(shotgun_forklift); +LINK_ENTITY_TO_GAME(shotgun_hev); +LINK_ENTITY_TO_GAME(shotgun_sci); +LINK_ENTITY_TO_GAME(show_wpt); +LINK_ENTITY_TO_GAME(shrapnel); +LINK_ENTITY_TO_GAME(shrink_timer); +LINK_ENTITY_TO_GAME(shrinker_project); +LINK_ENTITY_TO_GAME(siegeturret); +LINK_ENTITY_TO_GAME(skull); +LINK_ENTITY_TO_GAME(skunk_fart); +LINK_ENTITY_TO_GAME(slAGruntTakeCoverFromEnemy); +LINK_ENTITY_TO_GAME(slAGruntThreatDisplay); +LINK_ENTITY_TO_GAME(slAssassinTakeCoverFromBestSound); +LINK_ENTITY_TO_GAME(slAssassinTakeCoverFromEnemy); +LINK_ENTITY_TO_GAME(slAssassinTakeCoverFromEnemy2); +LINK_ENTITY_TO_GAME(slBaFaceTarget); +LINK_ENTITY_TO_GAME(slControllerTakeCover); +LINK_ENTITY_TO_GAME(slFaceTarget); +LINK_ENTITY_TO_GAME(slFaceTargetScared); +LINK_ENTITY_TO_GAME(slGruntTakeCover); +LINK_ENTITY_TO_GAME(slGruntTakeCoverFromBestSound); +LINK_ENTITY_TO_GAME(slGruntTossGrenadeCover); +LINK_ENTITY_TO_GAME(slIdleTrigger); +LINK_ENTITY_TO_GAME(slRunToScript); +LINK_ENTITY_TO_GAME(slTakeCoverFromBestSound); +LINK_ENTITY_TO_GAME(slTakeCoverFromEnemy); +LINK_ENTITY_TO_GAME(slTakeCoverFromOrigin); +LINK_ENTITY_TO_GAME(slTlkIdleEyecontact); +LINK_ENTITY_TO_GAME(slTlkIdleWatchClient); +LINK_ENTITY_TO_GAME(slTwitchDie); +LINK_ENTITY_TO_GAME(slWalkToScript); +LINK_ENTITY_TO_GAME(slowcurse); +LINK_ENTITY_TO_GAME(slowrefirecurse); +LINK_ENTITY_TO_GAME(sm_project); +LINK_ENTITY_TO_GAME(sm_rocket_01); +LINK_ENTITY_TO_GAME(smoking_grenade); +LINK_ENTITY_TO_GAME(snark_cam); +LINK_ENTITY_TO_GAME(snark_project); +LINK_ENTITY_TO_GAME(snowball); +LINK_ENTITY_TO_GAME(soundent); +LINK_ENTITY_TO_GAME(spark_shower); +LINK_ENTITY_TO_GAME(spawn_base_team1); +LINK_ENTITY_TO_GAME(spawn_base_team2); +LINK_ENTITY_TO_GAME(spawn_observer); +LINK_ENTITY_TO_GAME(spawn_player_custom); +LINK_ENTITY_TO_GAME(spawn_player_team1); +LINK_ENTITY_TO_GAME(spawn_player_team2); +LINK_ENTITY_TO_GAME(spawnfar); +LINK_ENTITY_TO_GAME(speaker); +LINK_ENTITY_TO_GAME(spear_bolt); +LINK_ENTITY_TO_GAME(specailbc); +LINK_ENTITY_TO_GAME(special_teleport_in); +LINK_ENTITY_TO_GAME(sphere_explosion); +LINK_ENTITY_TO_GAME(sphere_mine); +LINK_ENTITY_TO_GAME(spirit_bomb); +LINK_ENTITY_TO_GAME(spitgunprojectile); +LINK_ENTITY_TO_GAME(spore); +LINK_ENTITY_TO_GAME(sporegrenade); +LINK_ENTITY_TO_GAME(sporegunprojectile); +LINK_ENTITY_TO_GAME(spy_camera); +LINK_ENTITY_TO_GAME(spy_escape); +LINK_ENTITY_TO_GAME(squadmaker); +LINK_ENTITY_TO_GAME(squidspit); +LINK_ENTITY_TO_GAME(sstrike); +LINK_ENTITY_TO_GAME(st_rocket); +LINK_ENTITY_TO_GAME(streak_spiral); +LINK_ENTITY_TO_GAME(struct_goa); +LINK_ENTITY_TO_GAME(struct_goa_actual); +LINK_ENTITY_TO_GAME(struct_goa_actual_sub); +LINK_ENTITY_TO_GAME(struct_tau); +LINK_ENTITY_TO_GAME(struct_tau_actual); +LINK_ENTITY_TO_GAME(struct_tau_actual_sub); +LINK_ENTITY_TO_GAME(sturmbody); +LINK_ENTITY_TO_GAME(suck_grenade); +LINK_ENTITY_TO_GAME(suck_mine); +LINK_ENTITY_TO_GAME(sunofgod); +LINK_ENTITY_TO_GAME(swarm_garg_stomp); +LINK_ENTITY_TO_GAME(swarm_spawnpt_acontroller); +LINK_ENTITY_TO_GAME(swarm_spawnpt_agarg); +LINK_ENTITY_TO_GAME(swarm_spawnpt_aheadcrab); +LINK_ENTITY_TO_GAME(swarm_spawnpt_aslave); +LINK_ENTITY_TO_GAME(swarm_spawnpt_atripod); +LINK_ENTITY_TO_GAME(swarm_spawnpt_hassassin); +LINK_ENTITY_TO_GAME(swarm_spawnpt_hcommander); +LINK_ENTITY_TO_GAME(swarm_spawnpt_hengineer); +LINK_ENTITY_TO_GAME(swarm_spawnpt_hgrunt); +LINK_ENTITY_TO_GAME(swarm_spawnpt_hscientist); +LINK_ENTITY_TO_GAME(swarm_spawnpt_human); +LINK_ENTITY_TO_GAME(swarm_team_alien); +LINK_ENTITY_TO_GAME(swarm_team_human); +LINK_ENTITY_TO_GAME(tag_camp); +LINK_ENTITY_TO_GAME(tag_crouch_jump); +LINK_ENTITY_TO_GAME(tag_door); +LINK_ENTITY_TO_GAME(tag_duck); +LINK_ENTITY_TO_GAME(tag_jump); +LINK_ENTITY_TO_GAME(tag_run); +LINK_ENTITY_TO_GAME(tag_snipe); +LINK_ENTITY_TO_GAME(tag_walk); +LINK_ENTITY_TO_GAME(tango_nomad); +LINK_ENTITY_TO_GAME(tango_sentinel); +LINK_ENTITY_TO_GAME(tango_sniper); +LINK_ENTITY_TO_GAME(targ_speaker); +LINK_ENTITY_TO_GAME(target_all_players); +LINK_ENTITY_TO_GAME(target_animation); +LINK_ENTITY_TO_GAME(target_cdaudio); +LINK_ENTITY_TO_GAME(target_changemaster); +LINK_ENTITY_TO_GAME(target_changetarget); +LINK_ENTITY_TO_GAME(target_give); +LINK_ENTITY_TO_GAME(target_gravity); +LINK_ENTITY_TO_GAME(target_help); +LINK_ENTITY_TO_GAME(target_hurt); +LINK_ENTITY_TO_GAME(target_kill); +LINK_ENTITY_TO_GAME(target_mp3audio); +LINK_ENTITY_TO_GAME(target_print); +LINK_ENTITY_TO_GAME(target_push); +LINK_ENTITY_TO_GAME(target_random); +LINK_ENTITY_TO_GAME(target_random_player); +LINK_ENTITY_TO_GAME(target_relay); +LINK_ENTITY_TO_GAME(target_removeobject); +LINK_ENTITY_TO_GAME(target_reset); +LINK_ENTITY_TO_GAME(target_respawn); +LINK_ENTITY_TO_GAME(target_score); +LINK_ENTITY_TO_GAME(target_server_command); +LINK_ENTITY_TO_GAME(target_set_cvar); +LINK_ENTITY_TO_GAME(target_spawnitem); +LINK_ENTITY_TO_GAME(target_spectate); +LINK_ENTITY_TO_GAME(target_team); +LINK_ENTITY_TO_GAME(target_team_score); +LINK_ENTITY_TO_GAME(target_teamdie); +LINK_ENTITY_TO_GAME(target_teleport); +LINK_ENTITY_TO_GAME(target_tripmine); +LINK_ENTITY_TO_GAME(target_weaponstrip); +LINK_ENTITY_TO_GAME(target_win); +LINK_ENTITY_TO_GAME(tcontroller_cball); +LINK_ENTITY_TO_GAME(tcontroller_tball); +LINK_ENTITY_TO_GAME(team_advarmory); +LINK_ENTITY_TO_GAME(team_advturretfactory); +LINK_ENTITY_TO_GAME(team_armory); +LINK_ENTITY_TO_GAME(team_armslab); +LINK_ENTITY_TO_GAME(team_chemlab); +LINK_ENTITY_TO_GAME(team_command); +LINK_ENTITY_TO_GAME(team_goal); +LINK_ENTITY_TO_GAME(team_hive); +LINK_ENTITY_TO_GAME(team_infportal); +LINK_ENTITY_TO_GAME(team_medlab); +LINK_ENTITY_TO_GAME(team_nukeplant); +LINK_ENTITY_TO_GAME(team_observatory); +LINK_ENTITY_TO_GAME(team_prototypelab); +LINK_ENTITY_TO_GAME(team_turretfactory); +LINK_ENTITY_TO_GAME(team_webstrand); +LINK_ENTITY_TO_GAME(telebecon); +LINK_ENTITY_TO_GAME(teledeath); +LINK_ENTITY_TO_GAME(teleenter); +LINK_ENTITY_TO_GAME(temp_eject); +LINK_ENTITY_TO_GAME(teslagren); +LINK_ENTITY_TO_GAME(test_effect); +LINK_ENTITY_TO_GAME(testhull); +LINK_ENTITY_TO_GAME(testparticles); +LINK_ENTITY_TO_GAME(tf_ammo_rpgclip); +LINK_ENTITY_TO_GAME(tf_flame); +LINK_ENTITY_TO_GAME(tf_flamethrower_burst); +LINK_ENTITY_TO_GAME(tf_gl_grenade); +LINK_ENTITY_TO_GAME(tf_ic_rocket); +LINK_ENTITY_TO_GAME(tf_nailgun_nail); +LINK_ENTITY_TO_GAME(tf_rpg_rocket); +LINK_ENTITY_TO_GAME(tf_weapon_ac); +LINK_ENTITY_TO_GAME(tf_weapon_autorifle); +LINK_ENTITY_TO_GAME(tf_weapon_axe); +LINK_ENTITY_TO_GAME(tf_weapon_caltrop); +LINK_ENTITY_TO_GAME(tf_weapon_caltropgrenade); +LINK_ENTITY_TO_GAME(tf_weapon_concussiongrenade); +LINK_ENTITY_TO_GAME(tf_weapon_empgrenade); +LINK_ENTITY_TO_GAME(tf_weapon_flamethrower); +LINK_ENTITY_TO_GAME(tf_weapon_gasgrenade); +LINK_ENTITY_TO_GAME(tf_weapon_genericprimedgrenade); +LINK_ENTITY_TO_GAME(tf_weapon_gl); +LINK_ENTITY_TO_GAME(tf_weapon_ic); +LINK_ENTITY_TO_GAME(tf_weapon_knife); +LINK_ENTITY_TO_GAME(tf_weapon_medikit); +LINK_ENTITY_TO_GAME(tf_weapon_mirvbomblet); +LINK_ENTITY_TO_GAME(tf_weapon_mirvgrenade); +LINK_ENTITY_TO_GAME(tf_weapon_nailgrenade); +LINK_ENTITY_TO_GAME(tf_weapon_napalmgrenade); +LINK_ENTITY_TO_GAME(tf_weapon_ng); +LINK_ENTITY_TO_GAME(tf_weapon_normalgrenade); +LINK_ENTITY_TO_GAME(tf_weapon_pl); +LINK_ENTITY_TO_GAME(tf_weapon_railgun); +LINK_ENTITY_TO_GAME(tf_weapon_rpg); +LINK_ENTITY_TO_GAME(tf_weapon_shotgun); +LINK_ENTITY_TO_GAME(tf_weapon_sniperrifle); +LINK_ENTITY_TO_GAME(tf_weapon_spanner); +LINK_ENTITY_TO_GAME(tf_weapon_superng); +LINK_ENTITY_TO_GAME(tf_weapon_supershotgun); +LINK_ENTITY_TO_GAME(tf_weapon_tranq); +LINK_ENTITY_TO_GAME(tgrenade); +LINK_ENTITY_TO_GAME(thornbush); +LINK_ENTITY_TO_GAME(throwing_knife); +LINK_ENTITY_TO_GAME(thrown_katana); +LINK_ENTITY_TO_GAME(thrown_knife); +LINK_ENTITY_TO_GAME(thrown_object); +LINK_ENTITY_TO_GAME(thrown_sledge); +LINK_ENTITY_TO_GAME(timed_grenade); +LINK_ENTITY_TO_GAME(timedevent); +LINK_ENTITY_TO_GAME(timer); +LINK_ENTITY_TO_GAME(timer_add); +LINK_ENTITY_TO_GAME(tlAGruntTakeCoverFromEnemy); +LINK_ENTITY_TO_GAME(tlAGruntThreatDisplay); +LINK_ENTITY_TO_GAME(tlAssassinTakeCoverFromBestSound); +LINK_ENTITY_TO_GAME(tlAssassinTakeCoverFromEnemy); +LINK_ENTITY_TO_GAME(tlAssassinTakeCoverFromEnemy2); +LINK_ENTITY_TO_GAME(tlBaFaceTarget); +LINK_ENTITY_TO_GAME(tlControllerTakeCover); +LINK_ENTITY_TO_GAME(tlFaceTarget); +LINK_ENTITY_TO_GAME(tlFaceTargetScared); +LINK_ENTITY_TO_GAME(tlGruntTakeCover1); +LINK_ENTITY_TO_GAME(tlGruntTakeCoverFromBestSound); +LINK_ENTITY_TO_GAME(tlGruntTossGrenadeCover1); +LINK_ENTITY_TO_GAME(tlTakeCoverFromBestSound); +LINK_ENTITY_TO_GAME(tlTakeCoverFromEnemy); +LINK_ENTITY_TO_GAME(tlTakeCoverFromOrigin); +LINK_ENTITY_TO_GAME(tlTlkIdleEyecontact); +LINK_ENTITY_TO_GAME(tlTlkIdleWatchClient); +LINK_ENTITY_TO_GAME(tlTlkIdleWatchClientStare); +LINK_ENTITY_TO_GAME(tlTwitchDie); +LINK_ENTITY_TO_GAME(tod_control_area); +LINK_ENTITY_TO_GAME(tod_control_point); +LINK_ENTITY_TO_GAME(tod_notripmine_area); +LINK_ENTITY_TO_GAME(tod_roundend_trigger); +LINK_ENTITY_TO_GAME(tod_roundstart_trigger); +LINK_ENTITY_TO_GAME(tod_roundwon_trigger); +LINK_ENTITY_TO_GAME(tombstone); +LINK_ENTITY_TO_GAME(translocator_disc); +LINK_ENTITY_TO_GAME(transphasic_gib); +LINK_ENTITY_TO_GAME(transport_apc); +LINK_ENTITY_TO_GAME(transport_blackhawk); +LINK_ENTITY_TO_GAME(treasure_chest); +LINK_ENTITY_TO_GAME(trenches_allied_start); +LINK_ENTITY_TO_GAME(trenches_axis_start); +LINK_ENTITY_TO_GAME(trenches_central_start); +LINK_ENTITY_TO_GAME(trigger); +LINK_ENTITY_TO_GAME(trigger_GoalLine); +LINK_ENTITY_TO_GAME(trigger_PenaltyBox); +LINK_ENTITY_TO_GAME(trigger_SideLine); +LINK_ENTITY_TO_GAME(trigger_adv_teleport); +LINK_ENTITY_TO_GAME(trigger_armory); +LINK_ENTITY_TO_GAME(trigger_assault); +LINK_ENTITY_TO_GAME(trigger_auto); +LINK_ENTITY_TO_GAME(trigger_autosave); +LINK_ENTITY_TO_GAME(trigger_ball); +LINK_ENTITY_TO_GAME(trigger_baril); +LINK_ENTITY_TO_GAME(trigger_bounce); +LINK_ENTITY_TO_GAME(trigger_camera); +LINK_ENTITY_TO_GAME(trigger_capturetimer); +LINK_ENTITY_TO_GAME(trigger_captureupdate); +LINK_ENTITY_TO_GAME(trigger_cdaudio); +LINK_ENTITY_TO_GAME(trigger_changealias); +LINK_ENTITY_TO_GAME(trigger_changecvar); +LINK_ENTITY_TO_GAME(trigger_changelevel); +LINK_ENTITY_TO_GAME(trigger_changetarget); +LINK_ENTITY_TO_GAME(trigger_changevalue); +LINK_ENTITY_TO_GAME(trigger_coldbreath); +LINK_ENTITY_TO_GAME(trigger_comet); +LINK_ENTITY_TO_GAME(trigger_command); +LINK_ENTITY_TO_GAME(trigger_control); +LINK_ENTITY_TO_GAME(trigger_coop); +LINK_ENTITY_TO_GAME(trigger_counter); +LINK_ENTITY_TO_GAME(trigger_course); +LINK_ENTITY_TO_GAME(trigger_crash); +LINK_ENTITY_TO_GAME(trigger_ctf); +LINK_ENTITY_TO_GAME(trigger_ctfgeneric); +LINK_ENTITY_TO_GAME(trigger_deathmatch); +LINK_ENTITY_TO_GAME(trigger_deliveryzone); +LINK_ENTITY_TO_GAME(trigger_die); +LINK_ENTITY_TO_GAME(trigger_discerturn); +LINK_ENTITY_TO_GAME(trigger_discreturn); +LINK_ENTITY_TO_GAME(trigger_endround); +LINK_ENTITY_TO_GAME(trigger_endsection); +LINK_ENTITY_TO_GAME(trigger_env_hurt); +LINK_ENTITY_TO_GAME(trigger_execcommand); +LINK_ENTITY_TO_GAME(trigger_fall); +LINK_ENTITY_TO_GAME(trigger_flagcheck); +LINK_ENTITY_TO_GAME(trigger_geneworm_hit); +LINK_ENTITY_TO_GAME(trigger_goal); +LINK_ENTITY_TO_GAME(trigger_golem); +LINK_ENTITY_TO_GAME(trigger_gravity); +LINK_ENTITY_TO_GAME(trigger_gunmanteleport); +LINK_ENTITY_TO_GAME(trigger_hevcharge); +LINK_ENTITY_TO_GAME(trigger_hold); +LINK_ENTITY_TO_GAME(trigger_hurt); +LINK_ENTITY_TO_GAME(trigger_hurt_bleu); +LINK_ENTITY_TO_GAME(trigger_hurt_rouge); +LINK_ENTITY_TO_GAME(trigger_inout); +LINK_ENTITY_TO_GAME(trigger_jail); +LINK_ENTITY_TO_GAME(trigger_jail_release); +LINK_ENTITY_TO_GAME(trigger_jetpack); +LINK_ENTITY_TO_GAME(trigger_jump); +LINK_ENTITY_TO_GAME(trigger_jumppad); +LINK_ENTITY_TO_GAME(trigger_katehealth); +LINK_ENTITY_TO_GAME(trigger_kill_nogib); +LINK_ENTITY_TO_GAME(trigger_killmonster); +LINK_ENTITY_TO_GAME(trigger_lightstyle); +LINK_ENTITY_TO_GAME(trigger_loadhazard); +LINK_ENTITY_TO_GAME(trigger_mine); +LINK_ENTITY_TO_GAME(trigger_monsterjump); +LINK_ENTITY_TO_GAME(trigger_motion); +LINK_ENTITY_TO_GAME(trigger_multiple); +LINK_ENTITY_TO_GAME(trigger_music); +LINK_ENTITY_TO_GAME(trigger_noclaymores); +LINK_ENTITY_TO_GAME(trigger_npcarea); +LINK_ENTITY_TO_GAME(trigger_objectcapture); +LINK_ENTITY_TO_GAME(trigger_once); +LINK_ENTITY_TO_GAME(trigger_once_round); +LINK_ENTITY_TO_GAME(trigger_onsight); +LINK_ENTITY_TO_GAME(trigger_particles); +LINK_ENTITY_TO_GAME(trigger_playerfreeze); +LINK_ENTITY_TO_GAME(trigger_point_controle); +LINK_ENTITY_TO_GAME(trigger_presence); +LINK_ENTITY_TO_GAME(trigger_push); +LINK_ENTITY_TO_GAME(trigger_random); +LINK_ENTITY_TO_GAME(trigger_random_group); +LINK_ENTITY_TO_GAME(trigger_random_time); +LINK_ENTITY_TO_GAME(trigger_random_unique); +LINK_ENTITY_TO_GAME(trigger_regen); +LINK_ENTITY_TO_GAME(trigger_reinforcements); +LINK_ENTITY_TO_GAME(trigger_relay); +LINK_ENTITY_TO_GAME(trigger_respawn); +LINK_ENTITY_TO_GAME(trigger_rndbased); +LINK_ENTITY_TO_GAME(trigger_rottest); +LINK_ENTITY_TO_GAME(trigger_rs_hurt); +LINK_ENTITY_TO_GAME(trigger_script); +LINK_ENTITY_TO_GAME(trigger_secret); +LINK_ENTITY_TO_GAME(trigger_section); +LINK_ENTITY_TO_GAME(trigger_setflag); +LINK_ENTITY_TO_GAME(trigger_setorigin); +LINK_ENTITY_TO_GAME(trigger_shutup); +LINK_ENTITY_TO_GAME(trigger_sound); +LINK_ENTITY_TO_GAME(trigger_speed); +LINK_ENTITY_TO_GAME(trigger_sponly); +LINK_ENTITY_TO_GAME(trigger_startpatrol); +LINK_ENTITY_TO_GAME(trigger_teampush); +LINK_ENTITY_TO_GAME(trigger_teleport); +LINK_ENTITY_TO_GAME(trigger_transition); +LINK_ENTITY_TO_GAME(trigger_war); +LINK_ENTITY_TO_GAME(trigger_xen_return); +LINK_ENTITY_TO_GAME(trigger_zone); +LINK_ENTITY_TO_GAME(trigger_zone_bleu); +LINK_ENTITY_TO_GAME(trigger_zone_rouge); +LINK_ENTITY_TO_GAME(trip_beam); +LINK_ENTITY_TO_GAME(ts_bomb); +LINK_ENTITY_TO_GAME(ts_dmhill); +LINK_ENTITY_TO_GAME(ts_groundweapon); +LINK_ENTITY_TO_GAME(ts_hack); +LINK_ENTITY_TO_GAME(ts_mapglobals); +LINK_ENTITY_TO_GAME(ts_model); +LINK_ENTITY_TO_GAME(ts_objective_manager); +LINK_ENTITY_TO_GAME(ts_objective_ptr); +LINK_ENTITY_TO_GAME(ts_powerup); +LINK_ENTITY_TO_GAME(ts_slowmotion); +LINK_ENTITY_TO_GAME(ts_slowmotionpoint); +LINK_ENTITY_TO_GAME(ts_teamescape); +LINK_ENTITY_TO_GAME(ts_trigger); +LINK_ENTITY_TO_GAME(ts_vipescape); +LINK_ENTITY_TO_GAME(ts_wingiver); +LINK_ENTITY_TO_GAME(turf_zone); +LINK_ENTITY_TO_GAME(turret); +LINK_ENTITY_TO_GAME(ultima_grenade); +LINK_ENTITY_TO_GAME(umbracloud); +LINK_ENTITY_TO_GAME(umbraprojectile); +LINK_ENTITY_TO_GAME(uw_monster_hybrid); +LINK_ENTITY_TO_GAME(uw_monster_michael); +LINK_ENTITY_TO_GAME(uw_player_lycan); +LINK_ENTITY_TO_GAME(uw_player_vamp); +LINK_ENTITY_TO_GAME(uw_player_view); +LINK_ENTITY_TO_GAME(vehicle); +LINK_ENTITY_TO_GAME(vehicle_dreadnaught); +LINK_ENTITY_TO_GAME(vehicle_dreadnaught_weapon); +LINK_ENTITY_TO_GAME(vehicle_tank); +LINK_ENTITY_TO_GAME(vehicle_thing); +LINK_ENTITY_TO_GAME(vehicle_wraithlord); +LINK_ENTITY_TO_GAME(vehicle_wraithlord_weapon); +LINK_ENTITY_TO_GAME(victim_scientist); +LINK_ENTITY_TO_GAME(vipescape); +LINK_ENTITY_TO_GAME(virtual_hull); +LINK_ENTITY_TO_GAME(voltigoreshock); +LINK_ENTITY_TO_GAME(vote_llama); +LINK_ENTITY_TO_GAME(vscrossbow_bolt); +LINK_ENTITY_TO_GAME(watcher); +LINK_ENTITY_TO_GAME(watcher_count); +LINK_ENTITY_TO_GAME(weapmortar); +LINK_ENTITY_TO_GAME(weapon_1100); +LINK_ENTITY_TO_GAME(weapon_1445lda); +LINK_ENTITY_TO_GAME(weapon_1911); +LINK_ENTITY_TO_GAME(weapon_30cal); +LINK_ENTITY_TO_GAME(weapon_30mmsg); +LINK_ENTITY_TO_GAME(weapon_357); +LINK_ENTITY_TO_GAME(weapon_40gl); +LINK_ENTITY_TO_GAME(weapon_44sw); +LINK_ENTITY_TO_GAME(weapon_50cal); +LINK_ENTITY_TO_GAME(weapon_556AR); +LINK_ENTITY_TO_GAME(weapon_90mm); +LINK_ENTITY_TO_GAME(weapon_92d); +LINK_ENTITY_TO_GAME(weapon_9mmAR); +LINK_ENTITY_TO_GAME(weapon_9mmhandgun); +LINK_ENTITY_TO_GAME(weapon_9mmm41a); +LINK_ENTITY_TO_GAME(weapon_BritGrenMelee); +LINK_ENTITY_TO_GAME(weapon_BritGrenNade); +LINK_ENTITY_TO_GAME(weapon_BrownBess); +LINK_ENTITY_TO_GAME(weapon_CEnfield); +LINK_ENTITY_TO_GAME(weapon_CEnfieldMelee); +LINK_ENTITY_TO_GAME(weapon_CEnfieldNade); +LINK_ENTITY_TO_GAME(weapon_Charleville); +LINK_ENTITY_TO_GAME(weapon_FT); +LINK_ENTITY_TO_GAME(weapon_G11); +LINK_ENTITY_TO_GAME(weapon_GMauserG98); +LINK_ENTITY_TO_GAME(weapon_GMauserG98Melee); +LINK_ENTITY_TO_GAME(weapon_GMauserG98Nade); +LINK_ENTITY_TO_GAME(weapon_GermGrenMelee); +LINK_ENTITY_TO_GAME(weapon_GermGrenNade); +LINK_ENTITY_TO_GAME(weapon_Knife); +LINK_ENTITY_TO_GAME(weapon_Pennsylvania); +LINK_ENTITY_TO_GAME(weapon_PistolA); +LINK_ENTITY_TO_GAME(weapon_PistolB); +LINK_ENTITY_TO_GAME(weapon_Revolutionnaire); +LINK_ENTITY_TO_GAME(weapon_SPchemicalgun); +LINK_ENTITY_TO_GAME(weapon_Sabre); +LINK_ENTITY_TO_GAME(weapon_a5); +LINK_ENTITY_TO_GAME(weapon_aandagger); +LINK_ENTITY_TO_GAME(weapon_acannon); +LINK_ENTITY_TO_GAME(weapon_acidrocket); +LINK_ENTITY_TO_GAME(weapon_acidrocketgun); +LINK_ENTITY_TO_GAME(weapon_adrenaline); +LINK_ENTITY_TO_GAME(weapon_aicore); +LINK_ENTITY_TO_GAME(weapon_air_strike); +LINK_ENTITY_TO_GAME(weapon_ak); +LINK_ENTITY_TO_GAME(weapon_ak101); +LINK_ENTITY_TO_GAME(weapon_ak47); +LINK_ENTITY_TO_GAME(weapon_ak5); +LINK_ENTITY_TO_GAME(weapon_ak5s); +LINK_ENTITY_TO_GAME(weapon_ak74); +LINK_ENTITY_TO_GAME(weapon_akimbo_glocks); +LINK_ENTITY_TO_GAME(weapon_akimbob); +LINK_ENTITY_TO_GAME(weapon_akimboberettas); +LINK_ENTITY_TO_GAME(weapon_akimbocolts); +LINK_ENTITY_TO_GAME(weapon_akimbodeagles); +LINK_ENTITY_TO_GAME(weapon_akimbogun); +LINK_ENTITY_TO_GAME(weapon_akimbosawedoffs); +LINK_ENTITY_TO_GAME(weapon_akimcolt); +LINK_ENTITY_TO_GAME(weapon_akimsaa); +LINK_ENTITY_TO_GAME(weapon_aks74u); +LINK_ENTITY_TO_GAME(weapon_alarm); +LINK_ENTITY_TO_GAME(weapon_aliencannon); +LINK_ENTITY_TO_GAME(weapon_amerknife); +LINK_ENTITY_TO_GAME(weapon_ammo); +LINK_ENTITY_TO_GAME(weapon_amp); +LINK_ENTITY_TO_GAME(weapon_anaconda); +LINK_ENTITY_TO_GAME(weapon_angel); +LINK_ENTITY_TO_GAME(weapon_ar10); +LINK_ENTITY_TO_GAME(weapon_ar33); +LINK_ENTITY_TO_GAME(weapon_assaultminigun); +LINK_ENTITY_TO_GAME(weapon_aug); +LINK_ENTITY_TO_GAME(weapon_autococker); +LINK_ENTITY_TO_GAME(weapon_autogl); +LINK_ENTITY_TO_GAME(weapon_automag); +LINK_ENTITY_TO_GAME(weapon_autoshotgun); +LINK_ENTITY_TO_GAME(weapon_awm); +LINK_ENTITY_TO_GAME(weapon_awp); +LINK_ENTITY_TO_GAME(weapon_axe); +LINK_ENTITY_TO_GAME(weapon_axes); +LINK_ENTITY_TO_GAME(weapon_b93r); +LINK_ENTITY_TO_GAME(weapon_babblergun); +LINK_ENTITY_TO_GAME(weapon_babblerprojectile); +LINK_ENTITY_TO_GAME(weapon_balllightningspell); +LINK_ENTITY_TO_GAME(weapon_banana); +LINK_ENTITY_TO_GAME(weapon_banane); +LINK_ENTITY_TO_GAME(weapon_bandage); +LINK_ENTITY_TO_GAME(weapon_bandsaw); +LINK_ENTITY_TO_GAME(weapon_bang); +LINK_ENTITY_TO_GAME(weapon_bar); +LINK_ENTITY_TO_GAME(weapon_barett); +LINK_ENTITY_TO_GAME(weapon_baretta); +LINK_ENTITY_TO_GAME(weapon_barnacle); +LINK_ENTITY_TO_GAME(weapon_barney9mmar); +LINK_ENTITY_TO_GAME(weapon_barney9mmhg); +LINK_ENTITY_TO_GAME(weapon_barneyhandgrenade); +LINK_ENTITY_TO_GAME(weapon_barneyshotgun); +LINK_ENTITY_TO_GAME(weapon_barrett82); +LINK_ENTITY_TO_GAME(weapon_baseballbat); +LINK_ENTITY_TO_GAME(weapon_bat); +LINK_ENTITY_TO_GAME(weapon_baton); +LINK_ENTITY_TO_GAME(weapon_batsup); +LINK_ENTITY_TO_GAME(weapon_batte); +LINK_ENTITY_TO_GAME(weapon_battleaxe); +LINK_ENTITY_TO_GAME(weapon_bayonet); +LINK_ENTITY_TO_GAME(weapon_bazooka); +LINK_ENTITY_TO_GAME(weapon_beamgun); +LINK_ENTITY_TO_GAME(weapon_beanstalkspell); +LINK_ENTITY_TO_GAME(weapon_bearbite); +LINK_ENTITY_TO_GAME(weapon_bearclaw); +LINK_ENTITY_TO_GAME(weapon_beartrap); +LINK_ENTITY_TO_GAME(weapon_benelli); +LINK_ENTITY_TO_GAME(weapon_ber92f); +LINK_ENTITY_TO_GAME(weapon_ber92fs); +LINK_ENTITY_TO_GAME(weapon_ber93r); +LINK_ENTITY_TO_GAME(weapon_beretta); +LINK_ENTITY_TO_GAME(weapon_beretta_a); +LINK_ENTITY_TO_GAME(weapon_bfg); +LINK_ENTITY_TO_GAME(weapon_bigaxe); +LINK_ENTITY_TO_GAME(weapon_bigbang); +LINK_ENTITY_TO_GAME(weapon_biggun); +LINK_ENTITY_TO_GAME(weapon_bilebomb); +LINK_ENTITY_TO_GAME(weapon_bilebombgun); +LINK_ENTITY_TO_GAME(weapon_binoculars); +LINK_ENTITY_TO_GAME(weapon_binos); +LINK_ENTITY_TO_GAME(weapon_birdspell); +LINK_ENTITY_TO_GAME(weapon_bite2gun); +LINK_ENTITY_TO_GAME(weapon_bitegun); +LINK_ENTITY_TO_GAME(weapon_bizon); +LINK_ENTITY_TO_GAME(weapon_blaster); +LINK_ENTITY_TO_GAME(weapon_blazer); +LINK_ENTITY_TO_GAME(weapon_blink); +LINK_ENTITY_TO_GAME(weapon_blowpipe); +LINK_ENTITY_TO_GAME(weapon_bodypart); +LINK_ENTITY_TO_GAME(weapon_bola); +LINK_ENTITY_TO_GAME(weapon_boltrifle); +LINK_ENTITY_TO_GAME(weapon_bomb); +LINK_ENTITY_TO_GAME(weapon_bomber); +LINK_ENTITY_TO_GAME(weapon_bow); +LINK_ENTITY_TO_GAME(weapon_bren); +LINK_ENTITY_TO_GAME(weapon_brickcannon); +LINK_ENTITY_TO_GAME(weapon_briefcase); +LINK_ENTITY_TO_GAME(weapon_bsword); +LINK_ENTITY_TO_GAME(weapon_buffalo); +LINK_ENTITY_TO_GAME(weapon_burningattack); +LINK_ENTITY_TO_GAME(weapon_bush); +LINK_ENTITY_TO_GAME(weapon_bushmaster); +LINK_ENTITY_TO_GAME(weapon_c4); +LINK_ENTITY_TO_GAME(weapon_cal50); +LINK_ENTITY_TO_GAME(weapon_camera); +LINK_ENTITY_TO_GAME(weapon_candy); +LINK_ENTITY_TO_GAME(weapon_canister); +LINK_ENTITY_TO_GAME(weapon_cannon); +LINK_ENTITY_TO_GAME(weapon_case); +LINK_ENTITY_TO_GAME(weapon_cat); +LINK_ENTITY_TO_GAME(weapon_cattleprod); +LINK_ENTITY_TO_GAME(weapon_caws); +LINK_ENTITY_TO_GAME(weapon_ce_lasgun); +LINK_ENTITY_TO_GAME(weapon_ce_powersword); +LINK_ENTITY_TO_GAME(weapon_ce_psistaff); +LINK_ENTITY_TO_GAME(weapon_ce_rocketlauncher); +LINK_ENTITY_TO_GAME(weapon_ce_shurikencatapult); +LINK_ENTITY_TO_GAME(weapon_ce_shurikenpistol); +LINK_ENTITY_TO_GAME(weapon_cellphone); +LINK_ENTITY_TO_GAME(weapon_chaingun); +LINK_ENTITY_TO_GAME(weapon_chainsaw); +LINK_ENTITY_TO_GAME(weapon_charge); +LINK_ENTITY_TO_GAME(weapon_charged); +LINK_ENTITY_TO_GAME(weapon_chronosceptor); +LINK_ENTITY_TO_GAME(weapon_claw); +LINK_ENTITY_TO_GAME(weapon_claws); +LINK_ENTITY_TO_GAME(weapon_claymore); +LINK_ENTITY_TO_GAME(weapon_clip_generic); +LINK_ENTITY_TO_GAME(weapon_cloak); +LINK_ENTITY_TO_GAME(weapon_cloaker); +LINK_ENTITY_TO_GAME(weapon_cluster); +LINK_ENTITY_TO_GAME(weapon_cm_autocannon); +LINK_ENTITY_TO_GAME(weapon_cm_bolter); +LINK_ENTITY_TO_GAME(weapon_cm_bolterflamer); +LINK_ENTITY_TO_GAME(weapon_cm_boltpistol); +LINK_ENTITY_TO_GAME(weapon_cm_chainaxe); +LINK_ENTITY_TO_GAME(weapon_cm_chainsword); +LINK_ENTITY_TO_GAME(weapon_cm_flamer); +LINK_ENTITY_TO_GAME(weapon_cm_fraggrenade); +LINK_ENTITY_TO_GAME(weapon_cm_heavybolter); +LINK_ENTITY_TO_GAME(weapon_cm_lascannon); +LINK_ENTITY_TO_GAME(weapon_cm_missilelauncher); +LINK_ENTITY_TO_GAME(weapon_cm_stormbolter); +LINK_ENTITY_TO_GAME(weapon_cocker); +LINK_ENTITY_TO_GAME(weapon_cocogrenade); +LINK_ENTITY_TO_GAME(weapon_cocolauncher); +LINK_ENTITY_TO_GAME(weapon_colt); +LINK_ENTITY_TO_GAME(weapon_colt45); +LINK_ENTITY_TO_GAME(weapon_coltgov); +LINK_ENTITY_TO_GAME(weapon_colts); +LINK_ENTITY_TO_GAME(weapon_combatknife); +LINK_ENTITY_TO_GAME(weapon_combospell); +LINK_ENTITY_TO_GAME(weapon_cometspell); +LINK_ENTITY_TO_GAME(weapon_concussion); +LINK_ENTITY_TO_GAME(weapon_controlled); +LINK_ENTITY_TO_GAME(weapon_cougar); +LINK_ENTITY_TO_GAME(weapon_coujaf); +LINK_ENTITY_TO_GAME(weapon_couteau); +LINK_ENTITY_TO_GAME(weapon_croix); +LINK_ENTITY_TO_GAME(weapon_crossbow); +LINK_ENTITY_TO_GAME(weapon_crowbar); +LINK_ENTITY_TO_GAME(weapon_crowbar_electric); +LINK_ENTITY_TO_GAME(weapon_cutlass); +LINK_ENTITY_TO_GAME(weapon_cz75); +LINK_ENTITY_TO_GAME(weapon_d5k); +LINK_ENTITY_TO_GAME(weapon_dagger); +LINK_ENTITY_TO_GAME(weapon_daystick); +LINK_ENTITY_TO_GAME(weapon_dblpistolet); +LINK_ENTITY_TO_GAME(weapon_dblshot); +LINK_ENTITY_TO_GAME(weapon_dbshot); +LINK_ENTITY_TO_GAME(weapon_dd44); +LINK_ENTITY_TO_GAME(weapon_de50); +LINK_ENTITY_TO_GAME(weapon_deagle); +LINK_ENTITY_TO_GAME(weapon_deathball); +LINK_ENTITY_TO_GAME(weapon_deathrayspell); +LINK_ENTITY_TO_GAME(weapon_demo); +LINK_ENTITY_TO_GAME(weapon_deploygun); +LINK_ENTITY_TO_GAME(weapon_desert); +LINK_ENTITY_TO_GAME(weapon_deserteagle); +LINK_ENTITY_TO_GAME(weapon_destructodisc); +LINK_ENTITY_TO_GAME(weapon_devastator); +LINK_ENTITY_TO_GAME(weapon_devour); +LINK_ENTITY_TO_GAME(weapon_disc); +LINK_ENTITY_TO_GAME(weapon_disclauncher); +LINK_ENTITY_TO_GAME(weapon_discoballs); +LINK_ENTITY_TO_GAME(weapon_disintegrator); +LINK_ENTITY_TO_GAME(weapon_displacer); +LINK_ENTITY_TO_GAME(weapon_divinewind); +LINK_ENTITY_TO_GAME(weapon_dm4); +LINK_ENTITY_TO_GAME(weapon_dml); +LINK_ENTITY_TO_GAME(weapon_double); +LINK_ENTITY_TO_GAME(weapon_doublemagicmisslespell); +LINK_ENTITY_TO_GAME(weapon_doubleshotgun); +LINK_ENTITY_TO_GAME(weapon_dragonball); +LINK_ENTITY_TO_GAME(weapon_dragonbreathspell); +LINK_ENTITY_TO_GAME(weapon_dragonspell); +LINK_ENTITY_TO_GAME(weapon_dragunov); +LINK_ENTITY_TO_GAME(weapon_dsr1); +LINK_ENTITY_TO_GAME(weapon_dualberettas); +LINK_ENTITY_TO_GAME(weapon_dualscorpion); +LINK_ENTITY_TO_GAME(weapon_dummy); +LINK_ENTITY_TO_GAME(weapon_dynamite); +LINK_ENTITY_TO_GAME(weapon_dynomite); +LINK_ENTITY_TO_GAME(weapon_eagle); +LINK_ENTITY_TO_GAME(weapon_eballblaster); +LINK_ENTITY_TO_GAME(weapon_egon); +LINK_ENTITY_TO_GAME(weapon_el_standard); +LINK_ENTITY_TO_GAME(weapon_electro); +LINK_ENTITY_TO_GAME(weapon_elite); +LINK_ENTITY_TO_GAME(weapon_emag); +LINK_ENTITY_TO_GAME(weapon_empcannon); +LINK_ENTITY_TO_GAME(weapon_emsniper); +LINK_ENTITY_TO_GAME(weapon_energy); +LINK_ENTITY_TO_GAME(weapon_enfield); +LINK_ENTITY_TO_GAME(weapon_excal); +LINK_ENTITY_TO_GAME(weapon_experimental); +LINK_ENTITY_TO_GAME(weapon_expgrenade); +LINK_ENTITY_TO_GAME(weapon_exploder); +LINK_ENTITY_TO_GAME(weapon_explogun); +LINK_ENTITY_TO_GAME(weapon_eyelaser); +LINK_ENTITY_TO_GAME(weapon_famas); +LINK_ENTITY_TO_GAME(weapon_fev); +LINK_ENTITY_TO_GAME(weapon_fg42); +LINK_ENTITY_TO_GAME(weapon_finalflash); +LINK_ENTITY_TO_GAME(weapon_fingerlaser); +LINK_ENTITY_TO_GAME(weapon_finishingbuster); +LINK_ENTITY_TO_GAME(weapon_fireballspell); +LINK_ENTITY_TO_GAME(weapon_fishingrod); +LINK_ENTITY_TO_GAME(weapon_fist); +LINK_ENTITY_TO_GAME(weapon_fists); +LINK_ENTITY_TO_GAME(weapon_fiveseven); +LINK_ENTITY_TO_GAME(weapon_flail); +LINK_ENTITY_TO_GAME(weapon_flakcannon); +LINK_ENTITY_TO_GAME(weapon_flame); +LINK_ENTITY_TO_GAME(weapon_flamegrenade); +LINK_ENTITY_TO_GAME(weapon_flamegun); +LINK_ENTITY_TO_GAME(weapon_flamelickspell); +LINK_ENTITY_TO_GAME(weapon_flamer); +LINK_ENTITY_TO_GAME(weapon_flamethrower); +LINK_ENTITY_TO_GAME(weapon_flaregun); +LINK_ENTITY_TO_GAME(weapon_flarepistol); +LINK_ENTITY_TO_GAME(weapon_flashbang); +LINK_ENTITY_TO_GAME(weapon_fleshgrenade); +LINK_ENTITY_TO_GAME(weapon_flintlock); +LINK_ENTITY_TO_GAME(weapon_flute); +LINK_ENTITY_TO_GAME(weapon_fnfal); +LINK_ENTITY_TO_GAME(weapon_fnp90); +LINK_ENTITY_TO_GAME(weapon_forcespell); +LINK_ENTITY_TO_GAME(weapon_frag); +LINK_ENTITY_TO_GAME(weapon_fraggrenade); +LINK_ENTITY_TO_GAME(weapon_freeze); +LINK_ENTITY_TO_GAME(weapon_freezer); +LINK_ENTITY_TO_GAME(weapon_freezerayspell); +LINK_ENTITY_TO_GAME(weapon_friezadisc); +LINK_ENTITY_TO_GAME(weapon_froster); +LINK_ENTITY_TO_GAME(weapon_fusil); +LINK_ENTITY_TO_GAME(weapon_g11); +LINK_ENTITY_TO_GAME(weapon_g36); +LINK_ENTITY_TO_GAME(weapon_g36c); +LINK_ENTITY_TO_GAME(weapon_g36cs); +LINK_ENTITY_TO_GAME(weapon_g36e); +LINK_ENTITY_TO_GAME(weapon_g36k); +LINK_ENTITY_TO_GAME(weapon_g3a3); +LINK_ENTITY_TO_GAME(weapon_g3sg1); +LINK_ENTITY_TO_GAME(weapon_ga2uss); +LINK_ENTITY_TO_GAME(weapon_gacgoa); +LINK_ENTITY_TO_GAME(weapon_galil); +LINK_ENTITY_TO_GAME(weapon_gallitgun); +LINK_ENTITY_TO_GAME(weapon_garand); +LINK_ENTITY_TO_GAME(weapon_gasgrenade); +LINK_ENTITY_TO_GAME(weapon_gatlin); +LINK_ENTITY_TO_GAME(weapon_gatling); +LINK_ENTITY_TO_GAME(weapon_gattlinggun); +LINK_ENTITY_TO_GAME(weapon_gauss); +LINK_ENTITY_TO_GAME(weapon_gausspistol); +LINK_ENTITY_TO_GAME(weapon_generic); +LINK_ENTITY_TO_GAME(weapon_genericbeam); +LINK_ENTITY_TO_GAME(weapon_gerknife); +LINK_ENTITY_TO_GAME(weapon_germanknife); +LINK_ENTITY_TO_GAME(weapon_gewehr); +LINK_ENTITY_TO_GAME(weapon_giantplantspell); +LINK_ENTITY_TO_GAME(weapon_glauncher); +LINK_ENTITY_TO_GAME(weapon_glock); +LINK_ENTITY_TO_GAME(weapon_glock17); +LINK_ENTITY_TO_GAME(weapon_glock18); +LINK_ENTITY_TO_GAME(weapon_glock_auto); +LINK_ENTITY_TO_GAME(weapon_glock_auto_a); +LINK_ENTITY_TO_GAME(weapon_glstaff); +LINK_ENTITY_TO_GAME(weapon_gluongun); +LINK_ENTITY_TO_GAME(weapon_goaregen); +LINK_ENTITY_TO_GAME(weapon_goldpp7); +LINK_ENTITY_TO_GAME(weapon_gps); +LINK_ENTITY_TO_GAME(weapon_grappin); +LINK_ENTITY_TO_GAME(weapon_grapple); +LINK_ENTITY_TO_GAME(weapon_grease); +LINK_ENTITY_TO_GAME(weapon_greasegun); +LINK_ENTITY_TO_GAME(weapon_gren); +LINK_ENTITY_TO_GAME(weapon_grenade); +LINK_ENTITY_TO_GAME(weapon_grenadegun); +LINK_ENTITY_TO_GAME(weapon_grenadelauncher); +LINK_ENTITY_TO_GAME(weapon_guardian); +LINK_ENTITY_TO_GAME(weapon_hache); +LINK_ENTITY_TO_GAME(weapon_hammer); +LINK_ENTITY_TO_GAME(weapon_hand); +LINK_ENTITY_TO_GAME(weapon_handcannon); +LINK_ENTITY_TO_GAME(weapon_handgrenade); +LINK_ENTITY_TO_GAME(weapon_handgrenade_ex); +LINK_ENTITY_TO_GAME(weapon_harpoongun); +LINK_ENTITY_TO_GAME(weapon_he); +LINK_ENTITY_TO_GAME(weapon_healingspray); +LINK_ENTITY_TO_GAME(weapon_heavymachinegun); +LINK_ENTITY_TO_GAME(weapon_hegrenade); +LINK_ENTITY_TO_GAME(weapon_helico); +LINK_ENTITY_TO_GAME(weapon_hk21); +LINK_ENTITY_TO_GAME(weapon_hk33); +LINK_ENTITY_TO_GAME(weapon_hk33ka2); +LINK_ENTITY_TO_GAME(weapon_hkmp5); +LINK_ENTITY_TO_GAME(weapon_holybsword); +LINK_ENTITY_TO_GAME(weapon_horar1); +LINK_ENTITY_TO_GAME(weapon_horar2); +LINK_ENTITY_TO_GAME(weapon_horg1); +LINK_ENTITY_TO_GAME(weapon_horg2); +LINK_ENTITY_TO_GAME(weapon_hormg1); +LINK_ENTITY_TO_GAME(weapon_hormg2); +LINK_ENTITY_TO_GAME(weapon_hornetgun); +LINK_ENTITY_TO_GAME(weapon_hyperblaster); +LINK_ENTITY_TO_GAME(weapon_icepokespell); +LINK_ENTITY_TO_GAME(weapon_impulse); +LINK_ENTITY_TO_GAME(weapon_incendiary); +LINK_ENTITY_TO_GAME(weapon_infector); +LINK_ENTITY_TO_GAME(weapon_invis); +LINK_ENTITY_TO_GAME(weapon_islavezap); +LINK_ENTITY_TO_GAME(weapon_ithaca); +LINK_ENTITY_TO_GAME(weapon_jackhammer); +LINK_ENTITY_TO_GAME(weapon_javelin); +LINK_ENTITY_TO_GAME(weapon_jetfist); +LINK_ENTITY_TO_GAME(weapon_jetpack); +LINK_ENTITY_TO_GAME(weapon_jumpjet); +LINK_ENTITY_TO_GAME(weapon_k43); +LINK_ENTITY_TO_GAME(weapon_kamakazi); +LINK_ENTITY_TO_GAME(weapon_kameha); +LINK_ENTITY_TO_GAME(weapon_kamehameha); +LINK_ENTITY_TO_GAME(weapon_kametorpedo); +LINK_ENTITY_TO_GAME(weapon_kamikaze); +LINK_ENTITY_TO_GAME(weapon_kar); +LINK_ENTITY_TO_GAME(weapon_katana); +LINK_ENTITY_TO_GAME(weapon_kawauso); +LINK_ENTITY_TO_GAME(weapon_kbar); +LINK_ENTITY_TO_GAME(weapon_kf7); +LINK_ENTITY_TO_GAME(weapon_kiblast); +LINK_ENTITY_TO_GAME(weapon_killsaw); +LINK_ENTITY_TO_GAME(weapon_kmedkit); +LINK_ENTITY_TO_GAME(weapon_knife); +LINK_ENTITY_TO_GAME(weapon_lacrymo); +LINK_ENTITY_TO_GAME(weapon_lance); +LINK_ENTITY_TO_GAME(weapon_lanceflamme); +LINK_ENTITY_TO_GAME(weapon_larve); +LINK_ENTITY_TO_GAME(weapon_laser); +LINK_ENTITY_TO_GAME(weapon_laser_rifle); +LINK_ENTITY_TO_GAME(weapon_lasergatling); +LINK_ENTITY_TO_GAME(weapon_launcher); +LINK_ENTITY_TO_GAME(weapon_law); +LINK_ENTITY_TO_GAME(weapon_lawgiver); +LINK_ENTITY_TO_GAME(weapon_lawrod); +LINK_ENTITY_TO_GAME(weapon_leap); +LINK_ENTITY_TO_GAME(weapon_levitationspell); +LINK_ENTITY_TO_GAME(weapon_lflamme); +LINK_ENTITY_TO_GAME(weapon_lgrenades); +LINK_ENTITY_TO_GAME(weapon_lightning); +LINK_ENTITY_TO_GAME(weapon_lightningboltspell); +LINK_ENTITY_TO_GAME(weapon_lightningcloudspell); +LINK_ENTITY_TO_GAME(weapon_lightsaber); +LINK_ENTITY_TO_GAME(weapon_lightsabre); +LINK_ENTITY_TO_GAME(weapon_lngun); +LINK_ENTITY_TO_GAME(weapon_longbow); +LINK_ENTITY_TO_GAME(weapon_longslide); +LINK_ENTITY_TO_GAME(weapon_longsword); +LINK_ENTITY_TO_GAME(weapon_lr300); +LINK_ENTITY_TO_GAME(weapon_lr300s); +LINK_ENTITY_TO_GAME(weapon_lrifle); +LINK_ENTITY_TO_GAME(weapon_luger); +LINK_ENTITY_TO_GAME(weapon_m11); +LINK_ENTITY_TO_GAME(weapon_m11sd); +LINK_ENTITY_TO_GAME(weapon_m134); +LINK_ENTITY_TO_GAME(weapon_m14); +LINK_ENTITY_TO_GAME(weapon_m16); +LINK_ENTITY_TO_GAME(weapon_m16a2); +LINK_ENTITY_TO_GAME(weapon_m1carbine); +LINK_ENTITY_TO_GAME(weapon_m2); +LINK_ENTITY_TO_GAME(weapon_m21); +LINK_ENTITY_TO_GAME(weapon_m249); +LINK_ENTITY_TO_GAME(weapon_m3); +LINK_ENTITY_TO_GAME(weapon_m4); +LINK_ENTITY_TO_GAME(weapon_m40a1); +LINK_ENTITY_TO_GAME(weapon_m41); +LINK_ENTITY_TO_GAME(weapon_m4a1); +LINK_ENTITY_TO_GAME(weapon_m60); +LINK_ENTITY_TO_GAME(weapon_m61frag); +LINK_ENTITY_TO_GAME(weapon_m67); +LINK_ENTITY_TO_GAME(weapon_m72); +LINK_ENTITY_TO_GAME(weapon_m76); +LINK_ENTITY_TO_GAME(weapon_m79); +LINK_ENTITY_TO_GAME(weapon_m82); +LINK_ENTITY_TO_GAME(weapon_m86); +LINK_ENTITY_TO_GAME(weapon_m92s); +LINK_ENTITY_TO_GAME(weapon_m96); +LINK_ENTITY_TO_GAME(weapon_m98); +LINK_ENTITY_TO_GAME(weapon_mac); +LINK_ENTITY_TO_GAME(weapon_mac10); +LINK_ENTITY_TO_GAME(weapon_mace); +LINK_ENTITY_TO_GAME(weapon_machete); +LINK_ENTITY_TO_GAME(weapon_machinegun); +LINK_ENTITY_TO_GAME(weapon_mag); +LINK_ENTITY_TO_GAME(weapon_magicmisslespell); +LINK_ENTITY_TO_GAME(weapon_main); +LINK_ENTITY_TO_GAME(weapon_markmusket); +LINK_ENTITY_TO_GAME(weapon_masenko); +LINK_ENTITY_TO_GAME(weapon_mat49); +LINK_ENTITY_TO_GAME(weapon_match); +LINK_ENTITY_TO_GAME(weapon_matrix); +LINK_ENTITY_TO_GAME(weapon_maverick); +LINK_ENTITY_TO_GAME(weapon_mc51); +LINK_ENTITY_TO_GAME(weapon_medic); +LINK_ENTITY_TO_GAME(weapon_medikit); +LINK_ENTITY_TO_GAME(weapon_medkit); +LINK_ENTITY_TO_GAME(weapon_melee); +LINK_ENTITY_TO_GAME(weapon_metabolize); +LINK_ENTITY_TO_GAME(weapon_meteorspell); +LINK_ENTITY_TO_GAME(weapon_mf2); +LINK_ENTITY_TO_GAME(weapon_mg34); +LINK_ENTITY_TO_GAME(weapon_mg36); +LINK_ENTITY_TO_GAME(weapon_mg42); +LINK_ENTITY_TO_GAME(weapon_microuzi); +LINK_ENTITY_TO_GAME(weapon_microuzi_a); +LINK_ENTITY_TO_GAME(weapon_mindmisslespell); +LINK_ENTITY_TO_GAME(weapon_mindray); +LINK_ENTITY_TO_GAME(weapon_mine); +LINK_ENTITY_TO_GAME(weapon_minicanon); +LINK_ENTITY_TO_GAME(weapon_minigun); +LINK_ENTITY_TO_GAME(weapon_mk23); +LINK_ENTITY_TO_GAME(weapon_model98); +LINK_ENTITY_TO_GAME(weapon_molotov); +LINK_ENTITY_TO_GAME(weapon_molotov_cocktail); +LINK_ENTITY_TO_GAME(weapon_mop); +LINK_ENTITY_TO_GAME(weapon_mortar); +LINK_ENTITY_TO_GAME(weapon_mortier); +LINK_ENTITY_TO_GAME(weapon_morve); +LINK_ENTITY_TO_GAME(weapon_mosin); +LINK_ENTITY_TO_GAME(weapon_mossberg); +LINK_ENTITY_TO_GAME(weapon_mouthblast); +LINK_ENTITY_TO_GAME(weapon_mouton); +LINK_ENTITY_TO_GAME(weapon_mp40); +LINK_ENTITY_TO_GAME(weapon_mp44); +LINK_ENTITY_TO_GAME(weapon_mp5); +LINK_ENTITY_TO_GAME(weapon_mp510); +LINK_ENTITY_TO_GAME(weapon_mp5a2); +LINK_ENTITY_TO_GAME(weapon_mp5a4); +LINK_ENTITY_TO_GAME(weapon_mp5a5); +LINK_ENTITY_TO_GAME(weapon_mp5k); +LINK_ENTITY_TO_GAME(weapon_mp5ktac); +LINK_ENTITY_TO_GAME(weapon_mp5navy); +LINK_ENTITY_TO_GAME(weapon_mp5pdw); +LINK_ENTITY_TO_GAME(weapon_mp5sd); +LINK_ENTITY_TO_GAME(weapon_mp5sd5); +LINK_ENTITY_TO_GAME(weapon_msg90); +LINK_ENTITY_TO_GAME(weapon_musket); +LINK_ENTITY_TO_GAME(weapon_musketoon); +LINK_ENTITY_TO_GAME(weapon_mustardgrenade); +LINK_ENTITY_TO_GAME(weapon_mwgun); +LINK_ENTITY_TO_GAME(weapon_nailgun); +LINK_ENTITY_TO_GAME(weapon_napalm); +LINK_ENTITY_TO_GAME(weapon_narcogrenade); +LINK_ENTITY_TO_GAME(weapon_ndagger); +LINK_ENTITY_TO_GAME(weapon_needle); +LINK_ENTITY_TO_GAME(weapon_nervegrenade); +LINK_ENTITY_TO_GAME(weapon_ngun); +LINK_ENTITY_TO_GAME(weapon_nightstick); +LINK_ENTITY_TO_GAME(weapon_not_in_use_grenade); +LINK_ENTITY_TO_GAME(weapon_nukegun); +LINK_ENTITY_TO_GAME(weapon_nuker); +LINK_ENTITY_TO_GAME(weapon_null); +LINK_ENTITY_TO_GAME(weapon_nva_grenade); +LINK_ENTITY_TO_GAME(weapon_oicw); +LINK_ENTITY_TO_GAME(weapon_omen); +LINK_ENTITY_TO_GAME(weapon_orbital); +LINK_ENTITY_TO_GAME(weapon_orracle); +LINK_ENTITY_TO_GAME(weapon_p225); +LINK_ENTITY_TO_GAME(weapon_p226); +LINK_ENTITY_TO_GAME(weapon_p226mp); +LINK_ENTITY_TO_GAME(weapon_p228); +LINK_ENTITY_TO_GAME(weapon_p90); +LINK_ENTITY_TO_GAME(weapon_p99); +LINK_ENTITY_TO_GAME(weapon_paintball); +LINK_ENTITY_TO_GAME(weapon_paintgrenade); +LINK_ENTITY_TO_GAME(weapon_paralysis); +LINK_ENTITY_TO_GAME(weapon_parasite); +LINK_ENTITY_TO_GAME(weapon_parrot); +LINK_ENTITY_TO_GAME(weapon_pdw); +LINK_ENTITY_TO_GAME(weapon_penguin); +LINK_ENTITY_TO_GAME(weapon_pgp); +LINK_ENTITY_TO_GAME(weapon_phantom); +LINK_ENTITY_TO_GAME(weapon_phoenix); +LINK_ENTITY_TO_GAME(weapon_photongun); +LINK_ENTITY_TO_GAME(weapon_piat); +LINK_ENTITY_TO_GAME(weapon_pick); +LINK_ENTITY_TO_GAME(weapon_pigeon); +LINK_ENTITY_TO_GAME(weapon_pipebomb); +LINK_ENTITY_TO_GAME(weapon_pipewrench); +LINK_ENTITY_TO_GAME(weapon_pistol); +LINK_ENTITY_TO_GAME(weapon_pistolet); +LINK_ENTITY_TO_GAME(weapon_pkm); +LINK_ENTITY_TO_GAME(weapon_plasma); +LINK_ENTITY_TO_GAME(weapon_plasmarifle); +LINK_ENTITY_TO_GAME(weapon_plauncher); +LINK_ENTITY_TO_GAME(weapon_pmine); +LINK_ENTITY_TO_GAME(weapon_poison); +LINK_ENTITY_TO_GAME(weapon_poolstick); +LINK_ENTITY_TO_GAME(weapon_powderkeg); +LINK_ENTITY_TO_GAME(weapon_powerbeam); +LINK_ENTITY_TO_GAME(weapon_powerblade); +LINK_ENTITY_TO_GAME(weapon_prifle); +LINK_ENTITY_TO_GAME(weapon_primalscream); +LINK_ENTITY_TO_GAME(weapon_proximity); +LINK_ENTITY_TO_GAME(weapon_pschreck); +LINK_ENTITY_TO_GAME(weapon_psg); +LINK_ENTITY_TO_GAME(weapon_psg1); +LINK_ENTITY_TO_GAME(weapon_pt); +LINK_ENTITY_TO_GAME(weapon_pulserifle); +LINK_ENTITY_TO_GAME(weapon_pushhands); +LINK_ENTITY_TO_GAME(weapon_python); +LINK_ENTITY_TO_GAME(weapon_quakegun); +LINK_ENTITY_TO_GAME(weapon_radio); +LINK_ENTITY_TO_GAME(weapon_railgun); +LINK_ENTITY_TO_GAME(weapon_ralkek); +LINK_ENTITY_TO_GAME(weapon_rallyhp); +LINK_ENTITY_TO_GAME(weapon_rbull); +LINK_ENTITY_TO_GAME(weapon_rcp90); +LINK_ENTITY_TO_GAME(weapon_redeemer); +LINK_ENTITY_TO_GAME(weapon_reetou); +LINK_ENTITY_TO_GAME(weapon_regeneration); +LINK_ENTITY_TO_GAME(weapon_rem1100); +LINK_ENTITY_TO_GAME(weapon_remington); +LINK_ENTITY_TO_GAME(weapon_renzoku); +LINK_ENTITY_TO_GAME(weapon_resource); +LINK_ENTITY_TO_GAME(weapon_rgd5); +LINK_ENTITY_TO_GAME(weapon_rifle); +LINK_ENTITY_TO_GAME(weapon_rmine); +LINK_ENTITY_TO_GAME(weapon_rocketlauncher); +LINK_ENTITY_TO_GAME(weapon_rocketpistol); +LINK_ENTITY_TO_GAME(weapon_rollingstonespell); +LINK_ENTITY_TO_GAME(weapon_rpd); +LINK_ENTITY_TO_GAME(weapon_rpg); +LINK_ENTITY_TO_GAME(weapon_rpg7); +LINK_ENTITY_TO_GAME(weapon_rs202m2); +LINK_ENTITY_TO_GAME(weapon_rs_meta); +LINK_ENTITY_TO_GAME(weapon_ruche); +LINK_ENTITY_TO_GAME(weapon_ruger); +LINK_ENTITY_TO_GAME(weapon_rumgun); +LINK_ENTITY_TO_GAME(weapon_runner); +LINK_ENTITY_TO_GAME(weapon_sa80); +LINK_ENTITY_TO_GAME(weapon_saa); +LINK_ENTITY_TO_GAME(weapon_saber); +LINK_ENTITY_TO_GAME(weapon_sabers); +LINK_ENTITY_TO_GAME(weapon_saiga); +LINK_ENTITY_TO_GAME(weapon_sainte); +LINK_ENTITY_TO_GAME(weapon_sako); +LINK_ENTITY_TO_GAME(weapon_satchel); +LINK_ENTITY_TO_GAME(weapon_satelitelaser); +LINK_ENTITY_TO_GAME(weapon_satellite); +LINK_ENTITY_TO_GAME(weapon_sawed); +LINK_ENTITY_TO_GAME(weapon_sawedoff); +LINK_ENTITY_TO_GAME(weapon_sawgun); +LINK_ENTITY_TO_GAME(weapon_sbarrel); +LINK_ENTITY_TO_GAME(weapon_scatterbeam); +LINK_ENTITY_TO_GAME(weapon_scattergun); +LINK_ENTITY_TO_GAME(weapon_scattershot); +LINK_ENTITY_TO_GAME(weapon_scopedenfield); +LINK_ENTITY_TO_GAME(weapon_scopedfg42); +LINK_ENTITY_TO_GAME(weapon_scopedkar); +LINK_ENTITY_TO_GAME(weapon_scorpion); +LINK_ENTITY_TO_GAME(weapon_scout); +LINK_ENTITY_TO_GAME(weapon_seburo); +LINK_ENTITY_TO_GAME(weapon_sensu); +LINK_ENTITY_TO_GAME(weapon_seringue); +LINK_ENTITY_TO_GAME(weapon_sg550); +LINK_ENTITY_TO_GAME(weapon_sg552); +LINK_ENTITY_TO_GAME(weapon_sgenerator); +LINK_ENTITY_TO_GAME(weapon_shield); +LINK_ENTITY_TO_GAME(weapon_shieldattack); +LINK_ENTITY_TO_GAME(weapon_shieldgun); +LINK_ENTITY_TO_GAME(weapon_shieldspell); +LINK_ENTITY_TO_GAME(weapon_shocker); +LINK_ENTITY_TO_GAME(weapon_shocker2k); +LINK_ENTITY_TO_GAME(weapon_shockrifle); +LINK_ENTITY_TO_GAME(weapon_shockroach); +LINK_ENTITY_TO_GAME(weapon_shotgun); +LINK_ENTITY_TO_GAME(weapon_shrinker); +LINK_ENTITY_TO_GAME(weapon_sig); +LINK_ENTITY_TO_GAME(weapon_sig245); +LINK_ENTITY_TO_GAME(weapon_sig550); +LINK_ENTITY_TO_GAME(weapon_sigpro); +LINK_ENTITY_TO_GAME(weapon_silverpp7); +LINK_ENTITY_TO_GAME(weapon_sixshooter); +LINK_ENTITY_TO_GAME(weapon_skeletonspell); +LINK_ENTITY_TO_GAME(weapon_sks); +LINK_ENTITY_TO_GAME(weapon_skullspell); +LINK_ENTITY_TO_GAME(weapon_skunk); +LINK_ENTITY_TO_GAME(weapon_sl68); +LINK_ENTITY_TO_GAME(weapon_slappers); +LINK_ENTITY_TO_GAME(weapon_sledge); +LINK_ENTITY_TO_GAME(weapon_sledgehammer); +LINK_ENTITY_TO_GAME(weapon_sm_assaultcannon); +LINK_ENTITY_TO_GAME(weapon_sm_bolter); +LINK_ENTITY_TO_GAME(weapon_sm_boltpistol); +LINK_ENTITY_TO_GAME(weapon_sm_combatknife); +LINK_ENTITY_TO_GAME(weapon_sm_flamer); +LINK_ENTITY_TO_GAME(weapon_sm_fraggrenade); +LINK_ENTITY_TO_GAME(weapon_sm_heavybolter); +LINK_ENTITY_TO_GAME(weapon_sm_heavyflamer); +LINK_ENTITY_TO_GAME(weapon_sm_lascannon); +LINK_ENTITY_TO_GAME(weapon_sm_missilelauncher); +LINK_ENTITY_TO_GAME(weapon_sm_poweraxe); +LINK_ENTITY_TO_GAME(weapon_sm_powersword); +LINK_ENTITY_TO_GAME(weapon_sm_stormbolter); +LINK_ENTITY_TO_GAME(weapon_smartgun); +LINK_ENTITY_TO_GAME(weapon_smaw); +LINK_ENTITY_TO_GAME(weapon_smg9); +LINK_ENTITY_TO_GAME(weapon_smkgrenade); +LINK_ENTITY_TO_GAME(weapon_smoke); +LINK_ENTITY_TO_GAME(weapon_smokegrenade); +LINK_ENTITY_TO_GAME(weapon_snUZI); +LINK_ENTITY_TO_GAME(weapon_snark); +LINK_ENTITY_TO_GAME(weapon_snipe); +LINK_ENTITY_TO_GAME(weapon_sniper); +LINK_ENTITY_TO_GAME(weapon_sniper3); +LINK_ENTITY_TO_GAME(weapon_sniperrifle); +LINK_ENTITY_TO_GAME(weapon_snowball); +LINK_ENTITY_TO_GAME(weapon_socom); +LINK_ENTITY_TO_GAME(weapon_socomtac); +LINK_ENTITY_TO_GAME(weapon_solarflare); +LINK_ENTITY_TO_GAME(weapon_soniccannon); +LINK_ENTITY_TO_GAME(weapon_sonicgrenade); +LINK_ENTITY_TO_GAME(weapon_spade); +LINK_ENTITY_TO_GAME(weapon_spas); +LINK_ENTITY_TO_GAME(weapon_spas12); +LINK_ENTITY_TO_GAME(weapon_spear); +LINK_ENTITY_TO_GAME(weapon_specialbeamcannon); +LINK_ENTITY_TO_GAME(weapon_spectre); +LINK_ENTITY_TO_GAME(weapon_spider); +LINK_ENTITY_TO_GAME(weapon_spiderbomb); +LINK_ENTITY_TO_GAME(weapon_spikegun); +LINK_ENTITY_TO_GAME(weapon_spiritbomb); +LINK_ENTITY_TO_GAME(weapon_spiritwizspell); +LINK_ENTITY_TO_GAME(weapon_spit); +LINK_ENTITY_TO_GAME(weapon_spitcarbine); +LINK_ENTITY_TO_GAME(weapon_spitpistol); +LINK_ENTITY_TO_GAME(weapon_spore); +LINK_ENTITY_TO_GAME(weapon_sporelauncher); +LINK_ENTITY_TO_GAME(weapon_spotboltspell); +LINK_ENTITY_TO_GAME(weapon_spring); +LINK_ENTITY_TO_GAME(weapon_spy); +LINK_ENTITY_TO_GAME(weapon_spycam); +LINK_ENTITY_TO_GAME(weapon_spyder); +LINK_ENTITY_TO_GAME(weapon_srifle); +LINK_ENTITY_TO_GAME(weapon_ssg3000); +LINK_ENTITY_TO_GAME(weapon_sshotgun); +LINK_ENTITY_TO_GAME(weapon_st_far); +LINK_ENTITY_TO_GAME(weapon_st_heavy); +LINK_ENTITY_TO_GAME(weapon_st_medium); +LINK_ENTITY_TO_GAME(weapon_st_melee); +LINK_ENTITY_TO_GAME(weapon_st_power); +LINK_ENTITY_TO_GAME(weapon_st_psi); +LINK_ENTITY_TO_GAME(weapon_st_short); +LINK_ENTITY_TO_GAME(weapon_st_special); +LINK_ENTITY_TO_GAME(weapon_st_throw); +LINK_ENTITY_TO_GAME(weapon_staff); +LINK_ENTITY_TO_GAME(weapon_star); +LINK_ENTITY_TO_GAME(weapon_sten); +LINK_ENTITY_TO_GAME(weapon_sterling); +LINK_ENTITY_TO_GAME(weapon_steyr_m40); +LINK_ENTITY_TO_GAME(weapon_stg24); +LINK_ENTITY_TO_GAME(weapon_stickgrenade); +LINK_ENTITY_TO_GAME(weapon_stickgrenade_ex); +LINK_ENTITY_TO_GAME(weapon_stinger); +LINK_ENTITY_TO_GAME(weapon_stingray2); +LINK_ENTITY_TO_GAME(weapon_stomp); +LINK_ENTITY_TO_GAME(weapon_stoner); +LINK_ENTITY_TO_GAME(weapon_stonerscope); +LINK_ENTITY_TO_GAME(weapon_stonersilencer); +LINK_ENTITY_TO_GAME(weapon_stubgun); +LINK_ENTITY_TO_GAME(weapon_stumpgun); +LINK_ENTITY_TO_GAME(weapon_stupid); +LINK_ENTITY_TO_GAME(weapon_super_mouton); +LINK_ENTITY_TO_GAME(weapon_supernailgun); +LINK_ENTITY_TO_GAME(weapon_supershotgun); +LINK_ENTITY_TO_GAME(weapon_svd); +LINK_ENTITY_TO_GAME(weapon_swarm_gargflame); +LINK_ENTITY_TO_GAME(weapon_swipe); +LINK_ENTITY_TO_GAME(weapon_sword); +LINK_ENTITY_TO_GAME(weapon_syringe); +LINK_ENTITY_TO_GAME(weapon_tacgun); +LINK_ENTITY_TO_GAME(weapon_taucannon); +LINK_ENTITY_TO_GAME(weapon_tavor); +LINK_ENTITY_TO_GAME(weapon_tdagger); +LINK_ENTITY_TO_GAME(weapon_tec9); +LINK_ENTITY_TO_GAME(weapon_telekinesis); +LINK_ENTITY_TO_GAME(weapon_teleporter); +LINK_ENTITY_TO_GAME(weapon_teleporteur); +LINK_ENTITY_TO_GAME(weapon_teslagun); +LINK_ENTITY_TO_GAME(weapon_thompson); +LINK_ENTITY_TO_GAME(weapon_thornblastspell); +LINK_ENTITY_TO_GAME(weapon_throwaxe); +LINK_ENTITY_TO_GAME(weapon_throwing_knife); +LINK_ENTITY_TO_GAME(weapon_throwingknife); +LINK_ENTITY_TO_GAME(weapon_timmy); +LINK_ENTITY_TO_GAME(weapon_tknife); +LINK_ENTITY_TO_GAME(weapon_tmine); +LINK_ENTITY_TO_GAME(weapon_tmp); +LINK_ENTITY_TO_GAME(weapon_tnt); +LINK_ENTITY_TO_GAME(weapon_toad); +LINK_ENTITY_TO_GAME(weapon_tokarev); +LINK_ENTITY_TO_GAME(weapon_tomahawk); +LINK_ENTITY_TO_GAME(weapon_tommy); +LINK_ENTITY_TO_GAME(weapon_tommygun); +LINK_ENTITY_TO_GAME(weapon_tornadospell); +LINK_ENTITY_TO_GAME(weapon_transistor); +LINK_ENTITY_TO_GAME(weapon_translocator); +LINK_ENTITY_TO_GAME(weapon_treasure); +LINK_ENTITY_TO_GAME(weapon_trident); +LINK_ENTITY_TO_GAME(weapon_trigun); +LINK_ENTITY_TO_GAME(weapon_triplaser); +LINK_ENTITY_TO_GAME(weapon_tripmine); +LINK_ENTITY_TO_GAME(weapon_trooper); +LINK_ENTITY_TO_GAME(weapon_tsgun); +LINK_ENTITY_TO_GAME(weapon_tucan); +LINK_ENTITY_TO_GAME(weapon_turret); +LINK_ENTITY_TO_GAME(weapon_twosword); +LINK_ENTITY_TO_GAME(weapon_u2); +LINK_ENTITY_TO_GAME(weapon_umbra); +LINK_ENTITY_TO_GAME(weapon_umbrella); +LINK_ENTITY_TO_GAME(weapon_ump45); +LINK_ENTITY_TO_GAME(weapon_updraftspell); +LINK_ENTITY_TO_GAME(weapon_us_grenade); +LINK_ENTITY_TO_GAME(weapon_usas); +LINK_ENTITY_TO_GAME(weapon_usas12); +LINK_ENTITY_TO_GAME(weapon_usp); +LINK_ENTITY_TO_GAME(weapon_uspmp); +LINK_ENTITY_TO_GAME(weapon_uzi); +LINK_ENTITY_TO_GAME(weapon_uziakimbo); +LINK_ENTITY_TO_GAME(weapon_vepr); +LINK_ENTITY_TO_GAME(weapon_viksword); +LINK_ENTITY_TO_GAME(weapon_vomit); +LINK_ENTITY_TO_GAME(weapon_vsbike); +LINK_ENTITY_TO_GAME(weapon_vsclaw); +LINK_ENTITY_TO_GAME(weapon_vscolt); +LINK_ENTITY_TO_GAME(weapon_vscrossbow); +LINK_ENTITY_TO_GAME(weapon_vscue); +LINK_ENTITY_TO_GAME(weapon_vsdbshotgun); +LINK_ENTITY_TO_GAME(weapon_vsmp5); +LINK_ENTITY_TO_GAME(weapon_vsshotgun); +LINK_ENTITY_TO_GAME(weapon_vsstake); +LINK_ENTITY_TO_GAME(weapon_vsthunderfive); +LINK_ENTITY_TO_GAME(weapon_vswinchester); +LINK_ENTITY_TO_GAME(weapon_vulcan); +LINK_ENTITY_TO_GAME(weapon_wa2000); +LINK_ENTITY_TO_GAME(weapon_warhammer); +LINK_ENTITY_TO_GAME(weapon_webley); +LINK_ENTITY_TO_GAME(weapon_webspinner); +LINK_ENTITY_TO_GAME(weapon_welder); +LINK_ENTITY_TO_GAME(weapon_whirlwindspell); +LINK_ENTITY_TO_GAME(weapon_whiskey); +LINK_ENTITY_TO_GAME(weapon_whiterayspell); +LINK_ENTITY_TO_GAME(weapon_whl); +LINK_ENTITY_TO_GAME(weapon_winchester); +LINK_ENTITY_TO_GAME(weapon_wombatspell); +LINK_ENTITY_TO_GAME(weapon_wyvernspell); +LINK_ENTITY_TO_GAME(weapon_xbow); +LINK_ENTITY_TO_GAME(weapon_xm1014); +LINK_ENTITY_TO_GAME(weapon_xm4); +LINK_ENTITY_TO_GAME(weapon_zat); +LINK_ENTITY_TO_GAME(weapon_zatarc); +LINK_ENTITY_TO_GAME(weapon_zmg); +LINK_ENTITY_TO_GAME(weaponbox); +LINK_ENTITY_TO_GAME(weather_genie); +LINK_ENTITY_TO_GAME(weather_litnode); +LINK_ENTITY_TO_GAME(webgunprojectile); +LINK_ENTITY_TO_GAME(wh); +LINK_ENTITY_TO_GAME(wheel); +LINK_ENTITY_TO_GAME(wheel_ent); +LINK_ENTITY_TO_GAME(whiskey_whisk); +LINK_ENTITY_TO_GAME(whshard); +LINK_ENTITY_TO_GAME(world_areacontrol); +LINK_ENTITY_TO_GAME(world_artefact); +LINK_ENTITY_TO_GAME(world_capturelocation); +LINK_ENTITY_TO_GAME(world_items); +LINK_ENTITY_TO_GAME(worldspawn); +LINK_ENTITY_TO_GAME(ww_ammo_satchels); +LINK_ENTITY_TO_GAME(ww_ammo_spellbook); +LINK_ENTITY_TO_GAME(ww_bearbite); +LINK_ENTITY_TO_GAME(ww_emitter); +LINK_ENTITY_TO_GAME(ww_monstermaker); +LINK_ENTITY_TO_GAME(ww_satchel); +LINK_ENTITY_TO_GAME(ww_satchel_archmage); +LINK_ENTITY_TO_GAME(ww_satchel_death); +LINK_ENTITY_TO_GAME(ww_satchel_dragon); +LINK_ENTITY_TO_GAME(ww_satchel_earth); +LINK_ENTITY_TO_GAME(ww_satchel_fire); +LINK_ENTITY_TO_GAME(ww_satchel_ice); +LINK_ENTITY_TO_GAME(ww_satchel_life); +LINK_ENTITY_TO_GAME(ww_satchel_lightning); +LINK_ENTITY_TO_GAME(ww_satchel_nature); +LINK_ENTITY_TO_GAME(ww_satchel_wind); +LINK_ENTITY_TO_GAME(ww_seal); +LINK_ENTITY_TO_GAME(ww_seal_death); +LINK_ENTITY_TO_GAME(ww_seal_dragon); +LINK_ENTITY_TO_GAME(ww_seal_earth); +LINK_ENTITY_TO_GAME(ww_seal_fire); +LINK_ENTITY_TO_GAME(ww_seal_ice); +LINK_ENTITY_TO_GAME(ww_seal_life); +LINK_ENTITY_TO_GAME(ww_seal_lightning); +LINK_ENTITY_TO_GAME(ww_seal_nature); +LINK_ENTITY_TO_GAME(ww_seal_wind); +LINK_ENTITY_TO_GAME(ww_sentrycrystal); +LINK_ENTITY_TO_GAME(ww_spell_beanstalk); +LINK_ENTITY_TO_GAME(ww_spell_bird); +LINK_ENTITY_TO_GAME(ww_spell_deathray); +LINK_ENTITY_TO_GAME(ww_spell_doublemissile); +LINK_ENTITY_TO_GAME(ww_spell_dragonbreath); +LINK_ENTITY_TO_GAME(ww_spell_fireball); +LINK_ENTITY_TO_GAME(ww_spell_flamelick); +LINK_ENTITY_TO_GAME(ww_spell_forceblast); +LINK_ENTITY_TO_GAME(ww_spell_freezeray); +LINK_ENTITY_TO_GAME(ww_spell_iceshard); +LINK_ENTITY_TO_GAME(ww_spell_levitate); +LINK_ENTITY_TO_GAME(ww_spell_lightningbolt); +LINK_ENTITY_TO_GAME(ww_spell_missile); +LINK_ENTITY_TO_GAME(ww_spell_pebbleblast); +LINK_ENTITY_TO_GAME(ww_spell_seal); +LINK_ENTITY_TO_GAME(ww_spell_shield); +LINK_ENTITY_TO_GAME(ww_spell_skull); +LINK_ENTITY_TO_GAME(ww_spell_spotbolt); +LINK_ENTITY_TO_GAME(ww_spell_stone); +LINK_ENTITY_TO_GAME(ww_spell_thornblast); +LINK_ENTITY_TO_GAME(ww_spell_updraft); +LINK_ENTITY_TO_GAME(ww_spell_whiteray); +LINK_ENTITY_TO_GAME(ww_spell_wyvern); +LINK_ENTITY_TO_GAME(ww_staff); +LINK_ENTITY_TO_GAME(wyvern); +LINK_ENTITY_TO_GAME(xbow_teather); +LINK_ENTITY_TO_GAME(xbowbolt); +LINK_ENTITY_TO_GAME(xen_hair); +LINK_ENTITY_TO_GAME(xen_hull); +LINK_ENTITY_TO_GAME(xen_plantlight); +LINK_ENTITY_TO_GAME(xen_spore_large); +LINK_ENTITY_TO_GAME(xen_spore_medium); +LINK_ENTITY_TO_GAME(xen_spore_small); +LINK_ENTITY_TO_GAME(xen_tree); +LINK_ENTITY_TO_GAME(xen_ttrigger); +LINK_ENTITY_TO_GAME(zatarc_proj); +LINK_ENTITY_TO_GAME(zone); +LINK_ENTITY_TO_GAME(zone_bomb_target); +LINK_ENTITY_TO_GAME(zone_capture); +LINK_ENTITY_TO_GAME(zone_gatetravel); +LINK_ENTITY_TO_GAME(zone_nodamage); +LINK_ENTITY_TO_GAME(zone_shelter); diff --git a/metamod/src/linkplug.cpp b/metamod/src/linkplug.cpp deleted file mode 100644 index 78a6f1a..0000000 --- a/metamod/src/linkplug.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "precompiled.h" - -// Entity lists for plugins -//LINK_ENTITY_TO_PLUGIN(adminmod_timer, "adminmod"); - diff --git a/metamod/src/log_meta.cpp b/metamod/src/log_meta.cpp index d46d5f3..ba958c0 100644 --- a/metamod/src/log_meta.cpp +++ b/metamod/src/log_meta.cpp @@ -1,7 +1,42 @@ +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// log_mega.cpp - logging routines + +/* + * Copyright (c) 2001-2003 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game g_engine ("HL + * g_engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL g_engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + #include "precompiled.h" -cvar_t meta_debug = { "meta_debug", "0", FCVAR_EXTDLL, 0, NULL }; -int meta_debug_value = 0; // meta_debug_value is converted from float(meta_debug.value) to int on every frame +cvar_t meta_debug = {"meta_debug", "0", FCVAR_EXTDLL , 0, NULL}; enum MLOG_SERVICE { @@ -11,196 +46,154 @@ enum MLOG_SERVICE mlsCLIENT }; -void buffered_ALERT(MLOG_SERVICE service, ALERT_TYPE atype, const char *prefix, const char *fmt, va_list ap); +static void buffered_ALERT(MLOG_SERVICE service, ALERT_TYPE atype, const char* prefix, const char* fmt, va_list ap); // Print to console. -void META_CONS(const char *fmt, ...) +void META_CONS(const char* fmt, ...) { va_list ap; char buf[MAX_LOGMSG_LEN]; unsigned int len; va_start(ap, fmt); - safevoid_vsnprintf(buf, sizeof(buf), fmt, ap); + len = vsnprintf(buf, sizeof(buf) - 1, fmt, ap); va_end(ap); - len = Q_strlen(buf); - // -1 null, -1 for newline - if (len < sizeof(buf) - 2) { - strcat(buf, "\n"); - } - else - buf[len - 1] = '\n'; + buf[len] = '\n'; + buf[len + 1] = '\0'; SERVER_PRINT(buf); } -// Log developer-level messages (obsoleted). -void META_DEV(const char *fmt, ...) +void META_DEV(const char* fmt, ...) +{ + if (CVAR_GET_FLOAT && CVAR_GET_FLOAT("developer")) { + va_list ap; + va_start(ap, fmt); + buffered_ALERT(mlsDEV, at_logged, "[META] dev:", fmt, ap); + va_end(ap); + } +} + +void META_INFO(const char* fmt, ...) { va_list ap; - static const char *const prefixDEV = "[META] dev:"; - - if (!CVAR_GET_FLOAT("developer")) - return; va_start(ap, fmt); - buffered_ALERT(mlsDEV, at_logged, prefixDEV, fmt, ap); + buffered_ALERT(mlsIWEL, at_logged, "[META] INFO:", fmt, ap); va_end(ap); } -// Log infos. -void META_INFO(const char *fmt, ...) +void META_WARNING(const char* fmt, ...) { va_list ap; - static const char *const prefixINFO = "[META] INFO:"; va_start(ap, fmt); - buffered_ALERT(mlsIWEL, at_logged, prefixINFO, fmt, ap); + buffered_ALERT(mlsIWEL, at_logged, "[META] WARNING:", fmt, ap); va_end(ap); } -// Log warnings. -void META_WARNING(const char *fmt, ...) +void META_ERROR(const char* fmt, ...) { va_list ap; - static const char *const prefixWARNING = "[META] WARNING:"; va_start(ap, fmt); - buffered_ALERT(mlsIWEL, at_logged, prefixWARNING, fmt, ap); + buffered_ALERT(mlsIWEL, at_logged, "[META] ERROR:", fmt, ap); va_end(ap); } -// Log errors. -void META_ERROR(const char *fmt, ...) +void META_LOG(const char* fmt, ...) { va_list ap; - static const char *const prefixERROR = "[META] ERROR:"; va_start(ap, fmt); - buffered_ALERT(mlsIWEL, at_logged, prefixERROR, fmt, ap); - va_end(ap); -} - -// Normal log messages. -void META_LOG(const char *fmt, ...) -{ - va_list ap; - static const char *const prefixLOG = "[META]"; - - va_start(ap, fmt); - buffered_ALERT(mlsIWEL, at_logged, prefixLOG, fmt, ap); + buffered_ALERT(mlsIWEL, at_logged, "[META]", fmt, ap); va_end(ap); } // Print to client. -void META_CLIENT(edict_t *pEntity, const char *fmt, ...) +void META_CLIENT(edict_t* pEntity, const char* fmt, ...) { va_list ap; char buf[MAX_CLIENTMSG_LEN]; unsigned int len; va_start(ap, fmt); - safevoid_vsnprintf(buf, sizeof(buf), fmt, ap); + len = vsnprintf(buf, sizeof(buf) - 1, fmt, ap); va_end(ap); - len = Q_strlen(buf); - - // -1 null, -1 for newline - if (len < sizeof(buf) - 2) { - strcat(buf, "\n"); - } - else - buf[len - 1] = '\n'; + buf[len] = '\n'; + buf[len + 1] = '\0'; CLIENT_PRINTF(pEntity, print_console, buf); } -#ifndef __BUILD_FAST_METAMOD__ - -int debug_level; - -void META_DEBUG_SET_LEVEL(int level) +struct BufferedMessage { - debug_level = level; -} - -void META_DO_DEBUG(const char *fmt, ...) -{ - char meta_debug_str[1024]; - va_list ap; - - va_start(ap, fmt); - safevoid_vsnprintf(meta_debug_str, sizeof(meta_debug_str), fmt, ap); - va_end(ap); - - ALERT(at_logged, "[META] (debug:%d) %s\n", debug_level, meta_debug_str); -} - -#endif // __BUILD_FAST_METAMOD__ - -class BufferedMessage: public class_metamod_new { -public: MLOG_SERVICE service; ALERT_TYPE atype; - const char *prefix; + const char* prefix; char buf[MAX_LOGMSG_LEN]; - BufferedMessage *next; + BufferedMessage* next; }; -BufferedMessage *messageQueueStart = NULL; -BufferedMessage *messageQueueEnd = NULL; +static BufferedMessage* messageQueueStart = NULL; +static BufferedMessage* messageQueueEnd = NULL; -void buffered_ALERT(MLOG_SERVICE service, ALERT_TYPE atype, const char *prefix, const char *fmt, va_list ap) { +void buffered_ALERT(MLOG_SERVICE service, ALERT_TYPE atype, const char* prefix, const char* fmt, va_list ap) +{ char buf[MAX_LOGMSG_LEN]; - BufferedMessage *msg; + BufferedMessage* msg; - if (g_engfuncs.pfnAlertMessage) - { + if (NULL != g_engfuncs.pfnAlertMessage) { vsnprintf(buf, sizeof(buf), fmt, ap); ALERT(atype, "%s %s\n", prefix, buf); return; } - // Engine AlertMessage function not available. Buffer message. + // g_engine AlertMessage function not available. Buffer message. msg = new BufferedMessage; - if (NULL == msg) - { + if (NULL == msg) { // though luck, gonna lose this message return; } + msg->service = service; msg->atype = atype; msg->prefix = prefix; vsnprintf(msg->buf, sizeof(buf), fmt, ap); msg->next = NULL; - if (NULL == messageQueueEnd) - { + + if (NULL == messageQueueEnd) { messageQueueStart = messageQueueEnd = msg; - } else { + } + else { messageQueueEnd->next = msg; messageQueueEnd = msg; } } + // Flushes the message queue, printing messages to the respective // service. This function doesn't check anymore if the g_engfuncs // jumptable is set. Don't call it if it isn't set. -void flush_ALERT_buffer() +void flush_ALERT_buffer(void) { - BufferedMessage *msg = messageQueueStart; + BufferedMessage* msg = messageQueueStart; int dev = (int) CVAR_GET_FLOAT("developer"); - while (NULL != msg) - { - if (msg->service == mlsDEV && dev==0) - { + + while (NULL != msg) { + if (msg->service == mlsDEV && dev == 0) { ; - } else { + } + else { ALERT(msg->atype, "b>%s %s\n", msg->prefix, msg->buf); } messageQueueStart = messageQueueStart->next; delete msg; msg = messageQueueStart; } + messageQueueStart = messageQueueEnd = NULL; } + diff --git a/metamod/src/log_meta.h b/metamod/src/log_meta.h index 2827e55..4d67730 100644 --- a/metamod/src/log_meta.h +++ b/metamod/src/log_meta.h @@ -1,6 +1,46 @@ -#pragma once +// vi: set ts=4 sw=4 : +// vim: set tw=75 : -// Debug logging. +// log_meta.h - functions & macros for logging + +/* + * Copyright (c) 2001-2003 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game g_engine ("HL + * g_engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL g_engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + +#ifndef LOG_META_H +#define LOG_META_H + +#include "enginecallbacks.h" // ALERT, etc +#include "sdk_util.h" // UTIL_VarArgs, etc + +// Debug logging. // // This is done as a macro, rather than a function. This way, you can add // DEBUG statements all over, without worrying about performance @@ -16,33 +56,24 @@ // cvar, rather than calling CVAR_GET_FLOAT() and thus generating a string // compare for each DEBUG statement. // -// Called as: -// META_DEBUG(3, ("return code: %d", ret)); +// Called as: +// META_DEBUG(3, ("return code: %d", ret)); // // Note the double parens, and the missing parens around "args" in the -// macro itself. Note also the "do..while (0)" loop wrapping the +// macro itself. Note also the "do..while(0)" loop wrapping the // statements, so they become a single statement when expanded, necessary // for times when it might be called as a single-statement result of an // else (or other flow control). // -// Yes, it's all a bit of a hack. +// As suggested by Jussi Kivilinna: Use "if(meta_debug.value < level); else +// DO(something);" style because "meta_debug.value < level" is in most common +// case "false". Check disasm, contitional jumps are predicted not to be +// taken by CPU. // -// Using meta_debug_value instead of meta_debug.value. -// meta_debug_value is preconverted int-value of meta_debug.value. -// Reason for this optimization: Integer compare is much faster than float compare. -// i686 has fast float compare, but since we want to have i386 binary, we use this. +// Yes, it's all a bit of a hack. -#ifdef __BUILD_FAST_METAMOD__ - #define META_DEBUG(level, args) do { break; } while (0) -#else - #define META_DEBUG(level, args) \ - do { \ - if (meta_debug_value >= level) { \ - META_DEBUG_SET_LEVEL(level); \ - META_DO_DEBUG args; \ - } \ - } while (0) -#endif +#define META_DEBUG(level, args) \ + do { if(meta_debug.value < level) break; else ALERT(at_logged, "[META] (debug:%d) %s\n", level, UTIL_VarArgs args ); } while(0) // max buffer size for printed messages #define MAX_LOGMSG_LEN 1024 @@ -51,7 +82,6 @@ #define MAX_CLIENTMSG_LEN 128 extern cvar_t meta_debug; -extern int meta_debug_value; // META_DEV provides debug logging via the cvar "developer" (when set to 1) // and uses a function call rather than a macro as it's really intended to @@ -66,9 +96,7 @@ void META_WARNING(const char *fmt, ...); void META_ERROR(const char *fmt, ...); void META_LOG(const char *fmt, ...); void META_CLIENT(edict_t *pEntity, const char *fmt, ...); -#ifndef __BUILD_FAST_METAMOD__ - void META_DEBUG_SET_LEVEL(int level); - void META_DO_DEBUG(const char *fmt, ...); -#endif -void flush_ALERT_buffer(); +void flush_ALERT_buffer(void); + +#endif /* LOG_META_H */ diff --git a/metamod/src/meta_api.h b/metamod/src/meta_api.h index ec74f69..b203cb0 100644 --- a/metamod/src/meta_api.h +++ b/metamod/src/meta_api.h @@ -1,10 +1,47 @@ -#pragma once +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// meta_api.h - description of metamod's DLL interface + +/* + * Copyright (c) 2001-2003 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game g_engine ("HL + * g_engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL g_engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + +#ifndef META_API_H +#define META_API_H #include "dllapi.h" // GETENTITYAPI_FN, etc -#include "engine_api.h" // GET_ENGINE_FUNCTIONS_FN, etc +#include "engine_api.h" // GET_ENGINE_FUNCTIONS_FN, etc #include "plinfo.h" // plugin_info_t, etc +#include "mutil.h" // mutil_funcs_t, etc #include "osdep.h" // DLLEXPORT, etc -#include "mutil.h" // Version consists of "major:minor", two separate integer numbers. // Version 1 original @@ -23,48 +60,47 @@ // Version 5:9 added GetGameInfo [v1.14] // Version 5:10 added GINFO_REALDLL_FULLPATH for GetGameInfo [v1.17] // Version 5:11 added plugin loading and unloading API [v1.18] -// Version 5:12 added IS_QUERYING_CLIENT_CVAR to mutils [v1.18] -// Version 5:13 added MAKE_REQUESTID and GET_HOOK_TABLES to mutils [v1.19] +// Version 5:12 added util code for checking player query status [v1.18] +// Version 5:13 added cvarquery2 support and api for calling hook tables [v1.19] #define META_INTERFACE_VERSION "5:13" +#ifdef UNFINISHED +// Version 5:99 added event hook utility functions [v.???] +#define META_INTERFACE_VERSION "5:99" +#endif /* UNFINISHED */ + // Flags returned by a plugin's api function. // NOTE: order is crucial, as greater/less comparisons are made. -enum META_RES -{ +typedef enum { MRES_UNSET = 0, MRES_IGNORED, // plugin didn't take any action MRES_HANDLED, // plugin did something, but real function should still be called MRES_OVERRIDE, // call real function, but use my return value MRES_SUPERCEDE, // skip real function; use my return value -}; +} META_RES; // Variables provided to plugins. -struct meta_globals_t -{ +typedef struct meta_globals_s { META_RES mres; // writable; plugin's return flag META_RES prev_mres; // readable; return flag of the previous plugin called META_RES status; // readable; "highest" return flag so far void *orig_ret; // readable; return value from "real" function void *override_ret; // readable; return value from overriding/superceding plugin -}; +} meta_globals_t; extern meta_globals_t *gpMetaGlobals; -#define SET_META_RESULT(result) gpMetaGlobals->mres = result - +#define SET_META_RESULT(result) gpMetaGlobals->mres=result #define RETURN_META(result) \ - do { gpMetaGlobals->mres = result; return; } while (0) - + do { gpMetaGlobals->mres=result; return; } while(0) #define RETURN_META_VALUE(result, value) \ - do { gpMetaGlobals->mres = result; return value; } while (0) - -#define META_RESULT_STATUS gpMetaGlobals->status + do { gpMetaGlobals->mres=result; return(value); } while(0) +#define META_RESULT_STATUS gpMetaGlobals->status #define META_RESULT_PREVIOUS gpMetaGlobals->prev_mres #define META_RESULT_ORIG_RET(type) *(type *)gpMetaGlobals->orig_ret -#define META_RESULT_OVERRIDE_RET(type) *(type *)gpMetaGlobals->override_ret +#define META_RESULT_OVERRIDE_RET(type) *(type *)gpMetaGlobals->override_ret // Table of getapi functions, retrieved from each plugin. -struct META_FUNCTIONS -{ +typedef struct { GETENTITYAPI_FN pfnGetEntityAPI; GETENTITYAPI_FN pfnGetEntityAPI_Post; GETENTITYAPI2_FN pfnGetEntityAPI2; @@ -73,14 +109,13 @@ struct META_FUNCTIONS GETNEWDLLFUNCTIONS_FN pfnGetNewDLLFunctions_Post; GET_ENGINE_FUNCTIONS_FN pfnGetEngineFunctions; GET_ENGINE_FUNCTIONS_FN pfnGetEngineFunctions_Post; -}; +} META_FUNCTIONS; // Pair of function tables provided by game DLL. -struct gamedll_funcs_t -{ +typedef struct { DLL_FUNCTIONS *dllapi_table; NEW_DLL_FUNCTIONS *newapi_table; -}; +} gamedll_funcs_t; // Declared in plugin; referenced in macros. extern gamedll_funcs_t *gpGamedllFuncs; @@ -91,94 +126,112 @@ extern mutil_funcs_t *gpMetaUtilFuncs; // procedure. In particular, this will allow for DLL's that can be used as // both standalone DLL's and metamod plugins. (optional; not required in // plugin) -C_DLLEXPORT void Meta_Init(); -typedef void (*META_INIT_FN)(); +C_DLLEXPORT void Meta_Init(void); +typedef void (*META_INIT_FN) (void); // Get info about plugin, compare meta_interface versions, provide meta // utility callback functions. -C_DLLEXPORT int Meta_Query(char *interfaceVersion, plugin_info_t **plinfo, mutil_funcs_t *pMetaUtilFuncs); -typedef int (*META_QUERY_FN) (char *interfaceVersion, plugin_info_t **plinfo, mutil_funcs_t *pMetaUtilFuncs); +C_DLLEXPORT int Meta_Query(const char *interfaceVersion, + plugin_info_t **plinfo, + mutil_funcs_t *pMetaUtilFuncs); +typedef int (*META_QUERY_FN) (const char *interfaceVersion, + plugin_info_t **plinfo, + mutil_funcs_t *pMetaUtilFuncs); // Attach the plugin to the API; get the table of getapi functions; give // meta_globals and gamedll_funcs. -C_DLLEXPORT int Meta_Attach(PLUG_LOADTIME now, META_FUNCTIONS *pFunctionTable, meta_globals_t *pMGlobals, gamedll_funcs_t *pGamedllFuncs); -typedef int (*META_ATTACH_FN) (PLUG_LOADTIME now, META_FUNCTIONS *pFunctionTable, meta_globals_t *pMGlobals, gamedll_funcs_t *pGamedllFuncs); +C_DLLEXPORT int Meta_Attach(PLUG_LOADTIME now, + META_FUNCTIONS *pFunctionTable, + meta_globals_t *pMGlobals, + gamedll_funcs_t *pGamedllFuncs); +typedef int (*META_ATTACH_FN) (PLUG_LOADTIME now, + META_FUNCTIONS *pFunctionTable, + meta_globals_t *pMGlobals, + gamedll_funcs_t *pGamedllFuncs); // Detach the plugin; tell why and when. C_DLLEXPORT int Meta_Detach(PLUG_LOADTIME now, PL_UNLOAD_REASON reason); typedef int (*META_DETACH_FN) (PLUG_LOADTIME now, PL_UNLOAD_REASON reason); // Standard HL SDK interface function prototypes. -C_DLLEXPORT int GetEntityAPI_Post(DLL_FUNCTIONS *pFunctionTable, int interfaceVersion ); -C_DLLEXPORT int GetEntityAPI2_Post(DLL_FUNCTIONS *pFunctionTable, int *interfaceVersion ); +C_DLLEXPORT int GetEntityAPI_Post(DLL_FUNCTIONS *pFunctionTable, + int interfaceVersion ); +C_DLLEXPORT int GetEntityAPI2_Post(DLL_FUNCTIONS *pFunctionTable, + int *interfaceVersion ); // Additional SDK-like interface function prototypes. -C_DLLEXPORT int GetNewDLLFunctions_Post(NEW_DLL_FUNCTIONS *pNewFunctionTable, int *interfaceVersion ); -C_DLLEXPORT int GetEngineFunctions(enginefuncs_t *pengfuncsFromEngine, int *interfaceVersion); -C_DLLEXPORT int GetEngineFunctions_Post(enginefuncs_t *pengfuncsFromEngine, int *interfaceVersion); +C_DLLEXPORT int GetNewDLLFunctions_Post(NEW_DLL_FUNCTIONS *pNewFunctionTable, + int *interfaceVersion ); +C_DLLEXPORT int GetEngineFunctions(enginefuncs_t *pengfuncsFromEngine, + int *interfaceVersion); +C_DLLEXPORT int GetEngineFunctions_Post(enginefuncs_t *pengfuncsFromEngine, + int *interfaceVersion); // Convenience macros for accessing GameDLL functions. Note: these talk // _directly_ to the gamedll, and are not multiplexed through Metamod to // the other plugins. // DLL API functions: -#define MDLL_FUNC gpGamedllFuncs->dllapi_table +#define MDLL_FUNC gpGamedllFuncs->dllapi_table -#define MDLL_GameDLLInit MDLL_FUNC->pfnGameInit -#define MDLL_Spawn MDLL_FUNC->pfnSpawn -#define MDLL_Think MDLL_FUNC->pfnThink -#define MDLL_Use MDLL_FUNC->pfnUse -#define MDLL_Touch MDLL_FUNC->pfnTouch -#define MDLL_Blocked MDLL_FUNC->pfnBlocked -#define MDLL_KeyValue MDLL_FUNC->pfnKeyValue -#define MDLL_Save MDLL_FUNC->pfnSave -#define MDLL_Restore MDLL_FUNC->pfnRestore +#define MDLL_GameDLLInit MDLL_FUNC->pfnGameInit +#define MDLL_Spawn MDLL_FUNC->pfnSpawn +#define MDLL_Think MDLL_FUNC->pfnThink +#define MDLL_Use MDLL_FUNC->pfnUse +#define MDLL_Touch MDLL_FUNC->pfnTouch +#define MDLL_Blocked MDLL_FUNC->pfnBlocked +#define MDLL_KeyValue MDLL_FUNC->pfnKeyValue +#define MDLL_Save MDLL_FUNC->pfnSave +#define MDLL_Restore MDLL_FUNC->pfnRestore #define MDLL_ObjectCollsionBox MDLL_FUNC->pfnAbsBox #define MDLL_SaveWriteFields MDLL_FUNC->pfnSaveWriteFields -#define MDLL_SaveReadFields MDLL_FUNC->pfnSaveReadFields +#define MDLL_SaveReadFields MDLL_FUNC->pfnSaveReadFields #define MDLL_SaveGlobalState MDLL_FUNC->pfnSaveGlobalState #define MDLL_RestoreGlobalState MDLL_FUNC->pfnRestoreGlobalState #define MDLL_ResetGlobalState MDLL_FUNC->pfnResetGlobalState -#define MDLL_ClientConnect MDLL_FUNC->pfnClientConnect +#define MDLL_ClientConnect MDLL_FUNC->pfnClientConnect #define MDLL_ClientDisconnect MDLL_FUNC->pfnClientDisconnect -#define MDLL_ClientKill MDLL_FUNC->pfnClientKill +#define MDLL_ClientKill MDLL_FUNC->pfnClientKill #define MDLL_ClientPutInServer MDLL_FUNC->pfnClientPutInServer -#define MDLL_ClientCommand MDLL_FUNC->pfnClientCommand +#define MDLL_ClientCommand MDLL_FUNC->pfnClientCommand #define MDLL_ClientUserInfoChanged MDLL_FUNC->pfnClientUserInfoChanged -#define MDLL_ServerActivate MDLL_FUNC->pfnServerActivate +#define MDLL_ServerActivate MDLL_FUNC->pfnServerActivate #define MDLL_ServerDeactivate MDLL_FUNC->pfnServerDeactivate -#define MDLL_PlayerPreThink MDLL_FUNC->pfnPlayerPreThink +#define MDLL_PlayerPreThink MDLL_FUNC->pfnPlayerPreThink #define MDLL_PlayerPostThink MDLL_FUNC->pfnPlayerPostThink -#define MDLL_StartFrame MDLL_FUNC->pfnStartFrame -#define MDLL_ParmsNewLevel MDLL_FUNC->pfnParmsNewLevel +#define MDLL_StartFrame MDLL_FUNC->pfnStartFrame +#define MDLL_ParmsNewLevel MDLL_FUNC->pfnParmsNewLevel #define MDLL_ParmsChangeLevel MDLL_FUNC->pfnParmsChangeLevel #define MDLL_GetGameDescription MDLL_FUNC->pfnGetGameDescription #define MDLL_PlayerCustomization MDLL_FUNC->pfnPlayerCustomization #define MDLL_SpectatorConnect MDLL_FUNC->pfnSpectatorConnect #define MDLL_SpectatorDisconnect MDLL_FUNC->pfnSpectatorDisconnect -#define MDLL_SpectatorThink MDLL_FUNC->pfnSpectatorThink -#define MDLL_Sys_Error MDLL_FUNC->pfnSys_Error -#define MDLL_PM_Move MDLL_FUNC->pfnPM_Move -#define MDLL_PM_Init MDLL_FUNC->pfnPM_Init +#define MDLL_SpectatorThink MDLL_FUNC->pfnSpectatorThink +#define MDLL_Sys_Error MDLL_FUNC->pfnSys_Error +#define MDLL_PM_Move MDLL_FUNC->pfnPM_Move +#define MDLL_PM_Init MDLL_FUNC->pfnPM_Init #define MDLL_PM_FindTextureType MDLL_FUNC->pfnPM_FindTextureType #define MDLL_SetupVisibility MDLL_FUNC->pfnSetupVisibility #define MDLL_UpdateClientData MDLL_FUNC->pfnUpdateClientData -#define MDLL_AddToFullPack MDLL_FUNC->pfnAddToFullPack -#define MDLL_CreateBaseline MDLL_FUNC->pfnCreateBaseline +#define MDLL_AddToFullPack MDLL_FUNC->pfnAddToFullPack +#define MDLL_CreateBaseline MDLL_FUNC->pfnCreateBaseline #define MDLL_RegisterEncoders MDLL_FUNC->pfnRegisterEncoders -#define MDLL_GetWeaponData MDLL_FUNC->pfnGetWeaponData -#define MDLL_CmdStart MDLL_FUNC->pfnCmdStart -#define MDLL_CmdEnd MDLL_FUNC->pfnCmdEnd +#define MDLL_GetWeaponData MDLL_FUNC->pfnGetWeaponData +#define MDLL_CmdStart MDLL_FUNC->pfnCmdStart +#define MDLL_CmdEnd MDLL_FUNC->pfnCmdEnd #define MDLL_ConnectionlessPacket MDLL_FUNC->pfnConnectionlessPacket -#define MDLL_GetHullBounds MDLL_FUNC->pfnGetHullBounds -#define MDLL_CreateInstancedBaselines MDLL_FUNC->pfnCreateInstancedBaselines +#define MDLL_GetHullBounds MDLL_FUNC->pfnGetHullBounds +#define MDLL_CreateInstancedBaselines MDLL_FUNC->pfnCreateInstancedBaselines #define MDLL_InconsistentFile MDLL_FUNC->pfnInconsistentFile #define MDLL_AllowLagCompensation MDLL_FUNC->pfnAllowLagCompensation // NEW API functions: -#define MNEW_FUNC gpGamedllFuncs->newapi_table +#define MNEW_FUNC gpGamedllFuncs->newapi_table #define MNEW_OnFreeEntPrivateData MNEW_FUNC->pfnOnFreeEntPrivateData -#define MNEW_GameShutdown MNEW_FUNC->pfnGameShutdown -#define MNEW_ShouldCollide MNEW_FUNC->pfnShouldCollide -#define MNEW_CvarValue MNEW_FUNC->pfnCvarValue +#define MNEW_GameShutdown MNEW_FUNC->pfnGameShutdown +#define MNEW_ShouldCollide MNEW_FUNC->pfnShouldCollide +#define MNEW_CvarValue MNEW_FUNC->pfnCvarValue +#define MNEW_CvarValue2 MNEW_FUNC->pfnCvarValue2 + +#endif /* META_API_H */ diff --git a/metamod/src/meta_eiface.cpp b/metamod/src/meta_eiface.cpp index 3be320f..724cfe1 100644 --- a/metamod/src/meta_eiface.cpp +++ b/metamod/src/meta_eiface.cpp @@ -1,12 +1,58 @@ + +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// meta_eiface.cpp - wrapper for engine/dll interface + +/* + * Copyright (c) 2001-2006 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game g_engine ("HL + * g_engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL g_engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + #include "precompiled.h" -// meta_new_dll_functions_t + +// ------------------------------------------------------------------------ +// meta_new_dll_functions_t +// ------------------------------------------------------------------------ + +// static member initialisation +int meta_new_dll_functions_t::sm_version = 0; + + meta_new_dll_functions_t::meta_new_dll_functions_t( - void (*_pfnOnFreeEntPrivateData)(edict_t *), - void (*_pfnGameShutdown) (), - int (*_pfnShouldCollide) (edict_t *, edict_t *), - void (*_pfnCvarValue) (const edict_t *, const char *), - void (*_pfnCvarValue2) (const edict_t *, int, const char *, const char *)) + void (*_pfnOnFreeEntPrivateData)(edict_t*), + void (*_pfnGameShutdown)(void), + int (*_pfnShouldCollide)(edict_t*, edict_t*), + void (*_pfnCvarValue)(const edict_t*, const char*), + void (*_pfnCvarValue2)(const edict_t*, int, const char*, const char*) +) { pfnOnFreeEntPrivateData = _pfnOnFreeEntPrivateData; pfnGameShutdown = _pfnGameShutdown; @@ -15,339 +61,271 @@ meta_new_dll_functions_t::meta_new_dll_functions_t( pfnCvarValue2 = _pfnCvarValue2; } -void meta_new_dll_functions_t::copy_to(NEW_DLL_FUNCTIONS *_pFuncs) + +void meta_new_dll_functions_t::copy_to(NEW_DLL_FUNCTIONS* _pFuncs) { - Q_memcpy(_pFuncs, this, sizeof(NEW_DLL_FUNCTIONS)); + // This is where the magic happens. We check what version of the + // NEW_DLL_FUNCTIONS interface the engine has and calculate the size of + // that interface. Then we only copy the function pointers present in + // that version over to the receiver, so that we do not overwrite his + // memory with functions that he doesn't know of in his copy of the + // struct. + size_t size = get_size(); + + if (0 == size) { + // Ok, this is a real problem and should *not* happen. + // We try to work with NEW_DLL_FUNCTIONS without knowing what + // interface the attached engine uses. This means that the classes + // defined herein are not used in the way they are meant to because + // someone forgot to first create a HL_enginefuncs_t object and + // initialise it with the pointers passed from the engine. + // We treat this as a major developer error and bluntly exit the + // whole process, assuming that this will never happen on a + // production server as it should have been caught by the developer + // during testing. + // + // We use a printf() to complain since we do not know if we have + // already attached to the engine and can use its alerting + // functions. This should be augemnted with a windows version + // popping open a message box. + fprintf(stderr, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); + fprintf(stderr, "ERROR: INTERNAL ERROR.\n"); + fprintf(stderr, " Attempt to use meta_new_dll_functions_t without" + " initialised engine interface version!\n"); + fprintf(stderr, " %s at %d\n", __FILE__, __LINE__); + exit(1); + } + + memcpy(_pFuncs, this, size); } + +int meta_new_dll_functions_t::determine_interface_version(void) +{ + // If the meta_enginefuncs_t::version is 0, i.e. has not yet been + // determined, that is a problem and an error. We should probably throw + // a fit here or something. + // For now we just return 0 and leave it to the caller to complain. + if (meta_enginefuncs_t::version() == 0) return 0; + + // The default version is 1. + sm_version = 1; + + // With the enginefuncs interface version 156 the function + // pfnCvarValue() was added, which we call version 2. + if (meta_enginefuncs_t::version() >= 156) sm_version = 2; + + // With the enginefuncs interface version 157 the function + // pfnCvarValue2() was added, which we call version 3. + if (meta_enginefuncs_t::version() >= 157) sm_version = 3; + + return sm_version; +} + + +size_t meta_new_dll_functions_t::get_size(int _version) +{ + size_t size = sizeof(NEW_DLL_FUNCTIONS); + + if (0 == _version) { + // Use the current engine's interface version + _version = version(); + + // Error: meta_enginefuncs_t::version probably not yet set up. + if (0 == _version) return 0; + } + + switch (_version) { + case 1: + // Version 1 is missing all functions from CvarValue() on. + size -= sizeof(FN_CVARVALUE); + case 2: + // Version 2 is missing all functions from CvarValue2() on. + size -= sizeof(FN_CVARVALUE2); + } + + return size; +} + + +// -------------------------------------------------------------- // meta_enginefuncs_t -meta_enginefuncs_t::meta_enginefuncs_t( - int (*_pfnPrecacheModel) (const char*), - int (*_pfnPrecacheSound) (const char*), - void (*_pfnSetModel) (edict_t*, const char*), - int (*_pfnModelIndex) (const char*), - int (*_pfnModelFrames) (int), - void (*_pfnSetSize) (edict_t*, const float*, const float*), - void (*_pfnChangeLevel) (const char*, const char*), - void (*_pfnGetSpawnParms) (edict_t*), - void (*_pfnSaveSpawnParms) (edict_t*), - float (*_pfnVecToYaw) (const float*), - void (*_pfnVecToAngles) (const float*, float*), - void (*_pfnMoveToOrigin) (edict_t*, const float*, float, int), - void (*_pfnChangeYaw) (edict_t*), - void (*_pfnChangePitch) (edict_t*), - edict_t* (*_pfnFindEntityByString) (edict_t*, const char*, const char*), - int (*_pfnGetEntityIllum) (edict_t*), - edict_t* (*_pfnFindEntityInSphere) (edict_t*, const float*, float), - edict_t* (*_pfnFindClientInPVS) (edict_t*), - edict_t* (*_pfnEntitiesInPVS) (edict_t*), - void (*_pfnMakeVectors) (const float*), - void (*_pfnAngleVectors) (const float*, float*, float*, float*), - edict_t* (*_pfnCreateEntity) (), - void (*_pfnRemoveEntity) (edict_t*), - edict_t* (*_pfnCreateNamedEntity) (int), - void (*_pfnMakeStatic) (edict_t*), - int (*_pfnEntIsOnFloor) (edict_t*), - int (*_pfnDropToFloor) (edict_t*), - int (*_pfnWalkMove) (edict_t*, float, float, int), - void (*_pfnSetOrigin) (edict_t*, const float*), - void (*_pfnEmitSound) (edict_t*, int, const char*, float, float, int, int), - void (*_pfnEmitAmbientSound) (edict_t*, float*, const char*, float, float, int, int), - void (*_pfnTraceLine) (const float*, const float*, int, edict_t*, TraceResult*), - void (*_pfnTraceToss) (edict_t*, edict_t*, TraceResult*), - int (*_pfnTraceMonsterHull) (edict_t*, const float*, const float*, int, edict_t*, TraceResult*), - void (*_pfnTraceHull) (const float*, const float*, int, int, edict_t*, TraceResult*), - void (*_pfnTraceModel) (const float*, const float*, int, edict_t*, TraceResult*), - const char* (*_pfnTraceTexture) (edict_t*, const float*, const float*), - void (*_pfnTraceSphere) (const float*, const float*, int, float, edict_t*, TraceResult*), - void (*_pfnGetAimVector) (edict_t*, float, float*), - void (*_pfnServerCommand) (char*), - void (*_pfnServerExecute) (), - void (*_pfnClientCommand) (edict_t*, char*, ...), - void (*_pfnParticleEffect) (const float*, const float*, float, float), - void (*_pfnLightStyle) (int, char*), - int (*_pfnDecalIndex) (const char*), - int (*_pfnPointContents) (const float*), - void (*_pfnMessageBegin) (int, int, const float*, edict_t*), - void (*_pfnMessageEnd) (), - void (*_pfnWriteByte) (int), - void (*_pfnWriteChar) (int), - void (*_pfnWriteShort) (int), - void (*_pfnWriteLong) (int), - void (*_pfnWriteAngle) (float), - void (*_pfnWriteCoord) (float), - void (*_pfnWriteString) (const char*), - void (*_pfnWriteEntity) (int), - void (*_pfnCVarRegister) (cvar_t*), - float (*_pfnCVarGetFloat) (const char*), - const char* (*_pfnCVarGetString) (const char*), - void (*_pfnCVarSetFloat) (const char*, float), - void (*_pfnCVarSetString) (const char*, const char*), - void (*_pfnAlertMessage) (ALERT_TYPE, const char*, ...), - void (*_pfnEngineFprintf) (void *, const char*, ...), - void* (*_pfnPvAllocEntPrivateData) (edict_t*, int32), - void* (*_pfnPvEntPrivateData) (edict_t*), - void (*_pfnFreeEntPrivateData) (edict_t*), - const char* (*_pfnSzFromIndex) (int), - int (*_pfnAllocString) (const char*), - struct entvars_s*(*_pfnGetVarsOfEnt) (edict_t*), - edict_t* (*_pfnPEntityOfEntOffset) (int), - int (*_pfnEntOffsetOfPEntity) (const edict_t*), - int (*_pfnIndexOfEdict) (const edict_t*), - edict_t* (*_pfnPEntityOfEntIndex) (int), - edict_t* (*_pfnFindEntityByVars) (struct entvars_s*), - void* (*_pfnGetModelPtr) (edict_t*), - int (*_pfnRegUserMsg) (const char*, int), - void (*_pfnAnimationAutomove) (const edict_t*, float), - void (*_pfnGetBonePosition) (const edict_t*, int, float*, float*), - uint32 (*_pfnFunctionFromName) (const char*), - const char* (*_pfnNameForFunction) (uint32), - void (*_pfnClientPrintf) (edict_t*, PRINT_TYPE, const char*), - void (*_pfnServerPrint) (const char*), - const char* (*_pfnCmd_Args) (), - const char* (*_pfnCmd_Argv) (int argc), - int (*_pfnCmd_Argc) (), - void (*_pfnGetAttachment) (const edict_t*, int, float*, float*), - void (*_pfnCRC32_Init) (CRC32_t*), - void (*_pfnCRC32_ProcessBuffer) (CRC32_t*, void*, int), - void (*_pfnCRC32_ProcessByte) (CRC32_t*, unsigned char), - CRC32_t (*_pfnCRC32_Final) (CRC32_t), - int32 (*_pfnRandomLong) (int32, int32), - float (*_pfnRandomFloat) (float, float), - void (*_pfnSetView) (const edict_t*, const edict_t*), - float (*_pfnTime) (), - void (*_pfnCrosshairAngle) (const edict_t*, float, float), - byte* (*_pfnLoadFileForMe) (char*, int*), - void (*_pfnFreeFile) (void*), - void (*_pfnEndSection) (const char*), - int (*_pfnCompareFileTime) (char*, char*, int*), - void (*_pfnGetGameDir) (char*), - void (*_pfnCvar_RegisterVariable) (cvar_t*), - void (*_pfnFadeClientVolume) (const edict_t*, int, int, int, int), - void (*_pfnSetClientMaxspeed) (edict_t*, float), - edict_t* (*_pfnCreateFakeClient) (const char*), - void (*_pfnRunPlayerMove) (edict_t*, const float*, float, float, float, unsigned short, byte, byte), - int (*_pfnNumberOfEntities) (), - char* (*_pfnGetInfoKeyBuffer) (edict_t*), - char* (*_pfnInfoKeyValue) (char*, const char*), - void (*_pfnSetKeyValue) (char*, const char*, const char*), - void (*_pfnSetClientKeyValue) (int, char*, const char*, const char*), - int (*_pfnIsMapValid) (char*), - void (*_pfnStaticDecal) (const float*, int, int, int), - int (*_pfnPrecacheGeneric) (char*), - int (*_pfnGetPlayerUserId) (edict_t*), - void (*_pfnBuildSoundMsg) (edict_t*, int, const char*, float, float, int, int, int, int, const float*, edict_t*), - int (*_pfnIsDedicatedServer) (), - cvar_t* (*_pfnCVarGetPointer) (const char*), - unsigned int (*_pfnGetPlayerWONId) (edict_t*), - void (*_pfnInfo_RemoveKey) (char*, const char*), - const char* (*_pfnGetPhysicsKeyValue) (const edict_t*, const char*), - void (*_pfnSetPhysicsKeyValue) (const edict_t*, const char*, const char*), - const char* (*_pfnGetPhysicsInfoString) (const edict_t*), - unsigned short (*_pfnPrecacheEvent) (int, const char*), - void (*_pfnPlaybackEvent) (int, const edict_t*, unsigned short, float, float*, float*, float, float, int, int, int, int), - unsigned char* (*_pfnSetFatPVS) (float*), - unsigned char* (*_pfnSetFatPAS) (float*), - int (*_pfnCheckVisibility) (edict_t*, unsigned char*), - void (*_pfnDeltaSetField) (struct delta_s*, const char*), - void (*_pfnDeltaUnsetField) (struct delta_s*, const char*), - void (*_pfnDeltaAddEncoder) (char*, void (*)(struct delta_s*, const unsigned char*, const unsigned char*)), - int (*_pfnGetCurrentPlayer) (), - int (*_pfnCanSkipPlayer) (const edict_t*), - int (*_pfnDeltaFindField) (struct delta_s*, const char*), - void (*_pfnDeltaSetFieldByIndex) (struct delta_s*, int), - void (*_pfnDeltaUnsetFieldByIndex) (struct delta_s*, int), - void (*_pfnSetGroupMask) (int, int), - int (*_pfnCreateInstancedBaseline) (int, struct entity_state_s*), - void (*_pfnCvar_DirectSet) (struct cvar_s*, const char*), - void (*_pfnForceUnmodified) (FORCE_TYPE, float*, float*, const char*), - void (*_pfnGetPlayerStats) (const edict_t*, int*, int*), - void (*_pfnAddServerCommand) (char*, void (*) ()), - qboolean (*_pfnVoice_GetClientListening) (int, int), - qboolean (*_pfnVoice_SetClientListening) (int, int, qboolean), - const char* (*_pfnGetPlayerAuthId) (edict_t*), - sequenceEntry_s* (*_pfnSequenceGet) (const char*, const char*), - sentenceEntry_s* (*_pfnSequencePickSentence) (const char*, int, int*), - int (*_pfnGetFileSize) (char*), - unsigned int (*_pfnGetApproxWavePlayLen) (const char*), - int (*_pfnIsCareerMatch) (), - int (*_pfnGetLocalizedStringLength) (const char*), - void (*_pfnRegisterTutorMessageShown) (int), - int (*_pfnGetTimesTutorMessageShown) (int), - void (*_pfnProcessTutorMessageDecayBuffer) (int*, int), - void (*_pfnConstructTutorMessageDecayBuffer)(int*, int), - void (*_pfnResetTutorMessageDecayData) (), - void (*_pfnQueryClientCvarValue) (const edict_t*, const char*), - void (*_pfnQueryClientCvarValue2) (const edict_t*, const char*, int), - int (*_pfnEngCheckParm) (const char*, char**) - ) -{ - pfnPrecacheModel = _pfnPrecacheModel; - pfnPrecacheSound = _pfnPrecacheSound; - pfnSetModel = _pfnSetModel; - pfnModelIndex = _pfnModelIndex; - pfnModelFrames = _pfnModelFrames; - pfnSetSize = _pfnSetSize; - pfnChangeLevel = _pfnChangeLevel; - pfnGetSpawnParms = _pfnGetSpawnParms; - pfnSaveSpawnParms = _pfnSaveSpawnParms; - pfnVecToYaw = _pfnVecToYaw; - pfnVecToAngles = _pfnVecToAngles; - pfnMoveToOrigin = _pfnMoveToOrigin; - pfnChangeYaw = _pfnChangeYaw; - pfnChangePitch = _pfnChangePitch; - pfnFindEntityByString = _pfnFindEntityByString; - pfnGetEntityIllum = _pfnGetEntityIllum; - pfnFindEntityInSphere = _pfnFindEntityInSphere; - pfnFindClientInPVS = _pfnFindClientInPVS; - pfnEntitiesInPVS = _pfnEntitiesInPVS; - pfnMakeVectors = _pfnMakeVectors; - pfnAngleVectors = _pfnAngleVectors; - pfnCreateEntity = _pfnCreateEntity; - pfnRemoveEntity = _pfnRemoveEntity; - pfnCreateNamedEntity = _pfnCreateNamedEntity; - pfnMakeStatic = _pfnMakeStatic; - pfnEntIsOnFloor = _pfnEntIsOnFloor; - pfnDropToFloor = _pfnDropToFloor; - pfnWalkMove = _pfnWalkMove; - pfnSetOrigin = _pfnSetOrigin; - pfnEmitSound = _pfnEmitSound; - pfnEmitAmbientSound = _pfnEmitAmbientSound; - pfnTraceLine = _pfnTraceLine; - pfnTraceToss = _pfnTraceToss; - pfnTraceMonsterHull = _pfnTraceMonsterHull; - pfnTraceHull = _pfnTraceHull; - pfnTraceModel = _pfnTraceModel; - pfnTraceTexture = _pfnTraceTexture; - pfnTraceSphere = _pfnTraceSphere; - pfnGetAimVector = _pfnGetAimVector; - pfnServerCommand = _pfnServerCommand; - pfnServerExecute = _pfnServerExecute; - pfnClientCommand = _pfnClientCommand; - pfnParticleEffect = _pfnParticleEffect; - pfnLightStyle = _pfnLightStyle; - pfnDecalIndex = _pfnDecalIndex; - pfnPointContents = _pfnPointContents; - pfnMessageBegin = _pfnMessageBegin; - pfnMessageEnd = _pfnMessageEnd; - pfnWriteByte = _pfnWriteByte; - pfnWriteChar = _pfnWriteChar; - pfnWriteShort = _pfnWriteShort; - pfnWriteLong = _pfnWriteLong; - pfnWriteAngle = _pfnWriteAngle; - pfnWriteCoord = _pfnWriteCoord; - pfnWriteString = _pfnWriteString; - pfnWriteEntity = _pfnWriteEntity; - pfnCVarRegister = _pfnCVarRegister; - pfnCVarGetFloat = _pfnCVarGetFloat; - pfnCVarGetString = _pfnCVarGetString; - pfnCVarSetFloat = _pfnCVarSetFloat; - pfnCVarSetString = _pfnCVarSetString; - pfnAlertMessage = _pfnAlertMessage; - pfnEngineFprintf = _pfnEngineFprintf; - pfnPvAllocEntPrivateData = _pfnPvAllocEntPrivateData; - pfnPvEntPrivateData = _pfnPvEntPrivateData; - pfnFreeEntPrivateData = _pfnFreeEntPrivateData; - pfnSzFromIndex = _pfnSzFromIndex; - pfnAllocString = _pfnAllocString; - pfnGetVarsOfEnt = _pfnGetVarsOfEnt; - pfnPEntityOfEntOffset = _pfnPEntityOfEntOffset; - pfnEntOffsetOfPEntity = _pfnEntOffsetOfPEntity; - pfnIndexOfEdict = _pfnIndexOfEdict; - pfnPEntityOfEntIndex = _pfnPEntityOfEntIndex; - pfnFindEntityByVars = _pfnFindEntityByVars; - pfnGetModelPtr = _pfnGetModelPtr; - pfnRegUserMsg = _pfnRegUserMsg; - pfnAnimationAutomove = _pfnAnimationAutomove; - pfnGetBonePosition = _pfnGetBonePosition; - pfnFunctionFromName = _pfnFunctionFromName; - pfnNameForFunction = _pfnNameForFunction; - pfnClientPrintf = _pfnClientPrintf; - pfnServerPrint = _pfnServerPrint; - pfnCmd_Args = _pfnCmd_Args; - pfnCmd_Argv = _pfnCmd_Argv; - pfnCmd_Argc = _pfnCmd_Argc; - pfnGetAttachment = _pfnGetAttachment; - pfnCRC32_Init = _pfnCRC32_Init; - pfnCRC32_ProcessBuffer = _pfnCRC32_ProcessBuffer; - pfnCRC32_ProcessByte = _pfnCRC32_ProcessByte; - pfnCRC32_Final = _pfnCRC32_Final; - pfnRandomLong = _pfnRandomLong; - pfnRandomFloat = _pfnRandomFloat; - pfnSetView = _pfnSetView; - pfnTime = _pfnTime; - pfnCrosshairAngle = _pfnCrosshairAngle; - pfnLoadFileForMe = _pfnLoadFileForMe; - pfnFreeFile = _pfnFreeFile; - pfnEndSection = _pfnEndSection; - pfnCompareFileTime = _pfnCompareFileTime; - pfnGetGameDir = _pfnGetGameDir; - pfnCvar_RegisterVariable = _pfnCvar_RegisterVariable; - pfnFadeClientVolume = _pfnFadeClientVolume; - pfnSetClientMaxspeed = _pfnSetClientMaxspeed; - pfnCreateFakeClient = _pfnCreateFakeClient; - pfnRunPlayerMove = _pfnRunPlayerMove; - pfnNumberOfEntities = _pfnNumberOfEntities; - pfnGetInfoKeyBuffer = _pfnGetInfoKeyBuffer; - pfnInfoKeyValue = _pfnInfoKeyValue; - pfnSetKeyValue = _pfnSetKeyValue; - pfnSetClientKeyValue = _pfnSetClientKeyValue; - pfnIsMapValid = _pfnIsMapValid; - pfnStaticDecal = _pfnStaticDecal; - pfnPrecacheGeneric = _pfnPrecacheGeneric; - pfnGetPlayerUserId = _pfnGetPlayerUserId; - pfnBuildSoundMsg = _pfnBuildSoundMsg; - pfnIsDedicatedServer = _pfnIsDedicatedServer; - pfnCVarGetPointer = _pfnCVarGetPointer; - pfnGetPlayerWONId = _pfnGetPlayerWONId; - pfnInfo_RemoveKey = _pfnInfo_RemoveKey; - pfnGetPhysicsKeyValue = _pfnGetPhysicsKeyValue; - pfnSetPhysicsKeyValue = _pfnSetPhysicsKeyValue; - pfnGetPhysicsInfoString = _pfnGetPhysicsInfoString; - pfnPrecacheEvent = _pfnPrecacheEvent; - pfnPlaybackEvent = _pfnPlaybackEvent; - pfnSetFatPVS = _pfnSetFatPVS; - pfnSetFatPAS = _pfnSetFatPAS; - pfnCheckVisibility = _pfnCheckVisibility; - pfnDeltaSetField = _pfnDeltaSetField; - pfnDeltaUnsetField = _pfnDeltaUnsetField; - pfnDeltaAddEncoder = _pfnDeltaAddEncoder; - pfnGetCurrentPlayer = _pfnGetCurrentPlayer; - pfnCanSkipPlayer = _pfnCanSkipPlayer; - pfnDeltaFindField = _pfnDeltaFindField; - pfnDeltaSetFieldByIndex = _pfnDeltaSetFieldByIndex; - pfnDeltaUnsetFieldByIndex = _pfnDeltaUnsetFieldByIndex; - pfnSetGroupMask = _pfnSetGroupMask; - pfnCreateInstancedBaseline = _pfnCreateInstancedBaseline; - pfnCvar_DirectSet = _pfnCvar_DirectSet; - pfnForceUnmodified = _pfnForceUnmodified; - pfnGetPlayerStats = _pfnGetPlayerStats; - pfnAddServerCommand = _pfnAddServerCommand; - pfnVoice_GetClientListening = _pfnVoice_GetClientListening; - pfnVoice_SetClientListening = _pfnVoice_SetClientListening; - pfnGetPlayerAuthId = _pfnGetPlayerAuthId; - pfnSequenceGet = _pfnSequenceGet; - pfnSequencePickSentence = _pfnSequencePickSentence; - pfnGetFileSize = _pfnGetFileSize; - pfnGetApproxWavePlayLen = _pfnGetApproxWavePlayLen; - pfnIsCareerMatch = _pfnIsCareerMatch; - pfnGetLocalizedStringLength = _pfnGetLocalizedStringLength; - pfnRegisterTutorMessageShown = _pfnRegisterTutorMessageShown; - pfnGetTimesTutorMessageShown = _pfnGetTimesTutorMessageShown; - pfnProcessTutorMessageDecayBuffer = _pfnProcessTutorMessageDecayBuffer; - pfnConstructTutorMessageDecayBuffer = _pfnConstructTutorMessageDecayBuffer; - pfnResetTutorMessageDecayData = _pfnResetTutorMessageDecayData; - pfnQueryClientCvarValue = _pfnQueryClientCvarValue; - pfnQueryClientCvarValue2 = _pfnQueryClientCvarValue2; - pfnEngCheckParm = _pfnEngCheckParm; -} +// -------------------------------------------------------------- +// static member initialisation +int meta_enginefuncs_t::sm_version = 0; + +// ----------------------------------------------------------------- // HL_enginefuncs -void HL_enginefuncs_t::initialise_interface(enginefuncs_t *_pFuncs) +// ----------------------------------------------------------------- + +void HL_enginefuncs_t::initialise_interface(enginefuncs_t* _pFuncs) { set_from(_pFuncs); // Now the pfnAlertMessage is available and we trust it to be a valid // pointer, so flush the message buffer. flush_ALERT_buffer(); + + determine_engine_interface_version(); + fixup_engine_interface(); +} + + +// The following part (i.e. the end) of the enginefuncs_t struct is +// used to determine the engine interface version since it is the one +// that changed since SDK 212 engines. We call this the "signature" of +// the enginefuncs interface. +// +// Default version is 138. That's what the SDK says. +// +// 144: const char *(*pfnGetPlayerAuthId) ( edict_t *e ); +// +// // PSV: Added for CZ training map +// // const char *(*pfnKeyNameForBinding) ( const char* pBinding ); +// +// sequenceEntry_s* (*pfnSequenceGet) ( const char* fileName, const char* entryName ); +// sentenceEntry_s* (*pfnSequencePickSentence) ( const char* groupName, int pickMethod, int *picked ); +// +// // LH: Give access to filesize via filesystem +// 147: int (*pfnGetFileSize) ( const char *filename ); +// +// unsigned int (*pfnGetApproxWavePlayLen) (const char *filepath); +// // MDC: Added for CZ career-mode +// int (*pfnIsCareerMatch) ( void ); +// +// // BGC: return the number of characters of the localized string referenced by using "label" +// int (*pfnGetLocalizedStringLength) (const char *label); +// +// // BGC: added to facilitate persistent storage of tutor message decay values for +// // different career game profiles. Also needs to persist regardless of mp.dll being +// // destroyed and recreated. +// void (*pfnRegisterTutorMessageShown) (int mid); +// int (*pfnGetTimesTutorMessageShown) (int mid); +// void (*pfnProcessTutorMessageDecayBuffer) (int *buffer, int bufferLength); +// void (*pfnConstructTutorMessageDecayBuffer) (int *buffer, int bufferLength); +// 155: void (*pfnResetTutorMessageDecayData) ( void ); + +// 156: void (*pfnQueryClientCvarValue) ( const edict_t *player, const char *cvarName ); +// 157: void (*pfnQueryClientCvarValue2) ( const edict_t *player, const char *cvarName, int requestID ); +// 158: int (*pfnCheckParm) ( const char *pchCmdLineToke, char **ppnext ); + + +void HL_enginefuncs_t::determine_engine_interface_version(void) const +{ + // We only need to do this once. + if (0 != sm_version) { + return; + } + + // Now begins our heuristic, where we try to determine the engine + // interface version. + // As alluded to above we are currently only interested, and thus + // only detect, versions 144, 147, 156 or 157 (defined by us). + + // The minimal default is 138. + sm_version = 138; + + // If GetPlayerAuthId() is present, it is at least 144, + // otherwise leave it at the default 138. + // This may give incorrect results for *really* old engine versions, + // i.e. pre 1.1.0.8. We live with that risk. No one uses them anymore. + // Really. + if (pfnGetPlayerAuthId == NULL) { + return; + } + sm_version = 144; + + // The two function pointers for pfnSequenceGet() and + // pfnSequencePickSentence() are only valid in a few engine versions + // and are set to NULL in most other version, so they don't get + // checked. + + // If pfnGetFileSize() is present, it is at least 147, + // otherwise leave it at the so far determined value. + if (pfnGetFileSize == NULL) { + return; + } + sm_version = 147; + + // Now it gets a bit fuzzy. If all of the functions following GetFileSize() + // but before QueryClientCvarValue() are valid, it is at least 155. + // If even one of them is NULL, then our version can't be higher than 147, + // so use 147. Actually, it could be that there exist engine + // versions where one of them is NULL but the interface is still at + // least 155. If such an engine is found in use, adaptions need to be + // made. + // (Yes, I know this could be done with a little hacky for() loop. We + // don't need to do hacky here.) + int cntInvals = 0; + if (pfnGetApproxWavePlayLen == NULL) cntInvals++; + if (pfnIsCareerMatch == NULL) cntInvals++; + if (pfnGetLocalizedStringLength == NULL) cntInvals++; + if (pfnRegisterTutorMessageShown == NULL) cntInvals++; + if (pfnGetTimesTutorMessageShown == NULL) cntInvals++; + if (pfnProcessTutorMessageDecayBuffer == NULL) cntInvals++; + if (pfnConstructTutorMessageDecayBuffer == NULL) cntInvals++; + if (pfnResetTutorMessageDecayData == NULL) cntInvals++; + + if (cntInvals > 0) { + return; + } + sm_version = 155; + + // All functions up to QueryClientCvarValue() are valid. + // If QueryClientCvarValue() is not valid, leave it at the so far + // determined version. Otherwise the version is at least 156. + if (pfnQueryClientCvarValue == NULL) { + return; + } + sm_version = 156; + + // All functions up to QueryClientCvarValue2() are valid. + // If QueryClientCvarValue2() is not valid, leave it at the so far + // determined version. Otherwise the version is at least 157. + if (pfnQueryClientCvarValue2 == NULL) { + return; + } + sm_version = 157; + + // All functions up to CheckParm() are valid. + // If CheckParm() is not valid, leave it at the so far determined + // version. Otherwise the version is at least 158. + if (pfnEngCheckParm == NULL) { + return; + } + sm_version = 158; +} + + +void HL_enginefuncs_t::fixup_engine_interface(void) +{ + // This function will make sure that all function pointers that aren't + // valid are set to NULL, depending on the engine interface version. + // Sometimes a pointer has a valid value although the function doesn't + // exist in the interface version. + + switch (version()) { + case 138: + pfnGetPlayerAuthId = NULL; + case 144: + pfnSequenceGet = NULL; + pfnSequencePickSentence = NULL; + pfnGetFileSize = NULL; + case 147: + pfnGetApproxWavePlayLen = NULL; + pfnIsCareerMatch = NULL; + pfnGetLocalizedStringLength = NULL; + pfnRegisterTutorMessageShown = NULL; + pfnGetTimesTutorMessageShown = NULL; + pfnProcessTutorMessageDecayBuffer = NULL; + pfnConstructTutorMessageDecayBuffer = NULL; + pfnResetTutorMessageDecayData = NULL; + case 155: + pfnQueryClientCvarValue = NULL; + case 156: + pfnQueryClientCvarValue2 = NULL; + case 157: + pfnEngCheckParm = NULL; + } } diff --git a/metamod/src/meta_eiface.h b/metamod/src/meta_eiface.h index e319cf1..6fe134a 100644 --- a/metamod/src/meta_eiface.h +++ b/metamod/src/meta_eiface.h @@ -1,293 +1,288 @@ -#pragma once + +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// meta_eiface.h - wrapper for engine/dll interface + +/* + * Copyright (c) 2001-2006 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game g_engine ("HL + * g_engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL g_engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + +#ifndef MM_META_EIFACE_H +#define MM_META_EIFACE_H + +#include // NEW_DLL_FUNCTIONS, enginefuncs_t + +#include // memset() + + // We use our own versions of the engine/dll interface structs. We add a // few dummy entries to the end and set them to 0. That way we are // protected from updates to the HL SDK adding new functions which would // cause a) the game dll copying arbitrary values from us and b) the game // dll overwriting our memory when using an old Metamod with a new game -// dll. +// dll. +// -------------------------------------------------------------------- // meta_new_dll_functions_t -struct meta_new_dll_functions_t: public NEW_DLL_FUNCTIONS { -public: +// -------------------------------------------------------------------- + +struct meta_new_dll_functions_t : public NEW_DLL_FUNCTIONS +{ meta_new_dll_functions_t(); meta_new_dll_functions_t( - void (*pfnOnFreeEntPrivateData) (edict_t *), - void (*pfnGameShutdown) (), - int (*pfnShouldCollide) (edict_t *, edict_t *), - void (*pfnCvarValue) (const edict_t *, const char *), - void (*pfnCvarValue2) (const edict_t *, int, const char *, const char *) + void (*pfnOnFreeEntPrivateData)(edict_t*), + void (*pfnGameShutdown)(void), + int (*pfnShouldCollide)(edict_t*, edict_t*), + void (*pfnCvarValue)(const edict_t*, const char*), + void (*pfnCvarValue2)(const edict_t*, int, const char*, const char*) ); meta_new_dll_functions_t(const meta_new_dll_functions_t&); meta_new_dll_functions_t& operator=(const meta_new_dll_functions_t&); // Fill this object with pointers copied from a NEW_DLL_FUNCTIONS struct. - void set_from(NEW_DLL_FUNCTIONS *pFuncs); + void set_from(NEW_DLL_FUNCTIONS* pFuncs); // Copy the pointers from this object to a NEW_DLL_FUNCTIONS struct. - void copy_to(NEW_DLL_FUNCTIONS *pFuncs); + void copy_to(NEW_DLL_FUNCTIONS* pFuncs); + + // return the engine's version of NEW_DLL_FUNCTIONS + int version(void); + + +private: + + // data : + + // The NEW_DLL_FUNCTIONS struct also changed, but the version + // number did not change. That begs the question why to have + // it versioned in the first place, but whaddaya know. + // While the official version is left at 1, we internally + // calculate a different version of the engine's NEW_DLL_FUNCTIONS + // struct since we know that the engine lies to us about the + // version that it uses. + // + // The default version is 1. + // + // With the enginefuncs interface version 156 the function + // pfnCvarValue() was added, which we call version 2. + // + // With the enginefuncs interface version 157 the function + // pfnCvarValue2() was added, which we call version 3. + // + // If Valve ever decides to change the version of the + // NEW_DLL_FUNCTIONS interface in the future (haha), + // we are in trouble and will need to change our + // internal versions. + + static int sm_version; + + // functions : + + // Calculates our idea of the engine's version of the + // NEW_DLL_FUNCTIONS interface. Stores this version for future + // reference in m_version and returns it. + static int determine_interface_version(void); + + // Comfort function to determine the size of the NEW_DLL_FUNCTIONS + // struct for the different versions. + // If passed a version number other than 0, the size for that + // specific version is returned. + // If passed 0 as version number (default) the size for the version + // that was determined to be the version of the currently connected + // engine's interface. Should that version have not yet been + // determined (via the enginefuncs_t interface), 0 is returned to + // indicated this error state. + size_t get_size(int version = 0); }; + // Inline functions + inline meta_new_dll_functions_t::meta_new_dll_functions_t() { - Q_memset(this, 0, sizeof(meta_new_dll_functions_t)); + memset(this, 0, sizeof(meta_new_dll_functions_t)); } + inline meta_new_dll_functions_t::meta_new_dll_functions_t(const meta_new_dll_functions_t& _rhs) { - Q_memcpy(this, &_rhs, sizeof(NEW_DLL_FUNCTIONS)); + memcpy(this, &_rhs, sizeof(NEW_DLL_FUNCTIONS)); } + inline meta_new_dll_functions_t& meta_new_dll_functions_t::operator=(const meta_new_dll_functions_t& _rhs) { - Q_memcpy(this, &_rhs, sizeof(NEW_DLL_FUNCTIONS)); + memcpy(this, &_rhs, sizeof(NEW_DLL_FUNCTIONS)); return *this; } + inline void meta_new_dll_functions_t::set_from(NEW_DLL_FUNCTIONS* _pFuncs) { - Q_memcpy(this, _pFuncs, sizeof(NEW_DLL_FUNCTIONS)); + memcpy(this, _pFuncs, sizeof(NEW_DLL_FUNCTIONS)); } + +inline int meta_new_dll_functions_t::version(void) +{ + return sm_version ? sm_version : determine_interface_version(); +} + + +// No meta version of DLL_FUNCTIONS because that won't be changing anymore. + + +// -------------------------------------------------------------------- +// meta_enginefuncs_t +// -------------------------------------------------------------------- + + // meta_enginefuncs_t -struct meta_enginefuncs_t: public enginefuncs_t { -public: - // functions: - meta_enginefuncs_t(); +struct meta_enginefuncs_t : public enginefuncs_t +{ + meta_enginefuncs_t() + { + }; - // Spawn of the devil - meta_enginefuncs_t( - int (*_pfnPrecacheModel)(const char *), - int (*_pfnPrecacheSound)(const char *), - void (*_pfnSetModel)(edict_t *, const char *), - int (*_pfnModelIndex)(const char *), - int (*_pfnModelFrames)(int), - void (*_pfnSetSize)(edict_t *, const float *, const float *), - void (*_pfnChangeLevel)(const char *, const char *), - void (*_pfnGetSpawnParms)(edict_t *), - void (*_pfnSaveSpawnParms)(edict_t *), - float (*_pfnVecToYaw)(const float *), - void (*_pfnVecToAngles)(const float *, float *), - void (*_pfnMoveToOrigin)(edict_t *, const float *, float, int), - void (*_pfnChangeYaw)(edict_t *), - void (*_pfnChangePitch)(edict_t *), - edict_t *(*_pfnFindEntityByString)(edict_t *, const char *, const char *), - int (*_pfnGetEntityIllum)(edict_t *), - edict_t *(*_pfnFindEntityInSphere)(edict_t *, const float *, float), - edict_t *(*_pfnFindClientInPVS)(edict_t *), - edict_t *(*_pfnEntitiesInPVS)(edict_t *), - void (*_pfnMakeVectors)(const float *), - void (*_pfnAngleVectors)(const float *, float *, float *, float *), - edict_t *(*_pfnCreateEntity)(), - void (*_pfnRemoveEntity)(edict_t *), - edict_t *(*_pfnCreateNamedEntity)(int), - - void (*_pfnMakeStatic)(edict_t *), - int (*_pfnEntIsOnFloor)(edict_t *), - int (*_pfnDropToFloor)(edict_t *), - int (*_pfnWalkMove)(edict_t *, float, float, int), - void (*_pfnSetOrigin)(edict_t *, const float *), - void (*_pfnEmitSound)(edict_t *, int, const char *, float, float, int, int), - void (*_pfnEmitAmbientSound)(edict_t *, float *, const char *, float, float, int, int), - void (*_pfnTraceLine)(const float *, const float *, int, edict_t *, TraceResult*), - void (*_pfnTraceToss)(edict_t*, edict_t*, TraceResult *), - int (*_pfnTraceMonsterHull)(edict_t *, const float*, const float*, int, edict_t *, TraceResult *), - void (*_pfnTraceHull)(const float *, const float*, int, int, edict_t*, TraceResult *), - void (*_pfnTraceModel)(const float *, const float*, int, edict_t *, TraceResult *), - const char *(*_pfnTraceTexture)(edict_t *, const float*, const float*), - void (*_pfnTraceSphere)(const float *, const float*, int, float, edict_t*, TraceResult*), - void (*_pfnGetAimVector)(edict_t *, float, float*), - void (*_pfnServerCommand)(char*), - void (*_pfnServerExecute)(), - void (*_pfnClientCommand)(edict_t *, char *, ...), - void (*_pfnParticleEffect)(const float *, const float *, float, float), - void (*_pfnLightStyle)(int, char *), - int (*_pfnDecalIndex)(const char *), - int (*_pfnPointContents)(const float *), - void (*_pfnMessageBegin)(int, int, const float*, edict_t*), - void (*_pfnMessageEnd)(), - - void (*_pfnWriteByte)(int), - void (*_pfnWriteChar)(int), - void (*_pfnWriteShort)(int), - void (*_pfnWriteLong)(int), - void (*_pfnWriteAngle)(float), - void (*_pfnWriteCoord)(float), - void (*_pfnWriteString)(const char *), - void (*_pfnWriteEntity)(int), - void (*_pfnCVarRegister)(cvar_t *), - float (*_pfnCVarGetFloat)(const char *), - const char *(*_pfnCVarGetString)(const char *), - void (*_pfnCVarSetFloat)(const char *, float), - void (*_pfnCVarSetString)(const char *, const char*), - void (*_pfnAlertMessage)(ALERT_TYPE, const char *, ...), - void (*_pfnEngineFprintf)(void *, const char *, ...), - - void *(*_pfnPvAllocEntPrivateData)(edict_t *, int32), - void *(*_pfnPvEntPrivateData)(edict_t *), - void (*_pfnFreeEntPrivateData)(edict_t *), - const char *(*_pfnSzFromIndex)(int), - int (*_pfnAllocString)(const char *), - struct entvars_s*(*_pfnGetVarsOfEnt)(edict_t *), - edict_t *(*_pfnPEntityOfEntOffset)(int), - int (*_pfnEntOffsetOfPEntity)(const edict_t *), - int (*_pfnIndexOfEdict)(const edict_t *), - edict_t *(*_pfnPEntityOfEntIndex)(int), - edict_t *(*_pfnFindEntityByVars)(struct entvars_s *), - void *(*_pfnGetModelPtr)(edict_t *), - int (*_pfnRegUserMsg)(const char *, int), - void (*_pfnAnimationAutomove)(const edict_t *, float), - void (*_pfnGetBonePosition)(const edict_t *, int, float *, float *), - uint32 (*_pfnFunctionFromName)(const char*), - const char *(*_pfnNameForFunction)(uint32), - void (*_pfnClientPrintf)(edict_t *, PRINT_TYPE, const char *), - void (*_pfnServerPrint)(const char *), - const char *(*_pfnCmd_Args)(), - const char *(*_pfnCmd_Argv)(int argc), - int (*_pfnCmd_Argc)(), - void (*_pfnGetAttachment)(const edict_t *, int, float *, float *), - void (*_pfnCRC32_Init)(CRC32_t *), - void (*_pfnCRC32_ProcessBuffer)(CRC32_t *, void *, int), - void (*_pfnCRC32_ProcessByte)(CRC32_t *, unsigned char), - CRC32_t (*_pfnCRC32_Final)(CRC32_t), - int32 (*_pfnRandomLong)(int32, int32), - float (*_pfnRandomFloat)(float, float), - void (*_pfnSetView)(const edict_t *, const edict_t *), - float (*_pfnTime)(), - void (*_pfnCrosshairAngle)(const edict_t *, float, float), - byte *(*_pfnLoadFileForMe)(char *, int *), - void (*_pfnFreeFile)(void *), - - void (*_pfnEndSection)(const char *), - int (*_pfnCompareFileTime)(char *, char *, int *), - void (*_pfnGetGameDir)(char *), - void (*_pfnCvar_RegisterVariable)(cvar_t *), - void (*_pfnFadeClientVolume)(const edict_t *, int, int, int, int), - void (*_pfnSetClientMaxspeed)(edict_t *, float), - edict_t *(*_pfnCreateFakeClient)(const char *), - void (*_pfnRunPlayerMove)(edict_t *, const float *, float, float, float, unsigned short, byte, byte), - int (*_pfnNumberOfEntities)(), - char *(*_pfnGetInfoKeyBuffer)(edict_t *), - char *(*_pfnInfoKeyValue)(char *, const char *), - void (*_pfnSetKeyValue)(char *, const char *, const char *), - void (*_pfnSetClientKeyValue)(int, char *, const char *, const char *), - int (*_pfnIsMapValid)(char *), - void (*_pfnStaticDecal)(const float *, int, int, int), - int (*_pfnPrecacheGeneric)(char *), - int (*_pfnGetPlayerUserId)(edict_t *), - void (*_pfnBuildSoundMsg)(edict_t *, int, const char*, float, float, int, int, int, int, const float *, edict_t *), - int (*_pfnIsDedicatedServer)(), - cvar_t *(*_pfnCVarGetPointer)(const char *), - unsigned int (*_pfnGetPlayerWONId)(edict_t *), - - void (*_pfnInfo_RemoveKey)(char *, const char *), - const char *(*_pfnGetPhysicsKeyValue)(const edict_t *, const char *), - void (*_pfnSetPhysicsKeyValue)(const edict_t *, const char *, const char *), - const char *(*_pfnGetPhysicsInfoString)(const edict_t *), - unsigned short (*_pfnPrecacheEvent)(int, const char *), - void (*_pfnPlaybackEvent)(int, const edict_t *, unsigned short, float, float *, float *, float, float, int, int, int, int), - unsigned char *(*_pfnSetFatPVS)(float *), - unsigned char *(*_pfnSetFatPAS)(float *), - int (*_pfnCheckVisibility)(edict_t *, unsigned char *), - - void (*_pfnDeltaSetField)(struct delta_s *, const char *), - void (*_pfnDeltaUnsetField)(struct delta_s *, const char *), - void (*_pfnDeltaAddEncoder)(char *, void (*)(struct delta_s *, const unsigned char *, const unsigned char *)), - int (*_pfnGetCurrentPlayer)(), - int (*_pfnCanSkipPlayer)(const edict_t *), - int (*_pfnDeltaFindField)(struct delta_s *, const char *), - void (*_pfnDeltaSetFieldByIndex)(struct delta_s *, int), - void (*_pfnDeltaUnsetFieldByIndex)(struct delta_s *, int), - void (*_pfnSetGroupMask)(int, int), - int (*_pfnCreateInstancedBaseline)(int, struct entity_state_s *), - void (*_pfnCvar_DirectSet)(struct cvar_s *, const char *), - - void (*_pfnForceUnmodified)(FORCE_TYPE, float *, float *, const char *), - void (*_pfnGetPlayerStats)(const edict_t *, int *, int *), - void (*_pfnAddServerCommand)(char*, void (*)()), - - qboolean (*_pfnVoice_GetClientListening)(int, int), - qboolean (*_pfnVoice_SetClientListening)(int, int, qboolean), - const char *(*_pfnGetPlayerAuthId)(edict_t *), - sequenceEntry_s *(*_pfnSequenceGet)(const char *, const char *), - sentenceEntry_s *(*_pfnSequencePickSentence)(const char *, int, int *), - int (*_pfnGetFileSize)(char *), - unsigned int (*_pfnGetApproxWavePlayLen)(const char *), - int (*_pfnIsCareerMatch)(), - int (*_pfnGetLocalizedStringLength)(const char *), - void (*_pfnRegisterTutorMessageShown)(int), - int (*_pfnGetTimesTutorMessageShown)(int), - void (*_pfnProcessTutorMessageDecayBuffer)(int*, int), - void (*_pfnConstructTutorMessageDecayBuffer)(int*, int), - void (*_pfnResetTutorMessageDecayData)(), - void (*_pfnQueryClientCvarValue)(const edict_t *, const char *), - void (*_pfnQueryClientCvarValue2)(const edict_t *, const char *, int), - int (*_pfnEngCheckParm)(const char *, char**) - ); - - meta_enginefuncs_t(const meta_enginefuncs_t &); - meta_enginefuncs_t& operator=(const meta_enginefuncs_t &); + meta_enginefuncs_t(enginefuncs_t* pFuncs) + { + set_from(pFuncs); + }; // Fill this object with pointers copied from an enginefuncs_t struct. - void set_from(enginefuncs_t *pFuncs); + void set_from(enginefuncs_t* pFuncs); // Copy the pointers from this object to an enginefuncs_t struct. - void copy_to(enginefuncs_t *pFuncs); + void copy_to(enginefuncs_t* pFuncs); + + // The version of the engine functions interface. It is frozen at 138. But no one knows + // when that was and what it looked like then. So we simply interprete it as the + // number of functions that the enginefuncs struct contains. + // + // That means we get gaps inbetween versions and right now we can detect only + // about five different versions anyway, but that suffices for the current itches + // to get scratched. + // + // The default is hence 138. + // A value of 0 means "not yet determined". + // Other possible versions currently detectable: + // 144: engine versions after 1.1.0.9 build 1996 + // 147: engine versions after build 2384 with pfnGetFileSize() + // 155: all versions between build 2384 and the one + // including pfnQueryClientCvarValue() + // 156: includes pfnQueryClientCvarValue() + // 157: includes pfnQueryClientCvarValue2() + // 158: includes pfnCheckParm() + static int sm_version; + static int version(void); }; -inline meta_enginefuncs_t::meta_enginefuncs_t() +// +// Inline functions +// + +inline void meta_enginefuncs_t::set_from(enginefuncs_t* _pFuncs) { - Q_memset(this, 0, sizeof(meta_enginefuncs_t)); + memcpy(this, _pFuncs, sizeof(enginefuncs_t)); } -inline meta_enginefuncs_t::meta_enginefuncs_t(const meta_enginefuncs_t &_rhs) + +inline void meta_enginefuncs_t::copy_to(enginefuncs_t* _pFuncs) { - Q_memcpy(this, &_rhs, sizeof(enginefuncs_t)); + memcpy(_pFuncs, this, sizeof(enginefuncs_t)); } -inline meta_enginefuncs_t &meta_enginefuncs_t::operator=(const meta_enginefuncs_t &_rhs) + +inline int meta_enginefuncs_t::version(void) { - Q_memcpy(this, &_rhs, sizeof(enginefuncs_t)); - return *this; + return sm_version; } -inline void meta_enginefuncs_t::set_from(enginefuncs_t *_pFuncs) -{ - Q_memcpy(this, _pFuncs, sizeof(enginefuncs_t)); -} - -inline void meta_enginefuncs_t::copy_to(enginefuncs_t *_pFuncs) -{ - Q_memcpy(_pFuncs, this, sizeof(enginefuncs_t)); -} +// -------------------------------------------------------------------- // HL_enginefuncs_t +// -------------------------------------------------------------------- + // // This is a specialisation of the meta_enginefuncs_t struct which is only // used for the initial copy of the engine functions, i.e. those we get -// passed from the HL engine right at the beginning. +// passed from the HL engine right at the beginning. // This specialisation does some extra initialisation when getting set up // like calculating the engine interface version and fixing up any invalid // pointers. // Since there is only one master copy of engine functions this could be // implemented as a singleton. This is left as an option for later. // -struct HL_enginefuncs_t: public meta_enginefuncs_t { -public: - HL_enginefuncs_t(); +struct HL_enginefuncs_t : public meta_enginefuncs_t +{ + // functions : + + HL_enginefuncs_t() + { + }; // Fill this object with pointers copied from an enginefuncs_t struct // and fixup the interface. // For this class this happens in the GiveFptrsToDll() function // with the pointers passed from the HL engine. - void initialise_interface(enginefuncs_t *pFuncs); + void initialise_interface(enginefuncs_t* pFuncs); + private: + + // functions : + // Moving copy_to() and set_from() to the private space. - void set_from(enginefuncs_t *pFuncs) { meta_enginefuncs_t::set_from(pFuncs); }; - void copy_to(enginefuncs_t *pFuncs) { meta_enginefuncs_t::copy_to(pFuncs); }; + void set_from(enginefuncs_t* pFuncs) + { + meta_enginefuncs_t::set_from(pFuncs); + }; + + void copy_to(enginefuncs_t* pFuncs) + { + meta_enginefuncs_t::copy_to(pFuncs); + }; + + + // Determine the version of the engine interface from the + // enginefuncs signature. + void determine_engine_interface_version(void) const; + + // Fixup the enginefuncs pointers according to the determined + // version as some pointers may be invalid. + void fixup_engine_interface(void); }; -inline HL_enginefuncs_t::HL_enginefuncs_t() : meta_enginefuncs_t() {}; + +#endif /* META_EIFACE_H */ + diff --git a/metamod/src/metamod.cpp b/metamod/src/metamod.cpp index 67ed92e..115b567 100644 --- a/metamod/src/metamod.cpp +++ b/metamod/src/metamod.cpp @@ -1,146 +1,188 @@ +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// metamod.cpp - (main) implementation of metamod operations + +/* + * Copyright (c) 2001-2004 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game g_engine ("HL + * g_engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL g_engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + #include "precompiled.h" -cvar_t meta_version = { "metamod_version", APP_VERSION_STRD, FCVAR_SERVER, 0, NULL }; +cvar_t meta_version = {"metamod_version", VVERSION, FCVAR_SERVER , 0, NULL}; MConfig static_config; -MConfig *Config=&static_config; +MConfig* g_config = &static_config; option_t global_options[] = { - { "debuglevel", CF_INT, &Config->debuglevel, "0" }, - { "plugins_file", CF_PATH, &Config->plugins_file, PLUGINS_INI }, - { "exec_cfg", CF_STR, &Config->exec_cfg, EXEC_CFG }, - { "clientmeta", CF_BOOL, &Config->clientmeta, "yes" }, + {"debuglevel", CF_INT, &g_config->debuglevel, "0"}, + {"gamedll", CF_PATH, &g_config->gamedll, NULL}, + {"plugins_file", CF_PATH, &g_config->plugins_file, PLUGINS_INI}, + {"exec_cfg", CF_STR, &g_config->exec_cfg, EXEC_CFG}, // list terminator - { NULL, CF_NONE, NULL, NULL } + {NULL, CF_NONE, NULL, NULL} }; gamedll_t GameDLL; + meta_globals_t PublicMetaGlobals; meta_globals_t PrivateMetaGlobals; + meta_enginefuncs_t g_plugin_engfuncs; -MPluginList *Plugins; -MRegCmdList *RegCmds; -MRegCvarList *RegCvars; -MRegMsgList *RegMsgs; + +MPluginList* g_plugins; +MRegCmdList* g_regCmds; +MRegCvarList* g_regCvars; +MRegMsgList* g_regMsgs; + MPlayerList g_Players; + +unsigned int CALL_API_count = 0; + int requestid_counter = 0; -DLHANDLE metamod_handle; -int metamod_not_loaded = 0; + +#ifdef UNFINISHED +MHookList *Hooks; +#endif /* UNFINISHED */ // Very first metamod function that's run. // Do startup operations... -int metamod_startup() +void metamod_startup(void) { - char *cp, *mmfile = NULL, *cfile = NULL; + const char* mmfile = NULL; + const char* cfile = NULL; + const char* cp; META_CONS(" "); - META_CONS(" Metamod version %s Copyright (c) 2001-2016 Will Day (modification ReHLDS Team)", APP_VERSION_STRD); - META_CONS(" Metamod comes with ABSOLUTELY NO WARRANTY; for details type `meta gpl'."); + META_CONS(" %s version %s Copyright (c) 2001-%s %s", VNAME, VVERSION, COPYRIGHT_YEAR, VAUTHOR); + META_CONS(" %s comes with ABSOLUTELY NO WARRANTY; for details type `meta gpl'.", VNAME); META_CONS(" This is free software, and you are welcome to redistribute it"); META_CONS(" under certain conditions; type `meta gpl' for details."); META_CONS(" "); - META_CONS("Metamod v%s, API (%s)", APP_VERSION_STRD, META_INTERFACE_VERSION); - META_CONS("Metamod build: " __TIME__ " " __DATE__ " (" APP_VERSION_STRD ")"); - META_CONS("Metamod from: " APP_COMMITS_URL APP_COMMIT_ID " " APP_COMMIT_AUTHOR ""); + META_LOG("%s v%s %s", VNAME, VVERSION, VDATE); + META_LOG("by %s", VAUTHOR); + META_LOG(" %s", VURL); + META_LOG("compiled: %s %s (%s)", COMPILE_TIME, COMPILE_TZONE, OPT_TYPE); // If running with "+developer", allow an opportunity to break in with // a debugger. - if ((int)CVAR_GET_FLOAT("developer") != 0) - sleep(1); + if ((int) CVAR_GET_FLOAT("developer") != 0) { + //sleep(10); // TODO: WAT?????? + } + + // specify our new() handler + mm_set_new_handler(); // Get gamedir, very early on, because it seems we need it all over the // place here at the start. - if (!meta_init_gamedll()) - { + if (!meta_init_gamedll()) { META_ERROR("Failure to init game DLL; exiting..."); - return 0; + do_exit(1); } // Register various console commands and cvars. - // Can I do these here, rather than waiting for GameDLLInit() ? + // Can I do these here, rather than waiting for GameDLLInit() ? // Looks like it works okay.. meta_register_cmdcvar(); // Set a slight debug level for developer mode, if debug level not // already set. - if ((int)CVAR_GET_FLOAT("developer") != 0 && (int)meta_debug.value == 0) { - CVAR_SET_FLOAT("meta_debug", (float)(meta_debug_value = 3)); - } + if ((int) CVAR_GET_FLOAT("developer") != 0 && meta_debug.value == 0) + CVAR_SET_FLOAT("meta_debug", 3.0); // Init default values - Config->init(global_options); + g_config->init(global_options); // Find config file - cfile=CONFIG_INI; - if ((cp=LOCALINFO("mm_configfile")) && *cp != '\0') { + cfile = CONFIG_INI; + if ((cp = LOCALINFO("mm_configfile")) && *cp != '\0') { META_LOG("Configfile specified via localinfo: %s", cp); if (valid_gamedir_file(cp)) - cfile=cp; + cfile = cp; else - META_WARNING("Empty/missing config.ini file: %s; falling back to %s", - cp, cfile); + META_ERROR("Empty/missing config.ini file: %s; falling back to %s", + cp, cfile); } // Load config file if (valid_gamedir_file(cfile)) - Config->load(cfile); + g_config->load(cfile); else - META_DEBUG(2, ("No config.ini file found: %s", CONFIG_INI)); + META_DEBUG(2, ("No config.ini file found: %s", CONFIG_INI)); // Now, override config options with localinfo commandline options. - if ((cp=LOCALINFO("mm_debug")) && *cp != '\0') { + if ((cp = LOCALINFO("mm_debug")) && *cp != '\0') { META_LOG("Debuglevel specified via localinfo: %s", cp); - Config->set("debuglevel", cp); + g_config->set("debuglevel", cp); } - if ((cp=LOCALINFO("mm_gamedll")) && *cp != '\0') { + if ((cp = LOCALINFO("mm_gamedll")) && *cp != '\0') { META_LOG("Gamedll specified via localinfo: %s", cp); - Config->set("gamedll", cp); + g_config->set("gamedll", cp); } - if ((cp=LOCALINFO("mm_pluginsfile")) && *cp != '\0') { + if ((cp = LOCALINFO("mm_pluginsfile")) && *cp != '\0') { META_LOG("Pluginsfile specified via localinfo: %s", cp); - Config->set("plugins_file", cp); + g_config->set("plugins_file", cp); } - if ((cp=LOCALINFO("mm_execcfg")) && *cp != '\0') { + if ((cp = LOCALINFO("mm_execcfg")) && *cp != '\0') { META_LOG("Execcfg specified via localinfo: %s", cp); - Config->set("exec_cfg", cp); - } - if ((cp=LOCALINFO("mm_autodetect")) && *cp != '\0') { - META_LOG("Autodetect specified via localinfo: %s", cp); - Config->set("autodetect", cp); - } - if ((cp=LOCALINFO("mm_clientmeta")) && *cp != '\0') { - META_LOG("Clientmeta specified via localinfo: %s", cp); - Config->set("clientmeta", cp); + g_config->set("exec_cfg", cp); } // Check for an initial debug level, since cfg files don't get exec'd // until later. - if (Config->debuglevel != 0) { - CVAR_SET_FLOAT("meta_debug", (float)(meta_debug_value = Config->debuglevel)); - } + if (g_config->debuglevel != 0) + CVAR_SET_FLOAT("meta_debug", g_config->debuglevel); // Prepare for registered commands from plugins. - RegCmds = new MRegCmdList(); - RegCvars = new MRegCvarList(); + g_regCmds = new MRegCmdList(); + g_regCvars = new MRegCvarList(); // Prepare for registered user messages from gamedll. - RegMsgs = new MRegMsgList(); + g_regMsgs = new MRegMsgList(); - // Copy, and store pointer in Engine struct. Yes, we could just store - // the actual engine_t struct in Engine, but then it wouldn't be a + // Copy, and store pointer in g_engine struct. Yes, we could just store + // the actual engine_t struct in g_engine, but then it wouldn't be a // pointer to match the other g_engfuncs. - g_plugin_engfuncs.set_from(Engine.funcs); - Engine.pl_funcs=&g_plugin_engfuncs; + g_plugin_engfuncs.set_from(g_engine.funcs); + g_engine.pl_funcs = &g_plugin_engfuncs; // substitute our special versions of various commands - Engine.pl_funcs->pfnAddServerCommand = meta_AddServerCommand; - Engine.pl_funcs->pfnCVarRegister = meta_CVarRegister; - Engine.pl_funcs->pfnCvar_RegisterVariable = meta_CVarRegister; - Engine.pl_funcs->pfnRegUserMsg = meta_RegUserMsg; - if (IS_VALID_PTR((void*)Engine.pl_funcs->pfnQueryClientCvarValue)) - Engine.pl_funcs->pfnQueryClientCvarValue = meta_QueryClientCvarValue; - else - Engine.pl_funcs->pfnQueryClientCvarValue = NULL; - if (!IS_VALID_PTR((void*)Engine.pl_funcs->pfnQueryClientCvarValue2)) - Engine.pl_funcs->pfnQueryClientCvarValue2 = NULL; + g_engine.pl_funcs->pfnAddServerCommand = meta_AddServerCommand; + g_engine.pl_funcs->pfnCVarRegister = meta_CVarRegister; + g_engine.pl_funcs->pfnCvar_RegisterVariable = meta_CVarRegister; + g_engine.pl_funcs->pfnRegUserMsg = meta_RegUserMsg; + if (g_engine.pl_funcs->pfnQueryClientCvarValue) + g_engine.pl_funcs->pfnQueryClientCvarValue = meta_QueryClientCvarValue; + +#ifdef UNFINISHED + // Init the list of event/logline hooks. + Hooks = new MHookList(); +#endif /* UNFINISHED */ // Before, we loaded plugins before loading the game DLL, so that if no // plugins caught engine functions, we could pass engine funcs straight @@ -154,72 +196,76 @@ int metamod_startup() // // Thus, load gameDLL first, then plugins. // - // However, we have to init the Plugins object first, because if the + // However, we have to init the g_plugins object first, because if the // gamedll calls engine functions during GiveFnptrsToDll (like hpb_bot // does) then it needs to be non-null so META_ENGINE_HANDLE won't crash. // // However, having replaced valid_file with valid_gamedir_file, we need - // to at least initialize the gameDLL to include the gamedir, before + // to at least initialize the gameDLL to include the gamedir, before // looking for plugins.ini. // // In fact, we need gamedir even earlier, so moved up above. // Fall back to old plugins filename, if configured one isn't found. - mmfile=PLUGINS_INI; + mmfile = PLUGINS_INI; if (!valid_gamedir_file(PLUGINS_INI) && valid_gamedir_file(OLD_PLUGINS_INI)) - mmfile=OLD_PLUGINS_INI; - if (valid_gamedir_file(Config->plugins_file)) - mmfile=Config->plugins_file; + mmfile = OLD_PLUGINS_INI; + if (valid_gamedir_file(g_config->plugins_file)) + mmfile = g_config->plugins_file; else - META_WARNING("Plugins file is empty/missing: %s; falling back to %s", - Config->plugins_file, mmfile); + META_ERROR("g_plugins file is empty/missing: %s; falling back to %s", + g_config->plugins_file, mmfile); - Plugins = new MPluginList(mmfile); + g_plugins = new MPluginList(mmfile); if (!meta_load_gamedll()) { META_ERROR("Failure to load game DLL; exiting..."); - return 0; + do_exit(1); } - if (!Plugins->load()) { - META_WARNING("Failure to load plugins..."); + if (!g_plugins->load()) { + META_ERROR("Failure to load plugins..."); // Exit on failure here? Dunno... } +#ifdef UNFINISHED + // Start up the log parsing thread. + startup_logparse_thread(); +#endif /* UNFINISHED */ + // Allow for commands to metamod plugins at startup. Autoexec.cfg is // read too early, and server.cfg is read too late. // // Only attempt load if the file appears to exist and be non-empty, to // avoid confusing users with "couldn't exec exec.cfg" console // messages. - if (valid_gamedir_file(Config->exec_cfg)) - mmfile=Config->exec_cfg; + if (valid_gamedir_file(g_config->exec_cfg)) + mmfile = g_config->exec_cfg; else if (valid_gamedir_file(OLD_EXEC_CFG)) - mmfile=OLD_EXEC_CFG; + mmfile = OLD_EXEC_CFG; else - mmfile=NULL; + mmfile = NULL; if (mmfile) { - if (mmfile[0]=='/') - META_WARNING("Cannot exec absolute pathnames: %s", mmfile); + if (mmfile[0] == '/') + META_ERROR("Cannot exec absolute pathnames: %s", mmfile); else { - char cmd[NAME_MAX]; + char cmd[NAME_MAX ]; META_LOG("Exec'ing metamod exec.cfg: %s...", mmfile); - safevoid_snprintf(cmd, sizeof(cmd), "exec %s\n", mmfile); + snprintf(cmd, sizeof(cmd), "exec %s\n", mmfile); SERVER_COMMAND(cmd); } } - - return 1; } // Set initial GameDLL fields (name, gamedir). // meta_errno values: -// - ME_NULLRESULT getcwd failed -mBOOL meta_init_gamedll() { - char gamedir[PATH_MAX]; - char *cp; +// - ME_NULLRESULT _getcwd failed +mBOOL meta_init_gamedll(void) +{ + char gamedir[PATH_MAX ]; + char* cp; - Q_memset(&GameDLL, 0, sizeof(GameDLL)); + memset(&GameDLL, 0, sizeof(GameDLL)); GET_GAME_DIR(gamedir); normalize_pathname(gamedir); @@ -234,38 +280,32 @@ mBOOL meta_init_gamedll() { // Note: the code has always assumed the server op wouldn't do: // hlds -game other/firearms // - if (is_absolute_path(gamedir)) - { + if (is_absolute_path(gamedir)) { // Old style; GET_GAME_DIR returned full pathname. Copy this into // our gamedir, and truncate to get the game name. // (note check for both linux and win32 full pathname.) - Q_strncpy(GameDLL.gamedir, gamedir, sizeof(GameDLL.gamedir) - 1); - GameDLL.gamedir[sizeof(GameDLL.gamedir) - 1] = '\0'; - - cp = Q_strrchr(gamedir, '/') + 1; - - Q_strncpy(GameDLL.name, cp, sizeof(GameDLL.name) - 1); - GameDLL.name[sizeof(GameDLL.name) - 1] = '\0'; + strncpy(GameDLL.gamedir, gamedir, sizeof GameDLL.gamedir - 1); + GameDLL.gamedir[sizeof GameDLL.gamedir - 1] = '\0'; + cp = strrchr(gamedir, '/') + 1; + strncpy(GameDLL.name, cp, sizeof GameDLL.name - 1); + GameDLL.name[sizeof GameDLL.name - 1] = '\0'; } - else - { + else { // New style; GET_GAME_DIR returned game name. Copy this into our // game name, and prepend the current working directory. - char buf[PATH_MAX]; - if (!getcwd(buf, sizeof(buf))) - { - META_WARNING("dll: Couldn't get cwd; %s", strerror(errno)); + char buf[PATH_MAX ]; + if (!_getcwd(buf, sizeof(buf))) { + META_ERROR("dll: Couldn't get cwd; %s", strerror(errno)); RETURN_ERRNO(mFALSE, ME_NULLRESULT); } - safevoid_snprintf(GameDLL.gamedir, sizeof(GameDLL.gamedir), "%s/%s", buf, gamedir); - - Q_strncpy(GameDLL.name, gamedir, sizeof(GameDLL.name) - 1); - GameDLL.name[sizeof(GameDLL.name) - 1] = '\0'; + snprintf(GameDLL.gamedir, sizeof(GameDLL.gamedir), "%s/%s", buf, gamedir); + strncpy(GameDLL.name, gamedir, sizeof GameDLL.name - 1); + GameDLL.name[sizeof GameDLL.name - 1] = '\0'; } META_DEBUG(3, ("Game: %s", GameDLL.name)); - return mTRUE; + return (mTRUE); } // Load game DLL. @@ -273,9 +313,10 @@ mBOOL meta_init_gamedll() { // - ME_DLOPEN couldn't dlopen game dll file // - ME_DLMISSING couldn't find required routine in game dll // (GiveFnptrsToDll, GetEntityAPI, GetEntityAPI2) -mBOOL meta_load_gamedll() { +mBOOL meta_load_gamedll(void) +{ int iface_vers; - int found=0; + int found = 0; GIVE_ENGINE_FUNCTIONS_FN pfn_give_engfuncs; GETNEWDLLFUNCTIONS_FN pfn_getapinew; @@ -283,15 +324,15 @@ mBOOL meta_load_gamedll() { GETENTITYAPI_FN pfn_getapi; if (!setup_gamedll(&GameDLL)) { - META_WARNING("dll: Unrecognized game: %s", GameDLL.name); + META_ERROR("dll: Unrecognized game: %s", GameDLL.name); // meta_errno should be already set in lookup_game() - return mFALSE; + return (mFALSE); } // open the game DLL - if (!(GameDLL.handle=DLOPEN(GameDLL.pathname))) { - META_WARNING("dll: Couldn't load game DLL %s: %s", GameDLL.pathname, - DLERROR()); + if (!(GameDLL.handle = DLOPEN(GameDLL.pathname))) { + META_ERROR("dll: Couldn't load game DLL %s: %s", GameDLL.pathname, + DLERROR()); RETURN_ERRNO(mFALSE, ME_DLOPEN); } @@ -299,49 +340,41 @@ mBOOL meta_load_gamedll() { // wanted to catch one of the functions, but now that plugins are // dynamically loadable at any time, we have to always pass our table, // so that any plugin loaded later can catch what they need to. - if ((pfn_give_engfuncs = (GIVE_ENGINE_FUNCTIONS_FN) DLSYM(GameDLL.handle, "GiveFnptrsToDll"))) - { - pfn_give_engfuncs(&meta_engfuncs, gpGlobals); - META_DEBUG(3, ("dll: Game '%s': Called GiveFnptrsToDll", - GameDLL.name)); - - //activate linkent-replacement after give_engfuncs so that if game dll is - //plugin too and uses same method we get combined export table of plugin - //and game dll - if (!init_linkent_replacement(metamod_handle, GameDLL.handle)) { - META_WARNING("dll: Couldn't load linkent replacement for game DLL"); - RETURN_ERRNO(mFALSE, ME_DLERROR); - } + if ((pfn_give_engfuncs = (GIVE_ENGINE_FUNCTIONS_FN) DLSYM(GameDLL.handle, + "GiveFnptrsToDll"))) { + pfn_give_engfuncs(&meta_engfuncs, gpGlobals); + META_DEBUG(3, ("dll: Game '%s': Called GiveFnptrsToDll", + GameDLL.name)); } else { - META_WARNING("dll: Couldn't find GiveFnptrsToDll() in game DLL '%s': %s", - GameDLL.name, DLERROR()); + META_ERROR("dll: Couldn't find GiveFnptrsToDll() in game DLL '%s': %s", + GameDLL.name, DLERROR()); RETURN_ERRNO(mFALSE, ME_DLMISSING); } // Yes...another macro. #define GET_FUNC_TABLE_FROM_GAME(gamedll, pfnGetFuncs, STR_GetFuncs, struct_field, API_TYPE, TABLE_TYPE, vers_pass, vers_int, vers_want, gotit) \ - if ((pfnGetFuncs = (API_TYPE) DLSYM(gamedll.handle, STR_GetFuncs))) { \ + if((pfnGetFuncs = (API_TYPE) DLSYM(gamedll.handle, STR_GetFuncs))) { \ gamedll.funcs.struct_field = (TABLE_TYPE*) calloc(1, sizeof(TABLE_TYPE)); \ - if (!gamedll.funcs.struct_field) {\ - META_WARNING("malloc failed for gamedll struct_field: %s", STR_GetFuncs); \ + if(!gamedll.funcs.struct_field) {\ + META_ERROR("malloc failed for gamedll struct_field: %s", STR_GetFuncs); \ } \ - else if (pfnGetFuncs(gamedll.funcs.struct_field, vers_pass)) { \ + else if(pfnGetFuncs(gamedll.funcs.struct_field, vers_pass)) { \ META_DEBUG(3, ("dll: Game '%s': Found %s", gamedll.name, STR_GetFuncs)); \ gotit=1; \ } \ else { \ - META_WARNING("dll: Failure calling %s in game '%s'", STR_GetFuncs, gamedll.name); \ + META_ERROR("dll: Failure calling %s in game '%s'", STR_GetFuncs, gamedll.name); \ free(gamedll.funcs.struct_field); \ gamedll.funcs.struct_field=NULL; \ - if (vers_int != vers_want) { \ - META_WARNING("dll: Interface version didn't match; we wanted %d, they had %d", vers_want, vers_int); \ + if(vers_int != vers_want) { \ + META_ERROR("dll: Interface version didn't match; we wanted %d, they had %d", vers_want, vers_int); \ /* reproduce error from engine */ \ META_CONS("=================="); \ META_CONS("Game DLL version mismatch"); \ META_CONS("DLL version is %d, engine version is %d", vers_int, vers_want); \ - if (vers_int > vers_want) \ - META_CONS("Engine appears to be outdated, check for updates"); \ + if(vers_int > vers_want) \ + META_CONS("g_engine appears to be outdated, check for updates"); \ else \ META_CONS("The game DLL for %s appears to be outdated, check for updates", GameDLL.name); \ META_CONS("=================="); \ @@ -354,30 +387,34 @@ mBOOL meta_load_gamedll() { gamedll.funcs.struct_field=NULL; \ } - // Look for API-NEW interface in Game dll. We do this before API2/API, because + // Look for API-NEW interface in Game dll. We do this before API2/API, because // that's what the engine appears to do.. - iface_vers=NEW_DLL_FUNCTIONS_VERSION; - GET_FUNC_TABLE_FROM_GAME(GameDLL, pfn_getapinew, "GetNewDLLFunctions", newapi_table, GETNEWDLLFUNCTIONS_FN, meta_new_dll_functions_t, &iface_vers, iface_vers, NEW_DLL_FUNCTIONS_VERSION, found); + iface_vers = NEW_DLL_FUNCTIONS_VERSION; + GET_FUNC_TABLE_FROM_GAME(GameDLL, pfn_getapinew, "GetNewDLLFunctions", newapi_table, + GETNEWDLLFUNCTIONS_FN, meta_new_dll_functions_t, + &iface_vers, iface_vers, NEW_DLL_FUNCTIONS_VERSION, found); // Look for API2 interface in plugin; preferred over API-1. - found=0; - iface_vers=INTERFACE_VERSION; - GET_FUNC_TABLE_FROM_GAME(GameDLL, pfn_getapi2, "GetEntityAPI2", dllapi_table, GETENTITYAPI2_FN, DLL_FUNCTIONS, &iface_vers, iface_vers, INTERFACE_VERSION, found); + found = 0; + iface_vers = INTERFACE_VERSION; + GET_FUNC_TABLE_FROM_GAME(GameDLL, pfn_getapi2, "GetEntityAPI2", dllapi_table, + GETENTITYAPI2_FN, DLL_FUNCTIONS, + &iface_vers, iface_vers, INTERFACE_VERSION, found); // Look for API-1 in plugin, if API2 interface wasn't found. - if (!found) - { + if (!found) { found = 0; - GET_FUNC_TABLE_FROM_GAME(GameDLL, pfn_getapi, "GetEntityAPI", dllapi_table, GETENTITYAPI_FN, DLL_FUNCTIONS, INTERFACE_VERSION, INTERFACE_VERSION, INTERFACE_VERSION, found); + GET_FUNC_TABLE_FROM_GAME(GameDLL, pfn_getapi, "GetEntityAPI", dllapi_table, + GETENTITYAPI_FN, DLL_FUNCTIONS, + INTERFACE_VERSION, INTERFACE_VERSION, INTERFACE_VERSION, found); } // If didn't find either, return failure. - if (!found) - { - META_WARNING("dll: Couldn't find either GetEntityAPI nor GetEntityAPI2 in game DLL '%s'", GameDLL.name); + if (!found) { + META_ERROR("dll: Couldn't find either GetEntityAPI nor GetEntityAPI2 in game DLL '%s'", GameDLL.name); RETURN_ERRNO(mFALSE, ME_DLMISSING); } META_LOG("Game DLL for '%s' loaded successfully", GameDLL.desc); - return mTRUE; + return (mTRUE); } diff --git a/metamod/src/metamod.h b/metamod/src/metamod.h index fe1e7ac..4e761fe 100644 --- a/metamod/src/metamod.h +++ b/metamod/src/metamod.h @@ -1,71 +1,109 @@ -#pragma once +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// metamod.h - (main) description of metamod operations + +/* + * Copyright (c) 2001-2003 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game g_engine ("HL + * g_engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL g_engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + +#ifndef METAMOD_H +#define METAMOD_H #include "meta_api.h" // META_RES, etc -#include "mlist.h" // MPluginList, etc -#include "mreg.h" // MRegCmdList, etc +#include "mlist.h" // MPluginList, etc +#include "mreg.h" // MRegCmdList, etc #include "conf_meta.h" // MConfig -#include "osdep.h" // NAME_MAX, etc +#include "osdep.h" // NAME_MAX, etc #include "types_meta.h" // mBOOL -#include "mplayer.h" // MPlayerList -#include "meta_eiface.h" // HL_enginefuncs_t, meta_enginefuncs_t -#include "engine_t.h" // engine_t, Engine +#include "mplayer.h" // MPlayerList +#include "meta_eiface.h" // HL_enginefuncs_t, meta_enginefuncs_t +#include "engine_t.h" // engine_t, g_engine // file that lists plugins to load at startup #define PLUGINS_INI "addons/metamod/plugins.ini" -#define OLD_PLUGINS_INI "metamod.ini" +#define OLD_PLUGINS_INI "metamod.ini" // file that contains commands to metamod plugins at startup #define EXEC_CFG "addons/metamod/exec.cfg" -#define OLD_EXEC_CFG "metaexec.cfg" +#define OLD_EXEC_CFG "metaexec.cfg" // previously, file that contained path for an override-gamedll -#define OLD_GAMEDLL_TXT "metagame.ini" +#define OLD_GAMEDLL_TXT "metagame.ini" // generic config file #define CONFIG_INI "addons/metamod/config.ini" -// metamod module handle -extern DLHANDLE metamod_handle; // cvar to contain version extern cvar_t meta_version; // Info about the game dll/mod. -struct gamedll_t -{ +typedef struct gamedll_s { char name[NAME_MAX]; // ie "cstrike" (from gamedir) - const char *desc; // ie "Counter-Strike" + const char *desc; // ie "Counter-Strike" char gamedir[PATH_MAX]; // ie "/home/willday/half-life/cstrike" char pathname[PATH_MAX]; // ie "/home/willday/half-life/cstrike/dlls/cs_i386.so" - char const *file; // ie "cs_i386.so" + char const *file; // ie "cs_i386.so" char real_pathname[PATH_MAX]; // in case pathname overridden by bot, etc DLHANDLE handle; gamedll_funcs_t funcs; // dllapi_table, newapi_table -}; - +} gamedll_t; extern gamedll_t GameDLL; // SDK variables for storing engine funcs and globals. extern HL_enginefuncs_t g_engfuncs; -extern globalvars_t *gpGlobals; +extern globalvars_t *gpGlobals; // Our modified version of the engine funcs, to give to plugins. extern meta_enginefuncs_t g_plugin_engfuncs; -// Config structure. -extern MConfig *Config; +// g_config structure. +extern MConfig *g_config; // List of plugins loaded/opened/running. -extern MPluginList *Plugins; +extern MPluginList *g_plugins; // List of command functions registered by plugins. -extern MRegCmdList *RegCmds; +extern MRegCmdList *g_regCmds; // List of cvar structures registered by plugins. -extern MRegCvarList *RegCvars; +extern MRegCvarList *g_regCvars; // List of user messages registered by gamedll. -extern MRegMsgList *RegMsgs; +extern MRegMsgList *g_regMsgs; + +#ifdef UNFINISHED +// List of event/logline hooks requested by plugins. +extern MHookList *Hooks; +#endif /* UNFINISHED */ // Data provided to plugins. // Separate copies to prevent plugins from modifying "readable" parts. @@ -74,21 +112,30 @@ extern meta_globals_t PublicMetaGlobals; extern meta_globals_t PrivateMetaGlobals; // hook function tables -extern DLL_FUNCTIONS *g_pHookedDllFunctions; -extern NEW_DLL_FUNCTIONS *g_pHookedNewDllFunctions; +extern DLL_FUNCTIONS *pHookedDllFunctions; +extern NEW_DLL_FUNCTIONS *pHookedNewDllFunctions; -extern int metamod_not_loaded; +// (patch by hullu) +// Safety check for metamod-bot-plugin bugfix. +// engine_api->pfnRunPlayerMove calls dllapi-functions before it returns. +// This causes problems with bots running as metamod plugins, because +// metamod assumed that PublicMetaGlobals is free to be used. +// With call_count we can fix this by backuping up PublicMetaGlobals if +// it's already being used. +extern unsigned int CALL_API_count; +// stores previous requestid counter +extern int requestid_counter; + +// (patch by BAILOPAN) // Holds cached player info, right now only things for querying cvars // Max players is always 32, small enough that we can use a static array extern MPlayerList g_Players; -extern int requestid_counter; +void metamod_startup(void); -int metamod_startup(); - -mBOOL meta_init_gamedll(); -mBOOL meta_load_gamedll(); +mBOOL meta_init_gamedll(void); +mBOOL meta_load_gamedll(void); // ===== lotsa macros... ====================================================== @@ -145,63 +192,235 @@ mBOOL meta_load_gamedll(); // accept. Thus there are "_void" versions of the 5 macros; these are // listed first. -// macros for void-returning functions +// ===== macros for void-returning functions ================================== -// return () +// declare/init some variables +#define SETUP_API_CALLS_void(FN_TYPE, pfnName, api_info_table) \ + int i; \ + META_RES mres=MRES_UNSET, status=MRES_UNSET, prev_mres=MRES_UNSET; \ + MPlugin *iplug; \ + FN_TYPE pfn_routine=NULL; \ + int loglevel=api_info_table.pfnName.loglevel; \ + const char *pfn_string=api_info_table.pfnName.name; \ + meta_globals_t backup_meta_globals; \ + /* fix bug with metamod-bot-plugins (hullu)*/ \ + if (CALL_API_count++>0) \ + /* backup publicmetaglobals */ \ + backup_meta_globals = PublicMetaGlobals; + +// call each plugin +#define CALL_PLUGIN_API_void(post, pfnName, pfn_args, api_table) \ + prev_mres=MRES_UNSET; \ + for(i=0; i < g_plugins->endlist; i++) { \ + iplug=&g_plugins->plist[i]; \ + if (iplug->status != PL_RUNNING) \ + continue; \ + if(iplug->api_table && (pfn_routine=iplug->api_table->pfnName)); \ + else \ + /* plugin doesn't provide this function */ \ + continue; \ + /* initialize PublicMetaGlobals */ \ + PublicMetaGlobals.mres = MRES_UNSET; \ + PublicMetaGlobals.prev_mres = prev_mres; \ + PublicMetaGlobals.status = status; \ + /* call plugin */ \ + META_DEBUG(loglevel, ("Calling %s:%s%s()", iplug->file, pfn_string, (post?"_Post":""))); \ + pfn_routine pfn_args; \ + /* plugin's result code */ \ + mres=PublicMetaGlobals.mres; \ + if(mres > status) \ + status = mres; \ + /* save this for successive plugins to see */ \ + prev_mres = mres; \ + if(mres==MRES_UNSET) \ + META_ERROR("Plugin didn't set meta_result: %s:%s%s()", iplug->file, pfn_string, (post?"_Post":"")); \ + if(post && mres==MRES_SUPERCEDE) \ + META_ERROR("MRES_SUPERCEDE not valid in Post functions: %s:%s%s()", iplug->file, pfn_string, (post?"_Post":"")); \ + } + +// call "real" function, from gamedll +#define CALL_GAME_API_void(pfnName, pfn_args, api_table) \ + CALL_API_count--; \ + if(status==MRES_SUPERCEDE) { \ + META_DEBUG(loglevel, ("Skipped (supercede) %s:%s()", GameDLL.file, pfn_string)); \ + /* don't return here; superceded game routine, but still allow \ + * _post routines to run. \ + */ \ + } \ + else if(GameDLL.funcs.api_table) { \ + pfn_routine=GameDLL.funcs.api_table->pfnName; \ + if(pfn_routine) { \ + META_DEBUG(loglevel, ("Calling %s:%s()", GameDLL.file, pfn_string)); \ + pfn_routine pfn_args; \ + } \ + /* don't complain for NULL routines in NEW_DLL_FUNCTIONS */ \ + else if((void*) GameDLL.funcs.api_table != (void*) GameDLL.funcs.newapi_table) { \ + META_ERROR("Couldn't find api call: %s:%s", GameDLL.file, pfn_string); \ + status=MRES_UNSET; \ + } \ + } \ + else { \ + META_DEBUG(loglevel, ("No api table defined for api call: %s:%s", GameDLL.file, pfn_string)); \ + } \ + CALL_API_count++; + +// call "real" function, from engine +#define CALL_ENGINE_API_void(pfnName, pfn_args) \ + CALL_API_count--; \ + if(status==MRES_SUPERCEDE) { \ + META_DEBUG(loglevel, ("Skipped (supercede) engine:%s()", pfn_string)); \ + /* don't return here; superceded game routine, but still allow \ + * _post routines to run. \ + */ \ + } \ + else { \ + pfn_routine=g_engine.funcs->pfnName; \ + if(pfn_routine) { \ + META_DEBUG(loglevel, ("Calling engine:%s()", pfn_string)); \ + pfn_routine pfn_args; \ + } \ + else { \ + META_ERROR("Couldn't find api call: engine:%s", pfn_string); \ + status=MRES_UNSET; \ + } \ + } \ + CALL_API_count++; + +// return (void) #define RETURN_API_void() \ + if (--CALL_API_count>0) \ + /*restore backup*/ \ + PublicMetaGlobals = backup_meta_globals; \ return; -// macros for type-returning functions + +// ===== macros for type-returning functions ================================== + +// declare/init some variables +#define SETUP_API_CALLS(ret_t, ret_init, FN_TYPE, pfnName, api_info_table) \ + int i; \ + ret_t dllret=ret_init; \ + ret_t override_ret=ret_init; \ + ret_t pub_override_ret=ret_init; \ + ret_t orig_ret=ret_init; \ + ret_t pub_orig_ret=ret_init; \ + META_RES mres=MRES_UNSET, status=MRES_UNSET, prev_mres=MRES_UNSET; \ + MPlugin *iplug; \ + FN_TYPE pfn_routine=NULL; \ + int loglevel=api_info_table.pfnName.loglevel; \ + const char *pfn_string=api_info_table.pfnName.name; \ + meta_globals_t backup_meta_globals; \ + /*Fix bug with metamod-bot-plugins*/ \ + if (CALL_API_count++>0) \ + /*Backup PublicMetaGlobals*/ \ + backup_meta_globals = PublicMetaGlobals; + +// call each plugin +#define CALL_PLUGIN_API(post, ret_init, pfnName, pfn_args, MRES_TYPE, api_table) \ + override_ret=ret_init; \ + prev_mres=MRES_UNSET; \ + for(i=0; i < g_plugins->endlist; i++) { \ + if (g_plugins->plist[i].status != PL_RUNNING) \ + continue; \ + iplug=&g_plugins->plist[i]; \ + if(iplug->api_table && (pfn_routine=iplug->api_table->pfnName)); \ + else \ + /* plugin doesn't provide this function */ \ + continue; \ + /* initialize PublicMetaGlobals */ \ + PublicMetaGlobals.mres = MRES_UNSET; \ + PublicMetaGlobals.prev_mres = prev_mres; \ + PublicMetaGlobals.status = status; \ + pub_orig_ret = orig_ret; \ + PublicMetaGlobals.orig_ret = &pub_orig_ret; \ + if(status==MRES_TYPE) { \ + pub_override_ret = override_ret; \ + PublicMetaGlobals.override_ret = &pub_override_ret; \ + } \ + /* call plugin */ \ + META_DEBUG(loglevel, ("Calling %s:%s%s()", iplug->file, pfn_string, (post?"_Post":""))); \ + dllret=pfn_routine pfn_args; \ + /* plugin's result code */ \ + mres=PublicMetaGlobals.mres; \ + if(mres > status) \ + status = mres; \ + /* save this for successive plugins to see */ \ + prev_mres = mres; \ + if(mres==MRES_TYPE) \ + override_ret = pub_override_ret = dllret; \ + else if(mres==MRES_UNSET) \ + META_ERROR("Plugin didn't set meta_result: %s:%s%s()", iplug->file, pfn_string, (post?"_Post":"")); \ + else if(post && mres==MRES_SUPERCEDE) \ + META_ERROR("MRES_SUPERCEDE not valid in Post functions: %s:%s%s()", iplug->file, pfn_string, (post?"_Post":"")); \ + } + +// call "real" function, from gamedll +#define CALL_GAME_API(pfnName, pfn_args, api_table) \ + CALL_API_count--; \ + if(status==MRES_SUPERCEDE) { \ + META_DEBUG(loglevel, ("Skipped (supercede) %s:%s()", GameDLL.file, pfn_string)); \ + orig_ret = pub_orig_ret = override_ret; \ + PublicMetaGlobals.orig_ret = &pub_orig_ret; \ + /* don't return here; superceded game routine, but still allow \ + * _post routines to run. \ + */ \ + } \ + else if(GameDLL.funcs.api_table) { \ + pfn_routine=GameDLL.funcs.api_table->pfnName; \ + if(pfn_routine) { \ + META_DEBUG(loglevel, ("Calling %s:%s()", GameDLL.file, pfn_string)); \ + dllret=pfn_routine pfn_args; \ + orig_ret = dllret; \ + } \ + /* don't complain for NULL routines in NEW_DLL_FUNCTIONS */ \ + else if((void*) GameDLL.funcs.api_table != (void*) GameDLL.funcs.newapi_table) { \ + META_ERROR("Couldn't find api call: %s:%s", GameDLL.file, pfn_string); \ + status=MRES_UNSET; \ + } \ + } \ + else { \ + META_DEBUG(loglevel, ("No api table defined for api call: %s:%s", GameDLL.file, pfn_string)); \ + } \ + CALL_API_count++; + +// call "real" function, from engine +#define CALL_ENGINE_API(pfnName, pfn_args) \ + CALL_API_count--; \ + if(status==MRES_SUPERCEDE) { \ + META_DEBUG(loglevel, ("Skipped (supercede) engine:%s()", pfn_string)); \ + orig_ret = pub_orig_ret = override_ret; \ + PublicMetaGlobals.orig_ret = &pub_orig_ret; \ + /* don't return here; superceded game routine, but still allow \ + * _post routines to run. \ + */ \ + } \ + else { \ + pfn_routine=g_engine.funcs->pfnName; \ + if(pfn_routine) { \ + META_DEBUG(loglevel, ("Calling engine:%s()", pfn_string)); \ + dllret=pfn_routine pfn_args; \ + orig_ret = dllret; \ + } \ + else { \ + META_ERROR("Couldn't find api call: engine:%s", pfn_string); \ + status=MRES_UNSET; \ + } \ + } \ + CALL_API_count++; // return a value -#define RETURN_API(ret_t) \ - { return GET_RET_CLASS(ret_val, ret_t); } +#define RETURN_API() \ + if (--CALL_API_count>0) \ + /*Restore backup*/ \ + PublicMetaGlobals = backup_meta_globals; \ + if(status==MRES_OVERRIDE) { \ + META_DEBUG(loglevel, ("Returning (override) %s()", pfn_string)); \ + return(override_ret); \ + } \ + else \ + return(orig_ret); -#ifdef META_PERFMON +// ===== end macros =========================================================== -// Api-hook performance monitoring -extern long double total_tsc; -extern unsigned long long count_tsc; -extern unsigned long long active_tsc; -extern unsigned long long min_tsc; -inline unsigned long long GET_TSC() { - union { struct { unsigned int eax, edx; } split; unsigned long long full; } tsc; -#ifdef __GNUC__ - __asm__ __volatile__("rdtsc":"=a"(tsc.split.eax), "=d"(tsc.split.edx)); -#else - __asm - { - rdtsc - mov tsc.split.eax, eax - mov tsc.split.edx, edx - } -#endif - return tsc.full; -} - -#define API_START_TSC_TRACKING() \ - active_tsc = GET_TSC() - -#define API_PAUSE_TSC_TRACKING() \ - total_tsc += GET_TSC() - active_tsc - -#define API_UNPAUSE_TSC_TRACKING() \ - active_tsc = GET_TSC() - -#define API_END_TSC_TRACKING() { \ - unsigned long long run_tsc = GET_TSC() - active_tsc; \ - total_tsc += run_tsc; \ - count_tsc++; \ - if (min_tsc == 0 || run_tsc < min_tsc) \ - min_tsc = run_tsc; \ - } - -#else - -#define API_START_TSC_TRACKING() -#define API_PAUSE_TSC_TRACKING() -#define API_UNPAUSE_TSC_TRACKING() -#define API_END_TSC_TRACKING() - -#endif // META_PERFMON +#endif /* METAMOD_H */ diff --git a/metamod/src/mlist.cpp b/metamod/src/mlist.cpp index ab3ebf4..546f9f1 100644 --- a/metamod/src/mlist.cpp +++ b/metamod/src/mlist.cpp @@ -1,69 +1,68 @@ +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// mlist.cpp - functions for list of plugins (class MPluginList) + +/* + * Copyright (c) 2001-2003 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game g_engine ("HL + * g_engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL g_engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + #include "precompiled.h" // Constructor -MPluginList::MPluginList(const char *ifile) - : size(MAX_PLUGINS), endlist(0) +MPluginList::MPluginList(const char* ifile) : size(MAX_PLUGINS), endlist(0) { // store filename of ini file - Q_strncpy(inifile, ifile, sizeof(inifile) - 1); - inifile[sizeof(inifile) - 1] = '\0'; + strncpy(inifile, ifile, sizeof inifile - 1); + inifile[sizeof inifile - 1] = '\0'; // initialize array - for (int i = 0; i < size; i++) - { - //reset to empty - plist[i].index = i + 1; - reset_plugin(&plist[i]); + memset(plist, 0, sizeof(plist)); + for (int i = 0; i < size; i++) { + plist[i].index = i + 1; // 1-based } - endlist = 0; } -// Resets plugin to empty -void MPluginList::reset_plugin(MPlugin *pl_find) -{ - //calculate index - int i = pl_find - &plist[0]; - - //free any pointers first - pl_find->free_api_pointers(); - - //set zero - Q_memset(pl_find, 0, sizeof(*pl_find)); - - pl_find->index=i+1; // 1-based -} - -// Find a plugin based on the plugin index #. -// meta_errno values: -// - ME_ARGUMENT invalid pindex -// - ME_NOTFOUND couldn't find a matching plugin -MPlugin *MPluginList::find(int pindex) -{ - if (pindex <= 0) - RETURN_ERRNO(NULL, ME_ARGUMENT); - - MPlugin *pfound = &plist[pindex - 1]; - if (pfound->status < PL_VALID) - RETURN_ERRNO(NULL, ME_NOTFOUND); - else - return pfound; -} - // Find a plugin based on the plugin handle. // meta_errno values: // - ME_ARGUMENT invalid pindex // - ME_NOTFOUND couldn't find a matching plugin -MPlugin *MPluginList::find(DLHANDLE handle) +MPlugin* MPluginList::find(DLHANDLE handle) { if (!handle) RETURN_ERRNO(NULL, ME_ARGUMENT); - for (int i = 0; i < endlist; i++) - { + for (int i = 0; i < endlist; i++) { if (plist[i].status < PL_VALID) continue; - if (plist[i].handle == handle) return &plist[i]; } @@ -71,73 +70,34 @@ MPlugin *MPluginList::find(DLHANDLE handle) RETURN_ERRNO(NULL, ME_NOTFOUND); } -// Clear source_plugin_index on all matching plugins -void MPluginList::clear_source_plugin_index(int source_index) +// Find a plugin based on the plugin index #. +// meta_errno values: +// - ME_ARGUMENT invalid pindex +// - ME_NOTFOUND couldn't find a matching plugin +MPlugin* MPluginList::find(int pindex) { - if (source_index <= 0) - return; + if (pindex <= 0) + RETURN_ERRNO(NULL, ME_ARGUMENT); - for (int i = 0; i < endlist; i++) - { - if (plist[i].status < PL_VALID) - continue; - - if (plist[i].source_plugin_index == source_index) - plist[i].source_plugin_index = -1; - } -} - -// Find if any plugin has been loaded by plugin 'source_index' -mBOOL MPluginList::found_child_plugins(int source_index) -{ - if (source_index <= 0) - return mFALSE; - - for (int i = 0; i < endlist; i++) - { - if (plist[i].status < PL_VALID) - continue; - - if (plist[i].source_plugin_index == source_index) - return mTRUE; - } - - return mFALSE; -} - -// Try make endlist lower (called after plugin unload) -void MPluginList::trim_list() -{ - if (endlist <= 0) - return; - - int n = 0; - for (int i = 0; i < endlist; i++) - { - if (plist[i].status == PL_EMPTY) - continue; - - n = i + 1; - } - - if (n < endlist) - endlist = n; + auto pfound = &plist[pindex - 1]; + if (pfound->status < PL_VALID) + RETURN_ERRNO(NULL, ME_NOTFOUND); + else + return pfound; } // Find a plugin with the given plid. // meta_errno values: // - ME_ARGUMENT null plid_t // - ME_NOTFOUND couldn't find a matching plugin -MPlugin *MPluginList::find(plid_t id) +MPlugin* MPluginList::find(plid_t id) { if (!id) RETURN_ERRNO(NULL, ME_ARGUMENT); - for (int i = 0; i < endlist; i++) - { + for (int i = 0; i < endlist; i++) { if (plist[i].status < PL_VALID) continue; - if (plist[i].info == id) return &plist[i]; } @@ -149,20 +109,19 @@ MPlugin *MPluginList::find(plid_t id) // meta_errno values: // - ME_ARGUMENT null path // - ME_NOTFOUND couldn't find a matching plugin -MPlugin *MPluginList::find(const char *findpath) +MPlugin* MPluginList::find(const char* findpath) { if (!findpath) RETURN_ERRNO(NULL, ME_ARGUMENT); META_DEBUG(8, ("Looking for loaded plugin with dlfnamepath: %s", findpath)); - for (int i = 0; i < endlist; i++) - { + + for (int i = 0; i < endlist; i++) { META_DEBUG(9, ("Looking at: plugin %s loadedpath: %s", plist[i].file, plist[i].pathname)); + if (plist[i].status < PL_VALID) continue; - - if (!Q_strcmp(plist[i].pathname, findpath)) - { + if (!strcmp(plist[i].pathname, findpath)) { META_DEBUG(8, ("Found loaded plugin %s", plist[i].file)); return &plist[i]; } @@ -177,270 +136,284 @@ MPlugin *MPluginList::find(const char *findpath) // - ME_ARGUMENT null memptr // - ME_NOTFOUND couldn't find a matching plugin // - errno's from DLFNAME() -MPlugin *MPluginList::find_memloc(void *memptr) +MPlugin* MPluginList::find_memloc(void* memptr) { -#ifdef _WIN32 - DLHANDLE dlhandle; + const char* dlfile; if (!memptr) RETURN_ERRNO(NULL, ME_ARGUMENT); - if (!(dlhandle = get_module_handle_of_memptr(memptr))) - { - META_DEBUG(8, ("DLFNAME failed to find memloc %d", memptr)); - RETURN_ERRNO(NULL, ME_NOTFOUND); - } - - return find(dlhandle); -#else - const char *dlfile; - - if (!memptr) - RETURN_ERRNO(NULL, ME_ARGUMENT); - - if (!(dlfile = DLFNAME(memptr))) - { + if (!(dlfile = DLFNAME(memptr))) { META_DEBUG(8, ("DLFNAME failed to find memloc %d", memptr)); // meta_errno should be already set in DLFNAME return NULL; } - return find(dlfile); -#endif } -// Find a plugin with non-ambiguous prefix string matching desc, file, +// Find a plugin with non-ambiguous prefix string matching desc, file, // name, or logtag. // meta_errno values: // - ME_ARGUMENT null prefix // - ME_NOTFOUND couldn't find a matching plugin // - ME_NOTUNIQ found multiple matches; no unique match -MPlugin *MPluginList::find_match(const char *prefix) +MPlugin* MPluginList::find_match(const char* prefix) { - int len; + int i, len; MPlugin *iplug, *pfound; - char buf[NAME_MAX]; + char buf[NAME_MAX ]; if (!prefix) - RETURN_ERRNO(NULL, ME_ARGUMENT); - - pfound = nullptr; - len = Q_strlen(prefix); - safevoid_snprintf(buf, sizeof(buf), "mm_%s", prefix); - - for (int i = 0; i < endlist; i++) - { + RETURN_ERRNO(NULL, ME_ARGUMENT); + pfound = NULL; + len = strlen(prefix); + snprintf(buf, sizeof(buf), "mm_%s", prefix); + for (i = 0; i < endlist; i++) { iplug = &plist[i]; - if (iplug->status < PL_VALID) continue; - - if (iplug->info && Q_strnicmp(iplug->info->name, prefix, len) == 0) - { + if (iplug->info && _strnicmp(iplug->info->name, prefix, len) == 0) { if (pfound) - RETURN_ERRNO(NULL, ME_NOTUNIQ); + RETURN_ERRNO(NULL, ME_NOTUNIQ); pfound = iplug; continue; } - else if (Q_strnicmp(iplug->desc, prefix, len) == 0) - { + else if (_strnicmp(iplug->desc, prefix, len) == 0) { if (pfound) - RETURN_ERRNO(NULL, ME_NOTUNIQ); + RETURN_ERRNO(NULL, ME_NOTUNIQ); pfound = iplug; continue; } - else if (Q_strnicmp(iplug->file, prefix, len) == 0) - { + else if (_strnicmp(iplug->file, prefix, len) == 0) { if (pfound) - RETURN_ERRNO(NULL, ME_NOTUNIQ); + RETURN_ERRNO(NULL, ME_NOTUNIQ); pfound = iplug; continue; } - else if (Q_strnicmp(iplug->file, buf, Q_strlen(buf)) == 0) - { + else if (_strnicmp(iplug->file, buf, strlen(buf)) == 0) { if (pfound) - RETURN_ERRNO(NULL, ME_NOTUNIQ); + RETURN_ERRNO(NULL, ME_NOTUNIQ); pfound = iplug; continue; } - else if (iplug->info && Q_strnicmp(iplug->info->logtag, prefix, len) == 0) - { + else if (iplug->info + && _strnicmp(iplug->info->logtag, prefix, len) == 0) { if (pfound) - RETURN_ERRNO(NULL, ME_NOTUNIQ); + RETURN_ERRNO(NULL, ME_NOTUNIQ); pfound = iplug; continue; } } - if (pfound) - return pfound; - + return (pfound); + else RETURN_ERRNO(NULL, ME_NOTFOUND); } -// Find a plugin with same file, logtag, desc or significant + +// Find a plugin with same file, logtag, desc or significant // prefix of file. Uses the platform_match() method of MPlugin. // meta_errno values: // - ME_ARGUMENT null prefix // - ME_NOTFOUND couldn't find a matching plugin -MPlugin *MPluginList::find_match(MPlugin *pmatch) +MPlugin* MPluginList::find_match(MPlugin* pmatch) { + int i; MPlugin *iplug, *pfound; if (!pmatch) - RETURN_ERRNO(NULL, ME_ARGUMENT); - - pfound = nullptr; - for (int i = 0; i < endlist; i++) - { + RETURN_ERRNO(NULL, ME_ARGUMENT); + pfound = NULL; + for (i = 0; i < endlist; i++) { iplug = &plist[i]; - if (pmatch->platform_match(iplug)) - { - pfound=iplug; + if (pmatch->platform_match(iplug)) { + pfound = iplug; break; } } if (pfound) - return pfound; - + return (pfound); + else RETURN_ERRNO(NULL, ME_NOTFOUND); } +MPlugin* MPluginList::plugin_addload(plid_t plid, const char* fname, PLUG_LOADTIME now) +{ + MPlugin pl_temp; + MPlugin *pl_found, *pl_added, *pl_loader; + + if (!(pl_loader = find(plid))) { + META_DEBUG(1, ("Couldn't find plugin that gave this loading request!")); + RETURN_ERRNO(NULL, ME_BADREQ); + } + + memset(&pl_temp, 0, sizeof(pl_temp)); + + if (!pl_temp.plugin_parseline(fname, pl_loader->index)) { + RETURN_ERRNO(NULL, ME_NOTFOUND); + } + + if (pl_temp.resolve() != mTRUE) { + META_DEBUG(1, ("Couldn't resolve given path into a file: %s", pl_temp.file)); + RETURN_ERRNO(NULL, ME_NOTFOUND); + } + + if ((pl_found = find(pl_temp.pathname))) { + META_DEBUG(1, ("Plugin '%s' already in current list; file=%s desc='%s'", + pl_temp.file, pl_found->file, pl_found->desc)); + RETURN_ERRNO(NULL, ME_ALREADY); + } + + if (!(pl_added = add(&pl_temp))) { + META_DEBUG(1, ("Couldn't add plugin '%s' to list; see log", pl_temp.desc)); + return NULL; + } + + pl_added->action = PA_LOAD; + if (!pl_added->load(now)) { + if (meta_errno == ME_NOTALLOWED || meta_errno == ME_DELAYED) { + META_DEBUG(1, ("Plugin '%s' couldn't attach; only allowed %s", + pl_added->desc, pl_added->str_loadable(SL_ALLOWED))); + pl_added->clear(); + } + else if (pl_added->status == PL_OPENED) { + META_DEBUG(1, ("Opened plugin '%s', but failed to attach; see log", pl_added->desc)); + } + else { + META_DEBUG(1, ("Couldn't load plugin '%s'; see log", pl_added->desc)); + } + return NULL; + } + + META_DEBUG(1, ("Loaded plugin '%s' successfully", pl_added->desc)); + meta_errno = ME_NOERROR; + + return pl_added; +} + // Add a plugin to the list. // meta_errno values: // - ME_MAXREACHED reached max plugins -MPlugin *MPluginList::add(MPlugin *padd) +MPlugin* MPluginList::add(MPlugin* padd) { int i; - MPlugin *iplug; + MPlugin* iplug; // Find either: // - a slot in the list that's not being used // - the end of the list - for (i = 0; i < endlist && plist[i].status != PL_EMPTY; i++) {} + for (i = 0; i < endlist && plist[i].status != PL_EMPTY; i++); // couldn't find a slot to use - if (i == size) - { - META_WARNING("Couldn't add plugin '%s' to list; reached max plugins (%d)", padd->file, i); + if (i == size) { + META_ERROR("Couldn't add plugin '%s' to list; reached max plugins (%d)", + padd->file, i); RETURN_ERRNO(NULL, ME_MAXREACHED); } // if we found the end of the list, advance end marker if (i == endlist) endlist++; - iplug = &plist[i]; // copy filename into this free slot - Q_strncpy(iplug->filename, padd->filename, sizeof(iplug->filename) - 1); - iplug->filename[sizeof(iplug->filename) - 1] = '\0'; - + strncpy(iplug->filename, padd->filename, sizeof iplug->filename - 1); + iplug->filename[sizeof iplug->filename - 1] = '\0'; // Copy file offset ptr. // Can't just copy ptr, as it points to offset in padd, which will go // away; need to point to corresponding offset in iplug. iplug->file = iplug->filename + (padd->file - padd->filename); - // copy description - Q_strncpy(iplug->desc, padd->desc, sizeof(iplug->desc) - 1); - iplug->desc[sizeof(iplug->desc) - 1] = '\0'; - + strncpy(iplug->desc, padd->desc, sizeof iplug->desc - 1); + iplug->desc[sizeof iplug->desc - 1] = '\0'; // copy pathname - Q_strncpy(iplug->pathname, padd->pathname, sizeof(iplug->pathname) - 1); - iplug->pathname[sizeof(iplug->pathname) - 1] = '\0'; - + strncpy(iplug->pathname, padd->pathname, sizeof iplug->pathname - 1); + iplug->pathname[sizeof iplug->pathname - 1] = '\0'; // copy source iplug->source = padd->source; - - // copy loader-plugin - iplug->source_plugin_index = padd->source_plugin_index; - // copy status iplug->status = padd->status; + //copy other things + iplug->source_plugin_index = padd->source_plugin_index; return iplug; } + // Read plugins.ini at server startup. // meta_errno values: // - ME_NOFILE ini file missing or empty mBOOL MPluginList::ini_startup() { - FILE *fp; + FILE* fp; char line[MAX_STRBUF_LEN]; int n, ln; - MPlugin *pmatch; - if (!valid_gamedir_file(inifile)) - { - META_WARNING("ini: Metamod plugins file empty or missing: %s", inifile); + MPlugin* pmatch; + + if (!valid_gamedir_file(inifile)) { + META_ERROR("ini: Metamod plugins file empty or missing: %s", inifile); RETURN_ERRNO(mFALSE, ME_NOFILE); } - full_gamedir_path(inifile, inifile); fp = fopen(inifile, "r"); - if (!fp) - { - META_WARNING("ini: Unable to open plugins file '%s': %s", inifile, strerror(errno)); + if (!fp) { + META_ERROR("ini: Unable to open plugins file '%s': %s", inifile, + strerror(errno)); RETURN_ERRNO(mFALSE, ME_NOFILE); } META_LOG("ini: Begin reading plugins list: %s", inifile); - for (n = 0, ln = 1; !feof(fp) && fgets(line, sizeof(line), fp) && n < size; ln++) - { + for (n = 0 , ln = 1; + !feof(fp) && fgets(line, sizeof(line), fp) && n < size; + ln++) { // Remove line terminations. - char *cp; - if ((cp = Q_strrchr(line, '\r'))) + char* cp; + if ((cp = strrchr(line, '\r'))) *cp = '\0'; - if ((cp = Q_strrchr(line, '\n'))) + if ((cp = strrchr(line, '\n'))) *cp = '\0'; - // Parse directly into next entry in array - if (!plist[n].ini_parseline(line)) - { + if (!plist[n].ini_parseline(line)) { if (meta_errno == ME_FORMAT) - META_WARNING("ini: Skipping malformed line %d of %s", ln, inifile); + META_ERROR("ini: Skipping malformed line %d of %s", ln, + inifile); continue; } - // Check for a duplicate - an existing entry with this pathname. - if (find(plist[n].pathname)) - { + if (find(plist[n].pathname)) { // Should we check platform specific level here? - META_INFO("ini: Skipping duplicate plugin, line %d of %s: %s", ln, inifile, plist[n].pathname); + META_INFO("ini: Skipping duplicate plugin, line %d of %s: %s", + ln, inifile, plist[n].pathname); continue; } - // Check for a matching platform with different platform specifics // level. - if ((pmatch = find_match(&plist[n]))) - { - 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)); + if (NULL != (pmatch = find_match(&plist[n]))) { + 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)); 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)); - //reset to empty - reset_plugin(pmatch); + 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; + memset(pmatch, 0, sizeof(MPlugin)); + pmatch->index = _index; } - - plist[n].action=PA_LOAD; + plist[n].action = PA_LOAD; META_LOG("ini: Read plugin config for: %s", plist[n].desc); n++; - endlist = n; // mark end of list + endlist = n; // mark end of list } + META_LOG("ini: Finished reading plugins list: %s; Found %d plugins to load", + inifile, n); - META_LOG("ini: Finished reading plugins list: %s; Found %d plugins to load", inifile, n); fclose(fp); - - if (!n) - { - META_WARNING("ini: Warning; no plugins found to load?"); + if (!n) { + META_ERROR("ini: Warning; no plugins found to load?"); } - - return mTRUE; + return (mTRUE); } // Re-read plugins.ini looking for added/deleted/changed plugins. @@ -448,215 +421,117 @@ mBOOL MPluginList::ini_startup() // - ME_NOFILE ini file missing or empty mBOOL MPluginList::ini_refresh() { - FILE *fp; + FILE* fp; char line[MAX_STRBUF_LEN]; int n, ln; MPlugin pl_temp; MPlugin *pl_found, *pl_added; fp = fopen(inifile, "r"); - if (!fp) - { - META_WARNING("ini: Unable to open plugins file '%s': %s", inifile, strerror(errno)); + if (!fp) { + META_ERROR("ini: Unable to open plugins file '%s': %s", inifile, + strerror(errno)); RETURN_ERRNO(mFALSE, ME_NOFILE); } META_LOG("ini: Begin re-reading plugins list: %s", inifile); - for (n = 0, ln = 1; !feof(fp) && fgets(line, sizeof(line), fp) && n < size; ln++) - { + for (n = 0 , ln = 1; + !feof(fp) && fgets(line, sizeof(line), fp) && n < size; + ln++) { // Remove line terminations. - char *cp; - if ((cp = Q_strrchr(line, '\r'))) + char* cp; + if ((cp = strrchr(line, '\r'))) *cp = '\0'; - - if ((cp = Q_strrchr(line, '\n'))) + if ((cp = strrchr(line, '\n'))) *cp = '\0'; - // Parse into a temp plugin - Q_memset(&pl_temp, 0, sizeof(pl_temp)); - if (!pl_temp.ini_parseline(line)) - { + memset(&pl_temp, 0, sizeof(pl_temp)); + if (!pl_temp.ini_parseline(line)) { if (meta_errno == ME_FORMAT) - { - META_WARNING("ini: Skipping malformed line %d of %s", ln, inifile); - } - + META_ERROR("ini: Skipping malformed line %d of %s", + ln, inifile); continue; } // Try to find plugin with this pathname in the current list of // plugins. - if (!(pl_found = find(pl_temp.pathname))) - { + if (!(pl_found = find(pl_temp.pathname))) { // Check for a matching platform with higher platform specifics // level. - if ((pl_found = find_match(&pl_temp))) - { - 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)); + if (NULL != (pl_found = find_match(&pl_temp))) { + 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)); continue; } - 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)); - //reset to empty - reset_plugin(pl_found); + 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)); + int _index = pl_found->index; + memset(pl_found, 0, sizeof(MPlugin)); + pl_found->index = _index; } - 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)); + 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)); continue; } } - // new plugin; add to list - if ((pl_added = add(&pl_temp))) - { + if ((pl_added = add(&pl_temp))) { // try to load this plugin at the next opportunity pl_added->action = PA_LOAD; } else - // error details logged in add() + // error details logged in add() continue; } - else - { + else { // This plugin is already in the current list of plugins. // Pathname already matches. Recopy desc, if specified in // plugins.ini. - if (pl_temp.desc[0] != '<') - { - Q_strncpy(pl_found->desc, pl_temp.desc, sizeof(pl_found->desc) - 1); - pl_found->desc[sizeof(pl_found->desc) - 1] = '\0'; + if (pl_temp.desc[0] != '<') { + strncpy(pl_found->desc, pl_temp.desc, sizeof pl_found->desc - 1); + pl_found->desc[sizeof pl_found->desc - 1] = '\0'; } // Check the file to see if it looks like it's been modified // since we last loaded it. - if (!pl_found->newer_file()) - { - if (meta_errno == ME_NOFILE) - { - META_WARNING("ini: Skipping plugin, couldn't stat file '%s': %s", pl_found->pathname, strerror(errno)); + if (!pl_found->newer_file()) { + if (meta_errno == ME_NOFILE) { + META_ERROR("ini: Skipping plugin, couldn't stat file '%s': %s", + pl_found->pathname, strerror(errno)); continue; } - else - { + else { // File hasn't been updated. // Keep plugin (don't let refresh() unload it). pl_found->action = PA_KEEP; } } // Newer file on disk. - else if (pl_found->status >= PL_OPENED) - { + else if (pl_found->status >= PL_OPENED) { META_DEBUG(2, ("ini: Plugin '%s' has newer file on disk", pl_found->desc)); pl_found->action = PA_RELOAD; } else - META_WARNING("ini: Plugin '%s' has newer file, but unexpected status (%s)", pl_found->desc, pl_found->str_status()); + META_ERROR("ini: Plugin '%s' has newer file, but unexpected status (%s)", + pl_found->desc, pl_found->str_status()); } - if (pl_found) - { + if (NULL != pl_found) { META_LOG("ini: Read plugin config for: %s", pl_found->desc); } - else - { + else { META_LOG("ini: Read plugin config for: %s", pl_temp.desc); } - n++; } - META_LOG("ini: Finished reading plugins list: %s; Found %d plugins", inifile, n); fclose(fp); - if (!n) - { - META_WARNING("ini: Warning; no plugins found to load?"); + if (!n) { + META_ERROR("ini: Warning; no plugins found to load?"); } - - return mTRUE; -} - -// Load a plugin from plugin request. -// meta_errno values: -// - errno's from resolve() -// - ME_ALREADY this plugin already loaded -// - errno's from add() -// - errno's from load() -MPlugin *MPluginList::plugin_addload(plid_t plid, const char *fname, PLUG_LOADTIME now) -{ - MPlugin pl_temp; - MPlugin *pl_found, *pl_added, *pl_loader; - - // Find loader plugin - if (!(pl_loader = find(plid))) - { - // Couldn't find a matching file on disk - META_DEBUG(1, ("Couldn't find plugin that gave this loading request!")); - // meta_errno should be already set in resolve() - RETURN_ERRNO(NULL, ME_BADREQ); - } - - Q_memset(&pl_temp, 0, sizeof(pl_temp)); - - // copy filename - if (!pl_temp.plugin_parseline(fname, pl_loader->index)) - { - // parse_plugin_load doesn't return mFALSE. - RETURN_ERRNO(NULL, ME_NOTFOUND); - } - - // resolve given path into a file; accepts various "shortcut" - // pathnames. - if (pl_temp.resolve() != mTRUE) - { - // Couldn't find a matching file on disk - META_DEBUG(1, ("Couldn't resolve given path into a file: %s", pl_temp.file)); - // meta_errno should be already set in resolve() - RETURN_ERRNO(NULL, ME_NOTFOUND); - } - - // Try to find plugin with this pathname in the current list of - // plugins. - if ((pl_found = find(pl_temp.pathname))) - { - // Already in list - META_DEBUG(1, ("Plugin '%s' already in current list; file=%s desc='%s'", - pl_temp.file, pl_found->file, pl_found->desc)); - RETURN_ERRNO(NULL, ME_ALREADY); - } - - // new plugin; add to list - if (!(pl_added = add(&pl_temp))) - { - META_DEBUG(1, ("Couldn't add plugin '%s' to list; see log", pl_temp.desc)); - // meta_errno should be already set in add() - return NULL; - } - - // try to load new plugin (setting 'must load now') - pl_added->action = PA_LOAD; - if (!pl_added->load(now)) - { - // load failed - if (meta_errno == ME_NOTALLOWED || meta_errno == ME_DELAYED) - { - META_DEBUG(1, ("Plugin '%s' couldn't attach; only allowed %s", - pl_added->desc, pl_added->str_loadable(SL_ALLOWED))); - pl_added->clear(); - } - else if (pl_added->status == PL_OPENED) - META_DEBUG(1, ("Opened plugin '%s', but failed to attach; see log", pl_added->desc)); - else - META_DEBUG(1, ("Couldn't load plugin '%s'; see log", pl_added->desc)); - // meta_errno should be already set in load() - return NULL; - } - - META_DEBUG(1, ("Loaded plugin '%s' successfully", pl_added->desc)); - meta_errno = ME_NOERROR; - return pl_added; + return (mTRUE); } // Load a plugin from a console command. @@ -666,76 +541,69 @@ MPlugin *MPluginList::plugin_addload(plid_t plid, const char *fname, PLUG_LOADTI // - ME_ALREADY this plugin already loaded // - errno's from add() // - errno's from load() -mBOOL MPluginList::cmd_addload(const char *args) +mBOOL MPluginList::cmd_addload(const char* args) { MPlugin pl_temp; MPlugin *pl_found, *pl_added; - Q_memset(&pl_temp, 0, sizeof(pl_temp)); - // XXX move back to comands_meta ? // parse into a temp plugin - if (pl_temp.cmd_parseline(args) != mTRUE) - { + memset(&pl_temp, 0, sizeof(pl_temp)); + if (pl_temp.cmd_parseline(args) != mTRUE) { META_CONS("Couldn't parse 'meta load' arguments: %s", args); // meta_errno should be already set in cmd_parseline() - return mFALSE; + return (mFALSE); } // resolve given path into a file; accepts various "shortcut" // pathnames. - if (pl_temp.resolve() != mTRUE) - { + if (pl_temp.resolve() != mTRUE) { // Couldn't find a matching file on disk META_CONS("Couldn't resolve given path into a file: %s", - pl_temp.file); + pl_temp.file); // meta_errno should be already set in resolve() - return mFALSE; + return (mFALSE); } // Try to find plugin with this pathname in the current list of // plugins. - if ((pl_found=find(pl_temp.pathname))) - { + if ((pl_found = find(pl_temp.pathname))) { // Already in list META_CONS("Plugin '%s' already in current list; file=%s desc='%s'", - pl_temp.file, pl_found->file, pl_found->desc); + pl_temp.file, pl_found->file, pl_found->desc); RETURN_ERRNO(mFALSE, ME_ALREADY); } // new plugin; add to list - if (!(pl_added=add(&pl_temp))) - { + if (!(pl_added = add(&pl_temp))) { META_CONS("Couldn't add plugin '%s' to list; see log", pl_temp.desc); // meta_errno should be already set in add() - return mFALSE; + return (mFALSE); } // try to load new plugin - pl_added->action=PA_LOAD; - if (!pl_added->load(PT_ANYTIME)) - { + pl_added->action = PA_LOAD; + if (!pl_added->load(PT_ANYTIME)) { // load failed - if (meta_errno==ME_DELAYED) - META_CONS("Loaded plugin '%s', but will wait to become active, %s", pl_added->desc, pl_added->str_loadable(SL_ALLOWED)); - else if (meta_errno==ME_NOTALLOWED) - { - META_CONS("Plugin '%s' couldn't attach; only allowed %s", pl_added->desc, pl_added->str_loadable(SL_ALLOWED)); + if (meta_errno == ME_DELAYED) + META_CONS("Loaded plugin '%s', but will wait to become active, %s", + pl_added->desc, pl_added->str_loadable(SL_ALLOWED)); + else if (meta_errno == ME_NOTALLOWED) { + META_CONS("Plugin '%s' couldn't attach; only allowed %s", + pl_added->desc, pl_added->str_loadable(SL_ALLOWED)); pl_added->clear(); } else if (pl_added->status == PL_OPENED) META_CONS("Opened plugin '%s', but failed to attach; see log", pl_added->desc); else META_CONS("Couldn't load plugin '%s'; see log", pl_added->desc); - - show(); + show(0); // meta_errno should be already set in load() - return mFALSE; + return (mFALSE); } - META_CONS("Loaded plugin '%s' successfully", pl_added->desc); - show(); - return mTRUE; + show(0); + return (mTRUE); } // Load plugins at startup. @@ -743,30 +611,26 @@ mBOOL MPluginList::cmd_addload(const char *args) // - errno's from ini_startup() mBOOL MPluginList::load() { - if (!ini_startup()) - { - META_WARNING("Problem loading plugins.ini: %s", inifile); + int i, n; + + if (!ini_startup()) { + META_ERROR("Problem loading plugins.ini: %s", inifile); // meta_errno should be already set in ini_startup() - return mFALSE; + return (mFALSE); } META_LOG("dll: Loading plugins..."); - - int n = 0; - for (int i = 0; i < endlist; i++) - { + for (i = 0 , n = 0; i < endlist; i++) { if (plist[i].status < PL_VALID) continue; - if (plist[i].load(PT_STARTUP) == mTRUE) n++; else - // all plugins should be loadable at startup... - META_WARNING("dll: Failed to load plugin '%s'", plist[i].file); + // all plugins should be loadable at startup... + META_ERROR("dll: Failed to load plugin '%s'", plist[i].file); } - META_LOG("dll: Finished loading %d plugins", n); - return mTRUE; + return (mTRUE); } // Update list of loaded plugins from ini file, and load any new/changed plugins. @@ -775,25 +639,20 @@ mBOOL MPluginList::load() mBOOL MPluginList::refresh(PLUG_LOADTIME now) { int i, ndone = 0, nkept = 0, nloaded = 0, nunloaded = 0, nreloaded = 0, ndelayed = 0; - MPlugin *iplug; + MPlugin* iplug; - if (!ini_refresh()) - { - META_WARNING("dll: Problem reloading plugins.ini: %s", inifile); + if (!ini_refresh()) { + META_ERROR("dll: Problem reloading plugins.ini: %s", inifile); // meta_errno should be already set in ini_refresh() - return mFALSE; + return (mFALSE); } META_LOG("dll: Updating plugins..."); - for (i = 0; i < endlist; i++) - { + for (i = 0; i < endlist; i++) { iplug = &plist[i]; - if (iplug->status < PL_VALID) continue; - - switch (iplug->action) - { + switch (iplug->action) { case PA_KEEP: META_DEBUG(1, ("Keeping plugin '%s'", iplug->desc)); iplug->action = PA_NONE; @@ -801,32 +660,25 @@ mBOOL MPluginList::refresh(PLUG_LOADTIME now) break; case PA_LOAD: META_DEBUG(1, ("Loading plugin '%s'", iplug->desc)); - if (iplug->load(now)) nloaded++; - else if (meta_errno == ME_DELAYED) ndelayed++; break; case PA_RELOAD: META_DEBUG(1, ("Reloading plugin '%s'", iplug->desc)); - if (iplug->reload(now, PNL_FILE_NEWER)) nreloaded++; - else if (meta_errno == ME_DELAYED) ndelayed++; break; case PA_NONE: // If previously loaded from ini, but apparently removed from new ini. - if (iplug->source == PS_INI && iplug->status >= PL_RUNNING) - { + if (iplug->source == PS_INI && iplug->status >= PL_RUNNING) { META_DEBUG(1, ("Unloading plugin '%s'", iplug->desc)); iplug->action = PA_UNLOAD; - if (iplug->unload(now, PNL_INI_DELETED, PNL_INI_DELETED)) nunloaded++; - else if (meta_errno == ME_DELAYED) ndelayed++; } @@ -834,47 +686,42 @@ mBOOL MPluginList::refresh(PLUG_LOADTIME now) case PA_ATTACH: // Previously requested attach, but was delayed? META_DEBUG(1, ("Retrying attach plugin '%s'", iplug->desc)); - if (iplug->retry(now, PNL_DELAYED)) nloaded++; - else if (meta_errno == ME_DELAYED) ndelayed++; break; case PA_UNLOAD: // Previously requested unload, but was delayed? META_DEBUG(1, ("Retrying unload plugin '%s'", iplug->desc)); - if (iplug->retry(now, PNL_DELAYED)) nunloaded++; - else if (meta_errno == ME_DELAYED) ndelayed++; break; case PA_NULL: - META_WARNING("dll: Unexpected action for plugin '%s': '%s'", iplug->desc, iplug->str_action()); + META_ERROR("dll: Unexpected action for plugin '%s': '%s'", iplug->desc, iplug->str_action()); break; default: - META_WARNING("dll: Unrecognized action for plugin '%s': '%s'", iplug->desc, iplug->str_action()); + META_ERROR("dll: Unrecognized action for plugin '%s': '%s'", iplug->desc, iplug->str_action()); break; } ndone++; } - - META_LOG("dll: Finished updating %d plugins; kept %d, loaded %d, unloaded %d, reloaded %d, delayed %d", ndone, nkept, nloaded, nunloaded, nreloaded, ndelayed); - return mTRUE; + META_LOG("dll: Finished updating %d plugins; kept %d, loaded %d, unloaded %d, reloaded %d, delayed %d", + ndone, nkept, nloaded, nunloaded, nreloaded, ndelayed); + return (mTRUE); } // Re-enable any plugins currently paused. // meta_errno values: // - none -void MPluginList::unpause_all() +void MPluginList::unpause_all(void) { - MPlugin *iplug; - for (int i = 0; i < endlist; i++) - { + int i; + MPlugin* iplug; + for (i = 0; i < endlist; i++) { iplug = &plist[i]; - if (iplug->status == PL_PAUSED) iplug->unpause(); } @@ -886,11 +733,10 @@ void MPluginList::unpause_all() // - none void MPluginList::retry_all(PLUG_LOADTIME now) { - MPlugin *iplug; - for (int i = 0; i < endlist; i++) - { + int i; + MPlugin* iplug; + for (i = 0; i < endlist; i++) { iplug = &plist[i]; - if (iplug->action != PA_NONE) iplug->retry(now, PNL_DELAYED); } @@ -901,83 +747,109 @@ void MPluginList::retry_all(PLUG_LOADTIME now) // - none void MPluginList::show(int source_index) { - int n = 0, r = 0; - MPlugin *pl; - char desc[15 + 1], file[16 + 1], vers[7 + 1]; // plus 1 for term null + int i, n = 0, r = 0; + MPlugin* pl; + char desc[15 + 1], file[16 + 1], vers[7 + 1]; // plus 1 for term null if (source_index <= 0) META_CONS("Currently loaded plugins:"); else META_CONS("Child plugins:"); - META_CONS(" %*s %-*s %-4s %-4s %-*s v%-*s %-*s %-5s %-5s", WIDTH_MAX_PLUGINS, "", sizeof(desc) - 1, "description", "stat", "pend", - sizeof(file) - 1, "file", sizeof(vers) - 1, "ers", 2 + WIDTH_MAX_PLUGINS, "src", "load ", "unlod"); - - for (int i = 0; i < endlist; i++) - { + META_CONS(" %*s %-*s %-4s %-4s %-*s v%-*s %-3s %-5s %-5s", + WIDTH_MAX_PLUGINS, "", + sizeof(desc) - 1, "description", + "stat", "pend", + sizeof(file) - 1, "file", sizeof(vers) - 1, "ers", + "src", "load ", "unlod"); + for (i = 0; i < endlist; i++) { pl = &plist[i]; if (pl->status < PL_VALID) continue; - - if (source_index > 0 && pl->source_plugin_index != source_index) + if ((source_index > 0) && (pl->source_plugin_index != source_index)) continue; - - Q_strncpy(desc, pl->desc, sizeof(desc) - 1); - desc[sizeof(desc) - 1] = '\0'; - - Q_strncpy(file, pl->file, sizeof(file) - 1); - file[sizeof(file) - 1] = '\0'; - - if (pl->info && pl->info->version) - { - Q_strncpy(vers, pl->info->version, sizeof(vers) - 1); - vers[sizeof(vers) - 1] = '\0'; + strncpy(desc, pl->desc, sizeof desc - 1); + desc[sizeof desc - 1] = '\0'; + strncpy(file, pl->file, sizeof file - 1); + file[sizeof file - 1] = '\0'; + if (pl->info && pl->info->version) { + strncpy(vers, pl->info->version, sizeof vers - 1); + vers[sizeof vers - 1] = '\0'; } - else - { - Q_strncpy(vers, " -", sizeof(vers) - 1); - vers[sizeof(vers) - 1] = '\0'; + else { + strncpy(vers, " -", sizeof vers - 1); + vers[sizeof vers - 1] = '\0'; } - - META_CONS(" [%*d] %-*s %-4s %-4s %-*s v%-*s %-*s %-5s %-5s", WIDTH_MAX_PLUGINS, pl->index, - sizeof(desc) - 1, desc, pl->str_status(ST_SHOW), pl->str_action(SA_SHOW), sizeof(file) - 1, file, sizeof(vers) - 1, vers, - 2 + WIDTH_MAX_PLUGINS, pl->str_source(SO_SHOW), pl->str_loadable(SL_SHOW), pl->str_unloadable(SL_SHOW)); - + META_CONS(" [%*d] %-*s %-4s %-4s %-*s v%-*s %-3s %-5s %-5s", + WIDTH_MAX_PLUGINS, pl->index, + sizeof(desc) - 1, desc, + pl->str_status(ST_SHOW), pl->str_action(SA_SHOW), + sizeof(file) - 1, file, sizeof(vers) - 1, vers, + pl->str_source(SO_SHOW), + pl->str_loadable(SL_SHOW), pl->str_unloadable(SL_SHOW)); if (pl->status == PL_RUNNING) r++; n++; } - META_CONS("%d plugins, %d running", n, r); } // List plugins and information to Player/client entity. Differs from the // "meta list" console command in that: // - Shows only "running" plugins, skipping any failed or paused plugins. -// - Limited info about each plugin, mostly the "public" info (name, author, +// - Limited info about each plugin, mostly the "public" info (name, author, // etc). // meta_errno values: // - none -void MPluginList::show_client(edict_t *pEntity) +void MPluginList::show_client(edict_t* pEntity) { - int n = 0; - MPlugin *pl; + int i, n = 0; + MPlugin* pl; META_CLIENT(pEntity, "Currently running plugins:"); - - for (int i = 0; i < endlist; i++) - { + for (i = 0; i < endlist; i++) { pl = &plist[i]; - if (pl->status != PL_RUNNING || !pl->info) + if (pl->status != PL_RUNNING) continue; - n++; - META_CLIENT(pEntity, " [%3d] %s, v%s, %s, by %s, see %s", n, - pl->info->name ? pl->info->name : "", - pl->info->version ? pl->info->version : "", - pl->info->date ? pl->info->date : "<../../..>", - pl->info->author ? pl->info->author : "", - pl->info->url ? pl->info->url : ""); + META_CLIENT(pEntity, " [%3d] %s, v%s, %s, by %s, see %s", + n, + pl->info->name ? pl->info->name : "", + pl->info->version ? pl->info->version : "", + pl->info->date ? pl->info->date : "<../../..>", + pl->info->author ? pl->info->author : "", + pl->info->url ? pl->info->url : ""); } - META_CLIENT(pEntity, "%d plugins", n); } + +mBOOL MPluginList::found_child_plugins(int source_index) +{ + int i; + + if (source_index <= 0) + return mFALSE; + + for (i = 0; i < endlist; i++) { + if (plist[i].status < PL_VALID) + continue; + if (plist[i].source_plugin_index == source_index) + return mTRUE; + } + + return mFALSE; +} + +void MPluginList::clear_source_plugin_index(int source_index) +{ + int i; + + if (source_index <= 0) + return; + + for (i = 0; i < endlist; i++) { + if (plist[i].status < PL_VALID) + continue; + if (plist[i].source_plugin_index == source_index) + plist[i].source_plugin_index = -1; + } +} diff --git a/metamod/src/mlist.h b/metamod/src/mlist.h index 45f6f94..c045ce0 100644 --- a/metamod/src/mlist.h +++ b/metamod/src/mlist.h @@ -1,50 +1,90 @@ -#pragma once +// vi: set ts=4 sw=4 : +// vim: set tw=75 : -#include "types_meta.h" // mBOOL -#include "mplugin.h" // class MPlugin +// mlist.h - class and constants to describe a list of plugins + +/* + * Copyright (c) 2001-2003 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game g_engine ("HL + * g_engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL g_engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + +#ifndef MLIST_H +#define MLIST_H + +#include "types_meta.h" // mBOOL +#include "mplugin.h" // class MPlugin #include "plinfo.h" // plid_t, etc -#include "new_baseclass.h" // Max number of plugins we can manage. This is an arbitrary, fixed number, // for convenience. It would probably be better to dynamically grow the // list as needed, but we do this for now. #define MAX_PLUGINS 50 - // Width required to printf above MAX, for show() functions. #define WIDTH_MAX_PLUGINS 2 + // A list of plugins. -class MPluginList: public class_metamod_new { -public: - MPluginList(const char *ifile); +class MPluginList { + public: + // data: + char inifile[PATH_MAX]; // full pathname + MPlugin plist[MAX_PLUGINS]; // array of plugins + int size; // size of list, ie MAX_PLUGINS + int endlist; // index of last used entry - void reset_plugin(MPlugin *pl_find); - MPlugin *find(int pindex); // find by index - MPlugin *find(const char *findpath); // find by pathname - MPlugin *find(plid_t id); // find by plid_t - MPlugin *find(DLHANDLE handle); // find by handle - MPlugin *find_memloc(void *memptr); // find by memory location - MPlugin *find_match(const char *prefix); // find by partial prefix match - MPlugin *find_match(MPlugin *pmatch); // find by platform_match() - MPlugin *add(MPlugin *padd); - mBOOL found_child_plugins(int source_index); - void clear_source_plugin_index(int source_index); - void trim_list(); - mBOOL ini_startup(); // read inifile at startup - mBOOL ini_refresh(); // re-read inifile - mBOOL cmd_addload(const char *args); // load from console command - MPlugin *plugin_addload(plid_t plid, const char *fname, PLUG_LOADTIME now); //load from plugin - mBOOL load(); // load the list, at startup - mBOOL refresh(PLUG_LOADTIME now); // update from re-read inifile - void unpause_all(); // unpause any paused plugins - void retry_all(PLUG_LOADTIME now); // retry any pending plugin actions - void show(int source_index); // list plugins to console - void show() { show(-1); }; // list plugins to console - void show_client(edict_t *pEntity); // list plugins to player client + // constructor: + MPluginList(const char *ifile); -public: - MPlugin plist[MAX_PLUGINS]; // array of plugins - int size; // size of list, ie MAX_PLUGINS - int endlist; // index of last used entry - char inifile[PATH_MAX]; // full pathname + // functions: + MPlugin *find(int pindex); // find by index + MPlugin *find(const char *findpath); // find by pathname + MPlugin *find(plid_t id); // find by plid_t + MPlugin *find_memloc(void *memptr); // find by memory location + MPlugin *find_match(const char *prefix); // find by partial prefix match + MPlugin *find_match(MPlugin *pmatch); // find by platform_match() + MPlugin * find(DLHANDLE handle); // find by handle + MPlugin *add(MPlugin *padd); + + mBOOL found_child_plugins(int source_index); + + mBOOL ini_startup(void); // read inifile at startup + mBOOL ini_refresh(void); // re-read inifile + mBOOL cmd_addload(const char *args); // load from console command + MPlugin *plugin_addload(plid_t plid, const char *fname, PLUG_LOADTIME now); //load from plugin + + mBOOL load(void); // load the list, at startup + mBOOL refresh(PLUG_LOADTIME now); // update from re-read inifile + void unpause_all(void); // unpause any paused plugins + void retry_all(PLUG_LOADTIME now); // retry any pending plugin actions + void show(int source_index); // list plugins to console + void show_client(edict_t *pEntity); // list plugins to player client + void clear_source_plugin_index(int source_index); }; + +#endif /* MLIST_H */ diff --git a/metamod/src/mm_pextensions.h b/metamod/src/mm_pextensions.h deleted file mode 100644 index cb7ee22..0000000 --- a/metamod/src/mm_pextensions.h +++ /dev/null @@ -1,80 +0,0 @@ -#pragma once - -#include "plinfo.h" // plid_t -#include "meta_api.h" // PLUG_LOADTIME -/* - -How to use: - 1. Add new export function 'Meta_PExtGiveFnptrs' to your plugin file. - 'Meta_PExtGiveFnptrs' will be called right after 'Meta_Query' call. - 2. Meta_PExtGiveFnptrs is called with interface version 'META_PEXT_VERSION' - and pointer to extension function table. - 3. Meta_PExtGiveFnptrs should return plugin's interface version. - 4. !NOTE! Metamod will not stop loading plugin even if plugin returns - interface version greater than current. Plugin should disable itself in - this kind of situation. - -Example: - #include "mm_pextensions.h" - - pextension_funcs_t *gpMetaPExtFuncs; - - int Meta_PExtGiveFnptrs(int interfaceVersion, pextension_funcs_t *pMetaPExtFuncs) { - if (interfaceVersion < META_PEXT_VERSION) { - LOG_DEVELOPER(PLID, "Error! Metamod is too old, please update!"); - gpMetaPExtFuncs = NULL; - - return META_PEXT_VERSION; - } - - gpMetaPExtFuncs = pMetaPExtFuncs; - - return META_PEXT_VERSION; - } - -Callback functions: - - int PEXT_LOAD_PLUGIN_BY_NAME(PLID, const char *cmdline, PLUG_LOADTIME now, void **plugin_handle); - Parses 'cmdline' as metamod would parse 'meta load ' and loads found - plugin. If 'plugin_handle' is set, metamod writes module handle of loaded - plugin at it. - Returns zero on success. - For error codes see 'META_ERRNO' in 'types_meta.h'. - - - int PEXT_UNLOAD_PLUGIN_BY_NAME(PLID, const char *cmdline, PLUG_LOADTIME now, PL_UNLOAD_REASON reason); - Parses 'cmdline' as metamod would parse 'meta unload ' and - unloads found plugin. - Returns zero on success. - For error codes see 'META_ERRNO' in 'types_meta.h'. - - - int PEXT_UNLOAD_PLUGIN_BY_HANDLE(PLID, void *plugin_handle, PLUG_LOADTIME now, PL_UNLOAD_REASON reason); - Unloads plugin with 'plugin_handle'. - Returns zero on success. - For error codes see 'META_ERRNO' in 'types_meta.h'. - - !NOTE! Plugin cannot unload itself! -*/ - -// Interface version -// 1: first version. Used in p13 -// 2: Complete remake (p14): -// pfnLoadMetaPluginByName -// pfnUnloadMetaPluginByName -// pfnUnloadMetaPluginByHandle -// v2 is locked now. Don't modify old functions. If you add new functions, increase META_PEXT_VERSION. -#define META_PEXT_VERSION 2 - -// Meta PExtension Function table type. -typedef struct pextension_funcs_s { - int (*pfnLoadMetaPluginByName)(plid_t plid, const char *cmdline, PLUG_LOADTIME now, void **plugin_handle); - int (*pfnUnloadMetaPluginByName)(plid_t plid, const char *cmdline, PLUG_LOADTIME now, PL_UNLOAD_REASON reason); - int (*pfnUnloadMetaPluginByHandle)(plid_t plid, void *plugin_handle, PLUG_LOADTIME now, PL_UNLOAD_REASON reason); -} pextension_funcs_t; - -// Convenience macros for MetaPExtension functions. -#define PEXT_LOAD_PLUGIN_BY_NAME (*gpMetaPExtFuncs->pfnLoadMetaPluginByName) -#define PEXT_UNLOAD_PLUGIN_BY_NAME (*gpMetaPExtFuncs->pfnUnloadMetaPluginByName) -#define PEXT_UNLOAD_PLUGIN_BY_HANDLE (*gpMetaPExtFuncs->pfnUnloadMetaPluginByHandle) - -// Give plugin extension function table. -C_DLLEXPORT int Meta_PExtGiveFnptrs(int interfaceVersion, pextension_funcs_t *pMetaPExtFuncs); -typedef int (*META_GIVE_PEXT_FUNCTIONS_FN) (int interfaceVersion, pextension_funcs_t *pMetaPExtFuncs); diff --git a/metamod/src/mplayer.cpp b/metamod/src/mplayer.cpp index 8cb4669..7dcd8f9 100644 --- a/metamod/src/mplayer.cpp +++ b/metamod/src/mplayer.cpp @@ -1,116 +1,108 @@ +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// mplayer.cpp - methods of individual player (class MPlayer) and +// list of players (class MPlayerList). + +/* + * Copyright (c) 2005 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game g_engine ("HL + * g_engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL g_engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + #include "precompiled.h" // Constructor -MPlayer::MPlayer() - : isQueried(mFALSE), - cvarName(nullptr) +MPlayer::MPlayer() : isQueried(mFALSE) { } -// Destructor -MPlayer::~MPlayer() -{ - if (cvarName) { - free(cvarName); - } -} - -// Copy constructor -MPlayer::MPlayer(const MPlayer& rhs) - : isQueried(rhs.isQueried), - cvarName(nullptr) -{ - if (rhs.cvarName) { - cvarName = strdup(rhs.cvarName); - } -} - -// Assignment operator -MPlayer& MPlayer::operator=(const MPlayer& rhs) -{ - isQueried = rhs.isQueried; - - if (cvarName) { - free(cvarName); - } - cvarName = nullptr; - if (rhs.cvarName) { - cvarName = strdup(rhs.cvarName); - } - return *this; -} - // Mark a player as querying a client cvar and stores the cvar name // meta_errno values: // - ME_ARGUMENT cvar is NULL -void MPlayer::set_cvar_query(const char *cvar) +void MPlayer::set_cvar_query(const char* cvar) { // Do not allow NULL as queried cvar since we use this as // return value in is_querying_cvar as indication if a // client cvar is queried. - if (!cvar) - { + if (!cvar) { meta_errno = ME_ARGUMENT; return; } - isQueried = mTRUE; - if (cvarName) { - free(cvarName); - } - cvarName = strdup(cvar); -} + isQueried = mTRUE; + strncpy(cvarName, cvar, sizeof cvarName - 1); + cvarName[sizeof cvarName - 1] = '\0'; +} // Unmark player as querying a client cvar void MPlayer::clear_cvar_query(const char* /*cvar*/) { isQueried = mFALSE; - if (cvarName) - { - free(cvarName); - cvarName = nullptr; - } + cvarName[0] = '\0'; } + // Check if a client cvar is queried for this player // Returns NULL if not // or the name of the cvar. -const char *MPlayer::is_querying_cvar() +const char* MPlayer::is_querying_cvar(void) const { - if (isQueried) - { + if (isQueried) { return cvarName; } - return nullptr; + return NULL; } // Mark a player as querying a client cvar and stores the cvar name // meta_errno values: // - ME_ARGUMENT cvar is NULL -void MPlayerList::set_player_cvar_query(const edict_t *pEntity, const char *cvar) +void MPlayerList::set_player_cvar_query(const edict_t* pEntity, const char* cvar) { - int indx = ENTINDEX(const_cast(pEntity)); - if (indx < 1 || indx > gpGlobals->maxClients) - return; //maybe output a message? + int indx = ENTINDEX(pEntity); - players[indx].set_cvar_query(cvar); + if (indx >= 1 && indx <= maxplayers) + players[indx].set_cvar_query(cvar); } // Unmark player as querying a client cvar -void MPlayerList::clear_player_cvar_query(const edict_t *pEntity, const char *cvar) +void MPlayerList::clear_player_cvar_query(const edict_t* pEntity, const char* cvar) { - int indx = ENTINDEX(const_cast(pEntity)); - if (indx < 1 || indx > gpGlobals->maxClients) - return; //maybe output a message? + int indx = ENTINDEX(pEntity); - players[indx].clear_cvar_query(cvar); + if (indx >= 1 && indx <= maxplayers) + players[indx].clear_cvar_query(cvar); } -void MPlayerList::clear_all_cvar_queries() +void MPlayerList::clear_all_cvar_queries(void) { - for (int indx = 1; indx < gpGlobals->maxClients; ++indx) - { + for (int indx = 1; indx <= maxplayers; indx++) { players[indx].clear_cvar_query(); } } @@ -120,13 +112,12 @@ void MPlayerList::clear_all_cvar_queries() // or the name of the cvar. // meta_errno values: // - ME_NOTFOUND invalid entity -const char *MPlayerList::is_querying_cvar(const edict_t *pEntity) +const char* MPlayerList::is_querying_cvar(const edict_t* pEntity) const { - int indx = ENTINDEX(const_cast(pEntity)); - if (indx < 1 || indx > gpGlobals->maxClients) - { - RETURN_ERRNO(nullptr, ME_NOTFOUND); - } + int indx = ENTINDEX(pEntity); - return players[indx].is_querying_cvar(); + if (indx >= 1 && indx <= maxplayers) + return players[indx].is_querying_cvar(); + + RETURN_ERRNO(NULL, ME_NOTFOUND); } diff --git a/metamod/src/mplayer.h b/metamod/src/mplayer.h index 2904e6b..18d6140 100644 --- a/metamod/src/mplayer.h +++ b/metamod/src/mplayer.h @@ -1,38 +1,76 @@ -#pragma once +// vi: set ts=4 sw=4 : +// vim: set tw=75 : -#include "plinfo.h" // plugin_info_t, etc -#include "mutil.h" // query_callback_t -#include "types_meta.h" // mBOOL -#include "new_baseclass.h" // class_metamod_new +// mplayer.h - class to keep info about a player and a class listing all +// players + +/* + * Copyright (c) 2005 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game g_engine ("HL + * g_engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL g_engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + +#ifndef INCLUDE_METAMOD_PLAYER_H +#define INCLUDE_METAMOD_PLAYER_H + +#include "types_meta.h" // mBOOL + +// Numbers of players limit set by the engine +#define MAX_PLAYERS 32 // Info on an individual player -class MPlayer: public class_metamod_new +class MPlayer { -private: - mBOOL isQueried; // is this player currently queried for a cvar value - char *cvarName; // name of the cvar if getting queried - MPlayer (const MPlayer&); - MPlayer& operator=(const MPlayer&); - public: MPlayer(); - ~MPlayer(); - void set_cvar_query(const char *cvar); // mark this player as querying a client cvar - void clear_cvar_query(const char *cvar = nullptr); // unmark this player as querying a client cvar - const char *is_querying_cvar(); // check if a player is querying a cvar. returns - // NULL if not or the name of the cvar + + void set_cvar_query(const char *cvar); // mark this player as querying a client cvar + void clear_cvar_query(const char *cvar=NULL); // unmark this player as querying a client cvar + const char *is_querying_cvar(void) const; // check if a player is querying a cvar. returns + +private: + mBOOL isQueried; // is this player currently queried for a cvar value + char cvarName[64]; // name of the cvar if getting queried }; // A list of players. The number of max players is fixed and small enough // to use an array. class MPlayerList -{ -private: - MPlayer players[MAX_CLIENTS + 1]; // array of players - +{ public: - void set_player_cvar_query(const edict_t *pEntity, const char *cvar); - void clear_player_cvar_query(const edict_t *pEntity, const char *cvar = nullptr); - void clear_all_cvar_queries(); - const char *is_querying_cvar(const edict_t *pEntity); + void set_player_cvar_query(const edict_t *pEntity, const char *cvar); + void clear_player_cvar_query(const edict_t *pEntity, const char *cvar=NULL); + void clear_all_cvar_queries(void); + const char *is_querying_cvar(const edict_t *pEntity) const; + +private: + int maxplayers = 32; + MPlayer players[MAX_PLAYERS + 1]; // array of players }; + +#endif /* INCLUDE_METAMOD_PLAYER_H */ diff --git a/metamod/src/mplugin.cpp b/metamod/src/mplugin.cpp index 5b03bc2..330929b 100644 --- a/metamod/src/mplugin.cpp +++ b/metamod/src/mplugin.cpp @@ -1,3 +1,39 @@ +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// mplugin.cpp - functions for individual plugin (class MPlugin) + +/* + * Copyright (c) 2001-2003 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game g_engine ("HL + * g_engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL g_engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + #include "precompiled.h" // Parse a line from plugins.ini into a plugin. @@ -5,75 +41,55 @@ // - ME_COMMENT ignored commented line // - ME_FORMAT invalid line format // - ME_OSNOTSUP plugin is not for this OS -mBOOL MPlugin::ini_parseline(const char *line) +mBOOL MPlugin::ini_parseline(char* line) { - char *token; - char *ptr_token; - char *cp; - char *tmp_line; - - tmp_line = strdup(line); - if (!tmp_line) - RETURN_ERRNO(mFALSE, ME_NOMEM); + char* token; + char* ptr_token; + char* cp; // skip whitespace at start of line - while (*tmp_line == ' ' || *tmp_line == '\t') tmp_line++; + while (*line == ' ' || *line == '\t') line++; // remove whitespace at end of line - cp = tmp_line + Q_strlen(tmp_line) -1; + cp = line + strlen(line) - 1; while (*cp == ' ' || *cp == '\t') *cp-- = '\0'; // skip empty lines - if (tmp_line[0] == '\0') - { - META_DEBUG(7, ("ini: Ignoring empty line: %s", tmp_line)); - free(tmp_line); + if (line[0] == '\0') { + META_DEBUG(7, ("ini: Ignoring empty line: %s", line)); RETURN_ERRNO(mFALSE, ME_BLANK); } - if (tmp_line[0] == '#' || tmp_line[0] == ';' || Q_strstr(tmp_line, "//") == tmp_line) - { - META_DEBUG(7, ("ini: Ignoring commented line: %s", tmp_line)); - free(tmp_line); + if (line[0] == '#' || line[0] == ';' || strstr(line, "//") == line) { + META_DEBUG(7, ("ini: Ignoring commented line: %s", line)); RETURN_ERRNO(mFALSE, ME_COMMENT); } // grab platform ("win32" or "linux") - token = strtok_r(tmp_line, " \t", &ptr_token); + token = strtok_r(line, " \t", &ptr_token); if (!token) - { - free(tmp_line); - RETURN_ERRNO(mFALSE, ME_FORMAT); - } - if (!Q_stricmp(token, PLATFORM)) - { + RETURN_ERRNO(mFALSE, ME_FORMAT); + if (_stricmp(token, PLATFORM) == 0) { pfspecific = 0; - } else if (!Q_stricmp(token, PLATFORM_SPC)) - { + } + else if (_stricmp(token, PLATFORM_SPC) == 0) { pfspecific = 1; } - else - { + else { // plugin is not for this OS META_DEBUG(7, ("ini: Ignoring entry for %s", token)); - free(tmp_line); RETURN_ERRNO(mFALSE, ME_OSNOTSUP); } // grab filename token = strtok_r(NULL, " \t\r\n", &ptr_token); if (!token) - { - free(tmp_line); - RETURN_ERRNO(mFALSE, ME_FORMAT); - } - - Q_strncpy(filename, token, sizeof(filename) - 1); - filename[sizeof(filename) - 1] = '\0'; - + RETURN_ERRNO(mFALSE, ME_FORMAT); + strncpy(filename, token, sizeof filename - 1); + filename[sizeof filename - 1] = '\0'; normalize_pathname(filename); // Store name of just the actual _file_, without dir components. - cp = Q_strrchr(filename, '/'); + cp = strrchr(filename, '/'); if (cp) file = cp + 1; else @@ -82,17 +98,15 @@ mBOOL MPlugin::ini_parseline(const char *line) // Grab description. // Just get the the rest of the line, minus line-termination. token = strtok_r(NULL, "\n\r", &ptr_token); - if (token) - { - token=token+strspn(token, " \t"); // skip whitespace - Q_strncpy(desc, token, sizeof(desc) - 1); - desc[sizeof(desc) - 1] = '\0'; + if (token) { + token = token + strspn(token, " \t"); // skip whitespace + strncpy(desc, token, sizeof desc - 1); + desc[sizeof desc - 1] = '\0'; } - else - { + else { // If no description is specified, temporarily use plugin file, // until plugin can be queried, and desc replaced with info->name. - safevoid_snprintf(desc, sizeof(desc), "<%s>", file); + snprintf(desc, sizeof(desc), "<%s>", file); } // Make full pathname (from gamedir if relative, remove "..", @@ -101,146 +115,181 @@ mBOOL MPlugin::ini_parseline(const char *line) source = PS_INI; status = PL_VALID; + return (mTRUE); +} + +// Unload a plugin from plugin request +// meta_errno values: +// - errno's from unload() +mBOOL MPlugin::plugin_unload(plid_t plid, PLUG_LOADTIME now, PL_UNLOAD_REASON reason) +{ + PLUG_ACTION old_action; + MPlugin* pl_unloader; + + if (!(pl_unloader = g_plugins->find(plid))) { + META_WARNING("dll: Not unloading plugin '%s'; plugin that requested unload is not found.", desc); + RETURN_ERRNO(mFALSE, ME_BADREQ); + } + else if (pl_unloader->index == index) { + META_WARNING("dll: Not unloading plugin '%s'; Plugin tried to unload itself.", desc); + RETURN_ERRNO(mFALSE, ME_UNLOAD_SELF); + } + else if (is_unloader) { + META_WARNING("dll: Not unloading plugin '%s'; Plugin is unloading plugin that tried to unload it.", desc); + RETURN_ERRNO(mFALSE, ME_UNLOAD_UNLOADER); + } + else { + unloader_index = pl_unloader->index; + } + + //block unloader from being unloaded by other plugin + pl_unloader->is_unloader = mTRUE; + + //try unload + old_action = action; + action = PA_UNLOAD; + if (unload(now, reason, PNL_PLG_FORCED)) { + META_DEBUG(1,("Unloaded plugin '%s'", desc)); + pl_unloader->is_unloader = mFALSE; + return mTRUE; + } + + pl_unloader->is_unloader = mFALSE; + + //can't unload plugin now, set delayed + if (meta_errno == ME_DELAYED) { + action = old_action; + meta_errno = ME_NOTALLOWED; + META_DEBUG(2, ("dll: Failed unload plugin '%s'; can't detach now: allowed=%s; now=%s", desc, str_unloadable(), str_loadtime(PT_ANYTIME, SL_SIMPLE))); + } + + return mFALSE; +} + +// Parse a filename string from PEXT_LOAD_PLUGIN_BY_* function into a plugin. +// meta_errno values: +mBOOL MPlugin::plugin_parseline(const char* fname, int loader_index) +{ + char* cp; + + source_plugin_index = loader_index; + + strncpy(filename, fname, sizeof filename - 1); + filename[sizeof filename - 1] = '\0'; + + normalize_pathname(filename); + + //store just name of the actual _file, without path + cp = strrchr(filename, '/'); + if (cp) + file = cp + 1; + else + file = filename; + + //grab description + //temporarily use plugin file until plugin can be queried + snprintf(desc, sizeof(desc), "<%s>", file); + + //make full pathname + full_gamedir_path(filename, pathname); + + source = PS_PLUGIN; + status = PL_VALID; - free(tmp_line); return mTRUE; } // Parse a line from console "load" command into a plugin. // meta_errno values: // - ME_FORMAT invalid line format -mBOOL MPlugin::cmd_parseline(const char *line) +mBOOL MPlugin::cmd_parseline(const char* line) { char buf[NAME_MAX + PATH_MAX + MAX_DESC_LEN]; - char *token; - char *ptr_token; - char *cp; + char* token; + char* ptr_token; + char* cp; - Q_strncpy(buf, line, sizeof(buf) - 1); - buf[sizeof(buf) - 1] = '\0'; + strncpy(buf, line, sizeof buf - 1); + buf[sizeof buf - 1] = '\0'; // remove "load" - token=strtok_r(buf, " \t", &ptr_token); + token = strtok_r(buf, " \t", &ptr_token); if (!token) - RETURN_ERRNO(mFALSE, ME_FORMAT); + RETURN_ERRNO(mFALSE, ME_FORMAT); // grab filename token = strtok_r(NULL, " \t", &ptr_token); if (!token) - RETURN_ERRNO(mFALSE, ME_FORMAT); - - Q_strncpy(filename, token, sizeof(filename) - 1); - filename[sizeof(filename) - 1] = '\0'; - + RETURN_ERRNO(mFALSE, ME_FORMAT); + strncpy(filename, token, sizeof filename - 1); + filename[sizeof filename - 1] = '\0'; normalize_pathname(filename); // store name of just the actual _file_, without dir components - cp=Q_strrchr(filename, '/'); + cp = strrchr(filename, '/'); if (cp) - file=cp+1; + file = cp + 1; else - file=filename; + file = filename; // Grab description. // Specify no delimiter chars, as we just want the rest of the line. - token=strtok_r(NULL, "", &ptr_token); - if (token) - { - token = token + strspn(token, " \t"); // skip whitespace - - Q_strncpy(desc, token, sizeof(desc) - 1); - desc[sizeof(desc) - 1] = '\0'; + token = strtok_r(NULL, "", &ptr_token); + if (token) { + token = token + strspn(token, " \t"); // skip whitespace + strncpy(desc, token, sizeof desc - 1); + desc[sizeof desc - 1] = '\0'; } - else - { + else { // if no description is specified, temporarily use plugin file, // until plugin can be queried, and desc replaced with info->name. - safevoid_snprintf(desc, sizeof(desc), "<%s>", file); + snprintf(desc, sizeof(desc), "<%s>", file); } // Make full pathname (from gamedir if relative, remove "..", // backslashes, etc). full_gamedir_path(filename, pathname); - source=PS_CMD; - status=PL_VALID; - return mTRUE; -} - -// Parse a filename string from PEXT_LOAD_PLUGIN_BY_* function into a plugin. -// meta_errno values: -mBOOL MPlugin::plugin_parseline(const char *fname, int loader_index) -{ - char *cp; - - source_plugin_index = loader_index; - - Q_strncpy(filename, fname, sizeof(filename) - 1); - filename[sizeof(filename) - 1] = '\0'; - - normalize_pathname(filename); - // store name of just the actual _file_, without dir components - cp=Q_strrchr(filename, '/'); - if (cp) - file=cp+1; - else - file=filename; - - // Grab description. - // Temporarily use plugin file, until plugin can be queried, and desc replaced with info->name. - safevoid_snprintf(desc, sizeof(desc), "<%s>", file); - - // Make full pathname (from gamedir if relative, remove "..", - // backslashes, etc). - full_gamedir_path(filename, pathname); - - source=PS_PLUGIN; - status=PL_VALID; - return mTRUE; + source = PS_CMD; + status = PL_VALID; + return (mTRUE); } // Make sure this plugin has the necessary minimal information. // meta_errno values: // - ME_ARGUMENT missing necessary fields in plugin -mBOOL MPlugin::check_input() +mBOOL MPlugin::check_input(void) { // doublecheck our input/state - if (status < PL_VALID) - { - META_WARNING("dll: Tried to operate on plugin[%d] with a non-valid status (%d)", index, str_status()); + if (status < PL_VALID) { + META_ERROR("dll: Tried to operate on plugin[%d] with a non-valid status (%d)", index, str_status()); RETURN_ERRNO(mFALSE, ME_ARGUMENT); } - - if (!file || !file[0]) - { - META_WARNING("dll: Tried to operate on plugin[%d] with an empty file", index); + if (!file || !file[0]) { + META_ERROR("dll: Tried to operate on plugin[%d] with an empty file", + index); RETURN_ERRNO(mFALSE, ME_ARGUMENT); } - - if (!filename[0]) - { - META_WARNING("dll: Tried to operate on plugin[%d] with an empty filename", index); + if (!filename[0]) { + META_ERROR("dll: Tried to operate on plugin[%d] with an empty filename", + index); RETURN_ERRNO(mFALSE, ME_ARGUMENT); } - - if (!pathname[0]) - { - META_WARNING("dll: Tried to operate on plugin[%d] with an empty pathname", index); + if (!pathname[0]) { + META_ERROR("dll: Tried to operate on plugin[%d] with an empty pathname", + index); RETURN_ERRNO(mFALSE, ME_ARGUMENT); } - - if (!desc[0]) - { + if (!desc[0]) { // if no description is specified, temporarily use plugin file, // until plugin can be queried, and desc replaced with info->name. - safevoid_snprintf(desc, sizeof(desc), "<%s>", file); + snprintf(desc, sizeof(desc), "<%s>", file); } - - return mTRUE; + return (mTRUE); } // Try to resolve a plugin's filename as a (possibly partial) path to an // actual filename on disk, to facilitate easier console load-command -// arguments. Uses resolve_dirs, resolve_prefix, and resolve_suffix below. +// arguments. Uses resolve_dirs, resolve_prefix, and resolve_suffix below. // Example paths that it tries: // filename // Gamedir/filename.dll, Gamedir/filename.so @@ -251,86 +300,78 @@ mBOOL MPlugin::check_input() // meta_errno values: // - ME_NOTFOUND couldn't find a matching file for the partial name // - errno's from check_input() -mBOOL MPlugin::resolve() +mBOOL MPlugin::resolve(void) { - char *found; - char *cp; + char* found; + char* cp; int len; - if (!check_input()) - { + if (!check_input()) { // details logged, meta_errno set in check_input() - return mFALSE; + return (mFALSE); } - if (is_absolute_path(filename)) found = resolve_prefix(filename); else found = resolve_dirs(filename); - if (!found) - { + if (!found) { META_DEBUG(2, ("Couldn't resolve '%s' to file", filename)); RETURN_ERRNO(mFALSE, ME_NOTFOUND); } - META_DEBUG(2, ("Resolved '%s' to file '%s'", filename, found)); - // store pathname: the resolved path (should be absolute) - Q_strncpy(pathname, found, sizeof(pathname) - 1); - pathname[sizeof(pathname) - 1] = '\0'; - + strncpy(pathname, found, sizeof pathname - 1); + pathname[sizeof pathname - 1] = '\0'; // store file: the name of the file (without dir) - cp = Q_strrchr(pathname, '/'); + cp = strrchr(pathname, '/'); if (cp) - file=cp+1; + file = cp + 1; else - file=pathname; + file = pathname; // store pathname: the gamedir relative path, or an absolute path - len=Q_strlen(GameDLL.gamedir); - if (strncasecmp(pathname, GameDLL.gamedir, len) == 0) - { - Q_strncpy(filename, pathname + len + 1, sizeof(filename) - 1); - filename[sizeof(filename) - 1] = '\0'; + len = strlen(GameDLL.gamedir); + if (_strnicmp(pathname, GameDLL.gamedir, len) == 0) { + strncpy(filename, pathname + len + 1, sizeof filename - 1); + filename[sizeof filename - 1] = '\0'; } - else - { - Q_strncpy(filename, pathname, sizeof(filename) - 1); - filename[sizeof(filename) - 1] = '\0'; + else { + strncpy(filename, pathname, sizeof filename - 1); + filename[sizeof filename - 1] = '\0'; } - return mTRUE; + return (mTRUE); } -// For the given path, tries to find file in several possible +// For the given path, tries to find file in several possible // directories. // Try: // GAMEDIR/filename // GAMEDIR/dlls/filename // meta_errno values: // - none -char *MPlugin::resolve_dirs(const char *path) +char* MPlugin::resolve_dirs(char* path) { struct stat st; - static char buf[PATH_MAX]; - char *found; + static char buf[PATH_MAX ]; + char* found; - safevoid_snprintf(buf, sizeof(buf), "%s/%s", GameDLL.gamedir, path); + snprintf(buf, sizeof(buf), "%s/%s", GameDLL.gamedir, path); // try this path if (stat(buf, &st) == 0 && S_ISREG(st.st_mode)) - return buf; + return (buf); // try other file prefixes in this path - if ((found=resolve_prefix(buf))) - return found; + if ((found = resolve_prefix(buf))) + return (found); - safevoid_snprintf(buf, sizeof(buf), "%s/dlls/%s", GameDLL.gamedir, path); + snprintf(buf, sizeof(buf), "%s/dlls/%s", GameDLL.gamedir, path); // try this path if (stat(buf, &st) == 0 && S_ISREG(st.st_mode)) - return buf; + return (buf); // try other file prefixes for this path - if ((found=resolve_prefix(buf))) - return found; + if ((found = resolve_prefix(buf))) + return (found); - return NULL; + return (NULL); } // For the given path, tries several possible filename prefixes. @@ -339,43 +380,40 @@ char *MPlugin::resolve_dirs(const char *path) // dir/file // meta_errno values: // - none -char *MPlugin::resolve_prefix(const char *path) +char* MPlugin::resolve_prefix(char* path) { struct stat st; char *cp, *fname; - char dname[PATH_MAX]; - static char buf[PATH_MAX]; - char *found; + char dname[PATH_MAX ]; + static char buf[PATH_MAX ]; + char* found; // try "mm_" prefix FIRST. // split into dirname and filename - Q_strncpy(dname, path, sizeof(dname) - 1); - dname[sizeof(dname) - 1] = '\0'; - - cp = Q_strrchr(dname, '/'); - if (cp) - { + strncpy(dname, path, sizeof dname - 1); + dname[sizeof dname - 1] = '\0'; + cp = strrchr(dname, '/'); + if (cp) { *cp = '\0'; fname = cp + 1; - safevoid_snprintf(buf, sizeof(buf), "%s/mm_%s", dname, fname); + snprintf(buf, sizeof(buf), "%s/mm_%s", dname, fname); } - else - { + else { // no directory in given path - safevoid_snprintf(buf, sizeof(buf), "mm_%s", path); + snprintf(buf, sizeof(buf), "mm_%s", path); } // try this path if (stat(buf, &st) == 0 && S_ISREG(st.st_mode)) - return buf; + return (buf); // try other suffixes for this path - if ((found=resolve_suffix(buf))) - return found; + if ((found = resolve_suffix(buf))) + return (found); // try other suffixes for the original path - if ((found=resolve_suffix(path))) - return found; + if ((found = resolve_suffix(path))) + return (found); - return NULL; + return (NULL); } // For the given path, tries several different filename suffixes. @@ -383,90 +421,80 @@ char *MPlugin::resolve_prefix(const char *path) // path // path_mm // path_MM -// path.so (linux), path.dll (win32) +// path.so (linux), path.dll (win32), path.dylib (osx) // path_i386.so, path_i486.so, etc (if linux) // meta_errno values: // - none -char *MPlugin::resolve_suffix(const char *path) +char* MPlugin::resolve_suffix(char* path) { struct stat st; - static char buf[PATH_MAX]; - static char tmpbuf[PATH_MAX]; - char *found; + static char buf[PATH_MAX ]; + char* found; // Hmm, recursion. - if (!Q_strstr(path, "_mm")) - { - safevoid_snprintf(buf, sizeof(buf), "%s_mm", path); - Q_memcpy(tmpbuf,buf,sizeof(tmpbuf)); + if (!strstr(path, "_mm")) { + char* tmpbuf; + snprintf(buf, sizeof(buf), "%s_mm", path); + tmpbuf = _strdup(buf); found = resolve_suffix(tmpbuf); - if (found) - return found; + free(tmpbuf); + if (found) return (found); } - - if (!Q_strstr(path, "_MM")) - { - safevoid_snprintf(buf, sizeof(buf), "%s_MM", path); - Q_memcpy(tmpbuf,buf,sizeof(tmpbuf)); + if (!strstr(path, "_MM")) { + char* tmpbuf; + snprintf(buf, sizeof(buf), "%s_MM", path); + tmpbuf = _strdup(buf); found = resolve_suffix(tmpbuf); - if (found) - return found; + free(tmpbuf); + if (found) return (found); } #ifdef _WIN32 - safevoid_snprintf(buf, sizeof(buf), "%s.dll", path); + snprintf(buf, sizeof(buf), "%s.dll", path); +#elif defined(linux) + snprintf(buf, sizeof(buf), "%s.so", path); +#elif defined(__APPLE__) + snprintf(buf, sizeof(buf), "%s.dylib", path); #else - safevoid_snprintf(buf, sizeof(buf), "%s.so", path); -#endif +#error "OS unrecognized" +#endif /* _WIN32 */ + if (stat(buf, &st) == 0 && S_ISREG(st.st_mode)) + return (buf); - if (stat(buf, &st) == 0 && S_ISREG(st.st_mode)) - return buf; +#ifdef linux + snprintf(buf, sizeof(buf), "%s_i386.so", path); + if(stat(buf, &st) == 0 && S_ISREG(st.st_mode)) + return(buf); + snprintf(buf, sizeof(buf), "%s_i486.so", path); + if(stat(buf, &st) == 0 && S_ISREG(st.st_mode)) + return(buf); + snprintf(buf, sizeof(buf), "%s_i586.so", path); + if(stat(buf, &st) == 0 && S_ISREG(st.st_mode)) + return(buf); + snprintf(buf, sizeof(buf), "%s_i686.so", path); + if(stat(buf, &st) == 0 && S_ISREG(st.st_mode)) + return(buf); + snprintf(buf, sizeof(buf), "%s_amd64.so", path); + if(stat(buf, &st) == 0 && S_ISREG(st.st_mode)) + return(buf); +#endif /* linux */ -#ifndef _WIN32 - safevoid_snprintf(buf, sizeof(buf), "%s_i386.so", path); - if (stat(buf, &st) == 0 && S_ISREG(st.st_mode)) - return buf; - safevoid_snprintf(buf, sizeof(buf), "%s_i486.so", path); - if (stat(buf, &st) == 0 && S_ISREG(st.st_mode)) - return buf; - safevoid_snprintf(buf, sizeof(buf), "%s_i586.so", path); - if (stat(buf, &st) == 0 && S_ISREG(st.st_mode)) - return buf; - safevoid_snprintf(buf, sizeof(buf), "%s_i686.so", path); - if (stat(buf, &st) == 0 && S_ISREG(st.st_mode)) - return buf; -#endif - - return nullptr; + return (NULL); } // Check if a passed string starts with a known platform postfix. // It does not check beyond the period in order to work for both // Linux and Win32. -mBOOL MPlugin::is_platform_postfix(const char *pf) +static mBOOL is_platform_postfix(char* pf) { - typedef struct { const char *postfix; size_t len; } postfix_t; - static const postfix_t postfixes[] = - { - {"_i386.", 6}, - {"_i686.", 6}, - {"_amd64.", 7}, - {"_i486.", 6}, - {"_i586.", 6}, - {"_x86_64.", 8}, - {"_x86-64.", 8}, - {0,0}, - }; + if (NULL == pf) return mFALSE; - if (!pf) - return mFALSE; - - for (const postfix_t *plist = postfixes; plist->postfix; plist++) - { - if (!Q_strncmp(pf, plist->postfix, plist->len)) - return mTRUE; - } + if (0 == strncmp(pf, "_i386.", 6)) return mTRUE; + if (0 == strncmp(pf, "_i486.", 6)) return mTRUE; + if (0 == strncmp(pf, "_i586.", 6)) return mTRUE; + if (0 == strncmp(pf, "_i686.", 6)) return mTRUE; + if (0 == strncmp(pf, "_amd64.", 7)) return mTRUE; return mFALSE; } @@ -479,49 +507,41 @@ mBOOL MPlugin::is_platform_postfix(const char *pf) // 2b. the description is the same, or // 3. a significant part of the filename is the same. // A significant part of a plugin name is currently defined to: -// the part up to a known platform postfix as determined by +// the part up to a known platform postfix as determined by // the is_platform_postfix() function (see above), or // the part up to the last dot, if one exists. // meta_errno values: // - none -mBOOL MPlugin::platform_match(MPlugin *other) +mBOOL MPlugin::platform_match(MPlugin* other) { char *end, *other_end; int prefixlen; - if (status < PL_VALID || other->status < PL_VALID) - return mFALSE; + if (status == PL_EMPTY || other->status == PL_EMPTY) return mFALSE; - if (!Q_strcmp(file, other->file)) + if (strcmp(file, other->file) == 0) return mTRUE; + + if (status >= PL_OPENED && other->status >= PL_OPENED && + strcmp(info->logtag, other->info->logtag) == 0) return mTRUE; + if (*desc != '\0' && _stricmp(desc, other->desc) == 0) return mTRUE; - if (status >= PL_OPENED && other->status >= PL_OPENED && !Q_strcmp(info->logtag, other->info->logtag)) - return mTRUE; + end = strrchr(file, '_'); + if (end == NULL || !is_platform_postfix(end)) end = strrchr(file, '.'); + other_end = strrchr(other->file, '_'); + if (other_end == NULL || !is_platform_postfix(other_end)) other_end = strrchr(other->file, '.'); - if (*desc != '\0' && !Q_stricmp(desc,other->desc)) - return mTRUE; + if (end == NULL || other_end == NULL) return mFALSE; - end=Q_strrchr(file, '_'); - if (end == NULL || !is_platform_postfix(end)) - end=Q_strrchr(file, '.'); + prefixlen = end - file; + if ((other_end - other->file) != prefixlen) return mFALSE; - other_end=Q_strrchr(other->file, '_'); - if (other_end == NULL || !is_platform_postfix(other_end)) - other_end=Q_strrchr(other->file, '.'); - - if (end == NULL || other_end == NULL) - return mFALSE; - - prefixlen=end-file; - if ((other_end-other->file) != prefixlen) - return mFALSE; - - if (!Q_strncmp(file,other->file, prefixlen)) - return mTRUE; + if (strncmp(file, other->file, prefixlen) == 0) return mTRUE; return mFALSE; } + // Load a plugin; query, check allowed time, attach. // meta_errno values: // - ME_ARGUMENT missing necessary fields in plugin @@ -534,61 +554,51 @@ mBOOL MPlugin::platform_match(MPlugin *other) // - errno's from check_input() mBOOL MPlugin::load(PLUG_LOADTIME now) { - if (!check_input()) - { + if (!check_input()) { // details logged, meta_errno set in check_input() RETURN_ERRNO(mFALSE, ME_ARGUMENT); } - if (status >= PL_RUNNING) - { - META_WARNING("dll: Not loading plugin '%s'; already loaded (status=%s)", - desc, str_status()); + if (status >= PL_RUNNING) { + META_ERROR("dll: Not loading plugin '%s'; already loaded (status=%s)", + desc, str_status()); RETURN_ERRNO(mFALSE, ME_ALREADY); } - if (action != PA_LOAD && action != PA_ATTACH && action != PA_RELOAD) - { - META_WARNING("dll: Not loading plugin '%s'; not marked for load (action=%s)", desc, str_action()); + if (action != PA_LOAD && action != PA_ATTACH) { + META_ERROR("dll: Not loading plugin '%s'; not marked for load (action=%s)", desc, str_action()); RETURN_ERRNO(mFALSE, ME_BADREQ); } - if (status <= PL_OPENED) - { + if (status < PL_OPENED) { // query plugin; open file and get info about it - if (!query()) - { - META_WARNING("dll: Skipping plugin '%s'; couldn't query", desc); - if (meta_errno != ME_DLOPEN) - { - if (DLCLOSE(handle) != 0) - { - META_WARNING("dll: Couldn't close plugin file '%s': %s", file, DLERROR()); + if (!query()) { + META_ERROR("dll: Skipping plugin '%s'; couldn't query", desc); + if (meta_errno != ME_DLOPEN) { + if (DLCLOSE(handle) != 0) { + META_ERROR("dll: Couldn't close plugin file '%s': %s", + file, DLERROR()); } else - handle = nullptr; + handle = NULL; } - status = PL_BADFILE; - info = nullptr; // prevent crash - + info = NULL; //prevent crash // meta_errno should be already set in query() - return mFALSE; + return (mFALSE); } status = PL_OPENED; } // are we allowed to attach this plugin at this time? - if (info->loadable < now) - { - if (info->loadable > PT_STARTUP) - { + if (info->loadable < now) { + if (info->loadable > PT_STARTUP) { // will try to attach again at next opportunity - META_DEBUG(2, ("dll: Delaying load plugin '%s'; can't attach now: allowed=%s; now=%s", desc, str_loadable(), str_loadtime(now, SL_SIMPLE))); + META_DEBUG(2, ("dll: Delaying load plugin '%s'; can't attach now: allowed=%s; now=%s", + desc, str_loadable(), str_loadtime(now, SL_SIMPLE))); RETURN_ERRNO(mFALSE, ME_DELAYED); } - else - { - META_DEBUG(2, ("dll: Failed load plugin '%s'; can't attach now: allowed=%s; now=%s", desc, str_loadable(), str_loadtime(now, SL_SIMPLE))); - + else { + META_DEBUG(2, ("dll: Failed load plugin '%s'; can't attach now: allowed=%s; now=%s", + desc, str_loadable(), str_loadtime(now, SL_SIMPLE))); // don't try to attach again later action = PA_NONE; RETURN_ERRNO(mFALSE, ME_NOTALLOWED); @@ -596,64 +606,59 @@ mBOOL MPlugin::load(PLUG_LOADTIME now) } // attach plugin; get function tables - if (attach(now) != mTRUE) - { - META_WARNING("dll: Failed to attach plugin '%s'", desc); + if (attach(now) != mTRUE) { + META_ERROR("dll: Failed to attach plugin '%s'", desc); // Note we don't dlclose() here, since we're returning PL_FAILED, // which implies that it's been dlopened and queried successfully. // Doing so causes crashes, because things like "meta list" try to // look at *info, which is in the DLL memory space and unaccessible // (segfault) after dlclosed. - status = PL_FAILED; // meta_errno should be already set in attach() - return mFALSE; + return (mFALSE); } - status = PL_RUNNING; action = PA_NONE; // If not loading at server startup, then need to call plugin's // GameInit, since we've passed that. - if (now != PT_STARTUP) - { - FN_GAMEINIT pfn_gameinit = nullptr; - if (tables.dllapi && (pfn_gameinit=tables.dllapi->pfnGameInit)) + if (now != PT_STARTUP) { + FN_GAMEINIT pfn_gameinit = NULL; + if (dllapi_table && (pfn_gameinit = dllapi_table->pfnGameInit)) pfn_gameinit(); } - // If loading during map, then I'd like to call plugin's // ServerActivate, since we've passed that. However, I'm not sure what // arguments to give it... So, we'll just have to say for the // moment that plugins that are loadable during a map can't need to // hook ServerActivate. - META_LOG("dll: Loaded plugin '%s': %s v%s %s, %s", desc, info->name, info->version, info->date, info->author); - return mTRUE; + + META_LOG("dll: Loaded plugin '%s': %s v%s %s, %s", desc, info->name, + info->version, info->date, info->author); + return (mTRUE); } // Query a plugin: // - dlopen() the file, store the handle // - dlsym() and call: // Meta_Init (if present) - tell dll it'll be used as a metamod plugin -// GiveFnptrsToDll - give engine function ptrs +// GiveFnptrsToDll - give engine function ptrs // Meta_Query - say "hi" and get info about plugin // meta_errno values: // - ME_DLOPEN dlopen/loadlibrary failed; see dlerror() for details // - ME_DLMISSING couldn't find a query() or giveFuncs() in plugin // - ME_DLERROR plugin query() returned error // - ME_NULLDATA info struct from query() was null -mBOOL MPlugin::query() +mBOOL MPlugin::query(void) { - int plugin_pext_version; - META_GIVE_PEXT_FUNCTIONS_FN pfn_give_pext_funcs; META_INIT_FN pfn_init; GIVE_ENGINE_FUNCTIONS_FN pfn_give_engfuncs; META_QUERY_FN pfn_query; // open the plugin DLL - if (!(handle = DLOPEN(pathname))) - { - META_WARNING("dll: Failed query plugin '%s'; Couldn't open file '%s': %s", desc, pathname, DLERROR()); + if (!(handle = DLOPEN(pathname))) { + META_ERROR("dll: Failed query plugin '%s'; Couldn't open file '%s': %s", + desc, pathname, DLERROR()); RETURN_ERRNO(mFALSE, ME_DLOPEN); } @@ -663,21 +668,20 @@ mBOOL MPlugin::query() // startup in GiveFnptrsToDll, and trying to load them as metamod // plugins creates all sorts of crashes. So, we do a trivial check // first to see if the DLL looks like a metamod plugin before - // proceeding with the normal order. Note that we still have to call - // GiveFnptrsToDll before Meta_Query, because the latter typically uses - // engine functions like AlertMessage, which have to be passed along via + // proceeding with the normal order. Note that we still have to call + // GiveFnptrsToDll before Meta_Query, because the latter typically uses + // engine functions like AlertMessage, which have to be passed along via // GiveFnptrsToDll. pfn_query = (META_QUERY_FN) DLSYM(handle, "Meta_Query"); - if (!pfn_query) - { - META_WARNING("dll: Failed query plugin '%s'; Couldn't find Meta_Query(): %s", desc, DLERROR()); + if (!pfn_query) { + META_ERROR("dll: Failed query plugin '%s'; Couldn't find Meta_Query(): %s", desc, DLERROR()); // caller will dlclose() RETURN_ERRNO(mFALSE, ME_DLMISSING); } // Call Meta_Init, if present. This is an optional plugin routine to // allow plugin to do any special initializing or other processing - // prior to the standard query/attach procedure. + // prior to the standard query/attach procedure. // // In particular, this should allow for DLL's that can operate as both // a standalone dll AND a metamod plugin. This routine has to be @@ -687,80 +691,70 @@ mBOOL MPlugin::query() // startup needed for a standalone DLL. // // This passes nothing and returns nothing, and the routine in the - // plugin can NOT use any Engine functions, as they haven't been + // plugin can NOT use any g_engine functions, as they haven't been // provided yet (done next, in GiveFnptrsToDll). pfn_init = (META_INIT_FN) DLSYM(handle, "Meta_Init"); - if (pfn_init) - { + if (pfn_init) { pfn_init(); META_DEBUG(6, ("dll: Plugin '%s': Called Meta_Init()", desc)); } - else - { + else { META_DEBUG(5, ("dll: no Meta_Init present in plugin '%s'", desc)); // don't return; not an error } // pass on engine function table and globals to plugin - if (!(pfn_give_engfuncs = (GIVE_ENGINE_FUNCTIONS_FN) DLSYM(handle, "GiveFnptrsToDll"))) - { - // META_WARNING("dll: Couldn't find GiveFnptrsToDll() in plugin '%s': %s", desc, DLERROR()); - META_WARNING("dll: Failed query plugin '%s'; Couldn't find GiveFnptrsToDll(): %s", desc, DLERROR()); - + if (!(pfn_give_engfuncs = (GIVE_ENGINE_FUNCTIONS_FN) DLSYM(handle, "GiveFnptrsToDll"))) { + // META_ERROR("dll: Couldn't find GiveFnptrsToDll() in plugin '%s': %s", desc, DLERROR()); + META_ERROR("dll: Failed query plugin '%s'; Couldn't find GiveFnptrsToDll(): %s", desc, DLERROR()); // caller will dlclose() RETURN_ERRNO(mFALSE, ME_DLMISSING); } - - pfn_give_engfuncs(Engine.pl_funcs, Engine.globals); + pfn_give_engfuncs(g_engine.pl_funcs, g_engine.globals); META_DEBUG(6, ("dll: Plugin '%s': Called GiveFnptrsToDll()", desc)); // Call plugin's Meta_Query(), to pass our meta interface version, and get // plugin's info structure. meta_errno = ME_NOERROR; - info = nullptr; - + info = NULL; // Make a copy of the meta_util function table for each plugin, for the // same reason. - Q_memcpy(&mutil_funcs, &MetaUtilFunctions, sizeof(mutil_funcs)); + memcpy(&mutil_funcs, &MetaUtilFunctions, sizeof(mutil_funcs)); - if (pfn_query(META_INTERFACE_VERSION, &info, &mutil_funcs)) - { - META_DEBUG(6, ("dll: Plugin '%s': Called Meta_Query() successfully", desc)); - } - else - { - META_WARNING("dll: Failed query plugin '%s'; Meta_Query returned error", desc); + if (pfn_query(META_INTERFACE_VERSION, &info, &mutil_funcs) != TRUE) { + META_ERROR("dll: Failed query plugin '%s'; Meta_Query returned error", + desc); meta_errno = ME_DLERROR; } + else { + META_DEBUG(6, ("dll: Plugin '%s': Called Meta_Query() successfully", + desc)); + } // Check for interface differences... Generally, a difference in major // version will be incompatible, and a plugin that expects a later // minor version will be incompatible (it's expecting things that this - // Metamod won't be supplying). Plugins that use an older minor + // Metamod won't be supplying). g_plugins that use an older minor // version will still work, as backward-compability within major // version is expected (forward-compatibility is not). // // Note, this check is done regardless of whether meta_query returns an // error. - if (info && !FStrEq(info->ifvers, META_INTERFACE_VERSION)) - { + if (info && !FStrEq(info->ifvers, META_INTERFACE_VERSION)) { int mmajor = 0, mminor = 0, pmajor = 0, pminor = 0; META_DEBUG(3, ("dll: Note: Plugin '%s' interface version didn't match; expected %s, found %s", desc, META_INTERFACE_VERSION, info->ifvers)); sscanf(META_INTERFACE_VERSION, "%d:%d", &mmajor, &mminor); sscanf(info->ifvers, "%d:%d", &pmajor, &pminor); - - // If plugin has later interface version, it's incompatible + // If plugin has later interface version, it's incompatible // (update metamod). - if (pmajor > mmajor || (pmajor == mmajor && pminor > mminor)) - { - META_WARNING("dll: Plugin '%s' requires a newer version of Metamod (Metamod needs at least interface %s not the current %s)", desc, info->ifvers, META_INTERFACE_VERSION); + if (pmajor > mmajor || (pmajor == mmajor && pminor > mminor)) { + META_ERROR("dll: Plugin '%s' requires a newer version of Metamod (Metamod needs at least interface %s not the current %s)", desc, info->ifvers, META_INTERFACE_VERSION); meta_errno = ME_IFVERSION; } // If plugin has older major interface version, it's incompatible // (update plugin). - else if (pmajor < mmajor) - { - META_WARNING("dll: Plugin '%s' is out of date and incompatible with this version of Metamod; please find a newer version of the plugin (plugin needs at least interface %s not the current %s)", desc, META_INTERFACE_VERSION, info->ifvers); + else if (pmajor < mmajor) { + META_ERROR("dll: Plugin '%s' is out of date and incompatible with this version of Metamod; please find a newer version of the plugin (plugin needs at least interface %s not the current %s)", desc, META_INTERFACE_VERSION, info->ifvers); meta_errno = ME_IFVERSION; } // Plugin has identical major, with older minor. This is supposed to be @@ -768,58 +762,38 @@ mBOOL MPlugin::query() else if (pmajor == mmajor && pminor < mminor) META_LOG("dll: Note: plugin '%s' is using an older interface version (%s), not the latest interface version (%s); there might be an updated version of the plugin", desc, info->ifvers, META_INTERFACE_VERSION); else - META_LOG("dll: Plugin '%s': unexpected version comparision; metavers=%s, mmajor=%d, mminor=%d; plugvers=%s, pmajor=%d, pminor=%d", desc, META_INTERFACE_VERSION, mmajor, mminor, info->ifvers, pmajor, pminor); + META_LOG("dll: Plugin '%s': unexpected version comparision; metavers=%s, mmajor=%d, mminor=%d; plugvers=%s, pmajor=%d, pminor=%d", + desc, META_INTERFACE_VERSION, mmajor, mminor, info->ifvers, pmajor, pminor); } - if (meta_errno == ME_IFVERSION) - { - META_WARNING("dll: Rejected plugin '%s' due to interface version incompatibility (mm=%s, pl=%s)", desc, META_INTERFACE_VERSION, info->ifvers); - + if (meta_errno == ME_IFVERSION) { + META_ERROR("dll: Rejected plugin '%s' due to interface version incompatibility (mm=%s, pl=%s)", desc, META_INTERFACE_VERSION, info->ifvers); // meta_errno is set already above // caller will dlclose() - return mFALSE; + return (mFALSE); } else if (meta_errno != ME_NOERROR) - { - // some other error, already logged - return mFALSE; - } - - if (!info) - { - META_WARNING("dll: Failed query plugin '%s'; Empty info structure", desc); + // some other error, already logged + return (mFALSE); + if (!info) { + META_ERROR("dll: Failed query plugin '%s'; Empty info structure", desc); // caller will dlclose() RETURN_ERRNO(mFALSE, ME_NULLRESULT); } // Replace temporary desc with plugin's internal name. - if (desc[0] == '<') - { - Q_strncpy(desc, info->name, sizeof(desc) - 1); - desc[sizeof(desc) - 1] = '\0'; + if (desc[0] == '<') { + strncpy(desc, info->name, sizeof desc - 1); + desc[sizeof desc - 1] = '\0'; } - - // Give plugin the p-series extension function table. - // Check for version differences! - if ((pfn_give_pext_funcs = (META_GIVE_PEXT_FUNCTIONS_FN)DLSYM(handle, "Meta_PExtGiveFnptrs"))) - { - plugin_pext_version = (*pfn_give_pext_funcs)(META_PEXT_VERSION, (pextension_funcs_t*)(&(mutil_funcs.pfnLoadPlugin))); - - // if plugin is newer, we got incompatibility problem! - if (plugin_pext_version > META_PEXT_VERSION) - { - META_WARNING("dll: Plugin '%s' requires a newer version of Metamod-P (extension interface needs to be at least %d not the current %d)", desc, plugin_pext_version, META_PEXT_VERSION); - } - } - META_DEBUG(6, ("dll: Plugin '%s': Query successful", desc)); - return mTRUE; + return (mTRUE); } // Attach a plugin: // - dlsym() and call: // Meta_Attach - get table of api tables, give meta_globals -// - if provided by plugin, call various "Get" function pointers, +// - if provided by plugin, call various "Get" function pointers, // and store resulting function tables: // GetEntityAPI (std) // GetEntityAPI2 (std sdk2) @@ -845,48 +819,35 @@ mBOOL MPlugin::attach(PLUG_LOADTIME now) // Make copy of gameDLL's function tables for each plugin, so we don't // risk the plugins screwing with the tables everyone uses. - if (!gamedll_funcs.dllapi_table) - { - gamedll_funcs.dllapi_table = (DLL_FUNCTIONS *) calloc(1, sizeof(DLL_FUNCTIONS)); - if (!gamedll_funcs.dllapi_table) - { - META_WARNING("dll: Failed attach plugin '%s': Failed malloc() for dllapi_table"); + if (GameDLL.funcs.dllapi_table && !gamedll_funcs.dllapi_table) { + gamedll_funcs.dllapi_table = (DLL_FUNCTIONS *) malloc(sizeof(DLL_FUNCTIONS)); + if (!gamedll_funcs.dllapi_table) { + META_ERROR("dll: Failed attach plugin '%s': Failed malloc() for dllapi_table"); RETURN_ERRNO(mFALSE, ME_NOMEM); } - if (GameDLL.funcs.dllapi_table) - Q_memcpy(gamedll_funcs.dllapi_table, GameDLL.funcs.dllapi_table, sizeof(DLL_FUNCTIONS)); - else - Q_memset(gamedll_funcs.dllapi_table, 0, sizeof(DLL_FUNCTIONS)); + memcpy(gamedll_funcs.dllapi_table, GameDLL.funcs.dllapi_table, + sizeof(DLL_FUNCTIONS)); } - - if (!gamedll_funcs.newapi_table) - { - gamedll_funcs.newapi_table = (NEW_DLL_FUNCTIONS *) calloc(1, sizeof(NEW_DLL_FUNCTIONS)); - if (!gamedll_funcs.newapi_table) - { - META_WARNING("dll: Failed attach plugin '%s': Failed malloc() for newapi_table"); + if (GameDLL.funcs.newapi_table && !gamedll_funcs.newapi_table) { + gamedll_funcs.newapi_table = (NEW_DLL_FUNCTIONS *) calloc(1, sizeof(meta_new_dll_functions_t)); + if (!gamedll_funcs.newapi_table) { + META_ERROR("dll: Failed attach plugin '%s': Failed malloc() for newapi_table"); RETURN_ERRNO(mFALSE, ME_NOMEM); } - if (GameDLL.funcs.newapi_table) - Q_memcpy(gamedll_funcs.newapi_table, GameDLL.funcs.newapi_table, sizeof(NEW_DLL_FUNCTIONS)); - else - Q_memset(gamedll_funcs.newapi_table, 0, sizeof(NEW_DLL_FUNCTIONS)); + static_cast(gamedll_funcs.newapi_table)->set_from(GameDLL.funcs.newapi_table); } - - if (!(pfn_attach = (META_ATTACH_FN) DLSYM(handle, "Meta_Attach"))) - { - META_WARNING("dll: Failed attach plugin '%s': Couldn't find Meta_Attach(): %s", desc, DLERROR()); + if (!(pfn_attach = (META_ATTACH_FN) DLSYM(handle, "Meta_Attach"))) { + META_ERROR("dll: Failed attach plugin '%s': Couldn't find Meta_Attach(): %s", desc, DLERROR()); // caller will dlclose() RETURN_ERRNO(mFALSE, ME_DLMISSING); } - Q_memset(&meta_table, 0, sizeof(meta_table)); + memset(&meta_table, 0, sizeof(meta_table)); // get table of function tables, // give public meta globals ret = pfn_attach(now, &meta_table, &PublicMetaGlobals, &gamedll_funcs); - if (ret != TRUE) - { - META_WARNING("dll: Failed attach plugin '%s': Error from Meta_Attach(): %d", desc, ret); + if (ret != TRUE) { + META_ERROR("dll: Failed attach plugin '%s': Error from Meta_Attach(): %d", desc, ret); // caller will dlclose() RETURN_ERRNO(mFALSE, ME_DLERROR); } @@ -894,124 +855,91 @@ mBOOL MPlugin::attach(PLUG_LOADTIME now) // Rather than duplicate code, we use another ugly macro. Again, // a function isn't an option since we have varying types. -#define GET_FUNC_TABLE_FROM_PLUGIN(pfnGetFuncs, STR_GetFuncs, struct_field, API_TYPE, TABLE_TYPE, TABLE_SIZE, vers_pass, vers_int, vers_want)\ - if (meta_table.pfnGetFuncs) {\ - if (!struct_field) {\ - struct_field = (TABLE_TYPE*)calloc(1, TABLE_SIZE);\ - } else {\ - Q_memset(struct_field, 0, TABLE_SIZE);\ - }\ - if (meta_table.pfnGetFuncs(struct_field, vers_pass)) {\ - META_DEBUG(3, ("dll: Plugin '%s': Found %s", desc, STR_GetFuncs));\ - }\ - else {\ - META_WARNING("dll: Failure calling %s in plugin '%s'", STR_GetFuncs, desc);\ - if (vers_int != vers_want)\ - META_WARNING("dll: Interface version didn't match; expected %d, found %d", vers_want, vers_int);\ - }\ - }\ - else {\ - META_DEBUG(5, ("dll: Plugin '%s': No %s", desc, STR_GetFuncs));\ - if (struct_field)\ - free(struct_field);\ - struct_field = nullptr;\ +#define GET_FUNC_TABLE_FROM_PLUGIN(pfnGetFuncs, STR_GetFuncs, struct_field, API_TYPE, TABLE_TYPE, vers_pass, vers_int, vers_want) \ + if(meta_table.pfnGetFuncs) { \ + if (!struct_field) \ + struct_field = (TABLE_TYPE*) calloc(1, sizeof(TABLE_TYPE)); \ + if(meta_table.pfnGetFuncs(struct_field, vers_pass)) { \ + META_DEBUG(3, ("dll: Plugin '%s': Found %s", desc, STR_GetFuncs)); \ + } \ + else { \ + META_ERROR("dll: Failure calling %s in plugin '%s'", STR_GetFuncs, desc); \ + if(vers_int != vers_want) \ + META_ERROR("dll: Interface version didn't match; expected %d, found %d", vers_want, vers_int); \ + } \ + } \ + else { \ + META_DEBUG(5, ("dll: Plugin '%s': No %s", desc, STR_GetFuncs)); \ + if (struct_field) \ + free(struct_field); \ + struct_field=NULL; \ } // Look for API-NEW interface in plugin. We do this before API2/API, because // that's what the engine appears to do.. + // [But we only do this if the gamedll provides these, so that we don't + // give a plugin the idea that we'll call them, when in fact we won't + // (since we don't export them to the engine when the gamedll doesn't + // provide them).] + // We now do this even when the gamedll doesn't provide these because + // the plugins might want to use new functions like CvarValue() also + // with older gamedlls which do not use the API-NEW themselves. + // It is yet unknown if this causes any problems in the engine. iface_vers = NEW_DLL_FUNCTIONS_VERSION; - GET_FUNC_TABLE_FROM_PLUGIN(pfnGetNewDLLFunctions, "GetNewDLLFunctions", tables.newapi, NEW_DLL_FUNCTIONS_FN, NEW_DLL_FUNCTIONS, sizeof(NEW_DLL_FUNCTIONS), &iface_vers, iface_vers, NEW_DLL_FUNCTIONS_VERSION); - + GET_FUNC_TABLE_FROM_PLUGIN(pfnGetNewDLLFunctions, + "GetNewDLLFunctions", newapi_table, + NEW_DLL_FUNCTIONS_FN, meta_new_dll_functions_t, + &iface_vers, iface_vers, NEW_DLL_FUNCTIONS_VERSION); iface_vers = NEW_DLL_FUNCTIONS_VERSION; - GET_FUNC_TABLE_FROM_PLUGIN(pfnGetNewDLLFunctions_Post, "GetNewDLLFunctions_Post", post_tables.newapi, NEW_DLL_FUNCTIONS_FN, NEW_DLL_FUNCTIONS, sizeof(NEW_DLL_FUNCTIONS), &iface_vers, iface_vers, NEW_DLL_FUNCTIONS_VERSION); + GET_FUNC_TABLE_FROM_PLUGIN(pfnGetNewDLLFunctions_Post, + "GetNewDLLFunctions_Post", newapi_post_table, + NEW_DLL_FUNCTIONS_FN, meta_new_dll_functions_t, + &iface_vers, iface_vers, NEW_DLL_FUNCTIONS_VERSION); // Look for API2 interface in plugin; preferred over API-1. iface_vers = INTERFACE_VERSION; - GET_FUNC_TABLE_FROM_PLUGIN(pfnGetEntityAPI2, "GetEntityAPI2", tables.dllapi, APIFUNCTION2, DLL_FUNCTIONS, sizeof(DLL_FUNCTIONS), &iface_vers, iface_vers, INTERFACE_VERSION); - + GET_FUNC_TABLE_FROM_PLUGIN(pfnGetEntityAPI2, + "GetEntityAPI2", dllapi_table, + APIFUNCTION2, DLL_FUNCTIONS, + &iface_vers, iface_vers, INTERFACE_VERSION); iface_vers = INTERFACE_VERSION; - GET_FUNC_TABLE_FROM_PLUGIN(pfnGetEntityAPI2_Post, "GetEntityAPI2_Post", post_tables.dllapi, APIFUNCTION2, DLL_FUNCTIONS, sizeof(DLL_FUNCTIONS), &iface_vers, iface_vers, INTERFACE_VERSION); + GET_FUNC_TABLE_FROM_PLUGIN(pfnGetEntityAPI2_Post, + "GetEntityAPI2_Post", dllapi_post_table, + APIFUNCTION2, DLL_FUNCTIONS, + &iface_vers, iface_vers, INTERFACE_VERSION); // Look for old-style API in plugin, if API2 interface wasn't found. - if (!tables.dllapi && !post_tables.dllapi) - { - GET_FUNC_TABLE_FROM_PLUGIN(pfnGetEntityAPI, "GetEntityAPI", tables.dllapi, APIFUNCTION, DLL_FUNCTIONS, sizeof(DLL_FUNCTIONS), INTERFACE_VERSION, INTERFACE_VERSION, INTERFACE_VERSION); - GET_FUNC_TABLE_FROM_PLUGIN(pfnGetEntityAPI_Post, "GetEntityAPI_Post", post_tables.dllapi, APIFUNCTION, DLL_FUNCTIONS, sizeof(DLL_FUNCTIONS), INTERFACE_VERSION, INTERFACE_VERSION, INTERFACE_VERSION); + if (!dllapi_table && !dllapi_post_table) { + GET_FUNC_TABLE_FROM_PLUGIN(pfnGetEntityAPI, + "GetEntityAPI", dllapi_table, + APIFUNCTION, DLL_FUNCTIONS, + INTERFACE_VERSION, INTERFACE_VERSION, INTERFACE_VERSION); + GET_FUNC_TABLE_FROM_PLUGIN(pfnGetEntityAPI_Post, + "GetEntityAPI_Post", dllapi_post_table, + APIFUNCTION, DLL_FUNCTIONS, + INTERFACE_VERSION, INTERFACE_VERSION, INTERFACE_VERSION); } - // Look for Engine interface. + // Look for g_engine interface. iface_vers = ENGINE_INTERFACE_VERSION; - GET_FUNC_TABLE_FROM_PLUGIN(pfnGetEngineFunctions, "GetEngineFunctions", tables.engine, GET_ENGINE_FUNCTIONS_FN, enginefuncs_t, sizeof(enginefuncs_t), &iface_vers, iface_vers, ENGINE_INTERFACE_VERSION); - + GET_FUNC_TABLE_FROM_PLUGIN(pfnGetEngineFunctions, + "GetEngineFunctions", engine_table, + GET_ENGINE_FUNCTIONS_FN, meta_enginefuncs_t, + &iface_vers, iface_vers, ENGINE_INTERFACE_VERSION); iface_vers = ENGINE_INTERFACE_VERSION; - GET_FUNC_TABLE_FROM_PLUGIN(pfnGetEngineFunctions_Post, "GetEngineFunctions_Post", post_tables.engine, GET_ENGINE_FUNCTIONS_FN, enginefuncs_t, sizeof(enginefuncs_t), &iface_vers, iface_vers, ENGINE_INTERFACE_VERSION); + GET_FUNC_TABLE_FROM_PLUGIN(pfnGetEngineFunctions_Post, + "GetEngineFunctions_Post", engine_post_table, + GET_ENGINE_FUNCTIONS_FN, meta_enginefuncs_t, + &iface_vers, iface_vers, ENGINE_INTERFACE_VERSION); - if (!tables.dllapi && !post_tables.dllapi - && !tables.newapi && !post_tables.newapi - && !tables.engine && !post_tables.engine) - { + if (!dllapi_table && !dllapi_post_table + && !newapi_table && !newapi_post_table + && !engine_table && !engine_post_table) { META_LOG("dll: Plugin '%s' isn't catching _any_ functions ??", desc); } time_loaded = time(NULL); - return mTRUE; -} - -// Unload a plugin from plugin request -// meta_errno values: -// - errno's from unload() -mBOOL MPlugin::plugin_unload(plid_t plid, PLUG_LOADTIME now, PL_UNLOAD_REASON reason) -{ - PLUG_ACTION old_action; - MPlugin *pl_unloader; - - // try find unloader - if (!(pl_unloader = Plugins->find(plid))) - { - META_WARNING("dll: Not unloading plugin '%s'; plugin that requested unload is not found.", desc); - RETURN_ERRNO(mFALSE, ME_BADREQ); - } - // self check. Do not allow plugin to unload itself! - else if (pl_unloader->index == index) - { - META_WARNING("dll: Not unloading plugin '%s'; Plugin tried to unload itself.", desc); - RETURN_ERRNO(mFALSE, ME_UNLOAD_SELF); - } - // safe check. Do not allow active unloader to be unloaded! - else if (is_unloader) - { - META_WARNING("dll: Not unloading plugin '%s'; Plugin is unloading plugin that tried to unload it.", desc); - RETURN_ERRNO(mFALSE, ME_UNLOAD_UNLOADER); - } - else - { - unloader_index = pl_unloader->index; - } - - // block unloader from being unloaded by other plugin - pl_unloader->is_unloader = mTRUE; - - // try unload - old_action = action; - action = PA_UNLOAD; - if (unload(now, reason, (reason == PNL_CMD_FORCED) ? PNL_PLG_FORCED : PNL_PLUGIN)) - { - META_DEBUG(1,("Unloaded plugin '%s'", desc)); - pl_unloader->is_unloader = mFALSE; - return mTRUE; - } - - pl_unloader->is_unloader = mFALSE; - - // Cannot unload plugin now. Don't set delayed mode. - if (meta_errno == ME_DELAYED) - { - action = old_action; - meta_errno = ME_NOTALLOWED; - META_DEBUG(2, ("dll: Failed unload plugin '%s'; can't detach now: allowed=%s; now=%s", desc, str_unloadable(), str_loadtime(PT_ANYTIME, SL_SIMPLE))); - } - - return mFALSE; + return (mTRUE); } // Unload a plugin. Check time, detach. @@ -1024,46 +952,35 @@ mBOOL MPlugin::plugin_unload(plid_t plid, PLUG_LOADTIME now, PL_UNLOAD_REASON re // - errno's from check_input() mBOOL MPlugin::unload(PLUG_LOADTIME now, PL_UNLOAD_REASON reason, PL_UNLOAD_REASON real_reason) { - if (!check_input()) - { + if (!check_input()) { // details logged, meta_errno set in check_input() RETURN_ERRNO(mFALSE, ME_ARGUMENT); } - if (status < PL_RUNNING) - { - if (reason != PNL_CMD_FORCED && reason != PNL_RELOAD) - { - META_WARNING("dll: Not unloading plugin '%s'; already unloaded (status=%s)", desc, str_status()); + if (status < PL_RUNNING) { + if (reason != PNL_CMD_FORCED && reason != PNL_RELOAD) { + META_ERROR("dll: Not unloading plugin '%s'; already unloaded (status=%s)", desc, str_status()); RETURN_ERRNO(mFALSE, ME_ALREADY); } } - - if (action != PA_UNLOAD && action != PA_RELOAD) - { + if (action != PA_UNLOAD && action != PA_RELOAD) { META_WARNING("dll: Not unloading plugin '%s'; not marked for unload (action=%s)", desc, str_action()); RETURN_ERRNO(mFALSE, ME_BADREQ); } // Are we allowed to detach this plugin at this time? // If forcing unload, we disregard when plugin wants to be unloaded. - if (info && info->unloadable < now) - { - if (reason == PNL_CMD_FORCED) - { + if (info && info->unloadable < now) { + if (reason == PNL_CMD_FORCED) { META_DEBUG(2, ("dll: Forced unload plugin '%s' overriding allowed times: allowed=%s; now=%s", desc, str_unloadable(), str_loadtime(now, SL_SIMPLE))); } - else - { - if (info->unloadable > PT_STARTUP) - { + else { + if (info->unloadable > PT_STARTUP) { META_DEBUG(2, ("dll: Delaying unload plugin '%s'; can't detach now: allowed=%s; now=%s", desc, str_unloadable(), str_loadtime(now, SL_SIMPLE))); - // caller should give message to user // try to unload again at next opportunity RETURN_ERRNO(mFALSE, ME_DELAYED); } - else - { + else { META_DEBUG(2, ("dll: Failed unload plugin '%s'; can't detach now: allowed=%s; now=%s", desc, str_unloadable(), str_loadtime(now, SL_SIMPLE))); // don't try to unload again later action = PA_NONE; @@ -1078,65 +995,58 @@ mBOOL MPlugin::unload(PLUG_LOADTIME now, PL_UNLOAD_REASON reason, PL_UNLOAD_REAS // indicates these two routines should match call for call. // detach plugin - if (!detach(now, reason)) - { - if (reason == PNL_RELOAD) - { + if (!detach(now, reason)) { + if (reason == PNL_RELOAD) { META_DEBUG(2, ("dll: Reload plugin '%s' overriding failed detach", desc)); } - else if (reason == PNL_CMD_FORCED) - { - META_DEBUG(2, ("dll: Forced unload plugin '%s' overriding failed detach", desc)); + else if (reason == PNL_CMD_FORCED) { + META_DEBUG(2, ("dll: Forced unload plugin '%s' overriding failed detach")); } - else - { + else { META_WARNING("dll: Failed to detach plugin '%s'; ", desc); // meta_errno should be already set in detach() - return mFALSE; + return (mFALSE); } } + g_plugins->clear_source_plugin_index(index); + // successful detach, or forced unload - // clear source_plugin_index for all plugins that this plugin has loaded - Plugins->clear_source_plugin_index(index); - // Unmark registered commands for this plugin (by index number). - RegCmds->disable(index); - + g_regCmds->disable(index); // Unmark registered cvars for this plugin (by index number). - RegCvars->disable(index); + g_regCvars->disable(index); + +#ifdef UNFINISHED + // Remove all requested hooks from this plugin (by index number). + Hooks->remove_all(info); +#endif /* UNFINISHED */ // Close the file. Note: after this, attempts to reference any memory // locations in the file will produce a segfault. - if (DLCLOSE(handle) != 0) - { + if (DLCLOSE(handle) != 0) { // If DLL cannot be closed, OS is badly broken or we are giving invalid handle. // So we don't return here but instead remove plugin from our listings. - META_WARNING("dll: Couldn't dlclose plugin file '%s': %s", file, DLERROR()); + META_WARNING("dll: Couldn't close plugin file '%s': %s", file, DLERROR()); } + handle = NULL; - handle = nullptr; - - if (action == PA_UNLOAD) - { + if (action == PA_UNLOAD) { status = PL_EMPTY; clear(); } - else if (action == PA_RELOAD) - { + else if (action == PA_RELOAD) { status = PL_VALID; action = PA_LOAD; clear(); } - META_LOG("dll: Unloaded plugin '%s' for reason '%s'", desc, str_reason(reason, real_reason)); - return mTRUE; + return (mTRUE); } // Inform plugin we're going to unload it. // meta_errno values: -// - // - ME_DLMISSING couldn't find meta_detach() in plugin // - ME_DLERROR plugin detach() returned error mBOOL MPlugin::detach(PLUG_LOADTIME now, PL_UNLOAD_REASON reason) @@ -1150,22 +1060,19 @@ mBOOL MPlugin::detach(PLUG_LOADTIME now, PL_UNLOAD_REASON reason) if (!handle) return mTRUE; - if (!(pfn_detach = (META_DETACH_FN) DLSYM(handle, "Meta_Detach"))) - { - META_WARNING("dll: Error detach plugin '%s': Couldn't find Meta_Detach(): %s", desc, DLERROR()); + if (!(pfn_detach = (META_DETACH_FN) DLSYM(handle, "Meta_Detach"))) { + META_ERROR("dll: Error detach plugin '%s': Couldn't find Meta_Detach(): %s", desc, DLERROR()); // caller will dlclose() RETURN_ERRNO(mFALSE, ME_DLMISSING); } ret = pfn_detach(now, reason); - if (ret != TRUE) - { - META_WARNING("dll: Failed detach plugin '%s': Error from Meta_Detach(): %d", desc, ret); + if (ret != TRUE) { + META_ERROR("dll: Failed detach plugin '%s': Error from Meta_Detach(): %d", desc, ret); RETURN_ERRNO(mFALSE, ME_DLERROR); } - META_DEBUG(6, ("dll: Plugin '%s': Called Meta_Detach() successfully", desc)); - return mTRUE; + return (mTRUE); } // Reload a plugin; unload and load again. @@ -1176,25 +1083,20 @@ mBOOL MPlugin::detach(PLUG_LOADTIME now, PL_UNLOAD_REASON reason) // - errno's from load() mBOOL MPlugin::reload(PLUG_LOADTIME now, PL_UNLOAD_REASON reason) { - if (!check_input()) - { + if (!check_input()) { // details logged, meta_errno set in check_input() RETURN_ERRNO(mFALSE, ME_ARGUMENT); } - // Are we allowed to load this plugin at this time? // If we cannot load the plugin after unloading it, we keep it. - if (info && info->loadable < now) - { - if (info->loadable > PT_STARTUP) - { + if (info && info->loadable < now) { + if (info->loadable > PT_STARTUP) { META_DEBUG(2, ("dll: Delaying reload plugin '%s'; would not be able to reattach now: allowed=%s; now=%s", desc, str_loadable(), str_loadtime(now, SL_SIMPLE))); // caller should give message to user // try to reload again at next opportunity RETURN_ERRNO(mFALSE, ME_DELAYED); } - else - { + else { META_DEBUG(2, ("dll: Failed reload plugin '%s'; would not be able to reattach now: allowed=%s; now=%s", desc, str_loadable(), str_loadtime(now, SL_SIMPLE))); // don't try to reload again later action = PA_NONE; @@ -1202,28 +1104,21 @@ mBOOL MPlugin::reload(PLUG_LOADTIME now, PL_UNLOAD_REASON reason) } } - // this is to fix unloading - if (status < PL_RUNNING) - { + if (status < PL_RUNNING) { META_WARNING("dll: Plugin '%s' isn't running; Forcing unload plugin for reloading", desc); reason = PNL_RELOAD; } - - if (!unload(now, reason, reason)) - { + if (!unload(now, reason, reason)) { META_WARNING("dll: Failed to unload plugin '%s' for reloading", desc); // meta_errno should be set already in unload() - return mFALSE; + return (mFALSE); } - - if (!load(now)) - { + if (!load(now)) { META_WARNING("dll: Failed to reload plugin '%s' after unloading", desc); // meta_errno should be set already in load() - return mFALSE; + return (mFALSE); } - - return mTRUE; + return (mTRUE); } // Pause a plugin; temporarily disabled for API routines. @@ -1231,47 +1126,41 @@ mBOOL MPlugin::reload(PLUG_LOADTIME now, PL_UNLOAD_REASON reason) // - ME_ALREADY this plugin already paused // - ME_BADREQ can't pause; not running // - ME_NOTALLOWED plugin doesn't want to be paused -mBOOL MPlugin::pause() +mBOOL MPlugin::pause(void) { - if (status == PL_PAUSED) - { - META_WARNING("Not pausing plugin '%s'; already paused", desc); + if (status == PL_PAUSED) { + META_ERROR("Not pausing plugin '%s'; already paused", desc); RETURN_ERRNO(mFALSE, ME_ALREADY); } - - if (status != PL_RUNNING) - { - META_WARNING("Cannot pause plugin '%s'; not currently running (status=%s)", desc, str_status()); + if (status != PL_RUNNING) { + META_ERROR("Cannot pause plugin '%s'; not currently running (status=%s)", desc, str_status()); RETURN_ERRNO(mFALSE, ME_BADREQ); } // are we allowed to pause this plugin? - if (info->unloadable < PT_ANYPAUSE) - { - META_WARNING("Cannot pause plugin '%s'; not allowed by plugin (allowed=%s)", desc, str_unloadable()); + if (info->unloadable < PT_ANYPAUSE) { + META_ERROR("Cannot pause plugin '%s'; not allowed by plugin (allowed=%s)", desc, str_unloadable()); action = PA_NONE; RETURN_ERRNO(mFALSE, ME_NOTALLOWED); } status = PL_PAUSED; META_LOG("Paused plugin '%s'", desc); - return mTRUE; + return (mTRUE); } // Unpause a plugin. // meta_errno values: // - ME_BADREQ can't unpause; not paused -mBOOL MPlugin::unpause() +mBOOL MPlugin::unpause(void) { - if (status != PL_PAUSED) - { - META_WARNING("Cannot unpause plugin '%s'; not currently paused (status=%s)", desc, str_status()); + if (status != PL_PAUSED) { + META_ERROR("Cannot unpause plugin '%s'; not currently paused (status=%s)", desc, str_status()); RETURN_ERRNO(mFALSE, ME_BADREQ); } - status = PL_RUNNING; META_LOG("Unpaused plugin '%s'", desc); - return mTRUE; + return (mTRUE); } // Retry pending action, presumably from a previous failure. @@ -1282,39 +1171,18 @@ mBOOL MPlugin::unpause() // - errno's from reload() mBOOL MPlugin::retry(PLUG_LOADTIME now, PL_UNLOAD_REASON reason) { - switch (action) - { - case PA_LOAD: return load(now); - case PA_ATTACH: return load(now); - case PA_UNLOAD: return unload(now, reason, reason); - case PA_RELOAD: return reload(now, reason); - default: - { - META_WARNING("No pending action to retry for plugin '%s'; (status=%s, action=%s)", desc, str_status(), str_action()); + if (action == PA_LOAD) + return (load(now)); + else if (action == PA_ATTACH) + return (load(now)); + else if (action == PA_UNLOAD) + return (unload(now, reason, reason)); + else if (action == PA_RELOAD) + return (reload(now, reason)); + else { + META_ERROR("No pending action to retry for plugin '%s'; (status=%s, action=%s)", desc, str_status(), str_action()); RETURN_ERRNO(mFALSE, ME_BADREQ); } - } -} - -void MPlugin::free_api_pointers() -{ - if (gamedll_funcs.dllapi_table) - free(gamedll_funcs.dllapi_table); - if (gamedll_funcs.newapi_table) - free(gamedll_funcs.newapi_table); - - if (tables.dllapi) - free(tables.dllapi); - if (post_tables.dllapi) - free(post_tables.dllapi); - if (tables.newapi) - free(tables.newapi); - if (post_tables.newapi) - free(post_tables.newapi); - if (tables.engine) - free(tables.engine); - if (post_tables.engine) - free(post_tables.engine); } // Clear a plugin (it failed a previous action and should be @@ -1322,48 +1190,56 @@ void MPlugin::free_api_pointers() // meta_errno values: // - ME_BADREQ not marked for clearing // - ME_DLERROR failed to dlclose -mBOOL MPlugin::clear() +mBOOL MPlugin::clear(void) { - if (status != PL_FAILED && status != PL_BADFILE && status != PL_EMPTY && status != PL_OPENED) - { - META_WARNING("Cannot clear plugin '%s'; not marked as failed, empty, or open (status=%s)", desc, str_status()); + if (status != PL_FAILED && status != PL_BADFILE + && status != PL_EMPTY && status != PL_OPENED) { + META_ERROR("Cannot clear plugin '%s'; not marked as failed, empty, or open (status=%s)", desc, str_status()); RETURN_ERRNO(mFALSE, ME_BADREQ); } - // If file is open, close the file. Note: after this, attempts to // reference any memory locations in the file will produce a segfault. - if (handle && DLCLOSE(handle) != 0) - { - META_WARNING("dll: Couldn't close plugin file '%s': %s", file, DLERROR()); + if (handle && DLCLOSE(handle) != 0) { + META_ERROR("dll: Couldn't close plugin file '%s': %s", file, DLERROR()); status = PL_FAILED; RETURN_ERRNO(mFALSE, ME_DLERROR); } + handle = NULL; - handle = nullptr; - free_api_pointers(); + if (gamedll_funcs.dllapi_table) free(gamedll_funcs.dllapi_table); + if (gamedll_funcs.newapi_table) free(gamedll_funcs.newapi_table); + if (dllapi_table) free(dllapi_table); + if (dllapi_post_table) free(dllapi_post_table); + if (newapi_table) free(newapi_table); + if (newapi_post_table) free(newapi_post_table); + if (engine_table) free(engine_table); + if (engine_post_table) free(engine_post_table); status = PL_EMPTY; action = PA_NULL; - handle = nullptr; - info = nullptr; + handle = NULL; + info = NULL; time_loaded = 0; - gamedll_funcs.dllapi_table = nullptr; - gamedll_funcs.newapi_table = nullptr; - Q_memset(&tables, 0, sizeof(tables)); - Q_memset(&post_tables, 0, sizeof(post_tables)); - - Plugins->trim_list(); - - return mTRUE; + dllapi_table = NULL; + dllapi_post_table = NULL; + newapi_table = NULL; + newapi_post_table = NULL; + engine_table = NULL; + engine_post_table = NULL; + gamedll_funcs.dllapi_table = NULL; + gamedll_funcs.newapi_table = NULL; + source_plugin_index = 0; + unloader_index = 0; + is_unloader = mFALSE; + return (mTRUE); } // List information about plugin to console. -void MPlugin::show() +void MPlugin::show(void) { char *cp, *tstr; - const int width = 13; - int n; - + int n, width; + width = 13; META_CONS("%*s: %s", width, "name", info ? info->name : "(nil)"); META_CONS("%*s: %s", width, "desc", desc); META_CONS("%*s: %s", width, "status", str_status()); @@ -1381,74 +1257,61 @@ void MPlugin::show() META_CONS("%*s: %s", width, "url", info ? info->url : "(nil)"); META_CONS("%*s: %s", width, "logtag", info ? info->logtag : "(nil)"); META_CONS("%*s: %s", width, "ifvers", info ? info->ifvers : "(nil)"); - // ctime() includes newline at EOL tstr = ctime(&time_loaded); - if ((cp = Q_strchr(tstr, '\n'))) + if ((cp = strchr(tstr, '\n'))) *cp = '\0'; - META_CONS("%*s: %s", width, "last loaded", tstr); // XXX show file time ? - if (tables.dllapi) - { + if (dllapi_table) { META_CONS("DLLAPI functions:"); - SHOW_DEF_DLLAPI(tables.dllapi," ", ""); + SHOW_DEF_DLLAPI(dllapi_table, " ", ""); META_CONS("%d functions (dllapi)", n); } else META_CONS("No DLLAPI functions."); - - if (post_tables.dllapi) - { + if (dllapi_post_table) { META_CONS("DLLAPI-Post functions:"); - SHOW_DEF_DLLAPI(post_tables.dllapi, " ", "_Post"); + SHOW_DEF_DLLAPI(dllapi_post_table, " ", "_Post"); META_CONS("%d functions (dllapi post)", n); } else META_CONS("No DLLAPI-Post functions."); - if (tables.newapi) - { + if (newapi_table) { META_CONS("NEWAPI functions:"); - SHOW_DEF_NEWAPI(tables.newapi, " ", ""); + SHOW_DEF_NEWAPI(newapi_table, " ", ""); META_CONS("%d functions (newapi)", n); } else META_CONS("No NEWAPI functions."); - - if (post_tables.newapi) - { + if (newapi_post_table) { META_CONS("NEWAPI-Post functions:"); - SHOW_DEF_NEWAPI(post_tables.newapi, " ", "_Post"); + SHOW_DEF_NEWAPI(newapi_post_table, " ", "_Post"); META_CONS("%d functions (newapi post)", n); } else META_CONS("No NEWAPI-Post functions."); - if (tables.engine) - { - META_CONS("Engine functions:"); - SHOW_DEF_ENGINE(tables.engine, " ", ""); + if (engine_table) { + META_CONS("g_engine functions:"); + SHOW_DEF_ENGINE(engine_table, " ", ""); META_CONS("%d functions (engine)", n); } else - META_CONS("No Engine functions."); - - if (post_tables.engine) - { - META_CONS("Engine-Post functions:"); - SHOW_DEF_ENGINE(post_tables.engine, " ", "_Post"); + META_CONS("No g_engine functions."); + if (engine_post_table) { + META_CONS("g_engine-Post functions:"); + SHOW_DEF_ENGINE(engine_post_table, " ", "_Post"); META_CONS("%d functions (engine post)", n); } else - META_CONS("No Engine-Post functions."); - - RegCmds->show(index); - RegCvars->show(index); - - if (Plugins->found_child_plugins(index)) - Plugins->show(index); + META_CONS("No g_engine-Post functions."); + g_regCmds->show(index); + g_regCvars->show(index); + if (g_plugins->found_child_plugins(index)) + g_plugins->show(index); else META_CONS("No child plugins."); } @@ -1458,20 +1321,20 @@ void MPlugin::show() // meta_errno values: // - ME_NOFILE couldn't find file // - ME_NOERROR no error; false indicates file not newer -mBOOL MPlugin::newer_file() +mBOOL MPlugin::newer_file(void) { struct stat st; time_t file_time; if (stat(pathname, &st) != 0) - RETURN_ERRNO(mFALSE, ME_NOFILE); - - 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)); + RETURN_ERRNO(mFALSE, ME_NOFILE); + file_time = max(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) - return mTRUE; + return (mTRUE); else - RETURN_ERRNO(mFALSE, ME_NOERROR); + RETURN_ERRNO(mFALSE, ME_NOERROR); } // Return a string describing status of plugin. @@ -1479,34 +1342,33 @@ mBOOL MPlugin::newer_file() // SHOW is max 4 chars, for "show" output. // meta_errno values: // - none -const char *MPlugin::str_status(STR_STATUS fmt) +const char* MPlugin::str_status(STR_STATUS fmt) { - switch (status) - { + switch (status) { case PL_EMPTY: - if (fmt == ST_SHOW) return "empt"; - else return "empty"; + if (fmt == ST_SHOW) return ("empt"); + else return ("empty"); case PL_VALID: - if (fmt == ST_SHOW) return"info"; - else return "valid"; + if (fmt == ST_SHOW) return ("info"); + else return ("valid"); case PL_BADFILE: - if (fmt == ST_SHOW) return "badf"; - else return "badfile"; + if (fmt == ST_SHOW) return ("badf"); + else return ("badfile"); case PL_OPENED: - if (fmt == ST_SHOW) return "open"; - else return "opened"; + if (fmt == ST_SHOW) return ("open"); + else return ("opened"); case PL_FAILED: - if (fmt == ST_SHOW) return "fail"; - else return "failed"; + if (fmt == ST_SHOW) return ("fail"); + else return ("failed"); case PL_RUNNING: - if (fmt == ST_SHOW) return "RUN"; - else return "running"; + if (fmt == ST_SHOW) return ("RUN"); + else return ("running"); case PL_PAUSED: - if (fmt == ST_SHOW) return "PAUS"; - else return "paused"; + if (fmt == ST_SHOW) return ("PAUS"); + else return ("paused"); default: - if (fmt == ST_SHOW) return META_UTIL_VarArgs("UNK%d", status); - return META_UTIL_VarArgs("unknown (%d)", status); + if (fmt == ST_SHOW) return (UTIL_VarArgs("UNK%d", status)); + return (UTIL_VarArgs("unknown (%d)", status)); } } @@ -1515,34 +1377,33 @@ const char *MPlugin::str_status(STR_STATUS fmt) // SHOW is max 4 chars, for "show" output. // meta_errno values: // - none -const char *MPlugin::str_action(STR_ACTION fmt) +const char* MPlugin::str_action(STR_ACTION fmt) { - switch (action) - { + switch (action) { case PA_NULL: - if (fmt == SA_SHOW) return "NULL"; - else return "null"; + if (fmt == SA_SHOW) return ("NULL"); + else return ("null"); case PA_NONE: - if (fmt == SA_SHOW) return " - "; - else return "none"; + if (fmt == SA_SHOW) return (" - "); + else return ("none"); case PA_KEEP: - if (fmt == SA_SHOW) return "keep"; - else return "keep"; + if (fmt == SA_SHOW) return ("keep"); + else return ("keep"); case PA_LOAD: - if (fmt == SA_SHOW) return "load"; - else return "load"; + if (fmt == SA_SHOW) return ("load"); + else return ("load"); case PA_ATTACH: - if (fmt == SA_SHOW) return "atch"; - else return "attach"; + if (fmt == SA_SHOW) return ("atch"); + else return ("attach"); case PA_UNLOAD: - if (fmt == SA_SHOW) return "unld"; - else return "unload"; + if (fmt == SA_SHOW) return ("unld"); + else return ("unload"); case PA_RELOAD: - if (fmt == SA_SHOW) return "relo"; - else return "reload"; + if (fmt == SA_SHOW) return ("relo"); + else return ("reload"); default: - if (fmt == SA_SHOW) return META_UTIL_VarArgs("UNK%d", action); - else return META_UTIL_VarArgs("unknown (%d)", action); + if (fmt == SA_SHOW) return (UTIL_VarArgs("UNK%d", action)); + else return (UTIL_VarArgs("unknown (%d)", action)); } } @@ -1553,97 +1414,101 @@ const char *MPlugin::str_action(STR_ACTION fmt) // NOW is to describe current situation of load/unload attempt. // meta_errno values: // - none -const char *MPlugin::str_loadtime(PLUG_LOADTIME ptime, STR_LOADTIME fmt) +const char* MPlugin::str_loadtime(PLUG_LOADTIME ptime, STR_LOADTIME fmt) { - static const char *rPrintLoadTime[][26] = { - // SL_SIMPLE // SL_SHOW // SL_ALLOWED // SL_NOW - { "never", "Never", "never", "never" }, // PT_NEVER - { "startup", "Start", "at server startup", "during server startup" }, // PT_STARTUP - { "changelevel","Chlvl", "at changelevel", "during changelevel" }, // PT_CHANGELEVEL - { "anytime", "ANY", "at any time", "during map" }, // PT_ANYTIME - { "pausable", "Pause", "at any time, and pausable", "for requested pause" }, // PT_ANYPAUSE - }; - - if (ptime >= PT_NEVER || ptime <= PT_ANYPAUSE) - return rPrintLoadTime[ptime][fmt]; - - if (fmt == SL_SHOW) - return META_UTIL_VarArgs("UNK-%d", ptime); - - return META_UTIL_VarArgs("unknown (%d)", ptime); + switch (ptime) { + case PT_NEVER: + if (fmt == SL_SHOW) return ("Never"); + else return ("never"); + case PT_STARTUP: + if (fmt == SL_SHOW) return ("Start"); + else if (fmt == SL_ALLOWED) return ("at server startup"); + else if (fmt == SL_NOW) return ("during server startup"); + else return ("startup"); + case PT_CHANGELEVEL: + if (fmt == SL_SHOW) return ("Chlvl"); + else if (fmt == SL_ALLOWED) return ("at changelevel"); + else if (fmt == SL_NOW) return ("during changelevel"); + else return ("changelevel"); + case PT_ANYTIME: + if (fmt == SL_SHOW) return ("ANY"); + else if (fmt == SL_ALLOWED) return ("at any time"); + else if (fmt == SL_NOW) return ("during map"); + else return ("anytime"); + case PT_ANYPAUSE: + if (fmt == SL_SHOW) return ("Pause"); + else if (fmt == SL_ALLOWED) return ("at any time, and pausable"); + else if (fmt == SL_NOW) return ("for requested pause"); + else return ("pausable"); + default: + if (fmt == SL_SHOW) return (UTIL_VarArgs("UNK-%d", ptime)); + else return (UTIL_VarArgs("unknown (%d)", ptime)); + } } // Return a string describing why a plugin is to be unloaded. // meta_errno values: // - none -const char *MPlugin::str_reason(PL_UNLOAD_REASON preason, PL_UNLOAD_REASON preal_reason) +const char* MPlugin::str_reason(PL_UNLOAD_REASON preason, PL_UNLOAD_REASON preal_reason) { char buf[128]; if (preason == PNL_PLUGIN) preason = PNL_NULL; - else if (preason == PNL_PLG_FORCED) + if (preason == PNL_PLG_FORCED) preason = PNL_NULL; - switch (preal_reason) - { + switch (preal_reason) { case PNL_NULL: - return "null"; + return ("null"); case PNL_INI_DELETED: - return "deleted from ini file"; + return ("deleted from ini file"); case PNL_FILE_NEWER: - return "file on disk is newer"; + return ("file on disk is newer"); case PNL_COMMAND: - return "server command"; + return ("server command"); case PNL_CMD_FORCED: - return "forced by server command"; + return ("forced by server command"); case PNL_PLUGIN: - { - Q_strncpy(buf, str_reason(PNL_NULL, preason), sizeof(buf) - 1); - buf[sizeof(buf) - 1] = '\0'; - - return META_UTIL_VarArgs("%s (request from plugin[%d])", buf, unloader_index); - } + strncpy(buf, str_reason(PNL_NULL, preason), sizeof buf - 1); + buf[sizeof buf - 1] = '\0'; + return (UTIL_VarArgs("%s (request from plugin[%d])", buf, unloader_index)); case PNL_PLG_FORCED: - { - Q_strncpy(buf, str_reason(PNL_NULL, preason), sizeof(buf) - 1); - buf[sizeof(buf) - 1] = '\0'; - - return META_UTIL_VarArgs("%s (forced request from plugin[%d])", buf, unloader_index); - } + strncpy(buf, str_reason(PNL_NULL, preason), sizeof buf - 1); + buf[sizeof buf - 1] = '\0'; + return (UTIL_VarArgs("%s (forced request from plugin[%d])", buf, unloader_index)); case PNL_RELOAD: - return "reloading"; + return ("reloading"); default: - return META_UTIL_VarArgs("unknown (%d)", preal_reason); + return (UTIL_VarArgs("unknown (%d)", preal_reason)); } } // Return a string describing how the plugin was loaded. // meta_errno values: // - none -const char *MPlugin::str_source(STR_SOURCE fmt) +const char* MPlugin::str_source(STR_SOURCE fmt) { - switch (source) - { + switch (source) { case PS_INI: - if (fmt == SO_SHOW) return "ini"; - else return "ini file"; + if (fmt == SO_SHOW) return ("ini"); + else return ("ini file"); case PS_CMD: - if (fmt == SO_SHOW) return "cmd"; - else return "console command"; + if (fmt == SO_SHOW) return ("cmd"); + else return ("console command"); case PS_PLUGIN: - if (source_plugin_index <= 0) - { - if (fmt == SO_SHOW) return "plUN"; - else return "unloaded plugin"; + if (source_plugin_index <= 0) { + if (fmt == SO_SHOW) + return ("plUN"); + else + return ("unloaded plugin"); } - else - { - if (fmt == SO_SHOW) return META_UTIL_VarArgs("pl%d", source_plugin_index); - else return META_UTIL_VarArgs("plugin [%d]", source_plugin_index); + else { + if (fmt == SO_SHOW) return (UTIL_VarArgs("pl%d", source_plugin_index)); + else return (UTIL_VarArgs("plugin [%d]", source_plugin_index)); } default: - if (fmt == SO_SHOW) return META_UTIL_VarArgs("UNK%d", source); - else return META_UTIL_VarArgs("unknown (%d)", source); + if (fmt == SO_SHOW) return (UTIL_VarArgs("UNK%d", source)); + else return (UTIL_VarArgs("unknown (%d)", source)); } } diff --git a/metamod/src/mplugin.h b/metamod/src/mplugin.h index 60dea97..995ebf3 100644 --- a/metamod/src/mplugin.h +++ b/metamod/src/mplugin.h @@ -1,23 +1,67 @@ -#pragma once +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// mplugin.h - class and types to describe an individual plugin + +/* + * Copyright (c) 2001-2003 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game g_engine ("HL + * g_engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL g_engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + +#ifndef MPLUGIN_H +#define MPLUGIN_H + +#include // time_t, etc + +#include // DLL_FUNCTIONS, etc + +#include "types_meta.h" // mBOOL +#include "meta_api.h" // GETENTITYAPI_FN, etc +#include "api_info.h" // dllapi_info, etc +#include "support_meta.h" // MAX_DESC_LEN -#include "api_info.h" -#include "support_meta.h" // Flags to indicate current "load" state of plugin. // NOTE: order is important, as greater/less comparisons are made. -enum PLUG_STATUS { - PL_EMPTY = 0, // empty slot +typedef enum { + PL_EMPTY = 0, // empty slot PL_VALID, // has valid info in it - PL_BADFILE, // nonexistent file (open failed), - // or not a valid plugin file (query failed) + PL_BADFILE, // nonexistent file (open failed), + // or not a valid plugin file (query failed) PL_OPENED, // dlopened and queried PL_FAILED, // opened, but failed to attach or unattach PL_RUNNING, // attached and running PL_PAUSED, // attached but paused -}; +} PLUG_STATUS; // Action to take for plugin at next opportunity. -enum PLUG_ACTION { +typedef enum { PA_NULL = 0, PA_NONE, // no action needed right now PA_KEEP, // keep, after ini refresh @@ -25,160 +69,355 @@ enum PLUG_ACTION { PA_ATTACH, // attach PA_UNLOAD, // unload (detach, dlclose) PA_RELOAD, // unload and load again -}; +} PLUG_ACTION; // Flags to indicate from where the plugin was loaded. -enum PLOAD_SOURCE { +typedef enum { PS_INI = 0, // was loaded from the plugins.ini PS_CMD, // was loaded via a server command - PS_PLUGIN, // was loaded by other plugin -}; + PS_PLUGIN, // was loaded via a plugin +} PLOAD_SOURCE; // Flags for how to word description of plugin loadtime. -enum STR_LOADTIME { - SL_SIMPLE = 0, // single word +typedef enum { + SL_SIMPLE = 0, // single word SL_SHOW, // for "show" output, 5 chars SL_ALLOWED, // when plugin is allowed to load/unload SL_NOW, // current situation -}; +} STR_LOADTIME; // Flags for how to format description of status. -enum STR_STATUS { - ST_SIMPLE = 0, // single word +typedef enum { + ST_SIMPLE = 0, // single word ST_SHOW, // for "show" output, 4 chars -}; +} STR_STATUS; // Flags for how to format description of action. -enum STR_ACTION { - SA_SIMPLE = 0, // single word +typedef enum { + SA_SIMPLE = 0, // single word SA_SHOW, // for "show" output, 4 chars -}; +} STR_ACTION; // Flags for how to format description of source. -enum STR_SOURCE { - SO_SIMPLE = 0, // two words +typedef enum { + SO_SIMPLE = 0, // two words SO_SHOW, // for "list" output, 3 chars -}; - -// api table list -struct api_tables_t { - enginefuncs_t *engine; - DLL_FUNCTIONS *dllapi; - NEW_DLL_FUNCTIONS *newapi; -}; +} STR_SOURCE; // An individual plugin. -class MPlugin: public class_metamod_new { -public: - mBOOL ini_parseline(const char *line); // parse line from inifile - mBOOL cmd_parseline(const char *line); // parse from console command - mBOOL plugin_parseline(const char *fname, int loader_index); // parse from plugin - mBOOL check_input(); +class MPlugin { + private: + mBOOL query(void); + mBOOL attach(PLUG_LOADTIME now); + mBOOL detach(PLUG_LOADTIME now, PL_UNLOAD_REASON reason); + gamedll_funcs_t gamedll_funcs; + mutil_funcs_t mutil_funcs; + public: + // data: + int index; // 1-based + char filename[PATH_MAX]; // ie "dlls/mm_test_i386.so", from inifile + char *file; // ie "mm_test_i386.so", ptr from filename + char desc[MAX_DESC_LEN]; // ie "Test metamod plugin", from inifile + char pathname[PATH_MAX]; // UNIQUE, ie "/home/willday/half-life/cstrike/dlls/mm_test_i386.so", built with GameDLL.gamedir + int pfspecific; // level of specific platform affinity, used during load time + PLUG_STATUS status; // current status of plugin (loaded, etc) + PLUG_ACTION action; // what to do with plugin (load, unload, etc) + PLOAD_SOURCE source; // source of the request to load the plugin - mBOOL resolve(); // find a matching file on disk - char *resolve_dirs(const char *path); - char *resolve_prefix(const char *path); - char *resolve_suffix(const char *path); - static mBOOL is_platform_postfix(const char *pf); + DLHANDLE handle; // handle for dlopen, dlsym, etc + plugin_info_t *info; // information plugin provides about itself + time_t time_loaded; // when plugin was loaded + int source_plugin_index; // who loaded this plugin + int unloader_index; + mBOOL is_unloader; // fix to prevent other plugins unload active unloader. - mBOOL platform_match(MPlugin* plugin); + DLL_FUNCTIONS *dllapi_table; + DLL_FUNCTIONS *dllapi_post_table; + NEW_DLL_FUNCTIONS *newapi_table; + NEW_DLL_FUNCTIONS *newapi_post_table; + enginefuncs_t *engine_table; + enginefuncs_t *engine_post_table; - mBOOL load(PLUG_LOADTIME now); - mBOOL unload(PLUG_LOADTIME now, PL_UNLOAD_REASON reason, PL_UNLOAD_REASON real_reason); - mBOOL reload(PLUG_LOADTIME now, PL_UNLOAD_REASON reason); - mBOOL pause(); - mBOOL unpause(); - mBOOL retry(PLUG_LOADTIME now, PL_UNLOAD_REASON reason); // if previously failed - void free_api_pointers(); - mBOOL clear(); - mBOOL plugin_unload(plid_t plid, PLUG_LOADTIME now, PL_UNLOAD_REASON reason); // other plugin unloading - void show(); // print info about plugin to console + // functions: + + mBOOL ini_parseline(char *line); // parse line from inifile + mBOOL cmd_parseline(const char *line); // parse from console command + mBOOL plugin_parseline(const char *fname, int loader_index); // parse from plugin + mBOOL check_input(void); - mBOOL newer_file(); // check for newer file on disk + mBOOL resolve(void); // find a matching file on disk + char *resolve_dirs(char *path); + char *resolve_prefix(char *path); + char *resolve_suffix(char *path); - const char *str_status(STR_STATUS fmt); - const char *str_action(STR_ACTION fmt); - const char *str_source(STR_SOURCE fmt); + mBOOL platform_match(MPlugin* plugin); + + mBOOL load(PLUG_LOADTIME now); + mBOOL unload(PLUG_LOADTIME now, PL_UNLOAD_REASON reason, PL_UNLOAD_REASON real_reason); + mBOOL reload(PLUG_LOADTIME now, PL_UNLOAD_REASON reason); + mBOOL pause(void); + mBOOL unpause(void); + mBOOL retry(PLUG_LOADTIME now, PL_UNLOAD_REASON reason); // if previously failed + mBOOL clear(void); + mBOOL plugin_unload(plid_t plid, PLUG_LOADTIME now, PL_UNLOAD_REASON reason); // other plugin unloading + void show(void); // print info about plugin to console - const char *str_reason(PL_UNLOAD_REASON preason, PL_UNLOAD_REASON preal_reason); - const char *str_loadtime(PLUG_LOADTIME pallow, STR_LOADTIME fmt); + mBOOL newer_file(void); // check for newer file on disk - inline const char *str_status() { return str_status(ST_SIMPLE); }; - inline const char *str_action() { return str_action(SA_SIMPLE); }; - inline const char *str_source() { return str_source(SO_SIMPLE); }; + // output string functions + const char *str_status(STR_STATUS fmt); + const char *str_action(STR_ACTION fmt); + const char *str_source(STR_SOURCE fmt); - inline const char *str_loadable() { - return info ? str_loadtime(info->loadable, SL_SIMPLE) : " -"; - }; - inline const char *str_unloadable() { - return info ? str_loadtime(info->unloadable, SL_SIMPLE) : " -"; - }; - inline const char *str_loadable(STR_LOADTIME fmt) { - return info ? str_loadtime(info->loadable, fmt) : " -"; - }; - inline const char *str_unloadable(STR_LOADTIME fmt) { - return info ? str_loadtime(info->unloadable, fmt) : " -"; - }; + const char *str_reason(PL_UNLOAD_REASON preason, PL_UNLOAD_REASON preal_reason); + const char *str_loadtime(PLUG_LOADTIME pallow, STR_LOADTIME fmt); -public: - // reordered for faster api_hook.cpp functions - PLUG_STATUS status; // current status of plugin (loaded, etc) - api_tables_t tables; - api_tables_t post_tables; + const char *str_status(void) { return(str_status(ST_SIMPLE)); }; + const char *str_action(void) { return(str_action(SA_SIMPLE)); }; + const char *str_source(void) { return(str_source(SO_SIMPLE)); }; - inline void *get_api_table(enum_api_t api) { - return ((void **)&tables)[api]; - } - inline void *get_api_post_table(enum_api_t api) { - return ((void **)&post_tables)[api]; - } - - int index; // 1-based - int pfspecific; // level of specific platform affinity, used during load time - PLUG_ACTION action; // what to do with plugin (load, unload, etc) - PLOAD_SOURCE source; // source of the request to load the plugin - int source_plugin_index; // index of plugin that loaded this plugin. -1 means source plugin has been unloaded. - int unloader_index; - mBOOL is_unloader; // fix to prevent other plugins unload active unloader. - - DLHANDLE handle; // handle for dlopen, dlsym, etc - plugin_info_t *info; // information plugin provides about itself - time_t time_loaded; // when plugin was loaded - - char filename[PATH_MAX]; // ie "dlls/mm_test_i386.so", from inifile - char *file; // ie "mm_test_i386.so", ptr from filename - char desc[MAX_DESC_LEN]; // ie "Test metamod plugin", from inifile - char pathname[PATH_MAX]; // UNIQUE, ie "/home/willday/half-life/cstrike/dlls/mm_test_i386.so", built with GameDLL.gamedir - -private: - mBOOL query(); - mBOOL attach(PLUG_LOADTIME now); - mBOOL detach(PLUG_LOADTIME now, PL_UNLOAD_REASON reason); - - gamedll_funcs_t gamedll_funcs; - mutil_funcs_t mutil_funcs; + const char *str_loadable(void) { + if(info) return(str_loadtime(info->loadable, SL_SIMPLE)); + else return(" -"); + }; + const char *str_unloadable(void) { + if(info) return(str_loadtime(info->unloadable, SL_SIMPLE)); + else return(" -"); + }; + const char *str_loadable(STR_LOADTIME fmt) { + if(info) return(str_loadtime(info->loadable, fmt)); + else return(" -"); + }; + const char *str_unloadable(STR_LOADTIME fmt) { + if(info) return(str_loadtime(info->unloadable, fmt)); + else return(" -"); + }; }; // Macros used by MPlugin::show(), to list the functions that the plugin // catches. -#define SHOW_DEF_API(api_info, api_table, pre_str, post_str) \ - n=0; \ - { \ - const api_info_t * ainfo = (const api_info_t *)&api_info; \ - const void ** table = (const void **)api_table; \ - for (int i = 0; &ainfo[i] < &api_info.END; i++) { \ - if (table[i]) { \ - META_CONS("%s%s%s", pre_str, ainfo[i].name, post_str); \ - n++; \ - } \ - } \ - } +#define SHOW_IFDEF(api_table, info_table, pfnName, pre_str, post_str) \ + if(api_table->pfnName) { META_CONS("%s%s%s", pre_str, info_table.pfnName.name, post_str); n++;} #define SHOW_DEF_DLLAPI(api_table, pre_str, post_str) \ - SHOW_DEF_API(dllapi_info, api_table, pre_str, post_str) + n=0; \ + SHOW_IFDEF(api_table, dllapi_info, pfnGameInit, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnSpawn, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnThink, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnUse, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnTouch, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnBlocked, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnKeyValue, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnSave, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnRestore, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnSetAbsBox, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnSaveWriteFields, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnSaveReadFields, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnSaveGlobalState, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnRestoreGlobalState, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnResetGlobalState, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnClientConnect, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnClientDisconnect, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnClientKill, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnClientPutInServer, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnClientCommand, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnClientUserInfoChanged, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnServerActivate, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnServerDeactivate, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnPlayerPreThink, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnPlayerPostThink, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnStartFrame, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnParmsNewLevel, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnParmsChangeLevel, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnGetGameDescription, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnPlayerCustomization, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnSpectatorConnect, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnSpectatorDisconnect, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnSpectatorThink, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnSys_Error, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnPM_Move, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnPM_Init, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnPM_FindTextureType, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnSetupVisibility, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnUpdateClientData, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnAddToFullPack, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnCreateBaseline, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnRegisterEncoders, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnGetWeaponData, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnCmdStart, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnCmdEnd, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnConnectionlessPacket, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnGetHullBounds, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnCreateInstancedBaselines, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnInconsistentFile, pre_str, post_str); \ + SHOW_IFDEF(api_table, dllapi_info, pfnAllowLagCompensation, pre_str, post_str); #define SHOW_DEF_NEWAPI(api_table, pre_str, post_str) \ - SHOW_DEF_API(newapi_info, api_table, pre_str, post_str) + n=0; \ + SHOW_IFDEF(api_table, newapi_info, pfnOnFreeEntPrivateData, pre_str, post_str); \ + SHOW_IFDEF(api_table, newapi_info, pfnGameShutdown, pre_str, post_str); \ + SHOW_IFDEF(api_table, newapi_info, pfnShouldCollide, pre_str, post_str); \ + SHOW_IFDEF(api_table, newapi_info, pfnCvarValue, pre_str, post_str); #define SHOW_DEF_ENGINE(api_table, pre_str, post_str) \ - SHOW_DEF_API(engine_info, api_table, pre_str, post_str) + n=0; \ + SHOW_IFDEF(api_table, engine_info, pfnPrecacheModel, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnPrecacheSound, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnSetModel, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnModelIndex, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnModelFrames, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnSetSize, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnChangeLevel, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnGetSpawnParms, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnSaveSpawnParms, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnVecToYaw, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnVecToAngles, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnMoveToOrigin, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnChangeYaw, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnChangePitch, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnFindEntityByString, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnGetEntityIllum, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnFindEntityInSphere, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnFindClientInPVS, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnEntitiesInPVS, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnMakeVectors, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnAngleVectors, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnCreateEntity, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnRemoveEntity, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnCreateNamedEntity, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnMakeStatic, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnEntIsOnFloor, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnDropToFloor, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnWalkMove, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnSetOrigin, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnEmitSound, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnEmitAmbientSound, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnTraceLine, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnTraceToss, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnTraceMonsterHull, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnTraceHull, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnTraceModel, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnTraceTexture, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnTraceSphere, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnGetAimVector, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnServerCommand, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnServerExecute, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnClientCommand, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnParticleEffect, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnLightStyle, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnDecalIndex, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnPointContents, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnMessageBegin, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnMessageEnd, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnWriteByte, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnWriteChar, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnWriteShort, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnWriteLong, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnWriteAngle, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnWriteCoord, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnWriteString, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnWriteEntity, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnCVarRegister, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnCVarGetFloat, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnCVarGetString, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnCVarSetFloat, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnCVarSetString, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnAlertMessage, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnEngineFprintf, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnPvAllocEntPrivateData, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnPvEntPrivateData, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnFreeEntPrivateData, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnSzFromIndex, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnAllocString, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnGetVarsOfEnt, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnPEntityOfEntOffset, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnEntOffsetOfPEntity, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnIndexOfEdict, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnPEntityOfEntIndex, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnFindEntityByVars, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnGetModelPtr, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnRegUserMsg, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnAnimationAutomove, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnGetBonePosition, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnFunctionFromName, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnNameForFunction, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnClientPrintf, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnServerPrint, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnCmd_Args, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnCmd_Argv, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnCmd_Argc, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnGetAttachment, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnCRC32_Init, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnCRC32_ProcessBuffer, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnCRC32_ProcessByte, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnCRC32_Final, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnRandomLong, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnRandomFloat, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnSetView, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnTime, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnCrosshairAngle, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnLoadFileForMe, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnFreeFile, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnEndSection, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnCompareFileTime, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnGetGameDir, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnCvar_RegisterVariable, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnFadeClientVolume, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnSetClientMaxspeed, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnCreateFakeClient, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnRunPlayerMove, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnNumberOfEntities, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnGetInfoKeyBuffer, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnInfoKeyValue, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnSetKeyValue, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnSetClientKeyValue, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnIsMapValid, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnStaticDecal, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnPrecacheGeneric, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnGetPlayerUserId, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnBuildSoundMsg, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnIsDedicatedServer, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnCVarGetPointer, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnGetPlayerWONId, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnInfo_RemoveKey, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnGetPhysicsKeyValue, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnSetPhysicsKeyValue, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnGetPhysicsInfoString, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnPrecacheEvent, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnPlaybackEvent, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnSetFatPVS, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnSetFatPAS, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnCheckVisibility, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnDeltaSetField, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnDeltaUnsetField, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnDeltaAddEncoder, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnGetCurrentPlayer, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnCanSkipPlayer, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnDeltaFindField, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnDeltaSetFieldByIndex, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnDeltaUnsetFieldByIndex, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnSetGroupMask, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnCreateInstancedBaseline, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnCvar_DirectSet, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnForceUnmodified, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnGetPlayerStats, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnAddServerCommand, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnVoice_GetClientListening, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnVoice_SetClientListening, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnGetPlayerAuthId, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnSequenceGet, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnSequencePickSentence, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnGetFileSize, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnGetApproxWavePlayLen, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnIsCareerMatch, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnGetLocalizedStringLength, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnRegisterTutorMessageShown, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnGetTimesTutorMessageShown, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnProcessTutorMessageDecayBuffer, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnConstructTutorMessageDecayBuffer, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnResetTutorMessageDecayData, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnQueryClientCvarValue, pre_str, post_str); \ + SHOW_IFDEF(api_table, engine_info, pfnEngCheckParm, pre_str, post_str); + + +#endif /* MPLUGIN_H */ diff --git a/metamod/src/mreg.cpp b/metamod/src/mreg.cpp index d42ebdf..d91a1bb 100644 --- a/metamod/src/mreg.cpp +++ b/metamod/src/mreg.cpp @@ -1,5 +1,50 @@ +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// mreg.cpp - functions for registered items (classes MRegCmd, MRegCmdList) + +/* + * Copyright (c) 2001-2003 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game g_engine ("HL + * g_engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL g_engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + #include "precompiled.h" +#ifdef linux +// enable extra routines in system header files, like strsignal +# ifndef _GNU_SOURCE +# define _GNU_SOURCE +# endif +#endif /* linux */ + +///// class MRegCmd: + // Init values. It would probably be more "proper" to use containers and // constructors, rather than arrays and init-functions. void MRegCmd::init(int idx) @@ -17,49 +62,53 @@ void MRegCmd::init(int idx) // meta_errno values: // - ME_BADREQ function disabled/invalid // - ME_ARGUMENT function pointer is null -mBOOL MRegCmd::call() +mBOOL MRegCmd::call(void) { mBOOL ret; // can we expect to call this function? if (status != RG_VALID) - RETURN_ERRNO(mFALSE, ME_BADREQ); + RETURN_ERRNO(mFALSE, ME_BADREQ); if (!pfnCmd) - RETURN_ERRNO(mFALSE, ME_ARGUMENT); + RETURN_ERRNO(mFALSE, ME_ARGUMENT); // try to call this function - ret=os_safe_call(pfnCmd); + ret = os_safe_call(pfnCmd); if (!ret) { META_DEBUG(4, ("Plugin reg_cmd '%s' called after unloaded; removed from list", name)); - status=RG_INVALID; - pfnCmd=NULL; + status = RG_INVALID; + pfnCmd = NULL; // NOTE: we can't free the malloc'd space for the name, as that // would just re-introduce the segfault problem.. } // meta_errno (if failed) is set already in os_safe_call() - return ret; + return (ret); } -MRegCmdList::MRegCmdList() + +///// class MRegCmdList: + +// Constructor +MRegCmdList::MRegCmdList(void) : mlist(0), size(REG_CMD_GROWSIZE), endlist(0) { - mlist = (MRegCmd *)calloc(1, size * sizeof(MRegCmd)); - + int i; + mlist = (MRegCmd *) malloc(size * sizeof(MRegCmd)); // initialize array - for (int i = 0; i < size; i++) - mlist[i].init(i + 1); // 1-based index - + for (i = 0; i < size; i++) + mlist[i].init(i + 1); // 1-based index endlist = 0; } // Try to find a registered function with the given name. // meta_errno values: // - ME_NOTFOUND couldn't find a matching function -MRegCmd *MRegCmdList::find(const char *findname) { +MRegCmd* MRegCmdList::find(const char* findname) +{ int i; - for (i=0; i < endlist; i++) { - if (!strcasecmp(mlist[i].name, findname)) - return &mlist[i]; + for (i = 0; i < endlist; i++) { + if (!_stricmp(mlist[i].name, findname)) + return (&mlist[i]); } RETURN_ERRNO(NULL, ME_NOTFOUND); } @@ -69,119 +118,109 @@ MRegCmd *MRegCmdList::find(const char *findname) { // (meta_AddServerCommand). // meta_errno values: // - ME_NOMEM couldn't realloc or malloc for various parts -MRegCmd *MRegCmdList::add(const char *addname) { - MRegCmd *icmd; +MRegCmd* MRegCmdList::add(const char* addname) +{ + MRegCmd* icmd; - if (endlist==size) { + if (endlist == size) { // grow array - MRegCmd *temp; + MRegCmd* temp; int i, newsize; - newsize=size+REG_CMD_GROWSIZE; + newsize = size + REG_CMD_GROWSIZE; META_DEBUG(6, ("Growing reg cmd list from %d to %d", size, newsize)); - temp = (MRegCmd *) realloc(mlist, newsize*sizeof(MRegCmd)); + temp = (MRegCmd *) realloc(mlist, newsize * sizeof(MRegCmd)); if (!temp) { - META_WARNING("Couldn't grow registered command list to %d for '%s': %s", newsize, addname, strerror(errno)); + META_ERROR("Couldn't grow registered command list to %d for '%s': %s", newsize, addname, strerror(errno)); RETURN_ERRNO(NULL, ME_NOMEM); } - mlist=temp; - size=newsize; + mlist = temp; + size = newsize; // initialize new (unused) entries - for (i=endlist; iname=strdup(addname); + icmd->name = _strdup(addname); if (!icmd->name) { - META_WARNING("Couldn't strdup for adding reg cmd name '%s': %s", - addname, strerror(errno)); + META_ERROR("Couldn't _strdup for adding reg cmd name '%s': %s", + addname, strerror(errno)); RETURN_ERRNO(NULL, ME_NOMEM); } endlist++; - return icmd; + return (icmd); } // Disable any functions belonging to the given plugin (by index id). -void MRegCmdList::disable(int plugin_id) { +void MRegCmdList::disable(int plugin_id) +{ int i; - for (i=0; i < size; i++) { + for (i = 0; i < size; i++) { if (mlist[i].plugid == plugin_id) mlist[i].status = RG_INVALID; } } // List all the registered commands. -void MRegCmdList::show() +void MRegCmdList::show(void) { - int i, n=0, a=0; - MRegCmd *icmd; - MPlugin *iplug; - char bplug[18+1]; // +1 for term null + int i, n = 0, a = 0; + MRegCmd* icmd; + MPlugin* iplug; + char bplug[18 + 1]; // +1 for term null META_CONS("Registered plugin commands:"); - META_CONS(" %*s %-*s %-s", WIDTH_MAX_REG, "", sizeof(bplug)-1, "plugin", "command"); - - for (i = 0; i < endlist; i++) - { + META_CONS(" %*s %-*s %-s", + WIDTH_MAX_REG, "", + sizeof(bplug) - 1, "plugin", "command"); + for (i = 0; i < endlist; i++) { icmd = &mlist[i]; - - if (icmd->status == RG_VALID) - { - iplug=Plugins->find(icmd->plugid); - - if (iplug) - { - Q_strncpy(bplug, iplug->desc, sizeof(bplug) - 1); - bplug[sizeof(bplug) - 1] = '\0'; + if (icmd->status == RG_VALID) { + iplug = g_plugins->find(icmd->plugid); + if (iplug) { + 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 { + strncpy(bplug, "(unknown)", sizeof bplug - 1); + bplug[sizeof bplug - 1] = '\0'; } } - else - { - Q_strncpy(bplug, "(unloaded)", sizeof(bplug) - 1); - bplug[sizeof(bplug) - 1] = '\0'; + else { + strncpy(bplug, "(unloaded)", sizeof bplug - 1); + bplug[sizeof bplug - 1] = '\0'; } - - META_CONS(" [%*d] %-*s %-s", WIDTH_MAX_REG, icmd->index, sizeof(bplug)-1, bplug, icmd->name); - - if (icmd->status == RG_VALID) - a++; - + META_CONS(" [%*d] %-*s %-s", + WIDTH_MAX_REG, icmd->index, + sizeof(bplug) - 1, bplug, + icmd->name); + if (icmd->status == RG_VALID) a++; n++; } - META_CONS("%d commands, %d available (%d allocated)", n, a, size); } // List all the registered commands for the given plugin id. -void MRegCmdList::show(int plugin_id) { - int i, n=0; - MRegCmd *icmd; +void MRegCmdList::show(int plugin_id) +{ + int i, n = 0; + MRegCmd* icmd; - /* // If OS doesn't support DLFNAME, then we can't know what the plugin's // registered cvars are. DLFNAME(NULL); - if (meta_errno==ME_OSNOTSUP) { + if (meta_errno == ME_OSNOTSUP) { META_CONS("Registered commands: unknown (can't get info under this OS)"); return; } - */ - META_CONS("Registered commands:"); - for (i=0; i < endlist; i++) { + for (i = 0; i < endlist; i++) { icmd = &mlist[i]; if (icmd->plugid != plugin_id) continue; @@ -207,31 +246,35 @@ void MRegCvar::init(int idx) // Set the cvar, copying values from given cvar. // meta_errno values: // - ME_ARGUMENT given cvar doesn't match this cvar -mBOOL MRegCvar::set(cvar_t *src) { - if (strcasecmp(src->name, data->name)) { - META_WARNING("Tried to set cvar with mismatched name; src=%s dst=%s", - src->name, data->name); +mBOOL MRegCvar::set(cvar_t* src) +{ + if (_stricmp(src->name, data->name)) { + META_ERROR("Tried to set cvar with mismatched name; src=%s dst=%s", + src->name, data->name); RETURN_ERRNO(mFALSE, ME_ARGUMENT); } // Would like to free() existing string, but can't tell where it was // allocated... - data->string = strdup(src->string); + data->string = _strdup(src->string); data->flags = src->flags; data->value = src->value; data->next = src->next; - return mTRUE; + return (mTRUE); } + +///// class MRegCvarList: + // Constructor -MRegCvarList::MRegCvarList() +MRegCvarList::MRegCvarList(void) : vlist(0), size(REG_CVAR_GROWSIZE), endlist(0) { int i; - vlist = (MRegCvar *) calloc(1, size * sizeof(MRegCvar)); + vlist = (MRegCvar *) malloc(size * sizeof(MRegCvar)); // initialize array - for (i=0; i < size; i++) - vlist[i].init(i+1); // 1-based - endlist=0; + for (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 @@ -239,71 +282,72 @@ MRegCvarList::MRegCvarList() // cvar::set(). // meta_errno values: // - ME_NOMEM couldn't alloc or realloc for various parts -MRegCvar *MRegCvarList::add(const char *addname) { - MRegCvar *icvar; +MRegCvar* MRegCvarList::add(const char* addname) +{ + MRegCvar* icvar; - if (endlist==size) { + if (endlist == size) { // grow array - MRegCvar *temp; + MRegCvar* temp; int i, newsize; - newsize=size+REG_CVAR_GROWSIZE; + newsize = size + REG_CVAR_GROWSIZE; META_DEBUG(6, ("Growing reg cvar list from %d to %d", size, newsize)); - temp = (MRegCvar *) realloc(vlist, newsize*sizeof(MRegCvar)); + temp = (MRegCvar *) realloc(vlist, newsize * sizeof(MRegCvar)); if (!temp) { - META_WARNING("Couldn't grow registered cvar list to %d for '%s'; %s", newsize, addname, strerror(errno)); + META_ERROR("Couldn't grow registered cvar list to %d for '%s'; %s", newsize, addname, strerror(errno)); RETURN_ERRNO(NULL, ME_NOMEM); } - vlist=temp; - size=newsize; + vlist = temp; + size = newsize; // initialize new (unused) entries - for (i=endlist; idata = (cvar_t *) calloc(1, sizeof(cvar_t)); + icvar->data = (cvar_t *) malloc(sizeof(cvar_t)); if (!icvar->data) { - META_WARNING("Couldn't malloc cvar for adding reg cvar name '%s': %s", - addname, strerror(errno)); + META_ERROR("Couldn't malloc cvar for adding reg cvar name '%s': %s", + addname, strerror(errno)); RETURN_ERRNO(NULL, ME_NOMEM); } - icvar->data->name=strdup(addname); + icvar->data->name = _strdup(addname); if (!icvar->data->name) { - META_WARNING("Couldn't strdup for adding reg cvar name '%s': %s", - addname, strerror(errno)); + META_ERROR("Couldn't _strdup for adding reg cvar name '%s': %s", + addname, strerror(errno)); RETURN_ERRNO(NULL, ME_NOMEM); } endlist++; - return icvar; + 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) +{ int i; - for (i=0; i < endlist; i++) { - if (!strcasecmp(vlist[i].data->name, findname)) - return &vlist[i]; + for (i = 0; i < endlist; i++) { + if (!_stricmp(vlist[i].data->name, findname)) + return (&vlist[i]); } RETURN_ERRNO(NULL, ME_NOTFOUND); } // Disable any cvars belonging to the given plugin (by index id). -void MRegCvarList::disable(int plugin_id) { +void MRegCvarList::disable(int plugin_id) +{ int i; - MRegCvar *icvar; - for (i=0; i < size; i++) { - icvar=&vlist[i]; + MRegCvar* icvar; + for (i = 0; i < size; i++) { + icvar = &vlist[i]; if (icvar->plugid == plugin_id) { icvar->status = RG_INVALID; icvar->plugid = 0; @@ -315,104 +359,114 @@ void MRegCvarList::disable(int plugin_id) { } // List all the registered cvars. -void MRegCvarList::show() { - int i, n=0, a=0; - MRegCvar *icvar; - MPlugin *iplug; - char bplug[13+1], bname[20+1], bval[15+1]; // +1 for term null +void MRegCvarList::show(void) +{ + int i, n = 0, a = 0; + MRegCvar* icvar; + MPlugin* iplug; + char bplug[13 + 1], bname[20 + 1], bval[15 + 1]; // +1 for term null 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"); - - for (i=0; i < endlist; i++) - { + 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++) { icvar = &vlist[i]; - if (icvar->status==RG_VALID) - { - iplug=Plugins->find(icvar->plugid); - if (iplug) - { - Q_strncpy(bplug, iplug->desc, sizeof(bplug) - 1); - bplug[sizeof(bplug) - 1] = '\0'; + if (icvar->status == RG_VALID) { + iplug = g_plugins->find(icvar->plugid); + if (iplug) { + 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 { + strncpy(bplug, "(unknown)", sizeof bplug - 1); + bplug[sizeof bplug - 1] = '\0'; } } - else - { - Q_strncpy(bplug, "(unloaded)", sizeof(bplug) - 1); - bplug[sizeof(bplug) - 1] = '\0'; + else { + strncpy(bplug, "(unloaded)", sizeof bplug - 1); + bplug[sizeof bplug - 1] = '\0'; } - Q_strncpy(bname, icvar->data->name, sizeof(bname) - 1); - bname[sizeof(bname) - 1] = '\0'; - - safevoid_snprintf(bval, sizeof(bval), "%f", icvar->data->value); - + strncpy(bname, icvar->data->name, sizeof bname - 1); + bname[sizeof bname - 1] = '\0'; + snprintf(bval, sizeof(bval), "%f", icvar->data->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); - - if (icvar->status==RG_VALID) - a++; + WIDTH_MAX_REG, icvar->index, + sizeof(bplug) - 1, bplug, + sizeof(bname) - 1, bname, + sizeof(bval) - 1, bval, + icvar->data->string); + if (icvar->status == RG_VALID) a++; n++; } META_CONS("%d cvars, %d available (%d allocated)", n, a, size); } // List the registered cvars for the given plugin id. -void MRegCvarList::show(int plugin_id) { - int i, n=0; - MRegCvar *icvar; - char bname[30+1], bval[15+1]; // +1 for term null +void MRegCvarList::show(int plugin_id) +{ + int i, n = 0; + MRegCvar* icvar; + 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"); - for (i = 0; i < endlist; i++) - { + // If OS doesn't support DLFNAME, then we can't know what the plugin's + // registered cvars are. + DLFNAME(NULL); + if (meta_errno == ME_OSNOTSUP) { + META_CONS("Registered cvars: unknown (can't get info under this OS)"); + return; + } + META_CONS("%-*s %*s %s", + sizeof(bname) - 1, "Registered cvars:", + sizeof(bval) - 1, "float value", + "string value"); + for (i = 0; i < endlist; i++) { icvar = &vlist[i]; if (icvar->plugid != plugin_id) continue; - - Q_strncpy(bname, icvar->data->name, sizeof(bname) - 1); - bname[sizeof(bname) - 1] = '\0'; - - safevoid_snprintf(bval, sizeof(bval), "%f", icvar->data->value); - META_CONS(" %-*s %*s %s", sizeof(bname)-1, bname, sizeof(bval)-1, bval, icvar->data->string); + strncpy(bname, icvar->data->name, sizeof bname - 1); + bname[sizeof bname - 1] = '\0'; + snprintf(bval, sizeof(bval), "%f", icvar->data->value); + META_CONS(" %-*s %*s %s", + sizeof(bname) - 1, bname, + sizeof(bval) - 1, bval, + icvar->data->string); n++; } - META_CONS("%d cvars", n); } + +///// class MRegMsgList: + // Constructor -MRegMsgList::MRegMsgList() +MRegMsgList::MRegMsgList(void) : size(MAX_REG_MSGS), endlist(0) { int i; // initialize array - Q_memset(mlist, 0, sizeof(mlist)); - for (i=0; i < size; i++) { - mlist[i].index=i+1; // 1-based + memset(mlist, 0, sizeof(mlist)); + for (i = 0; i < size; i++) { + mlist[i].index = i + 1; // 1-based } - endlist=0; + 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 *imsg; +MRegMsg* MRegMsgList::add(const char* addname, int addmsgid, int addsize) +{ + MRegMsg* imsg; - if (endlist==size) { + if (endlist == size) { // all slots used META_ERROR("Couldn't add registered msg '%s' to list; reached max msgs (%d)", - addname, size); + addname, size); RETURN_ERRNO(NULL, ME_MAXREACHED); } @@ -422,59 +476,58 @@ MRegMsg *MRegMsgList::add(const char *addname, int addmsgid, int addsize) { // Copy msg data into empty slot. // Note: 'addname' assumed to be a constant string allocated in the // gamedll. - imsg->name=addname; - imsg->msgid=addmsgid; - imsg->size=addsize; + imsg->name = addname; + imsg->msgid = addmsgid; + imsg->size = addsize; - return imsg; + 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++) - { - if (!Q_strcmp(mlist[i].name, findname)) - return &mlist[i]; + int i; + for (i = 0; i < endlist; i++) { + if (!strcmp(mlist[i].name, findname)) + return (&mlist[i]); } - RETURN_ERRNO(NULL, ME_NOTFOUND); } // 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++) - { + int i; + for (i = 0; i < endlist; i++) { if (mlist[i].msgid == findmsgid) - return &mlist[i]; + return (&mlist[i]); } - RETURN_ERRNO(NULL, ME_NOTFOUND); } // List the registered usermsgs for the gamedll. -void MRegMsgList::show() +void MRegMsgList::show(void) { int i, n = 0; - MRegMsg *imsg; - char bname[25+1]; // +1 for term null + MRegMsg* imsg; + char bname[25 + 1]; // +1 for term null - META_CONS("%-*s %5s %5s", sizeof(bname)-1, "Game registered user msgs:", "msgid", "size"); - for (i = 0; i < endlist; i++) - { + META_CONS("%-*s %5s %5s", + sizeof(bname) - 1, "Game registered user msgs:", "msgid", "size"); + for (i = 0; i < endlist; i++) { imsg = &mlist[i]; - - Q_strncpy(bname, imsg->name, sizeof(bname) - 1); - bname[sizeof(bname) - 1] = '\0'; - - META_CONS(" %-*s %3d %3d", sizeof(bname)-1, bname, imsg->msgid, imsg->size); + strncpy(bname, imsg->name, sizeof bname - 1); + bname[sizeof bname - 1] = '\0'; + META_CONS(" %-*s %3d %3d", + sizeof(bname) - 1, bname, + imsg->msgid, + imsg->size); n++; } - META_CONS("%d game user msgs", n); } + diff --git a/metamod/src/mreg.h b/metamod/src/mreg.h index 168d4fa..48648c2 100644 --- a/metamod/src/mreg.h +++ b/metamod/src/mreg.h @@ -1,17 +1,53 @@ -#pragma once +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// mreg.h - description of registered items (classes MRegCmd, MRegCmdList) + +/* + * Copyright (c) 2001-2003 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game g_engine ("HL + * g_engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL g_engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + +#ifndef MREG_H +#define MREG_H #include "types_meta.h" // mBOOL -#include "new_baseclass.h" -// Number of entries to add to reglists when they need to grow. Typically +// 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. // This used to correspond to the number of digits in MAX_REG, which was a -// fixed, compile-time limit. However, now that the reg lists are grown -// dynamically, this has less strong correspondance to list sizes. So for +// fixed, compile-time limit. However, now that the reg lists are grown +// dynamically, this has less strong correspondance to list sizes. So for // the moment, it reflects what one might normally expect to be the max // width needed to print an index number; 4 allows 9999 (which is a damn // lot, if you ask me). @@ -20,117 +56,131 @@ // Max number of registered user msgs we can manage. #define MAX_REG_MSGS 256 -// Max number of clients on server -#define MAX_CLIENTS_CONNECTED 32 - // Flags to indicate if given cvar or func is part of a loaded plugin. -enum REG_STATUS { RG_INVALID, RG_VALID }; +typedef enum { + RG_INVALID, + RG_VALID, +} REG_STATUS; // Pointer to function registered by AddServerCommand. -typedef void (*REG_CMD_FN)(); +typedef void (*REG_CMD_FN) (void); + // An individual registered function/command. -class MRegCmd: public class_metamod_new -{ -public: +class MRegCmd { friend class MRegCmdList; - - char *name; // space is malloc'd - REG_CMD_FN pfnCmd; // pointer to the function - 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 - mBOOL call(); // try to call the function - -private: - int index; // 1-based + private: + // data: + int index; // 1-based + public: + char *name; // space is malloc'd + REG_CMD_FN pfnCmd; // pointer to the function + int plugid; // index id of corresponding plugin + REG_STATUS status; // whether corresponding plugin is loaded + // functions: + void init(int idx); // init values, as not using constructors + mBOOL call(void); // try to call the function }; + // A list of registered commands. -class MRegCmdList: public class_metamod_new { -public: - MRegCmdList(); +class MRegCmdList { + private: + // data: + MRegCmd *mlist; // malloc'd array of registered commands + int size; // current size of list + 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 MRegCmdList &src); + MRegCmdList(const MRegCmdList &src); - MRegCmd *find(const char *findname); // find by MRegCmd->name - MRegCmd *add(const char *addname); - void disable(int plugin_id); // change status to Invalid - void show(); // list all funcs to console - void show(int plugin_id); // list given plugin's funcs to console + public: + // constructor: + MRegCmdList(void); -private: - MRegCmd *mlist; // malloc'd array of registered commands - int size; // current size of list - 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 MRegCmdList &src); - MRegCmdList(const MRegCmdList &src); + // functions: + MRegCmd *find(const char *findname); // find by MRegCmd->name + MRegCmd *add(const char *addname); + void disable(int plugin_id); // change status to Invalid + void show(void); // list all funcs to console + void show(int plugin_id); // list given plugin's funcs to console }; + + // An individual registered cvar. -class MRegCvar: public class_metamod_new { -public: +class MRegCvar { friend class MRegCvarList; - - 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 - mBOOL set(cvar_t *src); -private: - int index; // 1-based + private: + // data: + int index; // 1-based + public: + cvar_t *data; // actual cvar structure, malloc'd + int plugid; // index id of corresponding plugin + REG_STATUS status; // whether corresponding plugin is loaded + // functions: + void init(int idx); // init values, as not using constructors + mBOOL set(cvar_t *src); }; + // A list of registered cvars. -class MRegCvarList: public class_metamod_new { -public: - MRegCvarList(); +class MRegCvarList { + private: + // data: + MRegCvar *vlist; // malloc'd array of registered cvars + 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); - MRegCvar *add(const char *addname); - MRegCvar *find(const char *findname); // find by MRegCvar->data.name - void disable(int plugin_id); // change status to Invalid - void show(); // list all cvars to console - void show(int plugin_id); // list given plugin's cvars to console + public: + // constructor: + MRegCvarList(void); -private: - MRegCvar *vlist; // malloc'd array of registered cvars - 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); + // functions: + MRegCvar *add(const char *addname); + MRegCvar *find(const char *findname); // find by MRegCvar->data.name + void disable(int plugin_id); // change status to Invalid + void show(void); // list all cvars to console + void show(int plugin_id); // list given plugin's cvars to console }; + + // An individual registered user msg, from gamedll. -class MRegMsg: public class_metamod_new { -public: +class MRegMsg { friend class MRegMsgList; - - const char *name; // name, assumed constant string in gamedll - int msgid; // msgid, assigned by engine - int size; // size, if given by gamedll - -private: - int index; // 1-based + private: + // data: + int index; // 1-based + public: + const char *name; // name, assumed constant string in gamedll + int msgid; // msgid, assigned by engine + int size; // size, if given by gamedll }; + // A list of registered user msgs. -class MRegMsgList: public class_metamod_new { -public: - MRegMsgList(); +class MRegMsgList { + private: + // data: + MRegMsg mlist[MAX_REG_MSGS]; // array of registered msgs + int size; // size of list, ie MAX_REG_MSGS + int endlist; // index of last used entry - MRegMsg *add(const char *addname, int addmsgid, int addsize); - MRegMsg *find(const char *findname); - MRegMsg *find(int findmsgid); - void show(); // list all msgs to console + public: + // constructor: + MRegMsgList(void); -private: - MRegMsg mlist[MAX_REG_MSGS]; // array of registered msgs - int size; // size of list, ie MAX_REG_MSGS - int endlist; // index of last used entry + // functions: + MRegMsg *add(const char *addname, int addmsgid, int addsize); + MRegMsg *find(const char *findname); + MRegMsg *find(int findmsgid); + void show(void); // list all msgs to console }; + +#endif /* MREG_H */ diff --git a/metamod/src/mutil.cpp b/metamod/src/mutil.cpp index e852ac5..7e0b04b 100644 --- a/metamod/src/mutil.cpp +++ b/metamod/src/mutil.cpp @@ -1,88 +1,119 @@ +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// mutil.cpp - utility functions to provide to plugins + +/* + * Copyright (c) 2001-2003 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game g_engine ("HL + * g_engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL g_engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + #include "precompiled.h" -static hudtextparms_t default_csay_tparms = { - -1, 0.25, // x, y - 2, // effect - 0, 255, 0, 0, // r, g, b, a1 - 0, 0, 0, 0, // r2, g2, b2, a2 - 0, 0, 10, 10, // fadein, fadeout, hold, fxtime - 1 // channel +hudtextparms_t default_csay_tparms = { + -1, 0.25, // x, y + 2, // effect + 0, 255, 0, 0, // r, g, b, a1 + 0, 0, 0, 0, // r2, g2, b2, a2 + 0, 0, 10, 10, // fadein, fadeout, hold, fxtime + 1 // channel }; // Log to console; newline added. -static void mutil_LogConsole(plid_t /* plid */, const char *fmt, ...) { +void mutil_LogConsole(plid_t /* plid */, const char* fmt, ...) +{ va_list ap; char buf[MAX_LOGMSG_LEN]; unsigned int len; + va_start(ap, fmt); - safevoid_vsnprintf(buf, sizeof(buf), fmt, ap); + vsnprintf(buf, sizeof(buf), fmt, ap); va_end(ap); // end msg with newline - len=Q_strlen(buf); - if (len < sizeof(buf)-2) // -1 null, -1 for newline - Q_strcat(buf, "\n"); + len = strlen(buf); + if (len < sizeof(buf) - 2) // -1 null, -1 for newline + strcat(buf, "\n"); else - buf[len-1] = '\n'; + buf[len - 1] = '\n'; + SERVER_PRINT(buf); } // Log regular message to logs; newline added. -static void mutil_LogMessage(plid_t plid, const char *fmt, ...) { +void mutil_LogMessage(plid_t plid, const char* fmt, ...) +{ va_list ap; char buf[MAX_LOGMSG_LEN]; - plugin_info_t *plinfo; - plinfo=(plugin_info_t *)plid; + plugin_info_t* plinfo; + + plinfo = (plugin_info_t *)plid; va_start(ap, fmt); - safevoid_vsnprintf(buf, sizeof(buf), fmt, ap); + vsnprintf(buf, sizeof(buf), fmt, ap); va_end(ap); ALERT(at_logged, "[%s] %s\n", plinfo->logtag, buf); } // Log an error message to logs; newline added. -static void mutil_LogError(plid_t plid, const char *fmt, ...) { +void mutil_LogError(plid_t plid, const char* fmt, ...) +{ va_list ap; char buf[MAX_LOGMSG_LEN]; - plugin_info_t *plinfo; - plinfo=(plugin_info_t *)plid; + plugin_info_t* plinfo; + + plinfo = (plugin_info_t *)plid; va_start(ap, fmt); - safevoid_vsnprintf(buf, sizeof(buf), fmt, ap); + vsnprintf(buf, sizeof(buf), fmt, ap); va_end(ap); ALERT(at_logged, "[%s] ERROR: %s\n", plinfo->logtag, buf); } // Log a message only if cvar "developer" set; newline added. -static void mutil_LogDeveloper(plid_t plid, const char *fmt, ...) { +void mutil_LogDeveloper(plid_t plid, const char* fmt, ...) +{ va_list ap; char buf[MAX_LOGMSG_LEN]; - plugin_info_t *plinfo; - if ((int)CVAR_GET_FLOAT("developer") == 0) + plugin_info_t* plinfo; + + if ((int) CVAR_GET_FLOAT("developer") == 0) return; - plinfo=(plugin_info_t *)plid; + + plinfo = (plugin_info_t *)plid; va_start(ap, fmt); - safevoid_vsnprintf(buf, sizeof(buf), fmt, ap); + vsnprintf(buf, sizeof(buf), fmt, ap); va_end(ap); ALERT(at_logged, "[%s] dev: %s\n", plinfo->logtag, buf); } -// Print a center-message, with text parameters and varargs. Provides -// functionality to the above center_say interfaces. -static void mutil_CenterSayVarargs(plid_t plid, hudtextparms_t tparms, - const char *fmt, va_list ap) -{ - char buf[MAX_LOGMSG_LEN]; - int n; - edict_t *pEntity; - safevoid_vsnprintf(buf, sizeof(buf), fmt, ap); - mutil_LogMessage(plid, "(centersay) %s", buf); - for (n=1; n <= gpGlobals->maxClients; n++) { - pEntity=INDEXENT(n); - META_UTIL_HudMessage(pEntity, tparms, buf); - } -} - // Print message on center of all player's screens. Uses default text // parameters (color green, 10 second fade-in). -static void mutil_CenterSay(plid_t plid, const char *fmt, ...) { +void mutil_CenterSay(plid_t plid, const char* fmt, ...) +{ va_list ap; va_start(ap, fmt); mutil_CenterSayVarargs(plid, default_csay_tparms, fmt, ap); @@ -90,124 +121,145 @@ static void mutil_CenterSay(plid_t plid, const char *fmt, ...) { } // Print a center-message, with given text parameters. -static void mutil_CenterSayParms(plid_t plid, hudtextparms_t tparms, const char *fmt, ...) { +void mutil_CenterSayParms(plid_t plid, hudtextparms_t tparms, const char* fmt, ...) +{ va_list ap; va_start(ap, fmt); mutil_CenterSayVarargs(plid, tparms, fmt, ap); va_end(ap); } +// Print a center-message, with text parameters and varargs. Provides +// functionality to the above center_say interfaces. +void mutil_CenterSayVarargs(plid_t plid, hudtextparms_t tparms, + const char* fmt, va_list ap) +{ + char buf[MAX_LOGMSG_LEN]; + int n; + edict_t* pEntity; + + vsnprintf(buf, sizeof(buf), fmt, ap); + + mutil_LogMessage(plid, "(centersay) %s", buf); + for (n = 1; n <= gpGlobals->maxClients; n++) { + pEntity = INDEXENT(n); + if (FNullEnt(pEntity) || pEntity->free) + continue; + //META_UTIL_HudMessage(pEntity, tparms, buf); // TODO + } +} + // Allow plugins to call the entity functions in the GameDLL. In // particular, calling "player()" as needed by most Bots. Suggested by // Jussi Kivilinna. -static qboolean mutil_CallGameEntity(plid_t plid, const char *entStr, entvars_t *pev) { - plugin_info_t *plinfo; +qboolean mutil_CallGameEntity(plid_t plid, const char* entStr, entvars_t* pev) +{ + plugin_info_t* plinfo; ENTITY_FN pfnEntity; - plinfo=(plugin_info_t *)plid; + + plinfo = (plugin_info_t *)plid; META_DEBUG(8, ("Looking up game entity '%s' for plugin '%s'", entStr, - plinfo->name)); + plinfo->name)); pfnEntity = (ENTITY_FN) DLSYM(GameDLL.handle, entStr); if (!pfnEntity) { - META_WARNING("Couldn't find game entity '%s' in game DLL '%s' for plugin '%s'", entStr, GameDLL.name, plinfo->name); - return false; + META_ERROR("Couldn't find game entity '%s' in game DLL '%s' for plugin '%s'", entStr, GameDLL.name, plinfo->name); + return (false); } META_DEBUG(7, ("Calling game entity '%s' for plugin '%s'", entStr, - plinfo->name)); + plinfo->name)); (*pfnEntity)(pev); - return true; + return (true); } // Find a usermsg, registered by the gamedll, with the corresponding // msgname, and return remaining info about it (msgid, size). -static int mutil_GetUserMsgID(plid_t plid, const char *msgname, int *size) { - plugin_info_t *plinfo; - MRegMsg *umsg; +int mutil_GetUserMsgID(plid_t plid, const char* msgname, int* size) +{ + plugin_info_t* plinfo; + MRegMsg* umsg; - plinfo=(plugin_info_t *)plid; + plinfo = (plugin_info_t *)plid; META_DEBUG(8, ("Looking up usermsg name '%s' for plugin '%s'", msgname, - plinfo->name)); - umsg=RegMsgs->find(msgname); + plinfo->name)); + umsg = g_regMsgs->find(msgname); if (umsg) { if (size) - *size=umsg->size; - return umsg->msgid; + *size = umsg->size; + return (umsg->msgid); } else - return 0; + return (0); } // Find a usermsg, registered by the gamedll, with the corresponding // msgid, and return remaining info about it (msgname, size). -static const char *mutil_GetUserMsgName(plid_t plid, int msgid, int *size) { - plugin_info_t *plinfo; - MRegMsg *umsg; +const char* mutil_GetUserMsgName(plid_t plid, int msgid, int* size) +{ + plugin_info_t* plinfo; + MRegMsg* umsg; - plinfo=(plugin_info_t *)plid; + plinfo = (plugin_info_t *)plid; META_DEBUG(8, ("Looking up usermsg id '%d' for plugin '%s'", msgid, - plinfo->name)); - // Guess names for any built-in Engine messages mentioned in the SDK; + plinfo->name)); + // Guess names for any built-in g_engine messages mentioned in the SDK; // from dlls/util.h. if (msgid < 64) { - switch (msgid) - { + switch (msgid) { case SVC_TEMPENTITY: if (size) *size = -1; - return "tempentity?"; + return ("tempentity?"); case SVC_INTERMISSION: if (size) *size = -1; - return "intermission?"; + return ("intermission?"); case SVC_CDTRACK: if (size) *size = -1; - return "cdtrack?"; + return ("cdtrack?"); case SVC_WEAPONANIM: if (size) *size = -1; - return "weaponanim?"; + return ("weaponanim?"); case SVC_ROOMTYPE: if (size) *size = -1; - return "roomtype?"; + return ("roomtype?"); case SVC_DIRECTOR: if (size) *size = -1; - return "director?"; + return ("director?"); } } - umsg = RegMsgs->find(msgid); - if (umsg) - { + umsg = g_regMsgs->find(msgid); + if (umsg) { if (size) *size = umsg->size; // 'name' is assumed to be a constant string, allocated in the // gamedll. - return umsg->name; + return (umsg->name); } - - return nullptr; + else + return (NULL); } // Return the full path of the plugin's loaded dll/so file. -static const char *mutil_GetPluginPath(plid_t plid) { - static char buf[PATH_MAX]; - MPlugin *plug; +const char* mutil_GetPluginPath(plid_t plid) +{ + static char buf[PATH_MAX ]; + MPlugin* plug; - plug = Plugins->find(plid); - if (!plug) - { - META_WARNING("GetPluginPath: couldn't find plugin '%s'", plid->name); - return nullptr; + plug = g_plugins->find(plid); + if (!plug) { + META_ERROR("GetPluginPath: couldn't find plugin '%s'", + plid->name); + return (NULL); } - - Q_strncpy(buf, plug->pathname, sizeof(buf) - 1); - buf[sizeof(buf) - 1] = '\0'; - + strncpy(buf, plug->pathname, sizeof buf - 1); + buf[sizeof buf - 1] = '\0'; return buf; } // Return various string-based info about the game/MOD/gamedll. -const char *mutil_GetGameInfo(plid_t plid, ginfo_t type) +const char* mutil_GetGameInfo(plid_t plid, ginfo_t type) { static char buf[MAX_STRBUF_LEN]; - const char *cp; - switch (type) - { + const char* cp; + switch (type) { case GINFO_NAME: cp = GameDLL.name; break; @@ -227,39 +279,39 @@ const char *mutil_GetGameInfo(plid_t plid, ginfo_t type) cp = GameDLL.real_pathname; break; default: - META_WARNING("GetGameInfo: invalid request '%d' from plugin '%s'", type, plid->name); - return nullptr; + META_ERROR("GetGameInfo: invalid request '%d' from plugin '%s'", + type, plid->name); + return (NULL); } - - Q_strncpy(buf, cp, sizeof(buf) - 1); - buf[sizeof(buf) - 1] = '\0'; - + strncpy(buf, cp, sizeof buf - 1); + buf[sizeof buf - 1] = '\0'; return buf; } -int mutil_LoadMetaPlugin(plid_t plid, const char *fname, PLUG_LOADTIME now, void **plugin_handle) +int mutil_LoadMetaPlugin(plid_t plid, const char* fname, PLUG_LOADTIME now, void** plugin_handle) { - MPlugin *pl_loaded; + MPlugin* pl_loaded; if (NULL == fname) { return ME_ARGUMENT; } meta_errno = ME_NOERROR; - if (!(pl_loaded=Plugins->plugin_addload(plid, fname, now))) { + if (! (pl_loaded = g_plugins->plugin_addload(plid, fname, now))) { if (plugin_handle) *plugin_handle = NULL; return meta_errno; - } else { + } + else { if (plugin_handle) - *plugin_handle = (void*)pl_loaded->handle; + *plugin_handle = (void *)pl_loaded->handle; return 0; } } -static int mutil_UnloadMetaPlugin(plid_t plid, const char *fname, PLUG_LOADTIME now, PL_UNLOAD_REASON reason) +int mutil_UnloadMetaPlugin(plid_t plid, const char* fname, PLUG_LOADTIME now, PL_UNLOAD_REASON reason) { - MPlugin *findp = NULL; + MPlugin* findp = NULL; int pindex; char* endptr; @@ -269,9 +321,9 @@ static int mutil_UnloadMetaPlugin(plid_t plid, const char *fname, PLUG_LOADTIME pindex = strtol(fname, &endptr, 10); if (*fname != '\0' && *endptr == '\0') - findp = Plugins->find(pindex); + findp = g_plugins->find(pindex); else - findp = Plugins->find_match(fname); + findp = g_plugins->find_match(fname); if (!findp) return meta_errno; @@ -284,15 +336,15 @@ static int mutil_UnloadMetaPlugin(plid_t plid, const char *fname, PLUG_LOADTIME return meta_errno; } -static int mutil_UnloadMetaPluginByHandle(plid_t plid, void *plugin_handle, PLUG_LOADTIME now, PL_UNLOAD_REASON reason) +int mutil_UnloadMetaPluginByHandle(plid_t plid, void* plugin_handle, PLUG_LOADTIME now, PL_UNLOAD_REASON reason) { - MPlugin *findp; + MPlugin* findp; if (NULL == plugin_handle) { return ME_ARGUMENT; } - if (!(findp=Plugins->find((DLHANDLE)plugin_handle))) + if (!(findp = g_plugins->find((DLHANDLE)plugin_handle))) return ME_NOTFOUND; meta_errno = ME_NOERROR; @@ -303,44 +355,90 @@ static int mutil_UnloadMetaPluginByHandle(plid_t plid, void *plugin_handle, PLUG return meta_errno; } -// Check if player is being queried for cvar -static const char * mutil_IsQueryingClientCvar(plid_t /*plid*/, const edict_t *player) { - return g_Players.is_querying_cvar(player); +const char* mutil_IsQueryingClientCvar(plid_t /*plid*/, const edict_t* pEdict) +{ + return g_Players.is_querying_cvar(pEdict); } -// -static int mutil_MakeRequestID(plid_t /*plid*/) { - return abs(0xbeef<<16) + (++requestid_counter); +int mutil_MakeRequestId(plid_t /*plid*/) +{ + //the offset is to distinguish from gamedll requests, if any + return (abs(0xbeef << 16) + (++requestid_counter)); } -// -static void mutil_GetHookTables(plid_t plid, enginefuncs_t **peng, DLL_FUNCTIONS **pdll, NEW_DLL_FUNCTIONS **pnewdll) { +void mutil_GetHookTables(plid_t /*plid*/, enginefuncs_t** peng, DLL_FUNCTIONS** pdll, NEW_DLL_FUNCTIONS** pnewdll) +{ if (peng) *peng = &meta_engfuncs; if (pdll) - *pdll = g_pHookedDllFunctions; + *pdll = pHookedDllFunctions; if (pnewdll) - *pnewdll = g_pHookedNewDllFunctions; + *pnewdll = pHookedNewDllFunctions; } +#ifdef UNFINISHED +int mutil_HookGameEvent(plid_t plid, game_event_t event, + event_func_t pfnHandle) +{ + return(Hooks->add(plid, event, pfnHandle)); +} + +int mutil_HookLogTrigger(plid_t plid, const char *trigger, + logmatch_func_t pfnHandle) +{ + return(Hooks->add(plid, H_TRIGGER, trigger, pfnHandle)); +} + +int mutil_HookLogString(plid_t plid, const char *string, + logmatch_func_t pfnHandle) +{ + return(Hooks->add(plid, H_STRING, string, pfnHandle)); +} + +int mutil_HookLogRegex(plid_t plid, const char *pattern, + logmatch_func_t pfnHandle) +{ + return(Hooks->add(plid, H_STRING, pattern, pfnHandle)); +} + +qboolean mutil_RemoveHookID(plid_t plid, int hookid) { + mBOOL ret; + ret=Hooks->remove(plid, hookid); + if(ret==mTRUE) return(true); + else return(false); +} + +int mutil_RemoveHookAll(plid_t plid) { + return(Hooks->remove_all(plid)); +} +#endif /* UNFINISHED */ + // Meta Utility Function table. mutil_funcs_t MetaUtilFunctions = { - mutil_LogConsole, // pfnLogConsole - mutil_LogMessage, // pfnLogMessage - mutil_LogError, // pfnLogError - mutil_LogDeveloper, // pfnLogDeveloper - mutil_CenterSay, // pfnCenterSay - mutil_CenterSayParms, // pfnCenterSayParms - mutil_CenterSayVarargs, // pfnCenterSayVarargs - mutil_CallGameEntity, // pfnCallGameEntity - mutil_GetUserMsgID, // pfnGetUserMsgID - mutil_GetUserMsgName, // pfnGetUserMsgName - mutil_GetPluginPath, // pfnGetPluginPath - mutil_GetGameInfo, // pfnGetGameInfo - mutil_LoadMetaPlugin, // pfnLoadPlugin - mutil_UnloadMetaPlugin, // pfnUnloadPlugin - mutil_UnloadMetaPluginByHandle, // pfnUnloadPluginByHandle - mutil_IsQueryingClientCvar, // pfnIsQueryingClientCvar - mutil_MakeRequestID, // pfnMakeRequestID - mutil_GetHookTables, // pfnGetHookTables + mutil_LogConsole, // pfnLogConsole + mutil_LogMessage, // pfnLogMessage + mutil_LogError, // pfnLogError + mutil_LogDeveloper, // pfnLogDeveloper + mutil_CenterSay, // pfnCenterSay + mutil_CenterSayParms, // pfnCenterSayParms + mutil_CenterSayVarargs, // pfnCenterSayVarargs + mutil_CallGameEntity, // pfnCallGameEntity + mutil_GetUserMsgID, // pfnGetUserMsgID + mutil_GetUserMsgName, // pfnGetUserMsgName + mutil_GetPluginPath, // pfnGetPluginPath + mutil_GetGameInfo, // pfnGetGameInfo + mutil_LoadMetaPlugin, // pfnLoadPlugin + mutil_UnloadMetaPlugin, // pfnUnloadPlugin + mutil_UnloadMetaPluginByHandle, //pfnUnloadPluginByHandle + mutil_IsQueryingClientCvar, //pfnIsQueryingClientCvar + mutil_MakeRequestId, // pfnMakeRequestId + mutil_GetHookTables, // pfnGetHookTables +#ifdef UNFINISHED + mutil_HookGameEvent, // pfnGameEvent + mutil_HookLogTrigger, // pfnLogTrigger + mutil_HookLogString, // pfnLogString + mutil_HookLogRegex, // pfnLogRegex + mutil_RemoveHookID, // pfnRemoveHookID + mutil_RemoveHookAll, // pfnRemoveHookAll +#endif /* UNFINISHED */ }; diff --git a/metamod/src/mutil.h b/metamod/src/mutil.h index 5730070..9d545a6 100644 --- a/metamod/src/mutil.h +++ b/metamod/src/mutil.h @@ -1,4 +1,41 @@ -#pragma once +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// mutil.h - prototypes for utility functions to provide to plugins + +/* + * Copyright (c) 2001-2003 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game g_engine ("HL + * g_engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL g_engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + +#ifndef MUTIL_H +#define MUTIL_H #include "plinfo.h" // plugin_info_t, etc #include "sdk_util.h" // hudtextparms_t, etc @@ -7,47 +44,95 @@ #define MAX_LOGMSG_LEN 1024 // For GetGameInfo: -enum ginfo_t -{ +typedef enum { GINFO_NAME = 0, GINFO_DESC, GINFO_GAMEDIR, GINFO_DLL_FULLPATH, GINFO_DLL_FILENAME, GINFO_REALDLL_FULLPATH, -}; +} ginfo_t; // Meta Utility Function table type. -struct mutil_funcs_t -{ +typedef struct meta_util_funcs_s { void (*pfnLogConsole) (plid_t plid, const char *fmt, ...); void (*pfnLogMessage) (plid_t plid, const char *fmt, ...); void (*pfnLogError) (plid_t plid, const char *fmt, ...); void (*pfnLogDeveloper) (plid_t plid, const char *fmt, ...); void (*pfnCenterSay) (plid_t plid, const char *fmt, ...); - void (*pfnCenterSayParms) (plid_t plid, hudtextparms_t tparms, const char *fmt, ...); - void (*pfnCenterSayVarargs) (plid_t plid, hudtextparms_t tparms, const char *fmt, va_list ap); - qboolean (*pfnCallGameEntity) (plid_t plid, const char *entStr, entvars_t *pev); - int (*pfnGetUserMsgID) (plid_t plid, const char *msgname, int *size); - const char * (*pfnGetUserMsgName) (plid_t plid, int msgid, int *size); - const char * (*pfnGetPluginPath) (plid_t plid); - const char * (*pfnGetGameInfo) (plid_t plid, ginfo_t tag); + void (*pfnCenterSayParms) (plid_t plid, hudtextparms_t tparms, + const char *fmt, ...); + void (*pfnCenterSayVarargs) (plid_t plid, hudtextparms_t tparms, + const char *fmt, va_list ap); + qboolean (*pfnCallGameEntity) (plid_t plid, const char *entStr, + entvars_t *pev); + int (*pfnGetUserMsgID) (plid_t plid, const char *msgname, int *size); + const char *(*pfnGetUserMsgName) (plid_t plid, int msgid, int *size); + const char *(*pfnGetPluginPath) (plid_t plid); + const char *(*pfnGetGameInfo) (plid_t plid, ginfo_t tag); int (*pfnLoadPlugin) (plid_t plid, const char *cmdline, PLUG_LOADTIME now, void **plugin_handle); - int (*pfnUnloadPlugin) (plid_t plid, const char *cmdline, PLUG_LOADTIME now, PL_UNLOAD_REASON reason); - int (*pfnUnloadPluginByHandle) (plid_t plid, void *plugin_handle, PLUG_LOADTIME now, PL_UNLOAD_REASON reason); - const char * (*pfnIsQueryingClientCvar) (plid_t plid, const edict_t *player); - int (*pfnMakeRequestID) (plid_t plid); + int (*pfnUnloadPlugin) (plid_t plid, const char *cmdline, PLUG_LOADTIME now, PL_UNLOAD_REASON reason); + int (*pfnUnloadPluginByHandle) (plid_t plid, void *plugin_handle, PLUG_LOADTIME now, PL_UNLOAD_REASON reason); + const char *(*pfnIsQueryingClientCvar) (plid_t plid, const edict_t *pEdict); + int (*pfnMakeRequestId) (plid_t plid); void (*pfnGetHookTables) (plid_t plid, enginefuncs_t **peng, DLL_FUNCTIONS **pdll, NEW_DLL_FUNCTIONS **pnewdll); -}; - +#ifdef UNFINISHED + int (*pfnHookGameEvent) (plid_t plid, game_event_t event, + event_func_t pfnHandle); + int (*pfnHookLogTrigger) (plid_t plid, const char *trigger, + logmatch_func_t pfnHandle); + int (*pfnHookLogString) (plid_t plid, const char *string, + logmatch_func_t pfnHandle); + int (*pfnHookLogRegex) (plid_t plid, const char *pattern, + logmatch_func_t pfnHandle); + qboolean (*pfnRemoveHookID) (plid_t plid, int hookid); + int (*pfnRemoveHookAll) (plid_t plid); +#endif /* UNFINISHED */ +} mutil_funcs_t; extern mutil_funcs_t MetaUtilFunctions; +// Meta Utility Functions +void mutil_LogConsole(plid_t plid, const char *fmt, ...); +void mutil_LogMessage(plid_t plid, const char *fmt, ...); +void mutil_LogError(plid_t plid, const char *fmt, ...); +void mutil_LogDeveloper(plid_t plid, const char *fmt, ...); + +void mutil_CenterSay(plid_t plid, const char *fmt, ...); +void mutil_CenterSayParms(plid_t plid, hudtextparms_t tparms, + const char *fmt, ...); +void mutil_CenterSayVarargs(plid_t plid, hudtextparms_t tparms, + const char *fmt, va_list ap); + +qboolean mutil_CallGameEntity(plid_t plid, const char *entStr, entvars_t *pev); + +int mutil_GetUserMsgID(plid_t plid, const char *name, int *size); +const char *mutil_GetUserMsgName(plid_t plid, int msgid, int *size); +const char *mutil_GetPluginPath(plid_t plid); +const char *mutil_GetGameInfo(plid_t plid, ginfo_t tag); +const char *mutil_IsQueryingClientCvar(plid_t plid, const edict_t *pEdict); +int mutil_MakeRequestId(plid_t plid); +void mutil_GetHookTables(plid_t plid, enginefuncs_t **peng, DLL_FUNCTIONS **pdll, NEW_DLL_FUNCTIONS **pnewdll); + +#ifdef UNFINISHED +int mutil_HookGameEvent(plid_t plid, game_event_t event, + event_func_t pfnHandle); +int mutil_HookLogTrigger(plid_t plid, const char *trigger, + logmatch_func_t pfnHandle); +int mutil_HookLogString(plid_t plid, const char *string, + logmatch_func_t pfnHandle); +int mutil_HookLogRegex(plid_t plid, const char *pattern, + logmatch_func_t pfnHandle); + +qboolean mutil_RemoveHookID(plid_t plid, int hookid); +int mutil_RemoveHookAll(plid_t plid); +#endif /* UNFINISHED */ + // Convenience macros for MetaUtil functions -#define LOG_CONSOLE (*gpMetaUtilFuncs->pfnLogConsole) -#define LOG_MESSAGE (*gpMetaUtilFuncs->pfnLogMessage) -#define LOG_ERROR (*gpMetaUtilFuncs->pfnLogError) +#define LOG_CONSOLE (*gpMetaUtilFuncs->pfnLogConsole) +#define LOG_MESSAGE (*gpMetaUtilFuncs->pfnLogMessage) +#define LOG_ERROR (*gpMetaUtilFuncs->pfnLogError) #define LOG_DEVELOPER (*gpMetaUtilFuncs->pfnLogDeveloper) -#define CENTER_SAY (*gpMetaUtilFuncs->pfnCenterSay) +#define CENTER_SAY (*gpMetaUtilFuncs->pfnCenterSay) #define CENTER_SAY_PARMS (*gpMetaUtilFuncs->pfnCenterSayParms) #define CENTER_SAY_VARARGS (*gpMetaUtilFuncs->pfnCenterSayVarargs) #define CALL_GAME_ENTITY (*gpMetaUtilFuncs->pfnCallGameEntity) @@ -55,9 +140,20 @@ extern mutil_funcs_t MetaUtilFunctions; #define GET_USER_MSG_NAME (*gpMetaUtilFuncs->pfnGetUserMsgName) #define GET_PLUGIN_PATH (*gpMetaUtilFuncs->pfnGetPluginPath) #define GET_GAME_INFO (*gpMetaUtilFuncs->pfnGetGameInfo) -#define LOAD_PLUGIN (*gpMetaUtilFuncs->pfnLoadPlugin) +#define LOAD_PLUGIN (*gpMetaUtilFuncs->pfnLoadPlugin) #define UNLOAD_PLUGIN (*gpMetaUtilFuncs->pfnUnloadPlugin) -#define UNLOAD_PLUGIN_BY_HANDLE (*gpMetaUtilFuncs->pfnUnloadPluginByHandle) +#define UNLOAD_PLUGIN_BY_HANDLE (*gpMetaUtilFuncs->pfnUnloadPluginByHandle) #define IS_QUERYING_CLIENT_CVAR (*gpMetaUtilFuncs->pfnIsQueryingClientCvar) -#define MAKE_REQUESTID (*gpMetaUtilFuncs->pfnMakeRequestID) -#define GET_HOOK_TABLES (*gpMetaUtilFuncs->pfnGetHookTables) +#define MAKE_REQUESTID (*gpMetaUtilFuncs->pfnMakeRequestId) +#define GET_HOOK_TABLES (*gpMetaUtilFuncs->pfnGetHookTables) + +#ifdef UNFINISHED +#define HOOK_GAME_EVENT (*gpMetaUtilFuncs->pfnHookGameEvent) +#define HOOK_LOG_TRIGGER (*gpMetaUtilFuncs->pfnHookLogTrigger) +#define HOOK_LOG_STRING (*gpMetaUtilFuncs->pfnHookLogString) +#define HOOK_LOG_REGEX (*gpMetaUtilFuncs->pfnHookLogRegex) +#define REMOVE_HOOK_ID (*gpMetaUtilFuncs->pfnRemoveHookID) +#define REMOVE_HOOK_ALL (*gpMetaUtilFuncs->pfnRemoveHookAll) +#endif /* UNFINISHED */ + +#endif /* MUTIL_H */ diff --git a/metamod/src/new_baseclass.h b/metamod/src/new_baseclass.h deleted file mode 100644 index 09f5aa0..0000000 --- a/metamod/src/new_baseclass.h +++ /dev/null @@ -1,35 +0,0 @@ -#pragma once - -// new/delete operators with malloc/free to remove need for libstdc++ - -class class_metamod_new { -public: - // Construction - class_metamod_new() { }; - // Operators - inline void *operator new(size_t size) - { - if (size==0) - return calloc(1, 1); - return calloc(1, size); - } - - inline void *operator new[](size_t size) - { - if (size==0) - return calloc(1, 1); - return calloc(1, size); - } - - inline void operator delete(void *ptr) - { - if (ptr) - free(ptr); - } - - inline void operator delete[](void *ptr) - { - if (ptr) - free(ptr); - } -}; diff --git a/metamod/src/osdep.cpp b/metamod/src/osdep.cpp index a643756..6efe904 100644 --- a/metamod/src/osdep.cpp +++ b/metamod/src/osdep.cpp @@ -1,188 +1,80 @@ +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// osdep.cpp - routines for operating system differences + +/* + * Copyright (c) 2001-2003 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game g_engine ("HL + * g_engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL g_engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + #include "precompiled.h" mBOOL dlclose_handle_invalid; +// To keep the rest of the sources clean and keep not only OS but also +// compiler dependant differences in this file, we define a local function +// to set the new handler. +void mm_set_new_handler( void ) +{ +#if defined(_MSC_VER) && (_MSC_VER < 1300) + _set_new_handler(meta_new_handler); +#else + std::set_new_handler(meta_new_handler); +#endif +} + #ifdef _WIN32 - -#ifdef _MSC_VER -#pragma comment(lib, "psapi.lib") // Process Status API -#endif // _MSC_VER - // Since windows doesn't provide a verison of strtok_r(), we include one // here. This may or may not operate exactly like strtok_r(), but does // what we need it it do. -char *my_strtok_r(char *s, const char *delim, char **ptrptr) -{ - char *begin = nullptr; - char *end = nullptr; - char *rest = nullptr; - - if (s) - begin = s; +char *my_strtok_r(char *s, const char *delim, char **ptrptr) { + char *begin=NULL; + char *end=NULL; + char *rest=NULL; + if(s) + begin=s; else - begin = *ptrptr; - - if (!begin) - return nullptr; - - end = strpbrk(begin, delim); - if (end) - { + begin=*ptrptr; + if(!begin) + return(NULL); + end=strpbrk(begin, delim); + if(end) { *end='\0'; - rest = end + 1; - *ptrptr = rest + strspn(rest, delim); + rest=end+1; + *ptrptr=rest+strspn(rest, delim); } else - *ptrptr = nullptr; - - return begin; -} -#endif // _WIN32 - -#ifndef _WIN32 -char *my_strlwr(char *s) -{ - char *c; - if (!s) - return 0; - for (c=s;*c;c++) - *c = tolower(*c); - return s; -} -#endif - -#ifndef DO_NOT_FIX_VARARG_ENGINE_API_WARPERS -// Microsoft's msvcrt.dll:vsnprintf is buggy and so is vsnprintf on some glibc versions. -// We use wrapper function to fix bugs. -// from: http://sourceforge.net/tracker/index.php?func=detail&aid=1083721&group_id=2435&atid=102435 -int safe_vsnprintf(char *s, size_t n, const char *format, va_list src_ap) -{ - va_list ap; - int res; - char *tmpbuf; - size_t bufsize = n; - - if (s && n > 0) - s[0] = 0; - - // If the format string is empty, nothing to do. - if (!format || !*format) - return 0; - - // The supplied count may be big enough. Try to use the library - // vsnprintf, fixing up the case where the library function - // neglects to terminate with '/0'. - if (n > 0) - { - // A NULL destination will cause a segfault with vsnprintf. - // if n > 0. Nor do we want to copy our tmpbuf to NULL later. - if (!s) - return -1; - - va_copy(ap, src_ap); - res = Q_vsnprintf(s, n, format, ap); - va_end(ap); - - if (res > 0) - { - if ((unsigned)res == n) - s[res - 1] = 0; - return res; - } - - // If n is already larger than INT_MAX, increasing it won't - // help. - if (n > INT_MAX) - return -1; - - // Try a larger buffer. - bufsize *= 2; - } - - if (bufsize < 1024) - bufsize = 1024; - - tmpbuf = (char *)malloc(bufsize * sizeof(char)); - if (!tmpbuf) - return -1; - - va_copy(ap, src_ap); - res = Q_vsnprintf(tmpbuf, bufsize, format, ap); - va_end(ap); - - // The test for bufsize limit is probably not necesary - // with 2GB address space limit, since, in practice, malloc will - // fail well before INT_MAX. - while (res < 0 && bufsize <= INT_MAX) - { - char *newbuf; - - bufsize *= 2; - newbuf = (char *)realloc(tmpbuf, bufsize * sizeof(char)); - - if (!newbuf) - break; - - tmpbuf = newbuf; - - va_copy(ap, src_ap); - res = Q_vsnprintf(tmpbuf, bufsize, format, ap); - va_end(ap); - } - - if (res > 0 && n > 0) - { - if (n > (unsigned)res) - Q_memcpy(s, tmpbuf, (res + 1) * sizeof (char)); - else - { - Q_memcpy(s, tmpbuf, (n - 1) * sizeof (char)); - s[n - 1] = 0; - } - } - - free(tmpbuf); - return res; -} - -int safe_snprintf(char *s, size_t n, const char *format, ...) -{ - int res; - va_list ap; - va_start(ap, format); - res = safe_vsnprintf(s, n, format, ap); - va_end(ap); - return res; -} -#endif - -void safevoid_vsnprintf(char *s, size_t n, const char *format, va_list ap) -{ - int res; - if (!s || n <= 0) - return; - - // If the format string is empty, nothing to do. - if (!format || !*format) - { - s[0] = 0; - return; - } - - res = Q_vsnprintf(s, n, format, ap); - // w32api returns -1 on too long write, glibc returns number of bytes it could have written if there were enough space - // w32api doesn't write null at all, some buggy glibc don't either - if (res < 0 || (size_t)res >= n) - s[n - 1] = 0; -} - -void safevoid_snprintf(char *s, size_t n, const char *format, ...) -{ - va_list ap; - va_start(ap, format); - safevoid_vsnprintf(s, n, format, ap); - va_end(ap); + *ptrptr=NULL; + return(begin); } +#endif /* _WIN32 */ #ifdef _WIN32 @@ -191,32 +83,31 @@ void safevoid_snprintf(char *s, size_t n, const char *format, ...) // http://msdn.microsoft.com/library/en-us/debug/errors_0sdh.asp // except without FORMAT_MESSAGE_ALLOCATE_BUFFER, since we use a local // static buffer. -char *str_GetLastError() -{ +const char *str_GetLastError(void) { static char buf[MAX_STRBUF_LEN]; - FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &buf, MAX_STRBUF_LEN - 1, NULL); - return buf; + FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, GetLastError(), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), //! Default language + (LPTSTR) &buf, MAX_STRBUF_LEN-1, NULL); + return(buf); } - -#endif // _WIN32 +#endif /* _WIN32 */ // Find the filename of the DLL/shared-lib where the given memory location // exists. -#ifndef _WIN32 +#if defined(linux) || defined(__APPLE__) // Errno values: // - ME_NOTFOUND couldn't find a sharedlib that contains memory location -const char *DLFNAME(void *memptr) -{ +const char *DLFNAME(void *memptr) { Dl_info dli; - Q_memset(&dli, 0, sizeof(dli)); - if (dladdr(memptr, &dli)) - return dli.dli_fname; + memset(&dli, 0, sizeof(dli)); + if(dladdr(memptr, &dli)) + return(dli.dli_fname); else RETURN_ERRNO(NULL, ME_NOTFOUND); } - -#else +#elif defined(_WIN32) // Implementation for win32 provided by Jussi Kivilinna : // // 1. Get memory location info on memptr with VirtualQuery. @@ -238,136 +129,88 @@ const char *DLFNAME(void *memptr) // // Errno values: // - ME_NOTFOUND couldn't find a DLL that contains memory location -const char *DLFNAME(void *memptr) -{ +const char *DLFNAME(void *memptr) { MEMORY_BASIC_INFORMATION MBI; static char fname[PATH_MAX]; - Q_memset(fname, 0, sizeof(fname)); + memset(fname, 0, sizeof(fname)); if (!VirtualQuery(memptr, &MBI, sizeof(MBI))) RETURN_ERRNO(NULL, ME_NOTFOUND); - if (MBI.State != MEM_COMMIT) RETURN_ERRNO(NULL, ME_NOTFOUND); - - if (!MBI.AllocationBase) + if(!MBI.AllocationBase) RETURN_ERRNO(NULL, ME_NOTFOUND); - + // MSDN indicates that GetModuleFileName will leave string // null-terminated, even if it's truncated because buffer is too small. - if (!GetModuleFileNameA((HMODULE)MBI.AllocationBase, fname, sizeof(fname) - 1)) + if(!GetModuleFileName((HMODULE)MBI.AllocationBase, fname, + sizeof(fname)-1)) RETURN_ERRNO(NULL, ME_NOTFOUND); - - if (!fname[0]) + if(!fname[0]) RETURN_ERRNO(NULL, ME_NOTFOUND); - + normalize_pathname(fname); - return fname; + return(fname); } -#endif // _WIN32 +#endif /* _WIN32 */ -#ifdef _WIN32 -// Normalize/standardize a pathname. -// - For win32, this involves: -// - Turning backslashes (\) into slashes (/), so that config files and -// Metamod internal code can be simpler and just use slashes (/). -// - Turning upper/mixed case into lowercase, since windows is -// non-case-sensitive. -// - For linux, this requires no work, as paths uses slashes (/) natively, -// and pathnames are case-sensitive. -void normalize_pathname(char *path) -{ - char *cp; - - META_DEBUG(8, ("normalize: %s", path)); - for (cp = path; *cp; cp++) - { - /*if (isupper(*cp))*/ - *cp=tolower(*cp); - - if (*cp == '\\') - *cp = '/'; - } - - META_DEBUG(8, ("normalized: %s", path)); -} - -// Buffer pointed to by resolved_name is assumed to be able to store a -// string of PATH_MAX length. -char *realpath(const char *file_name, char *resolved_name) -{ - int ret; - ret = GetFullPathNameA(file_name, PATH_MAX, resolved_name, NULL); - - if (ret > PATH_MAX) - { - errno=ENAMETOOLONG; - return nullptr; - } - else if (ret > 0) - { - HANDLE handle; - WIN32_FIND_DATAA find_data; - handle = FindFirstFileA(resolved_name, &find_data); - if (INVALID_HANDLE_VALUE == handle) - { - errno = ENOENT; - return nullptr; - } - - FindClose(handle); - normalize_pathname(resolved_name); - return resolved_name; - } - else - return nullptr; -} -#endif // _WIN32 // 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). -#ifndef _WIN32 +#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 -mBOOL IS_VALID_PTR(void *memptr) -{ +mBOOL IS_VALID_PTR(void *memptr) { Dl_info dli; - Q_memset(&dli, 0, sizeof(dli)); - if (dladdr(memptr, &dli)) - return mTRUE; + memset(&dli, 0, sizeof(dli)); + if(dladdr(memptr, &dli)) + return(mTRUE); else RETURN_ERRNO(mFALSE, ME_NOTFOUND); } -#else +#elif defined(_WIN32) // Use the native windows routine IsBadCodePtr. // meta_errno values: // - ME_BADMEMPTR not a valid memory pointer -mBOOL IS_VALID_PTR(void *memptr) -{ - if (IsBadCodePtr((FARPROC) memptr)) +mBOOL IS_VALID_PTR(void *memptr) { + if(IsBadCodePtr((FARPROC) memptr)) RETURN_ERRNO(mFALSE, ME_BADMEMPTR); else - return mTRUE; + return(mTRUE); } -#endif // _WIN32 +#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. -mBOOL os_safe_call(REG_CMD_FN pfn) -{ +mBOOL os_safe_call(REG_CMD_FN pfn) { // try and see if this is a valid memory location - if (!IS_VALID_PTR((void *)pfn)) + if(!IS_VALID_PTR((void *) pfn)) // meta_errno should be already set in is_valid_ptr() - return mFALSE; + return(mFALSE); pfn(); - return mTRUE; + return(mTRUE); } + +// See comments in osdep.h. +#if defined(__GNUC__) || (defined(_MSC_VER) && (_MSC_VER >= 1300)) +void MM_CDECL meta_new_handler(void) { + // This merely because we don't want the program to exit if new() + // fails.. + return; +} +#elif defined(_MSC_VER) +int meta_new_handler(size_t size) { + // This merely because we don't want the program to exit if new() + // fails.. + return(0); +} +#endif /* _MSC_VER */ diff --git a/metamod/src/osdep.h b/metamod/src/osdep.h index 9195b22..2dd5b68 100644 --- a/metamod/src/osdep.h +++ b/metamod/src/osdep.h @@ -1,103 +1,185 @@ -#pragma once +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// osdep.h - operating system dependencies + +/* + * Copyright (c) 2001-2003 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game g_engine ("HL + * g_engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL g_engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + +#ifndef OSDEP_H +#define OSDEP_H + +#include // strerror() +#include // isupper, tolower +#include // errno // Various differences between WIN32 and Linux. + #include "types_meta.h" // mBOOL #include "mreg.h" // REG_CMD_FN, etc #include "log_meta.h" // LOG_ERROR, etc +extern mBOOL dlclose_handle_invalid; + // String describing platform/DLL-type, for matching lines in plugins.ini. -#ifdef _WIN32 - #define UNUSED /**/ - - #define PLATFORM "mswin" - #define PLATFORM_SPC "win32" - #define PLATFORM_DLEXT ".dll" -#else - #define UNUSED __attribute__((unused)) - - #define PLATFORM "linux" +#ifdef __linux + #define PLATFORM "linux" +# ifdef __amd64__ + #define PLATFORM_SPC "lin64" +# else #define PLATFORM_SPC "lin32" - #define PLATFORM_DLEXT ".so" -#endif +# endif +#elif defined(_WIN32) + #define PLATFORM "mswin" + #define PLATFORM_SPC "win32" +#elif defined(__APPLE__) + #define PLATFORM "osx" + #define PLATFORM_SPC "osx32" +#else /* unknown */ + #error "OS unrecognized" +#endif /* unknown */ + + +// Macro for function-exporting from DLL.. +// from SDK dlls/cbase.h: +//! C functions for external declarations that call the appropriate C++ methods + +// Windows uses "__declspec(dllexport)" to mark functions in the DLL that +// should be visible/callable externally. +// +// It also apparently requires WINAPI for GiveFnptrsToDll(). +// +// See doc/notes_windows_coding for more information.. + +// Attributes to specify an "exported" function, visible from outside the +// DLL. +#undef DLLEXPORT +#ifdef _WIN32 + #define DLLEXPORT __declspec(dllexport) + // WINAPI should be provided in the windows compiler headers. + // It's usually defined to something like "__stdcall". +#elif defined(__GNUC__) +# if __GNUC__ >= 4 + #define DLLEXPORT __attribute__ ((visibility("default"))) +# else + #define DLLEXPORT /* */ +# endif + #define WINAPI /* */ +#endif /* linux */ + +#ifdef __GNUC__ +# define DECLSPEC(kw) +# define ATTRIBUTE(kw) __attribute__((kw)) +# define MM_CDECL +#elif defined(_MSC_VER) +# define DECLSPEC(kw) __declspec(kw) +# define ATTRIBUTE(kw) +# define MM_CDECL __cdecl +#endif /* _MSC_VER */ + + +// Simplified macro for declaring/defining exported DLL functions. They +// need to be 'extern "C"' so that the C++ compiler enforces parameter +// type-matching, rather than considering routines with mis-matched +// arguments/types to be overloaded functions... +// +// AFAIK, this is os-independent, but it's included here in osdep.h where +// DLLEXPORT is defined, for convenience. +#define C_DLLEXPORT extern "C" DLLEXPORT + + +#ifdef _MSC_VER + // Disable MSVC warning: + // 4390 : empty controlled statement found; is this what was intended? + // generated by the RETURN macros. + #pragma warning(disable: 4390) +#endif /* _MSC_VER */ -// Special version that fixes vsnprintf bugs. -#ifndef DO_NOT_FIX_VARARG_ENGINE_API_WARPERS -int safe_vsnprintf(char* s, size_t n, const char *format, va_list ap); -int safe_snprintf(char* s, size_t n, const char* format, ...); -#endif -void safevoid_vsnprintf(char* s, size_t n, const char *format, va_list ap); -void safevoid_snprintf(char* s, size_t n, const char* format, ...); // Functions & types for DLL open/close/etc operations. -extern mBOOL dlclose_handle_invalid; -#ifdef _WIN32 +#if defined(__linux) || defined(__APPLE__) + #include + typedef void* DLHANDLE; + typedef void* DLFUNC; + inline DLHANDLE DLOPEN(const char *filename) { + return(dlopen(filename, RTLD_NOW)); + } + inline DLFUNC DLSYM(DLHANDLE handle, const char *string) { + return(dlsym(handle, string)); + } + inline int DLCLOSE(DLHANDLE handle) { + if (!handle) { + dlclose_handle_invalid = mTRUE; + return(1); + } + dlclose_handle_invalid = mFALSE; + return(dlclose(handle)); + } + inline const char* DLERROR(void) { + if (dlclose_handle_invalid) + return("Invalid handle."); + return(dlerror()); + } +#elif defined(_WIN32) typedef HINSTANCE DLHANDLE; typedef FARPROC DLFUNC; - inline DLHANDLE DLOPEN(const char *filename) - { - return LoadLibraryA(filename); + inline DLHANDLE DLOPEN(const char *filename) { + return(LoadLibrary(filename)); } - inline DLFUNC DLSYM(DLHANDLE handle, const char *string) - { - return GetProcAddress(handle, string); + inline DLFUNC DLSYM(DLHANDLE handle, const char *string) { + return(GetProcAddress(handle, string)); } - inline int DLCLOSE(DLHANDLE handle) - { - if (!handle) - { + inline int DLCLOSE(DLHANDLE handle) { + if (!handle) { dlclose_handle_invalid = mTRUE; - return 1; + return(1); } - dlclose_handle_invalid = mFALSE; // NOTE: Windows FreeLibrary returns success=nonzero, fail=zero, // which is the opposite of the unix convention, thus the '!'. - return !FreeLibrary(handle); + return(!FreeLibrary(handle)); } // Windows doesn't provide a function corresponding to dlerror(), so // we make our own. - char *str_GetLastError(); - inline const char *DLERROR() - { + const char *str_GetLastError(void); + inline const char* DLERROR(void) { if (dlclose_handle_invalid) - return "Invalid handle."; - - return str_GetLastError(); + return("Invalid handle."); + return(str_GetLastError()); } -#else - typedef void *DLHANDLE; - typedef void *DLFUNC; - inline DLHANDLE DLOPEN(const char *filename) - { - return dlopen(filename, RTLD_NOW); - } - inline DLFUNC DLSYM(DLHANDLE handle, const char *string) - { - return dlsym(handle, string); - } - // dlclose crashes if handle is null. - inline int DLCLOSE(DLHANDLE handle) - { - if (!handle) - { - dlclose_handle_invalid = mTRUE; - return 1; - } - dlclose_handle_invalid = mFALSE; - return dlclose(handle); - } - inline const char *DLERROR() - { - if (dlclose_handle_invalid) - return "Invalid handle."; - - return dlerror(); - } -#endif - +#endif /* _WIN32 */ const char *DLFNAME(void *memptr); mBOOL IS_VALID_PTR(void *memptr); + // Attempt to call the given function pointer, without segfaulting. mBOOL os_safe_call(REG_CMD_FN pfn); @@ -106,11 +188,7 @@ mBOOL os_safe_call(REG_CMD_FN pfn); #ifdef _WIN32 #define strtok_r(s, delim, ptrptr) my_strtok_r(s, delim, ptrptr) char *my_strtok_r(char *s, const char *delim, char **ptrptr); -#else -// Linux doesn't have an strlwr() routine, so we write our own. - #define strlwr(s) my_strlwr(s) - char *my_strlwr(char *s); -#endif // _WIN32 +#endif /* _WIN32 */ // Set filename and pathname maximum lengths. Note some windows compilers @@ -120,48 +198,37 @@ mBOOL os_safe_call(REG_CMD_FN pfn); // Note that both OS's include room for null-termination: // linux: "# chars in a path name including nul" // win32: "note that the sizes include space for 0-terminator" -#ifdef linux +#if defined(__linux) || defined(__APPLE__) #include #elif defined(_WIN32) #include #define NAME_MAX _MAX_FNAME - #ifndef PATH_MAX - #define PATH_MAX _MAX_PATH - #endif -#endif // _WIN32 + #define PATH_MAX _MAX_PATH +#endif /* _WIN32 */ + // Various other windows routine differences. -#ifdef linux +#if defined(__linux) || defined(__APPLE__) #include // sleep #ifndef O_BINARY - #define O_BINARY 0 - #endif + #define O_BINARY 0 + #endif #elif defined(_WIN32) - #include - #include + #define snprintf _snprintf + #define vsnprintf _vsnprintf + #define sleep(x) Sleep(x*1000) + #include + #define open _open + #define read _read + #define write _write + #define close _close +#endif /* _WIN32 */ - #define sleep(x) Sleep(x*1000) - - // Fixed MSVC compiling, by Nikolay "The Storm" Baklicharov. - #if defined(__GNUC__) || defined (_MSC_VER) && _MSC_VER >= 1400 - #define snprintf _snprintf - #define vsnprintf _vsnprintf - #define unlink _unlink - #define strlwr _strlwr - #define strdup _strdup - #define strcasecmp _stricmp - #define strncasecmp _strnicmp - #define getcwd _getcwd - #define open _open - #define read _read - #define write _write - #define close _close - #endif /* GCC or MSVC 8.0+ */ -#endif // _WIN32 - -#if !defined WIN32 && !defined _MSC_VER -#include // getcwd -#endif +#ifdef __GNUC__ + #include // _getcwd +#elif defined(_MSC_VER) + #include // _getcwd +#endif /* _MSC_VER */ #include #ifndef S_ISREG @@ -177,7 +244,7 @@ mBOOL os_safe_call(REG_CMD_FN pfn); #ifndef S_IWUSR #define S_IWUSR _S_IWRITE #endif - + // The following two are defined neither in mingw nor in MSVC #ifndef S_IRGRP #define S_IRGRP S_IRUSR @@ -185,7 +252,201 @@ mBOOL os_safe_call(REG_CMD_FN pfn); #ifndef S_IWGRP #define S_IWGRP S_IWUSR #endif -#endif // _WIN32 +#endif /* _WIN32 */ + + +// Our handler for new(). +// +// Thanks to notes from: +// http://dragon.klte.hu/~kollarl/C++/node45.html +// +// At one point it appeared MSVC++ was no longer different from gcc, according +// to: +// http://msdn.microsoft.com/library/en-us/vclang98/stdlib/info/NEW.asp +// +// However, this page is apparently no longer available from MSDN. The +// only thing now is: +// http://msdn.microsoft.com/library/en-us/vccore98/HTML/_crt_malloc.asp +// +// According to Fritz Elfert : +// set_new_handler() is just a stub which (according to comments in the +// MSVCRT debugging sources) should never be used. It is just an ugly +// hack to make STL compile. It does _not_ set the new handler but +// always calls _set_new_handler(0) instead. _set_new_handler is the +// "real" function and uses the "old" semantic; handler-type is: +// int newhandler(size_t) +// +#if defined(__GNUC__) || (defined(_MSC_VER) && (_MSC_VER >= 1300)) + void MM_CDECL meta_new_handler(void); +#elif defined(_MSC_VER) + int meta_new_handler(size_t size); +#endif /* _MSC_VER */ + + +// To keep the rest of the sources clean and keep not only OS but also +// compiler dependant differences in this file, we define a local function +// to set the new handler. +void mm_set_new_handler( void ); + + + +// Thread handling... +#if defined(__linux) || defined(__APPLE__) + #include + typedef pthread_t THREAD_T; + // returns 0==success, non-zero==failure + inline int THREAD_CREATE(THREAD_T *tid, void (*func)(void)) { + int ret; + ret=pthread_create(tid, NULL, (void *(*)(void*)) func, NULL); + if(ret != 0) { + META_ERROR("Failure starting thread: %s", strerror(ret)); + return(ret); + } + ret=pthread_detach(*tid); + if(ret != 0) + META_ERROR("Failure detaching thread: %s", strerror(ret)); + return(ret); + } +#elif defined(_WIN32) + // See: + // http://msdn.microsoft.com/library/en-us/dllproc/prothred_4084.asp + typedef DWORD THREAD_T; + // returns 0==success, non-zero==failure + inline int THREAD_CREATE(THREAD_T *tid, void (*func)(void)) { + HANDLE ret; + // win32 returns NULL==failure, non-NULL==success + ret=CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) func, NULL, 0, tid); + if(ret==NULL) + META_ERROR("Failure starting thread: %s", str_GetLastError()); + return(ret==NULL); + } +#endif /* _WIN32 */ +#define THREAD_OK 0 + + +// Mutex handling... +#if defined(__linux) || defined(__APPLE__) + typedef pthread_mutex_t MUTEX_T; + inline int MUTEX_INIT(MUTEX_T *mutex) { + int ret; + ret=pthread_mutex_init(mutex, NULL); + if(ret!=THREAD_OK) + META_ERROR("mutex_init failed: %s", strerror(ret)); + return(ret); + } + inline int MUTEX_LOCK(MUTEX_T *mutex) { + int ret; + ret=pthread_mutex_lock(mutex); + if(ret!=THREAD_OK) + META_ERROR("mutex_lock failed: %s", strerror(ret)); + return(ret); + } + inline int MUTEX_UNLOCK(MUTEX_T *mutex) { + int ret; + ret=pthread_mutex_unlock(mutex); + if(ret!=THREAD_OK) + META_ERROR("mutex_unlock failed: %s", strerror(ret)); + return(ret); + } +#elif defined(_WIN32) + // Win32 has "mutexes" as well, but CS's are simpler. + // See: + // http://msdn.microsoft.com/library/en-us/dllproc/synchro_2a2b.asp + typedef CRITICAL_SECTION MUTEX_T; + // Note win32 routines don't return any error (return void). + inline int MUTEX_INIT(MUTEX_T *mutex) { + InitializeCriticalSection(mutex); + return(THREAD_OK); + } + inline int MUTEX_LOCK(MUTEX_T *mutex) { + EnterCriticalSection(mutex); + return(THREAD_OK); + } + inline int MUTEX_UNLOCK(MUTEX_T *mutex) { + LeaveCriticalSection(mutex); + return(THREAD_OK); + } +#endif /* _WIN32 (mutex) */ + + +// Condition variables... +#if defined(__linux) || defined(__APPLE__) + typedef pthread_cond_t COND_T; + inline int COND_INIT(COND_T *cond) { + int ret; + ret=pthread_cond_init(cond, NULL); + if(ret!=THREAD_OK) + META_ERROR("cond_init failed: %s", strerror(ret)); + return(ret); + } + inline int COND_WAIT(COND_T *cond, MUTEX_T *mutex) { + int ret; + ret=pthread_cond_wait(cond, mutex); + if(ret!=THREAD_OK) + META_ERROR("cond_wait failed: %s", strerror(ret)); + return(ret); + } + inline int COND_SIGNAL(COND_T *cond) { + int ret; + ret=pthread_cond_signal(cond); + if(ret!=THREAD_OK) + META_ERROR("cond_signal failed: %s", strerror(ret)); + return(ret); + } +#elif defined(_WIN32) + // Since win32 doesn't provide condition-variables, we have to model + // them with mutex/critical-sections and win32 events. This uses the + // second (SetEvent) solution from: + // + // http://www.cs.wustl.edu/~schmidt/win32-cv-1.html + // + // but without the waiters_count overhead, since we don't need + // broadcast functionality anyway. Or actually, I guess it's more like + // the first (PulseEvent) solution, but with SetEven rather than + // PulseEvent. :) + // + // See also: + // http://msdn.microsoft.com/library/en-us/dllproc/synchro_8ann.asp + typedef HANDLE COND_T; + inline int COND_INIT(COND_T *cond) { + *cond = CreateEvent(NULL, // security attributes (none) + FALSE, // manual-reset type (false==auto-reset) + FALSE, // initial state (unsignaled) + NULL); // object name (unnamed) + // returns NULL on error + if(*cond==NULL) { + META_ERROR("cond_init failed: %s", str_GetLastError()); + return(-1); + } + else + return(0); + } + inline int COND_WAIT(COND_T *cond, MUTEX_T *mutex) { + DWORD ret; + LeaveCriticalSection(mutex); + ret=WaitForSingleObject(*cond, INFINITE); + EnterCriticalSection(mutex); + // returns WAIT_OBJECT_0 if object was signaled; other return + // values indicate errors. + if(ret == WAIT_OBJECT_0) + return(0); + else { + META_ERROR("cond_wait failed: %s", str_GetLastError()); + return(-1); + } + } + inline int COND_SIGNAL(COND_T *cond) { + BOOL ret; + ret=SetEvent(*cond); + // returns zero on failure + if(ret==0) { + META_ERROR("cond_signal failed: %s", str_GetLastError()); + return(-1); + } + else + return(0); + } +#endif /* _WIN32 (condition variable) */ // Normalize/standardize a pathname. // - For win32, this involves: @@ -195,11 +456,20 @@ mBOOL os_safe_call(REG_CMD_FN pfn); // non-case-sensitive. // - For linux, this requires no work, as paths uses slashes (/) natively, // and pathnames are case-sensitive. -#ifdef linux +#if defined(__linux) || defined(__APPLE__) #define normalize_pathname(a) #elif defined(_WIN32) -void normalize_pathname(char *path); -#endif // _WIN32 +inline void normalize_pathname(char *path) { + char *cp; + + META_DEBUG(8, ("normalize: %s", path)); + for(cp=path; *cp; cp++) { + if(isupper(*cp)) *cp=tolower(*cp); + if(*cp=='\\') *cp='/'; + } + META_DEBUG(8, ("normalized: %s", path)); +} +#endif /* _WIN32 */ // Indicate if pathname appears to be an absolute-path. Under linux this // is a leading slash (/). Under win32, this can be: @@ -207,28 +477,51 @@ void normalize_pathname(char *path); // - a toplevel path (ie "\blah") // - a UNC network address (ie "\\srv1\blah"). // Also, handle both native and normalized pathnames. -inline mBOOL is_absolute_path(const char *path) { - if (path[0]=='/') return mTRUE; +inline int is_absolute_path(const char *path) { + if(path[0]=='/') return(TRUE); #ifdef _WIN32 - if (path[1]==':') return mTRUE; - if (path[0]=='\\') return mTRUE; -#endif // _WIN32 - return mFALSE; + if(path[1]==':') return(TRUE); + if(path[0]=='\\') return(TRUE); +#endif /* _WIN32 */ + return(FALSE); } #ifdef _WIN32 // Buffer pointed to by resolved_name is assumed to be able to store a // string of PATH_MAX length. -char *realpath(const char *file_name, char *resolved_name); -#endif // _WIN32 +inline char *realpath(const char *file_name, char *resolved_name) { + int ret; + ret=GetFullPathName(file_name, PATH_MAX, resolved_name, NULL); + if(ret > PATH_MAX) { + errno=ENAMETOOLONG; + return(NULL); + } + else if(ret > 0) { + HANDLE handle; + WIN32_FIND_DATA find_data; + handle=FindFirstFile(resolved_name, &find_data); + if(INVALID_HANDLE_VALUE == handle) { + errno=ENOENT; + return NULL; + } + FindClose(handle); + normalize_pathname(resolved_name); + return(resolved_name); + } + else + return(NULL); +} +#endif /* _WIN32 */ // Generic "error string" from a recent OS call. For linux, this is based // on errno. For win32, it's based on GetLastError. -inline const char *str_os_error() -{ -#ifdef _WIN32 - return str_GetLastError(); -#else - return strerror(errno); -#endif +inline const char *str_os_error(void) { +#if defined(__linux) || defined(__APPLE__) + return(strerror(errno)); +#elif defined(_WIN32) + return(str_GetLastError()); +#endif /* _WIN32 */ } + + +#endif /* OSDEP_H */ diff --git a/metamod/src/osdep_linkent_linux.cpp b/metamod/src/osdep_linkent_linux.cpp deleted file mode 100644 index e901e27..0000000 --- a/metamod/src/osdep_linkent_linux.cpp +++ /dev/null @@ -1,191 +0,0 @@ -#include // always - -#ifndef __USE_GNU -#define __USE_GNU -#endif - -#include -#include -#define PAGE_SIZE 4096UL -#define PAGE_MASK (~(PAGE_SIZE-1)) -#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) -#include -#include - -#include "osdep.h" -#include "osdep_p.h" -#include "log_meta.h" // META_LOG, etc -#include "support_meta.h" - -// Linux code for dynamic linkents -// opcode, e9, + sizeof pointer -#define BYTES_SIZE (1 + sizeof(void *)) - -typedef void *(*dlsym_func)(void *module, const char *funcname); - -static void *gamedll_module_handle = 0; -static void *metamod_module_handle = 0; - -// pointer to original dlsym -static dlsym_func dlsym_original; - -// contains jmp to replacement_dlsym @dlsym_original -static unsigned char dlsym_new_bytes[BYTES_SIZE]; - -// contains original bytes of dlsym -static unsigned char dlsym_old_bytes[BYTES_SIZE]; - -// Mutex for our protection -static pthread_mutex_t mutex_replacement_dlsym = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; - -// constructs new jmp forwarder -inline void construct_jmp_instruction(void *x, void *place, void *target) -{ - ((unsigned char *)x)[0] = 0xe9; - *(unsigned long *)((char *)x + 1) = (unsigned long)target - ((unsigned long)place + 5); -} - -// checks if pointer x points to jump forwarder -inline bool is_code_trampoline_jmp_opcode(void *x) -{ - return (((unsigned char *)x)[0] == 0xff || ((unsigned char *)x)[1] == 0x25); -} - -// extracts pointer from "jmp dword ptr[pointer]" -inline void *extract_function_pointer_from_trampoline_jmp(void *x) -{ - return (**(void ***)((char *)(x) + 2)); -} - -//restores old dlsym -inline void restore_original_dlsym() -{ - //Copy old dlsym bytes back - Q_memcpy((void *)dlsym_original, dlsym_old_bytes, BYTES_SIZE); -} - -//resets new dlsym -inline void reset_dlsym_hook() -{ - //Copy new dlsym bytes back - Q_memcpy((void *)dlsym_original, dlsym_new_bytes, BYTES_SIZE); -} - -// Replacement dlsym function -static void *__replacement_dlsym(void *module, const char *funcname) -{ - //these are needed in case dlsym calls dlsym, default one doesn't do - //it but some LD_PRELOADed library that hooks dlsym might actually - //do so. - static int is_original_restored = 0; - int was_original_restored = is_original_restored; - - //Lock before modifing original dlsym - pthread_mutex_lock(&mutex_replacement_dlsym); - - //restore old dlsym - if (!is_original_restored) - { - restore_original_dlsym(); - - is_original_restored = 1; - } - - //check if we should hook this call - if (module != metamod_module_handle || !metamod_module_handle || !gamedll_module_handle) - { - //no metamod/gamedll module? should we remove hook now? - void *retval = dlsym_original(module, funcname); - - if (metamod_module_handle && gamedll_module_handle) - { - if (!was_original_restored) - { - //reset dlsym hook - reset_dlsym_hook(); - - is_original_restored = 0; - } - } - else - { - //no metamod/gamedll module? should we remove hook now by not reseting it back? - } - - //unlock - pthread_mutex_unlock(&mutex_replacement_dlsym); - - return retval; - } - - //dlsym on metamod module - void *func = dlsym_original(module, funcname); - - if (!func) - { - //function not in metamod module, try gamedll - func = dlsym_original(gamedll_module_handle, funcname); - } - - if (!was_original_restored) - { - //reset dlsym hook - reset_dlsym_hook(); - - is_original_restored = 0; - } - - //unlock - pthread_mutex_unlock(&mutex_replacement_dlsym); - return func; -} - -// Initialize -int init_linkent_replacement(DLHANDLE MetamodHandle, DLHANDLE GameDllHandle) -{ - metamod_module_handle = MetamodHandle; - gamedll_module_handle = GameDllHandle; - - // dlsym is already known to be pointing to valid function, we loaded gamedll using it earlier! - void *sym_ptr = (void*)&dlsym; - while (is_code_trampoline_jmp_opcode(sym_ptr)) - { - sym_ptr = extract_function_pointer_from_trampoline_jmp(sym_ptr); - } - - dlsym_original = (dlsym_func)sym_ptr; - - // Backup old bytes of "dlsym" function - Q_memcpy(dlsym_old_bytes, (void *)dlsym_original, BYTES_SIZE); - - // Construct new bytes: "jmp offset[replacement_sendto] @ sendto_original" - construct_jmp_instruction((void *)&dlsym_new_bytes[0], (void *)dlsym_original, (void *)&__replacement_dlsym); - - // Check if bytes overlap page border. - unsigned long start_of_page = PAGE_ALIGN((long)dlsym_original) - PAGE_SIZE; - unsigned long size_of_pages = 0; - - if ((unsigned long)dlsym_original + BYTES_SIZE > PAGE_ALIGN((unsigned long)dlsym_original)) - { - // bytes are located on two pages - size_of_pages = PAGE_SIZE*2; - } - else - { - // bytes are located entirely on one page. - size_of_pages = PAGE_SIZE; - } - - // Remove PROT_READ restriction - if (mprotect((void*)start_of_page, size_of_pages, PROT_READ|PROT_WRITE|PROT_EXEC)) - { - META_ERROR("Couldn't initialize dynamic linkents, mprotect failed: %i. Exiting...", errno); - return 0; - } - - // Write our own jmp-forwarder on "dlsym" - reset_dlsym_hook(); - - // done - return 1; -} diff --git a/metamod/src/osdep_linkent_win32.cpp b/metamod/src/osdep_linkent_win32.cpp deleted file mode 100644 index 8b93d14..0000000 --- a/metamod/src/osdep_linkent_win32.cpp +++ /dev/null @@ -1,191 +0,0 @@ -#include "precompiled.h" - -// Reads metamod.dll and game.dll function export tables and combines theim to -// single table that replaces metamod.dll's original table. -typedef struct sort_names_s { - unsigned long name; - unsigned short nameOrdinal; -} sort_names_t; - -#define rva_to_va(base, rva) ((unsigned long)base + (unsigned long)rva) // relative virtual address to virtual address -#define va_to_rva(base, va) ((unsigned long)va - (unsigned long)base) // virtual address to relative virtual address - -// Checks module signatures and return ntheaders pointer for valid module -IMAGE_NT_HEADERS *get_ntheaders(HMODULE module) -{ - union { - unsigned long mem; - IMAGE_DOS_HEADER *dos; - IMAGE_NT_HEADERS *pe; - } mem; - - // Check if valid dos header - mem.mem = (unsigned long)module; - if (IsBadReadPtr(mem.dos, sizeof(*mem.dos)) || mem.dos->e_magic != IMAGE_DOS_SIGNATURE) - return nullptr; - - // Get and check pe header - mem.mem = rva_to_va(module, mem.dos->e_lfanew); - if (IsBadReadPtr(mem.pe, sizeof(*mem.pe)) || mem.pe->Signature != IMAGE_NT_SIGNATURE) - return nullptr; - - return mem.pe; -} - -// Returns export table for valid module -IMAGE_EXPORT_DIRECTORY *get_export_table(HMODULE module) -{ - union { - unsigned long mem; - void *pvoid; - IMAGE_DOS_HEADER *dos; - IMAGE_NT_HEADERS *pe; - IMAGE_EXPORT_DIRECTORY *export_dir; - } mem; - - // check module - mem.pe = get_ntheaders(module); - if (!mem.pe) - return nullptr; - - // check for exports - if (!mem.pe->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress) - return nullptr; - - mem.mem = rva_to_va(module, mem.pe->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress); - if (IsBadReadPtr(mem.export_dir, sizeof(*mem.export_dir))) - return nullptr; - - return mem.export_dir; -} - -// Sort function for qsort -int sort_names_list(const sort_names_t *A, const sort_names_t *B) -{ - const char *str_A = (const char *)A->name; - const char *str_B = (const char *)B->name; - - return Q_strcmp(str_A, str_B); -} - -// Combines moduleMM and moduleGame export tables and replaces moduleMM table with new one -int combine_module_export_tables(HMODULE moduleMM, HMODULE moduleGame) -{ - IMAGE_EXPORT_DIRECTORY *exportMM; - IMAGE_EXPORT_DIRECTORY *exportGame; - - unsigned long newNumberOfFunctions; - unsigned long newNumberOfNames; - unsigned long *newFunctions; - unsigned long *newNames; - unsigned short *newNameOrdinals; - sort_names_t *newSort; - - unsigned long i; - unsigned long u; - unsigned long funcCount; - unsigned long nameCount; - unsigned long listFix; - - // get export tables - exportMM = get_export_table(moduleMM); - exportGame = get_export_table(moduleGame); - if (!exportMM || !exportGame) - { - META_ERROR("Couldn't initialize dynamic linkents, exportMM: %i, exportGame: %i. Exiting...", exportMM, exportGame); - return 0; - } - - // setup new export table - newNumberOfFunctions = exportMM->NumberOfFunctions + exportGame->NumberOfFunctions; - newNumberOfNames = exportMM->NumberOfNames + exportGame->NumberOfNames; - - // alloc lists - *(void**)&newFunctions = calloc(1, newNumberOfFunctions * sizeof(*newFunctions)); - *(void**)&newSort = calloc(1, newNumberOfNames * sizeof(*newSort)); - - // copy moduleMM to new export - for (funcCount = 0; funcCount < exportMM->NumberOfFunctions; funcCount++) - newFunctions[funcCount] = rva_to_va(moduleMM, ((unsigned long*)rva_to_va(moduleMM, exportMM->AddressOfFunctions))[funcCount]); - for (nameCount = 0; nameCount < exportMM->NumberOfNames; nameCount++) - { - //fix name address - newSort[nameCount].name = rva_to_va(moduleMM, ((unsigned long*)rva_to_va(moduleMM, exportMM->AddressOfNames))[nameCount]); - //ordinal is index to function list - newSort[nameCount].nameOrdinal = ((unsigned short *)rva_to_va(moduleMM, exportMM->AddressOfNameOrdinals))[nameCount]; - } - - // copy moduleGame to new export - for (i = 0; i < exportGame->NumberOfFunctions; i++) - newFunctions[funcCount + i] = rva_to_va(moduleGame, ((unsigned long*)rva_to_va(moduleGame, exportGame->AddressOfFunctions))[i]); - for (i = 0, listFix = 0; i < exportGame->NumberOfNames; i++) - { - const char *name = (const char *)rva_to_va(moduleGame, ((unsigned long*)rva_to_va(moduleGame, exportGame->AddressOfNames))[i]); - // check if name already in the list - for (u = 0; u < nameCount; u++) - { - if (!strcasecmp(name, (const char*)newSort[u].name)) - { - listFix -= 1; - break; - } - } - - // already in the list.. skip - if (u < nameCount) - continue; - - newSort[nameCount + i + listFix].name = (unsigned long)name; - newSort[nameCount + i + listFix].nameOrdinal = (unsigned short)funcCount + ((unsigned short *)rva_to_va(moduleGame, exportGame->AddressOfNameOrdinals))[i]; - } - - // set new number - newNumberOfNames = nameCount + i + listFix; - - // sort names list - qsort(newSort, newNumberOfNames, sizeof(*newSort), (int(*)(const void*, const void*))&sort_names_list); - - // make newNames and newNameOrdinals lists (VirtualAlloc so we dont waste heap memory to stuff that isn't freed) - *(void**)&newNames = VirtualAlloc(0, newNumberOfNames * sizeof(*newNames), MEM_COMMIT, PAGE_READWRITE); - *(void**)&newNameOrdinals = VirtualAlloc(0, newNumberOfNames * sizeof(*newNameOrdinals), MEM_COMMIT, PAGE_READWRITE); - - for (i = 0; i < newNumberOfNames; i++) - { - newNames[i] = newSort[i].name; - newNameOrdinals[i] = newSort[i].nameOrdinal; - } - - free(newSort); - - //translate VAs to RVAs - for (i = 0; i < newNumberOfFunctions; i++) - newFunctions[i] = va_to_rva(moduleMM, newFunctions[i]); - - for (i = 0; i < newNumberOfNames; i++) - { - newNames[i] = va_to_rva(moduleMM, newNames[i]); - newNameOrdinals[i] = (unsigned short)va_to_rva(moduleMM, newNameOrdinals[i]); - } - - DWORD OldProtect; - if (!VirtualProtect(exportMM, sizeof(*exportMM), PAGE_READWRITE, &OldProtect)) - { - META_ERROR("Couldn't initialize dynamic linkents, VirtualProtect failed: %i. Exiting...", GetLastError()); - return 0; - } - - exportMM->Base = 1; - exportMM->NumberOfFunctions = newNumberOfFunctions; - exportMM->NumberOfNames = newNumberOfNames; - *(unsigned long*)&(exportMM->AddressOfFunctions) = va_to_rva(moduleMM, newFunctions); - *(unsigned long*)&(exportMM->AddressOfNames) = va_to_rva(moduleMM, newNames); - *(unsigned long*)&(exportMM->AddressOfNameOrdinals) = va_to_rva(moduleMM, newNameOrdinals); - - VirtualProtect(exportMM, sizeof(*exportMM), OldProtect, &OldProtect); - return 1; -} - -int init_linkent_replacement(DLHANDLE moduleMetamod, DLHANDLE moduleGame) -{ - return combine_module_export_tables(moduleMetamod, moduleGame); -} diff --git a/metamod/src/osdep_p.cpp b/metamod/src/osdep_p.cpp deleted file mode 100644 index 47962cd..0000000 --- a/metamod/src/osdep_p.cpp +++ /dev/null @@ -1,84 +0,0 @@ -#include "precompiled.h" - -#ifdef _WIN32 -// MSVC doesn't provide "dirent.h" header. These functions wrap opendir/readdir/closedir -// functions to FindFirst/FindNext/FindClose win32api-functions. -DIR *my_opendir(const char *path) -{ - char search_path[MAX_PATH]; - DIR *dir; - - // Add wildcards to path - safevoid_snprintf(search_path, sizeof(search_path), "%s\\*.*", path); - - // Get memory for new DIR object - dir = (DIR *)calloc(1, sizeof(DIR)); - - // Start searching - dir->handle = FindFirstFileA(search_path, &dir->find_data); - if (dir->handle == INVALID_HANDLE_VALUE) - { - free(dir); - return nullptr; - } - - // Found file - dir->not_found = 0; - return dir; -} - -struct dirent *my_readdir(DIR *dir) -{ - // If not found stop - if (!dir || dir->not_found) - return nullptr; - - // Set filename - Q_strncpy(dir->ent.d_name, dir->find_data.cFileName, sizeof(dir->ent.d_name) - 1); - dir->ent.d_name[sizeof(dir->ent.d_name) - 1] = '\0'; - - // Search next - dir->not_found = !FindNextFileA(dir->handle, &dir->find_data); - return &dir->ent; -} - -void my_closedir(DIR *dir) -{ - if (!dir) - return; - - FindClose(dir->handle); - free(dir); -} - -#endif // _WIN32 - -// get module handle of memptr -#ifdef _WIN32 -DLHANDLE get_module_handle_of_memptr(void *memptr) -{ - MEMORY_BASIC_INFORMATION MBI; - - if (!VirtualQuery(memptr, &MBI, sizeof(MBI))) - return nullptr; - - if (MBI.State != MEM_COMMIT) - return nullptr; - - if (!MBI.AllocationBase) - return nullptr; - - return (DLHANDLE)MBI.AllocationBase; -} -#else -DLHANDLE get_module_handle_of_memptr(void *memptr) -{ - Dl_info dli; - Q_memset(&dli, 0, sizeof(dli)); - - if (dladdr(memptr, &dli)) - return dlopen(dli.dli_fname, RTLD_NOW); - else - return (void*)0; -} -#endif diff --git a/metamod/src/osdep_p.h b/metamod/src/osdep_p.h deleted file mode 100644 index 06ad417..0000000 --- a/metamod/src/osdep_p.h +++ /dev/null @@ -1,33 +0,0 @@ -#pragma once - -#include "types_meta.h" // mBOOL -#include "osdep.h" // PATH_MAX - -// Checks if file is hlsdk api game dll (osdep_detect_gamedll_linux.cpp and osdep_detect_gamedll_win32.cpp) -mBOOL is_gamedll(const char *filename); - -// MSVC doesn't provide opendir/readdir/closedir, so we write our own. -#ifdef _WIN32 - struct my_dirent { - char d_name[PATH_MAX]; - }; - typedef struct { - HANDLE handle; - WIN32_FIND_DATAA find_data; - struct my_dirent ent; - int not_found; - } my_DIR; - - #define dirent my_dirent - #define DIR my_DIR - - DIR *my_opendir(const char *); - struct dirent *my_readdir(DIR *); - void my_closedir(DIR *); - - #define opendir(x) my_opendir(x) - #define readdir(x) my_readdir(x) - #define closedir(x) my_closedir(x) -#endif // _WIN32 - -DLHANDLE get_module_handle_of_memptr(void *memptr); diff --git a/metamod/src/plinfo.h b/metamod/src/plinfo.h index 048de10..6ac55cb 100644 --- a/metamod/src/plinfo.h +++ b/metamod/src/plinfo.h @@ -1,50 +1,82 @@ -#pragma once +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// plinfo.h - typedefs for plugin info structure + +/* + * Copyright (c) 2001-2003 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game g_engine ("HL + * g_engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL g_engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + +#ifndef PLINFO_H +#define PLINFO_H // Flags for plugin to indicate when it can be be loaded/unloaded. // NOTE: order is crucial, as greater/less comparisons are made. -enum PLUG_LOADTIME -{ +typedef enum { PT_NEVER = 0, - PT_STARTUP, // should only be loaded/unloaded at initial hlds execution + PT_STARTUP, // should only be loaded/unloaded at initial hlds execution PT_CHANGELEVEL, // can be loaded/unloaded between maps - PT_ANYTIME, // can be loaded/unloaded at any time + PT_ANYTIME, // can be loaded/unloaded at any time PT_ANYPAUSE, // can be loaded/unloaded at any time, and can be "paused" during a map -}; +} PLUG_LOADTIME; // Flags to indicate why the plugin is being unloaded. -enum PL_UNLOAD_REASON -{ +typedef enum { PNL_NULL = 0, PNL_INI_DELETED, // was deleted from plugins.ini PNL_FILE_NEWER, // file on disk is newer than last load PNL_COMMAND, // requested by server/console command PNL_CMD_FORCED, // forced by server/console command PNL_DELAYED, // delayed from previous request; can't tell origin - - // only used for 'real_reason' on MPlugin::unload() - PNL_PLUGIN, // requested by plugin function call +//only used for 'real_reason' on MPlugin::unload() + PNL_PLUGIN, // requested by plugin function call PNL_PLG_FORCED, // forced by plugin function call - - // only used internally for 'meta reload' - PNL_RELOAD, // forced unload by reload() -}; + PNL_RELOAD, // forced unload by reload() +} PL_UNLOAD_REASON; // Information plugin provides about itself. -struct plugin_info_t -{ - char *ifvers; // meta_interface version - char *name; // full name of plugin - char *version; // version - char *date; // date - char *author; // author name/email - char *url; // URL - char *logtag; // log message prefix (unused right now) - PLUG_LOADTIME loadable; // when loadable - PLUG_LOADTIME unloadable; // when unloadable -}; - +typedef struct { + const char *ifvers; // meta_interface version + const char *name; // full name of plugin + const char *version; // version + const char *date; // date + const char *author; // author name/email + const char *url; // URL + const char *logtag; // log message prefix (unused right now) + PLUG_LOADTIME loadable; // when loadable + PLUG_LOADTIME unloadable; // when unloadable +} plugin_info_t; extern plugin_info_t Plugin_info; // Plugin identifier, passed to all Meta Utility Functions. -typedef plugin_info_t *plid_t; -#define PLID &Plugin_info +typedef plugin_info_t* plid_t; +#define PLID &Plugin_info + +#endif /* PLINFO_H */ diff --git a/metamod/src/precompiled.h b/metamod/src/precompiled.h index 0cdfb7d..3ba44cc 100644 --- a/metamod/src/precompiled.h +++ b/metamod/src/precompiled.h @@ -1,59 +1,61 @@ #pragma once -#include "version/appversion.h" +#if defined(linux) || defined(__APPLE__) +// enable extra routines in system header files, like dladdr +# ifndef _GNU_SOURCE +# define _GNU_SOURCE +# endif +#include // dlopen, dladdr, etc +#include // sigaction, etc +#include // sigsetjmp, longjmp, etc +#endif /* linux */ -#include -#include +#if defined(_MSC_VER) && (_MSC_VER < 1300) +# include // set_new_handler() +#else +# include // set_new_handler() +#endif + +#include +#include +#include + +#include #include -#include // for strncpy(), etc +#include +#include +#include +#include #include -#include +#include +#include -#include "osconfig.h" -#include "h_export.h" - -#include "osdep.h" // win32 vsnprintf, etc -#include "sdk_util.h" - -#include "eiface.h" // engfuncs_t, globalvars_t -#include "meta_api.h" // meta_globals_t, etc - -#include "linkent.h" // LINK_ENTITY_TO_PLUGIN - -#include "ret_type.h" -#include "types_meta.h" +#include "osdep.h" #include "api_info.h" -#include "api_hook.h" -#include "mplugin.h" +#include "commands_meta.h" #include "metamod.h" - -#include "commands_meta.h" // me -#include "log_meta.h" // META_CONS, etc - -#include "conf_meta.h" // me -#include "support_meta.h" // strmatch - - -// #include // alloca, etc ?????????? - - - // Don't include winspool.h; clashes with SERVER_EXECUTE from engine -// #define _WINSPOOL_H -// #include -// #include // Header structures - - -#include "osdep_p.h" // is_gamedll, ... -#include "game_support.h" // lookup_game, etc -#include "reg_support.h" // meta_AddServerCommand, etc -#include "mm_pextensions.h" - - - - - - - - - +#include "log_meta.h" +#include "info_name.h" +#include "vdate.h" +#include "vers_meta.h" +#include "conf_meta.h" +#include "support_meta.h" +#include "dllapi.h" +#include "engine_api.h" +#include "game_support.h" +#include "h_export.h" +#include "linkent.h" +#include "meta_eiface.h" +#include "mreg.h" +#include "meta_api.h" +#include "mutil.h" +#include "reg_support.h" +#include "types_meta.h" +#include "mlist.h" +#include "mplugin.h" +#include "plinfo.h" +#include "mplayer.h" +#include "sdk_util.h" +#include "enginecallbacks.h" +#include "utils.h" diff --git a/metamod/src/reg_support.cpp b/metamod/src/reg_support.cpp index 1bce99f..0ec20d6 100644 --- a/metamod/src/reg_support.cpp +++ b/metamod/src/reg_support.cpp @@ -1,5 +1,49 @@ +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// reg_support.cpp - support for things "registered" by plugins (console +// cmds, cvars, msgs, etc) + +/* + * Copyright (c) 2001-2003 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game g_engine ("HL + * g_engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL g_engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + #include "precompiled.h" +#ifdef linux +// enable extra routines in system header files, like strsignal +# ifndef _GNU_SOURCE +# define _GNU_SOURCE +# endif +#endif /* linux */ + // "Register" support. // // This code is necessary to support the different "register" engine @@ -35,32 +79,34 @@ // from the console that they no longer have an effect. // // Also note, the console commands for listing registered cmds and cvars -// will try to show the name of the associated plugin. +// will try to show the name of the associated plugin. However, this only +// works under linux; under windows it will say "(unknown)". Linux +// provides a routine "dladdr()" which can indicate (during Reg request) +// which plugin it's coming from, and this is stored with the cvar entry. +// Windows didn't seem to have a similar routine, and I couldn't find +// another way to get the information.. // Generic command handler, passed to the engine for any AddServerCommand // calls made by the plugin. It finds the appropriate plugin function // pointer to call based on CMD_ARGV(0). -void meta_command_handler() +void meta_command_handler(void) { - MRegCmd *icmd; - const char *cmd; + MRegCmd* icmd; + const char* cmd; META_DEBUG(5, ("called: meta_command_handler; arg0=%s args='%s'", CMD_ARGV(0), CMD_ARGS())); cmd = CMD_ARGV(0); - if (!cmd) - { - META_WARNING("Null command name in meta_command_handler() ??"); + if (!cmd) { + META_ERROR("Null command name in meta_command_handler() ??"); return; } - icmd = RegCmds->find(cmd); - if (!icmd) - { - META_WARNING("Couldn't find registered plugin command: %s", cmd); + icmd = g_regCmds->find(cmd); + if (!icmd) { + META_ERROR("Couldn't find registered plugin command: %s", cmd); return; } - if (icmd->call() != mTRUE) META_CONS("[metamod: command '%s' unavailable; plugin unloaded]", cmd); } @@ -72,28 +118,28 @@ void meta_command_handler() // engine a command string and function pointer allocated locally (in the // metamod DLL). // -// The string handed to the engine is just a strdup() of the plugin's +// The string handed to the engine is just a _strdup() of the plugin's // string. The function pointer handed to the engine is actually a pointer // to a generic command-handler function (see above). -void meta_AddServerCommand(char *cmd_name, void (*function)()) +void meta_AddServerCommand(char* cmd_name, void (*function)(void)) { - MPlugin *iplug=NULL; - MRegCmd *icmd=NULL; + MPlugin* iplug = NULL; + MRegCmd* icmd = NULL; META_DEBUG(4, ("called: meta_AddServerCommand; cmd_name=%s, function=%d", cmd_name, function)); // try to find which plugin is registering this command - if (!(iplug=Plugins->find_memloc((void *)function))) { + if (!(iplug = g_plugins->find_memloc((void *)function))) { // if this isn't supported on this OS, don't log an error if (meta_errno != ME_OSNOTSUP) - META_WARNING("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. - icmd=RegCmds->find(cmd_name); + icmd = g_regCmds->find(cmd_name); if (!icmd) { // If not found, add. - icmd=RegCmds->add(cmd_name); + icmd = g_regCmds->add(cmd_name); if (!icmd) { // error details logged in add() return; @@ -102,8 +148,8 @@ void meta_AddServerCommand(char *cmd_name, void (*function)()) REG_SVR_COMMAND(icmd->name, meta_command_handler); } - icmd->pfnCmd=function; - icmd->status=RG_VALID; + icmd->pfnCmd = function; + icmd->status = RG_VALID; // Store which plugin this is for, if we know. We can use '0' for // unknown plugin, since plugin index starts at 1. if (iplug) @@ -119,44 +165,39 @@ void meta_AddServerCommand(char *cmd_name, void (*function)()) // locally (in the metamod DLL). // // The cvar handed to the engine is globally allocated in the metamod.dll; -// the "name" and "string" fields are strdup()'s of the plugin's strings. +// the "name" and "string" fields are _strdup()'s of the plugin's strings. // Note that, once this is done, the cvar_t allocated in the plugin is no // longer used for _anything_. As long as everything sets/gets the cvar // values via the engine functions, this will work fine. If the plugin // code tries to _directly_ read/set the fields of its own cvar structures, // it will fail to work properly. -void meta_CVarRegister(cvar_t *pCvar) +void meta_CVarRegister(cvar_t* pCvar) { - MPlugin *iplug = nullptr; - MRegCvar *icvar = nullptr; + MPlugin* iplug = NULL; + MRegCvar* icvar = NULL; META_DEBUG(4, ("called: meta_CVarRegister; name=%s", pCvar->name)); // try to find which plugin is registering this cvar - if (!(iplug = Plugins->find_memloc((void *)pCvar))) - { + if (!(iplug = g_plugins->find_memloc((void *)pCvar))) { // if this isn't supported on this OS, don't log an error if (meta_errno != ME_OSNOTSUP) - { - // Note: if cvar_t was malloc'd by the plugin, we can't - // determine the calling plugin. Thus, this becomes a Debug - // rather than Error message. - META_DEBUG(1, ("Failed to find memloc for regcvar '%s'", pCvar->name)); - } + // Note: if cvar_t was malloc'd by the plugin, we can't + // determine the calling plugin. Thus, this becomes a Debug + // rather than Error message. + META_DEBUG(1, ("Failed to find memloc for regcvar '%s'", + pCvar->name)); } // See if this cvar was previously registered, ie a "reloaded" plugin. - icvar = RegCvars->find(pCvar->name); - if (!icvar) - { + icvar = g_regCvars->find(pCvar->name); + if (!icvar) { // If not found, add. - icvar = RegCvars->add(pCvar->name); - if (!icvar) - { + icvar = g_regCvars->add(pCvar->name); + if (!icvar) { // error details logged in add() return; } - // Reset to given value icvar->set(pCvar); CVAR_REGISTER(icvar->data); @@ -165,7 +206,6 @@ void meta_CVarRegister(cvar_t *pCvar) // 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) @@ -174,14 +214,34 @@ void meta_CVarRegister(cvar_t *pCvar) icvar->plugid = 0; } -// Replacement for engine routine RegUserMsg; called by plugins. -int meta_RegUserMsg(const char *pszName, int iSize) { - return REG_USER_MSG(strdup(pszName), iSize); + +// Replacement for engine routine RegUserMsg; called by plugins. Rather +// than handing the engine the plugin's string (which is allocated in the +// plugin DLL), this hands the engine a string allocated from the stack. +// +// Note that while the above two functions maintain a list of registered +// strings/funcs/cvars from the plugins, this is not done here as I +// couldn't identify a need for it. Since the engine function merely maps +// a string to an int (msgid) for subsequent use in MessageBegin/etc, +// there's no function that needs to be provided and caught (like the +// commands) nor any useful actions to perform upon plugin unload (like the +// commands and cvars). This merely provides differently located storage +// for the string. + +int meta_RegUserMsg(const char* pszName, int iSize) +{ + char* cp; + + cp = _strdup(pszName); + return (REG_USER_MSG(cp, iSize)); } // Intercept and record queries -void meta_QueryClientCvarValue(const edict_t *player, const char *cvarName) +void meta_QueryClientCvarValue(const edict_t* player, const char* cvarName) { g_Players.set_player_cvar_query(player, cvarName); + (*g_engfuncs.pfnQueryClientCvarValue)(player, cvarName); } + + diff --git a/metamod/src/reg_support.h b/metamod/src/reg_support.h index 317ae1f..0c50f38 100644 --- a/metamod/src/reg_support.h +++ b/metamod/src/reg_support.h @@ -1,10 +1,48 @@ -#pragma once +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// reg_support.h - functions for "registered" cmd/cvar/msg support + +/* + * Copyright (c) 2001-2003 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game g_engine ("HL + * g_engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL g_engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + +#ifndef REG_SUPPORT_H +#define REG_SUPPORT_H #include "mreg.h" // REG_CMD_FN, etc -// these are only 'hidden' because called from outside (plugins and engine) -void meta_command_handler(); +void meta_command_handler(void); void meta_AddServerCommand(char *cmd_name, REG_CMD_FN function); void meta_CVarRegister(cvar_t *pCvar); int meta_RegUserMsg(const char *pszName, int iSize); void meta_QueryClientCvarValue(const edict_t *player, const char *cvarName); + +#endif /* REG_SUPPORT_H */ diff --git a/metamod/src/ret_type.h b/metamod/src/ret_type.h deleted file mode 100644 index aca85f2..0000000 --- a/metamod/src/ret_type.h +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once - -#include "new_baseclass.h" - -class class_ret_t: public class_metamod_new { -public: - // Construction - inline class_ret_t() { }; - inline class_ret_t(float f) { data.f = f; }; - inline class_ret_t(void * p) { data.p = p; }; - inline class_ret_t(const char * pc) { data.pc = pc; }; - inline class_ret_t(int i) { data.i = i; }; - inline class_ret_t(short s) { data.i = s; }; - inline class_ret_t(char c) { data.i = c; }; - inline class_ret_t(unsigned int ui) { data.ui = ui; }; - inline class_ret_t(unsigned long ui) { data.ui = ui; }; - inline class_ret_t(unsigned short us) { data.ui = us; }; - inline class_ret_t(unsigned char uc) { data.ui = uc; }; - - // Reading/Writing - inline void *getptr() { return &data; }; - - #define SET_RET_CLASS(ret,type,x) \ - *(type*)((ret).getptr()) = (type)(x) - #define GET_RET_CLASS(ret,type) \ - (*(type*)((ret).getptr())) -private: - // Data (select data size of largest type) (x86: 32bit, x86_64: 64bit) - union - { - void *p; - const char *pc; - float f; - long i; - unsigned long ui; - } data; -}; diff --git a/metamod/src/sdk_util.cpp b/metamod/src/sdk_util.cpp index 4582d1d..6eec14e 100644 --- a/metamod/src/sdk_util.cpp +++ b/metamod/src/sdk_util.cpp @@ -1,77 +1,63 @@ +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// sdk_util.cpp - utility routines from HL SDK util.cpp + +// Selected portions of dlls/util.cpp from SDK 2.1. +// Functions copied from there as needed... +// And modified to avoid buffer overflows (argh). +// Also modified to remove dependency on CBaseEntity class. + +/*** +* +* Copyright (c) 1999, 2000 Valve LLC. All rights reserved. +* +* This product contains software technology licensed from Id +* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. +* All Rights Reserved. +* +* Use, distribution, and modification of this source code and/or resulting +* object code is restricted to non-commercial enhancements to products from +* Valve LLC. All other use, distribution, or modification is prohibited +* without written permission from Valve LLC. +* +****/ +/* + +===== util.cpp ======================================================== + + Utility code. Really not optional after all. + +*/ + #include "precompiled.h" -const char *META_UTIL_VarArgs(const char *format, ...) +char* UTIL_VarArgs(char *format, ...) { - va_list argptr; - static char string[4096]; + va_list argptr; + static char string[1024]; va_start(argptr, format); - safevoid_vsnprintf(string, sizeof(string), format, argptr); + vsnprintf(string, sizeof(string), format, argptr); va_end(argptr); return string; } -short FixedSigned16(float value, float scale) + +//========================================================= +// UTIL_LogPrintf - Prints a logged message to console. +// Preceded by LOG: ( timestamp ) < message > +//========================================================= +void UTIL_LogPrintf(char *fmt, ...) { - int output = (int)(value * scale); - if (output > 32767) - output = 32767; + va_list argptr; + static char string[1024]; - if (output < -32768) - output = -32768; + va_start(argptr, fmt); + vsnprintf(string, sizeof(string), fmt, argptr); + va_end(argptr); - return (short)output; -} - -unsigned short FixedUnsigned16(float value, float scale) -{ - int output = (int)(value * scale); - if (output < 0) - output = 0; - - if (output > 0xFFFF) - output = 0xFFFF; - - return (unsigned short)output; -} - -void META_UTIL_HudMessage(edict_t *pEntity, const hudtextparms_t &textparms, const char *pMessage) -{ - if (fast_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 (Q_strlen(pMessage) < 512) - { - WRITE_STRING(pMessage); - } else { - char tmp[512]; - Q_strncpy(tmp, pMessage, 511); - tmp[511] = 0; - WRITE_STRING(tmp); - } - MESSAGE_END(); + // Print to server console + ALERT(at_logged, "%s", string); } diff --git a/metamod/src/sdk_util.h b/metamod/src/sdk_util.h index fd36813..b700bcf 100644 --- a/metamod/src/sdk_util.h +++ b/metamod/src/sdk_util.h @@ -1,4 +1,44 @@ -#pragma once +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// sdk_util.h - wrapper & extension of util.h from HL SDK + +/* + * Copyright (c) 2001-2003 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game g_engine ("HL + * g_engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL g_engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + +// Wrap util.h from SDK with ifndef/endif, to avoid problems from multiple +// inclusions. Dunno why Valve didn't do that in util.h themselves.. + +#ifndef SDK_UTIL_H +#define SDK_UTIL_H // We're not including the DBG_EntOfVars and DBG_AssertFunction routines // mentioned in the SDK util.h, so we're going to unset DEBUG here so that @@ -7,69 +47,13 @@ #undef DEBUG #endif /* DEBUG */ +// Inlcude local enginecallbacks wrapper *first* so that the g_engfuncs +// type is correct and the header protection is already +// defined. #include "enginecallbacks.h" + #include -// Also, create some additional macros for engine callback functions, which -// weren't in SDK dlls/enginecallbacks.h but probably should have been. -#define GET_INFOKEYBUFFER (*g_engfuncs.pfnGetInfoKeyBuffer) -#define INFOKEY_VALUE (*g_engfuncs.pfnInfoKeyValue) -#define SET_CLIENT_KEYVALUE (*g_engfuncs.pfnSetClientKeyValue) -#define REG_SVR_COMMAND (*g_engfuncs.pfnAddServerCommand) -#define SERVER_PRINT (*g_engfuncs.pfnServerPrint) -#define SET_SERVER_KEYVALUE (*g_engfuncs.pfnSetKeyValue) -#define QUERY_CLIENT_CVAR_VALUE (*g_engfuncs.pfnQueryClientCvarValue) -#define QUERY_CLIENT_CVAR_VALUE2 (*g_engfuncs.pfnQueryClientCvarValue2) -// Also, create some nice inlines for engine callback combos. - -// Get a setinfo value from a player entity. -inline char *ENTITY_KEYVALUE(edict_t *entity, char *key) -{ - return INFOKEY_VALUE(GET_INFOKEYBUFFER(entity), key); -} - -// Set a setinfo value for a player entity. -inline void ENTITY_SET_KEYVALUE(edict_t *entity, char *key, char *value) -{ - SET_CLIENT_KEYVALUE(ENTINDEX(entity), GET_INFOKEYBUFFER(entity), key, value); -} - -// Get a "serverinfo" value. -inline char *SERVERINFO(char *key) -{ - return ENTITY_KEYVALUE(INDEXENT(0), key); -} - -// Set a "serverinfo" value. -inline void SET_SERVERINFO(char *key, char *value) -{ - SET_SERVER_KEYVALUE(GET_INFOKEYBUFFER(INDEXENT(0)), key, value); -} - -// Get a "localinfo" value. -inline char *LOCALINFO(char *key) -{ - return ENTITY_KEYVALUE(NULL, key); -} - -// Set a "localinfo" value. -inline void SET_LOCALINFO(char *key, char *value) -{ - SET_SERVER_KEYVALUE(GET_INFOKEYBUFFER(NULL), key, value); -} - -inline int fast_FNullEnt(const edict_t* pent) -{ - return !pent || !(*g_engfuncs.pfnEntOffsetOfPEntity)(pent); -} - -// Our slightly modified version, using an edict_t pointer instead of a -// CBaseEntity pointer. (was in 1.17p1, included in 1.17.1) -void META_UTIL_HudMessage(edict_t *pEntity, const hudtextparms_t &textparms, const char *pMessage); - -const char *META_UTIL_VarArgs(const char *format, ...); - -short FixedSigned16(float value, float scale); -unsigned short FixedUnsigned16(float value, float scale); +#endif /* SDK_UTIL_H */ diff --git a/metamod/src/studioapi.cpp b/metamod/src/studioapi.cpp new file mode 100644 index 0000000..42f169f --- /dev/null +++ b/metamod/src/studioapi.cpp @@ -0,0 +1,92 @@ +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// studio.cpp - player model blending interfaces + +/* + * Copyright (c) 2001-2003 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game g_engine ("HL + * g_engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL g_engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + +#include "precompiled.h" + +// Another GET-API routine, another interface version. +// +// Added 5/2003 based on information from Leon Hartwig and Alfred Reynolds, +// in order to address observed problems with hitboxes not matching between +// client and server, in CS and DOD. +// +// Based around code apparently added to the g_engine around 1/2002, +// seemingly to address "the old CS hitbox problem", where "the client was +// doing custom player model blending and the server had no idea what was +// going on". +// +// http://www.mail-archive.com/hlcoders@list.valvesoftware.com/msg01224.html +// http://www.mail-archive.com/hlcoders@list.valvesoftware.com/msg02724.html + +C_DLLEXPORT int Server_GetBlendingInterface(int version, + struct sv_blending_interface_s **ppinterface, + struct engine_studio_api_s *pstudio, + float (*rotationmatrix)[3][4], + float (*bonetransform)[MAXSTUDIOBONES][3][4]) +{ + static GETBLENDAPI_FN getblend=NULL; + static int missing=0; + + // Note that we're not checking if + // (version==SV_BLENDING_INTERFACE_VERSION) because at this point, we + // don't really care, as we're not looking at or using the contents of + // the function tables; we're only passing them through to the gamedll, + // which presumably will check for version match, since it's the one + // that cares and actually uses the function tables. + // + // Return(0) if the gamedll does not provide this routine, and the + // g_engine will use its own builtin blending. The g_engine will report + // "Couldn't get server .dll studio model blending interface. Version + // mismatch?", but this will only show in "developer" (-dev) mode. + + META_DEBUG(6, ("called: Server_GetBlendingInterface; version=%d", version)); + if(missing) { + META_DEBUG(6, ("Skipping Server_GetBlendingInterface; was previously found missing")); + return(0); + } + if(!getblend) { + META_DEBUG(6, ("Looking up Server_GetBlendingInterface")); + getblend = (GETBLENDAPI_FN) DLSYM(GameDLL.handle, + "Server_GetBlendingInterface"); + } + if(!getblend) { + META_DEBUG(6, ("Couldn't find Server_GetBlendingInterface in game DLL '%s': %s", GameDLL.name, DLERROR())); + missing=1; + return(0); + } + META_DEBUG(6, ("Calling Server_GetBlendingInterface")); + return((getblend)(version, ppinterface, pstudio, rotationmatrix, + bonetransform)); +} diff --git a/metamod/src/studioapi.h b/metamod/src/studioapi.h new file mode 100644 index 0000000..eded726 --- /dev/null +++ b/metamod/src/studioapi.h @@ -0,0 +1,56 @@ +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// studio.cpp - player model blending interfaces + +/* + * Copyright (c) 2001-2003 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game g_engine ("HL + * g_engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL g_engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + +#ifndef STUDIOAPI_H +#define STUDIOAPI_H + +#include // MAXSTUDIOBONES + +// Typedef for Server_GetBlendingInterface() from Eric Smith on the hlcoders +// mailing list. +typedef int (*GETBLENDAPI_FN) (int version, + struct sv_blending_interface_s **ppinterface, + struct engine_studio_api_s *pstudio, + float (*rotationmatrix)[3][4], + float (*bonetransform)[MAXSTUDIOBONES][3][4]); + +extern int mm_Server_GetBlendingInterface(int version, + struct sv_blending_interface_s **ppinterface, + struct engine_studio_api_s *pstudio, + float (*rotationmatrix)[3][4], + float (*bonetransform)[MAXSTUDIOBONES][3][4]); + +#endif /* STUDIOAPI_H */ diff --git a/metamod/src/support_meta.cpp b/metamod/src/support_meta.cpp index f39ea2f..a7a3255 100644 --- a/metamod/src/support_meta.cpp +++ b/metamod/src/support_meta.cpp @@ -1,3 +1,39 @@ +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// support_meta.cpp - generic support routines + +/* + * Copyright (c) 2001-2003 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game g_engine ("HL + * g_engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL g_engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + #include "precompiled.h" META_ERRNO meta_errno; @@ -15,51 +51,47 @@ void do_exit(int exitval) // Also, formerly named just "valid_file". // // Special-case-recognize "/dev/null" as a valid file. -int valid_gamedir_file(const char *path) +int valid_gamedir_file(const char* path) { - char buf[PATH_MAX]; + char buf[PATH_MAX ]; struct stat st; int ret, reg, size; if (!path) - return FALSE; + return (FALSE); - if (!Q_strcmp(path, "/dev/null")) - return TRUE; + if (!strcmp(path, "/dev/null")) + return (TRUE); - if (is_absolute_path(path)) - { - Q_strncpy(buf, path, sizeof(buf) - 1); - buf[sizeof(buf) - 1] = '\0'; + if (is_absolute_path(path)) { + strncpy(buf, path, sizeof(buf)); + buf[sizeof buf - 1] = '\0'; } else - safevoid_snprintf(buf, sizeof(buf), "%s/%s", GameDLL.gamedir, path); + snprintf(buf, sizeof(buf), "%s/%s", GameDLL.gamedir, path); ret = stat(buf, &st); - if (ret != 0) - { + if (ret != 0) { META_DEBUG(5, ("Unable to stat '%s': %s", buf, strerror(errno))); - return FALSE; + return (FALSE); } reg = S_ISREG(st.st_mode); - if (!reg) - { + if (!reg) { META_DEBUG(5, ("Not a regular file: %s", buf)); - return FALSE; + return (FALSE); } size = st.st_size; - if (!size) - { + if (!size) { META_DEBUG(5, ("Empty file: %s", buf)); - return FALSE; + return (FALSE); } if (ret == 0 && reg && size) - return TRUE; + return (TRUE); else - return FALSE; + return (FALSE); } // Turns path into a full path: @@ -67,29 +99,26 @@ int valid_gamedir_file(const char *path) // - calls realpath() to collapse ".." and such // - calls normalize_pathname() to fix backslashes, etc // -// Much like realpath, buffer pointed to by fullpath is assumed to be +// Much like realpath, buffer pointed to by fullpath is assumed to be // able to store a string of PATH_MAX length. -char *full_gamedir_path(const char *path, char *fullpath) { - char buf[PATH_MAX]; +char* full_gamedir_path(const char* path, char* fullpath) +{ + char buf[PATH_MAX ]; // Build pathname from filename, plus gamedir if relative path. - if (is_absolute_path(path)) - { - Q_strncpy(buf, path, sizeof(buf) - 1); - buf[sizeof(buf) - 1] = '\0'; + if (is_absolute_path(path)) { + strncpy(buf, path, sizeof buf - 1); + buf[sizeof buf - 1] = '\0'; } else - safevoid_snprintf(buf, sizeof(buf), "%s/%s", GameDLL.gamedir, path); - + snprintf(buf, sizeof(buf), "%s/%s", GameDLL.gamedir, path); // Remove relative path components, if possible. - if (!realpath(buf, fullpath)) - { + if (!realpath(buf, fullpath)) { META_DEBUG(4, ("Unable to get realpath for '%s': %s", buf, str_os_error())); - - Q_strncpy(fullpath, path, sizeof(fullpath) - 1); - fullpath[sizeof(fullpath) - 1] = '\0'; + strncpy(fullpath, path, PATH_MAX - 1); + fullpath[PATH_MAX - 1] = '\0'; } // Replace backslashes, etc. normalize_pathname(fullpath); - return fullpath; + return (fullpath); } diff --git a/metamod/src/support_meta.h b/metamod/src/support_meta.h index 27e9196..25f264a 100644 --- a/metamod/src/support_meta.h +++ b/metamod/src/support_meta.h @@ -1,3 +1,39 @@ +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// support_meta.h - generic support macros + +/* + * Copyright (c) 2001-2003 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game g_engine ("HL + * g_engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL g_engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + #ifndef SUPPORT_META_H #define SUPPORT_META_H @@ -5,10 +41,9 @@ #include // stat #include // stat -#include "osdep.h" // strcasecmp, S_ISREG, -#include "enginecallbacks.h" // LOAD_FILE_FOR_ME, etc +#include "osdep.h" // _stricmp, S_ISREG, -void do_exit(int exitval); +void do_exit(int exitval) ATTRIBUTE(__noreturn__); // Unlike snprintf(), strncpy() doesn't necessarily null-terminate the // target. It appears the former function reasonably considers the given @@ -39,7 +74,47 @@ void do_exit(int exitval); // statements. // Technique 1: use "do..while": +#if 0 +#define STRNCPY(dst, src, size) \ + do { strcpy(dst, "\0"); strncat(dst, src, size-1); } while(0) +#endif +// Technique 2: use parens and commas: +#if 0 +#define STRNCPY(dst, src, size) \ + (strcpy(dst, "\0"), strncat(dst, src, size-1)) +#endif + +inline int strnmatch(const char *s1, const char *s2, size_t n) { + if(!s1 || !s2) + return(0); + else + return(!strncmp(s1, s2, n)); +} +inline int strcasematch(const char *s1, const char *s2) { + if(!s1 || !s2) + return(0); + else + return(!_stricmp(s1, s2)); +} +inline int strncasematch(const char *s1, const char *s2, size_t n) { + if(!s1 || !s2) + return(0); + else + return(!_strnicmp(s1, s2, n)); +} + +inline int old_valid_file(char *path) { + char *cp; + int len, ret; + cp = (char *) LOAD_FILE_FOR_ME(path, &len); + if(cp && len) + ret=1; + else + ret=0; + FREE_FILE(cp); + return(ret); +} int valid_gamedir_file(const char *path); char *full_gamedir_path(const char *path, char *fullpath); @@ -57,13 +132,4 @@ char *full_gamedir_path(const char *path, char *fullpath); // For various character string buffers. #define MAX_STRBUF_LEN 1024 - -// Smallest of two -#define MIN(x, y) (((x)<(y))?(x):(y)) - - -// Greatest of two -#define MAX(x, y) (((x)>(y))?(x):(y)) - - #endif /* SUPPORT_META_H */ diff --git a/metamod/src/types_meta.h b/metamod/src/types_meta.h index 1b874ce..98b5271 100644 --- a/metamod/src/types_meta.h +++ b/metamod/src/types_meta.h @@ -1,12 +1,51 @@ -#pragma once +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// types_meta.h - common internal type, etc definitions + +/* + * Copyright (c) 2001-2003 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game g_engine ("HL + * g_engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL g_engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + +#ifndef TYPES_META_H +#define TYPES_META_H // Our own boolean type, for stricter type matching. -enum mBOOL { mFALSE = 0, mTRUE, }; +typedef enum mBOOL { + mFALSE = 0, + mTRUE, +} mBOOL; // Like C's errno, for our various functions; describes causes of failure // or mFALSE returns. -enum META_ERRNO -{ +typedef enum { ME_NOERROR = 0, ME_FORMAT, // invalid format ME_COMMENT, // ignored comment @@ -31,12 +70,13 @@ enum META_ERRNO ME_IFVERSION, // incompatible interface version ME_UNLOAD_UNLOADER, // tried to unload unloader ME_UNLOAD_SELF, // tried to unload self -}; - +} META_ERRNO; extern META_ERRNO meta_errno; #define RETURN_ERRNO(retval, errval) \ - do { meta_errno=errval; return retval; } while (0) + do { meta_errno=errval; return(retval); } while(0) #define RETURN_LOGERR_ERRNO(errargs, retval, errval) \ - do { META_ERROR errargs ; meta_errno=errval; return retval; } while (0) + do { META_ERROR errargs ; meta_errno=errval; return(retval); } while(0) + +#endif /* TYPES_META_H */ diff --git a/metamod/src/utils.cpp b/metamod/src/utils.cpp new file mode 100644 index 0000000..bef460b --- /dev/null +++ b/metamod/src/utils.cpp @@ -0,0 +1,21 @@ +#include "precompiled.h" + +bool is_yes(const char* str) +{ + return !strcmp(str, "true") || !strcmp(str, "yes") || !strcmp(str, "1"); +} + +bool is_no(const char* str) +{ + return !strcmp(str, "false") || !strcmp(str, "no") || !strcmp(str, "0"); +} + +char* ENTITY_KEYVALUE(edict_t* entity, char* key) +{ + return (INFOKEY_VALUE(GET_INFOKEYBUFFER(entity), key)); +} + +const char* LOCALINFO(char* key) +{ + return (ENTITY_KEYVALUE(NULL, key)); +} diff --git a/metamod/src/utils.h b/metamod/src/utils.h new file mode 100644 index 0000000..97a2e46 --- /dev/null +++ b/metamod/src/utils.h @@ -0,0 +1,6 @@ +#pragma once + +bool is_yes(const char* str); +bool is_no(const char* str); + +const char* LOCALINFO(char* key); diff --git a/metamod/src/vdate.cpp b/metamod/src/vdate.cpp new file mode 100644 index 0000000..078fa45 --- /dev/null +++ b/metamod/src/vdate.cpp @@ -0,0 +1,56 @@ +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// vdate.cpp - compile-time version date + +/* + * Copyright (c) 2001-2003 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game g_engine ("HL + * g_engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL g_engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + +#include "precompiled.h" + +// Grab date/time of compile. The Makefile is set up to recompile this +// module before each link, so that this will always indicate the time the +// library was compiled and linked. + +// This is in a separate file from vers_*, so it can be generically used by +// multiple projects. + +char const *COMPILE_TIME=__DATE__ ", " __TIME__; + +#ifndef COMPILE_TZ +# define COMPILE_TZ "" +#endif + +char const *COMPILE_TZONE = COMPILE_TZ; + +// Include a string for /usr/bin/ident. + +char const *vstring="\n$Pg: " VNAME " -- " VVERSION " | " __DATE__ " - " __TIME__ " $\n"; diff --git a/metamod/src/vdate.h b/metamod/src/vdate.h new file mode 100644 index 0000000..b9f6e9f --- /dev/null +++ b/metamod/src/vdate.h @@ -0,0 +1,44 @@ +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// vdate.h - compile-time version date + +/* + * Copyright (c) 2001-2003 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game g_engine ("HL + * g_engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL g_engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + +#ifndef VDATE_H +#define VDATE_H + +extern char const *COMPILE_TIME; + +extern char const *COMPILE_TZONE; + +#endif /* VDATE_H */ diff --git a/metamod/src/vers_meta.h b/metamod/src/vers_meta.h new file mode 100644 index 0000000..d5baf14 --- /dev/null +++ b/metamod/src/vers_meta.h @@ -0,0 +1,55 @@ +// vi: set ts=4 sw=4 : +// vim: set tw=75 : + +// vers_meta.h - version info, intended to be common among DLLs distributed +// with metamod. + +/* + * Copyright (c) 2001-2013 Will Day + * + * This file is part of Metamod. + * + * Metamod is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * Metamod is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Metamod; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * In addition, as a special exception, the author gives permission to + * link the code of this program with the Half-Life Game g_engine ("HL + * g_engine") and Modified Game Libraries ("MODs") developed by Valve, + * L.L.C ("Valve"). You must obey the GNU General Public License in all + * respects for all of the code used other than the HL g_engine and MODs + * from Valve. If you modify this file, you may extend this exception + * to your version of the file, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + */ + +#ifndef VERS_META_H +#define VERS_META_H + +#ifndef OPT_TYPE +# if defined(_MSC_VER) && defined(_DEBUG) +# define OPT_TYPE "msc debugging" +# elif defined(_MSC_VER) && defined(NDEBUG) +# define OPT_TYPE "msc optimized" +# else +# define OPT_TYPE "default" +# endif /* _MSC_VER */ +#endif /* not OPT_TYPE */ + +#define VDATE "2013-09-26" +#define VVERSION "1.21.1-am" +#define RC_VERS_DWORD 1,21,1,0 // Version Windows DLL Resources in res_meta.rc + +#endif /* VERS_META_H */