From c623058d8d7cac3647be404acccb092bd1fc19e7 Mon Sep 17 00:00:00 2001 From: Kenzzer Date: Fri, 26 Jan 2024 00:53:13 +0100 Subject: [PATCH 01/18] Prepare extension for x64 build --- .gitmodules | 3 + AMBuildScript | 273 ++++--------------- PackageScript | 6 +- extension/AMBuilder | 25 +- extension/CDetour/detourhelpers.h | 99 ------- extension/CDetour/detours.cpp | 192 -------------- extension/CDetour/detours.h | 249 ------------------ extension/asm/asm.c | 420 ------------------------------ extension/asm/asm.h | 40 --- extension/cbasenpc_behavior.cpp | 2 +- extension/cbasenpc_locomotion.cpp | 16 +- extension/helpers.h | 4 +- extension/idatamapcontainer.cpp | 14 +- extension/pluginentityfactory.cpp | 4 +- extension/pluginentityfactory.h | 2 +- hl2sdk-manifests | 1 + 16 files changed, 102 insertions(+), 1248 deletions(-) create mode 100644 .gitmodules delete mode 100644 extension/CDetour/detourhelpers.h delete mode 100644 extension/CDetour/detours.cpp delete mode 100644 extension/CDetour/detours.h delete mode 100644 extension/asm/asm.c delete mode 100644 extension/asm/asm.h create mode 160000 hl2sdk-manifests diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..63f9cd8 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "hl2sdk-manifests"] + path = hl2sdk-manifests + url = git@github.com:alliedmodders/hl2sdk-manifests.git diff --git a/AMBuildScript b/AMBuildScript index b942aad..9cc3443 100644 --- a/AMBuildScript +++ b/AMBuildScript @@ -1,61 +1,6 @@ # vim: set sts=2 ts=8 sw=2 tw=99 et ft=python: import os, sys, shutil -# Simple extensions do not need to modify this file. - -class SDK(object): - def __init__(self, sdk, ext, aDef, name, platform, dir): - self.folder = 'hl2sdk-' + dir - self.envvar = sdk - self.ext = ext - self.code = aDef - self.define = name - self.platform = platform - self.name = dir - self.path = None # Actual path - self.platformSpec = platform - - # By default, nothing supports x64. - if type(platform) is list: - self.platformSpec = {p: ['x86'] for p in platform} - else: - self.platformSpec = platform - - def shouldBuild(self, targets): - for cxx in targets: - if cxx.target.platform in self.platformSpec: - if cxx.target.arch in self.platformSpec[cxx.target.platform]: - return True - return False - -WinOnly = ['windows'] -WinLinux = ['windows', 'linux'] -WinLinuxMac = ['windows', 'linux', 'mac'] - -PossibleSDKs = { -# 'episode1': SDK('HL2SDK', '1.ep1', '1', 'EPISODEONE', WinLinux, 'episode1'), -# 'ep2': SDK('HL2SDKOB', '2.ep2', '3', 'ORANGEBOX', WinLinux, 'orangebox'), -# 'css': SDK('HL2SDKCSS', '2.css', '6', 'CSS', WinLinuxMac, 'css'), -# 'hl2dm': SDK('HL2SDKHL2DM', '2.hl2dm', '7', 'HL2DM', WinLinuxMac, 'hl2dm'), -# 'dods': SDK('HL2SDKDODS', '2.dods', '8', 'DODS', WinLinuxMac, 'dods'), -# 'sdk2013': SDK('HL2SDK2013', '2.sdk2013', '9', 'SDK2013', WinLinuxMac, 'sdk2013'), - 'tf2': SDK('HL2SDKTF2', '2.tf2', '11', 'TF2', WinLinuxMac, 'tf2') -# 'l4d': SDK('HL2SDKL4D', '2.l4d', '12', 'LEFT4DEAD', WinLinuxMac, 'l4d'), -# 'nucleardawn': SDK('HL2SDKND', '2.nd', '13', 'NUCLEARDAWN', WinLinuxMac, 'nucleardawn'), -# 'l4d2': SDK('HL2SDKL4D2', '2.l4d2', '15', 'LEFT4DEAD2', WinLinuxMac, 'l4d2'), -# 'darkm': SDK('HL2SDK-DARKM', '2.darkm', '2', 'DARKMESSIAH', WinOnly, 'darkm'), -# 'swarm': SDK('HL2SDK-SWARM', '2.swarm', '16', 'ALIENSWARM', WinOnly, 'swarm'), -# 'bgt': SDK('HL2SDK-BGT', '2.bgt', '4', 'BLOODYGOODTIME', WinOnly, 'bgt'), -# 'eye': SDK('HL2SDK-EYE', '2.eye', '5', 'EYE', WinOnly, 'eye'), -# 'csgo': SDK('HL2SDKCSGO', '2.csgo', '20', 'CSGO', WinLinuxMac, 'csgo'), -# 'dota': SDK('HL2SDKDOTA', '2.dota', '21', 'DOTA', [], 'dota'), -# 'portal2': SDK('HL2SDKPORTAL2', '2.portal2', '17', 'PORTAL2', [], 'portal2'), -# 'blade': SDK('HL2SDKBLADE', '2.blade', '18', 'BLADE', WinLinux, 'blade'), -# 'insurgency': SDK('HL2SDKINSURGENCY', '2.insurgency', '19', 'INSURGENCY', WinLinuxMac, 'insurgency'), -# 'contagion': SDK('HL2SDKCONTAGION', '2.contagion', '14', 'CONTAGION', WinOnly, 'contagion'), -# 'bms': SDK('HL2SDKBMS', '2.bms', '10', 'BMS', WinLinux, 'bms'), -} - def ResolveEnvPath(env, folder=None): if env in os.environ: path = os.environ[env] @@ -86,9 +31,13 @@ def SetArchFlags(compiler): if compiler.target.arch == 'x86_64': compiler.defines += ['WIN64'] +SdkHelpers = builder.Eval('hl2sdk-manifests/SdkHelpers.ambuild', { 'Project': 'cbasenpc' }) + class ExtensionConfig(object): def __init__(self): self.sdks = {} + self.sdk_manifests = [] + self.sdk_targets = [] self.binaries = [] self.extensions = [] self.generated_headers = None @@ -147,35 +96,46 @@ class ExtensionConfig(object): import re with open(os.path.join(builder.sourcePath, 'product.version'), 'r') as fp: productContents = fp.read() - m = re.match('(\d+)\.(\d+)\.(\d+).*', productContents) + m = re.match(r'(\d+)\.(\d+)\.(\d+).*', productContents) if m == None: self.productVersion = '1.0.0' else: major, minor, release = m.groups() self.productVersion = '{0}.{1}.{2}'.format(major, minor, release) + def findSdkPath(self, sdk_name): + dir_name = 'hl2sdk-{}'.format(sdk_name) + if builder.options.hl2sdk_root: + sdk_path = os.path.join(builder.options.hl2sdk_root, dir_name) + if os.path.exists(sdk_path): + return sdk_path + return ResolveEnvPath('HL2SDK{}'.format(sdk_name.upper()), dir_name) + + def shouldIncludeSdk(self, sdk): + return not sdk.get('source2', False) + def detectSDKs(self): - sdk_list = builder.options.sdks.split(',') - use_all = sdk_list[0] == 'all' - use_present = sdk_list[0] == 'present' - - for sdk_name in PossibleSDKs: - sdk = PossibleSDKs[sdk_name] - if sdk.shouldBuild(self.all_targets): - if builder.options.hl2sdk_root: - sdk_path = os.path.join(builder.options.hl2sdk_root, sdk.folder) - else: - sdk_path = ResolveEnvPath(sdk.envvar, sdk.folder) - if sdk_path is None or not os.path.isdir(sdk_path): - if use_all or sdk_name in sdk_list: - raise Exception('Could not find a valid path for {0}'.format(sdk.envvar)) - continue - if use_all or use_present or sdk_name in sdk_list: - sdk.path = Normalize(sdk_path) - self.sdks[sdk_name] = sdk - - if len(self.sdks) < 1: - raise Exception('At least one SDK must be available.') + sdk_list = [s for s in builder.options.sdks.split(',') if s] + SdkHelpers.sdk_filter = self.shouldIncludeSdk + SdkHelpers.find_sdk_path = self.findSdkPath + SdkHelpers.findSdks(builder, self.all_targets, sdk_list) + + self.sdks = SdkHelpers.sdks + self.sdk_manifests = SdkHelpers.sdk_manifests + self.sdk_targets = SdkHelpers.sdk_targets + + for target in self.sdk_targets: + if target.sdk['name'] != 'tf2': + continue + # Our custom tf2 hl2sdk already has those defines + rm_defines = [ + 'stricmp=strcasecmp', '_stricmp=strcasecmp', + '_snprintf=snprintf', '_vsnprintf=vsnprintf,' + ] + cxx = target.cxx + for rm_define in rm_defines: + if rm_define in cxx.defines: + cxx.defines.remove(rm_define) if builder.options.sm_path: self.sm_root = builder.options.sm_path @@ -283,10 +243,6 @@ class ExtensionConfig(object): def configure_gcc(self, cxx): cxx.defines += [ - 'stricmp=strcasecmp', - '_stricmp=strcasecmp', - '_snprintf=snprintf', - '_vsnprintf=vsnprintf', 'typeof=__typeof__', 'HAVE_STDINT_H', 'GNUC', @@ -300,7 +256,6 @@ class ExtensionConfig(object): '-Wno-switch', '-Wno-array-bounds', '-msse', - '-m32', '-fvisibility=hidden', ] cxx.cxxflags += [ @@ -311,7 +266,6 @@ class ExtensionConfig(object): '-fvisibility-inlines-hidden', '-fpermissive' ] - cxx.linkflags += ['-m32'] have_gcc = cxx.vendor == 'gcc' have_clang = cxx.vendor == 'clang' @@ -398,7 +352,7 @@ class ExtensionConfig(object): cxx.cflags += ['/Oy-'] def configure_linux(self, cxx): - cxx.defines += ['_LINUX', 'POSIX'] + cxx.defines += ['LINUX', '_LINUX', 'POSIX', '_FILE_OFFSET_BITS=64'] cxx.linkflags += ['-Wl,--exclude-libs,ALL', '-lm'] if cxx.vendor == 'gcc': cxx.linkflags += ['-static-libgcc'] @@ -441,135 +395,10 @@ class ExtensionConfig(object): os.path.join(self.mms_root, 'core', 'sourcehook'), ] - defines = ['RAD_TELEMETRY_DISABLED'] - defines += ['SE_' + PossibleSDKs[i].define + '=' + PossibleSDKs[i].code for i in PossibleSDKs] - compiler.defines += defines - - paths = [ - ['public'], - ['public', 'engine'], - ['public', 'mathlib'], - ['public', 'vstdlib'], - ['public', 'tier0'], - ['public', 'tier1'] - ] - if sdk.name == 'episode1' or sdk.name == 'darkm': - paths.append(['public', 'dlls']) - paths.append(['game_shared']) - else: - paths.append(['public', 'game', 'server']) - paths.append(['public', 'toolframework']) - paths.append(['game', 'shared']) - paths.append(['common']) - - compiler.defines += ['SOURCE_ENGINE=' + sdk.code] - - if sdk.name in ['tf2', 'sdk2013', 'bms'] and compiler.like('gcc'): - # The 2013 SDK already has these in public/tier0/basetypes.h - compiler.defines.remove('stricmp=strcasecmp') - compiler.defines.remove('_stricmp=strcasecmp') - compiler.defines.remove('_snprintf=snprintf') - compiler.defines.remove('_vsnprintf=vsnprintf') - - if compiler.like('msvc'): - compiler.defines += ['COMPILER_MSVC'] - if compiler.target.arch == 'x86': - compiler.defines += ['COMPILER_MSVC32'] - elif compiler.target.arch == 'x86_64': - compiler.defines += ['COMPILER_MSVC64'] - compiler.linkflags += ['legacy_stdio_definitions.lib'] - else: - compiler.defines += ['COMPILER_GCC'] - - if compiler.target.arch == 'x86_64': - compiler.defines += ['X64BITS', 'PLATFORM_64BITS'] - - # For everything after Swarm, this needs to be defined for entity networking - # to work properly with sendprop value changes. - if sdk.name in ['blade', 'insurgency', 'doi', 'csgo']: - compiler.defines += ['NETWORK_VARS_ENABLED'] - - if sdk.name in ['css', 'hl2dm', 'dods', 'sdk2013', 'bms', 'tf2', 'l4d', 'nucleardawn', 'l4d2']: - if compiler.target.platform in ['linux', 'mac']: - compiler.defines += ['NO_HOOK_MALLOC', 'NO_MALLOC_OVERRIDE'] - - if compiler.target.platform == 'linux': - if sdk.name in ['csgo', 'blade']: - compiler.linkflags.remove('-static-libstdc++') - compiler.defines += ['_GLIBCXX_USE_CXX11_ABI=0'] - - for path in paths: - compiler.cxxincludes += [os.path.join(sdk.path, *path)] - - if compiler.target.platform == 'linux': - if sdk.name == 'episode1': - lib_folder = os.path.join(sdk.path, 'linux_sdk') - elif sdk.name in ['sdk2013', 'bms']: - lib_folder = os.path.join(sdk.path, 'lib', 'public', 'linux32') - elif compiler.target.arch == 'x86_64': - lib_folder = os.path.join(sdk.path, 'lib', 'linux64') - else: - lib_folder = os.path.join(sdk.path, 'lib', 'linux') - elif compiler.target.platform == 'mac': - if sdk.name in ['sdk2013', 'bms']: - lib_folder = os.path.join(sdk.path, 'lib', 'public', 'osx32') - elif compiler.target.arch == 'x86_64': - lib_folder = os.path.join(sdk.path, 'lib', 'osx64') - else: - lib_folder = os.path.join(sdk.path, 'lib', 'mac') - - if compiler.target.platform in ['linux', 'mac']: - if sdk.name in ['sdk2013', 'bms'] or compiler.target.arch == 'x86_64': - compiler.postlink += [ - os.path.join(lib_folder, 'tier1.a'), - os.path.join(lib_folder, 'mathlib.a') - ] - else: - compiler.postlink += [ - os.path.join(lib_folder, 'tier1_i486.a'), - os.path.join(lib_folder, 'mathlib_i486.a') - ] - - if sdk.name in ['blade', 'insurgency', 'doi', 'csgo']: - if compiler.target.arch == 'x86_64': - compiler.postlink += [os.path.join(lib_folder, 'interfaces.a')] - else: - compiler.postlink += [os.path.join(lib_folder, 'interfaces_i486.a')] - - dynamic_libs = [] - if compiler.target.platform == 'linux': - if sdk.name in ['css', 'hl2dm', 'dods', 'tf2', 'sdk2013', 'bms', 'nucleardawn', 'l4d2', 'insurgency', 'doi']: - dynamic_libs = ['libtier0_srv.so', 'libvstdlib_srv.so'] - elif compiler.target.arch == 'x86_64' and sdk.name in ['csgo', 'mock']: - dynamic_libs = ['libtier0_client.so', 'libvstdlib_client.so'] - elif sdk.name in ['l4d', 'blade', 'insurgency', 'doi', 'csgo']: - dynamic_libs = ['libtier0.so', 'libvstdlib.so'] - else: - dynamic_libs = ['tier0_i486.so', 'vstdlib_i486.so'] - elif compiler.target.platform == 'mac': - compiler.linkflags.append('-liconv') - dynamic_libs = ['libtier0.dylib', 'libvstdlib.dylib'] - elif compiler.target.platform == 'windows': - libs = ['tier0', 'tier1', 'vstdlib', 'mathlib'] - if sdk.name in ['swarm', 'blade', 'insurgency', 'doi', 'csgo']: - libs.append('interfaces') - for lib in libs: - if compiler.target.arch == 'x86': - lib_path = os.path.join(sdk.path, 'lib', 'public', lib) + '.lib' - elif compiler.target.arch == 'x86_64': - lib_path = os.path.join(sdk.path, 'lib', 'public', 'win64', lib) + '.lib' - compiler.linkflags.append(lib_path) - - for library in dynamic_libs: - source_path = os.path.join(lib_folder, library) - output_path = os.path.join(binary.localFolder, library) - - # Ensure the output path exists. - context.AddFolder(binary.localFolder) - output = context.AddSymlink(source_path, output_path) - - compiler.weaklinkdeps += [output] - compiler.linkflags[0:0] = [library] + for other_sdk in self.sdk_manifests: + compiler.defines += ['SE_{}={}'.format(other_sdk['define'], other_sdk['code'])] + + SdkHelpers.configureCxx(context, binary, sdk) return binary @@ -591,6 +420,18 @@ class ExtensionConfig(object): if self.use_auto_versioning(): binary.compiler.sourcedeps += Extension.generated_headers return binary + + def LibraryBuilder(self, compiler, name): + binary = compiler.Library(name) + self.AddVersioning(binary) + if binary.compiler.like('msvc'): + binary.compiler.linkflags += ['/SUBSYSTEM:WINDOWS'] + return binary + + def Library(self, context, compiler, name): + compiler = compiler.clone() + SetArchFlags(compiler) + return self.LibraryBuilder(compiler, name) def HL2Library(self, context, compiler, name, sdk): binary = self.Library(context, compiler, name) @@ -599,13 +440,13 @@ class ExtensionConfig(object): def HL2Config(self, project, context, compiler, name, sdk): binary = project.Configure(compiler, name, - '{0} - {1} {2}'.format(self.tag, sdk.name, compiler.target.arch)) + '{0} - {1} {2}'.format(self.tag, sdk['name'], compiler.target.arch)) self.AddVersioning(binary) return self.ConfigureForHL2(context, binary, sdk) def HL2ExtConfig(self, project, context, compiler, name, sdk): binary = project.Configure(compiler, name, - '{0} - {1} {2}'.format(self.tag, sdk.name, compiler.target.arch)) + '{0} - {1} {2}'.format(self.tag, sdk['name'], compiler.target.arch)) self.AddVersioning(binary) self.ConfigureForHL2(context, binary, sdk) self.ConfigureForExtension(context, binary.compiler) @@ -635,4 +476,4 @@ if Extension.build_extension(): BuildScripts += ['PackageScript'] -builder.Build(BuildScripts, {'Extension': Extension}) +builder.Build(BuildScripts, {'Extension': Extension}) \ No newline at end of file diff --git a/PackageScript b/PackageScript index c192d46..680199c 100644 --- a/PackageScript +++ b/PackageScript @@ -9,6 +9,7 @@ builder.SetBuildFolder('package') # Add any folders you need to this list folder_list = [ 'addons/sourcemod/extensions', + 'addons/sourcemod/extensions/x64', 'addons/sourcemod/scripting/include', 'addons/sourcemod/scripting/include/cbasenpc', 'addons/sourcemod/scripting/include/cbasenpc/tf', @@ -39,7 +40,10 @@ def CopyDirContent(src, dest): builder.AddCopy(item.path, dest_entry) # Copy binaries. for cxx_task in Extension.extensions: - builder.AddCopy(cxx_task.binary, folder_map['addons/sourcemod/extensions']) + if cxx_task.target.arch == 'x86_64': + builder.AddCopy(cxx_task.binary, folder_map['addons/sourcemod/extensions/x64']) + else: + builder.AddCopy(cxx_task.binary, folder_map['addons/sourcemod/extensions']) for smx_file in Extension.smx_files: smx_entry = Extension.smx_files[smx_file] builder.AddCopy(smx_entry, folder_map['addons/sourcemod/plugins/disabled']) diff --git a/extension/AMBuilder b/extension/AMBuilder index 25039d7..d7d0972 100644 --- a/extension/AMBuilder +++ b/extension/AMBuilder @@ -12,8 +12,6 @@ project.sources = [ 'pluginentityfactory.cpp', 'toolsnav_mesh.cpp', 'toolsnextbot.cpp', - 'CDetour/detours.cpp', - 'asm/asm.c', 'helpers.cpp', 'sourcesdk/NextBot/Path/NextBotPath.cpp', 'sourcesdk/NextBot/Path/NextBotPathFollow.cpp', @@ -69,29 +67,36 @@ project.sources = [ 'natives/nextbotplayer.cpp', 'natives/tf/nav.cpp', 'natives/tf/nav/area.cpp', - 'smsdk_ext.cpp' + 'smsdk_ext.cpp', + os.path.join(Extension.sm_root, 'public/CDetour/detours.cpp'), + os.path.join(Extension.sm_root, 'public/asm/asm.c'), + os.path.join(Extension.sm_root, 'public/libudis86/decode.c'), + os.path.join(Extension.sm_root, 'public/libudis86/itab.c'), + os.path.join(Extension.sm_root, 'public/libudis86/syn-att.c'), + os.path.join(Extension.sm_root, 'public/libudis86/syn-intel.c'), + os.path.join(Extension.sm_root, 'public/libudis86/syn.c'), + os.path.join(Extension.sm_root, 'public/libudis86/udis86.c') ] for sdk_name in Extension.sdks: sdk = Extension.sdks[sdk_name] for cxx in builder.targets: - if not cxx.target.arch in sdk.platformSpec[cxx.target.platform]: + if not cxx.target.arch in sdk['platforms'][cxx.target.platform]: continue - - binary = Extension.HL2ExtConfig(project, builder, cxx, 'cbasenpc.ext.' + sdk.ext, sdk) + binary = Extension.HL2ExtConfig(project, builder, cxx, 'cbasenpc.ext.' + sdk['extension'], sdk) binary.compiler.cxxincludes += [ os.path.join(builder.currentSourcePath, 'sourcesdk'), os.path.join(builder.currentSourcePath, 'sourcesdk/NextBot'), os.path.join(builder.currentSourcePath, 'sourcesdk/NextBot/Path'), os.path.join(builder.currentSourcePath, 'natives'), os.path.join(builder.currentSourcePath, 'shared'), - os.path.join(builder.currentSourcePath, ''), - os.path.join(sdk.path, 'game', 'shared'), - os.path.join(sdk.path, 'game', 'server') + os.path.join(builder.currentSourcePath), + os.path.join(sdk['path'], 'game', 'server') ] + binary.compiler.defines += ['RAD_TELEMETRY_DISABLED', 'HAVE_STRING_H'] if binary.compiler.behavior == 'gcc' or binary.compiler.behavior == 'clang': binary.compiler.cxxflags += ['-Wno-invalid-offsetof'] binary.sources += ['linux/glibc_compat.cpp'] -Extension.extensions = builder.Add(project) \ No newline at end of file +Extension.extensions += builder.Add(project) \ No newline at end of file diff --git a/extension/CDetour/detourhelpers.h b/extension/CDetour/detourhelpers.h deleted file mode 100644 index 954eb84..0000000 --- a/extension/CDetour/detourhelpers.h +++ /dev/null @@ -1,99 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod - * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program 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 - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id: detourhelpers.h 248 2008-08-27 00:56:22Z pred $ - */ - -#ifndef _INCLUDE_SOURCEMOD_DETOURHELPERS_H_ -#define _INCLUDE_SOURCEMOD_DETOURHELPERS_H_ - -#if defined PLATFORM_LINUX -#include -#define PAGE_SIZE 4096 -#define ALIGN(ar) ((long)ar & ~(PAGE_SIZE-1)) -#define PAGE_EXECUTE_READWRITE PROT_READ|PROT_WRITE|PROT_EXEC -#endif - -struct patch_t -{ - patch_t() - { - patch[0] = 0; - bytes = 0; - } - unsigned char patch[20]; - size_t bytes; -}; - -inline void ProtectMemory(void *addr, int length, int prot) -{ -#if defined PLATFORM_LINUX - void *addr2 = (void *)ALIGN(addr); - mprotect(addr2, sysconf(_SC_PAGESIZE), prot); -#elif defined PLATFORM_WINDOWS - DWORD old_prot; - VirtualProtect(addr, length, prot, &old_prot); -#endif -} - -inline void SetMemPatchable(void *address, size_t size) -{ - ProtectMemory(address, (int)size, PAGE_EXECUTE_READWRITE); -} - -inline void DoGatePatch(unsigned char *target, void *callback) -{ - SetMemPatchable(target, 20); - - target[0] = 0xFF; /* JMP */ - target[1] = 0x25; /* MEM32 */ - *(void **)(&target[2]) = callback; -} - -inline void ApplyPatch(void *address, int offset, const patch_t *patch, patch_t *restore) -{ - ProtectMemory(address, 20, PAGE_EXECUTE_READWRITE); - - unsigned char *addr = (unsigned char *)address + offset; - if (restore) - { - for (size_t i=0; ibytes; i++) - { - restore->patch[i] = addr[i]; - } - restore->bytes = patch->bytes; - } - - for (size_t i=0; ibytes; i++) - { - //g_pSM->LogMessage(myself, "Patching %02X with %02X..", addr[i], patch->patch[i]); - addr[i] = patch->patch[i]; - } -} - -#endif //_INCLUDE_SOURCEMOD_DETOURHELPERS_H_ diff --git a/extension/CDetour/detours.cpp b/extension/CDetour/detours.cpp deleted file mode 100644 index b4f6cc6..0000000 --- a/extension/CDetour/detours.cpp +++ /dev/null @@ -1,192 +0,0 @@ -/** -* vim: set ts=4 : -* ============================================================================= -* SourceMod -* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. -* ============================================================================= -* -* This program is free software; you can redistribute it and/or modify it under -* the terms of the GNU General Public License, version 3.0, as published by the -* Free Software Foundation. -* -* This program 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 -* this program. If not, see . -* -* As a special exception, AlliedModders LLC gives you permission to link the -* code of this program (as well as its derivative works) to "Half-Life 2," the -* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software -* by the Valve Corporation. You must obey the GNU General Public License in -* all respects for all other code used. Additionally, AlliedModders LLC grants -* this exception to all derivative works. AlliedModders LLC defines further -* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), -* or . -* -* Version: $Id: detours.cpp 248 2008-08-27 00:56:22Z pred $ -*/ - -#include "detours.h" -#include - -ISourcePawnEngine *CDetourManager::spengine = NULL; -IGameConfig *CDetourManager::gameconf = NULL; - -void CDetourManager::Init(ISourcePawnEngine *spengine, IGameConfig *gameconf) -{ - CDetourManager::spengine = spengine; - CDetourManager::gameconf = gameconf; -} - -CDetour *CDetourManager::CreateDetour(void *callbackfunction, void **trampoline, const char *signame) -{ - CDetour *detour = new CDetour(callbackfunction, trampoline, signame); - if (detour) - { - if (!detour->Init(spengine, gameconf)) - { - delete detour; - return NULL; - } - - return detour; - } - - return NULL; -} - -CDetour::CDetour(void *callbackfunction, void **trampoline, const char *signame) -{ - enabled = false; - detoured = false; - detour_address = NULL; - detour_trampoline = NULL; - this->signame = signame; - this->detour_callback = callbackfunction; - spengine = NULL; - gameconf = NULL; - this->trampoline = trampoline; -} - -bool CDetour::Init(ISourcePawnEngine *spengine, IGameConfig *gameconf) -{ - this->spengine = spengine; - this->gameconf = gameconf; - - if (!CreateDetour()) - { - enabled = false; - return enabled; - } - - enabled = true; - - return enabled; -} - -void CDetour::Destroy() -{ - DeleteDetour(); - delete this; -} - -bool CDetour::IsEnabled() -{ - return enabled; -} - -bool CDetour::CreateDetour() -{ - if (!gameconf->GetMemSig(signame, &detour_address)) - { - g_pSM->LogError(myself, "Could not locate %s - Disabling detour", signame); - return false; - } - - if (!detour_address) - { - g_pSM->LogError(myself, "Sigscan for %s failed - Disabling detour to prevent crashes", signame); - return false; - } - - detour_restore.bytes = copy_bytes((unsigned char *)detour_address, NULL, OP_JMP_SIZE+1); - - /* First, save restore bits */ - for (size_t i=0; iAllocatePageMemory(CodeSize); - spengine->SetReadWrite(wr.outbase); - wr.outptr = wr.outbase; - detour_trampoline = wr.outbase; - goto jit_rewind; - } - - spengine->SetReadExecute(wr.outbase); - - *trampoline = detour_trampoline; - - return true; -} - -void CDetour::DeleteDetour() -{ - if (detoured) - { - DisableDetour(); - } - - if (detour_trampoline) - { - /* Free the allocated trampoline memory */ - spengine->FreePageMemory(detour_trampoline); - detour_trampoline = NULL; - } -} - -void CDetour::EnableDetour() -{ - if (!detoured) - { - DoGatePatch((unsigned char *)detour_address, &detour_callback); - detoured = true; - } -} - -void CDetour::DisableDetour() -{ - if (detoured) - { - /* Remove the patch */ - ApplyPatch(detour_address, 0, &detour_restore, NULL); - detoured = false; - } -} diff --git a/extension/CDetour/detours.h b/extension/CDetour/detours.h deleted file mode 100644 index 1e81395..0000000 --- a/extension/CDetour/detours.h +++ /dev/null @@ -1,249 +0,0 @@ -/** -* vim: set ts=4 : -* ============================================================================= -* SourceMod -* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. -* ============================================================================= -* -* This program is free software; you can redistribute it and/or modify it under -* the terms of the GNU General Public License, version 3.0, as published by the -* Free Software Foundation. -* -* This program 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 -* this program. If not, see . -* -* As a special exception, AlliedModders LLC gives you permission to link the -* code of this program (as well as its derivative works) to "Half-Life 2," the -* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software -* by the Valve Corporation. You must obey the GNU General Public License in -* all respects for all other code used. Additionally, AlliedModders LLC grants -* this exception to all derivative works. AlliedModders LLC defines further -* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), -* or . -* -* Version: $Id: detours.h 257 2008-09-23 03:12:13Z pred $ -*/ - -#ifndef _INCLUDE_SOURCEMOD_DETOURS_H_ -#define _INCLUDE_SOURCEMOD_DETOURS_H_ - -#include "extension.h" -#include -#include -#include "detourhelpers.h" - -/** - * CDetours class for SourceMod Extensions by pRED* - * detourhelpers.h entirely stolen from CSS:DM and were written by BAILOPAN (I assume). - * asm.h/c from devmaster.net (thanks cybermind) edited by pRED* to handle gcc -fPIC thunks correctly - * Concept by Nephyrin Zey (http://www.doublezen.net/) and Windows Detour Library (http://research.microsoft.com/sn/detours/) - * Member function pointer ideas by Don Clugston (http://www.codeproject.com/cpp/FastDelegate.asp) - */ - -#define DETOUR_MEMBER_CALL(name) (this->*name##_Actual) -#define DETOUR_STATIC_CALL(name) (name##_Actual) - -#define DETOUR_DECL_STATIC0(name, ret) \ -ret (*name##_Actual)(void) = NULL; \ -ret name(void) - -#define DETOUR_DECL_STATIC1(name, ret, p1type, p1name) \ -ret (*name##_Actual)(p1type) = NULL; \ -ret name(p1type p1name) - -#define DETOUR_DECL_STATIC2(name, ret, p1type, p1name, p2type, p2name) \ -ret (*name##_Actual)(p1type, p2type) = NULL; \ -ret name(p1type p1name, p2type p2name) - -#define DETOUR_DECL_STATIC4(name, ret, p1type, p1name, p2type, p2name, p3type, p3name, p4type, p4name) \ -ret (*name##_Actual)(p1type, p2type, p3type, p4type) = NULL; \ -ret name(p1type p1name, p2type p2name, p3type p3name, p4type p4name) - -#define DETOUR_DECL_STATIC5(name, ret, p1type, p1name, p2type, p2name, p3type, p3name, p4type, p4name, p5type, p5name) \ -ret (*name##_Actual)(p1type, p2type, p3type, p4type, p5type) = NULL; \ -ret name(p1type p1name, p2type p2name, p3type p3name, p4type p4name, p5type p5name) - -#define DETOUR_DECL_MEMBER0(name, ret) \ -class name##Class \ -{ \ -public: \ - ret name(); \ - static ret (name##Class::* name##_Actual)(void); \ -}; \ -ret (name##Class::* name##Class::name##_Actual)(void) = NULL; \ -ret name##Class::name() - -#define DETOUR_DECL_MEMBER1(name, ret, p1type, p1name) \ -class name##Class \ -{ \ -public: \ - ret name(p1type p1name); \ - static ret (name##Class::* name##_Actual)(p1type); \ -}; \ -ret (name##Class::* name##Class::name##_Actual)(p1type) = NULL; \ -ret name##Class::name(p1type p1name) - -#define DETOUR_DECL_MEMBER2(name, ret, p1type, p1name, p2type, p2name) \ -class name##Class \ -{ \ -public: \ - ret name(p1type p1name, p2type p2name); \ - static ret (name##Class::* name##_Actual)(p1type, p2type); \ -}; \ -ret (name##Class::* name##Class::name##_Actual)(p1type, p2type) = NULL; \ -ret name##Class::name(p1type p1name, p2type p2name) - -#define DETOUR_DECL_MEMBER3(name, ret, p1type, p1name, p2type, p2name, p3type, p3name) \ -class name##Class \ -{ \ -public: \ - ret name(p1type p1name, p2type p2name, p3type p3name); \ - static ret (name##Class::* name##_Actual)(p1type, p2type, p3type); \ -}; \ -ret (name##Class::* name##Class::name##_Actual)(p1type, p2type, p3type) = NULL; \ -ret name##Class::name(p1type p1name, p2type p2name, p3type p3name) - -#define DETOUR_DECL_MEMBER4(name, ret, p1type, p1name, p2type, p2name, p3type, p3name, p4type, p4name) \ -class name##Class \ -{ \ -public: \ - ret name(p1type p1name, p2type p2name, p3type p3name, p4type p4name); \ - static ret (name##Class::* name##_Actual)(p1type, p2type, p3type, p4type); \ -}; \ -ret (name##Class::* name##Class::name##_Actual)(p1type, p2type, p3type, p4type) = NULL; \ -ret name##Class::name(p1type p1name, p2type p2name, p3type p3name, p4type p4name) - - -#define GET_MEMBER_CALLBACK(name) (void *)GetCodeAddress(&name##Class::name) -#define GET_MEMBER_TRAMPOLINE(name) (void **)(&name##Class::name##_Actual) - -#define GET_STATIC_CALLBACK(name) (void *)&name -#define GET_STATIC_TRAMPOLINE(name) (void **)&name##_Actual - -#define DETOUR_CREATE_MEMBER(name, gamedata) CDetourManager::CreateDetour(GET_MEMBER_CALLBACK(name), GET_MEMBER_TRAMPOLINE(name), gamedata); -#define DETOUR_CREATE_STATIC(name, gamedata) CDetourManager::CreateDetour(GET_STATIC_CALLBACK(name), GET_STATIC_TRAMPOLINE(name), gamedata); - - -class GenericClass {}; -typedef void (GenericClass::*VoidFunc)(); - -inline void *GetCodeAddr(VoidFunc mfp) -{ - return *(void **)&mfp; -} - -/** - * Converts a member function pointer to a void pointer. - * This relies on the assumption that the code address lies at mfp+0 - * This is the case for both g++ and later MSVC versions on non virtual functions but may be different for other compilers - * Based on research by Don Clugston : http://www.codeproject.com/cpp/FastDelegate.asp - */ -#define GetCodeAddress(mfp) GetCodeAddr(reinterpret_cast(mfp)) - -class CDetourManager; - -class CDetour -{ -public: - - bool IsEnabled(); - - /** - * These would be somewhat self-explanatory I hope - */ - void EnableDetour(); - void DisableDetour(); - - void Destroy(); - - friend class CDetourManager; - -protected: - CDetour(void *callbackfunction, void **trampoline, const char *signame); - - bool Init(ISourcePawnEngine *spengine, IGameConfig *gameconf); -private: - - /* These create/delete the allocated memory */ - bool CreateDetour(); - void DeleteDetour(); - - bool enabled; - bool detoured; - - patch_t detour_restore; - /* Address of the detoured function */ - void *detour_address; - /* Address of the allocated trampoline function */ - void *detour_trampoline; - /* Address of the callback handler */ - void *detour_callback; - /* The function pointer used to call our trampoline */ - void **trampoline; - - const char *signame; - ISourcePawnEngine *spengine; - IGameConfig *gameconf; -}; - -class CDetourManager -{ -public: - - static void Init(ISourcePawnEngine *spengine, IGameConfig *gameconf); - - /** - * Creates a new detour - * - * @param callbackfunction Void pointer to your detour callback function. - * @param trampoline Address of the trampoline pointer - * @param signame Section name containing a signature to fetch from the gamedata file. - * @return A new CDetour pointer to control your detour. - * - * Example: - * - * CBaseServer::ConnectClient(netadr_s &, int, int, int, char const*, char const*, char const*, int) - * - * Define a new class with the required function and a member function pointer to the same type: - * - * class CBaseServerDetour - * { - * public: - * bool ConnectClient(void *netaddr_s, int, int, int, char const*, char const*, char const*, int); - * static bool (CBaseServerDetour::* ConnectClient_Actual)(void *netaddr_s, int, int, int, char const*, char const*, char const*, int); - * } - * - * void *callbackfunc = GetCodeAddress(&CBaseServerDetour::ConnectClient); - * void **trampoline = (void **)(&CBaseServerDetour::ConnectClient_Actual); - * - * Creation: - * CDetourManager::CreateDetour(callbackfunc, trampoline, "ConnectClient"); - * - * Usage: - * - * CBaseServerDetour::ConnectClient(void *netaddr_s, int, int, int, char const*, char const*, char const*, int) - * { - * //pre hook code - * bool result = (this->*ConnectClient_Actual)(netaddr_s, rest of params); - * //post hook code - * return result; - * } - * - * Note we changed the netadr_s reference into a void* to avoid needing to define the type - */ - static CDetour *CreateDetour(void *callbackfunction, void **trampoline, const char *signame); - - friend class CBlocker; - friend class CDetour; - -private: - static ISourcePawnEngine *spengine; - static IGameConfig *gameconf; -}; - -#endif // _INCLUDE_SOURCEMOD_DETOURS_H_ diff --git a/extension/asm/asm.c b/extension/asm/asm.c deleted file mode 100644 index dc548a9..0000000 --- a/extension/asm/asm.c +++ /dev/null @@ -1,420 +0,0 @@ -#include "asm.h" - -#ifndef WIN32 -#define _GNU_SOURCE -#include -#include -#include -#include - -#define REG_EAX 0 -#define REG_ECX 1 -#define REG_EDX 2 -#define REG_EBX 3 - -#define IA32_MOV_REG_IMM 0xB8 // encoding is +r -#endif - -/** -* Checks if a call to a fpic thunk has just been written into dest. -* If found replaces it with a direct mov that sets the required register to the value of pc. -* -* @param dest Destination buffer where a call opcode + addr (5 bytes) has just been written. -* @param pc The program counter value that needs to be set (usually the next address from the source). -* @noreturn -*/ -void check_thunks(unsigned char *dest, unsigned char *pc) -{ -#ifndef WIN32 - /* Step write address back 4 to the start of the function address */ - unsigned char *writeaddr = dest - 4; - unsigned char *calloffset = *(unsigned char **)writeaddr; - unsigned char *calladdr = (unsigned char *)(dest + (unsigned int)calloffset); - - /* Lookup name of function being called */ - if ((*calladdr == 0x8B) && (*(calladdr+2) == 0x24) && (*(calladdr+3) == 0xC3)) - { - //a thunk maybe? - char movByte = IA32_MOV_REG_IMM; - - /* Calculate the correct mov opcode */ - switch (*(calladdr+1)) - { - case 0x04: - { - movByte += REG_EAX; - break; - } - case 0x1C: - { - movByte += REG_EBX; - break; - } - case 0x0C: - { - movByte += REG_ECX; - break; - } - case 0x14: - { - movByte += REG_EDX; - break; - } - default: - { - printf("Unknown thunk: %c\n", *(calladdr+1)); -#ifndef NDEBUG - abort(); -#endif - break; - } - } - - /* Move our write address back one to where the call opcode was */ - writeaddr--; - - - /* Write our mov */ - *writeaddr = movByte; - writeaddr++; - - /* Write the value - The provided program counter value */ - *(void **)writeaddr = (void *)pc; - writeaddr += 4; - } -#endif -} - -//if dest is NULL, returns minimum number of bytes needed to be copied -//if dest is not NULL, it will copy the bytes to dest as well as fix CALLs and JMPs -//http://www.devmaster.net/forums/showthread.php?t=2311 -int copy_bytes(unsigned char *func, unsigned char* dest, int required_len) { - int bytecount = 0; - - while(bytecount < required_len && *func != 0xCC) - { - // prefixes F0h, F2h, F3h, 66h, 67h, D8h-DFh, 2Eh, 36h, 3Eh, 26h, 64h and 65h - int operandSize = 4; - int FPU = 0; - int twoByte = 0; - unsigned char opcode = 0x90; - unsigned char modRM = 0xFF; - while(*func == 0xF0 || - *func == 0xF2 || - *func == 0xF3 || - (*func & 0xFC) == 0x64 || - (*func & 0xF8) == 0xD8 || - (*func & 0x7E) == 0x62) - { - if(*func == 0x66) - { - operandSize = 2; - } - else if((*func & 0xF8) == 0xD8) - { - FPU = *func; - if (dest) - *dest++ = *func++; - else - func++; - bytecount++; - break; - } - - if (dest) - *dest++ = *func++; - else - func++; - bytecount++; - } - - // two-byte opcode byte - if(*func == 0x0F) - { - twoByte = 1; - if (dest) - *dest++ = *func++; - else - func++; - bytecount++; - } - - // opcode byte - opcode = *func++; - if (dest) *dest++ = opcode; - bytecount++; - - // mod R/M byte - modRM = 0xFF; - if(FPU) - { - if((opcode & 0xC0) != 0xC0) - { - modRM = opcode; - } - } - else if(!twoByte) - { - if((opcode & 0xC4) == 0x00 || - ((opcode & 0xF4) == 0x60 && ((opcode & 0x0A) == 0x02 || (opcode & 0x09) == 0x09)) || - (opcode & 0xF0) == 0x80 || - ((opcode & 0xF8) == 0xC0 && (opcode & 0x0E) != 0x02) || - (opcode & 0xFC) == 0xD0 || - (opcode & 0xF6) == 0xF6) - { - modRM = *func++; - if (dest) *dest++ = modRM; - bytecount++; - } - } - else - { - if(((opcode & 0xF0) == 0x00 && (opcode & 0x0F) >= 0x04 && (opcode & 0x0D) != 0x0D) || - (opcode & 0xF0) == 0x30 || - opcode == 0x77 || - (opcode & 0xF0) == 0x80 || - ((opcode & 0xF0) == 0xA0 && (opcode & 0x07) <= 0x02) || - (opcode & 0xF8) == 0xC8) - { - // No mod R/M byte - } - else - { - modRM = *func++; - if (dest) *dest++ = modRM; - bytecount++; - } - } - - // SIB - if((modRM & 0x07) == 0x04 && - (modRM & 0xC0) != 0xC0) - { - if (dest) - *dest++ = *func++; //SIB - else - func++; - bytecount++; - } - - // mod R/M displacement - - // Dword displacement, no base - if((modRM & 0xC5) == 0x05) { - if (dest) { - *(unsigned int*)dest = *(unsigned int*)func; - dest += 4; - } - func += 4; - bytecount += 4; - } - - // Byte displacement - if((modRM & 0xC0) == 0x40) { - if (dest) - *dest++ = *func++; - else - func++; - bytecount++; - } - - // Dword displacement - if((modRM & 0xC0) == 0x80) { - if (dest) { - *(unsigned int*)dest = *(unsigned int*)func; - dest += 4; - } - func += 4; - bytecount += 4; - } - - // immediate - if(FPU) - { - // Can't have immediate operand - } - else if(!twoByte) - { - if((opcode & 0xC7) == 0x04 || - (opcode & 0xFE) == 0x6A || // PUSH/POP/IMUL - (opcode & 0xF0) == 0x70 || // Jcc - opcode == 0x80 || - opcode == 0x83 || - (opcode & 0xFD) == 0xA0 || // MOV - opcode == 0xA8 || // TEST - (opcode & 0xF8) == 0xB0 || // MOV - (opcode & 0xFE) == 0xC0 || // RCL - opcode == 0xC6 || // MOV - opcode == 0xCD || // INT - (opcode & 0xFE) == 0xD4 || // AAD/AAM - (opcode & 0xF8) == 0xE0 || // LOOP/JCXZ - opcode == 0xEB || - (opcode == 0xF6 && (modRM & 0x30) == 0x00)) // TEST - { - if (dest) - *dest++ = *func++; - else - func++; - bytecount++; - } - else if((opcode & 0xF7) == 0xC2) // RET - { - if (dest) { - *(unsigned short*)dest = *(unsigned short*)func; - dest += 2; - } - func += 2; - bytecount += 2; - } - else if((opcode & 0xFC) == 0x80 || - (opcode & 0xC7) == 0x05 || - (opcode & 0xF8) == 0xB8 || - (opcode & 0xFE) == 0xE8 || // CALL/Jcc - (opcode & 0xFE) == 0x68 || - (opcode & 0xFC) == 0xA0 || - (opcode & 0xEE) == 0xA8 || - opcode == 0xC7 || - (opcode == 0xF7 && (modRM & 0x30) == 0x00)) - { - if (dest) { - //Fix CALL/JMP offset - if ((opcode & 0xFE) == 0xE8) { - if (operandSize == 4) - { - *(long*)dest = ((func + *(long*)func) - dest); - - //pRED* edit. func is the current address of the call address, +4 is the next instruction, so the value of $pc - check_thunks(dest+4, func+4); - } - else - *(short*)dest = ((func + *(short*)func) - dest); - - } else { - if (operandSize == 4) - *(unsigned long*)dest = *(unsigned long*)func; - else - *(unsigned short*)dest = *(unsigned short*)func; - } - dest += operandSize; - } - func += operandSize; - bytecount += operandSize; - - } - } - else - { - if(opcode == 0xBA || // BT - opcode == 0x0F || // 3DNow! - (opcode & 0xFC) == 0x70 || // PSLLW - (opcode & 0xF7) == 0xA4 || // SHLD - opcode == 0xC2 || - opcode == 0xC4 || - opcode == 0xC5 || - opcode == 0xC6) - { - if (dest) - *dest++ = *func++; - else - func++; - } - else if((opcode & 0xF0) == 0x80) // Jcc -i - { - if (dest) { - if (operandSize == 4) - *(unsigned long*)dest = *(unsigned long*)func; - else - *(unsigned short*)dest = *(unsigned short*)func; - - dest += operandSize; - } - func += operandSize; - bytecount += operandSize; - } - } - } - - return bytecount; -} - -//insert a specific JMP instruction at the given location -void inject_jmp(void* src, void* dest) { - *(unsigned char*)src = OP_JMP; - *(long*)((unsigned char*)src+1) = (long)((unsigned char*)dest - ((unsigned char*)src + OP_JMP_SIZE)); -} - -//fill a given block with NOPs -void fill_nop(void* src, unsigned int len) { - unsigned char* src2 = (unsigned char*)src; - while (len) { - *src2++ = OP_NOP; - --len; - } -} - -void* eval_jump(void* src) { - unsigned char* addr = (unsigned char*)src; - - if (!addr) return 0; - - //import table jump - if (addr[0] == OP_PREFIX && addr[1] == OP_JMP_SEG) { - addr += 2; - addr = *(unsigned char**)addr; - //TODO: if addr points into the IAT - return *(void**)addr; - } - - //8bit offset - else if (addr[0] == OP_JMP_BYTE) { - addr = &addr[OP_JMP_BYTE_SIZE] + *(char*)&addr[1]; - //mangled 32bit jump? - if (addr[0] == OP_JMP) { - addr = addr + *(int*)&addr[1]; - } - return addr; - } - /* - //32bit offset - else if (addr[0] == OP_JMP) { - addr = &addr[OP_JMP_SIZE] + *(int*)&addr[1]; - } - */ - - return addr; -} -/* -from ms detours package -static bool detour_is_imported(PBYTE pbCode, PBYTE pbAddress) -{ - MEMORY_BASIC_INFORMATION mbi; - VirtualQuery((PVOID)pbCode, &mbi, sizeof(mbi)); - __try { - PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)mbi.AllocationBase; - if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE) { - return false; - } - - PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)((PBYTE)pDosHeader + - pDosHeader->e_lfanew); - if (pNtHeader->Signature != IMAGE_NT_SIGNATURE) { - return false; - } - - if (pbAddress >= ((PBYTE)pDosHeader + - pNtHeader->OptionalHeader - .DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress) && - pbAddress < ((PBYTE)pDosHeader + - pNtHeader->OptionalHeader - .DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress + - pNtHeader->OptionalHeader - .DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].Size)) { - return true; - } - return false; - } - __except(EXCEPTION_EXECUTE_HANDLER) { - return false; - } -} -*/ diff --git a/extension/asm/asm.h b/extension/asm/asm.h deleted file mode 100644 index 838e691..0000000 --- a/extension/asm/asm.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef __ASM_H__ -#define __ASM_H__ - -#define OP_JMP 0xE9 -#define OP_JMP_SIZE 5 - -#define OP_NOP 0x90 -#define OP_NOP_SIZE 1 - -#define OP_PREFIX 0xFF -#define OP_JMP_SEG 0x25 - -#define OP_JMP_BYTE 0xEB -#define OP_JMP_BYTE_SIZE 2 - -#ifdef __cplusplus -extern "C" { -#endif - -void check_thunks(unsigned char *dest, unsigned char *pc); - -//if dest is NULL, returns minimum number of bytes needed to be copied -//if dest is not NULL, it will copy the bytes to dest as well as fix CALLs and JMPs -//http://www.devmaster.net/forums/showthread.php?t=2311 -int copy_bytes(unsigned char *func, unsigned char* dest, int required_len); - -//insert a specific JMP instruction at the given location -void inject_jmp(void* src, void* dest); - -//fill a given block with NOPs -void fill_nop(void* src, unsigned int len); - -//evaluate a JMP at the target -void* eval_jump(void* src); - -#ifdef __cplusplus -} -#endif - -#endif //__ASM_H__ diff --git a/extension/cbasenpc_behavior.cpp b/extension/cbasenpc_behavior.cpp index d2073ba..2fcc17b 100644 --- a/extension/cbasenpc_behavior.cpp +++ b/extension/cbasenpc_behavior.cpp @@ -431,7 +431,7 @@ ENDEVENTCALLBACK_NOEXECUTE() BEGINEVENTCALLBACK(OnSpokeConcept, CBaseCombatCharacter* who, AIConcept_t concept, AI_Response *response) EVENTPUSHENTITY(who) - EVENTPUSHCELL(concept) + EVENTPUSHSTRING(concept) EVENTPUSHCELL(PtrToPawnAddress(response)) ENDEVENTCALLBACK() diff --git a/extension/cbasenpc_locomotion.cpp b/extension/cbasenpc_locomotion.cpp index d06740b..1567512 100644 --- a/extension/cbasenpc_locomotion.cpp +++ b/extension/cbasenpc_locomotion.cpp @@ -180,7 +180,7 @@ bool CBaseNPC_Locomotion::V_IsAbleToClimb() { cell_t _result = 0; - pCallback->PushCell((cell_t)this); + pCallback->PushCell(PtrToPawnAddress(this)); pCallback->Execute(&_result); result = !!_result; @@ -211,7 +211,7 @@ bool CBaseNPC_Locomotion::V_IsClimbingUpToLedge() { cell_t _result = 0; - pCallback->PushCell((cell_t)this); + pCallback->PushCell(PtrToPawnAddress(this)); pCallback->Execute(&_result); result = !!_result; @@ -285,7 +285,7 @@ bool CBaseNPC_Locomotion::V_ClimbUpToLedge(const Vector& vecGoal, const Vector& cell_t entRef = gamehelpers->EntityToBCompatRef(const_cast(pEntity)); cell_t _result = 0; - pCallback->PushCell((cell_t)this); + pCallback->PushCell(PtrToPawnAddress(this)); pCallback->PushArray(goalArr, 3); pCallback->PushArray(forwardArr, 3); pCallback->PushCell(entRef); @@ -319,7 +319,7 @@ bool CBaseNPC_Locomotion::V_IsAbleToJumpAcrossGaps() { cell_t _result = 0; - pCallback->PushCell((cell_t)this); + pCallback->PushCell(PtrToPawnAddress(this)); pCallback->Execute(&_result); result = !!_result; @@ -350,7 +350,7 @@ bool CBaseNPC_Locomotion::V_IsJumpingAcrossGap() { cell_t _result = 0; - pCallback->PushCell((cell_t)this); + pCallback->PushCell(PtrToPawnAddress(this)); pCallback->Execute(&_result); result = !!_result; @@ -383,7 +383,7 @@ void CBaseNPC_Locomotion::V_JumpAcrossGap(const Vector& landingGoal, const Vecto VectorToPawnVector(forwardArr, landingForward); cell_t result = 0; - pCallback->PushCell((cell_t)this); + pCallback->PushCell(PtrToPawnAddress(this)); pCallback->PushArray(goalArr, 3); pCallback->PushArray(forwardArr, 3); pCallback->Execute(&result); @@ -418,7 +418,7 @@ bool CBaseNPC_Locomotion::V_IsEntityTraversable(CBaseEntity* pEntity, ILocomotio cell_t entRef = gamehelpers->EntityToBCompatRef(pEntity); cell_t _result = 0; - pCallback->PushCell((cell_t)this); + pCallback->PushCell(PtrToPawnAddress(this)); pCallback->PushCell(entRef); pCallback->PushCell((cell_t)when); pCallback->Execute(&_result); @@ -452,7 +452,7 @@ bool CBaseNPC_Locomotion::V_ShouldCollideWith(const CBaseEntity* pEntity) cell_t entRef = gamehelpers->EntityToBCompatRef(const_cast(pEntity)); cell_t _result = 0; - pCallback->PushCell((cell_t)this); + pCallback->PushCell(PtrToPawnAddress(this)); pCallback->PushCell(entRef); pCallback->Execute(&_result); diff --git a/extension/helpers.h b/extension/helpers.h index bfed9d3..84ab100 100644 --- a/extension/helpers.h +++ b/extension/helpers.h @@ -150,7 +150,7 @@ inline void VectorToPawnVector(cell_t* angAddr, const QAngle* angle) inline cell_t PtrToPawnAddress(const void* ptr) { #ifdef PLATFORM_X64 - return g_pSM->ToPseudoAddress(ptr); + return g_pSM->ToPseudoAddress((void*)(ptr)); #else return (cell_t)ptr; #endif @@ -158,7 +158,7 @@ inline cell_t PtrToPawnAddress(const void* ptr) { inline void* PawnAddressToPtr(cell_t addr) { #ifdef PLATFORM_X64 - return (void*)g_pSM->FromPseudoAddress(param); + return (void*)g_pSM->FromPseudoAddress(addr); #else return (void*)addr; #endif diff --git a/extension/idatamapcontainer.cpp b/extension/idatamapcontainer.cpp index b0854b4..1a59d1d 100644 --- a/extension/idatamapcontainer.cpp +++ b/extension/idatamapcontainer.cpp @@ -772,8 +772,8 @@ void IEntityDataMapInputFuncDelegate::Alloc() if (m_pInputFuncPtr) return; - uint32_t thisAddr = (uint32_t)this; - uint32_t callFuncAddr = (uint32_t)(&IEntityDataMapInputFuncDelegate::HandleInput); + intp thisAddr = (intp)this; + intp callFuncAddr = (intp)(&IEntityDataMapInputFuncDelegate::HandleInput); uint8_t funcBytes[] = { #ifdef WIN32 @@ -824,11 +824,11 @@ void IEntityDataMapInputFuncDelegate::Alloc() g_InputFuncAlloc.SetRW(m_pInputFuncPtr); #ifdef WIN32 - *((uint32_t*)(&funcBytes[11])) = thisAddr; - *((uint32_t*)(&funcBytes[16])) = callFuncAddr; + *((intp*)(&funcBytes[11])) = thisAddr; + *((intp*)(&funcBytes[16])) = callFuncAddr; #else - *((uint32_t*)(&funcBytes[14])) = thisAddr; - *((uint32_t*)(&funcBytes[19])) = callFuncAddr; + *((intp*)(&funcBytes[14])) = thisAddr; + *((intp*)(&funcBytes[19])) = callFuncAddr; #endif memcpy(m_pInputFuncPtr, funcBytes, m_iInputFuncSize); @@ -984,7 +984,7 @@ void IEntityDataMapContainer::DefineInputFunc(const char* name, fieldtype_t fiel m_pEntityInputFuncDelegates.AddToTail(pDelegate); // this shuts up the compiler - *(uint32_t*)(&(typeDesc.inputFunc)) = (uint32_t)pDelegate->m_pInputFuncPtr; + *(intp*)(&(typeDesc.inputFunc)) = (intp)pDelegate->m_pInputFuncPtr; m_vecEntityDataTypeDescriptors.AddToTail(typeDesc); } diff --git a/extension/pluginentityfactory.cpp b/extension/pluginentityfactory.cpp index caad1df..f5245fc 100644 --- a/extension/pluginentityfactory.cpp +++ b/extension/pluginentityfactory.cpp @@ -117,7 +117,7 @@ PluginFactoryEntityRecord_t* CPluginEntityFactories::FindRecord(CBaseEntity* pEn return nullptr; } - cell_t key = (cell_t)pEntity; + intp key = (intp)pEntity; if (m_Records.find(key) == m_Records.end()) { if (create) @@ -140,7 +140,7 @@ void CPluginEntityFactories::RemoveRecord(CBaseEntity* pEntity) return; } - cell_t key = (cell_t)pEntity; + intp key = (intp)pEntity; m_Records.erase(key); } diff --git a/extension/pluginentityfactory.h b/extension/pluginentityfactory.h index 33d8562..80ae25b 100644 --- a/extension/pluginentityfactory.h +++ b/extension/pluginentityfactory.h @@ -119,7 +119,7 @@ class CPluginEntityFactories : public IPluginsListener, size_t m_BaseClassSizes[ FACTORYBASECLASS_MAX ]; CUtlVector< CPluginEntityFactory* > m_Factories; - std::map> m_Records; + std::map> m_Records; std::map m_gameFactories; std::map m_pluginFactories; std::vector m_hookIds; diff --git a/hl2sdk-manifests b/hl2sdk-manifests new file mode 160000 index 0000000..6ff6531 --- /dev/null +++ b/hl2sdk-manifests @@ -0,0 +1 @@ +Subproject commit 6ff653193999c887b17a803ee537b725da19a245 From 736bb93bd0c6c668317ef078de19b47861b6231b Mon Sep 17 00:00:00 2001 From: Kenzzer Date: Fri, 26 Jan 2024 01:08:48 +0100 Subject: [PATCH 02/18] Update CI --- .github/workflows/ci-extension.yml | 13 +++++++------ .github/workflows/ci-scripting.yml | 5 ++++- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci-extension.yml b/.github/workflows/ci-extension.yml index e3fdd58..f5a9b79 100644 --- a/.github/workflows/ci-extension.yml +++ b/.github/workflows/ci-extension.yml @@ -40,13 +40,14 @@ jobs: CACHE_PATH: ${{ github.workspace }}/cache steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 name: Repository checkout with: fetch-depth: 0 + submodules: true path: CBaseNPC - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 name: Sourcemod checkout with: repository: alliedmodders/sourcemod @@ -54,21 +55,21 @@ jobs: submodules: true path: cache/sourcemod - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 name: Metamod-Source checkout with: repository: alliedmodders/metamod-source ref: ${{ env.MMSOURCE_VERSION }}-dev path: cache/metamod - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 name: AMBuild checkout with: repository: alliedmodders/ambuild ref: master path: cache/ambuild - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 name: Custom TF2 SDK checkout with: repository: TF2-DMB/hl2sdk-tf2 @@ -121,7 +122,7 @@ jobs: run: | mkdir build cd build - python ../configure.py --extension-only --enable-auto-versioning --enable-optimize --sdks=${{ join(fromJSON(env.SDKS)) }} --mms-path=${{ env.CACHE_PATH }}/metamod --hl2sdk-root=${{ env.CACHE_PATH }} --sm-path=${{ env.CACHE_PATH }}/sourcemod + python ../configure.py --extension-only --enable-auto-versioning --enable-optimize --targets x86,x86_64 --sdks=${{ join(fromJSON(env.SDKS)) }} --mms-path=${{ env.CACHE_PATH }}/metamod --hl2sdk-root=${{ env.CACHE_PATH }} --sm-path=${{ env.CACHE_PATH }}/sourcemod ambuild - name: Upload artifact diff --git a/.github/workflows/ci-scripting.yml b/.github/workflows/ci-scripting.yml index 5b50a83..d70aea2 100644 --- a/.github/workflows/ci-scripting.yml +++ b/.github/workflows/ci-scripting.yml @@ -28,7 +28,10 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + submodules: true - uses: actions/setup-python@v3 name: Setup Python 3.8 From 8aeefd4e2036da230d0335b4c9563b39d96edb9b Mon Sep 17 00:00:00 2001 From: Kenzzer Date: Tue, 6 Feb 2024 19:39:09 +0100 Subject: [PATCH 03/18] fix various sections of the ext for x64 --- extension/extension.cpp | 1 - extension/sourcesdk/baseanimating.cpp | 8 ++ extension/sourcesdk/baseentity.cpp | 6 +- extension/sourcesdk/baseentityoutput.cpp | 5 + extension/sourcesdk/nav_mesh.cpp | 19 ++-- extension/sourcesdk/nav_mesh.h | 1 - gamedata/cbasenpc.txt | 121 ++++++++++++++++------- 7 files changed, 115 insertions(+), 46 deletions(-) diff --git a/extension/extension.cpp b/extension/extension.cpp index a0cbf95..6ac1280 100644 --- a/extension/extension.cpp +++ b/extension/extension.cpp @@ -167,7 +167,6 @@ void CBaseNPCExt::OnCoreMapStart(edict_t* edictlist, int edictCount, int clientM void CBaseNPCExt::OnCoreMapEnd() { g_pBaseNPCPluginActionFactories->OnCoreMapEnd(); g_pPluginEntityFactories->OnCoreMapEnd(); - CNavMesh::OnCoreMapEnd(); } void CBaseNPCExt::OnEntityCreated(CBaseEntity* pEntity, const char* classname) { diff --git a/extension/sourcesdk/baseanimating.cpp b/extension/sourcesdk/baseanimating.cpp index a8a0e0b..1b1cf57 100644 --- a/extension/sourcesdk/baseanimating.cpp +++ b/extension/sourcesdk/baseanimating.cpp @@ -74,6 +74,13 @@ bool CBaseAnimating::Init(SourceMod::IGameConfig* config, char* error, size_t ma } uint8_t* aGetAnimationEvent = reinterpret_cast(aVal); +#ifdef PLATFORM_X64 +#ifdef WIN64 +#else + SourceHook::SetMemAccess(aGetAnimationEvent + 0xF2, sizeof(uint32_t), SH_MEM_READ | SH_MEM_WRITE | SH_MEM_EXEC); + *(uint32_t*)(aGetAnimationEvent + 0xF2) = 9999; +#endif +#else #ifdef WIN32 SourceHook::SetMemAccess(aGetAnimationEvent + 0x83, sizeof(uint32_t), SH_MEM_READ | SH_MEM_WRITE | SH_MEM_EXEC); *(uint32_t*)(aGetAnimationEvent + 0x83) = 9999; @@ -82,6 +89,7 @@ bool CBaseAnimating::Init(SourceMod::IGameConfig* config, char* error, size_t ma *(uint32_t*)(aGetAnimationEvent + 0x17E) = 9999; SourceHook::SetMemAccess(aGetAnimationEvent + 0xB3, sizeof(uint32_t), SH_MEM_READ | SH_MEM_WRITE | SH_MEM_EXEC); *(uint32_t*)(aGetAnimationEvent + 0xB3) = 9999; +#endif #endif return true; } diff --git a/extension/sourcesdk/baseentity.cpp b/extension/sourcesdk/baseentity.cpp index 8e538af..ca87fee 100644 --- a/extension/sourcesdk/baseentity.cpp +++ b/extension/sourcesdk/baseentity.cpp @@ -166,8 +166,12 @@ bool CBaseEntity::Init(SourceMod::IGameConfig* config, char* error, size_t maxle snprintf(error, maxlength, "Couldn't find offset for g_TouchTrace ptr!"); return false; } - +#ifdef PLATFORM_X64 + int32_t relativeoffset = *reinterpret_cast(addr + offset); + g_pTouchTrace = *reinterpret_cast(addr + offset + sizeof(int32_t) + relativeoffset); +#else g_pTouchTrace = *reinterpret_cast(addr + offset); +#endif } else { diff --git a/extension/sourcesdk/baseentityoutput.cpp b/extension/sourcesdk/baseentityoutput.cpp index 499e8b5..4b5a053 100644 --- a/extension/sourcesdk/baseentityoutput.cpp +++ b/extension/sourcesdk/baseentityoutput.cpp @@ -27,7 +27,12 @@ bool CBaseEntityOutput::Init(SourceMod::IGameConfig* config, char* error, size_t snprintf(error, maxlength, "Couldn't find offset for g_EntityListPool ptr!"); return false; } +#ifdef PLATFORM_X64 + int32_t relativeoffset = *reinterpret_cast(addr + offset); + g_pEntityListPool = *reinterpret_cast(addr + offset + sizeof(int32_t) + relativeoffset); +#else g_pEntityListPool = *reinterpret_cast(addr + offset); +#endif #endif } else diff --git a/extension/sourcesdk/nav_mesh.cpp b/extension/sourcesdk/nav_mesh.cpp index 18e4de9..696a4b3 100644 --- a/extension/sourcesdk/nav_mesh.cpp +++ b/extension/sourcesdk/nav_mesh.cpp @@ -37,17 +37,24 @@ bool CNavMesh::Init(SourceMod::IGameConfig* config, char* error, size_t maxlengt snprintf(error, maxlength, "Couldn't find offset for TheNavMesh ptr!"); return false; } - - CNavMesh** pTheNavMesh = *reinterpret_cast(addr + offset); - TheNavMesh = *pTheNavMesh; +#ifdef PLATFORM_X64 + int32_t relativeoffset = *reinterpret_cast(addr + offset); + TheNavMesh = **reinterpret_cast(addr + offset + sizeof(int32_t) + relativeoffset); +#else + TheNavMesh = **reinterpret_cast(addr + offset); +#endif if (!config->GetOffset("TheNavAreas", &offset) || !offset) { snprintf(error, maxlength, "Couldn't find offset for TheNavAreas ptr!"); return false; } - +#ifdef PLATFORM_X64 + relativeoffset = *reinterpret_cast(addr + offset); + pTheNavAreas = reinterpret_cast(addr + offset + sizeof(int32_t) + relativeoffset); +#else pTheNavAreas = *reinterpret_cast(addr + offset); +#endif } else { @@ -88,10 +95,6 @@ bool CNavMesh::Init(SourceMod::IGameConfig* config, char* error, size_t maxlengt return true; } -void CNavMesh::OnCoreMapEnd() -{ -} - void CNavMesh::SDK_OnUnload() { if (g_pNavMeshLoad != nullptr) diff --git a/extension/sourcesdk/nav_mesh.h b/extension/sourcesdk/nav_mesh.h index 0d73f17..2cd14f4 100644 --- a/extension/sourcesdk/nav_mesh.h +++ b/extension/sourcesdk/nav_mesh.h @@ -29,7 +29,6 @@ class CNavMesh { public: static bool Init(SourceMod::IGameConfig* config, char* error, size_t maxlength); - static void OnCoreMapEnd(); static void SDK_OnUnload(); bool IsLoaded( void ) const { return *(bool*)((uint8_t*)this + offset_m_isLoaded); } diff --git a/gamedata/cbasenpc.txt b/gamedata/cbasenpc.txt index 0a48c3b..fe0df41 100644 --- a/gamedata/cbasenpc.txt +++ b/gamedata/cbasenpc.txt @@ -7,19 +7,22 @@ // Locate CNavMesh::Load, first dword is TheNavMesh second is TheNavAreas "TheNavMesh" { - "linux" "979" "windows" "786" + "linux" "979" + "linux64" "849" } "TheNavAreas" { - "linux" "1058" "windows" "819" + "linux" "1058" + "linux64" "1008" } // Locate CBaseEntity::PhysicsMarkEntitiesAsTouching, first dword is g_TouchTrace "g_TouchTrace" { - "linux" "29" "windows" "32" + "linux" "29" + "linux64" "55" } "g_EntityListPool" { @@ -27,138 +30,164 @@ } "CNavMesh::m_isLoaded" { - "linux" "52" "windows" "52" + "linux" "52" + "linux64" "72" } "CBaseEntity::Spawn" { - "linux" "25" "windows" "24" + "linux" "25" + "linux64" "25" } "CBaseEntity::PostConstructor" { - "linux" "29" "windows" "28" + "linux" "29" + "linux64" "29" } "CBaseEntity::GetBaseAnimating" { - "linux" "53" "windows" "52" + "linux" "53" + "linux64" "53" } "CBaseEntity::IsAlive" { - "linux" "68" "windows" "67" + "linux" "68" + "linux64" "68" } "CBaseEntity::Event_Killed" { - "linux" "69" "windows" "68" + "linux64" "69" } "CBaseEntity::MyCombatCharacterPointer" { - "linux" "74" "windows" "73" + "linux" "74" + "linux64" "74" } "CBaseEntity::MyNextBotPointer" { - "linux" "75" "windows" "74" + "linux" "75" + "linux64" "75" } "CBaseEntity::Touch" { - "linux" "105" "windows" "104" + "linux" "105" + "linux64" "105" } "CBaseEntity::PhysicsSimulate" { - "linux" "110" "windows" "109" + "linux" "110" + "linux64" "110" } "CBaseEntity::UpdateOnRemove" { - "linux" "111" "windows" "110" + "linux" "111" + "linux64" "111" } "CBaseEntity::EyeAngles" { - "linux" "138" "windows" "137" + "linux" "138" + "linux64" "138" } "CBaseEntity::GetVectors" { - "linux" "143" "windows" "142" + "linux" "143" + "linux64" "143" } "CBaseEntity::WorldSpaceCenter" { - "linux" "156" "windows" "155" + "linux" "156" + "linux64" "156" } "CBaseAnimating::StudioFrameAdvance" { - "linux" "201" "windows" "200" + "linux" "201" + "linux64" "201" } "CBaseAnimating::DispatchAnimEvents" { - "linux" "213" "windows" "212" + "linux" "213" + "linux64" "213" } "CBaseAnimating::HandleAnimEvent" { - "linux" "214" "windows" "213" + "linux" "214" + "linux64" "214" } "CBaseAnimating::GetAttachment" { - "linux" "216" "windows" "215" + "linux" "216" + "linux64" "216" } "CBaseCombatCharacter::Weapon_Equip" { - "linux" "272" "windows" "271" + "linux" "272" + "linux64" "272" } "CBaseCombatCharacter::Weapon_Drop" { - "linux" "274" "windows" "273" + "linux" "274" + "linux64" "274" } "CBaseCombatCharacter::OnTakeDamage_Alive" { - "linux" "283" "windows" "282" + "linux" "283" + "linux64" "283" } "CBaseCombatCharacter::OnTakeDamage_Dying" { - "linux" "284" "windows" "283" + "linux" "284" + "linux64" "284" } "CBaseCombatCharacter::GetLastKnownArea" { - "linux" "323" "windows" "322" + "linux" "323" + "linux64" "323" } "CBaseCombatCharacter::OnNavAreaChanged" { - "linux" "327" "windows" "326" + "linux" "327" + "linux64" "327" } "CBaseCombatCharacter::UpdateLastKnownArea" { - "linux" "326" "windows" "325" + "linux" "326" + "linux64" "326" } "NextBotCombatCharacter::vtable_entries" { "windows" "338" "linux" "338" + "linux64" "338" } "NextBotGroundLocomotion::vtable_entries" { - "linux" "111" "windows" "111" + "linux" "111" + "linux64" "111" } } "Signatures" @@ -168,18 +197,21 @@ "library" "server" "windows" "\xA1\x2A\x2A\x2A\x2A\x85\xC0\x75\x2A\x8B\x0D\x2A\x2A\x2A\x2A\xF6\xC1\x01" "linux" "@_Z11TheNextBotsv" + "linux64" "@_Z11TheNextBotsv" } "CTFGameRules::ApplyOnDamageModifyRules" { "library" "server" "windows" "\x55\x8B\xEC\x81\xEC\xAC\x00\x00\x00\x56\x8B\x75\x0C" "linux" "@_ZN12CTFGameRules24ApplyOnDamageModifyRulesER15CTakeDamageInfoP11CBaseEntityb" + "linux64" "@_ZN12CTFGameRules24ApplyOnDamageModifyRulesER15CTakeDamageInfoP11CBaseEntityb" } "CTFGameRules::ApplyOnDamageAliveModifyRules" { "library" "server" "windows" "\x55\x8B\xEC\x81\xEC\x2A\x00\x00\x00\x53\x8B\x5D\x0C\x89\x2A\x2A\x56" "linux" "@_ZN12CTFGameRules29ApplyOnDamageAliveModifyRulesERK15CTakeDamageInfoP11CBaseEntityRNS_20DamageModifyExtras_tE" + "linux64" "@_ZN12CTFGameRules29ApplyOnDamageAliveModifyRulesERK15CTakeDamageInfoP11CBaseEntityRNS_20DamageModifyExtras_tE" } // Find string "Invalid navigation file.\n" "CNavMesh::Load" @@ -187,36 +219,42 @@ "library" "server" "windows" "\x55\x8B\xEC\x81\xEC\x84\x01\x00\x00\x53\x56\x8B\x35\x2A\x2A\x2A\x2A" "linux" "@_ZN8CNavMesh4LoadEv" + "linux64" "@_ZN8CNavMesh4LoadEv" } "CNavMesh::GetGroundHeight" { "library" "server" "windows" "\x53\x8B\xDC\x83\xEC\x08\x83\xE4\xF0\x83\xC4\x04\x55\x8B\x6B\x04\x89\x6C\x24\x04\x8B\xEC\x81\xEC\xFC\x00\x00\x00\x56\x6A\x00\x6A\x00\x6A\x00\x8D" "linux" "@_ZNK8CNavMesh15GetGroundHeightERK6VectorPfPS0_" + "linux64" "@_ZNK8CNavMesh15GetGroundHeightERK6VectorPfPS0_" } "CTraceFilterSimple::ShouldHitEntity" { "library" "server" "windows" "\x55\x8B\xEC\x53\x8B\x5D\x0C\x56\x8B\x75\x08\x57\x53\x56" "linux" "@_ZN18CTraceFilterSimple15ShouldHitEntityEP13IHandleEntityi" + "linux64" "@_ZN18CTraceFilterSimple15ShouldHitEntityEP13IHandleEntityi" } "__GetAnimationEvent__" { "library" "server" "windows" "\x55\x8B\xEC\x53\x56\x8B\x75\x08\x85\xF6\x0F\x84\x2A\x2A\x2A\x2A\x8B\xCE\xE8\x2A\x2A\x2A\x2A" "linux" "@_Z17GetAnimationEventP10CStudioHdriP11animevent_tffi" + "linux64" "@_Z17GetAnimationEventP10CStudioHdriP11animevent_tffi" } "Studio_LookupSequence" { "library" "server" "windows" "\x55\x8B\xEC\x56\x8B\x75\x08\x85\xF6\x75\x2A\x33\xC0\x5E\x5D\xC3\x8B\xCE\xE8\x2A\x2A\x2A\x2A\x84\xC0\x74\x2A\x53" "linux" "@_Z14LookupSequenceP10CStudioHdrPKc" + "linux64" "@_Z14LookupSequenceP10CStudioHdrPKc" } "Studio_SelectWeightedSequence" { "library" "server" "windows" "\x55\x8B\xEC\x56\x8B\x75\x08\x85\xF6\x75\x2A\x33\xC0\x5E\x5D\xC3\x8B\xCE\xE8\x2A\x2A\x2A\x2A\x84\xC0\x74\x2A\x8B\xCE" "linux" "@_Z22SelectWeightedSequenceP10CStudioHdrii" + "linux64" "@_Z22SelectWeightedSequenceP10CStudioHdrii" } // Find "placementOrigin" first subroutine call below it "Studio_FindAttachment" @@ -224,6 +262,7 @@ "library" "server" "windows" "\x55\x8B\xEC\x53\x56\x57\x8B\x7D\x08\x85\xFF\x74\x2A\x8B\xCF" "linux" "@_Z21Studio_FindAttachmentPK10CStudioHdrPKc" + "linux64" "@_Z21Studio_FindAttachmentPK10CStudioHdrPKc" } // Bytes sequence search "00 00 C0 00", go to the only subroutine that uses that number with 'and' & 'cmp' "SimThink_EntityChanged" @@ -231,6 +270,7 @@ "library" "server" "windows" "\x55\x8B\xEC\x56\x57\x8B\x7D\x08\x8B\xF1\xF6\x87\x3C\x01\x00\x00\x01" "linux" "@_Z22SimThink_EntityChangedP11CBaseEntity" + "linux64" "@_Z22SimThink_EntityChangedP11CBaseEntity" } // Find ".?AVCRallyPoint@@" to get to CRallyPoint's type descriptor -> complete object locator -> vtable // goto xref to vtable to enter CRallyPoint's constructor @@ -240,6 +280,7 @@ "library" "server" "windows" "\x55\x8B\xEC\x83\xEC\x14\x53\x56\x8B\xF1\x57\x8D\x2A\x2A\xC7\x06" "linux" "@_ZN11CBaseEntityC2Eb" + "linux64" "@_ZN11CBaseEntityC2Eb" } // Find "add 0x%p: %s-%s (%d-%d) [%d in play, %d max]\n" to find CBaseEntity::PhysicsMarkEntityAsTouched // jump to the function calling this one, there can be only one and it's CBaseEntity::PhysicsMarkEntitiesAsTouching @@ -248,6 +289,7 @@ "library" "server" "windows" "\x55\x8B\xEC\x56\x8B\x75\x0C\x57\x8B\xF9\xB9\x2A\x2A\x2A\x2A\x56\xE8\x2A\x2A\x2A\x2A\xF3\x0F\x10\x46\x38\x8B\xCF\xF3\x0F\x11\x05\x2A\x2A\x2A\x2A\x8B\x46\x3C\xA3\x2A\x2A\x2A\x2A\x8B\x46\x40\xA3\x2A\x2A\x2A\x2A\x8B\x46\x44\xA3\x2A\x2A\x2A\x2A\x66\x8B\x46\x48\x66\xA3\x2A\x2A\x2A\x2A\x8B\x46\x4C\xA3\x2A\x2A\x2A\x2A\x8B\x46\x50\x8B\x75\x08\x56\xA3\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A" "linux" "@_ZN11CBaseEntity29PhysicsMarkEntitiesAsTouchingEPS_R10CGameTrace" + "linux64" "@_ZN11CBaseEntity29PhysicsMarkEntitiesAsTouchingEPS_R10CGameTrace" } // Find "m_CalcAbsolutePositionMutex" to find CBaseEntity::CalcAbsolutePosition "CBaseEntity::CalcAbsolutePosition" @@ -255,18 +297,14 @@ "library" "server" "windows" "\x55\x8B\xEC\x81\xEC\x80\x00\x00\x00\x56\x8B\xF1\x8B\x86\x3C\x01\x00\x00" "linux" "@_ZN11CBaseEntity20CalcAbsolutePositionEv" + "linux64" "@_ZN11CBaseEntity20CalcAbsolutePositionEv" } "CBaseEntity::InvalidatePhysicsRecursive" { "library" "server" "windows" "\x55\x8B\xEC\x53\x8B\x5D\x08\x56\x8B\xF3\x83\xE6\x04" "linux" "@_ZN11CBaseEntity26InvalidatePhysicsRecursiveEi" - } - "CBaseEntity::SetGroundEntity" - { - "library" "server" - "windows" "" - "linux" "@_ZN11CBaseEntity15SetGroundEntityEPS_" + "linux64" "@_ZN11CBaseEntity26InvalidatePhysicsRecursiveEi" } // Find string "CBaseEntity::TakeDamage: with inputInfo.GetDamageForce() == vec3_origin\n" "CBaseEntity::TakeDamage" @@ -274,6 +312,7 @@ "library" "server" "windows" "\x55\x8B\xEC\x81\xEC\x98\x00\x00\x00\x53\x8B\xD9" "linux" "@_ZN11CBaseEntity10TakeDamageERK15CTakeDamageInfo" + "linux64" "@_ZN11CBaseEntity10TakeDamageERK15CTakeDamageInfo" } // "g_EntityListPool" "g_EntityListPool" @@ -281,48 +320,56 @@ "library" "server" "windows" "\x6A\x00\x68\x2A\x2A\x2A\x2A\x6A\x01\x68\x00\x02\x00\x00\x6A\x1C" "linux" "@g_EntityListPool" + "linux64" "@g_EntityListPool" } "CBaseAnimating::SetPoseParameter" { "library" "server" "windows" "\x55\x8B\xEC\x8B\x45\x08\xD9\x45\x10" "linux" "@_ZN14CBaseAnimating16SetPoseParameterEP10CStudioHdrif" + "linux64" "@_ZN14CBaseAnimating16SetPoseParameterEP10CStudioHdrif" } "CBaseAnimating::GetPoseParameter" { "library" "server" "windows" "\x55\x8B\xEC\x56\x8B\xF1\x57\x80\xBE\x69\x03\x00\x00\x00\x75\x2A\x83\xBE\x98\x04\x00\x00\x00\x75\x2A\xE8\x2A\x2A\x2A\x2A\x85\xC0\x74\x2A\x8B\xCE\xE8\x2A\x2A\x2A\x2A\x8B\xBE\x98\x04\x00\x00" "linux" "@_ZN14CBaseAnimating16GetPoseParameterEi" + "linux64" "@_ZN14CBaseAnimating16GetPoseParameterEi" } "CBaseAnimating::LookupPoseParameter" { "library" "server" "windows" "\x55\x8B\xEC\x57\x8B\x7D\x08\x85\xFF\x75\x2A\x33\xC0\x5F\x5D\xC2\x08\x00" "linux" "@_ZN14CBaseAnimating19LookupPoseParameterEP10CStudioHdrPKc" + "linux64" "@_ZN14CBaseAnimating19LookupPoseParameterEP10CStudioHdrPKc" } "CBaseAnimating::SequenceDuration" { "library" "server" "windows" "\x55\x8B\xEC\x56\x8B\x75\x08\x57\x8B\xF9\x85\xF6\x75\x2A\x8B\x47\x5C" "linux" "@_ZN14CBaseAnimating16SequenceDurationEP10CStudioHdri" + "linux64" "@_ZN14CBaseAnimating16SequenceDurationEP10CStudioHdri" } "CBaseAnimating::ResetSequence" { "library" "server" "windows" "\x55\x8B\xEC\xA1\x2A\x2A\x2A\x2A\x53\x56\x57\x83\x78\x30\x00\x8B\xD9\x8B\x7D\x08" "linux" "@_ZN14CBaseAnimating13ResetSequenceEi" + "linux64" "@_ZN14CBaseAnimating13ResetSequenceEi" } "NextBotGroundLocomotion::NextBotGroundLocomotion" { "library" "server" "windows" "\x55\x8B\xEC\x56\xFF\x75\x08\x8B\xF1\xE8\x2A\x2A\x2A\x2A\xC7\x06\x2A\x2A\x2A\x2A\x8B\xC6\xC7\x86\xB4\x00\x00\x00\xFF\xFF\xFF\xFF" "linux" "@_ZN23NextBotGroundLocomotionC2EP8INextBot" + "linux64" "@_ZN23NextBotGroundLocomotionC2EP8INextBot" } "NextBotCombatCharacter::NextBotCombatCharacter" { "library" "server" "windows" "\x56\x57\x8B\xF9\xE8\x2A\x2A\x2A\x2A\x8D\x8F\x74\x08\x00\x00" "linux" "@_ZN22NextBotCombatCharacterC2Ev" + "linux64" "@_ZN22NextBotCombatCharacterC2Ev" } } "Addresses" @@ -337,6 +384,10 @@ { "signature" "__GetAnimationEvent__" } + "linux64" + { + "signature" "__GetAnimationEvent__" + } } } } From 441e2f24c7775435302ad70a12b14badd90629b2 Mon Sep 17 00:00:00 2001 From: Kenzzer Date: Tue, 6 Feb 2024 19:39:55 +0100 Subject: [PATCH 04/18] update datacontainer --- extension/idatamapcontainer.cpp | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/extension/idatamapcontainer.cpp b/extension/idatamapcontainer.cpp index 1a59d1d..909dc52 100644 --- a/extension/idatamapcontainer.cpp +++ b/extension/idatamapcontainer.cpp @@ -775,7 +775,21 @@ void IEntityDataMapInputFuncDelegate::Alloc() intp thisAddr = (intp)this; intp callFuncAddr = (intp)(&IEntityDataMapInputFuncDelegate::HandleInput); - uint8_t funcBytes[] = { + uint8_t funcBytes[] = { +#ifdef PLATFORM_X64 +#ifdef WIN64 +#else + // (IEntityDataMapInputFuncDelegate* pDelegate, CBaseEntity* pEntity, inputdata_t &data) + // this::(inputdata_t &) + // RDI, RSI, RDX, RCX, R8, R9 + 0x48, 0x89, 0xF2, // mov RDX, RSI - 3rd arg + 0x48, 0x89, 0xFE, // mov RSI, RDI + 0x48, 0xBF, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // mov rdi, thisAddr + 0x48, 0xB9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // mov r9, callFuncAddr + 0x41, 0xFF, 0xD1, // call r9 + 0xC3 // ret +#endif +#else #ifdef WIN32 // MSVC __thiscall 0x55, // push ebp @@ -813,6 +827,7 @@ void IEntityDataMapInputFuncDelegate::Alloc() 0x89, 0xEC, // mov esp, ebp 0x5D, // pop ebp 0xC3 // ret +#endif #endif }; @@ -823,6 +838,13 @@ void IEntityDataMapInputFuncDelegate::Alloc() { g_InputFuncAlloc.SetRW(m_pInputFuncPtr); +#ifdef PLATFORM_X64 +#ifdef WIN64 +#else + *((intp*)(&funcBytes[8])) = thisAddr; + *((intp*)(&funcBytes[18])) = callFuncAddr; +#endif +#else #ifdef WIN32 *((intp*)(&funcBytes[11])) = thisAddr; *((intp*)(&funcBytes[16])) = callFuncAddr; @@ -830,7 +852,7 @@ void IEntityDataMapInputFuncDelegate::Alloc() *((intp*)(&funcBytes[14])) = thisAddr; *((intp*)(&funcBytes[19])) = callFuncAddr; #endif - +#endif memcpy(m_pInputFuncPtr, funcBytes, m_iInputFuncSize); g_InputFuncAlloc.SetRE(m_pInputFuncPtr); From d13420dc36c21ec9cd2c25fe112081cede057b35 Mon Sep 17 00:00:00 2001 From: KitRifty Date: Tue, 6 Feb 2024 18:46:08 +0000 Subject: [PATCH 05/18] Update manifests submodule Add missing SDK_OnMetamodCreateInterface definition --- extension/smsdk_ext.cpp | 5 +++++ hl2sdk-manifests | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/extension/smsdk_ext.cpp b/extension/smsdk_ext.cpp index 496ec6a..9ecbd19 100644 --- a/extension/smsdk_ext.cpp +++ b/extension/smsdk_ext.cpp @@ -457,6 +457,11 @@ const char *SDKExtension::GetVersion() return GetExtensionVerString(); } +METAMOD_PLUGIN *SDKExtension::SDK_OnMetamodCreateInterface(const MetamodVersionInfo *mvi, const MetamodLoaderInfo *mli) +{ + return this; +} + bool SDKExtension::SDK_OnMetamodLoad(ISmmAPI *ismm, char *error, size_t maxlength, bool late) { return true; diff --git a/hl2sdk-manifests b/hl2sdk-manifests index 6ff6531..22f699a 160000 --- a/hl2sdk-manifests +++ b/hl2sdk-manifests @@ -1 +1 @@ -Subproject commit 6ff653193999c887b17a803ee537b725da19a245 +Subproject commit 22f699a941093d9d68c1f647c7c545ec346d0ee3 From 230846377e5091c2b9c2d187c21d395a8f006376 Mon Sep 17 00:00:00 2001 From: KitRifty Date: Tue, 6 Feb 2024 19:02:19 +0000 Subject: [PATCH 06/18] Fix -Wno-implicit-exception-spec-mismatch flag not being applied --- AMBuildScript | 4 +- extension/AMBuilder | 2 +- extension/smsdk_ext.cpp | 480 ---------------------------------------- 3 files changed, 3 insertions(+), 483 deletions(-) delete mode 100644 extension/smsdk_ext.cpp diff --git a/AMBuildScript b/AMBuildScript index 9cc3443..de1f29b 100644 --- a/AMBuildScript +++ b/AMBuildScript @@ -267,8 +267,8 @@ class ExtensionConfig(object): '-fpermissive' ] - have_gcc = cxx.vendor == 'gcc' - have_clang = cxx.vendor == 'clang' + have_gcc = cxx.family == 'gcc' + have_clang = cxx.family == 'clang' if cxx.version >= 'clang-3.9' or cxx.version == 'clang-3.4' or cxx.version > 'apple-clang-6.0': cxx.cxxflags += ['-Wno-expansion-to-defined'] if cxx.version == 'clang-3.9' or cxx.version == 'apple-clang-8.0': diff --git a/extension/AMBuilder b/extension/AMBuilder index d7d0972..1f68559 100644 --- a/extension/AMBuilder +++ b/extension/AMBuilder @@ -67,7 +67,7 @@ project.sources = [ 'natives/nextbotplayer.cpp', 'natives/tf/nav.cpp', 'natives/tf/nav/area.cpp', - 'smsdk_ext.cpp', + os.path.join(Extension.sm_root, 'public/smsdk_ext.cpp'), os.path.join(Extension.sm_root, 'public/CDetour/detours.cpp'), os.path.join(Extension.sm_root, 'public/asm/asm.c'), os.path.join(Extension.sm_root, 'public/libudis86/decode.c'), diff --git a/extension/smsdk_ext.cpp b/extension/smsdk_ext.cpp deleted file mode 100644 index 9ecbd19..0000000 --- a/extension/smsdk_ext.cpp +++ /dev/null @@ -1,480 +0,0 @@ -/** - * vim: set ts=4 sw=4 tw=99 noet: - * ============================================================================= - * SourceMod Base Extension Code - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program 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 - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ - -#include -#include -#include "smsdk_ext.h" -#include "am-string.h" - -/** - * @file smsdk_ext.cpp - * @brief Contains wrappers for making Extensions easier to write. - */ - -IExtension *myself = NULL; /**< Ourself */ -IShareSys *g_pShareSys = NULL; /**< Share system */ -IShareSys *sharesys = NULL; /**< Share system */ -ISourceMod *g_pSM = NULL; /**< SourceMod helpers */ -ISourceMod *smutils = NULL; /**< SourceMod helpers */ - -#if defined SMEXT_ENABLE_FORWARDSYS -IForwardManager *g_pForwards = NULL; /**< Forward system */ -IForwardManager *forwards = NULL; /**< Forward system */ -#endif -#if defined SMEXT_ENABLE_HANDLESYS -IHandleSys *g_pHandleSys = NULL; /**< Handle system */ -IHandleSys *handlesys = NULL; /**< Handle system */ -#endif -#if defined SMEXT_ENABLE_PLAYERHELPERS -IPlayerManager *playerhelpers = NULL; /**< Player helpers */ -#endif //SMEXT_ENABLE_PLAYERHELPERS -#if defined SMEXT_ENABLE_DBMANAGER -IDBManager *dbi = NULL; /**< DB Manager */ -#endif //SMEXT_ENABLE_DBMANAGER -#if defined SMEXT_ENABLE_GAMECONF -IGameConfigManager *gameconfs = NULL; /**< Game config manager */ -#endif //SMEXT_ENABLE_DBMANAGER -#if defined SMEXT_ENABLE_MEMUTILS -IMemoryUtils *memutils = NULL; -#endif //SMEXT_ENABLE_DBMANAGER -#if defined SMEXT_ENABLE_GAMEHELPERS -IGameHelpers *gamehelpers = NULL; -#endif -#if defined SMEXT_ENABLE_TIMERSYS -ITimerSystem *timersys = NULL; -#endif -#if defined SMEXT_ENABLE_ADTFACTORY -IADTFactory *adtfactory = NULL; -#endif -#if defined SMEXT_ENABLE_THREADER -IThreader *threader = NULL; -#endif -#if defined SMEXT_ENABLE_LIBSYS -ILibrarySys *libsys = NULL; -#endif -#if defined SMEXT_ENABLE_PLUGINSYS -SourceMod::IPluginManager *plsys; -#endif -#if defined SMEXT_ENABLE_MENUS -IMenuManager *menus = NULL; -#endif -#if defined SMEXT_ENABLE_ADMINSYS -IAdminSystem *adminsys = NULL; -#endif -#if defined SMEXT_ENABLE_TEXTPARSERS -ITextParsers *textparsers = NULL; -#endif -#if defined SMEXT_ENABLE_USERMSGS -IUserMessages *usermsgs = NULL; -#endif -#if defined SMEXT_ENABLE_TRANSLATOR -ITranslator *translator = NULL; -#endif -#if defined SMEXT_ENABLE_ROOTCONSOLEMENU -IRootConsole *rootconsole = NULL; -#endif - -/** Exports the main interface */ -PLATFORM_EXTERN_C IExtensionInterface *GetSMExtAPI() -{ - return g_pExtensionIface; -} - -SDKExtension::SDKExtension() -{ -#if defined SMEXT_CONF_METAMOD - m_SourceMMLoaded = false; - m_WeAreUnloaded = false; - m_WeGotPauseChange = false; -#endif -} - -bool SDKExtension::OnExtensionLoad(IExtension *me, IShareSys *sys, char *error, size_t maxlength, bool late) -{ - g_pShareSys = sharesys = sys; - myself = me; - -#if defined SMEXT_CONF_METAMOD - m_WeAreUnloaded = true; - - if (!m_SourceMMLoaded) - { - if (error) - { - ke::SafeStrcpy(error, maxlength, "Metamod attach failed"); - } - return false; - } -#endif - SM_GET_IFACE(SOURCEMOD, g_pSM); - smutils = g_pSM; -#if defined SMEXT_ENABLE_HANDLESYS - SM_GET_IFACE(HANDLESYSTEM, g_pHandleSys); - handlesys = g_pHandleSys; -#endif -#if defined SMEXT_ENABLE_FORWARDSYS - SM_GET_IFACE(FORWARDMANAGER, g_pForwards); - forwards = g_pForwards; -#endif -#if defined SMEXT_ENABLE_PLAYERHELPERS - SM_GET_IFACE(PLAYERMANAGER, playerhelpers); -#endif -#if defined SMEXT_ENABLE_DBMANAGER - SM_GET_IFACE(DBI, dbi); -#endif -#if defined SMEXT_ENABLE_GAMECONF - SM_GET_IFACE(GAMECONFIG, gameconfs); -#endif -#if defined SMEXT_ENABLE_MEMUTILS - SM_GET_IFACE(MEMORYUTILS, memutils); -#endif -#if defined SMEXT_ENABLE_GAMEHELPERS - SM_GET_IFACE(GAMEHELPERS, gamehelpers); -#endif -#if defined SMEXT_ENABLE_TIMERSYS - SM_GET_IFACE(TIMERSYS, timersys); -#endif -#if defined SMEXT_ENABLE_ADTFACTORY - SM_GET_IFACE(ADTFACTORY, adtfactory); -#endif -#if defined SMEXT_ENABLE_THREADER - SM_GET_IFACE(THREADER, threader); -#endif -#if defined SMEXT_ENABLE_LIBSYS - SM_GET_IFACE(LIBRARYSYS, libsys); -#endif -#if defined SMEXT_ENABLE_PLUGINSYS - SM_GET_IFACE(PLUGINSYSTEM, plsys); -#endif -#if defined SMEXT_ENABLE_MENUS - SM_GET_IFACE(MENUMANAGER, menus); -#endif -#if defined SMEXT_ENABLE_ADMINSYS - SM_GET_IFACE(ADMINSYS, adminsys); -#endif -#if defined SMEXT_ENABLE_TEXTPARSERS - SM_GET_IFACE(TEXTPARSERS, textparsers); -#endif -#if defined SMEXT_ENABLE_USERMSGS - SM_GET_IFACE(USERMSGS, usermsgs); -#endif -#if defined SMEXT_ENABLE_TRANSLATOR - SM_GET_IFACE(TRANSLATOR, translator); -#endif -#if defined SMEXT_ENABLE_ROOTCONSOLEMENU - SM_GET_IFACE(ROOTCONSOLE, rootconsole); -#endif - - if (SDK_OnLoad(error, maxlength, late)) - { -#if defined SMEXT_CONF_METAMOD - m_WeAreUnloaded = true; -#endif - return true; - } - - return false; -} - -bool SDKExtension::IsMetamodExtension() -{ -#if defined SMEXT_CONF_METAMOD - return true; -#else - return false; -#endif -} - -void SDKExtension::OnExtensionPauseChange(bool state) -{ -#if defined SMEXT_CONF_METAMOD - m_WeGotPauseChange = true; -#endif - SDK_OnPauseChange(state); -} - -void SDKExtension::OnExtensionsAllLoaded() -{ - SDK_OnAllLoaded(); -} - -void SDKExtension::OnExtensionUnload() -{ -#if defined SMEXT_CONF_METAMOD - m_WeAreUnloaded = true; -#endif - SDK_OnUnload(); -} - -void SDKExtension::OnDependenciesDropped() -{ - SDK_OnDependenciesDropped(); -} - -const char *SDKExtension::GetExtensionAuthor() -{ - return SMEXT_CONF_AUTHOR; -} - -const char *SDKExtension::GetExtensionDateString() -{ - return SMEXT_CONF_DATESTRING; -} - -const char *SDKExtension::GetExtensionDescription() -{ - return SMEXT_CONF_DESCRIPTION; -} - -const char *SDKExtension::GetExtensionVerString() -{ - return SMEXT_CONF_VERSION; -} - -const char *SDKExtension::GetExtensionName() -{ - return SMEXT_CONF_NAME; -} - -const char *SDKExtension::GetExtensionTag() -{ - return SMEXT_CONF_LOGTAG; -} - -const char *SDKExtension::GetExtensionURL() -{ - return SMEXT_CONF_URL; -} - -bool SDKExtension::SDK_OnLoad(char *error, size_t maxlength, bool late) -{ - return true; -} - -void SDKExtension::SDK_OnUnload() -{ -} - -void SDKExtension::SDK_OnPauseChange(bool paused) -{ -} - -void SDKExtension::SDK_OnAllLoaded() -{ -} - -void SDKExtension::SDK_OnDependenciesDropped() -{ -} - -#if defined SMEXT_CONF_METAMOD - -PluginId g_PLID = 0; /**< Metamod plugin ID */ -ISmmPlugin *g_PLAPI = NULL; /**< Metamod plugin API */ -SourceHook::ISourceHook *g_SHPtr = NULL; /**< SourceHook pointer */ -ISmmAPI *g_SMAPI = NULL; /**< SourceMM API pointer */ - -#ifndef META_NO_HL2SDK -IVEngineServer *engine = NULL; /**< IVEngineServer pointer */ -IServerGameDLL *gamedll = NULL; /**< IServerGameDLL pointer */ -#endif - -/** Exposes the extension to Metamod */ -SMM_API void *PL_EXPOSURE(const char *name, int *code) -{ -#if defined METAMOD_PLAPI_VERSION - if (name && !strcmp(name, METAMOD_PLAPI_NAME)) -#else - if (name && !strcmp(name, PLAPI_NAME)) -#endif - { - if (code) - { - *code = META_IFACE_OK; - } - return static_cast(g_pExtensionIface); - } - - if (code) - { - *code = META_IFACE_FAILED; - } - - return NULL; -} - -bool SDKExtension::Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen, bool late) -{ - PLUGIN_SAVEVARS(); - -#ifndef META_NO_HL2SDK -#if !defined METAMOD_PLAPI_VERSION - GET_V_IFACE_ANY(serverFactory, gamedll, IServerGameDLL, INTERFACEVERSION_SERVERGAMEDLL); - GET_V_IFACE_CURRENT(engineFactory, engine, IVEngineServer, INTERFACEVERSION_VENGINESERVER); -#else - GET_V_IFACE_ANY(GetServerFactory, gamedll, IServerGameDLL, INTERFACEVERSION_SERVERGAMEDLL); -#if SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_SDK2013 - // Shim to avoid hooking shims - engine = (IVEngineServer *) ismm->GetEngineFactory()("VEngineServer023", nullptr); - if (!engine) - { - engine = (IVEngineServer *) ismm->GetEngineFactory()("VEngineServer022", nullptr); - if (!engine) - { - engine = (IVEngineServer *) ismm->GetEngineFactory()("VEngineServer021", nullptr); - if (!engine) - { - if (error && maxlen) - { - ismm->Format(error, maxlen, "Could not find interface: VEngineServer023 or VEngineServer022"); - } - return false; - } - } - } -#else - GET_V_IFACE_CURRENT(GetEngineFactory, engine, IVEngineServer, INTERFACEVERSION_VENGINESERVER); -#endif // TF2 / CSS / DODS / HL2DM / SDK2013 -#endif // !METAMOD_PLAPI_VERSION -#endif //META_NO_HL2SDK - - m_SourceMMLoaded = true; - - return SDK_OnMetamodLoad(ismm, error, maxlen, late); -} - -bool SDKExtension::Unload(char *error, size_t maxlen) -{ - if (!m_WeAreUnloaded) - { - if (error) - { - ke::SafeStrcpy(error, maxlen, "This extension must be unloaded by SourceMod."); - } - return false; - } - - return SDK_OnMetamodUnload(error, maxlen); -} - -bool SDKExtension::Pause(char *error, size_t maxlen) -{ - if (!m_WeGotPauseChange) - { - if (error) - { - ke::SafeStrcpy(error, maxlen, "This extension must be paused by SourceMod."); - } - return false; - } - - m_WeGotPauseChange = false; - - return SDK_OnMetamodPauseChange(true, error, maxlen); -} - -bool SDKExtension::Unpause(char *error, size_t maxlen) -{ - if (!m_WeGotPauseChange) - { - if (error) - { - ke::SafeStrcpy(error, maxlen, "This extension must be unpaused by SourceMod."); - } - return false; - } - - m_WeGotPauseChange = false; - - return SDK_OnMetamodPauseChange(false, error, maxlen); -} - -const char *SDKExtension::GetAuthor() -{ - return GetExtensionAuthor(); -} - -const char *SDKExtension::GetDate() -{ - return GetExtensionDateString(); -} - -const char *SDKExtension::GetDescription() -{ - return GetExtensionDescription(); -} - -const char *SDKExtension::GetLicense() -{ - return SMEXT_CONF_LICENSE; -} - -const char *SDKExtension::GetLogTag() -{ - return GetExtensionTag(); -} - -const char *SDKExtension::GetName() -{ - return GetExtensionName(); -} - -const char *SDKExtension::GetURL() -{ - return GetExtensionURL(); -} - -const char *SDKExtension::GetVersion() -{ - return GetExtensionVerString(); -} - -METAMOD_PLUGIN *SDKExtension::SDK_OnMetamodCreateInterface(const MetamodVersionInfo *mvi, const MetamodLoaderInfo *mli) -{ - return this; -} - -bool SDKExtension::SDK_OnMetamodLoad(ISmmAPI *ismm, char *error, size_t maxlength, bool late) -{ - return true; -} - -bool SDKExtension::SDK_OnMetamodUnload(char *error, size_t maxlength) -{ - return true; -} - -bool SDKExtension::SDK_OnMetamodPauseChange(bool paused, char *error, size_t maxlength) -{ - return true; -} - -#endif \ No newline at end of file From 31064b64ec5692bd10b304fefb96f74603387b12 Mon Sep 17 00:00:00 2001 From: KitRifty Date: Tue, 6 Feb 2024 19:30:59 +0000 Subject: [PATCH 07/18] Use MM 1.12 and SM 1.12 (master) --- .github/workflows/ci-extension.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci-extension.yml b/.github/workflows/ci-extension.yml index f5a9b79..f90a6e9 100644 --- a/.github/workflows/ci-extension.yml +++ b/.github/workflows/ci-extension.yml @@ -35,8 +35,8 @@ jobs: # We currently only support tf2 - however when we support more sdks # we will have to deal with the special case of our custom tf2 + AM's sdks SDKS: '["tf2"]' - MMSOURCE_VERSION: '1.10' - SOURCEMOD_VERSION: '1.11' + MMSOURCE_VERSION: '1.12-dev' + SOURCEMOD_VERSION: '35ac74c7a7243e17a3aa2338b116eaa8a0a9ccdc' CACHE_PATH: ${{ github.workspace }}/cache steps: @@ -51,7 +51,7 @@ jobs: name: Sourcemod checkout with: repository: alliedmodders/sourcemod - ref: ${{ env.SOURCEMOD_VERSION }}-dev + ref: ${{ env.SOURCEMOD_VERSION }} submodules: true path: cache/sourcemod @@ -59,7 +59,7 @@ jobs: name: Metamod-Source checkout with: repository: alliedmodders/metamod-source - ref: ${{ env.MMSOURCE_VERSION }}-dev + ref: ${{ env.MMSOURCE_VERSION }} path: cache/metamod - uses: actions/checkout@v4 From 1b3954bea4ae678fb828ab857200a2e999836413 Mon Sep 17 00:00:00 2001 From: KitRifty Date: Tue, 6 Feb 2024 20:30:15 +0000 Subject: [PATCH 08/18] Set m_scriptInstance type to HSCRIPT Don't omit frame pointer --- AMBuildScript | 3 +++ extension/sourcesdk/NextBot/NextBotComponentInterface.cpp | 2 +- extension/sourcesdk/NextBot/NextBotComponentInterface.h | 6 +++++- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/AMBuildScript b/AMBuildScript index de1f29b..b60221b 100644 --- a/AMBuildScript +++ b/AMBuildScript @@ -304,6 +304,9 @@ class ExtensionConfig(object): if builder.options.opt == '1': cxx.cflags += ['-O3'] + # Don't omit the frame pointer. + cxx.cflags += ['-fno-omit-frame-pointer'] + def configure_msvc(self, cxx): if builder.options.debug == '1': cxx.cflags += ['/MTd'] diff --git a/extension/sourcesdk/NextBot/NextBotComponentInterface.cpp b/extension/sourcesdk/NextBot/NextBotComponentInterface.cpp index 58cba6f..5790c04 100644 --- a/extension/sourcesdk/NextBot/NextBotComponentInterface.cpp +++ b/extension/sourcesdk/NextBot/NextBotComponentInterface.cpp @@ -23,7 +23,7 @@ bool INextBotComponent::Init(SourceMod::IGameConfig* config, char* error, size_t INextBotComponent::INextBotComponent(INextBot *bot) { #if SOURCE_ENGINE == SE_TF2 - m_scriptInstance = 0; + m_scriptInstance = nullptr; #endif m_curInterval = TICK_INTERVAL; diff --git a/extension/sourcesdk/NextBot/NextBotComponentInterface.h b/extension/sourcesdk/NextBot/NextBotComponentInterface.h index 7f6962e..b1fc989 100644 --- a/extension/sourcesdk/NextBot/NextBotComponentInterface.h +++ b/extension/sourcesdk/NextBot/NextBotComponentInterface.h @@ -4,6 +4,10 @@ #include "helpers.h" #include "NextBotEventResponderInterface.h" +#if SOURCE_ENGINE == SE_TF2 +FORWARD_DECLARE_HANDLE(HSCRIPT); +#endif + class INextBot; class Path; class CGameTrace; @@ -61,7 +65,7 @@ class INextBotComponent : public INextBotEventResponder INextBotComponent *m_nextComponent; #if SOURCE_ENGINE == SE_TF2 - std::int32_t m_scriptInstance; + HSCRIPT m_scriptInstance; #endif public: From 81e304288cab93a1c688baa876b5608b5c39f6ea Mon Sep 17 00:00:00 2001 From: KitRifty Date: Sun, 11 Feb 2024 22:51:03 +0000 Subject: [PATCH 09/18] Fix entity input functions crashing on invocation - In x64, there's a tendency for jmp calls to be used to go to another function instead of using call. There's probably some stack fuckery going on here since call pushes the return address on the stack. However, since we don't need to use the stack, we can substitute this with a simple jmp reg call instead, which also fixes the crash. --- extension/idatamapcontainer.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/extension/idatamapcontainer.cpp b/extension/idatamapcontainer.cpp index 909dc52..4457173 100644 --- a/extension/idatamapcontainer.cpp +++ b/extension/idatamapcontainer.cpp @@ -782,12 +782,11 @@ void IEntityDataMapInputFuncDelegate::Alloc() // (IEntityDataMapInputFuncDelegate* pDelegate, CBaseEntity* pEntity, inputdata_t &data) // this::(inputdata_t &) // RDI, RSI, RDX, RCX, R8, R9 - 0x48, 0x89, 0xF2, // mov RDX, RSI - 3rd arg - 0x48, 0x89, 0xFE, // mov RSI, RDI - 0x48, 0xBF, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // mov rdi, thisAddr - 0x48, 0xB9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // mov r9, callFuncAddr - 0x41, 0xFF, 0xD1, // call r9 - 0xC3 // ret + 0x48, 0x89, 0xF2, // mov RDX, RSI - 3rd arg + 0x48, 0x89, 0xFE, // mov RSI, RDI + 0x48, 0xBF, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // movabs rdi, thisAddr + 0x49, 0xB9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // movabs r9, callFuncAddr + 0x41, 0xFF, 0xE1 // jmp r9 #endif #else #ifdef WIN32 From 95d0fcd791179a36e5e9554894c743dcdbfc6019 Mon Sep 17 00:00:00 2001 From: KitRifty Date: Mon, 12 Feb 2024 19:49:18 -0800 Subject: [PATCH 10/18] =?UTF-8?q?=F0=9F=AA=9F=20Update=20gamedata=20+=20fi?= =?UTF-8?q?x=20compilation=20Untested,=20but=20probably=20correct=20Add=20?= =?UTF-8?q?more=20comments=20on=20getting=20sigs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AMBuildScript | 1 - extension/idatamapcontainer.cpp | 16 +++-- gamedata/cbasenpc.txt | 110 +++++++++++++++++++++++++++++++- 3 files changed, 119 insertions(+), 8 deletions(-) diff --git a/AMBuildScript b/AMBuildScript index b60221b..ed0a509 100644 --- a/AMBuildScript +++ b/AMBuildScript @@ -328,7 +328,6 @@ class ExtensionConfig(object): '/std:c++17' ] cxx.linkflags += [ - '/MACHINE:X86', 'kernel32.lib', 'user32.lib', 'gdi32.lib', diff --git a/extension/idatamapcontainer.cpp b/extension/idatamapcontainer.cpp index 4457173..f72883c 100644 --- a/extension/idatamapcontainer.cpp +++ b/extension/idatamapcontainer.cpp @@ -188,7 +188,7 @@ void IDataMapContainer::EndDataDesc() void IDataMapContainer::DefineField(const char* name, fieldtype_t fieldType, unsigned short count, short flags, const char* externalName, float fieldTolerance) { size_t padding = 0; - int fieldOffset = GetAlignedOffset( GetDataDescOffset() + m_DataMapDescSizeInBytes, fieldType, &padding ); + int fieldOffset = (int)GetAlignedOffset( GetDataDescOffset() + m_DataMapDescSizeInBytes, fieldType, &padding ); int fieldSizeInBytes = g_DataMapDescFieldSizes[fieldType] * count; name = name ? strdup(name) : NULL; @@ -777,10 +777,16 @@ void IEntityDataMapInputFuncDelegate::Alloc() uint8_t funcBytes[] = { #ifdef PLATFORM_X64 -#ifdef WIN64 -#else // (IEntityDataMapInputFuncDelegate* pDelegate, CBaseEntity* pEntity, inputdata_t &data) // this::(inputdata_t &) +#ifdef WIN64 + // RCX / XMM0L, RDX / XMM1L, R8 / XMM2L, and R9 / XMM3L + 0x49, 0x89, 0xD0, // mov R8, RDX + 0x48, 0x89, 0xCA, // mov RDX, RCX + 0x48, 0xB9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // movabs rcx, thisAddr + 0x49, 0xB9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // movabs r9, callFuncAddr + 0x41, 0xFF, 0xE1 // jmp r9 +#else // RDI, RSI, RDX, RCX, R8, R9 0x48, 0x89, 0xF2, // mov RDX, RSI - 3rd arg 0x48, 0x89, 0xFE, // mov RSI, RDI @@ -839,6 +845,8 @@ void IEntityDataMapInputFuncDelegate::Alloc() #ifdef PLATFORM_X64 #ifdef WIN64 + *((intp*)(&funcBytes[8])) = thisAddr; + *((intp*)(&funcBytes[18])) = callFuncAddr; #else *((intp*)(&funcBytes[8])) = thisAddr; *((intp*)(&funcBytes[18])) = callFuncAddr; @@ -1013,7 +1021,7 @@ void IEntityDataMapContainer::DefineInputFunc(const char* name, fieldtype_t fiel void IEntityDataMapContainer::DefineOutput(const char* name, const char* mapname) { size_t padding = 0; - int fieldOffset = GetAlignedOffset( GetDataDescOffset() + m_DataMapDescSizeInBytes, sizeof(int*), &padding ); + int fieldOffset = (int)GetAlignedOffset( GetDataDescOffset() + m_DataMapDescSizeInBytes, sizeof(int*), &padding ); int fieldSizeInBytes = sizeof(CBaseEntityOutput); name = name ? strdup(name) : NULL; diff --git a/gamedata/cbasenpc.txt b/gamedata/cbasenpc.txt index fe0df41..aa4ff25 100644 --- a/gamedata/cbasenpc.txt +++ b/gamedata/cbasenpc.txt @@ -8,12 +8,14 @@ "TheNavMesh" { "windows" "786" + "windows64" "569" "linux" "979" "linux64" "849" } "TheNavAreas" { "windows" "819" + "windows64" "839" "linux" "1058" "linux64" "1008" } @@ -21,195 +23,232 @@ "g_TouchTrace" { "windows" "32" + "windows64" "56" "linux" "29" "linux64" "55" } "g_EntityListPool" { "windows" "17" + "windows64" "33" } "CNavMesh::m_isLoaded" { "windows" "52" + "windows64" "72" "linux" "52" "linux64" "72" } "CBaseEntity::Spawn" { "windows" "24" + "windows64" "24" "linux" "25" "linux64" "25" } "CBaseEntity::PostConstructor" { "windows" "28" + "windows64" "28" "linux" "29" "linux64" "29" } "CBaseEntity::GetBaseAnimating" { "windows" "52" + "windows64" "52" "linux" "53" "linux64" "53" } "CBaseEntity::IsAlive" { "windows" "67" + "windows64" "67" "linux" "68" "linux64" "68" } "CBaseEntity::Event_Killed" { "windows" "68" + "windows64" "68" + "linux" "69" "linux64" "69" } "CBaseEntity::MyCombatCharacterPointer" { "windows" "73" + "windows64" "73" "linux" "74" "linux64" "74" } "CBaseEntity::MyNextBotPointer" { "windows" "74" + "windows64" "74" "linux" "75" "linux64" "75" } "CBaseEntity::Touch" { "windows" "104" + "windows64" "104" "linux" "105" "linux64" "105" } "CBaseEntity::PhysicsSimulate" { "windows" "109" + "windows64" "109" "linux" "110" "linux64" "110" } "CBaseEntity::UpdateOnRemove" { "windows" "110" + "windows64" "110" "linux" "111" "linux64" "111" } "CBaseEntity::EyeAngles" { "windows" "137" + "windows64" "137" "linux" "138" "linux64" "138" } "CBaseEntity::GetVectors" { "windows" "142" + "windows64" "142" "linux" "143" "linux64" "143" } "CBaseEntity::WorldSpaceCenter" { "windows" "155" + "windows64" "155" "linux" "156" "linux64" "156" } "CBaseAnimating::StudioFrameAdvance" { "windows" "200" + "windows64" "200" "linux" "201" "linux64" "201" } "CBaseAnimating::DispatchAnimEvents" { "windows" "212" + "windows64" "212" "linux" "213" "linux64" "213" } "CBaseAnimating::HandleAnimEvent" { "windows" "213" + "windows64" "213" "linux" "214" "linux64" "214" } "CBaseAnimating::GetAttachment" { "windows" "215" + "windows64" "215" "linux" "216" "linux64" "216" } "CBaseCombatCharacter::Weapon_Equip" { "windows" "271" + "windows64" "271" "linux" "272" "linux64" "272" } "CBaseCombatCharacter::Weapon_Drop" { "windows" "273" + "windows64" "273" "linux" "274" "linux64" "274" } "CBaseCombatCharacter::OnTakeDamage_Alive" { "windows" "282" + "windows64" "282" "linux" "283" "linux64" "283" } "CBaseCombatCharacter::OnTakeDamage_Dying" { "windows" "283" + "windows64" "283" "linux" "284" "linux64" "284" } "CBaseCombatCharacter::GetLastKnownArea" { "windows" "322" + "windows64" "322" "linux" "323" "linux64" "323" } "CBaseCombatCharacter::OnNavAreaChanged" { "windows" "326" + "windows64" "326" "linux" "327" "linux64" "327" } "CBaseCombatCharacter::UpdateLastKnownArea" { "windows" "325" + "windows64" "325" "linux" "326" "linux64" "326" } "NextBotCombatCharacter::vtable_entries" { "windows" "338" + "windows64" "338" "linux" "338" "linux64" "338" } "NextBotGroundLocomotion::vtable_entries" { "windows" "111" + "windows64" "111" "linux" "111" "linux64" "111" } } "Signatures" { + // Find string "Missing command string" which is used by nb_command + // nb_command calls TheNextBots() "TheNextBots" { "library" "server" "windows" "\xA1\x2A\x2A\x2A\x2A\x85\xC0\x75\x2A\x8B\x0D\x2A\x2A\x2A\x2A\xF6\xC1\x01" + "windows64" "\x48\x83\xEC\x28\x48\x8B\x05\x2A\x2A\x2A\x2A\x48\x85\xC0\x0F\x85\x2A\x2A\x2A\x2A\x8B\x05\x2A\x2A\x2A\x2A" "linux" "@_Z11TheNextBotsv" "linux64" "@_Z11TheNextBotsv" } + // Find string "or_crit_vs_playercond" "CTFGameRules::ApplyOnDamageModifyRules" { "library" "server" "windows" "\x55\x8B\xEC\x81\xEC\xAC\x00\x00\x00\x56\x8B\x75\x0C" + "windows64" "\x48\x8B\xC4\x44\x88\x48\x2A\x4C\x89\x40\x2A\x48\x89\x48\x2A\x55\x53\x56\x57" "linux" "@_ZN12CTFGameRules24ApplyOnDamageModifyRulesER15CTakeDamageInfoP11CBaseEntityb" "linux64" "@_ZN12CTFGameRules24ApplyOnDamageModifyRulesER15CTakeDamageInfoP11CBaseEntityb" } + // Find string "mult_dmgtaken" "CTFGameRules::ApplyOnDamageAliveModifyRules" { "library" "server" "windows" "\x55\x8B\xEC\x81\xEC\x2A\x00\x00\x00\x53\x8B\x5D\x0C\x89\x2A\x2A\x56" + "windows64" "\x48\x8B\xC4\x4C\x89\x40\x2A\x48\x89\x48\x2A\x55" "linux" "@_ZN12CTFGameRules29ApplyOnDamageAliveModifyRulesERK15CTakeDamageInfoP11CBaseEntityRNS_20DamageModifyExtras_tE" "linux64" "@_ZN12CTFGameRules29ApplyOnDamageAliveModifyRulesERK15CTakeDamageInfoP11CBaseEntityRNS_20DamageModifyExtras_tE" } @@ -218,41 +257,64 @@ { "library" "server" "windows" "\x55\x8B\xEC\x81\xEC\x84\x01\x00\x00\x53\x56\x8B\x35\x2A\x2A\x2A\x2A" + "windows64" "\x48\x8B\xC4\x48\x89\x48\x2A\x55\x53\x57\x41\x55" "linux" "@_ZN8CNavMesh4LoadEv" "linux64" "@_ZN8CNavMesh4LoadEv" } + // Go to first data xref of "Warning: NavArea #%d: Truncated hiding spot list to 255\n", this is CNavArea::Save + // Go to first data xref to reach CNavArea vtable + // Go to vfunc "CNavArea::ComputeLighting" + // Go to last call "CNavMesh::GetGroundHeight" { "library" "server" "windows" "\x53\x8B\xDC\x83\xEC\x08\x83\xE4\xF0\x83\xC4\x04\x55\x8B\x6B\x04\x89\x6C\x24\x04\x8B\xEC\x81\xEC\xFC\x00\x00\x00\x56\x6A\x00\x6A\x00\x6A\x00\x8D" + "windows64" "\x48\x8B\xC4\x48\x89\x58\x2A\x48\x89\x70\x2A\x48\x89\x78\x2A\x4C\x89\x70\x2A\x55\x48\x8D\xA8\x2A\x2A\x2A\x2A\x48\x81\xEC\xD0\x01\x00\x00\x0F\x29\x70\x2A\x48\x8D\x4D\x00" "linux" "@_ZNK8CNavMesh15GetGroundHeightERK6VectorPfPS0_" "linux64" "@_ZNK8CNavMesh15GetGroundHeightERK6VectorPfPS0_" } + // Go to first data xref of string " Usage: test_dispatcheffect \n ", this is CC_Player_TestDispatchEffect + // Go to first call that takes 6 params, this is UTIL_TraceLine + // Go to first call, this is CTraceFilterSimple::CTraceFilterSimple + // Go to src of first LEA op, this is CTraceFilterSimple vtable + // Go to first vfunc, this is CTraceFilterSimple::ShouldHitEntity "CTraceFilterSimple::ShouldHitEntity" { "library" "server" "windows" "\x55\x8B\xEC\x53\x8B\x5D\x0C\x56\x8B\x75\x08\x57\x53\x56" + "windows64" "\x48\x89\x5C\x24\x2A\x48\x89\x6C\x24\x2A\x48\x89\x74\x24\x2A\x48\x89\x7C\x24\x2A\x41\x56\x48\x83\xEC\x20\x48\x8B\xE9\x41\x8B\xF8" "linux" "@_ZN18CTraceFilterSimple15ShouldHitEntityEP13IHandleEntityi" "linux64" "@_ZN18CTraceFilterSimple15ShouldHitEntityEP13IHandleEntityi" } + // Go to first data xref of string "%s has changed its model while processing AnimEvents on sequence %d. Aborting dispatch.\n", this is CBaseAnimating::DispatchAnimEvents + // Go to call that takes 6 params, this is GetAnimationEvent "__GetAnimationEvent__" { "library" "server" "windows" "\x55\x8B\xEC\x53\x56\x8B\x75\x08\x85\xF6\x0F\x84\x2A\x2A\x2A\x2A\x8B\xCE\xE8\x2A\x2A\x2A\x2A" + "windows64" "\x48\x89\x5C\x24\x2A\x48\x89\x74\x24\x2A\x57\x48\x83\xEC\x30\x0F\x29\x74\x24\x2A\x0F\x28\xF3\x49\x8B\xF0" "linux" "@_Z17GetAnimationEventP10CStudioHdriP11animevent_tffi" "linux64" "@_Z17GetAnimationEventP10CStudioHdriP11animevent_tffi" } + // Go to first data xref of string "Dynamic prop %s: no sequence named:%s\n", this is CDynamicProp::PropSetAnim + // Go to first call, this is CBaseAnimating::LookupSequence + // Go to last call, this is ::LookupSequence "Studio_LookupSequence" { "library" "server" "windows" "\x55\x8B\xEC\x56\x8B\x75\x08\x85\xF6\x75\x2A\x33\xC0\x5E\x5D\xC3\x8B\xCE\xE8\x2A\x2A\x2A\x2A\x84\xC0\x74\x2A\x53" + "windows64" "\x48\x89\x5C\x24\x2A\x55\x48\x83\xEC\x20\x48\x8B\xEA" "linux" "@_Z14LookupSequenceP10CStudioHdrPKc" "linux64" "@_Z14LookupSequenceP10CStudioHdrPKc" } + // Go to data xref of string "No appropriate sequence for arrival activity %s (%d)\n", this is CAI_Navigator::GetArrivalSequence + // Go to fourth call, this is CBaseAnimating::SelectWeightedSequence + // Follow jmp op at end to func "Studio_SelectWeightedSequence" { "library" "server" "windows" "\x55\x8B\xEC\x56\x8B\x75\x08\x85\xF6\x75\x2A\x33\xC0\x5E\x5D\xC3\x8B\xCE\xE8\x2A\x2A\x2A\x2A\x84\xC0\x74\x2A\x8B\xCE" + "windows64" "\x48\x89\x5C\x24\x2A\x48\x89\x6C\x24\x2A\x56\x48\x83\xEC\x20\x41\x8B\xF0" "linux" "@_Z22SelectWeightedSequenceP10CStudioHdrii" "linux64" "@_Z22SelectWeightedSequenceP10CStudioHdrii" } @@ -261,6 +323,7 @@ { "library" "server" "windows" "\x55\x8B\xEC\x53\x56\x57\x8B\x7D\x08\x85\xFF\x74\x2A\x8B\xCF" + "windows64" "\x48\x89\x5C\x24\x2A\x48\x89\x74\x24\x2A\x57\x48\x83\xEC\x20\x48\x8B\xF2\x48\x8B\xF9\x48\x85\xC9" "linux" "@_Z21Studio_FindAttachmentPK10CStudioHdrPKc" "linux64" "@_Z21Studio_FindAttachmentPK10CStudioHdrPKc" } @@ -269,16 +332,25 @@ { "library" "server" "windows" "\x55\x8B\xEC\x56\x57\x8B\x7D\x08\x8B\xF1\xF6\x87\x3C\x01\x00\x00\x01" + "windows64" "\x40\x53\x56\x48\x83\xEC\x28\xF6\x82\x2A\x2A\x2A\x2A\x01" "linux" "@_Z22SimThink_EntityChangedP11CBaseEntity" "linux64" "@_Z22SimThink_EntityChangedP11CBaseEntity" } - // Find ".?AVCRallyPoint@@" to get to CRallyPoint's type descriptor -> complete object locator -> vtable - // goto xref to vtable to enter CRallyPoint's constructor - // CBaseEntity constructor is second call that takes additional argument (bServerOnly set to 0) + // Go to first data xref of "simple_bot" + // Go to src of other LEA op, this is the instance of CEntityFactory singleton + // Go to ptr, this is the vtable + // Go to first vptr, this is CEntityFactory::Create (CSimpleBot::CSimpleBot is inlined in this function) + // Go to second call, this is NextBotCombatCharacter::NextBotCombatCharacter + // Go to first call, this is CBaseCombatCharacter::CBaseCombatCharacter + // ... CBaseCombatCharacter::CBaseCombatCharacter + // ... CBaseFlex::CBaseFlex + // ... CBaseAnimating::CBaseAnimating (CBaseAnimatingOverlay doesn't have a ctor) + // ... CBaseEntity::CBaseEntity (first call, has two arguments, this and false) "CBaseEntity::CBaseEntity" { "library" "server" "windows" "\x55\x8B\xEC\x83\xEC\x14\x53\x56\x8B\xF1\x57\x8D\x2A\x2A\xC7\x06" + "windows64" "\x48\x89\x5C\x24\x2A\x48\x89\x6C\x24\x2A\x48\x89\x74\x24\x2A\x88\x54\x24\x2A" "linux" "@_ZN11CBaseEntityC2Eb" "linux64" "@_ZN11CBaseEntityC2Eb" } @@ -288,6 +360,7 @@ { "library" "server" "windows" "\x55\x8B\xEC\x56\x8B\x75\x0C\x57\x8B\xF9\xB9\x2A\x2A\x2A\x2A\x56\xE8\x2A\x2A\x2A\x2A\xF3\x0F\x10\x46\x38\x8B\xCF\xF3\x0F\x11\x05\x2A\x2A\x2A\x2A\x8B\x46\x3C\xA3\x2A\x2A\x2A\x2A\x8B\x46\x40\xA3\x2A\x2A\x2A\x2A\x8B\x46\x44\xA3\x2A\x2A\x2A\x2A\x66\x8B\x46\x48\x66\xA3\x2A\x2A\x2A\x2A\x8B\x46\x4C\xA3\x2A\x2A\x2A\x2A\x8B\x46\x50\x8B\x75\x08\x56\xA3\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A" + "windows64" "\x48\x85\xD2\x0F\x84\x2A\x2A\x2A\x2A\x48\x89\x5C\x24\x2A\x57\x48\x83\xEC\x20\x8B\x82\x2A\x2A\x2A\x2A\x48\x8B\xDA\x0B\x81\x2A\x2A\x2A\x2A" "linux" "@_ZN11CBaseEntity29PhysicsMarkEntitiesAsTouchingEPS_R10CGameTrace" "linux64" "@_ZN11CBaseEntity29PhysicsMarkEntitiesAsTouchingEPS_R10CGameTrace" } @@ -296,13 +369,17 @@ { "library" "server" "windows" "\x55\x8B\xEC\x81\xEC\x80\x00\x00\x00\x56\x8B\xF1\x8B\x86\x3C\x01\x00\x00" + "windows64" "\x4C\x8B\xDC\x55\x53\x49\x8D\x6B\x2A\x48\x81\xEC\xE8\x00\x00\x00" "linux" "@_ZN11CBaseEntity20CalcAbsolutePositionEv" "linux64" "@_ZN11CBaseEntity20CalcAbsolutePositionEv" } + // Go to first data xref of string "Bad SetLocalAngles(%f,%f,%f) on %s\n", this is CBaseEntity::SetLocalAngles + // Go to call being passed 2 params (this, and the literal 2 which is ANGLES_CHANGED) "CBaseEntity::InvalidatePhysicsRecursive" { "library" "server" "windows" "\x55\x8B\xEC\x53\x8B\x5D\x08\x56\x8B\xF3\x83\xE6\x04" + "windows64" "\x48\x89\x5C\x24\x2A\x48\x89\x74\x24\x2A\x57\x48\x83\xEC\x20\x8B\xF2\x48\x89\x6C\x24\x2A" "linux" "@_ZN11CBaseEntity26InvalidatePhysicsRecursiveEi" "linux64" "@_ZN11CBaseEntity26InvalidatePhysicsRecursiveEi" } @@ -311,6 +388,7 @@ { "library" "server" "windows" "\x55\x8B\xEC\x81\xEC\x98\x00\x00\x00\x53\x8B\xD9" + "windows64" "\x40\x55\x53\x57\x48\x8D\x6C\x24\x2A\x48\x81\xEC\x00\x01\x00\x00\x48\x8B\xF9" "linux" "@_ZN11CBaseEntity10TakeDamageERK15CTakeDamageInfo" "linux64" "@_ZN11CBaseEntity10TakeDamageERK15CTakeDamageInfo" } @@ -319,55 +397,77 @@ { "library" "server" "windows" "\x6A\x00\x68\x2A\x2A\x2A\x2A\x6A\x01\x68\x00\x02\x00\x00\x6A\x1C" + "windows64" "\x48\x83\xEC\x38\xBA\x30\x00\x00\x00" "linux" "@g_EntityListPool" "linux64" "@g_EntityListPool" } + // Go to data xref of CMultiPlayerAnimState::SetupPoseParameters, this is CMultiPlayerAnimState vtable + // Go to CMultiPlayerAnimState::ComputePoseParam_MoveYaw vfunc + // Multiple call pairs of CBaseAnimating::SetPoseParameter "CBaseAnimating::SetPoseParameter" { "library" "server" "windows" "\x55\x8B\xEC\x8B\x45\x08\xD9\x45\x10" + "windows64" "\x48\x89\x5C\x24\x2A\x57\x48\x83\xEC\x30\x0F\x29\x74\x24\x2A\x0F\x28\xF3" "linux" "@_ZN14CBaseAnimating16SetPoseParameterEP10CStudioHdrif" "linux64" "@_ZN14CBaseAnimating16SetPoseParameterEP10CStudioHdrif" } + // Go to CMultiPlayerAnimState vtable + // Go to CMultiPlayerAnimState::GetCurrentMaxGroundSpeed vfunc + // Multiple call pairs of CBaseAnimating::GetPoseParameter "CBaseAnimating::GetPoseParameter" { "library" "server" "windows" "\x55\x8B\xEC\x56\x8B\xF1\x57\x80\xBE\x69\x03\x00\x00\x00\x75\x2A\x83\xBE\x98\x04\x00\x00\x00\x75\x2A\xE8\x2A\x2A\x2A\x2A\x85\xC0\x74\x2A\x8B\xCE\xE8\x2A\x2A\x2A\x2A\x8B\xBE\x98\x04\x00\x00" + "windows64" "\x48\x89\x5C\x24\x2A\x48\x89\x74\x24\x2A\x57\x48\x83\xEC\x20\x80\xB9\x2A\x2A\x2A\x2A\x00\x48\x8B\xD9\x48\x63\xF2" "linux" "@_ZN14CBaseAnimating16GetPoseParameterEi" "linux64" "@_ZN14CBaseAnimating16GetPoseParameterEi" } + // Go to data xref of string "move_scale", this is CMultiPlayerAnimState::SetupPoseParameters + // Multiple calls to CBaseAnimating::LookupPoseParameter with different pose param names "CBaseAnimating::LookupPoseParameter" { "library" "server" "windows" "\x55\x8B\xEC\x57\x8B\x7D\x08\x85\xFF\x75\x2A\x33\xC0\x5F\x5D\xC2\x08\x00" + "windows64" "\x48\x89\x74\x24\x2A\x57\x48\x83\xEC\x20\x49\x8B\xF0\x48\x8B\xFA\x48\x85\xD2\x74\x2A\x48\x8B\xCA" "linux" "@_ZN14CBaseAnimating19LookupPoseParameterEP10CStudioHdrPKc" "linux64" "@_ZN14CBaseAnimating19LookupPoseParameterEP10CStudioHdrPKc" } + // Go to data xref of string "CBaseAnimating::SequenceDuration( %d ) NULL pstudiohdr on %s!\n" "CBaseAnimating::SequenceDuration" { "library" "server" "windows" "\x55\x8B\xEC\x56\x8B\x75\x08\x57\x8B\xF9\x85\xF6\x75\x2A\x8B\x47\x5C" + "windows64" "\x48\x89\x5C\x24\x2A\x48\x89\x74\x24\x2A\x57\x48\x83\xEC\x20\x80\xB9\x2A\x2A\x2A\x2A\x00\x8B\xF2" "linux" "@_ZN14CBaseAnimating16SequenceDurationEP10CStudioHdri" "linux64" "@_ZN14CBaseAnimating16SequenceDurationEP10CStudioHdri" } + // Go to data xref of string "ResetSequence : %s: %s -> %s\n" "CBaseAnimating::ResetSequence" { "library" "server" "windows" "\x55\x8B\xEC\xA1\x2A\x2A\x2A\x2A\x53\x56\x57\x83\x78\x30\x00\x8B\xD9\x8B\x7D\x08" + "windows64" "\x41\x56\x48\x83\xEC\x20\x48\x8B\x05\x2A\x2A\x2A\x2A\x4C\x8B\xF1" "linux" "@_ZN14CBaseAnimating13ResetSequenceEi" "linux64" "@_ZN14CBaseAnimating13ResetSequenceEi" } + // Go to CEntityFactory::Create + // There's a call that has one parameter of around ~0x178 bytes, this is operator.new and NextBotGroundLocomotion::NextBotGroundLocomotion is below it "NextBotGroundLocomotion::NextBotGroundLocomotion" { "library" "server" "windows" "\x55\x8B\xEC\x56\xFF\x75\x08\x8B\xF1\xE8\x2A\x2A\x2A\x2A\xC7\x06\x2A\x2A\x2A\x2A\x8B\xC6\xC7\x86\xB4\x00\x00\x00\xFF\xFF\xFF\xFF" + "windows64" "\x40\x53\x48\x83\xEC\x20\x48\x8B\xD9\xE8\x2A\x2A\x2A\x2A\x33\xC9\x48\x8D\x05\x2A\x2A\x2A\x2A\x48\x89\x03\x48\x8D\x05\x2A\x2A\x2A\x2A\x48\x89\x83\x2A\x2A\x2A\x2A\x48\x89\x83\x2A\x2A\x2A\x2A" "linux" "@_ZN23NextBotGroundLocomotionC2EP8INextBot" "linux64" "@_ZN23NextBotGroundLocomotionC2EP8INextBot" } + // Go to CEntityFactory::Create + // Go to second call, this is NextBotCombatCharacter::NextBotCombatCharacter "NextBotCombatCharacter::NextBotCombatCharacter" { "library" "server" "windows" "\x56\x57\x8B\xF9\xE8\x2A\x2A\x2A\x2A\x8D\x8F\x74\x08\x00\x00" + "windows64" "\x48\x89\x5C\x24\x2A\x57\x48\x83\xEC\x20\x48\x8B\xF9\xE8\x2A\x2A\x2A\x2A\x48\x8D\x8F\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A" "linux" "@_ZN22NextBotCombatCharacterC2Ev" "linux64" "@_ZN22NextBotCombatCharacterC2Ev" } @@ -380,6 +480,10 @@ { "signature" "__GetAnimationEvent__" } + "windows64" + { + "signature" "__GetAnimationEvent__" + } "linux" { "signature" "__GetAnimationEvent__" From e38c5da0546c2d1e0862933d50582333109e7fbe Mon Sep 17 00:00:00 2001 From: KitRifty Date: Fri, 16 Feb 2024 13:37:08 -0800 Subject: [PATCH 11/18] Fix edge case with passing 0 to PawnAddressToPtr --- extension/helpers.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/extension/helpers.h b/extension/helpers.h index 84ab100..8d32c46 100644 --- a/extension/helpers.h +++ b/extension/helpers.h @@ -158,6 +158,11 @@ inline cell_t PtrToPawnAddress(const void* ptr) { inline void* PawnAddressToPtr(cell_t addr) { #ifdef PLATFORM_X64 + if (!addr) { + // BUGFIX: Passing 0 to FromPseudoAddress won't return nullptr but a valid pseudo address. + // If we're getting 0 from a plugin then we treat it as nullptr since Address_Null is 0. + return 0; + } return (void*)g_pSM->FromPseudoAddress(addr); #else return (void*)addr; From c36f2fec0587f75252c69817a4e483af9ccac28f Mon Sep 17 00:00:00 2001 From: KitRifty Date: Fri, 16 Feb 2024 17:19:49 -0800 Subject: [PATCH 12/18] Fix "CBaseAnimating::SequenceDuration" signature --- gamedata/cbasenpc.txt | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/gamedata/cbasenpc.txt b/gamedata/cbasenpc.txt index aa4ff25..ec14034 100644 --- a/gamedata/cbasenpc.txt +++ b/gamedata/cbasenpc.txt @@ -123,7 +123,7 @@ "linux" "143" "linux64" "143" } - "CBaseEntity::WorldSpaceCenter" + "CBaseEntity::WorldSpaceCenter" { "windows" "155" "windows64" "155" @@ -256,7 +256,7 @@ "CNavMesh::Load" { "library" "server" - "windows" "\x55\x8B\xEC\x81\xEC\x84\x01\x00\x00\x53\x56\x8B\x35\x2A\x2A\x2A\x2A" + "windows" "\x55\x8B\xEC\x81\xEC\x84\x01\x00\x00\x53\x56\x8B\x35\x2A\x2A\x2A\x2A" "windows64" "\x48\x8B\xC4\x48\x89\x48\x2A\x55\x53\x57\x41\x55" "linux" "@_ZN8CNavMesh4LoadEv" "linux64" "@_ZN8CNavMesh4LoadEv" @@ -433,12 +433,17 @@ "linux" "@_ZN14CBaseAnimating19LookupPoseParameterEP10CStudioHdrPKc" "linux64" "@_ZN14CBaseAnimating19LookupPoseParameterEP10CStudioHdrPKc" } - // Go to data xref of string "CBaseAnimating::SequenceDuration( %d ) NULL pstudiohdr on %s!\n" + // Look up data xrefs to string "CBaseAnimating::SequenceDuration( %d ) NULL pstudiohdr on %s!\n" + // One of them is CBaseAnimating::GetSequenceCycleRate, is referenced by CBaseAnimating::DispatchAnimEvents + // One of them is CBaseAnimating::GetSequenceGroundSpeed, it's a virtual function + // One of them is CBaseAnimating::ScriptGetSequenceDuration, has xref to a VScript init function which has a xref to string "GetAttachmentBone" + // One of them divides the final result + // The last xref left should be CBaseAnimating::SequenceDuration "CBaseAnimating::SequenceDuration" { "library" "server" "windows" "\x55\x8B\xEC\x56\x8B\x75\x08\x57\x8B\xF9\x85\xF6\x75\x2A\x8B\x47\x5C" - "windows64" "\x48\x89\x5C\x24\x2A\x48\x89\x74\x24\x2A\x57\x48\x83\xEC\x20\x80\xB9\x2A\x2A\x2A\x2A\x00\x8B\xF2" + "windows64" "\x48\x89\x5C\x24\x2A\x48\x89\x74\x24\x2A\x57\x48\x83\xEC\x20\x41\x8B\xD8\x48\x8B\xFA\x48\x8B\xF1\x48\x85\xD2\x75\x2A\x48\x8B\x81\x2A\x2A\x2A\x2A\x4C\x8D\x0D\x2A\x2A\x2A\x2A\x48\x85\xC0\x48\x8D\x15\x2A\x2A\x2A\x2A\x8D\x4F\x2A\x4C\x0F\x45\xC8\xFF\x15\x2A\x2A\x2A\x2A\xEB\x2A\x48\x8B\xCF\xE8\x2A\x2A\x2A\x2A\x84\xC0\x74\x2A\x48\x8B\xCF\xE8\x2A\x2A\x2A\x2A\x3B\xD8\x7D\x2A\x85\xDB\x78\x2A\x4C\x8D\x86\x2A\x2A\x2A\x2A\x8B\xD3\x48\x8B\xCF\x48\x8B\x5C\x24" "linux" "@_ZN14CBaseAnimating16SequenceDurationEP10CStudioHdri" "linux64" "@_ZN14CBaseAnimating16SequenceDurationEP10CStudioHdri" } @@ -473,7 +478,7 @@ } } "Addresses" - { + { "GetAnimationEvent" { "windows" From 9e13516904f52f6cf49813c24f10bf700b7e6a10 Mon Sep 17 00:00:00 2001 From: KitRifty Date: Fri, 16 Feb 2024 18:01:27 -0800 Subject: [PATCH 13/18] Reimplement CBaseAnimating::SequenceDuration Replace sig with Studio_Duration signature Fetch m_flPoseParameter array member --- extension/sourcesdk/baseanimating.cpp | 10 ++++++---- extension/sourcesdk/baseanimating.h | 4 +++- gamedata/cbasenpc.txt | 24 ++++++++++-------------- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/extension/sourcesdk/baseanimating.cpp b/extension/sourcesdk/baseanimating.cpp index 1b1cf57..3f7e412 100644 --- a/extension/sourcesdk/baseanimating.cpp +++ b/extension/sourcesdk/baseanimating.cpp @@ -8,13 +8,13 @@ FCall fStudio_LookupSequence; FCall fStudio_FindAttachment; FCall fStudio_SelectWeightedSequence; +FCall fStudio_Duration; int CBaseAnimating::offset_HandleAnimEvent = 0; VCall CBaseAnimating::vStudioFrameAdvance; VCall CBaseAnimating::vDispatchAnimEvents; VCall< bool, int, matrix3x4_t& > CBaseAnimating::vGetAttachment; -MCall CBaseAnimating::mSequenceDuration; MCall CBaseAnimating::mResetSequence; MCall CBaseAnimating::mLookupPoseParameter; MCall CBaseAnimating::mGetPoseParameter; @@ -25,6 +25,7 @@ DEFINEVAR(CBaseAnimating, m_pStudioHdr); DEFINEVAR(CBaseAnimating, m_OnIgnite); DEFINEVAR(CBaseAnimating, m_nSequence); DEFINEVAR(CBaseAnimating, m_flModelScale); +DEFINEVAR(CBaseAnimating, m_flPoseParameter); bool CBaseAnimating::Init(SourceMod::IGameConfig* config, char* error, size_t maxlength) { @@ -33,8 +34,8 @@ bool CBaseAnimating::Init(SourceMod::IGameConfig* config, char* error, size_t ma fStudio_LookupSequence.Init(config, "Studio_LookupSequence"); fStudio_FindAttachment.Init(config, "Studio_FindAttachment"); fStudio_SelectWeightedSequence.Init(config, "Studio_SelectWeightedSequence"); + fStudio_Duration.Init(config, "Studio_Duration"); - mSequenceDuration.Init(config, "CBaseAnimating::SequenceDuration"); mResetSequence.Init(config, "CBaseAnimating::ResetSequence"); mLookupPoseParameter.Init(config, "CBaseAnimating::LookupPoseParameter"); mSetPoseParameter.Init(config, "CBaseAnimating::SetPoseParameter"); @@ -64,6 +65,7 @@ bool CBaseAnimating::Init(SourceMod::IGameConfig* config, char* error, size_t ma OFFSETVAR_SEND(CBaseAnimating, m_flModelScale); // m_pStudioHdr is in front of m_OnIgnite VAR_OFFSET_SET(m_pStudioHdr, VAR_OFFSET(m_OnIgnite) + sizeof(COutputEvent)); + OFFSETVAR_SEND(CBaseAnimating, m_flPoseParameter); END_VAR; void* aVal = nullptr; @@ -135,9 +137,9 @@ float CBaseAnimating::GetPoseParameter(const char* name) return GetPoseParameter(LookupPoseParameter(name)); } -float CBaseAnimating::SequenceDuration(CStudioHdr* studio, int sequence) +float CBaseAnimating::SequenceDuration(CStudioHdr* pStudioHdr, int iSequence) { - return mSequenceDuration(this, studio, sequence); + return fStudio_Duration(pStudioHdr, iSequence, GetPoseParameterArray()); } void CBaseAnimating::ResetSequence(int sequence) diff --git a/extension/sourcesdk/baseanimating.h b/extension/sourcesdk/baseanimating.h index 3b327bc..ca0c15e 100644 --- a/extension/sourcesdk/baseanimating.h +++ b/extension/sourcesdk/baseanimating.h @@ -34,6 +34,8 @@ class CBaseAnimating : public CBaseEntity float GetPoseParameter(const char* name); + const float* GetPoseParameterArray() { return m_flPoseParameter(); } + static int offset_HandleAnimEvent; static VCall vStudioFrameAdvance; @@ -42,7 +44,6 @@ class CBaseAnimating : public CBaseEntity static VCall vDispatchAnimEvents; void DispatchAnimEvents(CBaseAnimating*); - static MCall mSequenceDuration; float SequenceDuration(CStudioHdr*, int); static MCall mResetSequence; @@ -67,6 +68,7 @@ class CBaseAnimating : public CBaseEntity DECLAREVAR(CStudioHdr*, m_pStudioHdr); DECLAREVAR(int, m_nSequence); DECLAREVAR(float, m_flModelScale); + DECLAREVAR(float, m_flPoseParameter); }; inline float CBaseAnimating::GetModelScale() const diff --git a/gamedata/cbasenpc.txt b/gamedata/cbasenpc.txt index ec14034..a1eb45b 100644 --- a/gamedata/cbasenpc.txt +++ b/gamedata/cbasenpc.txt @@ -327,6 +327,16 @@ "linux" "@_Z21Studio_FindAttachmentPK10CStudioHdrPKc" "linux64" "@_Z21Studio_FindAttachmentPK10CStudioHdrPKc" } + // Look up data xrefs to string "CBaseAnimating::SequenceDuration( %d ) NULL pstudiohdr on %s!\n" + // Find call that takes 3 parameters + "Studio_Duration" + { + "library" "server" + "windows" "\x55\x8B\xEC\xFF\x75\x2A\x8B\x4D\x2A\xE8\x2A\x2A\x2A\x2A\xFF\x75" + "windows64" "\x48\x89\x5C\x24\x2A\x48\x89\x74\x24\x2A\x57\x48\x83\xEC\x20\x49\x8B\xD8\x8B\xFA" + "linux" "@_Z15Studio_DurationPK10CStudioHdriPKf" + "linux64" "@_Z15Studio_DurationPK10CStudioHdriPKf" + } // Bytes sequence search "00 00 C0 00", go to the only subroutine that uses that number with 'and' & 'cmp' "SimThink_EntityChanged" { @@ -433,20 +443,6 @@ "linux" "@_ZN14CBaseAnimating19LookupPoseParameterEP10CStudioHdrPKc" "linux64" "@_ZN14CBaseAnimating19LookupPoseParameterEP10CStudioHdrPKc" } - // Look up data xrefs to string "CBaseAnimating::SequenceDuration( %d ) NULL pstudiohdr on %s!\n" - // One of them is CBaseAnimating::GetSequenceCycleRate, is referenced by CBaseAnimating::DispatchAnimEvents - // One of them is CBaseAnimating::GetSequenceGroundSpeed, it's a virtual function - // One of them is CBaseAnimating::ScriptGetSequenceDuration, has xref to a VScript init function which has a xref to string "GetAttachmentBone" - // One of them divides the final result - // The last xref left should be CBaseAnimating::SequenceDuration - "CBaseAnimating::SequenceDuration" - { - "library" "server" - "windows" "\x55\x8B\xEC\x56\x8B\x75\x08\x57\x8B\xF9\x85\xF6\x75\x2A\x8B\x47\x5C" - "windows64" "\x48\x89\x5C\x24\x2A\x48\x89\x74\x24\x2A\x57\x48\x83\xEC\x20\x41\x8B\xD8\x48\x8B\xFA\x48\x8B\xF1\x48\x85\xD2\x75\x2A\x48\x8B\x81\x2A\x2A\x2A\x2A\x4C\x8D\x0D\x2A\x2A\x2A\x2A\x48\x85\xC0\x48\x8D\x15\x2A\x2A\x2A\x2A\x8D\x4F\x2A\x4C\x0F\x45\xC8\xFF\x15\x2A\x2A\x2A\x2A\xEB\x2A\x48\x8B\xCF\xE8\x2A\x2A\x2A\x2A\x84\xC0\x74\x2A\x48\x8B\xCF\xE8\x2A\x2A\x2A\x2A\x3B\xD8\x7D\x2A\x85\xDB\x78\x2A\x4C\x8D\x86\x2A\x2A\x2A\x2A\x8B\xD3\x48\x8B\xCF\x48\x8B\x5C\x24" - "linux" "@_ZN14CBaseAnimating16SequenceDurationEP10CStudioHdri" - "linux64" "@_ZN14CBaseAnimating16SequenceDurationEP10CStudioHdri" - } // Go to data xref of string "ResetSequence : %s: %s -> %s\n" "CBaseAnimating::ResetSequence" { From b30aaefd6e7969c2f70265209995357a9a819fb4 Mon Sep 17 00:00:00 2001 From: KitRifty Date: Fri, 16 Feb 2024 18:38:47 -0800 Subject: [PATCH 14/18] Add studiohdr checks to SequenceDuration Add source studio.cpp --- extension/AMBuilder | 1 + extension/sourcesdk/baseanimating.cpp | 18 +++++++++++++++++- extension/sourcesdk/studio.cpp | 21 +++++++++++++++++++++ 3 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 extension/sourcesdk/studio.cpp diff --git a/extension/AMBuilder b/extension/AMBuilder index 1f68559..08a87b3 100644 --- a/extension/AMBuilder +++ b/extension/AMBuilder @@ -28,6 +28,7 @@ project.sources = [ 'sourcesdk/nav_mesh.cpp', 'sourcesdk/entityfactorydictionary.cpp', 'sourcesdk/customfactory.cpp', + 'sourcesdk/studio.cpp', 'sourcesdk/baseentity.cpp', 'sourcesdk/baseentityoutput.cpp', 'sourcesdk/baseanimating.cpp', diff --git a/extension/sourcesdk/baseanimating.cpp b/extension/sourcesdk/baseanimating.cpp index 3f7e412..fd66358 100644 --- a/extension/sourcesdk/baseanimating.cpp +++ b/extension/sourcesdk/baseanimating.cpp @@ -1,4 +1,5 @@ #include "sourcesdk/baseanimating.h" +#include #include #include #include @@ -139,6 +140,21 @@ float CBaseAnimating::GetPoseParameter(const char* name) float CBaseAnimating::SequenceDuration(CStudioHdr* pStudioHdr, int iSequence) { + if ( !pStudioHdr ) + { + DevWarning( 2, "CBaseAnimating::SequenceDuration( %d ) NULL pstudiohdr on %s!\n", iSequence, GetClassname() ); + return 0.1; + } + if ( !pStudioHdr->SequencesAvailable() ) + { + return 0.1; + } + if (iSequence >= pStudioHdr->GetNumSeq() || iSequence < 0 ) + { + DevWarning( 2, "CBaseAnimating::SequenceDuration( %d ) out of range\n", iSequence ); + return 0.1; + } + return fStudio_Duration(pStudioHdr, iSequence, GetPoseParameterArray()); } @@ -148,7 +164,7 @@ void CBaseAnimating::ResetSequence(int sequence) } bool CBaseAnimating::GetAttachment(const char *szName, Vector &absOrigin, QAngle &absAngles) -{ +{ return GetAttachment(LookupAttachment(szName), absOrigin, absAngles); } diff --git a/extension/sourcesdk/studio.cpp b/extension/sourcesdk/studio.cpp new file mode 100644 index 0000000..d0d0fd4 --- /dev/null +++ b/extension/sourcesdk/studio.cpp @@ -0,0 +1,21 @@ +#include + +bool CStudioHdr::SequencesAvailable() const +{ + if (m_pStudioHdr->numincludemodels == 0) + { + return true; + } + + return m_pVModel != nullptr; +} + +int CStudioHdr::GetNumSeq( void ) const +{ + if (m_pVModel == NULL) + { + return m_pStudioHdr->numlocalseq; + } + + return m_pVModel->m_seq.Count(); +} \ No newline at end of file From 07210897644e54052298be714e85079ea09f02f0 Mon Sep 17 00:00:00 2001 From: Kenzzer Date: Sat, 27 Jul 2024 22:31:40 +0200 Subject: [PATCH 15/18] Setup MemoryPointer --- .gitmodules | 3 + AMBuildScript | 23 ++- extension/AMBuilder | 11 +- extension/cbasenpc_behavior.cpp | 151 ++++++++++++++---- extension/cbasenpc_locomotion.cpp | 48 +++++- extension/extension.cpp | 2 + extension/helpers.h | 94 +++++++++-- extension/natives.cpp | 20 +-- extension/natives/baseanimating.cpp | 2 +- extension/natives/baseanimatingoverlay.cpp | 4 +- extension/natives/basecombatcharacter.cpp | 2 +- extension/natives/baseentity.cpp | 10 +- extension/natives/cbasenpc.cpp | 12 +- extension/natives/nav.cpp | 43 +++-- extension/natives/nav/area.cpp | 40 ++--- extension/natives/nextbot.cpp | 20 +-- extension/natives/nextbot/behavior.cpp | 20 +-- extension/natives/nextbot/body.cpp | 2 +- extension/natives/nextbot/component.cpp | 4 +- extension/natives/nextbot/eventresponder.cpp | 12 +- extension/natives/nextbot/intention.cpp | 10 +- extension/natives/nextbot/knownentity.cpp | 4 +- extension/natives/nextbot/locomotion.cpp | 8 +- .../natives/nextbot/locomotion/ground.cpp | 2 +- extension/natives/nextbot/path.cpp | 51 +++--- extension/natives/nextbot/path/chase.cpp | 6 +- extension/natives/nextbot/path/follower.cpp | 4 +- extension/natives/nextbot/vision.cpp | 8 +- extension/natives/nextbotplayer.cpp | 6 +- extension/natives/takedamageinfo.cpp | 10 +- extension/natives/tf/nav/area.cpp | 2 +- extension/pluginentityfactory.cpp | 9 +- hl2sdk-manifests | 2 +- product.version | 2 +- third_party/safetyhook | 1 + 35 files changed, 442 insertions(+), 206 deletions(-) create mode 160000 third_party/safetyhook diff --git a/.gitmodules b/.gitmodules index 63f9cd8..84ea369 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "hl2sdk-manifests"] path = hl2sdk-manifests url = git@github.com:alliedmodders/hl2sdk-manifests.git +[submodule "third_party\\safetyhook"] + path = third_party\\safetyhook + url = https://github.com/alliedmodders/safetyhook.git diff --git a/AMBuildScript b/AMBuildScript index ed0a509..0942047 100644 --- a/AMBuildScript +++ b/AMBuildScript @@ -48,6 +48,7 @@ class ExtensionConfig(object): self.smapi_path = None self.all_targets = [] self.target_archs = set() + self.libsafetyhook = {} if self.build_extension(): if builder.options.targets: @@ -343,7 +344,7 @@ class ExtensionConfig(object): ] if builder.options.opt == '1': - cxx.cflags += ['/Ox', '/Zo', '-O3'] + cxx.cflags += ['/Ox', '/Zo'] cxx.linkflags += ['/OPT:ICF', '/OPT:REF'] if builder.options.debug == '1': @@ -422,6 +423,16 @@ class ExtensionConfig(object): if self.use_auto_versioning(): binary.compiler.sourcedeps += Extension.generated_headers return binary + + def AddCDetour(self, binary): + binary.sources += [ os.path.join(self.sm_root, 'public', 'CDetour', 'detours.cpp') ] + binary.compiler.cxxincludes += [ os.path.join(builder.sourcePath, 'third_party', 'safetyhook', 'include') ] + + for task in self.libsafetyhook: + if task.target.arch == binary.compiler.target.arch: + binary.compiler.linkflags += [task.binary] + return + raise Exception('No suitable build of safetyhook was found.') def LibraryBuilder(self, compiler, name): binary = compiler.Library(name) @@ -460,6 +471,16 @@ if Extension.build_extension(): Extension.detectSDKs() Extension.configure() +class SafetyHookShim(object): + def __init__(self): + self.all_targets = {} + self.libsafetyhook = {} + +SafetyHook = SafetyHookShim() +SafetyHook.all_targets = Extension.all_targets +builder.Build(os.path.join('third_party/safetyhook/AMBuilder'), {'SafetyHook': SafetyHook }) +Extension.libsafetyhook = SafetyHook.libsafetyhook + if Extension.use_auto_versioning(): Extension.generated_headers = builder.Build( 'tools/Versioning', diff --git a/extension/AMBuilder b/extension/AMBuilder index 08a87b3..30bafde 100644 --- a/extension/AMBuilder +++ b/extension/AMBuilder @@ -68,15 +68,7 @@ project.sources = [ 'natives/nextbotplayer.cpp', 'natives/tf/nav.cpp', 'natives/tf/nav/area.cpp', - os.path.join(Extension.sm_root, 'public/smsdk_ext.cpp'), - os.path.join(Extension.sm_root, 'public/CDetour/detours.cpp'), - os.path.join(Extension.sm_root, 'public/asm/asm.c'), - os.path.join(Extension.sm_root, 'public/libudis86/decode.c'), - os.path.join(Extension.sm_root, 'public/libudis86/itab.c'), - os.path.join(Extension.sm_root, 'public/libudis86/syn-att.c'), - os.path.join(Extension.sm_root, 'public/libudis86/syn-intel.c'), - os.path.join(Extension.sm_root, 'public/libudis86/syn.c'), - os.path.join(Extension.sm_root, 'public/libudis86/udis86.c') + os.path.join(Extension.sm_root, 'public/smsdk_ext.cpp') ] for sdk_name in Extension.sdks: @@ -86,6 +78,7 @@ for sdk_name in Extension.sdks: if not cxx.target.arch in sdk['platforms'][cxx.target.platform]: continue binary = Extension.HL2ExtConfig(project, builder, cxx, 'cbasenpc.ext.' + sdk['extension'], sdk) + Extension.AddCDetour(binary) binary.compiler.cxxincludes += [ os.path.join(builder.currentSourcePath, 'sourcesdk'), os.path.join(builder.currentSourcePath, 'sourcesdk/NextBot'), diff --git a/extension/cbasenpc_behavior.cpp b/extension/cbasenpc_behavior.cpp index 2fcc17b..e409a34 100644 --- a/extension/cbasenpc_behavior.cpp +++ b/extension/cbasenpc_behavior.cpp @@ -2,6 +2,8 @@ #include "cbasenpc_behavior.h" #include +#define CBPUSHPTR(ptr) Handle_t hndl_##ptr = PtrToPawnAddress(ptr, nullptr); pCallback->PushCell(hndl_##ptr); +#define CBRELPTR(ptr) ReleasePawnAddress(hndl_##ptr, nullptr); #define CBPUSHCELL(cell) pCallback->PushCell((cell_t)(cell)); #define CBPUSHFLOAT(fl) pCallback->PushCell(sp_ftoc(fl)); #define CBPUSHENTITY(ent) CBPUSHCELL(gamehelpers->EntityToBCompatRef(ent)) @@ -19,12 +21,16 @@ ActionResult< INextBot > CBaseNPCPluginAction:: funcName (INextBot* me, ##__VA_A ResetPluginActionResult(); \ IPluginFunction* pCallback = m_pFactory->GetCallback( CBaseNPCPluginActionFactory::CallbackType::typeName ); \ if (pCallback && pCallback->IsRunnable()) { \ - pCallback->PushCell(PtrToPawnAddress(this)); pCallback->PushCell(gamehelpers->EntityToBCompatRef(me->GetEntity())); + Handle_t hndlThis = PtrToPawnAddress((void*)this, nullptr); \ + pCallback->PushCell(hndlThis); pCallback->PushCell(gamehelpers->EntityToBCompatRef(me->GetEntity())); #define BEGINACTIONCALLBACK(funcName, ...) BEGINACTIONCALLBACKEX(funcName, funcName, ##__VA_ARGS__) +#define EXECUTEACTIONCALLBACK() \ + pCallback->Execute(nullptr); + #define ENDACTIONCALLBACK() \ - pCallback->Execute(nullptr); \ + ReleasePawnAddress(hndlThis, nullptr); \ } \ m_bInActionCallback = false; \ return m_pluginActionResult; \ @@ -35,10 +41,16 @@ QueryResultType CBaseNPCPluginAction:: funcName ( const INextBot *me, ##__VA_ARG cell_t result = ANSWER_UNDEFINED; \ IPluginFunction* pCallback = m_pFactory->GetQueryCallback( CBaseNPCPluginActionFactory::QueryCallbackType::funcName ); \ if (pCallback && pCallback->IsRunnable()) { \ - CBPUSHCELL(PtrToPawnAddress(this)); CBPUSHCELL(PtrToPawnAddress(me)); + Handle_t hndlThis = PtrToPawnAddress(this, nullptr); \ + Handle_t hndlMe = PtrToPawnAddress(me, nullptr); \ + CBPUSHCELL(hndlThis); CBPUSHCELL(hndlMe); + +#define EXECUTEQUERYCALLBACK() \ + pCallback->Execute(&result); #define ENDQUERYCALLBACK() \ - pCallback->Execute(&result); \ + ReleasePawnAddress(hndlThis, nullptr); \ + ReleasePawnAddress(hndlMe, nullptr); \ } \ return (QueryResultType)result; \ } @@ -49,19 +61,25 @@ EventDesiredResult< INextBot > CBaseNPCPluginAction:: funcName (INextBot* me, ## ResetPluginEventResult(); \ IPluginFunction* pCallback = m_pFactory->GetEventCallback( CBaseNPCPluginActionFactory::EventResponderCallbackType::typeName ); \ if (pCallback && pCallback->IsRunnable()) { \ - pCallback->PushCell(PtrToPawnAddress(this)); \ + Handle_t hndlThis = PtrToPawnAddress(this, nullptr); \ + pCallback->PushCell(hndlThis); \ pCallback->PushCell(gamehelpers->EntityToBCompatRef(me->GetEntity())); #define BEGINEVENTCALLBACK(funcName, ...) BEGINEVENTCALLBACKEX(funcName, funcName, ##__VA_ARGS__) +#define EVENTPUSHPTR(cell) CBPUSHPTR(cell) +#define EVENTRELPTR(cell) CBRELPTR(cell) #define EVENTPUSHCELL(cell) CBPUSHCELL(cell) #define EVENTPUSHFLOAT(fl) CBPUSHFLOAT(fl) #define EVENTPUSHENTITY(ent) CBPUSHENTITY(ent) #define EVENTPUSHSTRING(str) CBPUSHSTRING(str) #define EVENTPUSHVECTOR(vec) CBPUSHVECTOR(vec) +#define EXECUTEEVENTCALLBACK() \ + pCallback->Execute(nullptr); + #define ENDEVENTCALLBACK() \ - pCallback->Execute(nullptr); \ + ReleasePawnAddress(hndlThis, nullptr); \ } \ m_inEventCallback--; \ return m_pluginEventResult; \ @@ -185,28 +203,37 @@ void CBaseNPCPluginAction::PluginTryToSustain( EventResultPriorityType priority, // Actions BEGINACTIONCALLBACK(OnStart, Action< INextBot > *prevAction) - CBPUSHCELL(PtrToPawnAddress(prevAction)) + CBPUSHPTR(prevAction) + EXECUTEACTIONCALLBACK() + CBRELPTR(prevAction) ENDACTIONCALLBACK() BEGINACTIONCALLBACK(Update, float interval) CBPUSHFLOAT(interval) + EXECUTEACTIONCALLBACK() ENDACTIONCALLBACK() BEGINACTIONCALLBACK(OnSuspend, Action< INextBot > *interruptingAction) - CBPUSHCELL(PtrToPawnAddress(interruptingAction)) + CBPUSHPTR(interruptingAction) + EXECUTEACTIONCALLBACK() + CBRELPTR(interruptingAction) ENDACTIONCALLBACK() BEGINACTIONCALLBACK(OnResume, Action< INextBot > *interruptingAction) - CBPUSHCELL(PtrToPawnAddress(interruptingAction)) + CBPUSHPTR(interruptingAction) + EXECUTEACTIONCALLBACK() + CBRELPTR(interruptingAction) ENDACTIONCALLBACK() void CBaseNPCPluginAction::OnEnd( INextBot * me, Action< INextBot > *nextAction ) { IPluginFunction* pCallback = m_pFactory->GetCallback( CBaseNPCPluginActionFactory::CallbackType::OnEnd ); if (pCallback && pCallback->IsRunnable()) { - CBPUSHCELL(PtrToPawnAddress(this)) + CBPUSHPTR(this) CBPUSHENTITY(me->GetEntity()) - CBPUSHCELL(PtrToPawnAddress(nextAction)) + CBPUSHPTR(nextAction) pCallback->Execute(nullptr); + CBRELPTR(this) + CBRELPTR(nextAction) } } @@ -217,13 +244,14 @@ Action< INextBot >* CBaseNPCPluginAction::InitialContainedAction( INextBot * me IPluginFunction* pCallback = m_pFactory->GetCallback( CBaseNPCPluginActionFactory::CallbackType::InitialContainedAction ); if (pCallback && pCallback->IsRunnable()) { - CBPUSHCELL(PtrToPawnAddress(this)) + CBPUSHPTR(this) CBPUSHENTITY(me->GetEntity()) pCallback->Execute(&result); + CBRELPTR(this) } - return (Action< INextBot >*)PawnAddressToPtr(result); + return (Action< INextBot >*)PawnAddressToPtr(result, nullptr); } bool CBaseNPCPluginAction::IsAbleToBlockMovementOf( const INextBot *botInMotion ) const @@ -233,10 +261,12 @@ bool CBaseNPCPluginAction::IsAbleToBlockMovementOf( const INextBot *botInMotion IPluginFunction* pCallback = m_pFactory->GetCallback( CBaseNPCPluginActionFactory::CallbackType::IsAbleToBlockMovementOf ); if (pCallback && pCallback->IsRunnable()) { - CBPUSHCELL(PtrToPawnAddress(this)) - CBPUSHCELL(PtrToPawnAddress(botInMotion)) + CBPUSHPTR(this) + CBPUSHPTR(botInMotion) pCallback->Execute(&result); + CBRELPTR(this) + CBRELPTR(botInMotion) } return !!result; @@ -246,20 +276,26 @@ bool CBaseNPCPluginAction::IsAbleToBlockMovementOf( const INextBot *botInMotion BEGINQUERYCALLBACK(ShouldPickUp, CBaseEntity *item ) CBPUSHENTITY(item); + EXECUTEQUERYCALLBACK() ENDQUERYCALLBACK() BEGINQUERYCALLBACK(ShouldHurry) + EXECUTEQUERYCALLBACK() ENDQUERYCALLBACK() BEGINQUERYCALLBACK(ShouldRetreat) + EXECUTEQUERYCALLBACK() ENDQUERYCALLBACK() BEGINQUERYCALLBACK(ShouldAttack, const CKnownEntity *them) - CBPUSHCELL(PtrToPawnAddress(them)) + CBPUSHPTR(them) + EXECUTEQUERYCALLBACK() + CBRELPTR(them) ENDQUERYCALLBACK() BEGINQUERYCALLBACK(IsHindrance, CBaseEntity* blocker) CBPUSHENTITY(blocker == IS_ANY_HINDRANCE_POSSIBLE ? nullptr : blocker) + EXECUTEQUERYCALLBACK() ENDQUERYCALLBACK() Vector CBaseNPCPluginAction::SelectTargetPoint( const INextBot* me, const CBaseCombatCharacter* subject ) const @@ -274,11 +310,13 @@ Vector CBaseNPCPluginAction::SelectTargetPoint( const INextBot* me, const CBaseC buffer[1] = sp_ftoc(result[1]); buffer[2] = sp_ftoc(result[2]); - CBPUSHCELL(PtrToPawnAddress(this)) - CBPUSHCELL(PtrToPawnAddress(me)) + CBPUSHPTR(this) + CBPUSHPTR(me) CBPUSHENTITY((CBaseCombatCharacter*)subject) pCallback->PushArray(buffer, 3, SM_PARAM_COPYBACK); pCallback->Execute(nullptr); + CBRELPTR(this) + CBRELPTR(me) result[0] = sp_ctof(buffer[0]); result[1] = sp_ctof(buffer[1]); @@ -290,6 +328,7 @@ Vector CBaseNPCPluginAction::SelectTargetPoint( const INextBot* me, const CBaseC BEGINQUERYCALLBACK(IsPositionAllowed, const Vector &pos) CBPUSHVECTOR(pos) + EXECUTEQUERYCALLBACK() ENDQUERYCALLBACK() const CKnownEntity * CBaseNPCPluginAction::SelectMoreDangerousThreat( const INextBot *me, @@ -302,56 +341,73 @@ const CKnownEntity * CBaseNPCPluginAction::SelectMoreDangerousThreat( const INex IPluginFunction* pCallback = m_pFactory->GetQueryCallback( CBaseNPCPluginActionFactory::QueryCallbackType::SelectMoreDangerousThreat ); if (pCallback && pCallback->IsRunnable()) { - CBPUSHCELL(PtrToPawnAddress(this)) - CBPUSHCELL(PtrToPawnAddress(me)) + CBPUSHPTR(this) + CBPUSHPTR(me) CBPUSHENTITY((CBaseCombatCharacter*)subject) - CBPUSHCELL(PtrToPawnAddress(threat1)) - CBPUSHCELL(PtrToPawnAddress(threat2)) + CBPUSHPTR(threat1) + CBPUSHPTR(threat2) pCallback->Execute(&result); + CBRELPTR(this) + CBRELPTR(me) + CBRELPTR(threat1) + CBRELPTR(threat2) } - return (const CKnownEntity*)PawnAddressToPtr(result); + return (const CKnownEntity*)PawnAddressToPtr(result, nullptr); } // Events BEGINEVENTCALLBACK(OnLeaveGround, CBaseEntity* ground) EVENTPUSHENTITY(ground) + EXECUTEEVENTCALLBACK() ENDEVENTCALLBACK() BEGINEVENTCALLBACK(OnLandOnGround, CBaseEntity* ground) EVENTPUSHENTITY(ground) + EXECUTEEVENTCALLBACK() ENDEVENTCALLBACK() BEGINEVENTCALLBACK(OnContact, CBaseEntity* other, CGameTrace* traceResult) EVENTPUSHENTITY(other) - EVENTPUSHCELL(PtrToPawnAddress(traceResult)) + EVENTPUSHPTR(traceResult) + EXECUTEEVENTCALLBACK() + EVENTRELPTR(traceResult) ENDEVENTCALLBACK() BEGINEVENTCALLBACK(OnMoveToSuccess, const Path *path) - EVENTPUSHCELL(PtrToPawnAddress(path)) + EVENTPUSHPTR(path) + EXECUTEEVENTCALLBACK() + EVENTRELPTR(path) ENDEVENTCALLBACK() BEGINEVENTCALLBACK(OnMoveToFailure, const Path *path, MoveToFailureType reason) - EVENTPUSHCELL(PtrToPawnAddress(path)) + EVENTPUSHPTR(path) EVENTPUSHCELL(reason) + EXECUTEEVENTCALLBACK() + EVENTRELPTR(path) ENDEVENTCALLBACK() BEGINEVENTCALLBACK(OnStuck) + EXECUTEEVENTCALLBACK() ENDEVENTCALLBACK() BEGINEVENTCALLBACK(OnUnStuck) + EXECUTEEVENTCALLBACK() ENDEVENTCALLBACK() BEGINEVENTCALLBACK(OnPostureChanged) + EXECUTEEVENTCALLBACK() ENDEVENTCALLBACK() BEGINEVENTCALLBACK(OnAnimationActivityComplete, int activity) EVENTPUSHCELL(activity) + EXECUTEEVENTCALLBACK() ENDEVENTCALLBACK() BEGINEVENTCALLBACK(OnAnimationActivityInterrupted, int activity) EVENTPUSHCELL(activity) + EXECUTEEVENTCALLBACK() ENDEVENTCALLBACK() BEGINEVENTCALLBACK(OnAnimationEvent, animevent_t *event) @@ -361,9 +417,11 @@ BEGINEVENTCALLBACK(OnAnimationEvent, animevent_t *event) EVENTPUSHFLOAT(event->eventtime) EVENTPUSHCELL(event->type) EVENTPUSHENTITY((CBaseAnimating*)event->pSource) + EXECUTEEVENTCALLBACK() ENDEVENTCALLBACK() BEGINEVENTCALLBACK(OnIgnite) + EXECUTEEVENTCALLBACK() ENDEVENTCALLBACK() BEGINEVENTCALLBACK(OnInjured, const CTakeDamageInfo &info) @@ -375,6 +433,7 @@ BEGINEVENTCALLBACK(OnInjured, const CTakeDamageInfo &info) EVENTPUSHVECTOR(info.GetDamageForce()) EVENTPUSHVECTOR(info.GetDamagePosition()) EVENTPUSHCELL(info.GetDamageCustom()) + EXECUTEEVENTCALLBACK() ENDEVENTCALLBACK() BEGINEVENTCALLBACK(OnKilled, const CTakeDamageInfo &info) @@ -386,6 +445,7 @@ BEGINEVENTCALLBACK(OnKilled, const CTakeDamageInfo &info) EVENTPUSHVECTOR(info.GetDamageForce()) EVENTPUSHVECTOR(info.GetDamagePosition()) EVENTPUSHCELL(info.GetDamageCustom()) + EXECUTEEVENTCALLBACK() ENDEVENTCALLBACK() BEGINEVENTCALLBACK(OnOtherKilled, CBaseCombatCharacter *victim, const CTakeDamageInfo &info) @@ -398,14 +458,17 @@ BEGINEVENTCALLBACK(OnOtherKilled, CBaseCombatCharacter *victim, const CTakeDamag EVENTPUSHVECTOR(info.GetDamageForce()) EVENTPUSHVECTOR(info.GetDamagePosition()) EVENTPUSHCELL(info.GetDamageCustom()) + EXECUTEEVENTCALLBACK() ENDEVENTCALLBACK() BEGINEVENTCALLBACK(OnSight, CBaseEntity *subject) EVENTPUSHENTITY(subject) + EXECUTEEVENTCALLBACK() ENDEVENTCALLBACK() BEGINEVENTCALLBACK(OnLostSight, CBaseEntity *subject) EVENTPUSHENTITY(subject) + EXECUTEEVENTCALLBACK() ENDEVENTCALLBACK() BEGINEVENTCALLBACK(OnSound, CBaseEntity *source, const Vector &pos, KeyValues *keys) @@ -426,95 +489,119 @@ BEGINEVENTCALLBACK(OnSound, CBaseEntity *source, const Vector &pos, KeyValues *k // Deletes pStk handlesys->FreeHandle(hndl, &sec); - + EXECUTEEVENTCALLBACK() ENDEVENTCALLBACK_NOEXECUTE() BEGINEVENTCALLBACK(OnSpokeConcept, CBaseCombatCharacter* who, AIConcept_t concept, AI_Response *response) EVENTPUSHENTITY(who) EVENTPUSHSTRING(concept) - EVENTPUSHCELL(PtrToPawnAddress(response)) + EVENTPUSHPTR(response) + EXECUTEEVENTCALLBACK() + EVENTRELPTR(response) ENDEVENTCALLBACK() BEGINEVENTCALLBACK(OnWeaponFired, CBaseCombatCharacter* whoFired, CBaseEntity* weapon ) EVENTPUSHENTITY(whoFired) EVENTPUSHENTITY(weapon) + EXECUTEEVENTCALLBACK() ENDEVENTCALLBACK() BEGINEVENTCALLBACK(OnNavAreaChanged, CNavArea *newArea, CNavArea *oldArea) - EVENTPUSHCELL(PtrToPawnAddress(newArea)) - EVENTPUSHCELL(PtrToPawnAddress(oldArea)) + EVENTPUSHPTR(newArea) + EVENTPUSHPTR(oldArea) + EXECUTEEVENTCALLBACK() + EVENTRELPTR(newArea) + EVENTRELPTR(oldArea) ENDEVENTCALLBACK() BEGINEVENTCALLBACK(OnModelChanged) + EXECUTEEVENTCALLBACK() ENDEVENTCALLBACK() BEGINEVENTCALLBACK(OnPickUp, CBaseEntity* item, CBaseCombatCharacter* giver) EVENTPUSHENTITY(item) EVENTPUSHENTITY(giver) + EXECUTEEVENTCALLBACK() ENDEVENTCALLBACK() BEGINEVENTCALLBACK(OnDrop, CBaseEntity* item) EVENTPUSHENTITY(item) + EXECUTEEVENTCALLBACK() ENDEVENTCALLBACK() BEGINEVENTCALLBACK(OnActorEmoted, CBaseCombatCharacter* emoter, int emote) EVENTPUSHENTITY(emoter) EVENTPUSHCELL(emote) + EXECUTEEVENTCALLBACK() ENDEVENTCALLBACK() BEGINEVENTCALLBACK(OnCommandAttack, CBaseEntity *victim) EVENTPUSHENTITY(victim) + EXECUTEEVENTCALLBACK() ENDEVENTCALLBACK() BEGINEVENTCALLBACK(OnCommandApproach, const Vector &pos, float range ) EVENTPUSHVECTOR(pos) EVENTPUSHFLOAT(range) + EXECUTEEVENTCALLBACK() ENDEVENTCALLBACK() BEGINEVENTCALLBACKEX(OnCommandApproach, OnCommandApproachEntity, CBaseEntity* goal) EVENTPUSHENTITY(goal) + EXECUTEEVENTCALLBACK() ENDEVENTCALLBACK() BEGINEVENTCALLBACK(OnCommandRetreat, CBaseEntity *threat, float range) EVENTPUSHENTITY(threat) EVENTPUSHFLOAT(range) + EXECUTEEVENTCALLBACK() ENDEVENTCALLBACK() BEGINEVENTCALLBACK(OnCommandPause, float duration) EVENTPUSHFLOAT(duration) + EXECUTEEVENTCALLBACK() ENDEVENTCALLBACK() BEGINEVENTCALLBACK(OnCommandResume) + EXECUTEEVENTCALLBACK() ENDEVENTCALLBACK() BEGINEVENTCALLBACK(OnCommandString, const char *command) EVENTPUSHSTRING(command) + EXECUTEEVENTCALLBACK() ENDEVENTCALLBACK() BEGINEVENTCALLBACK(OnShoved, CBaseEntity *pusher) EVENTPUSHENTITY(pusher) + EXECUTEEVENTCALLBACK() ENDEVENTCALLBACK() BEGINEVENTCALLBACK(OnBlinded, CBaseEntity *blinder) EVENTPUSHENTITY(blinder) + EXECUTEEVENTCALLBACK() ENDEVENTCALLBACK() BEGINEVENTCALLBACK(OnTerritoryContested, int territoryID) EVENTPUSHCELL(territoryID) + EXECUTEEVENTCALLBACK() ENDEVENTCALLBACK() BEGINEVENTCALLBACK(OnTerritoryCaptured, int territoryID) EVENTPUSHCELL(territoryID) + EXECUTEEVENTCALLBACK() ENDEVENTCALLBACK() BEGINEVENTCALLBACK(OnTerritoryLost, int territoryID) EVENTPUSHCELL(territoryID) + EXECUTEEVENTCALLBACK() ENDEVENTCALLBACK() BEGINEVENTCALLBACK(OnWin) + EXECUTEEVENTCALLBACK() ENDEVENTCALLBACK() BEGINEVENTCALLBACK(OnLose) + EXECUTEEVENTCALLBACK() ENDEVENTCALLBACK() CBaseNPCIntention::CBaseNPCIntention( INextBot * bot, CBaseNPCPluginActionFactory* initialActionFactory ) @@ -750,7 +837,9 @@ void CBaseNPCPluginActionFactory::OnCreateInitialAction(Action * pActi IPluginFunction * pCallback = GetCallback( CreateInitialAction ); if (pCallback && pCallback->IsRunnable()) { - pCallback->PushCell(PtrToPawnAddress(pAction)); + Handle_t hndlAction = PtrToPawnAddress(pAction, nullptr); + pCallback->PushCell(hndlAction); pCallback->Execute(nullptr); + ReleasePawnAddress(hndlAction, nullptr); } } diff --git a/extension/cbasenpc_locomotion.cpp b/extension/cbasenpc_locomotion.cpp index 1567512..7a30506 100644 --- a/extension/cbasenpc_locomotion.cpp +++ b/extension/cbasenpc_locomotion.cpp @@ -180,9 +180,13 @@ bool CBaseNPC_Locomotion::V_IsAbleToClimb() { cell_t _result = 0; - pCallback->PushCell(PtrToPawnAddress(this)); + Handle_t hndlThis = PtrToPawnAddress(this, nullptr); + + pCallback->PushCell(hndlThis); pCallback->Execute(&_result); + ReleasePawnAddress(hndlThis, nullptr); + result = !!_result; } else @@ -211,9 +215,13 @@ bool CBaseNPC_Locomotion::V_IsClimbingUpToLedge() { cell_t _result = 0; - pCallback->PushCell(PtrToPawnAddress(this)); + Handle_t hndlThis = PtrToPawnAddress(this, nullptr); + + pCallback->PushCell(hndlThis); pCallback->Execute(&_result); + ReleasePawnAddress(hndlThis, nullptr); + result = !!_result; } else @@ -285,12 +293,16 @@ bool CBaseNPC_Locomotion::V_ClimbUpToLedge(const Vector& vecGoal, const Vector& cell_t entRef = gamehelpers->EntityToBCompatRef(const_cast(pEntity)); cell_t _result = 0; - pCallback->PushCell(PtrToPawnAddress(this)); + Handle_t hndlThis = PtrToPawnAddress(this, nullptr); + + pCallback->PushCell(hndlThis); pCallback->PushArray(goalArr, 3); pCallback->PushArray(forwardArr, 3); pCallback->PushCell(entRef); pCallback->Execute(&_result); + ReleasePawnAddress(hndlThis, nullptr); + result = !!_result; } else @@ -319,9 +331,13 @@ bool CBaseNPC_Locomotion::V_IsAbleToJumpAcrossGaps() { cell_t _result = 0; - pCallback->PushCell(PtrToPawnAddress(this)); + Handle_t hndlThis = PtrToPawnAddress(this, nullptr); + + pCallback->PushCell(hndlThis); pCallback->Execute(&_result); + ReleasePawnAddress(hndlThis, nullptr); + result = !!_result; } else @@ -350,9 +366,13 @@ bool CBaseNPC_Locomotion::V_IsJumpingAcrossGap() { cell_t _result = 0; - pCallback->PushCell(PtrToPawnAddress(this)); + Handle_t hndlThis = PtrToPawnAddress(this, nullptr); + + pCallback->PushCell(hndlThis); pCallback->Execute(&_result); + ReleasePawnAddress(hndlThis, nullptr); + result = !!_result; } else @@ -383,10 +403,14 @@ void CBaseNPC_Locomotion::V_JumpAcrossGap(const Vector& landingGoal, const Vecto VectorToPawnVector(forwardArr, landingForward); cell_t result = 0; - pCallback->PushCell(PtrToPawnAddress(this)); + Handle_t hndlThis = PtrToPawnAddress(this, nullptr); + + pCallback->PushCell(hndlThis); pCallback->PushArray(goalArr, 3); pCallback->PushArray(forwardArr, 3); pCallback->Execute(&result); + + ReleasePawnAddress(hndlThis, nullptr); } else { @@ -418,11 +442,15 @@ bool CBaseNPC_Locomotion::V_IsEntityTraversable(CBaseEntity* pEntity, ILocomotio cell_t entRef = gamehelpers->EntityToBCompatRef(pEntity); cell_t _result = 0; - pCallback->PushCell(PtrToPawnAddress(this)); + Handle_t hndlThis = PtrToPawnAddress(this, nullptr); + + pCallback->PushCell(hndlThis); pCallback->PushCell(entRef); pCallback->PushCell((cell_t)when); pCallback->Execute(&_result); + ReleasePawnAddress(hndlThis, nullptr); + result = !!_result; } else @@ -452,10 +480,14 @@ bool CBaseNPC_Locomotion::V_ShouldCollideWith(const CBaseEntity* pEntity) cell_t entRef = gamehelpers->EntityToBCompatRef(const_cast(pEntity)); cell_t _result = 0; - pCallback->PushCell(PtrToPawnAddress(this)); + Handle_t hndlThis = PtrToPawnAddress(this, nullptr); + + pCallback->PushCell(hndlThis); pCallback->PushCell(entRef); pCallback->Execute(&_result); + ReleasePawnAddress(hndlThis, nullptr); + result = !!_result; } else diff --git a/extension/extension.cpp b/extension/extension.cpp index 6ac1280..a015068 100644 --- a/extension/extension.cpp +++ b/extension/extension.cpp @@ -54,6 +54,7 @@ extern ConVar* nb_update_framelimit; extern ConVar* nb_update_maxslide; HandleType_t g_KeyValueType; +HandleType_t g_MemoryPtr; CBaseNPCExt g_CBaseNPCExt; SMEXT_LINK(&g_CBaseNPCExt); @@ -211,6 +212,7 @@ void CBaseNPCExt::SDK_OnAllLoaded() { SM_GET_LATE_IFACE(SDKHOOKS, g_pSDKHooks); handlesys->FindHandleType("KeyValues", &g_KeyValueType); + handlesys->FindHandleType("MemoryPointer", &g_MemoryPtr); // HACK: Get g_pCoreIdent from KeyValues QHandleType // g_KeyValueType is an index of QHandleType array m_Types diff --git a/extension/helpers.h b/extension/helpers.h index 8d32c46..dda7ace 100644 --- a/extension/helpers.h +++ b/extension/helpers.h @@ -4,6 +4,7 @@ #pragma once #include "smsdk_ext.h" +#include "IMemoryPointer.h" #include #include #include @@ -148,25 +149,86 @@ inline void VectorToPawnVector(cell_t* angAddr, const QAngle* angle) angAddr[2] = sp_ftoc(angle->z); } -inline cell_t PtrToPawnAddress(const void* ptr) { -#ifdef PLATFORM_X64 - return g_pSM->ToPseudoAddress((void*)(ptr)); -#else - return (cell_t)ptr; -#endif -} +class ForeignMemoryPointer : IMemoryPointer { +public: + ForeignMemoryPointer(const void* ptr) : m_ptr(ptr) {} + + virtual void Delete() override + { + delete this; + } -inline void* PawnAddressToPtr(cell_t addr) { -#ifdef PLATFORM_X64 - if (!addr) { - // BUGFIX: Passing 0 to FromPseudoAddress won't return nullptr but a valid pseudo address. - // If we're getting 0 from a plugin then we treat it as nullptr since Address_Null is 0. + virtual cell_t GetSize() override + { return 0; } - return (void*)g_pSM->FromPseudoAddress(addr); -#else - return (void*)addr; -#endif + + virtual void* Get() override + { + return (void*)m_ptr; + } +protected: + const void* m_ptr; +}; + +extern HandleType_t g_MemoryPtr; + +inline void ReleasePawnAddress(Handle_t hndl, IPluginContext* context) +{ + HandleSecurity security; + security.pIdentity = myself->GetIdentity(); + if (context) { + security.pOwner = context->GetIdentity(); + } else { + security.pOwner = nullptr; + } + + handlesys->FreeHandle(hndl, &security); +} + +inline Handle_t PtrToPawnAddress(const void* ptr, IPluginContext* context) { + auto foreignPtr = new ForeignMemoryPointer(ptr); + + IdentityToken_t* identity = nullptr; + if (context) { + identity = context->GetIdentity(); + } + + Handle_t handle = handlesys->CreateHandle(g_MemoryPtr, foreignPtr, identity, myself->GetIdentity(), nullptr); + if (handle == BAD_HANDLE) + { + delete foreignPtr; + return BAD_HANDLE; + } + + return handle; +} + +inline void* PawnAddressToPtr(cell_t cellHndl, IPluginContext* context) { + Handle_t hndl = (Handle_t)cellHndl; + if (hndl == BAD_HANDLE) { + return nullptr; + } + + HandleError err = HandleError_None; + IMemoryPointer* ptr = nullptr; + + HandleSecurity security; + security.pIdentity = myself->GetIdentity(); + if (context) { + security.pOwner = context->GetIdentity(); + } else { + security.pOwner = nullptr; + } + + if ((err=handlesys->ReadHandle(hndl, g_MemoryPtr, &security, (void **)&ptr)) != HandleError_None || ptr == nullptr) { + if (context) { + context->ThrowNativeError("Could not read Handle %x (error %d)", hndl, err); + } + return nullptr; + } + + return ptr->Get(); } #if SOURCEPAWN_API_VERSION >= 0x0211 diff --git a/extension/natives.cpp b/extension/natives.cpp index 8c2078f..e27e784 100644 --- a/extension/natives.cpp +++ b/extension/natives.cpp @@ -118,14 +118,14 @@ void Event_Killed(CTakeDamageInfoHack &info) RETURN_META(MRES_IGNORED); } -cell_t CBaseNPC_GetNextBotOfEntity(IPluginContext *pContext, const cell_t *params) { +cell_t CBaseNPC_GetNextBotOfEntity(IPluginContext* pContext, const cell_t *params) { CBaseEntity *pEntity; ENTINDEX_TO_CBASEENTITY(params[1], pEntity); - return PtrToPawnAddress(pEntity->MyNextBotPointer()); + return PtrToPawnAddress(pEntity->MyNextBotPointer(), pContext); } -cell_t CBaseNPC_HookEventKilled(IPluginContext *pContext, const cell_t *params) +cell_t CBaseNPC_HookEventKilled(IPluginContext* pContext, const cell_t *params) { CBaseEntity *pEntity; ENTINDEX_TO_CBASEENTITY(params[1], pEntity); @@ -139,22 +139,22 @@ cell_t CBaseNPC_HookEventKilled(IPluginContext *pContext, const cell_t *params) return 1; } -cell_t Util_ConcatTransforms(IPluginContext* pContext, const cell_t* params) { +cell_t Util_ConcatTransforms(IPluginContext* context, const cell_t* params) { cell_t* inMat1; cell_t* inMat2; cell_t* outMat; - pContext->LocalToPhysAddr(params[1], &inMat1); - pContext->LocalToPhysAddr(params[2], &inMat2); - pContext->LocalToPhysAddr(params[3], &outMat); + context->LocalToPhysAddr(params[1], &inMat1); + context->LocalToPhysAddr(params[2], &inMat2); + context->LocalToPhysAddr(params[3], &outMat); matrix3x4_t in1; matrix3x4_t in2; matrix3x4_t out; - PawnMatrixToMatrix(pContext, inMat1, in1); - PawnMatrixToMatrix(pContext, inMat2, in2); + PawnMatrixToMatrix(context, inMat1, in1); + PawnMatrixToMatrix(context, inMat2, in2); ConcatTransforms(in1, in2, out); - MatrixToPawnMatrix(pContext, outMat, out); + MatrixToPawnMatrix(context, outMat, out); return 0; } diff --git a/extension/natives/baseanimating.cpp b/extension/natives/baseanimating.cpp index 9de0a1b..558ca1a 100644 --- a/extension/natives/baseanimating.cpp +++ b/extension/natives/baseanimating.cpp @@ -133,7 +133,7 @@ cell_t GetModelPtr(IPluginContext* context, const cell_t* params) { return 0; } - return PtrToPawnAddress(entity->GetModelPtr()); + return PtrToPawnAddress(entity->GetModelPtr(), context); } cell_t LookupPoseParameter(IPluginContext* context, const cell_t* params) { diff --git a/extension/natives/baseanimatingoverlay.cpp b/extension/natives/baseanimatingoverlay.cpp index 61fba02..eedb180 100644 --- a/extension/natives/baseanimatingoverlay.cpp +++ b/extension/natives/baseanimatingoverlay.cpp @@ -6,7 +6,7 @@ namespace natives::baseanimatingoverlay { namespace layer { inline CAnimationLayer* Get(IPluginContext* context, const cell_t param) { - CAnimationLayer* layer = (CAnimationLayer*)PawnAddressToPtr(param); + CAnimationLayer* layer = (CAnimationLayer*)PawnAddressToPtr(param, context); if (!layer) { context->ThrowNativeError("Layer is a null ptr!"); return nullptr; @@ -697,7 +697,7 @@ cell_t GetAnimOverlay(IPluginContext* context, const cell_t* params) { return 0; } - return PtrToPawnAddress(entity->GetAnimOverlay(params[2])); + return PtrToPawnAddress(entity->GetAnimOverlay(params[2]), context); }; cell_t GetNumAnimOverlays(IPluginContext* context, const cell_t* params) { diff --git a/extension/natives/basecombatcharacter.cpp b/extension/natives/basecombatcharacter.cpp index 0059999..2d676b7 100644 --- a/extension/natives/basecombatcharacter.cpp +++ b/extension/natives/basecombatcharacter.cpp @@ -34,7 +34,7 @@ cell_t GetLastKnownArea(IPluginContext* context, const cell_t* params) { return 0; } - return PtrToPawnAddress(entity->GetLastKnownArea()); + return PtrToPawnAddress(entity->GetLastKnownArea(), context); }; void setup(std::vector& natives) { diff --git a/extension/natives/baseentity.cpp b/extension/natives/baseentity.cpp index c6f506e..f70d956 100644 --- a/extension/natives/baseentity.cpp +++ b/extension/natives/baseentity.cpp @@ -23,7 +23,7 @@ cell_t NetworkProp(IPluginContext* context, const cell_t* params) { return 0; } - return PtrToPawnAddress(entity->NetworkProp()); + return PtrToPawnAddress(entity->NetworkProp(), context); } cell_t CollisionProp(IPluginContext* context, const cell_t* params) { @@ -32,7 +32,7 @@ cell_t CollisionProp(IPluginContext* context, const cell_t* params) { return 0; } - return PtrToPawnAddress(entity->CollisionProp()); + return PtrToPawnAddress(entity->CollisionProp(), context); } cell_t DispatchUpdateTransmitState(IPluginContext* context, const cell_t* params) { @@ -300,7 +300,7 @@ cell_t NetworkStateChangedVar(IPluginContext* context, const cell_t* params) { return 0; } - entity->NetworkStateChanged(PawnAddressToPtr(params[2])); + entity->NetworkStateChanged(PawnAddressToPtr(params[2], context)); return 0; } @@ -480,7 +480,7 @@ cell_t MyNextBotPointer(IPluginContext* context, const cell_t* params) { return 0; } - return PtrToPawnAddress(entity->MyNextBotPointer()); + return PtrToPawnAddress(entity->MyNextBotPointer(), context); } cell_t GetBaseAnimating(IPluginContext* context, const cell_t* params) { @@ -516,7 +516,7 @@ cell_t TakeDamage(IPluginContext* context, const cell_t* params) { return 0; } - CTakeDamageInfo* inputInfo = (CTakeDamageInfo*)PawnAddressToPtr(params[2]); + CTakeDamageInfo* inputInfo = (CTakeDamageInfo*)PawnAddressToPtr(params[2], context); if (!inputInfo) { context->ThrowNativeError("CTakeDamageInfo is a null ptr!"); return 0; diff --git a/extension/natives/cbasenpc.cpp b/extension/natives/cbasenpc.cpp index 34c836f..06587af 100644 --- a/extension/natives/cbasenpc.cpp +++ b/extension/natives/cbasenpc.cpp @@ -47,7 +47,7 @@ void setup(std::vector& natives) { namespace locomotion { inline CBaseNPC_Locomotion* Get(IPluginContext* context, const cell_t param) { - CBaseNPC_Locomotion* mover = (CBaseNPC_Locomotion*)PawnAddressToPtr(param); + CBaseNPC_Locomotion* mover = (CBaseNPC_Locomotion*)PawnAddressToPtr(param, context); if (!mover) { context->ThrowNativeError("Invalid Locomotion %i", param); return nullptr; @@ -261,7 +261,7 @@ cell_t GetBot(IPluginContext* context, const cell_t* params) { return 0; } - return PtrToPawnAddress(npc->GetEntity()->MyNextBotPointer()); + return PtrToPawnAddress(npc->GetEntity()->MyNextBotPointer(), context); } cell_t GetLocomotion(IPluginContext* context, const cell_t* params) { @@ -270,7 +270,7 @@ cell_t GetLocomotion(IPluginContext* context, const cell_t* params) { return 0; } - return PtrToPawnAddress(npc->m_pMover); + return PtrToPawnAddress(npc->m_pMover, context); } cell_t GetBody(IPluginContext* context, const cell_t* params) { @@ -279,7 +279,7 @@ cell_t GetBody(IPluginContext* context, const cell_t* params) { return 0; } - return PtrToPawnAddress(npc->m_pBody); + return PtrToPawnAddress(npc->m_pBody, context); } cell_t GetVision(IPluginContext* context, const cell_t* params) { @@ -288,7 +288,7 @@ cell_t GetVision(IPluginContext* context, const cell_t* params) { return 0; } - return PtrToPawnAddress(npc->GetEntity()->MyNextBotPointer()->GetVisionInterface()); + return PtrToPawnAddress(npc->GetEntity()->MyNextBotPointer()->GetVisionInterface(), context); } cell_t GetIntention(IPluginContext* context, const cell_t* params) { @@ -297,7 +297,7 @@ cell_t GetIntention(IPluginContext* context, const cell_t* params) { return 0; } - return PtrToPawnAddress(npc->GetEntity()->MyNextBotPointer()->GetIntentionInterface()); + return PtrToPawnAddress(npc->GetEntity()->MyNextBotPointer()->GetIntentionInterface(), context); } cell_t SetType(IPluginContext* context, const cell_t* params) { diff --git a/extension/natives/nav.cpp b/extension/natives/nav.cpp index d968adb..9d33646 100644 --- a/extension/natives/nav.cpp +++ b/extension/natives/nav.cpp @@ -31,7 +31,7 @@ cell_t GetElement(IPluginContext* context, const cell_t* params) { if (ID > collector->Count()) { return 0; } - return PtrToPawnAddress(collector->Element(ID)); + return PtrToPawnAddress(collector->Element(ID), context); } void setup(std::vector& natives) { @@ -48,7 +48,11 @@ void setup(std::vector& natives) { } cell_t GetAddress(IPluginContext* context, const cell_t* params) { - return PtrToPawnAddress(TheNavMesh); + static Handle_t hndlNavMesh = BAD_HANDLE; + if (hndlNavMesh == BAD_HANDLE) { + hndlNavMesh = PtrToPawnAddress(TheNavMesh, nullptr); + } + return hndlNavMesh; } cell_t IsLoaded(IPluginContext* context, const cell_t* params) { @@ -72,7 +76,7 @@ cell_t GetNavArea(IPluginContext* context, const cell_t* params) { context->LocalToPhysAddr(params[2], &vecAddr); Vector vecPos; PawnVectorToVector(vecAddr, vecPos); - return PtrToPawnAddress(ToolsNavMesh->GetNavArea(vecPos, sp_ctof(params[3]))); + return PtrToPawnAddress(ToolsNavMesh->GetNavArea(vecPos, sp_ctof(params[3])), context); } cell_t GetNavAreaEntity(IPluginContext* context, const cell_t* params) { @@ -80,7 +84,7 @@ cell_t GetNavAreaEntity(IPluginContext* context, const cell_t* params) { if (!ent) { return context->ThrowNativeError("Invalid Entity index/reference %d", params[1]); } - return PtrToPawnAddress(ToolsNavMesh->GetNavArea(ent, params[3], sp_ctof(params[4]))); + return PtrToPawnAddress(ToolsNavMesh->GetNavArea(ent, params[3], sp_ctof(params[4])), context); } cell_t GetNearestNavArea(IPluginContext* context, const cell_t* params) { @@ -88,12 +92,12 @@ cell_t GetNearestNavArea(IPluginContext* context, const cell_t* params) { context->LocalToPhysAddr(params[2], &vecAddr); Vector vecPos; PawnVectorToVector(vecAddr, vecPos); - return PtrToPawnAddress(ToolsNavMesh->GetNearestNavArea(vecPos, params[3], sp_ctof(params[4]), params[5], params[6], params[7])); + return PtrToPawnAddress(ToolsNavMesh->GetNearestNavArea(vecPos, params[3], sp_ctof(params[4]), params[5], params[6], params[7]), context); } cell_t GetNavAreaByID(IPluginContext* context, const cell_t* params) { unsigned int id = (unsigned int)params[2]; - return PtrToPawnAddress(ToolsNavMesh->GetNavAreaByID(id)); + return PtrToPawnAddress(ToolsNavMesh->GetNavAreaByID(id), context); } class CCollectorAddToTail { @@ -107,7 +111,7 @@ class CCollectorAddToTail { cell_t CollectSurroundingAreas(IPluginContext* context, const cell_t* params) { CUtlVector *pCollector = new CUtlVector; - CollectSurroundingAreas( pCollector, (CNavArea*)PawnAddressToPtr(params[2]), sp_ctof(params[3]), sp_ctof(params[4]), sp_ctof(params[5])); + CollectSurroundingAreas( pCollector, (CNavArea*)PawnAddressToPtr(params[2], context), sp_ctof(params[3]), sp_ctof(params[4]), sp_ctof(params[5])); return CREATEHANDLE(AreasCollector, pCollector); } @@ -145,8 +149,8 @@ cell_t CollectAreasInRadius(IPluginContext* context, const cell_t* params) { } cell_t CollectAreasAlongLine(IPluginContext* context, const cell_t* params) { - CNavArea* startArea = (CNavArea*)PawnAddressToPtr(params[2]); - CNavArea* endArea = (CNavArea*)PawnAddressToPtr(params[3]); + CNavArea* startArea = (CNavArea*)PawnAddressToPtr(params[2], context); + CNavArea* endArea = (CNavArea*)PawnAddressToPtr(params[3], context); cell_t* reachedEndAddr; context->LocalToPhysAddr(params[4], &reachedEndAddr); @@ -166,13 +170,22 @@ class SMPathCost : public IPathCost { if (m_pFunc && m_pFunc->IsRunnable()) { + Handle_t hndlArea = PtrToPawnAddress(area, nullptr); + Handle_t hndlFromArea = PtrToPawnAddress(fromArea, nullptr); + Handle_t hndlLadder = PtrToPawnAddress(ladder, nullptr); + cell_t result = sp_ftoc(0.0); - m_pFunc->PushCell(PtrToPawnAddress(area)); - m_pFunc->PushCell(PtrToPawnAddress(fromArea)); - m_pFunc->PushCell(PtrToPawnAddress(ladder)); + m_pFunc->PushCell(hndlArea); + m_pFunc->PushCell(hndlFromArea); + m_pFunc->PushCell(hndlLadder); m_pFunc->PushCell(gamehelpers->EntityToBCompatRef((CBaseEntity*)elevator)); m_pFunc->PushFloat(length); m_pFunc->Execute(&result); + + ReleasePawnAddress(hndlArea, nullptr); + ReleasePawnAddress(hndlFromArea, nullptr); + ReleasePawnAddress(hndlLadder, nullptr); + return sp_ctof(result); } else { @@ -215,12 +228,12 @@ class SMPathCost : public IPathCost }; cell_t BuildPath(IPluginContext* context, const cell_t* params) { - CNavArea *startArea = (CNavArea *)PawnAddressToPtr(params[2]); + CNavArea *startArea = (CNavArea *)PawnAddressToPtr(params[2], context); if (!startArea) { return context->ThrowNativeError("Starting area is null!"); } - CNavArea* goalArea = (CNavArea *)PawnAddressToPtr(params[3]); + CNavArea* goalArea = (CNavArea *)PawnAddressToPtr(params[3], context); cell_t* goalPosAddr; context->LocalToPhysAddr(params[4], &goalPosAddr); Vector goalPos; @@ -248,7 +261,7 @@ cell_t BuildPath(IPluginContext* context, const cell_t* params) { ignoreNavBlockers); if (closestAreaAddr) { - *closestAreaAddr = PtrToPawnAddress(closestArea); + *closestAreaAddr = PtrToPawnAddress(closestArea, context); } return result; diff --git a/extension/natives/nav/area.cpp b/extension/natives/nav/area.cpp index 36fff52..0014ccd 100644 --- a/extension/natives/nav/area.cpp +++ b/extension/natives/nav/area.cpp @@ -19,7 +19,7 @@ inline cell_t Get(IPluginContext* context, const cell_t* params) if (i < 0 || i >= TheHidingSpots.Count()) { return context->ThrowNativeError("Index is out of bounds!"); } - return PtrToPawnAddress(TheHidingSpots[i]); + return PtrToPawnAddress(TheHidingSpots[i], context); } void setup(std::vector& natives) { @@ -38,7 +38,7 @@ void setup(std::vector& natives) { } inline HidingSpot* Get(IPluginContext* context, const cell_t param) { - HidingSpot* spot = (HidingSpot*)PawnAddressToPtr(param); + HidingSpot* spot = (HidingSpot*)PawnAddressToPtr(param, context); if (!spot) { context->ThrowNativeError("Hiding spot ptr is null!"); return nullptr; @@ -82,7 +82,7 @@ cell_t GetArea(IPluginContext* context, const cell_t* params) { return 0; } - return PtrToPawnAddress(spot->GetArea()); + return PtrToPawnAddress(spot->GetArea(), context); } void setup(std::vector& natives) { @@ -103,7 +103,7 @@ void setup(std::vector& natives) { namespace ladder { inline CNavLadder* Get(IPluginContext* context, const cell_t param) { - CNavLadder* spot = (CNavLadder*)PawnAddressToPtr(param); + CNavLadder* spot = (CNavLadder*)PawnAddressToPtr(param, context); if (!spot) { context->ThrowNativeError("Nav ladder ptr is null!"); return nullptr; @@ -146,7 +146,7 @@ inline cell_t Get(IPluginContext* context, const cell_t* params) if (i < 0 || i >= TheNavAreas.Count()) { return context->ThrowNativeError("Index is out of bounds!"); } - return PtrToPawnAddress(TheNavAreas[i]); + return PtrToPawnAddress(TheNavAreas[i], context); } void setup(std::vector& natives) { @@ -173,11 +173,11 @@ cell_t IsOpenListEmpty(IPluginContext* context, const cell_t* params) { } cell_t PopOpenList(IPluginContext* context, const cell_t* params) { - return PtrToPawnAddress(CNavArea::PopOpenList()); + return PtrToPawnAddress(CNavArea::PopOpenList(), context); } inline CNavArea* Get(IPluginContext* context, const cell_t param) { - CNavArea* area = (CNavArea*)PawnAddressToPtr(param); + CNavArea* area = (CNavArea*)PawnAddressToPtr(param, context); if (!area) { context->ThrowNativeError("Nav area ptr is null!"); return nullptr; @@ -219,7 +219,7 @@ cell_t SetParent(IPluginContext* context, const cell_t* params) { return 0; } - area->SetParent((CNavArea*)PawnAddressToPtr(params[2]), (NavTraverseType)params[3]); + area->SetParent((CNavArea*)PawnAddressToPtr(params[2], context), (NavTraverseType)params[3]); return 1; } @@ -229,7 +229,7 @@ cell_t GetParent(IPluginContext* context, const cell_t* params) { return 0; } - return PtrToPawnAddress(area->GetParent()); + return PtrToPawnAddress(area->GetParent(), context); } cell_t GetParentHow(IPluginContext* context, const cell_t* params) { @@ -304,7 +304,7 @@ cell_t ComputePortal(IPluginContext* context, const cell_t* params) { return 0; } - CNavArea* other = (CNavArea*)PawnAddressToPtr(params[2]); + CNavArea* other = (CNavArea*)PawnAddressToPtr(params[2], context); if (!other) { return context->ThrowNativeError("Nav area is null !"); } @@ -328,7 +328,7 @@ cell_t ComputeClosestPointInPortal(IPluginContext* context, const cell_t* params return 0; } - CNavArea* other = (CNavArea*)PawnAddressToPtr(params[2]); + CNavArea* other = (CNavArea*)PawnAddressToPtr(params[2], context); if (!other) { return context->ThrowNativeError("Nav area is null !"); } @@ -436,7 +436,7 @@ cell_t IsConnected(IPluginContext* context, const cell_t* params) { return 0; } - return area->IsConnected((CNavArea*)PawnAddressToPtr(params[2]), (NavDirType)params[3]); + return area->IsConnected((CNavArea*)PawnAddressToPtr(params[2], context), (NavDirType)params[3]); } cell_t IsOverlappingPoint(IPluginContext* context, const cell_t* params) { @@ -568,7 +568,7 @@ cell_t GetAdjacentArea(IPluginContext* context, const cell_t* params) { if (dir < 0 || dir >= NUM_DIRECTIONS) { return context->ThrowNativeError("Invalid direction %d", dir); } - return PtrToPawnAddress(area->GetAdjacentArea(dir, params[3])); + return PtrToPawnAddress(area->GetAdjacentArea(dir, params[3]), context); } cell_t GetAdjacentLength(IPluginContext* context, const cell_t* params) { @@ -619,7 +619,7 @@ cell_t GetIncomingConnection(IPluginContext* context, const cell_t* params) { if (i < 0 || i >= incoming->Count()) { return 0; } - return PtrToPawnAddress(incoming->Element(i).area); + return PtrToPawnAddress(incoming->Element(i).area, context); } cell_t GetIncomingConnectionLength(IPluginContext* context, const cell_t* params) { @@ -657,7 +657,7 @@ cell_t Contains(IPluginContext* context, const cell_t* params) { return 0; } - return area->Contains((CNavArea*)PawnAddressToPtr(params[2])); + return area->Contains((CNavArea*)PawnAddressToPtr(params[2], context)); } cell_t ContainsPoint(IPluginContext* context, const cell_t* params) { @@ -769,7 +769,7 @@ cell_t GetHidingSpot(IPluginContext* context, const cell_t* params) { if ((i < 0) || (i >= pSpots->Count())) { return 0; } - return PtrToPawnAddress(pSpots->Element(i)); + return PtrToPawnAddress(pSpots->Element(i), context); } cell_t IsOpen(IPluginContext* context, const cell_t* params) { @@ -864,7 +864,7 @@ cell_t IsPotentiallyVisible(IPluginContext* context, const cell_t* params) { return 0; } - CNavArea* viewedArea = (CNavArea*)PawnAddressToPtr(params[2]); + CNavArea* viewedArea = (CNavArea*)PawnAddressToPtr(params[2], context); if (!viewedArea) { return context->ThrowNativeError("Nav area is null !"); } @@ -877,16 +877,16 @@ cell_t IsCompletelyVisible(IPluginContext* context, const cell_t* params) { return 0; } - CNavArea* viewedArea = (CNavArea*)PawnAddressToPtr(params[2]); + CNavArea* viewedArea = (CNavArea*)PawnAddressToPtr(params[2], context); if (!viewedArea) { return context->ThrowNativeError("Nav area is null !"); } return area->IsCompletelyVisible(viewedArea); } -cell_t native_GetHidingSpotByID(IPluginContext* pContext, const cell_t* params) { +cell_t native_GetHidingSpotByID(IPluginContext* context, const cell_t* params) { unsigned int id = params[1]; - return PtrToPawnAddress(GetHidingSpotByID(id)); + return PtrToPawnAddress(GetHidingSpotByID(id), context); } void setup(std::vector& natives) { diff --git a/extension/natives/nextbot.cpp b/extension/natives/nextbot.cpp index 2c7b828..f49045a 100644 --- a/extension/natives/nextbot.cpp +++ b/extension/natives/nextbot.cpp @@ -15,7 +15,7 @@ namespace natives::nextbot { template inline T* Get(IPluginContext* context, const cell_t param) { - T* bot = (T*)PawnAddressToPtr(param); + T* bot = (T*)PawnAddressToPtr(param, context); if (!bot) { context->ThrowNativeError("Bot is a null ptr!"); return nullptr; @@ -79,7 +79,7 @@ cell_t GetLocomotionInterface(IPluginContext* context, const cell_t* params) { if (!bot) { return 0; } - return PtrToPawnAddress(bot->GetLocomotionInterface()); + return PtrToPawnAddress(bot->GetLocomotionInterface(), context); } cell_t GetBodyInterface(IPluginContext* context, const cell_t* params) { @@ -87,7 +87,7 @@ cell_t GetBodyInterface(IPluginContext* context, const cell_t* params) { if (!bot) { return 0; } - return PtrToPawnAddress(bot->GetBodyInterface()); + return PtrToPawnAddress(bot->GetBodyInterface(), context); } cell_t GetIntentionInterface(IPluginContext* context, const cell_t* params) { @@ -95,7 +95,7 @@ cell_t GetIntentionInterface(IPluginContext* context, const cell_t* params) { if (!bot) { return 0; } - return PtrToPawnAddress(bot->GetIntentionInterface()); + return PtrToPawnAddress(bot->GetIntentionInterface(), context); } cell_t GetVisionInterface(IPluginContext* context, const cell_t* params) { @@ -103,7 +103,7 @@ cell_t GetVisionInterface(IPluginContext* context, const cell_t* params) { if (!bot) { return 0; } - return PtrToPawnAddress(bot->GetVisionInterface()); + return PtrToPawnAddress(bot->GetVisionInterface(), context); } cell_t SetPosition(IPluginContext* context, const cell_t* params) { @@ -274,7 +274,7 @@ cell_t GetCurrentPath(IPluginContext* context, const cell_t* params) { return 0; } - return PtrToPawnAddress(bot->GetCurrentPath()); + return PtrToPawnAddress(bot->GetCurrentPath(), context); } cell_t SetCurrentPath(IPluginContext* context, const cell_t* params) { @@ -283,7 +283,7 @@ cell_t SetCurrentPath(IPluginContext* context, const cell_t* params) { return 0; } - bot->SetCurrentPath((PathFollower*)PawnAddressToPtr(params[2])); + bot->SetCurrentPath((PathFollower*)PawnAddressToPtr(params[2], context)); return 0; } @@ -293,7 +293,7 @@ cell_t NotifyPathDestruction(IPluginContext* context, const cell_t* params) { return 0; } - bot->NotifyPathDestruction((PathFollower*)PawnAddressToPtr(params[2])); + bot->NotifyPathDestruction((PathFollower*)PawnAddressToPtr(params[2], context)); return 0; } @@ -454,12 +454,12 @@ cell_t DisplayDebugText(IPluginContext* context, const cell_t* params) { } cell_t ToolsNextBot(IPluginContext* context, const cell_t* params) { - CBaseCombatCharacter* entity = (CBaseCombatCharacter*)PawnAddressToPtr(params[1]); + CBaseCombatCharacter* entity = (CBaseCombatCharacter*)PawnAddressToPtr(params[1], context); if (!entity) { return context->ThrowNativeError("Invalid entity address %x", params[1]); } - return PtrToPawnAddress(new class ToolsNextBot(entity)); + return PtrToPawnAddress(new class ToolsNextBot(entity), context); } void setup(std::vector& natives) { diff --git a/extension/natives/nextbot/behavior.cpp b/extension/natives/nextbot/behavior.cpp index 707dcc9..432239f 100644 --- a/extension/natives/nextbot/behavior.cpp +++ b/extension/natives/nextbot/behavior.cpp @@ -83,7 +83,7 @@ cell_t Create(IPluginContext* context, const cell_t* params) { return 0; } - return PtrToPawnAddress(factory->Create()); + return PtrToPawnAddress(factory->Create(), context); } cell_t BeginDataMapDesc(IPluginContext* context, const cell_t* params) { @@ -171,7 +171,7 @@ void setup(std::vector& natives) { } inline CBaseNPCPluginAction* Get(IPluginContext* context, const cell_t param) { - CBaseNPCPluginAction* action = (CBaseNPCPluginAction*)PawnAddressToPtr(param); + CBaseNPCPluginAction* action = (CBaseNPCPluginAction*)PawnAddressToPtr(param, context); if (!action) { context->ThrowNativeError("CBaseNPCPluginAction ptr is null!"); return nullptr; @@ -301,7 +301,7 @@ cell_t GetParent(IPluginContext* context, const cell_t* params) { return 0; } - return PtrToPawnAddress(action->GetParentAction()); + return PtrToPawnAddress(action->GetParentAction(), context); } cell_t GetActiveChild(IPluginContext* context, const cell_t* params) { @@ -310,7 +310,7 @@ cell_t GetActiveChild(IPluginContext* context, const cell_t* params) { return 0; } - return PtrToPawnAddress(action->GetActiveChildAction()); + return PtrToPawnAddress(action->GetActiveChildAction(), context); } cell_t GetActionBuriedUnderMe(IPluginContext* context, const cell_t* params) { @@ -319,7 +319,7 @@ cell_t GetActionBuriedUnderMe(IPluginContext* context, const cell_t* params) { return 0; } - return PtrToPawnAddress(action->GetActionBuriedUnderMe()); + return PtrToPawnAddress(action->GetActionBuriedUnderMe(), context); } cell_t GetActionCoveringMe(IPluginContext* context, const cell_t* params) { @@ -328,7 +328,7 @@ cell_t GetActionCoveringMe(IPluginContext* context, const cell_t* params) { return 0; } - return PtrToPawnAddress(action->GetActionCoveringMe()); + return PtrToPawnAddress(action->GetActionCoveringMe(), context); } cell_t GetIsSuspended(IPluginContext* context, const cell_t* params) { @@ -531,7 +531,7 @@ cell_t ChangeTo(IPluginContext* context, const cell_t* params) { char* reason = nullptr; context->LocalToStringNULL( params[3], &reason ); - action->PluginChangeTo( (CBaseNPCPluginAction*)PawnAddressToPtr(params[2]), reason ); + action->PluginChangeTo( (CBaseNPCPluginAction*)PawnAddressToPtr(params[2], context), reason ); return 0; } @@ -547,7 +547,7 @@ cell_t SuspendFor(IPluginContext* context, const cell_t* params) { char* reason = nullptr; context->LocalToStringNULL( params[3], &reason ); - action->PluginSuspendFor( (CBaseNPCPluginAction*)PawnAddressToPtr(params[2]), reason ); + action->PluginSuspendFor( (CBaseNPCPluginAction*)PawnAddressToPtr(params[2], context), reason ); return 0; } @@ -591,7 +591,7 @@ cell_t TryChangeTo(IPluginContext* context, const cell_t* params) { return context->ThrowNativeError( "Cannot use TryChangeTo() outside of event callback" ); } - CBaseNPCPluginAction* otherAction = (CBaseNPCPluginAction*)PawnAddressToPtr(params[2]); + CBaseNPCPluginAction* otherAction = (CBaseNPCPluginAction*)PawnAddressToPtr(params[2], context); if (!otherAction) { return context->ThrowNativeError("action is NULL"); } @@ -613,7 +613,7 @@ cell_t TrySuspendFor(IPluginContext* context, const cell_t* params) { return context->ThrowNativeError( "Cannot use TrySuspendFor() outside of event callback" ); } - CBaseNPCPluginAction* otherAction = (CBaseNPCPluginAction*)PawnAddressToPtr(params[2]); + CBaseNPCPluginAction* otherAction = (CBaseNPCPluginAction*)PawnAddressToPtr(params[2], context); if (!otherAction) { return context->ThrowNativeError("action is NULL"); } diff --git a/extension/natives/nextbot/body.cpp b/extension/natives/nextbot/body.cpp index 284da73..00e9d19 100644 --- a/extension/natives/nextbot/body.cpp +++ b/extension/natives/nextbot/body.cpp @@ -5,7 +5,7 @@ namespace natives::nextbot::body { inline IBody* Get(IPluginContext* context, const cell_t param) { - IBody* body = (IBody*)PawnAddressToPtr(param); + IBody* body = (IBody*)PawnAddressToPtr(param, context); if (!body) { context->ThrowNativeError("Body ptr is null!"); return nullptr; diff --git a/extension/natives/nextbot/component.cpp b/extension/natives/nextbot/component.cpp index 36493f6..0eb0feb 100644 --- a/extension/natives/nextbot/component.cpp +++ b/extension/natives/nextbot/component.cpp @@ -3,7 +3,7 @@ namespace natives::nextbot::component { inline INextBotComponent* Get(IPluginContext* context, const cell_t param) { - INextBotComponent* component = (INextBotComponent*)PawnAddressToPtr(param); + INextBotComponent* component = (INextBotComponent*)PawnAddressToPtr(param, context); if (!component) { context->ThrowNativeError("Component is a null ptr!"); return nullptr; @@ -48,7 +48,7 @@ cell_t GetBot(IPluginContext* context, const cell_t* params) { return 0; } - return PtrToPawnAddress(component->GetBot()); + return PtrToPawnAddress(component->GetBot(), context); } void setup(std::vector& natives) { diff --git a/extension/natives/nextbot/eventresponder.cpp b/extension/natives/nextbot/eventresponder.cpp index c1bd644..4bb4878 100644 --- a/extension/natives/nextbot/eventresponder.cpp +++ b/extension/natives/nextbot/eventresponder.cpp @@ -6,7 +6,7 @@ namespace natives::nextbot::eventresponder { inline INextBotEventResponder* Get(IPluginContext* context, const cell_t param) { - INextBotEventResponder* responder = (INextBotEventResponder*)PawnAddressToPtr(param); + INextBotEventResponder* responder = (INextBotEventResponder*)PawnAddressToPtr(param, context); if (!responder) { context->ThrowNativeError("Event responder ptr is null!"); return nullptr; @@ -20,7 +20,7 @@ cell_t FirstContainedResponder(IPluginContext* context, const cell_t* params) { return 0; } - return PtrToPawnAddress(responder->FirstContainedResponder()); + return PtrToPawnAddress(responder->FirstContainedResponder(), context); } cell_t NextContainedResponder(IPluginContext* context, const cell_t* params) { @@ -33,7 +33,7 @@ cell_t NextContainedResponder(IPluginContext* context, const cell_t* params) { if (!responder2) { return 0; } - return PtrToPawnAddress(responder->NextContainedResponder(responder2)); + return PtrToPawnAddress(responder->NextContainedResponder(responder2), context); } cell_t OnLeaveGround(IPluginContext* context, const cell_t* params) { @@ -74,7 +74,7 @@ cell_t OnMoveToSuccess(IPluginContext* context, const cell_t* params) { return 0; } - Path* path = (Path*)PawnAddressToPtr(params[2]); + Path* path = (Path*)PawnAddressToPtr(params[2], context); if (!path) { return context->ThrowNativeError("Path is null!"); } @@ -89,7 +89,7 @@ cell_t OnMoveToFailure(IPluginContext* context, const cell_t* params) { return 0; } - Path* path = (Path*)PawnAddressToPtr(params[2]); + Path* path = (Path*)PawnAddressToPtr(params[2], context); if (!path) { return context->ThrowNativeError("Path is null!"); } @@ -231,7 +231,7 @@ cell_t OnNavAreaChanged(IPluginContext* context, const cell_t* params) { return 0; } - responder->OnNavAreaChanged((CNavArea*)PawnAddressToPtr(params[2]), (CNavArea*)PawnAddressToPtr(params[3])); + responder->OnNavAreaChanged((CNavArea*)PawnAddressToPtr(params[2], context), (CNavArea*)PawnAddressToPtr(params[3], context)); return 0; } diff --git a/extension/natives/nextbot/intention.cpp b/extension/natives/nextbot/intention.cpp index 989c6d6..45ddd15 100644 --- a/extension/natives/nextbot/intention.cpp +++ b/extension/natives/nextbot/intention.cpp @@ -6,7 +6,7 @@ namespace natives::nextbot::intention { inline IIntention* Get(IPluginContext* context, const cell_t param) { - IIntention* intention = (IIntention*)PawnAddressToPtr(param); + IIntention* intention = (IIntention*)PawnAddressToPtr(param, context); if (!intention) { context->ThrowNativeError("Intention ptr is null!"); return nullptr; @@ -67,7 +67,7 @@ cell_t ShouldAttack(IPluginContext* context, const cell_t* params) { return 0; } - CKnownEntity* them = reinterpret_cast< CKnownEntity* >( PawnAddressToPtr(params[2]) ); + CKnownEntity* them = reinterpret_cast< CKnownEntity* >( PawnAddressToPtr(params[2], context) ); if (!them) { return context->ThrowNativeError("them entity is a null ptr!"); } @@ -171,12 +171,12 @@ cell_t SelectMoreDangerousThreat(IPluginContext* context, const cell_t* params) return context->ThrowNativeError( "Subject entity is not a CBaseCombatCharacter."); } - CKnownEntity* threat1 = reinterpret_cast< CKnownEntity* >( PawnAddressToPtr(params[3]) ); + CKnownEntity* threat1 = reinterpret_cast< CKnownEntity* >( PawnAddressToPtr(params[3], context) ); if (!threat1) { return context->ThrowNativeError("threat1 entity cannot be a null ptr!"); } - CKnownEntity* threat2 = reinterpret_cast< CKnownEntity* >( PawnAddressToPtr(params[4]) ); + CKnownEntity* threat2 = reinterpret_cast< CKnownEntity* >( PawnAddressToPtr(params[4], context) ); if (!threat2) { return context->ThrowNativeError("threat2 entity cannot be a null ptr!"); } @@ -186,7 +186,7 @@ cell_t SelectMoreDangerousThreat(IPluginContext* context, const cell_t* params) return context->ThrowNativeError("GetBot returned null!"); } - return PtrToPawnAddress(intention->SelectMoreDangerousThreat(me, subject, threat1, threat2)); + return PtrToPawnAddress(intention->SelectMoreDangerousThreat(me, subject, threat1, threat2), context); } void setup(std::vector& natives) { diff --git a/extension/natives/nextbot/knownentity.cpp b/extension/natives/nextbot/knownentity.cpp index 4ae8598..dab6a7e 100644 --- a/extension/natives/nextbot/knownentity.cpp +++ b/extension/natives/nextbot/knownentity.cpp @@ -5,7 +5,7 @@ namespace natives::nextbot::knownentity { inline CKnownEntity* Get(IPluginContext* context, const cell_t param) { - CKnownEntity* entity = (CKnownEntity*)PawnAddressToPtr(param); + CKnownEntity* entity = (CKnownEntity*)PawnAddressToPtr(param, context); if (!entity) { context->ThrowNativeError("Known entity ptr is null!"); return nullptr; @@ -81,7 +81,7 @@ cell_t GetLastKnownArea(IPluginContext* context, const cell_t* params) { return 0; } - return PtrToPawnAddress(entity->GetLastKnownArea()); + return PtrToPawnAddress(entity->GetLastKnownArea(), context); } cell_t GetTimeSinceLastKnown(IPluginContext* context, const cell_t* params) { diff --git a/extension/natives/nextbot/locomotion.cpp b/extension/natives/nextbot/locomotion.cpp index f389a97..be11536 100644 --- a/extension/natives/nextbot/locomotion.cpp +++ b/extension/natives/nextbot/locomotion.cpp @@ -6,7 +6,7 @@ namespace natives::nextbot::locomotion { inline ILocomotion* Get(IPluginContext* context, const cell_t param) { - ILocomotion* mover = (ILocomotion*)PawnAddressToPtr(param); + ILocomotion* mover = (ILocomotion*)PawnAddressToPtr(param, context); if (!mover) { context->ThrowNativeError("Locomotion ptr is null!"); return nullptr; @@ -263,7 +263,7 @@ cell_t ClimbLadder(IPluginContext* context, const cell_t* params) { return 0; } - mover->ClimbLadder((CNavLadder*)PawnAddressToPtr(params[2]), (CNavArea*)PawnAddressToPtr(params[3])); + mover->ClimbLadder((CNavLadder*)PawnAddressToPtr(params[2], context), (CNavArea*)PawnAddressToPtr(params[3], context)); return 0; } @@ -273,7 +273,7 @@ cell_t DescendLadder(IPluginContext* context, const cell_t* params) { return 0; } - mover->DescendLadder((CNavLadder*)PawnAddressToPtr(params[2]), (CNavArea*)PawnAddressToPtr(params[3])); + mover->DescendLadder((CNavLadder*)PawnAddressToPtr(params[2], context), (CNavArea*)PawnAddressToPtr(params[3], context)); return 0; } @@ -480,7 +480,7 @@ cell_t IsAreaTraversable(IPluginContext* context, const cell_t* params) { return 0; } - return (mover->IsAreaTraversable((CNavArea *)PawnAddressToPtr(params[2])) == true) ? 1 : 0; + return (mover->IsAreaTraversable((CNavArea *)PawnAddressToPtr(params[2], context)) == true) ? 1 : 0; } cell_t GetTraversableSlopeLimit(IPluginContext* context, const cell_t* params) { diff --git a/extension/natives/nextbot/locomotion/ground.cpp b/extension/natives/nextbot/locomotion/ground.cpp index 07e9198..1818ae4 100644 --- a/extension/natives/nextbot/locomotion/ground.cpp +++ b/extension/natives/nextbot/locomotion/ground.cpp @@ -5,7 +5,7 @@ namespace natives::nextbot::locomotion::ground { inline NextBotGroundLocomotion* Get(IPluginContext* context, const cell_t param) { - NextBotGroundLocomotion* mover = (NextBotGroundLocomotion*)PawnAddressToPtr(param); + NextBotGroundLocomotion* mover = (NextBotGroundLocomotion*)PawnAddressToPtr(param, context); if (!mover) { context->ThrowNativeError("NextBotGroundLocomotion ptr is null!"); return nullptr; diff --git a/extension/natives/nextbot/path.cpp b/extension/natives/nextbot/path.cpp index 0d3d3d6..865aa90 100644 --- a/extension/natives/nextbot/path.cpp +++ b/extension/natives/nextbot/path.cpp @@ -44,13 +44,24 @@ float SMPathFollowerCost::operator()(CNavArea* area, CNavArea* fromArea, const C } cell_t cost = sp_ftoc(0.0); - m_pFunc->PushCell(PtrToPawnAddress(m_bot)); - m_pFunc->PushCell(PtrToPawnAddress(area)); - m_pFunc->PushCell(PtrToPawnAddress(fromArea)); - m_pFunc->PushCell(PtrToPawnAddress(ladder)); + + Handle_t hndlBot = PtrToPawnAddress(m_bot, nullptr); + Handle_t hndlArea = PtrToPawnAddress(area, nullptr); + Handle_t hndlfromArea = PtrToPawnAddress(fromArea, nullptr); + Handle_t hndlladder = PtrToPawnAddress(ladder, nullptr); + + m_pFunc->PushCell(hndlBot); + m_pFunc->PushCell(hndlArea); + m_pFunc->PushCell(hndlfromArea); + m_pFunc->PushCell(hndlladder); m_pFunc->PushCell(gamehelpers->EntityToBCompatRef((CBaseEntity *)elevator)); m_pFunc->PushFloat(length); m_pFunc->Execute(&cost); + + ReleasePawnAddress(hndlBot, nullptr); + ReleasePawnAddress(hndlArea, nullptr); + ReleasePawnAddress(hndlfromArea, nullptr); + ReleasePawnAddress(hndlladder, nullptr); return sp_ctof(cost); } @@ -58,7 +69,7 @@ float SMPathFollowerCost::operator()(CNavArea* area, CNavArea* fromArea, const C template inline T* Get(IPluginContext* context, const cell_t param) { - T* bot = (T*)PawnAddressToPtr(param); + T* bot = (T*)PawnAddressToPtr(param, context); if (!bot) { context->ThrowNativeError("Object is a null ptr!"); return nullptr; @@ -74,7 +85,7 @@ cell_t GetArea(IPluginContext* context, const cell_t* params) { return 0; } - return PtrToPawnAddress(seg->area); + return PtrToPawnAddress(seg->area, context); } cell_t GetHow(IPluginContext* context, const cell_t* params) { @@ -104,7 +115,7 @@ cell_t GetLadder(IPluginContext* context, const cell_t* params) { return 0; } - return PtrToPawnAddress(seg->ladder); + return PtrToPawnAddress(seg->ladder, context); } cell_t GetType(IPluginContext* context, const cell_t* params) { @@ -246,7 +257,7 @@ cell_t GetSegmentPrior(IPluginContext* context, const cell_t* params) { return 0; } - return PtrToPawnAddress(cursor->segmentPrior); + return PtrToPawnAddress(cursor->segmentPrior, context); } void setup(std::vector& natives) { @@ -276,7 +287,7 @@ cell_t PathCtor(IPluginContext* context, const cell_t* params) { path->pTraceFilterIgnoreActors = pTraceFilter; path->pTraceFilterOnlyActors = pTraceFilter2; - return PtrToPawnAddress(path); + return PtrToPawnAddress(path, context); } cell_t GetLength(IPluginContext* context, const cell_t* params) { @@ -297,7 +308,7 @@ cell_t GetPosition(IPluginContext* context, const cell_t* params) { float dist = sp_ctof(params[2]); cell_t* addr; context->LocalToPhysAddr(params[3], &addr); - Path::Segment* segment = (Path::Segment*)PawnAddressToPtr(params[4]); + Path::Segment* segment = (Path::Segment*)PawnAddressToPtr(params[4], context); Vector pos = path->GetPosition(dist, segment); VectorToPawnVector(addr, pos); @@ -310,8 +321,8 @@ cell_t Copy(IPluginContext* context, const cell_t* params) { return 0; } - INextBot* bot = (INextBot*)PawnAddressToPtr(params[2]); - Path* path2 = (Path*)PawnAddressToPtr(params[3]); + INextBot* bot = (INextBot*)PawnAddressToPtr(params[2], context); + Path* path2 = (Path*)PawnAddressToPtr(params[3], context); path->Copy(bot, *path2); return 0; @@ -329,7 +340,7 @@ cell_t GetClosestPosition(IPluginContext* context, const cell_t* params) { PawnVectorToVector(nearAddr, vecNear); cell_t* posAddr; context->LocalToPhysAddr(params[3], &posAddr); - Path::Segment* segment = (Path::Segment*)PawnAddressToPtr(params[4]); + Path::Segment* segment = (Path::Segment*)PawnAddressToPtr(params[4], context); float alongLimit = sp_ctof(params[5]); Vector pos = path->GetClosestPosition(vecNear, segment, alongLimit); @@ -379,7 +390,7 @@ cell_t GetCurrentGoal(IPluginContext* context, const cell_t* params) { return 0; } - return PtrToPawnAddress(path->GetCurrentGoal()); + return PtrToPawnAddress(path->GetCurrentGoal(), context); } cell_t GetAge(IPluginContext* context, const cell_t* params) { @@ -450,7 +461,7 @@ cell_t GetCursorData(IPluginContext* context, const cell_t* params) { return 0; } - return PtrToPawnAddress(&path->GetCursorData()); + return PtrToPawnAddress(&path->GetCursorData(), context); } cell_t IsValid(IPluginContext* context, const cell_t* params) { @@ -478,7 +489,7 @@ cell_t Draw(IPluginContext* context, const cell_t* params) { return 0; } - Path::Segment* segment = (Path::Segment*)PawnAddressToPtr(params[2]); + Path::Segment* segment = (Path::Segment*)PawnAddressToPtr(params[2], context); path->Draw(segment); return 0; } @@ -499,7 +510,7 @@ cell_t FirstSegment(IPluginContext* context, const cell_t* params) { return 0; } - return PtrToPawnAddress(path->FirstSegment()); + return PtrToPawnAddress(path->FirstSegment(), context); } cell_t NextSegment(IPluginContext* context, const cell_t* params) { @@ -513,7 +524,7 @@ cell_t NextSegment(IPluginContext* context, const cell_t* params) { return 0; } - return PtrToPawnAddress(path->NextSegment(segment)); + return PtrToPawnAddress(path->NextSegment(segment), context); } cell_t PriorSegment(IPluginContext* context, const cell_t* params) { @@ -527,7 +538,7 @@ cell_t PriorSegment(IPluginContext* context, const cell_t* params) { return 0; } - return PtrToPawnAddress(path->PriorSegment(segment)); + return PtrToPawnAddress(path->PriorSegment(segment), context); } cell_t LastSegment(IPluginContext* context, const cell_t* params) { @@ -536,7 +547,7 @@ cell_t LastSegment(IPluginContext* context, const cell_t* params) { return 0; } - return PtrToPawnAddress(path->LastSegment()); + return PtrToPawnAddress(path->LastSegment(), context); } cell_t ComputeToPos(IPluginContext* context, const cell_t* params) { diff --git a/extension/natives/nextbot/path/chase.cpp b/extension/natives/nextbot/path/chase.cpp index ad4e5e1..eee592f 100644 --- a/extension/natives/nextbot/path/chase.cpp +++ b/extension/natives/nextbot/path/chase.cpp @@ -6,7 +6,7 @@ namespace natives::nextbot::path::chase { template inline T* Get(IPluginContext* context, const cell_t param) { - T* bot = (T*)PawnAddressToPtr(param); + T* bot = (T*)PawnAddressToPtr(param, context); if (!bot) { context->ThrowNativeError("Object is a null ptr!"); return nullptr; @@ -26,7 +26,7 @@ cell_t ChasePathCtor(IPluginContext* context, const cell_t* params) { path->pTraceFilterIgnoreActors = pTraceFilter; path->pTraceFilterOnlyActors = pTraceFilter2; - return PtrToPawnAddress(path); + return PtrToPawnAddress(path, context); } cell_t Update(IPluginContext* context, const cell_t* params) { @@ -144,7 +144,7 @@ cell_t DirectChasePathCtor(IPluginContext* context, const cell_t* params) { path->pTraceFilterIgnoreActors = pTraceFilter; path->pTraceFilterOnlyActors = pTraceFilter2; - return PtrToPawnAddress(path); + return PtrToPawnAddress(path, context); } void setup(std::vector& natives) { diff --git a/extension/natives/nextbot/path/follower.cpp b/extension/natives/nextbot/path/follower.cpp index 817599a..4e2b57b 100644 --- a/extension/natives/nextbot/path/follower.cpp +++ b/extension/natives/nextbot/path/follower.cpp @@ -7,7 +7,7 @@ namespace natives::nextbot::path::follower { template inline T* Get(IPluginContext* context, const cell_t param) { - T* bot = (T*)PawnAddressToPtr(param); + T* bot = (T*)PawnAddressToPtr(param, context); if (!bot) { context->ThrowNativeError("Object is a null ptr!"); return nullptr; @@ -26,7 +26,7 @@ cell_t PathFollowerCtor(IPluginContext* context, const cell_t* params) { path->pTraceFilterIgnoreActors = pTraceFilter; path->pTraceFilterOnlyActors = pTraceFilter2; - return PtrToPawnAddress(path); + return PtrToPawnAddress(path, context); } cell_t Update(IPluginContext* context, const cell_t* params) { diff --git a/extension/natives/nextbot/vision.cpp b/extension/natives/nextbot/vision.cpp index 4919df3..5e841bc 100644 --- a/extension/natives/nextbot/vision.cpp +++ b/extension/natives/nextbot/vision.cpp @@ -6,7 +6,7 @@ namespace natives::nextbot::vision { inline IVision* Get(IPluginContext* context, const cell_t param) { - IVision* vision = (IVision*)PawnAddressToPtr(param); + IVision* vision = (IVision*)PawnAddressToPtr(param, context); if (!vision) { context->ThrowNativeError("Vision ptr is null!"); return nullptr; @@ -20,7 +20,7 @@ cell_t GetPrimaryKnownThreat(IPluginContext* context, const cell_t* params) { return 0; } - return PtrToPawnAddress(vision->GetPrimaryKnownThreat((params[2]) ? true : false)); + return PtrToPawnAddress(vision->GetPrimaryKnownThreat((params[2]) ? true : false), context); } cell_t GetTimeSinceVisible(IPluginContext* context, const cell_t* params) { @@ -38,7 +38,7 @@ cell_t GetClosestKnown(IPluginContext* context, const cell_t* params) { return 0; } - return PtrToPawnAddress(vision->GetClosestKnown(params[2])); + return PtrToPawnAddress(vision->GetClosestKnown(params[2]), context); } cell_t GetKnownCount(IPluginContext* context, const cell_t* params) { @@ -60,7 +60,7 @@ cell_t GetKnown(IPluginContext* context, const cell_t* params) { if (!entity) { return context->ThrowNativeError("Invalid Entity Reference/Index %i", params[2]); } - return PtrToPawnAddress(vision->GetKnown(entity)); + return PtrToPawnAddress(vision->GetKnown(entity), context); } cell_t AddKnownEntity(IPluginContext* context, const cell_t* params) { diff --git a/extension/natives/nextbotplayer.cpp b/extension/natives/nextbotplayer.cpp index 40e9195..64105e1 100644 --- a/extension/natives/nextbotplayer.cpp +++ b/extension/natives/nextbotplayer.cpp @@ -7,7 +7,7 @@ namespace natives::nextbotplayer { template inline T* Get(IPluginContext* context, const cell_t param) { - T* bot = (T*)PawnAddressToPtr(param); + T* bot = (T*)PawnAddressToPtr(param, context); if (!bot) { context->ThrowNativeError("Botplayer is a null ptr!"); return nullptr; @@ -16,12 +16,12 @@ inline T* Get(IPluginContext* context, const cell_t param) { } cell_t ToolsNextBotPlayer(IPluginContext* context, const cell_t* params) { - CBaseCombatCharacter* entity = (CBaseCombatCharacter*)PawnAddressToPtr(params[1]); + CBaseCombatCharacter* entity = (CBaseCombatCharacter*)PawnAddressToPtr(params[1], context); if (!entity) { return context->ThrowNativeError("Invalid entity address %x", params[1]); } - return PtrToPawnAddress(new class ToolsNextBotPlayer(entity)); + return PtrToPawnAddress(new class ToolsNextBotPlayer(entity), context); } cell_t SetIsDormantWhenDead(IPluginContext* context, const cell_t* params) { diff --git a/extension/natives/takedamageinfo.cpp b/extension/natives/takedamageinfo.cpp index b4615d4..c522dda 100644 --- a/extension/natives/takedamageinfo.cpp +++ b/extension/natives/takedamageinfo.cpp @@ -18,7 +18,7 @@ namespace natives::takedamageinfo { CTakeDamageInfo g_GlobalDamageInfo; inline CTakeDamageInfo* Get(IPluginContext* context, const cell_t param) { - CTakeDamageInfo* info = (CTakeDamageInfo*)PawnAddressToPtr(param); + CTakeDamageInfo* info = (CTakeDamageInfo*)PawnAddressToPtr(param, context); if (!info) { context->ThrowNativeError("CTakeDamageInfo is a null ptr!"); return nullptr; @@ -27,11 +27,15 @@ inline CTakeDamageInfo* Get(IPluginContext* context, const cell_t param) { } cell_t CTakeDamageInfo_Ctor(IPluginContext* context, const cell_t* params) { - return PtrToPawnAddress(PawnAddressToPtr(params[1])); + return PtrToPawnAddress(PawnAddressToPtr(params[1], context), context); } cell_t GetGlobalDamageInfo(IPluginContext* context, const cell_t* params) { - return PtrToPawnAddress(&g_GlobalDamageInfo); + static Handle_t globalDmg = BAD_HANDLE; + if (globalDmg == BAD_HANDLE) { + globalDmg = PtrToPawnAddress(&g_GlobalDamageInfo, nullptr); + } + return globalDmg; } cell_t Init(IPluginContext* context, const cell_t* params) { diff --git a/extension/natives/tf/nav/area.cpp b/extension/natives/tf/nav/area.cpp index b06b1fe..ca05452 100644 --- a/extension/natives/tf/nav/area.cpp +++ b/extension/natives/tf/nav/area.cpp @@ -5,7 +5,7 @@ namespace natives::tf::nav::area { inline CTFNavArea* Get(IPluginContext* context, const cell_t param) { - CTFNavArea* area = (CTFNavArea*)PawnAddressToPtr(param); + CTFNavArea* area = (CTFNavArea*)PawnAddressToPtr(param, context); if (!area) { context->ThrowNativeError("TFNav area ptr is null!"); return nullptr; diff --git a/extension/pluginentityfactory.cpp b/extension/pluginentityfactory.cpp index f5245fc..4eb082b 100644 --- a/extension/pluginentityfactory.cpp +++ b/extension/pluginentityfactory.cpp @@ -985,10 +985,15 @@ IServerNetworkable* CPluginEntityFactory::RecursiveCreate(const char* classname, { if (nextBotFactory->IsRunnable()) { - nextBotFactory->PushCell(PtrToPawnAddress(pEnt)); + Handle_t hndlEnt = PtrToPawnAddress(pEnt, nullptr); + + nextBotFactory->PushCell(hndlEnt); cell_t address = 0; nextBotFactory->Execute(&address); - createdBot = (INextBot*)PawnAddressToPtr(address); + + ReleasePawnAddress(hndlEnt, nullptr); + + createdBot = (INextBot*)PawnAddressToPtr(address, nullptr); } } else diff --git a/hl2sdk-manifests b/hl2sdk-manifests index 22f699a..a57b309 160000 --- a/hl2sdk-manifests +++ b/hl2sdk-manifests @@ -1 +1 @@ -Subproject commit 22f699a941093d9d68c1f647c7c545ec346d0ee3 +Subproject commit a57b3095a6fc31a98b13e2d73ebb668dac4f1300 diff --git a/product.version b/product.version index 1cac385..359a5b9 100644 --- a/product.version +++ b/product.version @@ -1 +1 @@ -1.11.0 +2.0.0 \ No newline at end of file diff --git a/third_party/safetyhook b/third_party/safetyhook new file mode 160000 index 0000000..4c93319 --- /dev/null +++ b/third_party/safetyhook @@ -0,0 +1 @@ +Subproject commit 4c933195789e9a0551a49c929dc3a2dd1e8fb97f From 5f4618179f2e66580d5861f5e836fb5b38b60285 Mon Sep 17 00:00:00 2001 From: Kenzzer Date: Sat, 27 Jul 2024 22:47:03 +0200 Subject: [PATCH 16/18] Setup MemoryPointer on the methodmaps --- .../include/cbasenpc/baseanimatingoverlay.inc | 88 +------------------ scripting/include/cbasenpc/nav.inc | 7 +- scripting/include/cbasenpc/nextbot.inc | 2 +- .../include/cbasenpc/nextbot/knownentity.inc | 2 +- scripting/include/cbasenpc/nextbot/path.inc | 6 +- scripting/include/cbasenpc/takedamageinfo.inc | 8 +- 6 files changed, 14 insertions(+), 99 deletions(-) diff --git a/scripting/include/cbasenpc/baseanimatingoverlay.inc b/scripting/include/cbasenpc/baseanimatingoverlay.inc index d7de063..1846a31 100644 --- a/scripting/include/cbasenpc/baseanimatingoverlay.inc +++ b/scripting/include/cbasenpc/baseanimatingoverlay.inc @@ -13,93 +13,7 @@ #define MAX_OVERLAYS 15 -#pragma deprecated Use CAnimationLayer instead -enum //CAnimationLayer -{ - m_fFlags = 0, //0x0000 - m_bSequenceFinished = 4, //0x0004 - m_bLooping = 6, //0x0006 - m_nSequence = 8, //0x0008 - m_flCycle = 12, //0x000C - m_flPrevCycle = 16, //0x0010 - m_flWeight = 20, //0x0014 - m_flPlaybackRate = 24, //0x0018 - m_flBlendIn = 28, //0x001C - m_flBlendOut = 32, //0x0020 - m_flKillRate = 36, //0x0024 - m_flKillDelay = 40, //0x0028 - m_flLayerAnimtime = 44, //0x002C - m_flLayerFadeOuttime = 48, //0x0030 - m_nActivity = 52, //0x0034 - m_nPriority = 56, //0x0038 - m_nOrder = 60, //0x003C - m_flLastEventCheck = 64, //0x0040 - m_flLastEventAccess = 68, //0x0044 - m_pOwnerEntity = 72, //0x0048 - - CAnimationLayer_Size = 76 //0x004C -}; //Size=0x004C - -methodmap CAnimationOverlay -{ - #pragma deprecated Use CAnimationLayer instead - public CAnimationOverlay(Address address) - { - return view_as(address); - } - - property Address Address - { - public get() - { - return view_as
(this); - } - } - - property bool isNull - { - public get() - { - return this.Address == Address_Null; - } - } - - public any Get(int iOffset) - { - return LoadFromAddress(this.Address + view_as
(iOffset), NumberType_Int32); - } - - public void Set(int iOffset, any iValue) - { - StoreToAddress(this.Address + view_as
(iOffset), iValue, NumberType_Int32); - } - - #pragma deprecated Use CAnimationLayer.IsActive() instead - public bool IsActive() { return ((this.Get(m_fFlags) & ANIM_LAYER_ACTIVE) != 0); } - #pragma deprecated Use CAnimationLayer.IsAutokill() instead - public bool IsAutokill() { return ((this.Get(m_fFlags) & ANIM_LAYER_AUTOKILL) != 0); } - #pragma deprecated Use CAnimationLayer.IsKillMe() instead - public bool IsKillMe() { return ((this.Get(m_fFlags) & ANIM_LAYER_KILLME) != 0); } - #pragma deprecated Use CAnimationLayer.IsDying() instead - public bool IsDying() { return ((this.Get(m_fFlags) & ANIM_LAYER_DYING) != 0); } - #pragma deprecated Use CAnimationLayer.NoEvents() instead - public bool NoEvents() { return ((this.Get(m_fFlags) & ANIM_LAYER_NOEVENTS) != 0); } - #pragma deprecated Use CAnimationLayer.KillMe() instead - public void KillMe() { this.Set(m_fFlags, this.Get(m_fFlags) | ANIM_LAYER_KILLME); } - #pragma deprecated Use CAnimationLayer.AutoKill() instead - public void AutoKill() { this.Set(m_fFlags, this.Get(m_fFlags) | ANIM_LAYER_AUTOKILL); } - #pragma deprecated Use CAnimationLayer.Dying() instead - public void Dying() { this.Set(m_fFlags, this.Get(m_fFlags) | ANIM_LAYER_DYING); } - #pragma deprecated Use CAnimationLayer.Dead() instead - public void Dead() { this.Set(m_fFlags, this.Get(m_fFlags) & ~ANIM_LAYER_DYING); } - #pragma deprecated Use CAnimationLayer.IsAlive() instead - public bool IsAlive() { int iFlags = this.Get(m_fFlags); return (((iFlags & ANIM_LAYER_ACTIVE) != 0) || ((iFlags & ANIM_LAYER_KILLME) == 0)); } - - #pragma deprecated Use CAnimationLayer.m_nSequence instead - public int GetLayerSequence() { return (this.Get(m_nSequence)); } -}; - -methodmap CAnimationLayer < CAnimationOverlay +methodmap CAnimationLayer < MemoryPointer { property int m_fFlags { diff --git a/scripting/include/cbasenpc/nav.inc b/scripting/include/cbasenpc/nav.inc index c15d3a2..81be7c9 100644 --- a/scripting/include/cbasenpc/nav.inc +++ b/scripting/include/cbasenpc/nav.inc @@ -180,8 +180,9 @@ methodmap CNavMesh { /** * Pointer to TheNavMesh. + * You don't have to free the handle. */ - property Address Address + property MemoryPointer Address { public native get(); } @@ -330,7 +331,7 @@ methodmap CNavMesh bool ignoreNavBlockers = false); }; -methodmap CNavLadder +methodmap CNavLadder < MemoryPointer { /** * The length of the ladder. @@ -472,7 +473,7 @@ native HidingSpot GetHidingSpotByID(int id); /** * A rectangular region defining a walkable area in the environment. */ -methodmap CNavArea +methodmap CNavArea < MemoryPointer { /** * Updates the blocked status of the area. diff --git a/scripting/include/cbasenpc/nextbot.inc b/scripting/include/cbasenpc/nextbot.inc index 2f2be98..4dc4f24 100644 --- a/scripting/include/cbasenpc/nextbot.inc +++ b/scripting/include/cbasenpc/nextbot.inc @@ -19,7 +19,7 @@ enum NextBotDebugType DEBUG_ERRORS = (1 << 8), }; -methodmap INextBotEventResponder +methodmap INextBotEventResponder < MemoryPointer { public native INextBotEventResponder FirstContainedResponder(); public native INextBotEventResponder NextContainedResponder(INextBotEventResponder prev); diff --git a/scripting/include/cbasenpc/nextbot/knownentity.inc b/scripting/include/cbasenpc/nextbot/knownentity.inc index 19711d9..5ccee0f 100644 --- a/scripting/include/cbasenpc/nextbot/knownentity.inc +++ b/scripting/include/cbasenpc/nextbot/knownentity.inc @@ -9,7 +9,7 @@ * Note: Do not attempt to save pointers of this class as location of the data * can (and will!) change. */ -methodmap CKnownEntity +methodmap CKnownEntity < MemoryPointer { /** * Invalidates this entry. This will mark the entry for deletion. diff --git a/scripting/include/cbasenpc/nextbot/path.inc b/scripting/include/cbasenpc/nextbot/path.inc index abcea32..2ec2360 100644 --- a/scripting/include/cbasenpc/nextbot/path.inc +++ b/scripting/include/cbasenpc/nextbot/path.inc @@ -49,7 +49,7 @@ typeset PathFollowerCostFunctor /** * A segment of a Path. */ -methodmap Segment +methodmap Segment < MemoryPointer { /** * The CNavArea that this segment traverses. @@ -200,7 +200,7 @@ methodmap Segment /** * A structure that stores data about the current progress on the Path. */ -methodmap CursorData +methodmap CursorData < MemoryPointer { /** * The current position along the path. @@ -261,7 +261,7 @@ typeset PathComputeCallback function void (Path path, bool success, any data); }; -methodmap Path +methodmap Path < MemoryPointer { /** * A Path that is used by NextBots to navigate the world. diff --git a/scripting/include/cbasenpc/takedamageinfo.inc b/scripting/include/cbasenpc/takedamageinfo.inc index 2e53d64..9697ae9 100644 --- a/scripting/include/cbasenpc/takedamageinfo.inc +++ b/scripting/include/cbasenpc/takedamageinfo.inc @@ -10,14 +10,14 @@ enum TakeDamageInfo_CritType TakeDamageInfo_CritType_Full }; -methodmap CTakeDamageInfo +methodmap CTakeDamageInfo < MemoryPointer { /** - * Retrieves the CTakeDamageInfo class from the given address ptr. + * Retrieves the CTakeDamageInfo class from the given ptr. * * @return The CTakeDamageInfo. */ - public native CTakeDamageInfo(Address ptr); + public native CTakeDamageInfo(MemoryPointer ptr); /** * Initializes the CTakeDamageInfo's values. @@ -393,6 +393,6 @@ methodmap CTakeDamageInfo * initialize the values of the object first using CTakeDamageInfo.Init() * before modifying and using it in a function call. * - * @return Address to the global CTakeDamageInfo object. + * @return Handle to the global CTakeDamageInfo object. You don't have to free this handle. */ native CTakeDamageInfo GetGlobalDamageInfo(); \ No newline at end of file From da4a7b934b76c8faf89ec895132cfee69ea22ccf Mon Sep 17 00:00:00 2001 From: Kenzzer Date: Fri, 4 Oct 2024 00:48:03 +0200 Subject: [PATCH 17/18] Free Handles for plugin authors --- extension/extension.cpp | 19 +++++++++++++++++++ extension/helpers.h | 25 ++++++++++++++++++------- extension/natives/nav.cpp | 2 +- extension/natives/takedamageinfo.cpp | 2 +- 4 files changed, 39 insertions(+), 9 deletions(-) diff --git a/extension/extension.cpp b/extension/extension.cpp index a015068..ab215df 100644 --- a/extension/extension.cpp +++ b/extension/extension.cpp @@ -16,6 +16,7 @@ class CTakeDamageInfoHack; SH_DECL_MANUALEXTERN1_void(MEvent_Killed, CTakeDamageInfoHack &); +SH_DECL_HOOK1_void(IServerGameDLL, GameFrame, SH_NOATTRIB, false, bool); CGlobalVars* gpGlobals = nullptr; IGameConfig* g_pGameConf = nullptr; @@ -55,6 +56,7 @@ extern ConVar* nb_update_maxslide; HandleType_t g_KeyValueType; HandleType_t g_MemoryPtr; +std::unordered_set gHandlesToFree; CBaseNPCExt g_CBaseNPCExt; SMEXT_LINK(&g_CBaseNPCExt); @@ -63,6 +65,19 @@ IForward *g_pForwardEventKilled = nullptr; bool (ToolsTraceFilterSimple:: *ToolsTraceFilterSimple::func_ShouldHitEntity)(IHandleEntity *pHandleEntity, int contentsMask) = nullptr; CUtlMap g_EntitiesHooks; +void Hook_GameFrame(bool simulating) { + // This is only temporary help for plugin authors getting + // accustomed with the new handles + HandleSecurity security; + security.pIdentity = myself->GetIdentity(); + security.pOwner = nullptr; + + for (auto hndl : gHandlesToFree) { + handlesys->FreeHandle(hndl, &security); + } + gHandlesToFree.clear(); +} + bool CBaseNPCExt::SDK_OnLoad(char* error, size_t maxlength, bool late) { char conf_error[255]; if (!gameconfs->LoadGameConfigFile("cbasenpc", &g_pGameConf, conf_error, sizeof(conf_error))) { @@ -154,6 +169,8 @@ bool CBaseNPCExt::SDK_OnMetamodLoad(ISmmAPI *ismm, char *error, size_t maxlen, b g_pSharedChangeInfo = engine->GetSharedEdictChangeInfo(); gpGlobals = ismm->GetCGlobals(); + + SH_ADD_HOOK(IServerGameDLL, GameFrame, gamedll, SH_STATIC(Hook_GameFrame), false); return true; } @@ -281,6 +298,8 @@ void CBaseNPCExt::NotifyInterfaceDrop(SMInterface* interface) { } void CBaseNPCExt::SDK_OnUnload() { + SH_REMOVE_HOOK(IServerGameDLL, GameFrame, gamedll, SH_STATIC(Hook_GameFrame), false); + gameconfs->CloseGameConfigFile(g_pGameConf); forwards->ReleaseForward(g_pForwardEventKilled); diff --git a/extension/helpers.h b/extension/helpers.h index dda7ace..7c4d3e6 100644 --- a/extension/helpers.h +++ b/extension/helpers.h @@ -11,6 +11,7 @@ #include #include #include +#include #define GETGAMEDATAOFFSET(name, var) \ if(!g_pGameConf->GetOffset(name, &var) || var == -1) { snprintf(error, maxlength, "FAILED TO GET GAMEDATA OFFSET FOR %s", name); return false; } \ @@ -172,35 +173,45 @@ class ForeignMemoryPointer : IMemoryPointer { }; extern HandleType_t g_MemoryPtr; +extern std::unordered_set gHandlesToFree; inline void ReleasePawnAddress(Handle_t hndl, IPluginContext* context) { HandleSecurity security; security.pIdentity = myself->GetIdentity(); - if (context) { + // Enable when plugins should be in charge of the handles + /*if (context) { security.pOwner = context->GetIdentity(); } else { security.pOwner = nullptr; - } + }*/ + security.pOwner = nullptr; + gHandlesToFree.erase(hndl); handlesys->FreeHandle(hndl, &security); } -inline Handle_t PtrToPawnAddress(const void* ptr, IPluginContext* context) { +inline Handle_t PtrToPawnAddress(const void* ptr, IPluginContext* context, bool keepAround = false) { auto foreignPtr = new ForeignMemoryPointer(ptr); - IdentityToken_t* identity = nullptr; + // Enable when plugins should be in charge of the handles + /*IdentityToken_t* identity = nullptr; if (context) { identity = context->GetIdentity(); - } - - Handle_t handle = handlesys->CreateHandle(g_MemoryPtr, foreignPtr, identity, myself->GetIdentity(), nullptr); + }*/ + // Atm regardless of identity, the handle will be owned by no-one + Handle_t handle = handlesys->CreateHandle(g_MemoryPtr, foreignPtr, nullptr, myself->GetIdentity(), nullptr); if (handle == BAD_HANDLE) { delete foreignPtr; return BAD_HANDLE; } + // Unless explicitly specified otherwise, handles will be automatically destroyed next server frame + if (!keepAround) { + gHandlesToFree.insert(handle); + } + return handle; } diff --git a/extension/natives/nav.cpp b/extension/natives/nav.cpp index 9d33646..ff4b0ad 100644 --- a/extension/natives/nav.cpp +++ b/extension/natives/nav.cpp @@ -50,7 +50,7 @@ void setup(std::vector& natives) { cell_t GetAddress(IPluginContext* context, const cell_t* params) { static Handle_t hndlNavMesh = BAD_HANDLE; if (hndlNavMesh == BAD_HANDLE) { - hndlNavMesh = PtrToPawnAddress(TheNavMesh, nullptr); + hndlNavMesh = PtrToPawnAddress(TheNavMesh, nullptr, true); } return hndlNavMesh; } diff --git a/extension/natives/takedamageinfo.cpp b/extension/natives/takedamageinfo.cpp index c522dda..2d920d5 100644 --- a/extension/natives/takedamageinfo.cpp +++ b/extension/natives/takedamageinfo.cpp @@ -33,7 +33,7 @@ cell_t CTakeDamageInfo_Ctor(IPluginContext* context, const cell_t* params) { cell_t GetGlobalDamageInfo(IPluginContext* context, const cell_t* params) { static Handle_t globalDmg = BAD_HANDLE; if (globalDmg == BAD_HANDLE) { - globalDmg = PtrToPawnAddress(&g_GlobalDamageInfo, nullptr); + globalDmg = PtrToPawnAddress(&g_GlobalDamageInfo, nullptr, true); } return globalDmg; } From 0f3ffe16237b1764dbdcc4acda2cf8ed19675ec9 Mon Sep 17 00:00:00 2001 From: Kenzzer Date: Fri, 4 Oct 2024 01:16:47 +0200 Subject: [PATCH 18/18] Eliminate the rest of Address instances from the includes --- extension/natives/entityfactory.cpp | 4 +--- extension/pluginentityfactory.cpp | 21 +++++++------------ scripting/include/cbasenpc/baseanimating.inc | 2 +- scripting/include/cbasenpc/baseentity.inc | 6 +++--- scripting/include/cbasenpc/entityfactory.inc | 4 ++-- scripting/include/cbasenpc/nextbot.inc | 8 +++---- .../include/cbasenpc/nextbot/behavior.inc | 16 +++++++------- 7 files changed, 27 insertions(+), 34 deletions(-) diff --git a/extension/natives/entityfactory.cpp b/extension/natives/entityfactory.cpp index 5a27663..d50491e 100644 --- a/extension/natives/entityfactory.cpp +++ b/extension/natives/entityfactory.cpp @@ -254,9 +254,7 @@ cell_t AttachNextBot(IPluginContext* context, const cell_t* params) { return 0; } - // TO-DO: 2.0.0 - bool old = ((params[0] < 2) || context->GetFunctionById(params[2]) == nullptr); - factory->AttachNextBot((old) ? (IPluginFunction*)0x1 : context->GetFunctionById(params[2])); + factory->AttachNextBot(context->GetFunctionById(params[2])); return 0; } diff --git a/extension/pluginentityfactory.cpp b/extension/pluginentityfactory.cpp index 4eb082b..12b411c 100644 --- a/extension/pluginentityfactory.cpp +++ b/extension/pluginentityfactory.cpp @@ -981,25 +981,20 @@ IServerNetworkable* CPluginEntityFactory::RecursiveCreate(const char* classname, if (nextBotFactory && pEnt->MyCombatCharacterPointer() && !pEnt->MyNextBotPointer()) { INextBot* createdBot = nullptr; - if (nextBotFactory != (IPluginFunction*)0x1) + if (nextBotFactory->IsRunnable()) { - if (nextBotFactory->IsRunnable()) - { - Handle_t hndlEnt = PtrToPawnAddress(pEnt, nullptr); + Handle_t hndlEnt = PtrToPawnAddress(pEnt, nullptr); - nextBotFactory->PushCell(hndlEnt); - cell_t address = 0; - nextBotFactory->Execute(&address); + nextBotFactory->PushCell(hndlEnt); + Handle_t hndlBot = BAD_HANDLE; + nextBotFactory->Execute((cell_t*)&hndlBot); - ReleasePawnAddress(hndlEnt, nullptr); + ReleasePawnAddress(hndlEnt, nullptr); - createdBot = (INextBot*)PawnAddressToPtr(address, nullptr); + if (hndlBot != BAD_HANDLE) { + createdBot = (INextBot*)PawnAddressToPtr(hndlBot, nullptr); } } - else - { - createdBot = new ToolsNextBot(pEnt->MyCombatCharacterPointer()); - } pEntityRecord->m_pNextBot = createdBot; } diff --git a/scripting/include/cbasenpc/baseanimating.inc b/scripting/include/cbasenpc/baseanimating.inc index bbb3cfb..3cfca00 100644 --- a/scripting/include/cbasenpc/baseanimating.inc +++ b/scripting/include/cbasenpc/baseanimating.inc @@ -132,7 +132,7 @@ methodmap CBaseAnimating < CBaseEntity * @return Memory address of CStudioHdr. * @error Invalid entity. */ - public native Address GetModelPtr(); + public native MemoryPointer GetModelPtr(); /** * Retrieves the parameter index of a named pose parameter. diff --git a/scripting/include/cbasenpc/baseentity.inc b/scripting/include/cbasenpc/baseentity.inc index 26d5f86..852ac90 100644 --- a/scripting/include/cbasenpc/baseentity.inc +++ b/scripting/include/cbasenpc/baseentity.inc @@ -44,7 +44,7 @@ methodmap CBaseEntity * @return Memory address of CServerNetworkProperty. * @error Invalid entity. */ - public native Address NetworkProp(); + public native MemoryPointer NetworkProp(); /** * Obtains the entity's CCollisionProperty. @@ -52,7 +52,7 @@ methodmap CBaseEntity * @return Memory address of CCollisionProperty. * @error Invalid entity. */ - public native Address CollisionProp(); + public native MemoryPointer CollisionProp(); /** * Informs the server that the network properties of this entity changed. @@ -69,7 +69,7 @@ methodmap CBaseEntity * @param varAddr Entity networked property address. * @error Invalid entity. */ - public native void NetworkStateChangedVar(Address varAddr); + public native void NetworkStateChangedVar(MemoryPointer varAddr); /** * Gets the entity simulation time. diff --git a/scripting/include/cbasenpc/entityfactory.inc b/scripting/include/cbasenpc/entityfactory.inc index ab9d0ee..4d355ce 100644 --- a/scripting/include/cbasenpc/entityfactory.inc +++ b/scripting/include/cbasenpc/entityfactory.inc @@ -60,7 +60,7 @@ typeset CEntityFactoryOnRemoveCallback typeset CEntityFactoryNextBot { - function INextBot (Address link); + function INextBot (MemoryPointer link); }; methodmap CEntityFactory < Handle @@ -241,7 +241,7 @@ methodmap CEntityFactory < Handle * * @error Invalid handle. */ - public native void AttachNextBot(CEntityFactoryNextBot factory = INVALID_FUNCTION); + public native void AttachNextBot(CEntityFactoryNextBot factory); // Datamap diff --git a/scripting/include/cbasenpc/nextbot.inc b/scripting/include/cbasenpc/nextbot.inc index 4dc4f24..a6bc6d2 100644 --- a/scripting/include/cbasenpc/nextbot.inc +++ b/scripting/include/cbasenpc/nextbot.inc @@ -410,10 +410,10 @@ methodmap ToolsNextBot < INextBot * @param entity Entity address * @return The created NextBot interface */ - public native ToolsNextBot(Address entity); + public native ToolsNextBot(MemoryPointer entity); } -stock INextBot ToolsNextBot_Factory(Address entity) +stock INextBot ToolsNextBot_Factory(MemoryPointer entity) { return ToolsNextBot(entity); } @@ -429,7 +429,7 @@ methodmap ToolsNextBotPlayer < ToolsNextBot * @param entity Entity address * @return The created NextBot interface */ - public native ToolsNextBotPlayer(Address entity); + public native ToolsNextBotPlayer(MemoryPointer entity); /* * Defines whether or not the nextbot interface should update when @@ -442,7 +442,7 @@ methodmap ToolsNextBotPlayer < ToolsNextBot } } -stock INextBot ToolsNextBotPlayer_Factory(Address entity) +stock INextBot ToolsNextBotPlayer_Factory(MemoryPointer entity) { return ToolsNextBotPlayer(entity); } diff --git a/scripting/include/cbasenpc/nextbot/behavior.inc b/scripting/include/cbasenpc/nextbot/behavior.inc index cae4034..db6a33c 100644 --- a/scripting/include/cbasenpc/nextbot/behavior.inc +++ b/scripting/include/cbasenpc/nextbot/behavior.inc @@ -76,10 +76,10 @@ typeset ActionEventResponderCallback // OnContact // result is a CGameTrace* structure - function int (NextBotAction action, int actor, int other, Address result); - function int (NextBotAction action, CBaseCombatCharacter actor, CBaseEntity other, Address result); - function void (NextBotAction action, int actor, int other, Address result); - function void (NextBotAction action, CBaseCombatCharacter actor, CBaseEntity other, Address result); + function int (NextBotAction action, int actor, int other, MemoryPointer result); + function int (NextBotAction action, CBaseCombatCharacter actor, CBaseEntity other, MemoryPointer result); + function void (NextBotAction action, int actor, int other, MemoryPointer result); + function void (NextBotAction action, CBaseCombatCharacter actor, CBaseEntity other, MemoryPointer result); // OnMoveToSuccess function int (NextBotAction action, int actor, Path path); @@ -203,11 +203,11 @@ typeset ActionEventResponderCallback // OnSpokeConcept // response is AI_Response* - function int (NextBotAction action, int actor, int who, const char[] concept, Address response); - function int (NextBotAction action, CBaseCombatCharacter actor, CBaseCombatCharacter who, const char[] concept, Address response); + function int (NextBotAction action, int actor, int who, const char[] concept, MemoryPointer response); + function int (NextBotAction action, CBaseCombatCharacter actor, CBaseCombatCharacter who, const char[] concept, MemoryPointer response); - function void (NextBotAction action, int actor, int who, const char[] concept, Address response); - function void (NextBotAction action, CBaseCombatCharacter actor, CBaseCombatCharacter who, const char[] concept, Address response); + function void (NextBotAction action, int actor, int who, const char[] concept, MemoryPointer response); + function void (NextBotAction action, CBaseCombatCharacter actor, CBaseCombatCharacter who, const char[] concept, MemoryPointer response); // OnWeaponFired function int (NextBotAction action, int actor, int whoFired, int weapon);