2
0
mirror of https://github.com/rehlds/metamod-r.git synced 2025-02-04 17:50:52 +03:00

Changed source to static linking version

This commit is contained in:
asmodai 2016-07-26 15:18:32 +03:00
parent 1294178a8d
commit 05067b28b5
68 changed files with 12106 additions and 7945 deletions

View File

@ -12,20 +12,17 @@
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{02832A39-E902-46B7-8D47-911C37CF41B0}</ProjectGuid>
<RootNamespace>metamod</RootNamespace>
<Keyword>Win32Proj</Keyword>
<SccProjectName />
<SccLocalPath />
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v120_xp</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v120_xp</PlatformToolset>
<CharacterSet>NotSet</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
@ -38,239 +35,164 @@
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>12.0.30501.0</_ProjectFileVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>$(SolutionDir)$(Configuration)\</OutDir>
<IntDir>$(Configuration)\</IntDir>
<LinkIncremental>true</LinkIncremental>
<TargetName>$(ProjectName)_mm</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>$(SolutionDir)$(Configuration)\</OutDir>
<IntDir>$(Configuration)\</IntDir>
<LinkIncremental>false</LinkIncremental>
<TargetName>$(ProjectName)_mm</TargetName>
<_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>$(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)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;METAMOD_EXPORTS;_CRT_SECURE_NO_DEPRECATE;__METAMOD_BUILD__;__BUILD_FAST_METAMOD__;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<PreprocessorDefinitions>METAMOD_CORE;WIN32;_DEBUG;_WINDOWS;_USRDLL;METAMOD_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderOutputFile>.\debug/metamod.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\debug/asm/</AssemblerListingLocation>
<ObjectFileName>.\debug/obj/</ObjectFileName>
<ProgramDataBaseFileName>.\debug/inf/</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<TreatWarningAsError>true</TreatWarningAsError>
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<PrecompiledHeaderFile>precompiled.h</PrecompiledHeaderFile>
</ClCompile>
<Link>
<ModuleDefinitionFile>metamod.def</ModuleDefinitionFile>
<OutputFile>.\debug/metamod.dll</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<ModuleDefinitionFile>.\metamod.def</ModuleDefinitionFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<ProgramDatabaseFile>.\debug/inf/metamod.pdb</ProgramDatabaseFile>
<ImportLibrary>.\debug/metamod.lib</ImportLibrary>
<TargetMachine>MachineX86</TargetMachine>
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
</Link>
<PostBuildEvent>
<Command>IF EXIST "$(ProjectDir)PostBuild.bat" (CALL "$(ProjectDir)PostBuild.bat" "$(TargetDir)" "$(TargetName)" "$(TargetExt)" "$(ProjectDir)")</Command>
</PostBuildEvent>
<PostBuildEvent>
<Message>Automatic deployment script</Message>
</PostBuildEvent>
<PreBuildEvent>
<Command>IF EXIST "$(ProjectDir)PreBuild.bat" (CALL "$(ProjectDir)PreBuild.bat" "$(ProjectDir)..\version\" "$(ProjectDir)..\")</Command>
</PreBuildEvent>
<PreBuildEvent>
<Message>Setup version from Git revision</Message>
</PreBuildEvent>
<CustomBuildStep>
<Command>echo Empty Action</Command>
</CustomBuildStep>
<CustomBuildStep>
<Message>Force build to run Pre-Build event</Message>
</CustomBuildStep>
<Midl>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MkTypLibCompatible>true</MkTypLibCompatible>
<SuppressStartupBanner>true</SuppressStartupBanner>
<TargetEnvironment>Win32</TargetEnvironment>
<TypeLibraryName>.\debug/metamod.tlb</TypeLibraryName>
<HeaderFileName>
</HeaderFileName>
</Midl>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<AdditionalIncludeDirectories>$(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)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;METAMOD_EXPORTS;_CRT_SECURE_NO_DEPRECATE;__METAMOD_BUILD__;__BUILD_FAST_METAMOD__;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>METAMOD_CORE;WIN32;NDEBUG;_WINDOWS;_USRDLL;METAMOD_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderOutputFile>.\release/metamod.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\release/</AssemblerListingLocation>
<ObjectFileName>.\release/obj/</ObjectFileName>
<ProgramDataBaseFileName>.\release/inf/</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<TreatWarningAsError>true</TreatWarningAsError>
<SuppressStartupBanner>true</SuppressStartupBanner>
<CompileAs>Default</CompileAs>
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
<PrecompiledHeaderFile>precompiled.h</PrecompiledHeaderFile>
<Optimization>Full</Optimization>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OutputFile>.\release/metamod.dll</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<ModuleDefinitionFile>.\metamod.def</ModuleDefinitionFile>
<ProgramDatabaseFile>.\release/inf/metamod.pdb</ProgramDatabaseFile>
<ImportLibrary>.\release/metamod.lib</ImportLibrary>
<TargetMachine>MachineX86</TargetMachine>
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
<ModuleDefinitionFile>metamod.def</ModuleDefinitionFile>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
</Link>
<CustomBuildStep>
<Command>echo Empty Action</Command>
</CustomBuildStep>
<CustomBuildStep>
<Message>Force build to run Pre-Build event</Message>
</CustomBuildStep>
<PostBuildEvent>
<Command>IF EXIST "$(ProjectDir)PostBuild.bat" (CALL "$(ProjectDir)PostBuild.bat" "$(TargetDir)" "$(TargetName)" "$(TargetExt)" "$(ProjectDir)")</Command>
</PostBuildEvent>
<PostBuildEvent>
<Message>Automatic deployment script</Message>
</PostBuildEvent>
<PreBuildEvent>
<Command>IF EXIST "$(ProjectDir)PreBuild.bat" (CALL "$(ProjectDir)PreBuild.bat" "$(ProjectDir)..\version\" "$(ProjectDir)..\")</Command>
</PreBuildEvent>
<PreBuildEvent>
<Message>Setup version from Git revision</Message>
</PreBuildEvent>
<Midl>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MkTypLibCompatible>true</MkTypLibCompatible>
<SuppressStartupBanner>true</SuppressStartupBanner>
<TargetEnvironment>Win32</TargetEnvironment>
<TypeLibraryName>.\release/metamod.tlb</TypeLibraryName>
<HeaderFileName>
</HeaderFileName>
</Midl>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\src\api_hook.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">precompiled.h</PrecompiledHeaderFile>
</ClCompile>
<ClCompile Include="..\src\api_info.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">precompiled.h</PrecompiledHeaderFile>
</ClCompile>
<ClCompile Include="..\src\commands_meta.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">precompiled.h</PrecompiledHeaderFile>
</ClCompile>
<ClCompile Include="..\src\conf_meta.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">precompiled.h</PrecompiledHeaderFile>
</ClCompile>
<ClCompile Include="..\src\dllapi.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">precompiled.h</PrecompiledHeaderFile>
</ClCompile>
<ClCompile Include="..\src\engine_api.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">precompiled.h</PrecompiledHeaderFile>
</ClCompile>
<ClCompile Include="..\src\game_support.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">precompiled.h</PrecompiledHeaderFile>
</ClCompile>
<ClCompile Include="..\src\h_export.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">precompiled.h</PrecompiledHeaderFile>
</ClCompile>
<ClCompile Include="..\src\linkplug.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">precompiled.h</PrecompiledHeaderFile>
</ClCompile>
<ClCompile Include="..\src\log_meta.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">precompiled.h</PrecompiledHeaderFile>
</ClCompile>
<ClCompile Include="..\src\metamod.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">precompiled.h</PrecompiledHeaderFile>
</ClCompile>
<ClCompile Include="..\src\meta_eiface.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">precompiled.h</PrecompiledHeaderFile>
</ClCompile>
<ClCompile Include="..\src\mlist.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">precompiled.h</PrecompiledHeaderFile>
</ClCompile>
<ClCompile Include="..\src\mplayer.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">precompiled.h</PrecompiledHeaderFile>
</ClCompile>
<ClCompile Include="..\src\mplugin.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">precompiled.h</PrecompiledHeaderFile>
</ClCompile>
<ClCompile Include="..\src\mreg.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">precompiled.h</PrecompiledHeaderFile>
</ClCompile>
<ClCompile Include="..\src\mutil.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">precompiled.h</PrecompiledHeaderFile>
</ClCompile>
<ClCompile Include="..\src\osdep.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">precompiled.h</PrecompiledHeaderFile>
</ClCompile>
<ClCompile Include="..\src\osdep_linkent_win32.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">precompiled.h</PrecompiledHeaderFile>
</ClCompile>
<ClCompile Include="..\src\osdep_p.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">precompiled.h</PrecompiledHeaderFile>
</ClCompile>
<ClCompile Include="..\src\api_info.cpp" />
<ClCompile Include="..\src\commands_meta.cpp" />
<ClCompile Include="..\src\conf_meta.cpp" />
<ClCompile Include="..\src\dllapi.cpp" />
<ClCompile Include="..\src\engine_api.cpp" />
<ClCompile Include="..\src\game_support.cpp" />
<ClCompile Include="..\src\h_export.cpp" />
<ClCompile Include="..\src\linkent.cpp" />
<ClCompile Include="..\src\linkgame.cpp" />
<ClCompile Include="..\src\log_meta.cpp" />
<ClCompile Include="..\src\meta_eiface.cpp" />
<ClCompile Include="..\src\metamod.cpp" />
<ClCompile Include="..\src\mlist.cpp" />
<ClCompile Include="..\src\mplayer.cpp" />
<ClCompile Include="..\src\mplugin.cpp" />
<ClCompile Include="..\src\mreg.cpp" />
<ClCompile Include="..\src\mutil.cpp" />
<ClCompile Include="..\src\osdep.cpp" />
<ClCompile Include="..\src\precompiled.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">precompiled.h</PrecompiledHeaderFile>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="..\src\reg_support.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">precompiled.h</PrecompiledHeaderFile>
</ClCompile>
<ClCompile Include="..\src\sdk_util.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">precompiled.h</PrecompiledHeaderFile>
</ClCompile>
<ClCompile Include="..\src\support_meta.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">precompiled.h</PrecompiledHeaderFile>
</ClCompile>
<ClCompile Include="..\src\reg_support.cpp" />
<ClCompile Include="..\src\sdk_util.cpp" />
<ClCompile Include="..\src\studioapi.cpp" />
<ClCompile Include="..\src\support_meta.cpp" />
<ClCompile Include="..\src\utils.cpp" />
<ClCompile Include="..\src\vdate.cpp" />
</ItemGroup>
<ItemGroup>
<None Include="metamod.def" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="metamod.rc" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\src\api_hook.h" />
<ClInclude Include="..\src\api_info.h" />
<ClInclude Include="..\src\commands_meta.h" />
<ClInclude Include="..\src\comp_dep.h" />
<ClInclude Include="..\src\conf_meta.h" />
<ClInclude Include="..\src\dllapi.h" />
<ClInclude Include="..\src\enginecallbacks.h" />
<ClInclude Include="..\src\engine_api.h" />
<ClInclude Include="..\src\engine_t.h" />
<ClInclude Include="..\src\enginecallbacks.h" />
<ClInclude Include="..\src\game_support.h" />
<ClInclude Include="..\src\games.h" />
<ClInclude Include="..\src\h_export.h" />
<ClInclude Include="..\src\info_name.h" />
<ClInclude Include="..\src\linkent.h" />
<ClInclude Include="..\src\log_meta.h" />
<ClInclude Include="..\src\metamod.h" />
<ClInclude Include="..\src\meta_api.h" />
<ClInclude Include="..\src\meta_eiface.h" />
<ClInclude Include="..\src\metamod.h" />
<ClInclude Include="..\src\mhook.h" />
<ClInclude Include="..\src\mlist.h" />
<ClInclude Include="..\src\mm_pextensions.h" />
<ClInclude Include="..\src\mplayer.h" />
<ClInclude Include="..\src\mplugin.h" />
<ClInclude Include="..\src\mqueue.h" />
<ClInclude Include="..\src\mreg.h" />
<ClInclude Include="..\src\mutil.h" />
<ClInclude Include="..\src\new_baseclass.h" />
<ClInclude Include="..\src\osdep.h" />
<ClInclude Include="..\src\osdep_p.h" />
<ClInclude Include="..\src\plinfo.h" />
<ClInclude Include="..\src\precompiled.h" />
<ClInclude Include="..\src\reg_support.h" />
<ClInclude Include="..\src\ret_type.h" />
<ClInclude Include="..\src\sdk_util.h" />
<ClInclude Include="..\src\studioapi.h" />
<ClInclude Include="..\src\support_meta.h" />
<ClInclude Include="..\src\types_meta.h" />
<ClInclude Include="..\src\utils.h" />
<ClInclude Include="..\src\vdate.h" />
<ClInclude Include="..\src\vers_meta.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">

View File

@ -2,18 +2,15 @@
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
<UniqueIdentifier>{a2511622-7e99-4c67-845f-0751105c3bde}</UniqueIdentifier>
<Extensions>cpp;c;cxx;rc;def;r;odl;idl;hpj;bat</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions>
<UniqueIdentifier>{dfc6c7bb-cea4-43c5-bb1b-b8145cf93dd5}</UniqueIdentifier>
<Extensions>ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\src\api_hook.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\api_info.cpp">
<Filter>Source Files</Filter>
</ClCompile>
@ -35,7 +32,10 @@
<ClCompile Include="..\src\h_export.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\linkplug.cpp">
<ClCompile Include="..\src\linkent.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\linkgame.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\log_meta.cpp">
@ -65,10 +65,7 @@
<ClCompile Include="..\src\osdep.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\osdep_linkent_win32.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\osdep_p.cpp">
<ClCompile Include="..\src\precompiled.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\reg_support.cpp">
@ -77,42 +74,26 @@
<ClCompile Include="..\src\sdk_util.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\studioapi.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\support_meta.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\precompiled.cpp">
<ClCompile Include="..\src\utils.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\vdate.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="metamod.def">
<Filter>Resource Files</Filter>
</None>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="metamod.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\src\precompiled.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="..\src\types_meta.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="..\src\api_hook.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="..\src\api_info.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="..\src\commands_meta.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="..\src\comp_dep.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="..\src\conf_meta.h">
<Filter>Source Files</Filter>
</ClInclude>
@ -131,10 +112,10 @@
<ClInclude Include="..\src\game_support.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="..\src\h_export.h">
<ClInclude Include="..\src\games.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="..\src\info_name.h">
<ClInclude Include="..\src\h_export.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="..\src\linkent.h">
@ -152,10 +133,10 @@
<ClInclude Include="..\src\metamod.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="..\src\mlist.h">
<ClInclude Include="..\src\mhook.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="..\src\mm_pextensions.h">
<ClInclude Include="..\src\mlist.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="..\src\mplayer.h">
@ -164,35 +145,47 @@
<ClInclude Include="..\src\mplugin.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="..\src\mqueue.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="..\src\mreg.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="..\src\mutil.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="..\src\new_baseclass.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="..\src\osdep.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="..\src\osdep_p.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="..\src\plinfo.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="..\src\reg_support.h">
<ClInclude Include="..\src\precompiled.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="..\src\ret_type.h">
<ClInclude Include="..\src\reg_support.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="..\src\sdk_util.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="..\src\studioapi.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="..\src\support_meta.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="..\src\types_meta.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="..\src\utils.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="..\src\vdate.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="..\src\vers_meta.h">
<Filter>Source Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

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

View File

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

View File

@ -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 <willday@hpgx.net>
*
* 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 },
};

View File

@ -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 <willday@hpgx.net>
*
* 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);
struct api_info_t
{
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
api_caller_func_t api_caller; // argument format/type for single-main-hook-function optimization
const char *name; // string representation of function name
};
} api_info_t;
// 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 */

View File

@ -1,78 +1,91 @@
// vi: set ts=4 sw=4 :
// vim: set tw=75 :
// commands_meta.cpp - implementation of various console commands
/*
* Copyright (c) 2001-2004 Will Day <willday@hpgx.net>
*
* 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);
#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();
}
@ -81,24 +94,24 @@ void svr_meta()
void client_meta(edict_t* pEntity)
{
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 <command> [<arguments>]");
META_CONS("valid commands are:");
META_CONS(" version - display metamod version info");
@ -130,38 +143,37 @@ void client_meta_usage(edict_t *pEntity)
}
// "meta version" console command.
void cmd_meta_version()
{
if (CMD_ARGC() != 2)
void cmd_meta_version(void)
{
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)
{
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 <willday@hpgx.net>", 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()
{
if (CMD_ARGC() != 2)
void cmd_meta_game(void)
{
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()
{
if (CMD_ARGC() != 2)
void cmd_meta_refresh(void)
{
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()
{
if (CMD_ARGC() != 2)
void cmd_meta_pluginlist(void)
{
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)
{
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()
{
if (CMD_ARGC() != 2)
void cmd_meta_cmdlist(void)
{
if (CMD_ARGC() != 2) {
META_CONS("usage: meta cmds");
return;
}
RegCmds->show();
g_regCmds->show();
}
// "meta cvars" console command.
void cmd_meta_cvarlist()
{
if (CMD_ARGC() != 2)
void cmd_meta_cvarlist(void)
{
if (CMD_ARGC() != 2) {
META_CONS("usage: meta cvars");
return;
}
RegCvars->show();
g_regCvars->show();
}
// "meta config" console command.
void cmd_meta_config()
{
if (CMD_ARGC() != 2)
void cmd_meta_config(void)
{
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 <name> [<description>]");
META_CONS(" where <name> 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(" <gamedir>");
META_CONS(" <gamedir>/dlls");
META_CONS(" <given path, if absolute>");
return;
}
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);
if (argc < 3)
{
if (argc < 3) {
META_CONS("usage: meta %s <plugin> [<plugin> ...]", cmd);
META_CONS(" where <plugin> 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++)
{
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);
Plugins->show();
break;
case PC_INFO:
g_plugins->show(0);
}
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;
}
}
}

View File

@ -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 <willday@hpgx.net>
*
* 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 */

View File

@ -1,7 +1,42 @@
// vi: set ts=4 sw=4 :
// vim: set tw=75 :
// conf_meta.cpp - configfile reading routines
/*
* Copyright (c) 2001-2003 Will Day <willday@hpgx.net>
*
* 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)
{
}
@ -9,31 +44,28 @@ MConfig::MConfig()
// _after_ constructor, so that all the fields are allocated (d'oh).
void MConfig::init(option_t* global_options)
{
option_t *optp;
list = global_options;
for (optp=list; optp->name; optp++)
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 (optp = list; optp->name && Q_strcmp(optp->name, lookup); optp++);
if (optp->name)
for (auto optp = list; optp->name; optp++)
if (!strcmp(optp->name, lookup)) {
return optp;
else
RETURN_ERRNO(nullptr, ME_NOTFOUND);
}
RETURN_ERRNO(NULL, ME_NOTFOUND);
}
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);
}
@ -42,34 +74,31 @@ mBOOL MConfig::set(option_t *setp, const char *setstr)
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,24 +106,32 @@ 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)
@ -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++)
{
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;
}

View File

@ -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 <willday@hpgx.net>
*
* 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
{
typedef enum {
CF_NONE=0,
CF_INT,
CF_BOOL,
CF_STR,
CF_PATH,
};
#if 0
CF_CVAR,
CF_CMD,
#endif
} cf_type_t;
struct option_t
{
char *name; // option name
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
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();
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);
mBOOL set(option_t *setp, const char *value);
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;
};
#endif /* CONF_META_H */

View File

@ -1,177 +1,175 @@
// vi: set ts=4 sw=4 :
// vim: set tw=75 :
// dllapi.cpp - implementation of Half-Life DLL routines
/*
* Copyright (c) 2001-2003 Will Day <willday@hpgx.net>
*
* 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.
//
@ -185,266 +183,221 @@ 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.
@ -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;
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;
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);
}

View File

@ -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 <willday@hpgx.net>
*
* 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 */

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,43 @@
#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 <willday@hpgx.net>
*
* 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 <archtypes.h>
// Plugin's GetEngineFunctions, called by metamod.
typedef int (*GET_ENGINE_FUNCTIONS_FN) (enginefuncs_t *pengfuncsFromEngine, int *interfaceVersion);
@ -10,21 +49,250 @@ 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__
#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 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)(char *s1, char *s2);
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);
@ -39,7 +307,7 @@ 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 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);
@ -58,14 +326,14 @@ typedef const char *(*FN_TRACETEXTURE)(edict_t *pTextureEntity, const float *v1,
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_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)();
typedef void (*FN_MESSAGEEND) (void);
typedef void (*FN_WRITEBYTE) (int iValue);
typedef void (*FN_WRITECHAR) (int iValue);
typedef void (*FN_WRITESHORT) (int iValue);
@ -79,9 +347,14 @@ 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_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);
@ -96,22 +369,31 @@ 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)();
typedef const char * (*FN_CMD_ARGS) ( void );
typedef const char * (*FN_CMD_ARGV) ( int argc );
typedef int (*FN_CMD_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)();
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);
@ -120,20 +402,20 @@ typedef int (*FN_COMPAREFILETIME)(char *filename1, char *filename2, int *iCompar
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 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)();
typedef int (*FN_NUMBEROFENTITIES) (void);
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 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)();
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 );
@ -144,35 +426,43 @@ 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 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)();
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, char *value);
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)());
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)();
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)();
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 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 */

View File

@ -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 <willday@hpgx.net>
*
* 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
};
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;

View File

@ -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,7 +47,7 @@
// "hack" our way around that by using a flag METAMOD_CORE which is set
// when compiling Metamod proper.
#ifdef __METAMOD_BUILD__
#ifdef METAMOD_CORE
# include "meta_eiface.h" // HL_enginefuncs_t
// Use a #define to bend the enginefuncs_t type to our HL_enginefuncs_t
@ -57,7 +57,7 @@
#include <enginecallback.h> // ALERT, etc
#ifdef __METAMOD_BUILD__
#ifdef METAMOD_CORE
# undef enginefuncs_t
#endif /* METAMOD_CORE */

View File

@ -1,56 +1,87 @@
// 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 <willday@hpgx.net>
*
* 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
//! 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
// 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)
{
int length_in;
int length_out;
if (!from)
return mFALSE;
if (!to)
to = from;
if (NULL == from) return mFALSE;
if (NULL == to) to = from;
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;
}
@ -60,22 +91,19 @@ mBOOL install_gamedll(char *from, const char *to)
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;
}
@ -90,57 +118,160 @@ mBOOL install_gamedll(char *from, const char *to)
// - ME_NOTFOUND couldn't recognize game
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 <dllfile>'", OLD_GAMEDLL_TXT, CONFIG_INI);
}
META_ERROR("File '%s' is no longer supported; instead, specify override gamedll in %s or with '+localinfo mm_gamedll <dllfile>'", 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 */
}
// Neither override nor auto-detect found a gamedll.
if (!known && !g_config->gamedll)
RETURN_ERRNO(mFALSE, ME_NOTFOUND);
// 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 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) );
safevoid_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))
{
safevoid_snprintf(gamedll->real_pathname, sizeof(gamedll->real_pathname), "%s/dlls/%s", gamedll->gamedir, 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);
}
}
else
{
// Neither known-list found a gamedll.
RETURN_ERRNO(mFALSE, ME_NOTFOUND);
usedfn = knownfn;
}
safevoid_snprintf(gamedll->pathname, sizeof(gamedll->pathname), "%s/dlls/%s", gamedll->gamedir, knownfn);
// Now make an absolute path
snprintf(gamedll->pathname, sizeof(gamedll->pathname), "%s/dlls/%s",
gamedll->gamedir, usedfn);
}
// 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';
gamedll->desc = known->desc;
META_LOG("Recognized game '%s'; using dllfile '%s'", gamedll->name, gamedll->file);
return mTRUE;
// 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';
}
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);
}
if (0 != strippedfn) free(strippedfn);
return (mTRUE);
}

View File

@ -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 <willday@hpgx.net>
*
* 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 {
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 *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 */

131
metamod/src/games.h Normal file
View File

@ -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 <willday@hpgx.net>
*
* 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"},

View File

@ -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)
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() {
// NOTE: These aren't actually called. Needs investigation.
void _init(void) {
// called before dlopen() returns
}
void _fini() {
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;
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;
metamod_startup();
}
return;
// 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

View File

@ -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 <willday@hpgx.net>
*
* 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 */

54
metamod/src/info_name.h Normal file
View File

@ -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 <willday@hpgx.net>
*
* 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 <willday@metamod.org>"
#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 */

59
metamod/src/linkent.cpp Normal file
View File

@ -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 <willday@hpgx.net>
*
* 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 <kijuhe00@students.oamk.fi>.
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);
}

View File

@ -1,12 +1,50 @@
#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 <willday@hpgx.net>
*
* 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 <extdll.h> // 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);
// Comments from SDK dlls/util.h:
//! This is the glue that hooks .MAP entity class names to our CPP classes.
//! The _declspec forces them to be exported by name so we can do a lookup with GetProcAddress().
@ -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
@ -40,13 +90,13 @@ typedef void (*ENTITY_FN) (entvars_t *);
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(!(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()); \
META_ERROR("Can't link entity '%s' for plugin '%s'; loadable != startup: %s", entStr, pluginName, findp->str_loadable()); \
missing=1; \
return; \
} \
@ -54,10 +104,12 @@ typedef void (*ENTITY_FN) (entvars_t *);
pfnEntity = (ENTITY_FN) DLSYM(findp->handle, entStr); \
} \
if(!pfnEntity) { \
META_WARNING("Couldn't find plugin entity '%s' in plugin DLL '%s'", entStr, findp->file); \
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 */

3631
metamod/src/linkgame.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +0,0 @@
#include "precompiled.h"
// Entity lists for plugins
//LINK_ENTITY_TO_PLUGIN(adminmod_timer, "adminmod");

View File

@ -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 <willday@hpgx.net>
*
* 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
enum MLOG_SERVICE
{
@ -11,7 +46,7 @@ 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, ...)
@ -21,75 +56,58 @@ void META_CONS(const char *fmt, ...)
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, ...)
{
if (CVAR_GET_FLOAT && CVAR_GET_FLOAT("developer")) {
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(mlsDEV, at_logged, "[META] dev:", fmt, ap);
va_end(ap);
}
}
// Log infos.
void META_INFO(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] INFO:", fmt, ap);
va_end(ap);
}
// Log warnings.
void META_WARNING(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] WARNING:", fmt, ap);
va_end(ap);
}
// Log errors.
void META_ERROR(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);
buffered_ALERT(mlsIWEL, at_logged, "[META] ERROR:", 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);
}
@ -101,46 +119,17 @@ void META_CLIENT(edict_t *pEntity, const char *fmt, ...)
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;
@ -148,59 +137,63 @@ public:
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;
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;
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;
}

View File

@ -1,4 +1,44 @@
#pragma once
// vi: set ts=4 sw=4 :
// vim: set tw=75 :
// log_meta.h - functions & macros for logging
/*
* Copyright (c) 2001-2003 Will Day <willday@hpgx.net>
*
* 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.
//
@ -25,24 +65,15 @@
// 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
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 */

View File

@ -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 <willday@hpgx.net>
*
* 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 "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 RETURN_META(result) \
do { gpMetaGlobals->mres=result; return; } while(0)
#define RETURN_META_VALUE(result, value) \
do { gpMetaGlobals->mres = result; return value; } while (0)
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
// 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,31 +126,46 @@ 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
@ -182,3 +232,6 @@ C_DLLEXPORT int GetEngineFunctions_Post(enginefuncs_t *pengfuncsFromEngine, int
#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 */

View File

@ -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 <willday@hpgx.net>
*
* 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
// ------------------------------------------------------------------------
// 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) (),
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 *))
void (*_pfnCvarValue2)(const edict_t*, int, const char*, const char*)
)
{
pfnOnFreeEntPrivateData = _pfnOnFreeEntPrivateData;
pfnGameShutdown = _pfnGameShutdown;
@ -15,334 +61,104 @@ meta_new_dll_functions_t::meta_new_dll_functions_t(
pfnCvarValue2 = _pfnCvarValue2;
}
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);
}
// 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**)
)
memcpy(_pFuncs, this, size);
}
int meta_new_dll_functions_t::determine_interface_version(void)
{
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;
// 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
// --------------------------------------------------------------
// static member initialisation
int meta_enginefuncs_t::sm_version = 0;
// -----------------------------------------------------------------
// HL_enginefuncs
// -----------------------------------------------------------------
void HL_enginefuncs_t::initialise_interface(enginefuncs_t* _pFuncs)
{
set_from(_pFuncs);
@ -350,4 +166,166 @@ void HL_enginefuncs_t::initialise_interface(enginefuncs_t *_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;
}
}

View File

@ -1,4 +1,48 @@
#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 <willday@hpgx.net>
*
* 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 <extdll.h> // NEW_DLL_FUNCTIONS, enginefuncs_t
#include <string.h> // 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
@ -7,13 +51,16 @@
// dll overwriting our memory when using an old Metamod with a new game
// 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) (),
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*)
@ -27,243 +74,165 @@ public:
// Copy the pointers from this object to a NEW_DLL_FUNCTIONS struct.
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
struct meta_enginefuncs_t: public enginefuncs_t {
public:
// functions:
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)(),
// meta_enginefuncs_t
struct meta_enginefuncs_t : public enginefuncs_t
{
meta_enginefuncs_t()
{
};
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);
// Copy the pointers from this object to an enginefuncs_t struct.
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()
{
Q_memset(this, 0, sizeof(meta_enginefuncs_t));
}
inline meta_enginefuncs_t::meta_enginefuncs_t(const meta_enginefuncs_t &_rhs)
{
Q_memcpy(this, &_rhs, sizeof(enginefuncs_t));
}
inline meta_enginefuncs_t &meta_enginefuncs_t::operator=(const meta_enginefuncs_t &_rhs)
{
Q_memcpy(this, &_rhs, sizeof(enginefuncs_t));
return *this;
}
//
// Inline functions
//
inline void meta_enginefuncs_t::set_from(enginefuncs_t* _pFuncs)
{
Q_memcpy(this, _pFuncs, sizeof(enginefuncs_t));
memcpy(this, _pFuncs, sizeof(enginefuncs_t));
}
inline void meta_enginefuncs_t::copy_to(enginefuncs_t* _pFuncs)
{
Q_memcpy(_pFuncs, this, sizeof(enginefuncs_t));
memcpy(_pFuncs, this, sizeof(enginefuncs_t));
}
inline int meta_enginefuncs_t::version(void)
{
return sm_version;
}
// --------------------------------------------------------------------
// 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
@ -274,9 +243,13 @@ inline void meta_enginefuncs_t::copy_to(enginefuncs_t *_pFuncs)
// 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.
@ -284,10 +257,32 @@ public:
// with the pointers passed from the HL engine.
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);
};
inline HL_enginefuncs_t::HL_enginefuncs_t() : meta_enginefuncs_t() {};
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);
};
#endif /* META_EIFACE_H */

View File

@ -1,59 +1,110 @@
// vi: set ts=4 sw=4 :
// vim: set tw=75 :
// metamod.cpp - (main) implementation of metamod operations
/*
* Copyright (c) 2001-2004 Will Day <willday@hpgx.net>
*
* 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}
};
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.
@ -63,12 +114,11 @@ int metamod_startup()
// 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') {
@ -76,71 +126,63 @@ int metamod_startup()
if (valid_gamedir_file(cp))
cfile = cp;
else
META_WARNING("Empty/missing config.ini file: %s; falling back to %s",
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));
// Now, override config options with localinfo commandline options.
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') {
META_LOG("Gamedll specified via localinfo: %s", cp);
Config->set("gamedll", cp);
g_config->set("gamedll", cp);
}
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') {
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,7 +196,7 @@ 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.
//
@ -168,31 +210,36 @@ int metamod_startup()
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;
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;
else
@ -200,26 +247,25 @@ int metamod_startup()
if (mmfile) {
if (mmfile[0] == '/')
META_WARNING("Cannot exec absolute pathnames: %s", mmfile);
META_ERROR("Cannot exec absolute pathnames: %s", mmfile);
else {
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() {
// - 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));
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,7 +313,8 @@ 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;
@ -283,14 +324,14 @@ 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,
META_ERROR("dll: Couldn't load game DLL %s: %s", GameDLL.pathname,
DLERROR());
RETURN_ERRNO(mFALSE, ME_DLOPEN);
}
@ -299,22 +340,14 @@ 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")))
{
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);
}
}
else {
META_WARNING("dll: Couldn't find GiveFnptrsToDll() in game DLL '%s': %s",
META_ERROR("dll: Couldn't find GiveFnptrsToDll() in game DLL '%s': %s",
GameDLL.name, DLERROR());
RETURN_ERRNO(mFALSE, ME_DLMISSING);
}
@ -324,24 +357,24 @@ mBOOL meta_load_gamedll() {
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); \
META_ERROR("malloc failed for gamedll struct_field: %s", STR_GetFuncs); \
} \
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); \
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"); \
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("=================="); \
@ -357,27 +390,31 @@ mBOOL meta_load_gamedll() {
// 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);
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);
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);
}

View File

@ -1,4 +1,41 @@
#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 <willday@hpgx.net>
*
* 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
@ -8,7 +45,7 @@
#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 "engine_t.h" // engine_t, g_engine
// file that lists plugins to load at startup
#define PLUGINS_INI "addons/metamod/plugins.ini"
@ -24,15 +61,12 @@
// 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"
char gamedir[PATH_MAX]; // ie "/home/willday/half-life/cstrike"
@ -41,8 +75,7 @@ struct gamedll_t
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.
@ -52,20 +85,25 @@ 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 */

File diff suppressed because it is too large Load Diff

View File

@ -1,50 +1,90 @@
#pragma once
// vi: set ts=4 sw=4 :
// vim: set tw=75 :
// mlist.h - class and constants to describe a list of plugins
/*
* Copyright (c) 2001-2003 Will Day <willday@hpgx.net>
*
* 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);
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
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
char inifile[PATH_MAX]; // full pathname
// constructor:
MPluginList(const char *ifile);
// 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 */

View File

@ -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 <cmdline>' 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 <cmdline>' 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);

View File

@ -1,45 +1,47 @@
// 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 <willday@hpgx.net>
*
* 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
@ -48,41 +50,34 @@ 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()
{
if (isQueried)
const char* MPlayer::is_querying_cvar(void) const
{
if (isQueried) {
return cvarName;
}
return nullptr;
return NULL;
}
// Mark a player as querying a client cvar and stores the cvar name
@ -90,27 +85,24 @@ const char *MPlayer::is_querying_cvar()
// - ME_ARGUMENT cvar is NULL
void MPlayerList::set_player_cvar_query(const edict_t* pEntity, const char* cvar)
{
int indx = ENTINDEX(const_cast<edict_t *>(pEntity));
if (indx < 1 || indx > gpGlobals->maxClients)
return; //maybe output a message?
int indx = ENTINDEX(pEntity);
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)
{
int indx = ENTINDEX(const_cast<edict_t *>(pEntity));
if (indx < 1 || indx > gpGlobals->maxClients)
return; //maybe output a message?
int indx = ENTINDEX(pEntity);
if (indx >= 1 && indx <= maxplayers)
players[indx].clear_cvar_query(cvar);
}
void MPlayerList::clear_all_cvar_queries()
{
for (int indx = 1; indx < gpGlobals->maxClients; ++indx)
void MPlayerList::clear_all_cvar_queries(void)
{
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<edict_t *>(pEntity));
if (indx < 1 || indx > gpGlobals->maxClients)
{
RETURN_ERRNO(nullptr, ME_NOTFOUND);
}
int indx = ENTINDEX(pEntity);
if (indx >= 1 && indx <= maxplayers)
return players[indx].is_querying_cvar();
RETURN_ERRNO(NULL, ME_NOTFOUND);
}

View File

@ -1,38 +1,76 @@
#pragma once
// vi: set ts=4 sw=4 :
// vim: set tw=75 :
// mplayer.h - class to keep info about a player and a class listing all
// players
/*
* Copyright (c) 2005 Will Day <willday@hpgx.net>
*
* 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 "plinfo.h" // plugin_info_t, etc
#include "mutil.h" // query_callback_t
#include "types_meta.h" // mBOOL
#include "new_baseclass.h" // class_metamod_new
// 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 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 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 */

File diff suppressed because it is too large Load Diff

View File

@ -1,11 +1,55 @@
#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 <willday@hpgx.net>
*
* 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.h> // time_t, etc
#include <eiface.h> // 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 {
typedef enum {
PL_EMPTY = 0, // empty slot
PL_VALID, // has valid info in it
PL_BADFILE, // nonexistent file (open failed),
@ -14,10 +58,10 @@ enum PLUG_STATUS {
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,77 +69,102 @@ 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 {
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 {
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 {
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 {
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 {
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:
mBOOL ini_parseline(const char *line); // parse line from inifile
// 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
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.
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;
// 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();
mBOOL check_input(void);
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);
mBOOL resolve(void); // find a matching file on disk
char *resolve_dirs(char *path);
char *resolve_prefix(char *path);
char *resolve_suffix(char *path);
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();
mBOOL unpause();
mBOOL pause(void);
mBOOL unpause(void);
mBOOL retry(PLUG_LOADTIME now, PL_UNLOAD_REASON reason); // if previously failed
void free_api_pointers();
mBOOL clear();
mBOOL clear(void);
mBOOL plugin_unload(plid_t plid, PLUG_LOADTIME now, PL_UNLOAD_REASON reason); // other plugin unloading
void show(); // print info about plugin to console
void show(void); // print info about plugin to console
mBOOL newer_file(); // check for newer file on disk
mBOOL newer_file(void); // check for newer file on disk
// output string functions
const char *str_status(STR_STATUS fmt);
const char *str_action(STR_ACTION fmt);
const char *str_source(STR_SOURCE fmt);
@ -103,82 +172,252 @@ public:
const char *str_reason(PL_UNLOAD_REASON preason, PL_UNLOAD_REASON preal_reason);
const char *str_loadtime(PLUG_LOADTIME pallow, STR_LOADTIME fmt);
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); };
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 const char *str_loadable() {
return info ? str_loadtime(info->loadable, SL_SIMPLE) : " -";
const char *str_loadable(void) {
if(info) return(str_loadtime(info->loadable, SL_SIMPLE));
else return(" -");
};
inline const char *str_unloadable() {
return info ? str_loadtime(info->unloadable, SL_SIMPLE) : " -";
const char *str_unloadable(void) {
if(info) return(str_loadtime(info->unloadable, SL_SIMPLE));
else return(" -");
};
inline const char *str_loadable(STR_LOADTIME fmt) {
return info ? str_loadtime(info->loadable, fmt) : " -";
const char *str_loadable(STR_LOADTIME fmt) {
if(info) return(str_loadtime(info->loadable, fmt));
else return(" -");
};
inline const char *str_unloadable(STR_LOADTIME fmt) {
return info ? str_loadtime(info->unloadable, fmt) : " -";
const char *str_unloadable(STR_LOADTIME fmt) {
if(info) return(str_loadtime(info->unloadable, fmt));
else return(" -");
};
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;
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;
};
// 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 */

View File

@ -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 <willday@hpgx.net>
*
* 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,7 +62,7 @@ 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;
@ -37,29 +82,33 @@ mBOOL MRegCmd::call()
// 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++)
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];
if (!_stricmp(mlist[i].name, findname))
return (&mlist[i]);
}
RETURN_ERRNO(NULL, ME_NOTFOUND);
}
@ -69,7 +118,8 @@ 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* MRegCmdList::add(const char* addname)
{
MRegCmd* icmd;
if (endlist == size) {
@ -80,17 +130,15 @@ MRegCmd *MRegCmdList::add(const char *addname) {
META_DEBUG(6, ("Growing reg cmd list from %d to %d", size, newsize));
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;
// initialize new (unused) entries
for (i=endlist; i<size; i++) {
Q_memset(&mlist[i], 0, sizeof(mlist[i]));
for (i = endlist; i < size; i++)
mlist[i].init(i + 1); // 1-based
}
}
icmd = &mlist[endlist];
// Malloc space separately for the command name, because:
@ -98,19 +146,20 @@ MRegCmd *MRegCmdList::add(const char *addname) {
// happen).
// - Can't point to memory in mlist which might get moved later by
// realloc (again, segv).
icmd->name=strdup(addname);
icmd->name = _strdup(addname);
if (!icmd->name) {
META_WARNING("Couldn't strdup for adding reg cmd name '%s': %s",
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++) {
if (mlist[i].plugid == plugin_id)
@ -119,7 +168,7 @@ void MRegCmdList::disable(int plugin_id) {
}
// List all the registered commands.
void MRegCmdList::show()
void MRegCmdList::show(void)
{
int i, n = 0, a = 0;
MRegCmd* icmd;
@ -127,50 +176,42 @@ void MRegCmdList::show()
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) {
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);
@ -178,8 +219,6 @@ void MRegCmdList::show(int plugin_id) {
META_CONS("Registered commands: unknown (can't get info under this OS)");
return;
}
*/
META_CONS("Registered commands:");
for (i = 0; i < endlist; i++) {
icmd = &mlist[i];
@ -207,27 +246,31 @@ 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",
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
@ -239,7 +282,8 @@ MRegCvarList::MRegCvarList()
// cvar::set().
// meta_errno values:
// - ME_NOMEM couldn't alloc or realloc for various parts
MRegCvar *MRegCvarList::add(const char *addname) {
MRegCvar* MRegCvarList::add(const char* addname)
{
MRegCvar* icvar;
if (endlist == size) {
@ -250,17 +294,15 @@ MRegCvar *MRegCvarList::add(const char *addname) {
META_DEBUG(6, ("Growing reg cvar list from %d to %d", size, newsize));
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;
// initialize new (unused) entries
for (i=endlist; i<size; i++) {
Q_memset(&vlist[i], 0, sizeof(vlist[i]));
for (i = endlist; i < size; i++)
vlist[i].init(i + 1); // 1-based
}
}
icvar = &vlist[endlist];
@ -269,37 +311,39 @@ MRegCvar *MRegCvarList::add(const char *addname) {
// happen).
// - Can't point to memory in vlist which might get moved later by
// realloc (again, segv).
icvar->data = (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",
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",
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];
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++) {
@ -315,88 +359,97 @@ void MRegCvarList::disable(int plugin_id) {
}
// List all the registered cvars.
void MRegCvarList::show() {
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++;
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) {
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));
memset(mlist, 0, sizeof(mlist));
for (i = 0; i < size; i++) {
mlist[i].index = i + 1; // 1-based
}
@ -406,7 +459,8 @@ MRegMsgList::MRegMsgList()
// Add the given user msg the list and return the instance.
// meta_errno values:
// - ME_MAXREACHED reached max number of msgs allowed
MRegMsg *MRegMsgList::add(const char *addname, int addmsgid, int addsize) {
MRegMsg* MRegMsgList::add(const char* addname, int addmsgid, int addsize)
{
MRegMsg* imsg;
if (endlist == size) {
@ -426,7 +480,7 @@ MRegMsg *MRegMsgList::add(const char *addname, int addmsgid, int addsize) {
imsg->msgid = addmsgid;
imsg->size = addsize;
return imsg;
return (imsg);
}
// Try to find a registered msg with the given name.
@ -434,12 +488,11 @@ MRegMsg *MRegMsgList::add(const char *addname, int addmsgid, int addsize) {
// - ME_NOTFOUND couldn't find a matching cvar
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);
}
@ -448,33 +501,33 @@ MRegMsg *MRegMsgList::find(const char *findname)
// - ME_NOTFOUND couldn't find a matching cvar
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
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);
}

View File

@ -1,7 +1,43 @@
#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 <willday@hpgx.net>
*
* 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
// more cvars than commands, so we grow them at different increments.
@ -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;
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(); // try to call the function
private:
int index; // 1-based
mBOOL call(void); // try to call the function
};
// A list of registered commands.
class MRegCmdList: public class_metamod_new {
public:
MRegCmdList();
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
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);
public:
// constructor:
MRegCmdList(void);
// 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:
friend class MRegCvarList;
// An individual registered cvar.
class MRegCvar {
friend class MRegCvarList;
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);
private:
int index; // 1-based
};
// A list of registered cvars.
class MRegCvarList: public class_metamod_new {
public:
MRegCvarList();
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
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);
public:
// constructor:
MRegCvarList(void);
// 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:
friend class MRegMsgList;
// An individual registered user msg, from gamedll.
class MRegMsg {
friend class MRegMsgList;
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
private:
int index; // 1-based
};
// A list of registered user msgs.
class MRegMsgList: public class_metamod_new {
public:
MRegMsgList();
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
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
public:
// constructor:
MRegMsgList(void);
// 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 */

View File

@ -1,6 +1,42 @@
// vi: set ts=4 sw=4 :
// vim: set tw=75 :
// mutil.cpp - utility functions to provide to plugins
/*
* Copyright (c) 2001-2003 Will Day <willday@hpgx.net>
*
* 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 = {
hudtextparms_t default_csay_tparms = {
-1, 0.25, // x, y
2, // effect
0, 255, 0, 0, // r, g, b, a1
@ -10,79 +46,74 @@ static hudtextparms_t default_csay_tparms = {
};
// 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);
len = strlen(buf);
if (len < sizeof(buf) - 2) // -1 null, -1 for newline
Q_strcat(buf, "\n");
strcat(buf, "\n");
else
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;
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;
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)
return;
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,114 +121,136 @@ 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) {
qboolean mutil_CallGameEntity(plid_t plid, const char* entStr, entvars_t* pev)
{
plugin_info_t* plinfo;
ENTITY_FN pfnEntity;
plinfo = (plugin_info_t *)plid;
META_DEBUG(8, ("Looking up game entity '%s' for plugin '%s'", entStr,
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));
(*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) {
int mutil_GetUserMsgID(plid_t plid, const char* msgname, int* size)
{
plugin_info_t* plinfo;
MRegMsg* umsg;
plinfo = (plugin_info_t *)plid;
META_DEBUG(8, ("Looking up usermsg name '%s' for plugin '%s'", msgname,
plinfo->name));
umsg=RegMsgs->find(msgname);
umsg = g_regMsgs->find(msgname);
if (umsg) {
if (size)
*size = umsg->size;
return umsg->msgid;
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) {
const char* mutil_GetUserMsgName(plid_t plid, int msgid, int* size)
{
plugin_info_t* plinfo;
MRegMsg* umsg;
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;
// 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) {
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;
}
@ -206,8 +259,7 @@ const char *mutil_GetGameInfo(plid_t plid, ginfo_t type)
{
static char buf[MAX_STRBUF_LEN];
const char* cp;
switch (type)
{
switch (type) {
case GINFO_NAME:
cp = GameDLL.name;
break;
@ -227,13 +279,12 @@ 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;
}
@ -246,18 +297,19 @@ int mutil_LoadMetaPlugin(plid_t plid, const char *fname, PLUG_LOADTIME now, void
}
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;
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;
int pindex;
@ -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,7 +336,7 @@ 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;
@ -292,7 +344,7 @@ static int mutil_UnloadMetaPluginByHandle(plid_t plid, void *plugin_handle, PLUG
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,26 +355,64 @@ 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
@ -341,6 +431,14 @@ mutil_funcs_t MetaUtilFunctions = {
mutil_UnloadMetaPlugin, // pfnUnloadPlugin
mutil_UnloadMetaPluginByHandle, //pfnUnloadPluginByHandle
mutil_IsQueryingClientCvar, //pfnIsQueryingClientCvar
mutil_MakeRequestID, // pfnMakeRequestID
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 */
};

View File

@ -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 <willday@hpgx.net>
*
* 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,27 +44,28 @@
#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);
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);
@ -35,13 +73,60 @@ struct mutil_funcs_t
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);
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)
@ -59,5 +144,16 @@ extern mutil_funcs_t MetaUtilFunctions;
#define UNLOAD_PLUGIN (*gpMetaUtilFuncs->pfnUnloadPlugin)
#define UNLOAD_PLUGIN_BY_HANDLE (*gpMetaUtilFuncs->pfnUnloadPluginByHandle)
#define IS_QUERYING_CLIENT_CVAR (*gpMetaUtilFuncs->pfnIsQueryingClientCvar)
#define MAKE_REQUESTID (*gpMetaUtilFuncs->pfnMakeRequestID)
#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 */

View File

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

View File

@ -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 <willday@hpgx.net>
*
* 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;
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;
return(NULL);
end=strpbrk(begin, delim);
if (end)
{
if(end) {
*end='\0';
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));
memset(&dli, 0, sizeof(dli));
if(dladdr(memptr, &dli))
return dli.dli_fname;
return(dli.dli_fname);
else
RETURN_ERRNO(NULL, ME_NOTFOUND);
}
#else
#elif defined(_WIN32)
// Implementation for win32 provided by Jussi Kivilinna <kijuhe00@rhea.otol.fi>:
//
// 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)
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])
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));
memset(&dli, 0, sizeof(dli));
if(dladdr(memptr, &dli))
return mTRUE;
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)
{
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))
// 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 */

View File

@ -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 <willday@hpgx.net>
*
* 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 <string.h> // strerror()
#include <ctype.h> // isupper, tolower
#include <errno.h> // 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
// String describing platform/DLL-type, for matching lines in plugins.ini.
#ifdef _WIN32
#define UNUSED /**/
extern mBOOL dlclose_handle_invalid;
// String describing platform/DLL-type, for matching lines in plugins.ini.
#ifdef __linux
#define PLATFORM "linux"
# ifdef __amd64__
#define PLATFORM_SPC "lin64"
# else
#define PLATFORM_SPC "lin32"
# endif
#elif defined(_WIN32)
#define PLATFORM "mswin"
#define PLATFORM_SPC "win32"
#define PLATFORM_DLEXT ".dll"
#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 UNUSED __attribute__((unused))
#define PLATFORM "linux"
#define PLATFORM_SPC "lin32"
#define PLATFORM_DLEXT ".so"
#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 <dlfcn.h>
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 <limits.h>
#elif defined(_WIN32)
#include <stdlib.h>
#define NAME_MAX _MAX_FNAME
#ifndef PATH_MAX
#define PATH_MAX _MAX_PATH
#endif
#endif // _WIN32
#endif /* _WIN32 */
// Various other windows routine differences.
#ifdef linux
#if defined(__linux) || defined(__APPLE__)
#include <unistd.h> // sleep
#ifndef O_BINARY
#define O_BINARY 0
#endif
#elif defined(_WIN32)
#include <io.h>
#include <direct.h>
#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 sleep(x) Sleep(x*1000)
#include <io.h>
#define open _open
#define read _read
#define write _write
#define close _close
#endif /* GCC or MSVC 8.0+ */
#endif // _WIN32
#endif /* _WIN32 */
#if !defined WIN32 && !defined _MSC_VER
#include <unistd.h> // getcwd
#endif
#ifdef __GNUC__
#include <unistd.h> // _getcwd
#elif defined(_MSC_VER)
#include <direct.h> // _getcwd
#endif /* _MSC_VER */
#include <sys/stat.h>
#ifndef S_ISREG
@ -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 <felfert@to.com>:
// 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 <pthread.h>
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 */

View File

@ -1,191 +0,0 @@
#include <extdll.h> // always
#ifndef __USE_GNU
#define __USE_GNU
#endif
#include <dlfcn.h>
#include <sys/mman.h>
#define PAGE_SIZE 4096UL
#define PAGE_MASK (~(PAGE_SIZE-1))
#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
#include <pthread.h>
#include <link.h>
#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;
}

View File

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

View File

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

View File

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

View File

@ -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 <willday@hpgx.net>
*
* 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_CHANGELEVEL, // can be loaded/unloaded between maps
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
PNL_PLG_FORCED, // forced by plugin function call
// only used internally for 'meta 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)
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
#endif /* PLINFO_H */

View File

@ -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 <dlfcn.h> // dlopen, dladdr, etc
#include <signal.h> // sigaction, etc
#include <setjmp.h> // sigsetjmp, longjmp, etc
#endif /* linux */
#include <stdarg.h>
#include <stdlib.h>
#if defined(_MSC_VER) && (_MSC_VER < 1300)
# include <new.h> // set_new_handler()
#else
# include <new> // set_new_handler()
#endif
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <ctype.h>
#include <stdio.h>
#include <string.h> // for strncpy(), etc
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <errno.h>
#include <extdll.h>
#include <eiface.h>
#include <studio.h>
#include <studioapi.h>
#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 <malloc.h> // alloca, etc ??????????
// Don't include winspool.h; clashes with SERVER_EXECUTE from engine
// #define _WINSPOOL_H
// #include <windows.h>
// #include <winnt.h> // 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"

View File

@ -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 <willday@hpgx.net>
*
* 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;
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,10 +118,10 @@ 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;
@ -83,17 +129,17 @@ void meta_AddServerCommand(char *cmd_name, void (*function)())
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;
@ -119,7 +165,7 @@ 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
@ -127,36 +173,31 @@ void meta_AddServerCommand(char *cmd_name, void (*function)())
// it will fail to work properly.
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));
}
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)
{
g_Players.set_player_cvar_query(player, cvarName);
(*g_engfuncs.pfnQueryClientCvarValue)(player, cvarName);
}

View File

@ -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 <willday@hpgx.net>
*
* 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 */

View File

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

View File

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

View File

@ -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 <willday@hpgx.net>
*
* 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 <enginecallback.h> header protection is already
// defined.
#include "enginecallbacks.h"
#include <util.h>
// 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 */

92
metamod/src/studioapi.cpp Normal file
View File

@ -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 <willday@hpgx.net>
*
* 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));
}

56
metamod/src/studioapi.h Normal file
View File

@ -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 <willday@hpgx.net>
*
* 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 <studio.h> // 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 */

View File

@ -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 <willday@hpgx.net>
*
* 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;
@ -22,44 +58,40 @@ int valid_gamedir_file(const char *path)
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:
@ -69,27 +101,24 @@ int valid_gamedir_file(const char *path)
//
// 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* 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);
}

View File

@ -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 <willday@hpgx.net>
*
* 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 <sys/types.h> // stat
#include <sys/stat.h> // 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 */

View File

@ -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 <willday@hpgx.net>
*
* 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 */

21
metamod/src/utils.cpp Normal file
View File

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

6
metamod/src/utils.h Normal file
View File

@ -0,0 +1,6 @@
#pragma once
bool is_yes(const char* str);
bool is_no(const char* str);
const char* LOCALINFO(char* key);

56
metamod/src/vdate.cpp Normal file
View File

@ -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 <willday@hpgx.net>
*
* 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";

44
metamod/src/vdate.h Normal file
View File

@ -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 <willday@hpgx.net>
*
* 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 */

55
metamod/src/vers_meta.h Normal file
View File

@ -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 <willday@hpgx.net>
*
* 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 */