diff --git a/.github/workflows/ci-extension.yml b/.github/workflows/ci-extension.yml index e3fdd58..f90a6e9 100644 --- a/.github/workflows/ci-extension.yml +++ b/.github/workflows/ci-extension.yml @@ -35,40 +35,41 @@ 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: - - 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 - ref: ${{ env.SOURCEMOD_VERSION }}-dev + ref: ${{ env.SOURCEMOD_VERSION }} 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 + ref: ${{ env.MMSOURCE_VERSION }} 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 diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..84ea369 --- /dev/null +++ b/.gitmodules @@ -0,0 +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 b942aad..0942047 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 @@ -99,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: @@ -147,35 +97,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 +244,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 +257,6 @@ class ExtensionConfig(object): '-Wno-switch', '-Wno-array-bounds', '-msse', - '-m32', '-fvisibility=hidden', ] cxx.cxxflags += [ @@ -311,10 +267,9 @@ class ExtensionConfig(object): '-fvisibility-inlines-hidden', '-fpermissive' ] - cxx.linkflags += ['-m32'] - 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': @@ -350,6 +305,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'] @@ -371,7 +329,6 @@ class ExtensionConfig(object): '/std:c++17' ] cxx.linkflags += [ - '/MACHINE:X86', 'kernel32.lib', 'user32.lib', 'gdi32.lib', @@ -387,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': @@ -398,7 +355,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 +398,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 @@ -592,6 +424,28 @@ class ExtensionConfig(object): 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) + 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) self.ConfigureForExtension(context, binary.compiler) @@ -599,13 +453,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) @@ -617,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', @@ -635,4 +499,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..30bafde 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', @@ -30,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', @@ -69,29 +68,29 @@ 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') ] 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) + Extension.AddCDetour(binary) 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..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) - EVENTPUSHCELL(concept) - EVENTPUSHCELL(PtrToPawnAddress(response)) + EVENTPUSHSTRING(concept) + 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 d06740b..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((cell_t)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((cell_t)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((cell_t)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((cell_t)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((cell_t)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((cell_t)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((cell_t)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((cell_t)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 a0cbf95..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; @@ -54,6 +55,8 @@ extern ConVar* nb_update_framelimit; extern ConVar* nb_update_maxslide; HandleType_t g_KeyValueType; +HandleType_t g_MemoryPtr; +std::unordered_set gHandlesToFree; CBaseNPCExt g_CBaseNPCExt; SMEXT_LINK(&g_CBaseNPCExt); @@ -62,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))) { @@ -153,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; } @@ -167,7 +185,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) { @@ -212,6 +229,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 @@ -280,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 bfed9d3..7c4d3e6 100644 --- a/extension/helpers.h +++ b/extension/helpers.h @@ -4,12 +4,14 @@ #pragma once #include "smsdk_ext.h" +#include "IMemoryPointer.h" #include #include #include #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; } \ @@ -148,20 +150,96 @@ 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(ptr); -#else - return (cell_t)ptr; -#endif +class ForeignMemoryPointer : IMemoryPointer { +public: + ForeignMemoryPointer(const void* ptr) : m_ptr(ptr) {} + + virtual void Delete() override + { + delete this; + } + + virtual cell_t GetSize() override + { + return 0; + } + + virtual void* Get() override + { + return (void*)m_ptr; + } +protected: + const void* m_ptr; +}; + +extern HandleType_t g_MemoryPtr; +extern std::unordered_set gHandlesToFree; + +inline void ReleasePawnAddress(Handle_t hndl, IPluginContext* context) +{ + HandleSecurity security; + security.pIdentity = myself->GetIdentity(); + // 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 void* PawnAddressToPtr(cell_t addr) { -#ifdef PLATFORM_X64 - return (void*)g_pSM->FromPseudoAddress(param); -#else - return (void*)addr; -#endif +inline Handle_t PtrToPawnAddress(const void* ptr, IPluginContext* context, bool keepAround = false) { + auto foreignPtr = new ForeignMemoryPointer(ptr); + + // Enable when plugins should be in charge of the handles + /*IdentityToken_t* identity = nullptr; + if (context) { + identity = context->GetIdentity(); + }*/ + // 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; +} + +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/idatamapcontainer.cpp b/extension/idatamapcontainer.cpp index b0854b4..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; @@ -772,10 +772,29 @@ void IEntityDataMapInputFuncDelegate::Alloc() if (m_pInputFuncPtr) return; - uint32_t thisAddr = (uint32_t)this; - uint32_t callFuncAddr = (uint32_t)(&IEntityDataMapInputFuncDelegate::HandleInput); - - uint8_t funcBytes[] = { + intp thisAddr = (intp)this; + intp callFuncAddr = (intp)(&IEntityDataMapInputFuncDelegate::HandleInput); + + uint8_t funcBytes[] = { +#ifdef PLATFORM_X64 + // (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 + 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 // MSVC __thiscall 0x55, // push ebp @@ -813,6 +832,7 @@ void IEntityDataMapInputFuncDelegate::Alloc() 0x89, 0xEC, // mov esp, ebp 0x5D, // pop ebp 0xC3 // ret +#endif #endif }; @@ -823,14 +843,23 @@ void IEntityDataMapInputFuncDelegate::Alloc() { g_InputFuncAlloc.SetRW(m_pInputFuncPtr); +#ifdef PLATFORM_X64 +#ifdef WIN64 + *((intp*)(&funcBytes[8])) = thisAddr; + *((intp*)(&funcBytes[18])) = callFuncAddr; +#else + *((intp*)(&funcBytes[8])) = thisAddr; + *((intp*)(&funcBytes[18])) = callFuncAddr; +#endif +#else #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 #endif - memcpy(m_pInputFuncPtr, funcBytes, m_iInputFuncSize); g_InputFuncAlloc.SetRE(m_pInputFuncPtr); @@ -984,7 +1013,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); } @@ -992,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/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/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/natives/nav.cpp b/extension/natives/nav.cpp index d968adb..ff4b0ad 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, true); + } + 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..2d920d5 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, true); + } + 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 caad1df..12b411c 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); } @@ -981,20 +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()) - { - nextBotFactory->PushCell(PtrToPawnAddress(pEnt)); - cell_t address = 0; - nextBotFactory->Execute(&address); - createdBot = (INextBot*)PawnAddressToPtr(address); + Handle_t hndlEnt = PtrToPawnAddress(pEnt, nullptr); + + nextBotFactory->PushCell(hndlEnt); + Handle_t hndlBot = BAD_HANDLE; + nextBotFactory->Execute((cell_t*)&hndlBot); + + ReleasePawnAddress(hndlEnt, nullptr); + + if (hndlBot != BAD_HANDLE) { + createdBot = (INextBot*)PawnAddressToPtr(hndlBot, nullptr); } } - else - { - createdBot = new ToolsNextBot(pEnt->MyCombatCharacterPointer()); - } pEntityRecord->m_pNextBot = createdBot; } 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/extension/smsdk_ext.cpp b/extension/smsdk_ext.cpp deleted file mode 100644 index 496ec6a..0000000 --- a/extension/smsdk_ext.cpp +++ /dev/null @@ -1,475 +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(); -} - -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 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: diff --git a/extension/sourcesdk/baseanimating.cpp b/extension/sourcesdk/baseanimating.cpp index a8a0e0b..fd66358 100644 --- a/extension/sourcesdk/baseanimating.cpp +++ b/extension/sourcesdk/baseanimating.cpp @@ -1,4 +1,5 @@ #include "sourcesdk/baseanimating.h" +#include #include #include #include @@ -8,13 +9,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 +26,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 +35,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 +66,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; @@ -74,6 +77,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 +92,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; } @@ -127,9 +138,24 @@ 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); + 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()); } void CBaseAnimating::ResetSequence(int sequence) @@ -138,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/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/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/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 diff --git a/gamedata/cbasenpc.txt b/gamedata/cbasenpc.txt index 0a48c3b..a1eb45b 100644 --- a/gamedata/cbasenpc.txt +++ b/gamedata/cbasenpc.txt @@ -7,239 +7,362 @@ // Locate CNavMesh::Load, first dword is TheNavMesh second is TheNavAreas "TheNavMesh" { - "linux" "979" "windows" "786" + "windows64" "569" + "linux" "979" + "linux64" "849" } "TheNavAreas" { - "linux" "1058" "windows" "819" + "windows64" "839" + "linux" "1058" + "linux64" "1008" } // Locate CBaseEntity::PhysicsMarkEntitiesAsTouching, first dword is g_TouchTrace "g_TouchTrace" { - "linux" "29" "windows" "32" + "windows64" "56" + "linux" "29" + "linux64" "55" } "g_EntityListPool" { "windows" "17" + "windows64" "33" } "CNavMesh::m_isLoaded" { - "linux" "52" "windows" "52" + "windows64" "72" + "linux" "52" + "linux64" "72" } "CBaseEntity::Spawn" { - "linux" "25" "windows" "24" + "windows64" "24" + "linux" "25" + "linux64" "25" } "CBaseEntity::PostConstructor" { - "linux" "29" "windows" "28" + "windows64" "28" + "linux" "29" + "linux64" "29" } "CBaseEntity::GetBaseAnimating" { - "linux" "53" "windows" "52" + "windows64" "52" + "linux" "53" + "linux64" "53" } "CBaseEntity::IsAlive" { - "linux" "68" "windows" "67" + "windows64" "67" + "linux" "68" + "linux64" "68" } "CBaseEntity::Event_Killed" { - "linux" "69" "windows" "68" + "windows64" "68" + "linux" "69" + "linux64" "69" } "CBaseEntity::MyCombatCharacterPointer" { - "linux" "74" "windows" "73" + "windows64" "73" + "linux" "74" + "linux64" "74" } "CBaseEntity::MyNextBotPointer" { - "linux" "75" "windows" "74" + "windows64" "74" + "linux" "75" + "linux64" "75" } "CBaseEntity::Touch" { - "linux" "105" "windows" "104" + "windows64" "104" + "linux" "105" + "linux64" "105" } "CBaseEntity::PhysicsSimulate" { - "linux" "110" "windows" "109" + "windows64" "109" + "linux" "110" + "linux64" "110" } "CBaseEntity::UpdateOnRemove" { - "linux" "111" "windows" "110" + "windows64" "110" + "linux" "111" + "linux64" "111" } "CBaseEntity::EyeAngles" { - "linux" "138" "windows" "137" + "windows64" "137" + "linux" "138" + "linux64" "138" } "CBaseEntity::GetVectors" { - "linux" "143" "windows" "142" + "windows64" "142" + "linux" "143" + "linux64" "143" } - "CBaseEntity::WorldSpaceCenter" + "CBaseEntity::WorldSpaceCenter" { - "linux" "156" "windows" "155" + "windows64" "155" + "linux" "156" + "linux64" "156" } "CBaseAnimating::StudioFrameAdvance" { - "linux" "201" "windows" "200" + "windows64" "200" + "linux" "201" + "linux64" "201" } "CBaseAnimating::DispatchAnimEvents" { - "linux" "213" "windows" "212" + "windows64" "212" + "linux" "213" + "linux64" "213" } "CBaseAnimating::HandleAnimEvent" { - "linux" "214" "windows" "213" + "windows64" "213" + "linux" "214" + "linux64" "214" } "CBaseAnimating::GetAttachment" { - "linux" "216" "windows" "215" + "windows64" "215" + "linux" "216" + "linux64" "216" } "CBaseCombatCharacter::Weapon_Equip" { - "linux" "272" "windows" "271" + "windows64" "271" + "linux" "272" + "linux64" "272" } "CBaseCombatCharacter::Weapon_Drop" { - "linux" "274" "windows" "273" + "windows64" "273" + "linux" "274" + "linux64" "274" } "CBaseCombatCharacter::OnTakeDamage_Alive" { - "linux" "283" "windows" "282" + "windows64" "282" + "linux" "283" + "linux64" "283" } "CBaseCombatCharacter::OnTakeDamage_Dying" { - "linux" "284" "windows" "283" + "windows64" "283" + "linux" "284" + "linux64" "284" } "CBaseCombatCharacter::GetLastKnownArea" { - "linux" "323" "windows" "322" + "windows64" "322" + "linux" "323" + "linux64" "323" } "CBaseCombatCharacter::OnNavAreaChanged" { - "linux" "327" "windows" "326" + "windows64" "326" + "linux" "327" + "linux64" "327" } "CBaseCombatCharacter::UpdateLastKnownArea" { - "linux" "326" "windows" "325" + "windows64" "325" + "linux" "326" + "linux64" "326" } "NextBotCombatCharacter::vtable_entries" { "windows" "338" + "windows64" "338" "linux" "338" + "linux64" "338" } "NextBotGroundLocomotion::vtable_entries" { - "linux" "111" "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" } // Find string "Invalid navigation file.\n" "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" } + // 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" } // Find "placementOrigin" first subroutine call below it "Studio_FindAttachment" { "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" + } + // 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" { "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" - } - // 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) + "linux64" "@_Z22SimThink_EntityChangedP11CBaseEntity" + } + // 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" } // 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 @@ -247,96 +370,129 @@ { "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" } // Find "m_CalcAbsolutePositionMutex" to find CBaseEntity::CalcAbsolutePosition "CBaseEntity::CalcAbsolutePosition" { "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" - } - "CBaseEntity::SetGroundEntity" - { - "library" "server" - "windows" "" - "linux" "@_ZN11CBaseEntity15SetGroundEntityEPS_" + "linux64" "@_ZN11CBaseEntity26InvalidatePhysicsRecursiveEi" } // Find string "CBaseEntity::TakeDamage: with inputInfo.GetDamageForce() == vec3_origin\n" "CBaseEntity::TakeDamage" { "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" } // "g_EntityListPool" "g_EntityListPool" { "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" } - "CBaseAnimating::SequenceDuration" - { - "library" "server" - "windows" "\x55\x8B\xEC\x56\x8B\x75\x08\x57\x8B\xF9\x85\xF6\x75\x2A\x8B\x47\x5C" - "linux" "@_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" } } "Addresses" - { + { "GetAnimationEvent" { "windows" { "signature" "__GetAnimationEvent__" } + "windows64" + { + "signature" "__GetAnimationEvent__" + } "linux" { "signature" "__GetAnimationEvent__" } + "linux64" + { + "signature" "__GetAnimationEvent__" + } } } } diff --git a/hl2sdk-manifests b/hl2sdk-manifests new file mode 160000 index 0000000..a57b309 --- /dev/null +++ b/hl2sdk-manifests @@ -0,0 +1 @@ +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/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/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/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/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..a6bc6d2 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); @@ -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); 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 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