From 080e0107bc2f6c44c75c49c1d4480aa0ddabb388 Mon Sep 17 00:00:00 2001 From: maxime1907 <19607336+maxime1907@users.noreply.github.com> Date: Mon, 12 Jul 2021 02:30:37 +0200 Subject: [PATCH] Initial commit --- AMBuildScript | 454 ++++++++++ AMBuilder | 20 + PackageScript | 36 + addons/metamod/sendsnapshotfixer.vdf | 5 + configure.py | 23 + engine_wrappers.h | 98 +++ msvc9/sample_mm.sln | 56 ++ msvc9/sample_mm.vcproj | 1162 ++++++++++++++++++++++++++ ssf.cpp | 165 ++++ ssf.h | 38 + 10 files changed, 2057 insertions(+) create mode 100644 AMBuildScript create mode 100644 AMBuilder create mode 100644 PackageScript create mode 100644 addons/metamod/sendsnapshotfixer.vdf create mode 100644 configure.py create mode 100644 engine_wrappers.h create mode 100644 msvc9/sample_mm.sln create mode 100644 msvc9/sample_mm.vcproj create mode 100644 ssf.cpp create mode 100644 ssf.h diff --git a/AMBuildScript b/AMBuildScript new file mode 100644 index 0000000..2b3fdda --- /dev/null +++ b/AMBuildScript @@ -0,0 +1,454 @@ +# vim: set sts=2 ts=8 sw=2 tw=99 et ft=python: +import os, sys + +# 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 + +WinOnly = ['windows'] +WinLinux = ['windows', 'linux'] +WinLinuxMac = ['windows', 'linux', 'mac'] + +PossibleSDKs = { + 'episode1': SDK('HL2SDK', '1.ep1', '1', 'EPISODEONE', WinLinux, 'episode1'), + 'darkm': SDK('HL2SDK-DARKM', '2.darkm', '2', 'DARKMESSIAH', WinOnly, 'darkm'), + 'ep2': SDK('HL2SDKOB', '2.ep2', '3', 'ORANGEBOX', WinLinux, 'orangebox'), + 'bgt': SDK('HL2SDK-BGT', '2.bgt', '4', 'BLOODYGOODTIME', WinOnly, 'bgt'), + 'eye': SDK('HL2SDK-EYE', '2.eye', '5', 'EYE', WinOnly, 'eye'), + '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'), + 'bms': SDK('HL2SDKBMS', '2.bms', '10', 'BMS', WinLinux, 'bms'), + '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'), + 'contagion': SDK('HL2SDKCONTAGION', '2.contagion', '14', 'CONTAGION', WinOnly, 'contagion'), + 'l4d2': SDK('HL2SDKL4D2', '2.l4d2', '15', 'LEFT4DEAD2', WinLinuxMac, 'l4d2'), + 'swarm': SDK('HL2SDK-SWARM', '2.swarm', '16', 'ALIENSWARM', WinOnly, 'swarm'), + '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'), + 'csgo': SDK('HL2SDKCSGO', '2.csgo', '20', 'CSGO', WinLinuxMac, 'csgo'), + 'dota': SDK('HL2SDKDOTA', '2.dota', '21', 'DOTA', [], 'dota'), +} + +def ResolveEnvPath(env, folder): + if env in os.environ: + path = os.environ[env] + if os.path.isdir(path): + return path + return None + + head = os.getcwd() + oldhead = None + while head != None and head != oldhead: + path = os.path.join(head, folder) + if os.path.isdir(path): + return path + oldhead = head + head, tail = os.path.split(head) + + return None + +def Normalize(path): + return os.path.abspath(os.path.normpath(path)) + +class ExtensionConfig(object): + def __init__(self): + self.sdks = {} + self.binaries = [] + self.extensions = [] + self.generated_headers = None + self.mms_root = None + self.sm_root = None + + @property + def tag(self): + if builder.options.debug == '1': + return 'Debug' + return 'Release' + + 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 builder.target_platform in sdk.platform: + 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.') + + if builder.options.sm_path: + self.sm_root = builder.options.sm_path + else: + self.sm_root = ResolveEnvPath('SOURCEMOD18', 'sourcemod-1.8') + if not self.sm_root: + self.sm_root = ResolveEnvPath('SOURCEMOD', 'sourcemod') + if not self.sm_root: + self.sm_root = ResolveEnvPath('SOURCEMOD_DEV', 'sourcemod-central') + + if not self.sm_root or not os.path.isdir(self.sm_root): + raise Exception('Could not find a source copy of SourceMod') + self.sm_root = Normalize(self.sm_root) + + if builder.options.mms_path: + self.mms_root = builder.options.mms_path + else: + self.mms_root = ResolveEnvPath('MMSOURCE110', 'mmsource-1.10') + if not self.mms_root: + self.mms_root = ResolveEnvPath('MMSOURCE', 'metamod-source') + if not self.mms_root: + self.mms_root = ResolveEnvPath('MMSOURCE_DEV', 'mmsource-central') + + if not self.mms_root or not os.path.isdir(self.mms_root): + raise Exception('Could not find a source copy of Metamod:Source') + self.mms_root = Normalize(self.mms_root) + + def configure(self): + cxx = builder.DetectCompilers() + + if cxx.like('gcc'): + self.configure_gcc(cxx) + elif cxx.vendor == 'msvc': + self.configure_msvc(cxx) + + # Optimizaiton + if builder.options.opt == '1': + cxx.defines += ['NDEBUG'] + + # Debugging + if builder.options.debug == '1': + cxx.defines += ['DEBUG', '_DEBUG'] + + # Platform-specifics + if builder.target_platform == 'linux': + self.configure_linux(cxx) + elif builder.target_platform == 'mac': + self.configure_mac(cxx) + elif builder.target_platform == 'windows': + self.configure_windows(cxx) + + # Finish up. + cxx.includes += [ + os.path.join(self.sm_root, 'public'), + ] + + def configure_gcc(self, cxx): + cxx.defines += [ + 'stricmp=strcasecmp', + '_stricmp=strcasecmp', + '_snprintf=snprintf', + '_vsnprintf=vsnprintf', + 'HAVE_STDINT_H', + 'GNUC', + ] + cxx.cflags += [ + '-pipe', + '-fPIC', + '-fno-strict-aliasing', + '-Wall', + '-Werror', + '-Wno-unused', + '-Wno-switch', + '-Wno-array-bounds', + '-msse', + '-m32', + '-fvisibility=hidden', + ] + cxx.cxxflags += [ + '-std=c++11', + '-fno-exceptions', + '-fno-threadsafe-statics', + '-Wno-non-virtual-dtor', + '-Wno-overloaded-virtual', + '-fno-rtti', + '-fvisibility-inlines-hidden', + '-fpermissive', + ] + cxx.linkflags += ['-m32'] + + have_gcc = cxx.vendor == 'gcc' + have_clang = cxx.vendor == 'clang' + if cxx.version >= 'clang-3.6': + cxx.cxxflags += ['-Wno-inconsistent-missing-override'] + if have_clang or (cxx.version >= 'gcc-4.6'): + cxx.cflags += ['-Wno-narrowing'] + if have_clang or (cxx.version >= 'gcc-4.7'): + cxx.cxxflags += ['-Wno-delete-non-virtual-dtor'] + if cxx.version >= 'gcc-4.8': + cxx.cflags += ['-Wno-unused-result'] + + if have_clang: + cxx.cxxflags += ['-Wno-implicit-exception-spec-mismatch'] + if cxx.version >= 'apple-clang-5.1' or cxx.version >= 'clang-3.4': + cxx.cxxflags += ['-Wno-deprecated-register'] + else: + cxx.cxxflags += ['-Wno-deprecated'] + cxx.cflags += ['-Wno-sometimes-uninitialized'] + + if have_gcc: + cxx.cflags += ['-mfpmath=sse'] + + if builder.options.opt == '1': + cxx.cflags += [ + '-O3', + '-funroll-loops', + ] + + def configure_msvc(self, cxx): + if builder.options.debug == '1': + cxx.cflags += ['/MTd'] + cxx.linkflags += ['/NODEFAULTLIB:libcmt'] + else: + cxx.cflags += ['/MT'] + cxx.defines += [ + '_CRT_SECURE_NO_DEPRECATE', + '_CRT_SECURE_NO_WARNINGS', + '_CRT_NONSTDC_NO_DEPRECATE', + '_ITERATOR_DEBUG_LEVEL=0', + ] + cxx.cflags += [ + '/W3', + ] + cxx.cxxflags += [ + '/EHsc', + '/GR-', + '/TP', + ] + cxx.linkflags += [ + '/MACHINE:X86', + 'kernel32.lib', + 'user32.lib', + 'gdi32.lib', + 'winspool.lib', + 'comdlg32.lib', + 'advapi32.lib', + 'shell32.lib', + 'ole32.lib', + 'oleaut32.lib', + 'uuid.lib', + 'odbc32.lib', + 'odbccp32.lib', + ] + + if builder.options.opt == '1': + cxx.cflags += ['/Ox', '/Zo'] + cxx.linkflags += ['/OPT:ICF', '/OPT:REF'] + + if builder.options.debug == '1': + cxx.cflags += ['/Od', '/RTC1'] + + # This needs to be after our optimization flags which could otherwise disable it. + # Don't omit the frame pointer. + cxx.cflags += ['/Oy-'] + + def configure_linux(self, cxx): + cxx.defines += ['_LINUX', 'POSIX'] + cxx.linkflags += ['-lm', '-ldl'] + if cxx.vendor == 'gcc': + cxx.linkflags += ['-static-libgcc'] + elif cxx.vendor == 'clang': + cxx.linkflags += ['-lgcc_eh'] + cxx.linkflags += ['-static-libstdc++'] + + def configure_mac(self, cxx): + cxx.defines += ['OSX', '_OSX', 'POSIX'] + cxx.cflags += ['-mmacosx-version-min=10.5'] + cxx.linkflags += [ + '-mmacosx-version-min=10.5', + '-arch', 'i386', + '-lstdc++', + '-stdlib=libstdc++', + ] + + def configure_windows(self, cxx): + cxx.defines += ['WIN32', '_WINDOWS'] + + def ConfigureForExtension(self, context, compiler): + compiler.cxxincludes += [ + os.path.join(context.currentSourcePath), + os.path.join(self.sm_root, 'public'), + os.path.join(self.sm_root, 'public', 'extensions'), + os.path.join(self.sm_root, 'sourcepawn', 'include'), + os.path.join(self.sm_root, 'public', 'amtl', 'amtl'), + os.path.join(self.sm_root, 'public', 'amtl'), + os.path.join(self.sm_root, 'extensions', 'common', 'include'), + ] + return compiler + + def ConfigureForHL2(self, binary, sdk): + compiler = binary.compiler + + if sdk.name == 'episode1': + mms_path = os.path.join(self.mms_root, 'core-legacy') + else: + mms_path = os.path.join(self.mms_root, 'core') + + compiler.cxxincludes += [ + os.path.join(mms_path), + os.path.join(mms_path, 'sourcehook'), + ] + + 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 ['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', 'COMPILER_MSVC32'] + else: + compiler.defines += ['COMPILER_GCC'] + + # 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 builder.target_platform in ['linux', 'mac']: + compiler.defines += ['NO_HOOK_MALLOC', 'NO_MALLOC_OVERRIDE'] + + if sdk.name == 'csgo' and builder.target_platform == 'linux': + compiler.linkflags += ['-lstdc++'] + + for path in paths: + compiler.cxxincludes += [os.path.join(sdk.path, *path)] + + if builder.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') + else: + lib_folder = os.path.join(sdk.path, 'lib', 'linux') + elif builder.target_platform == 'mac': + if sdk.name in ['sdk2013', 'bms']: + lib_folder = os.path.join(sdk.path, 'lib', 'public', 'osx32') + else: + lib_folder = os.path.join(sdk.path, 'lib', 'mac') + + if builder.target_platform in ['linux', 'mac']: + if sdk.name in ['sdk2013', 'bms']: + compiler.postlink += [ + compiler.Dep(os.path.join(lib_folder, 'tier1.a')), + compiler.Dep(os.path.join(lib_folder, 'mathlib.a')) + ] + else: + compiler.postlink += [ + compiler.Dep(os.path.join(lib_folder, 'tier1_i486.a')), + compiler.Dep(os.path.join(lib_folder, 'mathlib_i486.a')) + ] + + if sdk.name in ['blade', 'insurgency', 'doi', 'csgo']: + compiler.postlink += [compiler.Dep(os.path.join(lib_folder, 'interfaces_i486.a'))] + + dynamic_libs = [] + if builder.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 sdk.name in ['l4d', 'blade', 'insurgency', 'doi', 'csgo']: + dynamic_libs = ['libtier0.so', 'libvstdlib.so'] + else: + dynamic_libs = ['tier0_i486.so', 'vstdlib_i486.so'] + elif builder.target_platform == 'mac': + compiler.linkflags.append('-liconv') + dynamic_libs = ['libtier0.dylib', 'libvstdlib.dylib'] + elif builder.target_platform == 'windows': + libs = ['tier0', 'tier1', 'vstdlib', 'mathlib'] + if sdk.name in ['swarm', 'blade', 'insurgency', 'doi', 'csgo']: + libs.append('interfaces') + for lib in libs: + lib_path = os.path.join(sdk.path, 'lib', 'public', lib) + '.lib' + compiler.linkflags.append(compiler.Dep(lib_path)) + + for library in dynamic_libs: + source_path = os.path.join(lib_folder, library) + output_path = os.path.join(binary.localFolder, library) + + def make_linker(source_path, output_path): + def link(context, binary): + cmd_node, (output,) = context.AddSymlink(source_path, output_path) + return output + return link + + linker = make_linker(source_path, output_path) + compiler.linkflags[0:0] = [compiler.Dep(library, linker)] + + return binary + + def HL2Library(self, context, name, sdk): + binary = context.compiler.Library(name) + self.ConfigureForExtension(context, binary.compiler) + return self.ConfigureForHL2(binary, sdk) + + def HL2Project(self, context, name): + project = context.compiler.LibraryProject(name) + self.ConfigureForExtension(context, project.compiler) + return project + + def HL2Config(self, project, name, sdk): + binary = project.Configure(name, '{0} - {1}'.format(self.tag, sdk.name)) + return self.ConfigureForHL2(binary, sdk) + +Extension = ExtensionConfig() +Extension.detectSDKs() +Extension.configure() + +# Add additional buildscripts here +BuildScripts = [ + 'AMBuilder', +] + +if builder.backend == 'amb2': + BuildScripts += [ + 'PackageScript', + ] + +builder.RunBuildScripts(BuildScripts, { 'Extension': Extension}) diff --git a/AMBuilder b/AMBuilder new file mode 100644 index 0000000..33bd18a --- /dev/null +++ b/AMBuilder @@ -0,0 +1,20 @@ +# vim: set sts=2 ts=8 sw=2 tw=99 et ft=python: +import os + +if not "SM" in globals(): + SM = Extension + +projectName = 'sendsnapshotfixer' + +project = SM.HL2Project(builder, projectName + '.ext') +project.sources += [ + 'ssf.cpp', +] +project.compiler.defines += ['HAVE_STRING_H']; + +for sdk_name in SM.sdks: + sdk = SM.sdks[sdk_name] + + binary = SM.HL2Config(project, projectName + '_mm_i486', sdk) + +SM.extensions += builder.Add(project) diff --git a/PackageScript b/PackageScript new file mode 100644 index 0000000..2521942 --- /dev/null +++ b/PackageScript @@ -0,0 +1,36 @@ +# vim: set ts=8 sts=2 sw=2 tw=99 et ft=python: +import os + +# This is where the files will be output to +# package is the default +builder.SetBuildFolder('package') + +# Add any folders you need to this list +folder_list = [ + 'addons/metamod', + 'addons/sendsnapshotfixer/bin', +] + +# Create the distribution folder hierarchy. +folder_map = {} +for folder in folder_list: + norm_folder = os.path.normpath(folder) + folder_map[folder] = builder.AddFolder(norm_folder) + +# Do all straight-up file copies from the source tree. +def CopyFiles(src, dest, files): + if not dest: + dest = src + dest_entry = folder_map[dest] + for source_file in files: + source_path = os.path.join(builder.sourcePath, src, source_file) + builder.AddCopy(source_path, dest_entry) + +# Metamod VDF +CopyFiles('addons/metamod', 'addons/metamod', + [ 'sendsnapshotfixer.vdf' ] +) + +# Copy binaries. +for cxx_task in Extension.extensions: + builder.AddCopy(cxx_task.binary, folder_map['addons/sendsnapshotfixer/bin']) diff --git a/addons/metamod/sendsnapshotfixer.vdf b/addons/metamod/sendsnapshotfixer.vdf new file mode 100644 index 0000000..6b137de --- /dev/null +++ b/addons/metamod/sendsnapshotfixer.vdf @@ -0,0 +1,5 @@ +"Metamod Plugin" +{ + "alias" "sendsnapshotfixer" + "file" "addons/sendsnapshotfixer/bin/sendsnapshotfixer_mm" +} diff --git a/configure.py b/configure.py new file mode 100644 index 0000000..57910e8 --- /dev/null +++ b/configure.py @@ -0,0 +1,23 @@ +# vim: set sts=2 ts=8 sw=2 tw=99 et: +import sys +from ambuild2 import run + +# Simple extensions do not need to modify this file. + +builder = run.PrepareBuild(sourcePath = sys.path[0]) + +builder.options.add_option('--hl2sdk-root', type=str, dest='hl2sdk_root', default=None, + help='Root search folder for HL2SDKs') +builder.options.add_option('--mms-path', type=str, dest='mms_path', default=None, + help='Path to Metamod:Source') +builder.options.add_option('--sm-path', type=str, dest='sm_path', default=None, + help='Path to SourceMod') +builder.options.add_option('--enable-debug', action='store_const', const='1', dest='debug', + help='Enable debugging symbols') +builder.options.add_option('--enable-optimize', action='store_const', const='1', dest='opt', + help='Enable optimization') +builder.options.add_option('-s', '--sdks', default='all', dest='sdks', + help='Build against specified SDKs; valid args are "all", "present", or ' + 'comma-delimited list of engine names (default: %default)') + +builder.Configure() diff --git a/engine_wrappers.h b/engine_wrappers.h new file mode 100644 index 0000000..255b648 --- /dev/null +++ b/engine_wrappers.h @@ -0,0 +1,98 @@ +/** + * vim: set ts=4 sw=4 tw=99 noet : + * ====================================================== + * Metamod:Source Sample Plugin + * Written by AlliedModders LLC. + * ====================================================== + * + * This software is provided 'as-is', without any express or implied warranty. + * In no event will the authors be held liable for any damages arising from + * the use of this software. + * + * This sample plugin is public domain. + */ + +#ifndef _INCLUDE_SOURCE_ENGINE_WRAPPERS_ +#define _INCLUDE_SOURCE_ENGINE_WRAPPERS_ + +#include + +extern IVEngineServer *engine; +extern CGlobalVars *gpGlobals; + +#if SOURCE_ENGINE == SE_EPISODEONE && defined METAMOD_PLAPI_VERSION +#error "Metamod:Source 1.6 API is not supported on the old engine." +#endif + +#define ENGINE_CALL(func) SH_CALL(engine, &IVEngineServer::func) + +/** + * Wrap some API calls for legacy MM:S. + */ +#if !defined METAMOD_PLAPI_VERSION +#define GetEngineFactory engineFactory +#define GetServerFactory serverFactory +#define MM_Format snprintf +#define GetCGlobals pGlobals +#else +#define MM_Format g_SMAPI->Format +#endif + +#if SOURCE_ENGINE <= SE_DARKMESSIAH +/** + * Wrap the CCommand class so our code looks the same on all engines. + */ +class CCommand +{ +public: + const char *ArgS() + { + return engine->Cmd_Args(); + } + int ArgC() + { + return engine->Cmd_Argc(); + } + + const char *Arg(int index) + { + return engine->Cmd_Argv(index); + } +}; + +#define CVAR_INTERFACE_VERSION VENGINE_CVAR_INTERFACE_VERSION +#endif + +/** + * Left 4 Dead engine removed these from IVEngineServer. + */ +#if SOURCE_ENGINE >= SE_LEFT4DEAD + +inline int IndexOfEdict(const edict_t *pEdict) +{ + return (int)(pEdict - gpGlobals->pEdicts); +} +inline edict_t *PEntityOfEntIndex(int iEntIndex) +{ + if (iEntIndex >= 0 && iEntIndex < gpGlobals->maxEntities) + { + return (edict_t *)(gpGlobals->pEdicts + iEntIndex); + } + return NULL; +} + +#else + +inline int IndexOfEdict(const edict_t *pEdict) +{ + return engine->IndexOfEdict(pEdict); +} +inline edict_t *PEntityOfEntIndex(int iEntIndex) +{ + return engine->PEntityOfEntIndex(iEntIndex); +} + +#endif + +#endif //_INCLUDE_SOURCE_ENGINE_WRAPPERS_ + diff --git a/msvc9/sample_mm.sln b/msvc9/sample_mm.sln new file mode 100644 index 0000000..3aa0d4d --- /dev/null +++ b/msvc9/sample_mm.sln @@ -0,0 +1,56 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sample_mm", "sample_mm.vcproj", "{E62E5876-E1E2-41A0-85CA-1B41B9DA55F9}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug - Alien Swarm|Win32 = Debug - Alien Swarm|Win32 + Debug - Dark Messiah|Win32 = Debug - Dark Messiah|Win32 + Debug - Left 4 Dead 2|Win32 = Debug - Left 4 Dead 2|Win32 + Debug - Left 4 Dead|Win32 = Debug - Left 4 Dead|Win32 + Debug - Orange Box Valve|Win32 = Debug - Orange Box Valve|Win32 + Debug - Orange Box|Win32 = Debug - Orange Box|Win32 + Debug - Original|Win32 = Debug - Original|Win32 + Release - Alien Swarm|Win32 = Release - Alien Swarm|Win32 + Release - Dark Messiah|Win32 = Release - Dark Messiah|Win32 + Release - Left 4 Dead 2|Win32 = Release - Left 4 Dead 2|Win32 + Release - Left 4 Dead|Win32 = Release - Left 4 Dead|Win32 + Release - Orange Box Valve|Win32 = Release - Orange Box Valve|Win32 + Release - Orange Box|Win32 = Release - Orange Box|Win32 + Release - Original|Win32 = Release - Original|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E62E5876-E1E2-41A0-85CA-1B41B9DA55F9}.Debug - Alien Swarm|Win32.ActiveCfg = Debug - Alien Swarm|Win32 + {E62E5876-E1E2-41A0-85CA-1B41B9DA55F9}.Debug - Alien Swarm|Win32.Build.0 = Debug - Alien Swarm|Win32 + {E62E5876-E1E2-41A0-85CA-1B41B9DA55F9}.Debug - Dark Messiah|Win32.ActiveCfg = Debug - Dark Messiah|Win32 + {E62E5876-E1E2-41A0-85CA-1B41B9DA55F9}.Debug - Dark Messiah|Win32.Build.0 = Debug - Dark Messiah|Win32 + {E62E5876-E1E2-41A0-85CA-1B41B9DA55F9}.Debug - Left 4 Dead 2|Win32.ActiveCfg = Debug - Left 4 Dead 2|Win32 + {E62E5876-E1E2-41A0-85CA-1B41B9DA55F9}.Debug - Left 4 Dead 2|Win32.Build.0 = Debug - Left 4 Dead 2|Win32 + {E62E5876-E1E2-41A0-85CA-1B41B9DA55F9}.Debug - Left 4 Dead|Win32.ActiveCfg = Debug - Left 4 Dead|Win32 + {E62E5876-E1E2-41A0-85CA-1B41B9DA55F9}.Debug - Left 4 Dead|Win32.Build.0 = Debug - Left 4 Dead|Win32 + {E62E5876-E1E2-41A0-85CA-1B41B9DA55F9}.Debug - Orange Box Valve|Win32.ActiveCfg = Debug - Orange Box Valve|Win32 + {E62E5876-E1E2-41A0-85CA-1B41B9DA55F9}.Debug - Orange Box Valve|Win32.Build.0 = Debug - Orange Box Valve|Win32 + {E62E5876-E1E2-41A0-85CA-1B41B9DA55F9}.Debug - Orange Box|Win32.ActiveCfg = Debug - Orange Box|Win32 + {E62E5876-E1E2-41A0-85CA-1B41B9DA55F9}.Debug - Orange Box|Win32.Build.0 = Debug - Orange Box|Win32 + {E62E5876-E1E2-41A0-85CA-1B41B9DA55F9}.Debug - Original|Win32.ActiveCfg = Debug - Original|Win32 + {E62E5876-E1E2-41A0-85CA-1B41B9DA55F9}.Debug - Original|Win32.Build.0 = Debug - Original|Win32 + {E62E5876-E1E2-41A0-85CA-1B41B9DA55F9}.Release - Alien Swarm|Win32.ActiveCfg = Release - Alien Swarm|Win32 + {E62E5876-E1E2-41A0-85CA-1B41B9DA55F9}.Release - Alien Swarm|Win32.Build.0 = Release - Alien Swarm|Win32 + {E62E5876-E1E2-41A0-85CA-1B41B9DA55F9}.Release - Dark Messiah|Win32.ActiveCfg = Release - Dark Messiah|Win32 + {E62E5876-E1E2-41A0-85CA-1B41B9DA55F9}.Release - Dark Messiah|Win32.Build.0 = Release - Dark Messiah|Win32 + {E62E5876-E1E2-41A0-85CA-1B41B9DA55F9}.Release - Left 4 Dead 2|Win32.ActiveCfg = Release - Left 4 Dead 2|Win32 + {E62E5876-E1E2-41A0-85CA-1B41B9DA55F9}.Release - Left 4 Dead 2|Win32.Build.0 = Release - Left 4 Dead 2|Win32 + {E62E5876-E1E2-41A0-85CA-1B41B9DA55F9}.Release - Left 4 Dead|Win32.ActiveCfg = Release - Left 4 Dead|Win32 + {E62E5876-E1E2-41A0-85CA-1B41B9DA55F9}.Release - Left 4 Dead|Win32.Build.0 = Release - Left 4 Dead|Win32 + {E62E5876-E1E2-41A0-85CA-1B41B9DA55F9}.Release - Orange Box Valve|Win32.ActiveCfg = Release - Orange Box Valve|Win32 + {E62E5876-E1E2-41A0-85CA-1B41B9DA55F9}.Release - Orange Box Valve|Win32.Build.0 = Release - Orange Box Valve|Win32 + {E62E5876-E1E2-41A0-85CA-1B41B9DA55F9}.Release - Orange Box|Win32.ActiveCfg = Release - Orange Box|Win32 + {E62E5876-E1E2-41A0-85CA-1B41B9DA55F9}.Release - Orange Box|Win32.Build.0 = Release - Orange Box|Win32 + {E62E5876-E1E2-41A0-85CA-1B41B9DA55F9}.Release - Original|Win32.ActiveCfg = Release - Original|Win32 + {E62E5876-E1E2-41A0-85CA-1B41B9DA55F9}.Release - Original|Win32.Build.0 = Release - Original|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/msvc9/sample_mm.vcproj b/msvc9/sample_mm.vcproj new file mode 100644 index 0000000..b50822b --- /dev/null +++ b/msvc9/sample_mm.vcproj @@ -0,0 +1,1162 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ssf.cpp b/ssf.cpp new file mode 100644 index 0000000..dca76c8 --- /dev/null +++ b/ssf.cpp @@ -0,0 +1,165 @@ +#include "ssf.h" + +using namespace SourceHook; + +SSF g_SSF; + +PLUGIN_EXPOSE(SSF, g_SSF); + +CGlobalVars *gpGlobals = NULL; + +uint8_t g_UserIDtoClientMap[USHRT_MAX + 1]; + +// SH_DECL_HOOK1(IClient, SendSnapshot, SH_NOATTRIB, 0, void, CClientFrame *); + +SH_DECL_MANUALHOOK1(CBaseClient_SendSnapshot, 0, 0, 0, void, CClientFrame *) + +#if !defined ORANGEBOX_BUILD +ICvar* g_pCVar = NULL; +#endif + +ICvar* GetICVar() +{ +#if defined METAMOD_PLAPI_VERSION +#if SOURCE_ENGINE==SE_ORANGEBOX || SOURCE_ENGINE==SE_LEFT4DEAD || SOURCE_ENGINE==SE_LEFT4DEAD2 || SOURCE_ENGINE==SE_TF2 || SOURCE_ENGINE==SE_DODS || SOURCE_ENGINE==SE_HL2DM || SOURCE_ENGINE==SE_NUCLEARDAWN || \ + SOURCE_ENGINE==SE_ALIENSWARM || SOURCE_ENGINE==SE_BLOODYGOODTIME || SOURCE_ENGINE==SE_CSGO || SOURCE_ENGINE==SE_CSS || SOURCE_ENGINE==SE_INSURGENCY || SOURCE_ENGINE==SE_SDK2013 || SOURCE_ENGINE== SE_BMS + return (ICvar *)((g_SMAPI->GetEngineFactory())(CVAR_INTERFACE_VERSION, NULL)); +#else + return (ICvar *)((g_SMAPI->GetEngineFactory())(VENGINE_CVAR_INTERFACE_VERSION, NULL)); +#endif +#else + return (ICvar *)((g_SMAPI->engineFactory())(VENGINE_CVAR_INTERFACE_VERSION, NULL)); +#endif +} + +ConVar cvar_ssf_log("ssf_log", "0", FCVAR_NONE, "Log sendsnapshot"); + +bool SSF::Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen, bool late) +{ + PLUGIN_SAVEVARS(); + gpGlobals = ismm->GetCGlobals(); + + META_LOG(g_PLAPI, "Starting plugin."); + +#if SOURCE_ENGINE==SE_ORANGEBOX || SOURCE_ENGINE==SE_LEFT4DEAD || SOURCE_ENGINE==SE_LEFT4DEAD2 || SOURCE_ENGINE==SE_TF2 || SOURCE_ENGINE==SE_DODS || SOURCE_ENGINE==SE_HL2DM || SOURCE_ENGINE==SE_NUCLEARDAWN || \ + SOURCE_ENGINE==SE_ALIENSWARM || SOURCE_ENGINE==SE_BLOODYGOODTIME || SOURCE_ENGINE==SE_CSGO || SOURCE_ENGINE==SE_CSS || SOURCE_ENGINE==SE_INSURGENCY || SOURCE_ENGINE==SE_SDK2013 || SOURCE_ENGINE== SE_BMS + g_pCVar = GetICVar(); + ConVar_Register(0, this); +#else + ConCommandBaseMgr::OneTimeInit(this); +#endif + + return true; +} + +bool SSF::Unload(char *error, size_t maxlen) +{ + return true; +} + +void Hook_SendSnapshot(CClientFrame *pFrame) +{ + if (cvar_ssf_log.GetBool()) + { + g_SMAPI->LogMsg(g_PLAPI, "SSF: Inside SendSnapshot"); + } +} + +void PlayerConnect(const int client, const int userid, const bool bot, const char *name) +{ + if (client >= 1 && client <= SM_MAXPLAYERS) + { + g_UserIDtoClientMap[userid] = client; + + IClient* pClient = iserver->GetClient(client - 1); + void *pGameClient = (void *)((intptr_t)pClient - 4); + SH_ADD_MANUALHOOK(CBaseClient_SendSnapshot, pGameClient, SH_STATIC(Hook_SendSnapshot), false); + } +} + +void PlayerDisconnect(const int userid) +{ + const int client = g_UserIDtoClientMap[userid]; + g_UserIDtoClientMap[userid] = 0; + + SH_REMOVE_MANUALHOOK(CBaseClient_SendSnapshot, pGameClient, SH_STATIC(Hook_SendSnapshot), false); +} + +void ConnectEvents::FireGameEvent(IGameEvent *event) +{ + const char *name = event->GetName(); + + if(strcmp(name, "player_connect") == 0) + { + const int client = event->GetInt("index") + 1; + const int userid = event->GetInt("userid"); + const bool bot = event->GetBool("bot"); + const char *name = event->GetString("name"); + PlayerConnect(client, userid, bot, name); + } + else if(strcmp(name, "player_disconnect") == 0) + { + const int userid = event->GetInt("userid"); + PlayerDisconnect(userid); + } +} + + +bool SSF::RegisterConCommandBase(ConCommandBase *pVar) +{ + return META_REGCVAR(pVar); +} + +bool SSF::Pause(char *error, size_t maxlen) +{ + return true; +} + +bool SSF::Unpause(char *error, size_t maxlen) +{ + return true; +} + +void SSF::AllPluginsLoaded() +{ +} + +const char *SSF::GetLicense() +{ + return "GPL"; +} + +const char *SSF::GetVersion() +{ + return "1.0.0"; +} + +const char *SSF::GetDate() +{ + return __DATE__; +} + +const char *SSF::GetLogTag() +{ + return "SSF"; +} + +const char *SSF::GetAuthor() +{ + return "maxime1907"; +} + +const char *SSF::GetDescription() +{ + return "Fixes the currently messed up sv_parallel_sendsnapshot."; +} + +const char *SSF::GetName() +{ + return "SendSnapshot Fixer"; +} + +const char *SSF::GetURL() +{ + return "http://www.gitlab.com/leroy_0/sendsnapshotfixer/"; +} \ No newline at end of file diff --git a/ssf.h b/ssf.h new file mode 100644 index 0000000..479d806 --- /dev/null +++ b/ssf.h @@ -0,0 +1,38 @@ +#ifdef _INCLUDE_METAMOD_SOURCE_SSF +#endinput +#endif + +#define _INCLUDE_METAMOD_SOURCE_SSF + +#include +#include "engine_wrappers.h" +#include +#include + +void Hook_SendSnapshot(CClientFrame *pFrame); + +class SSF : + public ISmmPlugin, + public IConCommandBaseAccessor +{ +public: + bool Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen, bool late); + bool Unload(char *error, size_t maxlen); + bool Pause(char *error, size_t maxlen); + bool Unpause(char *error, size_t maxlen); + void AllPluginsLoaded(); +public: + const char *GetAuthor(); + const char *GetName(); + const char *GetDescription(); + const char *GetURL(); + const char *GetLicense(); + const char *GetVersion(); + const char *GetDate(); + const char *GetLogTag(); +public: //IConCommandBaseAccessor + bool RegisterConCommandBase(ConCommandBase *pVar); + +}; + +PLUGIN_GLOBALVARS();