├── .github └── workflows │ └── ci.yml ├── .gitignore ├── .gitmodules ├── .travis.yml ├── AMBuildScript ├── LICENSE.txt ├── README.md ├── appveyor.yml ├── configure.py ├── core ├── AMBuilder ├── IPluginManager.h ├── ISmmAPI.h ├── ISmmPlugin.h ├── ISmmPluginExt.h ├── gamedll_bridge.cpp ├── metamod.cpp ├── metamod.h ├── metamod_console.cpp ├── metamod_console.h ├── metamod_convar.h ├── metamod_oslink.cpp ├── metamod_oslink.h ├── metamod_plugins.cpp ├── metamod_plugins.h ├── metamod_provider.h ├── metamod_util.cpp ├── metamod_util.h ├── provider │ ├── provider_base.cpp │ ├── provider_base.h │ ├── source │ │ ├── provider_source.cpp │ │ ├── provider_source.h │ │ └── provider_source_console.cpp │ └── source2 │ │ ├── provider_source2.cpp │ │ └── provider_source2.h ├── sourcehook │ ├── FastDelegate.h │ ├── generate │ │ ├── generate │ │ ├── generate.bat │ │ ├── shworker.bin │ │ ├── shworker.exe │ │ ├── shworker │ │ │ ├── Makefile │ │ │ ├── fd_hopter.cpp │ │ │ ├── msvc7 │ │ │ │ └── shworker.vcproj │ │ │ ├── msvc8 │ │ │ │ └── shworker.vcproj │ │ │ ├── msvc9 │ │ │ │ ├── shworker.sln │ │ │ │ └── shworker.vcproj │ │ │ └── shworker.cpp │ │ └── sourcehook.hxx │ ├── sh_asm.h │ ├── sh_asm_x86_64.h │ ├── sh_list.h │ ├── sh_memfuncinfo.h │ ├── sh_memory.h │ ├── sh_pagealloc.h │ ├── sh_stack.h │ ├── sh_string.h │ ├── sh_tinyhash.h │ ├── sh_vector.h │ ├── sourcehook.cpp │ ├── sourcehook.h │ ├── sourcehook_hookmangen.cpp │ ├── sourcehook_hookmangen.h │ ├── sourcehook_hookmangen_x86.cpp │ ├── sourcehook_hookmangen_x86.h │ ├── sourcehook_hookmangen_x86_64.cpp │ ├── sourcehook_hookmangen_x86_64.h │ ├── sourcehook_impl.h │ ├── sourcehook_impl_chook.h │ ├── sourcehook_impl_chookidman.cpp │ ├── sourcehook_impl_chookidman.h │ ├── sourcehook_impl_chookmaninfo.cpp │ ├── sourcehook_impl_chookmaninfo.h │ ├── sourcehook_impl_ciface.h │ ├── sourcehook_impl_cleanuptask.h │ ├── sourcehook_impl_cproto.cpp │ ├── sourcehook_impl_cproto.h │ ├── sourcehook_impl_cvfnptr.cpp │ ├── sourcehook_impl_cvfnptr.h │ ├── sourcehook_pibuilder.h │ └── test │ │ ├── AMBuilder │ │ ├── Makefile │ │ ├── generate.bat │ │ ├── main.cpp │ │ ├── msvc12 │ │ ├── test.sln │ │ ├── test.vcxproj │ │ └── test.vcxproj.filters │ │ ├── msvc7 │ │ └── test.vcproj │ │ ├── msvc8 │ │ └── test.vcproj │ │ ├── sourcehook_test.h │ │ ├── test.sln │ │ ├── test.vcproj │ │ ├── test1.cpp │ │ ├── test2.cpp │ │ ├── test3.cpp │ │ ├── test4.cpp │ │ ├── testbail.cpp │ │ ├── testbail.h │ │ ├── testbail2.cpp │ │ ├── testevents.h │ │ ├── testhookmangen.cpp │ │ ├── testhookmangen.h │ │ ├── testhookmangen.hxx │ │ ├── testlist.cpp │ │ ├── testmanual.cpp │ │ ├── testmulti.cpp │ │ ├── testoddthunks.cpp │ │ ├── testrecall.cpp │ │ ├── testreentr.cpp │ │ ├── testref.cpp │ │ ├── testrefret.cpp │ │ ├── testvphooks.cpp │ │ └── version.rc ├── version.rc └── vsp_bridge.cpp ├── cruft └── installer │ ├── Attach.cfg │ ├── Attach.dpr │ ├── Attach.exe │ ├── HL2Launch.cfg │ ├── HL2Launch.dpr │ ├── HL2Launch.exe │ ├── MMS_Installer.cfg │ ├── MMS_Installer.dpr │ ├── MMS_Installer.exe │ ├── MMS_Installer.res │ ├── UnitFunctions.pas │ ├── UnitInstall.pas │ ├── UnitPackSystem.pas │ ├── UnitSelectModPath.dfm │ ├── UnitSelectModPath.pas │ ├── UnitfrmMain.dfm │ ├── UnitfrmMain.pas │ ├── UnitfrmProxy.dfm │ ├── UnitfrmProxy.pas │ ├── del.bat │ ├── files │ └── Readme.txt │ ├── install.bmp │ └── upx.exe ├── loader ├── AMBuilder ├── gamedll.cpp ├── gamedll.h ├── loader.cpp ├── loader.h ├── loader_bridge.h ├── serverplugin.cpp ├── serverplugin.h ├── test │ ├── AMBuilder │ ├── README.md │ ├── determinebackends1.cpp │ ├── main.cpp │ ├── testutility.cpp │ └── version.rc ├── utility.cpp ├── utility.h └── version.rc ├── product.version ├── public └── metamod_version.h ├── pushbuild.txt ├── samples ├── s1_sample_mm │ ├── AMBuildScript │ ├── README.md │ ├── configure.py │ ├── engine_wrappers.h │ ├── msvc10 │ │ ├── sample_mm.sln │ │ ├── sample_mm.vcxproj │ │ └── sample_mm.vcxproj.filters │ ├── msvc8 │ │ ├── sample_mm.sln │ │ └── sample_mm.vcproj │ ├── msvc9 │ │ ├── sample_mm.sln │ │ └── sample_mm.vcproj │ ├── product.version │ ├── sample_mm.cpp │ ├── sample_mm.h │ └── sample_mm.vdf ├── s1_stub_mm │ ├── Makefile │ ├── README.md │ ├── msvc10 │ │ ├── stub_mm.sln │ │ ├── stub_mm.vcxproj │ │ └── stub_mm.vcxproj.filters │ ├── msvc8 │ │ ├── stub_mm.sln │ │ └── stub_mm.vcproj │ ├── msvc9 │ │ ├── stub_mm.sln │ │ └── stub_mm.vcproj │ ├── stub_mm.cpp │ ├── stub_mm.h │ └── stub_mm.vdf └── s2_sample_mm │ ├── AMBuildScript │ ├── AMBuilder │ ├── PackageScript │ ├── README.md │ ├── configure.py │ ├── sample_mm.cpp │ └── sample_mm.h ├── support ├── README.txt ├── SourceMM.Doxyfile ├── buildbot │ ├── BreakpadSymbols │ ├── PackageScript │ ├── Versioning │ ├── bootstrap.py │ ├── build_type │ ├── buildconfig.json │ ├── generate_headers.py │ ├── helpers.pm │ ├── package.pl │ ├── startbuild.pl │ ├── symstore.pl │ ├── trigger_full_rebuild │ └── upload_symbols.py ├── changelog.txt ├── checkout-deps.ps1 ├── checkout-deps.sh ├── dll2lib.ps1 ├── metamod.vdf ├── metamod_linux64.vdf ├── metamod_osx64.vdf ├── metamod_win64.vdf ├── metaplugins.ini └── msvc_project_templates │ ├── MMSProjectTemplate.2005.vcproj │ ├── MMSProjectTemplate.2008.vcproj │ └── VC │ ├── VCProjects │ ├── MMSProjectTemplate.ico │ ├── MMSProjectTemplate.vsz │ └── Metamod │ │ └── MMSProjectTemplate.vsdir │ └── VCWizards │ └── AppWiz │ └── Metamod │ └── MMSProjectTemplate │ ├── 1033 │ ├── Images │ │ ├── DottedHori.gif │ │ ├── DottedVert.gif │ │ └── spacer.gif │ └── NewStyles.css │ ├── HTML │ └── 1033 │ │ └── default.htm │ ├── Images │ ├── MMSProjectTemplate.gif │ └── MMSProjectTemplate_Background.gif │ ├── Scripts │ └── 1033 │ │ └── default.js │ └── Templates │ └── 1033 │ ├── ReadMe.txt │ ├── StdMMS.h │ ├── Templates.inf │ ├── plugin.vcproj │ ├── plugin.vdf │ ├── plugin_engine.h │ ├── plugin_hooks.cpp │ ├── plugin_hooks.h │ ├── plugin_mm.cpp │ └── plugin_mm.h └── versionlib ├── AMBuildScript ├── versionlib.cpp └── versionlib.h /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries 2 | *.dll 3 | *.dylib 4 | *.exe 5 | *.so 6 | 7 | # Files generated by Visual Studio 8 | *.aps 9 | *.ncb 10 | *.sdf 11 | *.suo 12 | *.user 13 | 14 | # Build directories 15 | Debug.*/ 16 | Release.*/ 17 | 18 | # Files generated by Mac OS X Finder 19 | .DS_Store 20 | 21 | # Files generated by Windows Explorer 22 | [Dd]esktop.ini 23 | [Tt]humbs.db 24 | 25 | # AMBuild build directories 26 | build/ 27 | build-*/ 28 | obj-*/ 29 | .gdb_history 30 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "third_party/amtl"] 2 | path = third_party/amtl 3 | url = https://github.com/alliedmodders/amtl 4 | [submodule "hl2sdk-manifests"] 5 | path = hl2sdk-manifests 6 | url = https://github.com/alliedmodders/hl2sdk-manifests 7 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | git: 2 | depth: 3 3 | 4 | sudo: false 5 | language: cpp 6 | os: linux 7 | dist: trusty 8 | addons: 9 | apt: 10 | sources: 11 | - ubuntu-toolchain-r-test 12 | - llvm-toolchain-trusty-3.9 13 | - llvm-toolchain-trusty-4.0 14 | - llvm-toolchain-trusty-5.0 15 | packages: 16 | - lib32stdc++6 17 | - lib32z1-dev 18 | - libc6-dev-i386 19 | - linux-libc-dev 20 | - g++-multilib 21 | # - clang-3.6 22 | # - clang-3.8 23 | # - clang-4.0 24 | # - clang-5.0 25 | # - g++-6 26 | # - g++-6-multilib 27 | - clang-3.9 28 | - g++-4.8-multilib 29 | - g++-4.8 30 | - g++-4.9-multilib 31 | - g++-4.9 32 | - g++-5-multilib 33 | - g++-5 34 | - g++-7-multilib 35 | - g++-7 36 | cache: 37 | directories: 38 | - ../mysql-5.0 39 | 40 | matrix: 41 | fast_finish: true 42 | include: 43 | - os: linux 44 | sudo: false 45 | language: cpp 46 | addons: 47 | apt: 48 | packages: ['clang-3.6', 'lib32stdc++6', 'lib32z1-dev', 'libc6-dev-i386', 'linux-libc-dev', 'g++-multilib'] 49 | env: ['MATRIX_EVAL="CC=clang-3.6 && CXX=clang++-3.6"'] 50 | 51 | - os: linux 52 | sudo: false 53 | language: cpp 54 | addons: 55 | apt: 56 | packages: ['clang-3.8', 'lib32stdc++6', 'lib32z1-dev', 'libc6-dev-i386', 'linux-libc-dev', 'g++-multilib'] 57 | env: ['MATRIX_EVAL="CC=clang-3.8 && CXX=clang++-3.8"'] 58 | 59 | - os: linux 60 | sudo: false 61 | language: cpp 62 | addons: 63 | apt: 64 | sources: ['ubuntu-toolchain-r-test'] 65 | packages: ['g++-6', 'g++-6-multilib', 'lib32stdc++6', 'lib32z1-dev', 'libc6-dev-i386', 'linux-libc-dev', 'g++-multilib'] 66 | env: ['MATRIX_EVAL="CC=gcc-6 && CXX=g++-6"'] 67 | 68 | before_script: 69 | - CHECKOUT_DIR=$PWD && cd .. && $CHECKOUT_DIR/support/checkout-deps.sh && cd $CHECKOUT_DIR 70 | script: 71 | - mkdir build && cd build 72 | - PATH="~/.local/bin:$PATH" 73 | - eval "${MATRIX_EVAL}" 74 | - python ../configure.py --enable-optimize --sdks=episode1,tf2,l4d2,csgo,dota 75 | - ambuild 76 | - cd .. && mkdir build-sh-opt && cd build-sh-opt 77 | - python ../configure.py --enable-optimize --enable-tests --sdks= 78 | - ambuild 79 | - ./core/sourcehook/test/test_sourcehook/linux-x86/test_sourcehook -v 80 | - ./core/sourcehook/test/test_sourcehook/linux-x86_64/test_sourcehook -v 81 | - cd .. && mkdir build-sh-debug && cd build-sh-debug 82 | - python ../configure.py --enable-debug --enable-tests --sdks= 83 | - ambuild 84 | - ./core/sourcehook/test/test_sourcehook/linux-x86/test_sourcehook -v 85 | - ./core/sourcehook/test/test_sourcehook/linux-x86_64/test_sourcehook -v 86 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The software is Copyright (C) 2004-2008, Metamod:Source Development Team. 2 | 3 | Metamod:Source is distributed under the "zLib/libpng" license, which is reproduced 4 | below: 5 | 6 | ----------------------------------------------------------------------------- 7 | 8 | This software is provided "as-is", without any express or implied warranty. 9 | In no event will the authors be held liable for any damages arising from 10 | the use of this software. 11 | 12 | Permission is granted to anyone to use this software for any purpose, 13 | including commercial applications, and to alter it and redistribute it 14 | freely, subject to the following restrictions: 15 | 16 | 1. The origin of this software must not be misrepresented; you must not 17 | claim that you wrote the original software. If you use this software in 18 | a product, an acknowledgment in the product documentation would be 19 | appreciated but is not required. 20 | 21 | 2. Altered source versions must be plainly marked as such, and must not 22 | be misrepresented as being the original software. 23 | 24 | 3. This notice may not be removed or altered from any source distribution. 25 | 26 | ----------------------------------------------------------------------------- 27 | 28 | The zLib/libpng license has been approved by the "Open Source Initiative" 29 | organization. 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Metamod:Source 2 | ============== 3 | 4 | Metamod:Source - A C++ Plugin Environment and Detour Library for the Source Engine. 5 | 6 | Build instructions 7 | ------------------ 8 | 9 | Make sure ambuild2 is installed: https://github.com/alliedmodders/ambuild 10 | 11 | Clone the repo with submodules: 12 | ``` 13 | git clone --recurse-submodules https://github.com/alliedmodders/metamod-source 14 | ``` 15 | 16 | Clone the SDK dependencies: 17 | ``` 18 | cd .. 19 | metamod-source/support/checkout-deps.sh 20 | cd metamod-source 21 | ``` 22 | 23 | Configure the build: 24 | ``` 25 | mkdir build 26 | cd build 27 | python ../configure.py 28 | ``` 29 | 30 | Build: 31 | ``` 32 | ambuild 33 | ``` 34 | 35 | You can clone an individual SDK e.g.: 36 | ``` 37 | cd .. 38 | metamod-source/support/checkout-deps.sh -s episode1 39 | cd metamod-source 40 | ``` 41 | 42 | You can configure the build for an individual SDK e.g.: 43 | ``` 44 | mkdir build 45 | cd build 46 | python ../configure.py --sdks episode1 47 | ``` 48 | 49 | Stable build snapshots: 50 | 51 | Development build snapshots: 52 | 53 | General documentation: 54 | 55 | Detouring with SourceHook: 56 | 57 | Development: -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | version: 1.0.{build} 2 | image: Visual Studio 2015 3 | clone_folder: c:\projects\metamod-source 4 | clone_depth: 1 5 | environment: 6 | SDKS: csgo,l4d2,tf2,episode1,insurgency 7 | install: 8 | # https://www.appveyor.com/docs/windows-images-software/#python 9 | - cmd: set PATH=C:\Python38;C:\Python38\Scripts;%PATH% 10 | - cmd: git pull 11 | - cmd: cd .. 12 | - ps: metamod-source/support/checkout-deps.ps1 -SDKs ($env:SDKS -split ',') 13 | - cmd: cd metamod-source 14 | build_script: 15 | - cmd: mkdir build 16 | - cmd: cd build 17 | - cmd: python ../configure.py --enable-optimize --sdks=%SDKS% --targets=x86,x86_64 18 | - cmd: ambuild 19 | -------------------------------------------------------------------------------- /configure.py: -------------------------------------------------------------------------------- 1 | # vim: set sts=2 ts=8 sw=2 tw=99 et: 2 | import sys 3 | try: 4 | from ambuild2 import run, util 5 | except: 6 | try: 7 | import ambuild 8 | sys.stderr.write('It looks like you have AMBuild 1 installed, but this project uses AMBuild 2.\n') 9 | sys.stderr.write('Upgrade to the latest version of AMBuild to continue.\n') 10 | except: 11 | sys.stderr.write('AMBuild must be installed to build this project.\n') 12 | sys.stderr.write('http://www.alliedmods.net/ambuild\n') 13 | sys.exit(1) 14 | 15 | # Hack to show a decent upgrade message, which wasn't done until 2.2. 16 | ambuild_version = getattr(run, 'CURRENT_API', '2.1') 17 | if ambuild_version.startswith('2.1'): 18 | sys.stderr.write("AMBuild 2.2 or higher is required; please update\n") 19 | sys.exit(1) 20 | 21 | parser = run.BuildParser(sourcePath=sys.path[0], api='2.2') 22 | parser.options.add_argument('--hl2sdk-root', type=str, dest='hl2sdk_root', default=None, 23 | help='Root search folder for HL2SDKs') 24 | parser.options.add_argument('--enable-debug', action='store_const', const='1', dest='debug', 25 | help='Enable debugging symbols') 26 | parser.options.add_argument('--enable-optimize', action='store_const', const='1', dest='opt', 27 | help='Enable optimization') 28 | parser.options.add_argument('-s', '--sdks', default='present', dest='sdks', 29 | help='Build against specified SDKs; valid args are "all", "present", or ' 30 | 'comma-delimited list of engine names') 31 | parser.options.add_argument('--enable-tests', default=False, dest='enable_tests', action='store_true', 32 | help='Build tests.') 33 | parser.options.add_argument('--breakpad-dump', action='store_true', dest='breakpad_dump', 34 | default=False, help='Dump and upload breakpad symbols') 35 | parser.options.add_argument('--targets', type=str, dest='targets', default=None, 36 | help="Override the target architecture (use commas to separate multiple targets).") 37 | parser.options.add_argument('--disable-auto-versioning', action='store_true', dest='disable_auto_versioning') 38 | parser.Configure() 39 | -------------------------------------------------------------------------------- /core/AMBuilder: -------------------------------------------------------------------------------- 1 | # vim: set sts=2 ts=8 sw=2 tw=99 et ft=python: 2 | import os 3 | 4 | for sdk_target in MMS.sdk_targets: 5 | sdk = sdk_target.sdk 6 | cxx = sdk_target.cxx 7 | 8 | name = 'metamod.' + sdk['extension'] 9 | binary = MMS.HL2Library(builder, cxx, name, sdk) 10 | 11 | binary.sources += [ 12 | 'metamod.cpp', 13 | 'metamod_console.cpp', 14 | 'metamod_oslink.cpp', 15 | 'metamod_plugins.cpp', 16 | 'metamod_util.cpp', 17 | 'provider/provider_base.cpp', 18 | 'sourcehook/sourcehook.cpp', 19 | 'sourcehook/sourcehook_impl_chookidman.cpp', 20 | 'sourcehook/sourcehook_impl_chookmaninfo.cpp', 21 | 'sourcehook/sourcehook_impl_cproto.cpp', 22 | 'sourcehook/sourcehook_impl_cvfnptr.cpp', 23 | 'sourcehook/sourcehook_hookmangen.cpp', 24 | 'gamedll_bridge.cpp' 25 | ] 26 | 27 | if sdk.get('source2', False): 28 | binary.sources += [ 29 | 'provider/source2/provider_source2.cpp', 30 | ] 31 | binary.custom = [builder.tools.Protoc(protoc = sdk_target.protoc, sources = [ 32 | os.path.join(sdk['path'], 'common', 'network_connection.proto'), 33 | ])] 34 | else: 35 | binary.sources += [ 36 | 'provider/source/provider_source.cpp', 37 | 'provider/source/provider_source_console.cpp', 38 | 'vsp_bridge.cpp' 39 | ] 40 | binary.compiler.defines += ['_ALLOW_KEYWORD_MACROS'] 41 | 42 | if cxx.target.arch == 'x86': 43 | binary.sources += ['sourcehook/sourcehook_hookmangen_x86.cpp'] 44 | elif binary.compiler.target.arch == 'x86_64' and binary.compiler.target.platform != 'linux': 45 | binary.sources += ['sourcehook/sourcehook_hookmangen_x86_64.cpp'] 46 | nodes = builder.Add(binary) 47 | MMS.binaries += [nodes] 48 | -------------------------------------------------------------------------------- /core/gamedll_bridge.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * vim: set ts=4 sw=4 tw=99 noet : 3 | * ====================================================== 4 | * Metamod:Source 5 | * Copyright (C) 2004-2009 AlliedModders LLC and authors. 6 | * All rights reserved. 7 | * ====================================================== 8 | * 9 | * This software is provided 'as-is', without any express or implied warranty. 10 | * In no event will the authors be held liable for any damages arising from 11 | * the use of this software. 12 | * 13 | * Permission is granted to anyone to use this software for any purpose, 14 | * including commercial applications, and to alter it and redistribute it 15 | * freely, subject to the following restrictions: 16 | * 17 | * 1. The origin of this software must not be misrepresented; you must not 18 | * claim that you wrote the original software. If you use this software in a 19 | * product, an acknowledgment in the product documentation would be 20 | * appreciated but is not required. 21 | * 2. Altered source versions must be plainly marked as such, and must not be 22 | * misrepresented as being the original software. 23 | * 3. This notice may not be removed or altered from any source distribution. 24 | */ 25 | 26 | #include 27 | 28 | #include "metamod.h" 29 | #include "metamod_plugins.h" 30 | #include "metamod_util.h" 31 | #include "loader_bridge.h" 32 | #include "provider/provider_base.h" 33 | 34 | using namespace SourceMM; 35 | 36 | class GameDllBridge : public IGameDllBridge 37 | { 38 | public: 39 | virtual bool DLLInit_Pre(const gamedll_bridge_info *info, char *buffer, size_t maxlength) 40 | { 41 | server = (IServerGameDLL *) info->isgd; 42 | g_Metamod.SetGameDLLInfo((CreateInterfaceFn)info->gsFactory, 43 | info->dllInterfaceName, 44 | info->dllVersion, 45 | true); 46 | g_Metamod.SetVSPListener(info->vsp_listener_path); 47 | mm_InitializeGlobals((CreateInterfaceFn) info->engineFactory, 48 | (CreateInterfaceFn) info->physicsFactory, 49 | (CreateInterfaceFn) info->fsFactory, 50 | (CGlobalVars*) info->pGlobals); 51 | 52 | if (!mm_DetectGameInformation()) 53 | { 54 | UTIL_Format(buffer, maxlength, "Metamod:Source failed to detect game paths; cannot load."); 55 | return false; 56 | } 57 | 58 | mm_InitializeForLoad(); 59 | mm_StartupMetamod(false); 60 | 61 | return true; 62 | } 63 | virtual void DLLInit_Post(int *isgdUnload) 64 | { 65 | SourceHook::MemFuncInfo mfi; 66 | 67 | mfi.isVirtual = false; 68 | #ifdef META_IS_SOURCE2 69 | SourceHook::GetFuncInfo(&ISource2ServerConfig::Disconnect, mfi); 70 | #else 71 | SourceHook::GetFuncInfo(&IServerGameDLL::DLLShutdown, mfi); 72 | #endif 73 | assert(mfi.isVirtual); 74 | assert(mfi.vtbloffs == 0); 75 | assert(mfi.thisptroffs == 0); 76 | *isgdUnload = mfi.vtblindex; 77 | 78 | g_PluginMngr.SetAllLoaded(); 79 | } 80 | virtual void *QueryInterface(const char *iface, int *ret) 81 | { 82 | return g_Metamod.GetServerFactory(true)(iface, ret); 83 | } 84 | virtual void Unload() 85 | { 86 | mm_UnloadMetamod(); 87 | } 88 | }; 89 | 90 | GameDllBridge mm16_gamedll_bridge; 91 | 92 | SMM_API IGameDllBridge * 93 | GetGameDllBridge() 94 | { 95 | return &mm16_gamedll_bridge; 96 | } 97 | 98 | -------------------------------------------------------------------------------- /core/metamod_console.h: -------------------------------------------------------------------------------- 1 | /** 2 | * vim: set ts=4 : 3 | * ====================================================== 4 | * Metamod:Source 5 | * Copyright (C) 2004-2008 AlliedModders LLC and authors. 6 | * All rights reserved. 7 | * ====================================================== 8 | * 9 | * This software is provided 'as-is', without any express or implied warranty. 10 | * In no event will the authors be held liable for any damages arising from 11 | * the use of this software. 12 | * 13 | * Permission is granted to anyone to use this software for any purpose, 14 | * including commercial applications, and to alter it and redistribute it 15 | * freely, subject to the following restrictions: 16 | * 17 | * 1. The origin of this software must not be misrepresented; you must not 18 | * claim that you wrote the original software. If you use this software in a 19 | * product, an acknowledgment in the product documentation would be 20 | * appreciated but is not required. 21 | * 2. Altered source versions must be plainly marked as such, and must not be 22 | * misrepresented as being the original software. 23 | * 3. This notice may not be removed or altered from any source distribution. 24 | * 25 | * Version: $Id$ 26 | */ 27 | 28 | #ifndef _INCLUDE_CONCOMMANDS_H 29 | #define _INCLUDE_CONCOMMANDS_H 30 | 31 | #include "metamod_provider.h" 32 | 33 | bool Command_Meta(IMetamodSourceCommandInfo *info); 34 | bool Command_ClientMeta(MMSPlayer_t client, IMetamodSourceCommandInfo *info); 35 | 36 | #endif //_INCLUDE_CONCOMMANDS_H 37 | -------------------------------------------------------------------------------- /core/metamod_convar.h: -------------------------------------------------------------------------------- 1 | /** 2 | * vim: set ts=4 : 3 | * ====================================================== 4 | * Metamod:Source 5 | * Copyright (C) 2004-2025 AlliedModders LLC and authors. 6 | * All rights reserved. 7 | * ====================================================== 8 | * 9 | * This software is provided 'as-is', without any express or implied warranty. 10 | * In no event will the authors be held liable for any damages arising from 11 | * the use of this software. 12 | * 13 | * Permission is granted to anyone to use this software for any purpose, 14 | * including commercial applications, and to alter it and redistribute it 15 | * freely, subject to the following restrictions: 16 | * 17 | * 1. The origin of this software must not be misrepresented; you must not 18 | * claim that you wrote the original software. If you use this software in a 19 | * product, an acknowledgment in the product documentation would be 20 | * appreciated but is not required. 21 | * 2. Altered source versions must be plainly marked as such, and must not be 22 | * misrepresented as being the original software. 23 | * 3. This notice may not be removed or altered from any source distribution. 24 | * 25 | * Version: $Id$ 26 | */ 27 | 28 | #pragma once 29 | 30 | #ifndef META_IS_SOURCE2 31 | #define protected public 32 | #define private public 33 | #endif 34 | 35 | #include "convar.h" 36 | 37 | #ifndef META_IS_SOURCE2 38 | #undef protected 39 | #undef private 40 | #endif 41 | -------------------------------------------------------------------------------- /core/metamod_oslink.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * vim: set ts=4 : 3 | * ====================================================== 4 | * Metamod:Source 5 | * Copyright (C) 2004-2008 AlliedModders LLC and authors. 6 | * All rights reserved. 7 | * ====================================================== 8 | * 9 | * This software is provided 'as-is', without any express or implied warranty. 10 | * In no event will the authors be held liable for any damages arising from 11 | * the use of this software. 12 | * 13 | * Permission is granted to anyone to use this software for any purpose, 14 | * including commercial applications, and to alter it and redistribute it 15 | * freely, subject to the following restrictions: 16 | * 17 | * 1. The origin of this software must not be misrepresented; you must not 18 | * claim that you wrote the original software. If you use this software in a 19 | * product, an acknowledgment in the product documentation would be 20 | * appreciated but is not required. 21 | * 2. Altered source versions must be plainly marked as such, and must not be 22 | * misrepresented as being the original software. 23 | * 3. This notice may not be removed or altered from any source distribution. 24 | * 25 | * Version: $Id$ 26 | */ 27 | 28 | #include 29 | #include 30 | #if defined __linux__ || defined __APPLE__ 31 | #include 32 | #endif 33 | 34 | #include "metamod_oslink.h" 35 | 36 | #if defined __WIN32__ || defined _WIN32 || defined WIN32 37 | const char *dlerror() 38 | { 39 | static char buf[1024]; 40 | DWORD num; 41 | 42 | num = GetLastError(); 43 | 44 | if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 45 | NULL, 46 | num, 47 | MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 48 | buf, 49 | sizeof(buf), 50 | NULL) 51 | == 0) 52 | { 53 | _snprintf(buf, sizeof(buf), "unknown error %x", num); 54 | } 55 | 56 | return buf; 57 | } 58 | #endif 59 | 60 | #if defined __linux_ || defined __APPLE___ 61 | int GetLastError() 62 | { 63 | return errno; 64 | } 65 | 66 | extern "C" void __cxa_guard_acquire(void) 67 | { 68 | } 69 | 70 | extern "C" void __cxa_guard_release(void) 71 | { 72 | } 73 | #endif 74 | 75 | bool GetFileOfAddress(void *pAddr, char *buffer, size_t maxlength) 76 | { 77 | #if defined WIN32 || defined _WIN32 78 | MEMORY_BASIC_INFORMATION mem; 79 | if (!VirtualQuery(pAddr, &mem, sizeof(mem))) 80 | return false; 81 | if (mem.AllocationBase == NULL) 82 | return false; 83 | HMODULE dll = (HMODULE)mem.AllocationBase; 84 | GetModuleFileName(dll, (LPTSTR)buffer, static_cast(maxlength)); 85 | #elif defined __linux__ || defined __APPLE__ 86 | Dl_info info; 87 | if (!dladdr(pAddr, &info)) 88 | return false; 89 | if (!info.dli_fbase || !info.dli_fname) 90 | return false; 91 | const char *dllpath = info.dli_fname; 92 | snprintf(buffer, maxlength, "%s", dllpath); 93 | #endif 94 | return true; 95 | } 96 | 97 | #if defined __GNUC__ && defined(NO_MALLOC_OVERRIDE) 98 | void * operator new(size_t size) { 99 | return malloc(size); 100 | } 101 | 102 | void * operator new[](size_t size) { 103 | return malloc(size); 104 | } 105 | 106 | void operator delete(void * ptr) { 107 | free(ptr); 108 | } 109 | 110 | void operator delete[](void * ptr) { 111 | free(ptr); 112 | } 113 | #endif 114 | 115 | -------------------------------------------------------------------------------- /core/metamod_oslink.h: -------------------------------------------------------------------------------- 1 | /** 2 | * vim: set ts=4 sw=4 tw=99 noet : 3 | * ====================================================== 4 | * Metamod:Source 5 | * Copyright (C) 2004-2009 AlliedModders LLC and authors. 6 | * All rights reserved. 7 | * ====================================================== 8 | * 9 | * This software is provided 'as-is', without any express or implied warranty. 10 | * In no event will the authors be held liable for any damages arising from 11 | * the use of this software. 12 | * 13 | * Permission is granted to anyone to use this software for any purpose, 14 | * including commercial applications, and to alter it and redistribute it 15 | * freely, subject to the following restrictions: 16 | * 17 | * 1. The origin of this software must not be misrepresented; you must not 18 | * claim that you wrote the original software. If you use this software in a 19 | * product, an acknowledgment in the product documentation would be 20 | * appreciated but is not required. 21 | * 2. Altered source versions must be plainly marked as such, and must not be 22 | * misrepresented as being the original software. 23 | * 3. This notice may not be removed or altered from any source distribution. 24 | */ 25 | 26 | #ifndef _INCLUDE_OSLINK_H 27 | #define _INCLUDE_OSLINK_H 28 | 29 | /** 30 | * @brief Defines OS-independent information 31 | * @file oslink.h 32 | */ 33 | 34 | #if defined __WIN32__ || defined _WIN32 || defined WIN32 35 | #define WIN32_LEAN_AND_MEAN 36 | #define OS_WIN32 37 | #if !defined _MSC_VER || _MSC_VER < 1400 38 | #define mkdir(a) _mkdir(a) 39 | #endif 40 | #include 41 | #include 42 | #include 43 | #define dlmount(x) LoadLibrary(x) 44 | #define dlsym(x, s) GetProcAddress(x, s) 45 | #define dlclose(x) FreeLibrary(x) 46 | const char* dlerror(); 47 | #define abspath(x, s) _fullpath(x, s, sizeof(x)) 48 | #define PATH_SEP_STR "\\" 49 | #define PATH_SEP_CHAR '\\' 50 | #define ALT_SEP_CHAR '/' 51 | #define PATH_SIZE MAX_PATH 52 | #define strcasecmp stricmp 53 | inline bool _IsPathSepChar(char c) { return (c == '/' || c == '\\'); } 54 | #elif defined __linux__ || defined __APPLE__ 55 | #if defined __linux__ 56 | #define OS_LINUX 57 | #elif defined __APPLE__ 58 | #define OS_DARWIN 59 | #include 60 | #endif 61 | #include 62 | #include 63 | #include 64 | #include 65 | typedef void* HINSTANCE; 66 | #ifdef META_IS_SOURCE2 67 | #define dlmount(x) dlopen(x,RTLD_NOW | RTLD_DEEPBIND) 68 | #else 69 | #define dlmount(x) dlopen(x,RTLD_NOW) 70 | #endif 71 | #define abspath(x, s) realpath(s, x) 72 | #define PATH_SEP_STR "/" 73 | #define PATH_SEP_CHAR '/' 74 | #define ALT_SEP_CHAR '\\' 75 | #define PATH_SIZE PATH_MAX 76 | #ifndef stricmp 77 | #define stricmp strcasecmp 78 | #endif 79 | #ifndef strnicmp 80 | #define strnicmp strncasecmp 81 | #endif 82 | inline bool _IsPathSepChar(char c) { return (c == '/'); } 83 | #endif 84 | 85 | #if defined __linux__ || defined __APPLE__ 86 | #include 87 | int GetLastError(); 88 | #endif 89 | 90 | bool GetFileOfAddress(void *pAddr, char *buffer, size_t maxlength); 91 | 92 | #if defined __WIN32__ || defined _WIN32 || defined WIN32 93 | #define SMM_API extern "C" __declspec(dllexport) 94 | #elif defined __GNUC__ 95 | #define SMM_API extern "C" __attribute__ ((visibility("default"))) 96 | #endif 97 | 98 | #if defined __WIN32__ || defined _WIN32 || defined WIN32 99 | typedef __int64 int64_t; 100 | typedef unsigned __int64 uint64_t; 101 | typedef __int32 int32_t; 102 | typedef unsigned __int32 uint32_t; 103 | #elif defined __GNUC__ 104 | #include 105 | #endif 106 | 107 | #if !defined __linux__ && !defined __APPLE__ 108 | #define snprintf _snprintf 109 | #if defined _MSC_VER && _MSC_VER < 1500 110 | #define vsnprintf _vsnprintf 111 | #endif 112 | #endif 113 | 114 | #endif //_INCLUDE_OSLINK_H 115 | -------------------------------------------------------------------------------- /core/metamod_util.h: -------------------------------------------------------------------------------- 1 | /** 2 | * vim: set ts=4 : 3 | * ====================================================== 4 | * Metamod:Source 5 | * Copyright (C) 2004-2008 AlliedModders LLC and authors. 6 | * All rights reserved. 7 | * ====================================================== 8 | * 9 | * This software is provided 'as-is', without any express or implied warranty. 10 | * In no event will the authors be held liable for any damages arising from 11 | * the use of this software. 12 | * 13 | * Permission is granted to anyone to use this software for any purpose, 14 | * including commercial applications, and to alter it and redistribute it 15 | * freely, subject to the following restrictions: 16 | * 17 | * 1. The origin of this software must not be misrepresented; you must not 18 | * claim that you wrote the original software. If you use this software in a 19 | * product, an acknowledgment in the product documentation would be 20 | * appreciated but is not required. 21 | * 2. Altered source versions must be plainly marked as such, and must not be 22 | * misrepresented as being the original software. 23 | * 3. This notice may not be removed or altered from any source distribution. 24 | * 25 | * Version: $Id$ 26 | */ 27 | 28 | #ifndef _INCLUDE_UTIL_H 29 | #define _INCLUDE_UTIL_H 30 | 31 | #include 32 | #include 33 | 34 | #if defined(WIN32) || defined(_WIN32) 35 | #define BINARY_EXT ".dll" 36 | #elif defined(__linux__) 37 | #define BINARY_EXT ".so" 38 | #elif defined(__APPLE__) 39 | #define BINARY_EXT ".dylib" 40 | #endif 41 | 42 | /** 43 | * @brief Utility functions 44 | * @file util.h 45 | */ 46 | 47 | /** 48 | * @brief Returns true is string is not blank, false otherwise. 49 | */ 50 | #define IS_STR_FILLED(var) (var != NULL && var[0] != '\0') 51 | 52 | /** 53 | * @brief Returns a pointer to the extension in a file name. 54 | */ 55 | const char *UTIL_GetExtension(const char *file); 56 | 57 | /** 58 | * @brief Removes whitespace characters from left side of string. 59 | */ 60 | void UTIL_TrimLeft(char *buffer); 61 | 62 | /** 63 | * @brief Removes whitespace characters from right side of string. 64 | */ 65 | void UTIL_TrimRight(char *buffer); 66 | 67 | /** 68 | * @brief Compares two file paths. 69 | */ 70 | bool UTIL_PathCmp(const char *path1, const char *path2); 71 | 72 | /** 73 | * @brief Same as snprintf except that it ensures the string buffer is null terminated. 74 | */ 75 | size_t UTIL_Format(char *buffer, size_t maxlength, const char *fmt, ...); 76 | 77 | /** 78 | * @brief Same as vsnprintf except that it ensures the string buffer is null terminated. 79 | */ 80 | size_t UTIL_FormatArgs(char *buffer, size_t maxlength, const char *fmt, va_list params); 81 | 82 | /** 83 | * @brief Forms a relative path given two absolute paths. 84 | * 85 | * @param buffer Buffer to store relative path in. 86 | * @param maxlength Maximum length of the output buffer. 87 | * @param relTo Destination folder to use as a working directory. 88 | * Final folder name should not be pathchar-terminated. 89 | * @param relFrom Source file or folder to use as a target. 90 | * @return True on success, false on failure. 91 | */ 92 | bool UTIL_Relatize(char buffer[], size_t maxlength, const char *relTo, const char *relFrom); 93 | 94 | // The previous version of Relatize is broken. Do not use it. We include it for 95 | // backwards compatibility in old engines only, in case there are weird path 96 | // scenarios going on. 97 | bool UTIL_Relatize2(char buffer[], size_t maxlength, const char *relTo, const char *relFrom); 98 | 99 | /** 100 | * @brief Compares memory address against a signature. 101 | * 102 | * @param addr Memory address to check. 103 | * @param sig Signature used to check against memory address. Accept 0x2A as wildcard. 104 | * @param len Length of signature. 105 | * @return True if signature was verified, false otherwise. 106 | */ 107 | bool UTIL_VerifySignature(const void *addr, const char *sig, size_t len); 108 | 109 | #endif //_INCLUDE_UTIL_H 110 | 111 | -------------------------------------------------------------------------------- /core/provider/provider_base.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * vim: set ts=4 sw=4 tw=99 noet : 3 | * ====================================================== 4 | * Metamod:Source 5 | * Copyright (C) 2004-2023 AlliedModders LLC and authors. 6 | * All rights reserved. 7 | * ====================================================== 8 | * 9 | * This software is provided 'as-is', without any express or implied warranty. 10 | * In no event will the authors be held liable for any damages arising from 11 | * the use of this software. 12 | * 13 | * Permission is granted to anyone to use this software for any purpose, 14 | * including commercial applications, and to alter it and redistribute it 15 | * freely, subject to the following restrictions: 16 | * 17 | * 1. The origin of this software must not be misrepresented; you must not 18 | * claim that you wrote the original software. If you use this software in a 19 | * product, an acknowledgment in the product documentation would be 20 | * appreciated but is not required. 21 | * 2. Altered source versions must be plainly marked as such, and must not be 22 | * misrepresented as being the original software. 23 | * 3. This notice may not be removed or altered from any source distribution. 24 | */ 25 | 26 | #include 27 | #include 28 | 29 | #include "../metamod_oslink.h" 30 | #include "../metamod_util.h" 31 | #include "sourcehook.h" 32 | #include "eiface.h" 33 | #include "tier0/icommandline.h" 34 | #include "provider_base.h" 35 | #include "metamod_console.h" 36 | #include "filesystem.h" 37 | #include "metamod.h" 38 | #include "tier1/KeyValues.h" 39 | 40 | 41 | /* Imports */ 42 | #if SOURCE_ENGINE < SE_ORANGEBOX 43 | #undef CommandLine 44 | DLL_IMPORT ICommandLine *CommandLine(); 45 | #endif 46 | 47 | void _ServerCommand(); 48 | /* Variables */ 49 | static List conbases_unreg; 50 | 51 | ICvar *icvar = NULL; 52 | IServerGameDLL *server = NULL; 53 | IVEngineServer *engine = NULL; 54 | IServerGameClients *gameclients = NULL; 55 | CGlobalVars *gpGlobals = NULL; 56 | 57 | 58 | bool BaseProvider::IsSourceEngineBuildCompatible(int build) 59 | { 60 | return (build == SOURCE_ENGINE_ORIGINAL 61 | || build == SOURCE_ENGINE_EPISODEONE); 62 | } 63 | 64 | int BaseProvider::TryServerGameDLL(const char *iface) 65 | { 66 | if (strncmp(iface, "ServerGameDLL", 13) != 0) 67 | { 68 | return 0; 69 | } 70 | 71 | return atoi(&iface[13]); 72 | } 73 | 74 | bool BaseProvider::LogMessage(const char *buffer) 75 | { 76 | if (!engine) 77 | { 78 | return false; 79 | } 80 | 81 | engine->LogPrint(buffer); 82 | 83 | return true; 84 | } 85 | 86 | void BaseProvider::DisplayError(const char *fmt, ...) 87 | { 88 | va_list ap; 89 | char buffer[2048]; 90 | 91 | va_start(ap, fmt); 92 | UTIL_FormatArgs(buffer, sizeof(buffer), fmt, ap); 93 | va_end(ap); 94 | 95 | Error("%s", buffer); 96 | } 97 | 98 | void BaseProvider::DisplayWarning(const char *fmt, ...) 99 | { 100 | va_list ap; 101 | char buffer[2048]; 102 | 103 | va_start(ap, fmt); 104 | UTIL_FormatArgs(buffer, sizeof(buffer), fmt, ap); 105 | va_end(ap); 106 | 107 | Warning("%s", buffer); 108 | } 109 | 110 | void BaseProvider::DisplayDevMsg(const char* fmt, ...) 111 | { 112 | va_list ap; 113 | char buffer[2048]; 114 | 115 | va_start(ap, fmt); 116 | UTIL_FormatArgs(buffer, sizeof(buffer), fmt, ap); 117 | va_end(ap); 118 | 119 | DevMsg("%s", buffer); 120 | } 121 | -------------------------------------------------------------------------------- /core/sourcehook/generate/generate: -------------------------------------------------------------------------------- 1 | #/bin/sh 2 | 3 | cd shworker 4 | make 5 | cd .. 6 | 7 | shworker/bin/shworker.bin iter sourcehook.hxx sourcehook.h $1 8 | 9 | cp *.h .. 10 | -------------------------------------------------------------------------------- /core/sourcehook/generate/generate.bat: -------------------------------------------------------------------------------- 1 | :: Generates everything 2 | :: Usage: 3 | :: generate.bat 4 | 5 | 6 | shworker iter sourcehook.hxx sourcehook.h %1 7 | 8 | copy *.h .. 9 | -------------------------------------------------------------------------------- /core/sourcehook/generate/shworker.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alliedmodders/metamod-source/5d2bb7e206232879729a0b53aa6f289077977f3c/core/sourcehook/generate/shworker.bin -------------------------------------------------------------------------------- /core/sourcehook/generate/shworker.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alliedmodders/metamod-source/5d2bb7e206232879729a0b53aa6f289077977f3c/core/sourcehook/generate/shworker.exe -------------------------------------------------------------------------------- /core/sourcehook/generate/shworker/Makefile: -------------------------------------------------------------------------------- 1 | CPP = clang 2 | 3 | default: shworker 4 | 5 | bin: 6 | mkdir bin 7 | 8 | fd_hopter.o: fd_hopter.cpp bin 9 | $(CPP) -fPIC -O2 -o bin/$@ -c $< 10 | 11 | main.o: shworker.cpp bin 12 | $(CPP) -fPIC -O2 -o bin/$@ -c $< 13 | 14 | shworker: fd_hopter.o main.o bin 15 | $(CPP) -ldl -lstdc++ bin/fd_hopter.o bin/main.o -o bin/shworker.bin 16 | -------------------------------------------------------------------------------- /core/sourcehook/generate/shworker/msvc7/shworker.vcproj: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 11 | 12 | 13 | 19 | 30 | 32 | 40 | 42 | 44 | 46 | 48 | 50 | 52 | 54 | 56 | 58 | 60 | 61 | 67 | 80 | 82 | 91 | 93 | 95 | 97 | 99 | 101 | 103 | 105 | 107 | 109 | 111 | 112 | 113 | 114 | 115 | 116 | 119 | 121 | 122 | 124 | 125 | 126 | 129 | 130 | 133 | 134 | 135 | 136 | 137 | 138 | -------------------------------------------------------------------------------- /core/sourcehook/generate/shworker/msvc9/shworker.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 10.00 3 | # Visual Studio 2008 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shworker", "shworker.vcproj", "{7CD76E64-A9DF-47DB-8A68-36297C67E557}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Win32 = Debug|Win32 9 | Release|Win32 = Release|Win32 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {7CD76E64-A9DF-47DB-8A68-36297C67E557}.Debug|Win32.ActiveCfg = Debug|Win32 13 | {7CD76E64-A9DF-47DB-8A68-36297C67E557}.Debug|Win32.Build.0 = Debug|Win32 14 | {7CD76E64-A9DF-47DB-8A68-36297C67E557}.Release|Win32.ActiveCfg = Release|Win32 15 | {7CD76E64-A9DF-47DB-8A68-36297C67E557}.Release|Win32.Build.0 = Release|Win32 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /core/sourcehook/sh_asm.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "sh_pagealloc.h" 5 | 6 | namespace SourceHook 7 | { 8 | namespace Asm 9 | { 10 | class GenBuffer 11 | { 12 | static CPageAlloc ms_Allocator; 13 | 14 | unsigned char *m_pData; 15 | std::uint32_t m_Size; 16 | std::uint32_t m_AllocatedSize; 17 | 18 | public: 19 | GenBuffer() : m_pData(NULL), m_Size(0), m_AllocatedSize(0) 20 | { 21 | } 22 | ~GenBuffer() 23 | { 24 | clear(); 25 | } 26 | std::uint32_t GetSize() 27 | { 28 | return m_Size; 29 | } 30 | unsigned char *GetData() 31 | { 32 | return m_pData; 33 | } 34 | 35 | template void push(PT what) 36 | { 37 | push((const unsigned char *)&what, sizeof(PT)); 38 | } 39 | 40 | void push(const unsigned char *data, std::uint32_t size) 41 | { 42 | std::uint32_t newSize = m_Size + size; 43 | if (newSize > m_AllocatedSize) 44 | { 45 | m_AllocatedSize = newSize > m_AllocatedSize*2 ? newSize : m_AllocatedSize*2; 46 | if (m_AllocatedSize < 64) 47 | m_AllocatedSize = 64; 48 | 49 | unsigned char *newBuf; 50 | newBuf = reinterpret_cast(ms_Allocator.Alloc(m_AllocatedSize)); 51 | ms_Allocator.SetRW(newBuf); 52 | if (!newBuf) 53 | { 54 | SH_ASSERT(0, ("bad_alloc: couldn't allocate 0x%08X bytes of memory\n", m_AllocatedSize)); 55 | return; 56 | } 57 | memset((void*)newBuf, 0xCC, m_AllocatedSize); // :TODO: remove this ! 58 | memcpy((void*)newBuf, (const void*)m_pData, m_Size); 59 | if (m_pData) 60 | { 61 | ms_Allocator.SetRE(reinterpret_cast(m_pData)); 62 | ms_Allocator.SetRW(newBuf); 63 | ms_Allocator.Free(reinterpret_cast(m_pData)); 64 | } 65 | m_pData = newBuf; 66 | } 67 | memcpy((void*)(m_pData + m_Size), (const void*)data, size); 68 | m_Size = newSize; 69 | } 70 | 71 | template void rewrite(std::uint32_t offset, PT what) 72 | { 73 | rewrite(offset, (const unsigned char *)&what, sizeof(PT)); 74 | } 75 | 76 | void rewrite(std::uint32_t offset, const unsigned char *data, std::uint32_t size) 77 | { 78 | SH_ASSERT(offset + size <= m_AllocatedSize, ("rewrite too far")); 79 | 80 | memcpy((void*)(m_pData + offset), (const void*)data, size); 81 | } 82 | 83 | void clear() 84 | { 85 | if (m_pData) 86 | ms_Allocator.Free(reinterpret_cast(m_pData)); 87 | m_pData = NULL; 88 | m_Size = 0; 89 | m_AllocatedSize = 0; 90 | } 91 | 92 | void SetRE() 93 | { 94 | ms_Allocator.SetRE(reinterpret_cast(m_pData)); 95 | } 96 | 97 | operator void *() 98 | { 99 | return reinterpret_cast(GetData()); 100 | } 101 | 102 | void write_ubyte(std::uint8_t x) { push(x); } 103 | void write_byte(std::int8_t x) { push(x); } 104 | 105 | void write_ushort(unsigned short x) { push(x); } 106 | void write_short(signed short x) { push(x); } 107 | 108 | void write_uint32(std::uint32_t x) { push(x); } 109 | void write_int32(std::int32_t x) { push(x); } 110 | 111 | void write_uint64(std::uint64_t x) { push(x); } 112 | void write_int64(std::int64_t x) { push(x); } 113 | 114 | std::uint32_t get_outputpos() 115 | { 116 | return m_Size; 117 | } 118 | 119 | void start_count(std::uint32_t &offs) 120 | { 121 | offs = get_outputpos(); 122 | } 123 | void end_count(std::uint32_t &offs) 124 | { 125 | offs = get_outputpos() - offs; 126 | } 127 | }; 128 | } 129 | } -------------------------------------------------------------------------------- /core/sourcehook/sh_pagealloc.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alliedmodders/metamod-source/5d2bb7e206232879729a0b53aa6f289077977f3c/core/sourcehook/sh_pagealloc.h -------------------------------------------------------------------------------- /core/sourcehook/sourcehook_hookmangen.cpp: -------------------------------------------------------------------------------- 1 | /* ======== SourceHook ======== 2 | * Copyright (C) 2004-2010 Metamod:Source Development Team 3 | * No warranties of any kind 4 | * 5 | * License: zlib/libpng 6 | * 7 | * Author(s): Pavol "PM OnoTo" Marko 8 | * Contributor(s): Borja "faluco" Ferav (many thanks for assitance!) 9 | * David "BAILOPAN" Anderson 10 | * ============================ 11 | */ 12 | 13 | // recommended literature: 14 | // http://www.cs.umbc.edu/~chang/cs313.s02/stack.shtml 15 | // http://www.angelcode.com/dev/callconv/callconv.html 16 | // http://www.arl.wustl.edu/~lockwood/class/cs306/books/artofasm/Chapter_6/CH06-1.html 17 | 18 | #include 19 | #include // we might need the address of vsnprintf 20 | 21 | #include "sourcehook_impl.h" 22 | #include "sourcehook_hookmangen.h" 23 | #if defined( PLATFORM_64BITS ) && !defined( _LINUX ) 24 | #include "sourcehook_hookmangen_x86_64.h" 25 | typedef SourceHook::Impl::x64GenContext SHGenContext; 26 | #else 27 | #include "sourcehook_hookmangen_x86.h" 28 | typedef SourceHook::Impl::GenContext SHGenContext; 29 | #endif 30 | #include "sh_memory.h" 31 | 32 | #if SH_COMP == SH_COMP_MSVC 33 | # define GCC_ONLY(x) 34 | # define MSVC_ONLY(x) x 35 | #elif SH_COMP == SH_COMP_GCC 36 | # define GCC_ONLY(x) x 37 | # define MSVC_ONLY(x) 38 | #endif 39 | 40 | // :TODO: test BIG vtable indices 41 | 42 | namespace SourceHook 43 | { 44 | CPageAlloc Asm::GenBuffer::ms_Allocator(16); 45 | 46 | namespace Impl 47 | { 48 | // *********************************** class GenContextContainer 49 | CHookManagerAutoGen::CHookManagerAutoGen(ISourceHook *pSHPtr) : m_pSHPtr(pSHPtr) { } 50 | 51 | CHookManagerAutoGen::~CHookManagerAutoGen() { } 52 | 53 | int CHookManagerAutoGen::GetIfaceVersion() 54 | { 55 | return SH_HOOKMANAUTOGEN_IFACE_VERSION; 56 | } 57 | 58 | int CHookManagerAutoGen::GetImplVersion() 59 | { 60 | return SH_HOOKMANAUTOGEN_IMPL_VERSION; 61 | } 62 | 63 | HookManagerPubFunc CHookManagerAutoGen::MakeHookMan(const ProtoInfo *proto, int vtbl_offs, int vtbl_idx) 64 | { 65 | #if defined( PLATFORM_64BITS ) && defined( _LINUX ) 66 | return nullptr; 67 | #else 68 | CProto mproto(proto); 69 | for (auto iter = m_Contexts.begin(); iter != m_Contexts.end(); ++iter) 70 | { 71 | if (iter->m_GenContext->Equal(mproto, vtbl_offs, vtbl_idx)) 72 | { 73 | iter->m_RefCnt++; 74 | return iter->m_GenContext->GetPubFunc(); 75 | } 76 | } 77 | 78 | // Not found yet -> new one 79 | StoredContext sctx; 80 | sctx.m_RefCnt = 1; 81 | sctx.m_GenContext = std::make_unique(proto, vtbl_offs, vtbl_idx, m_pSHPtr); 82 | 83 | auto pubFunc = sctx.m_GenContext->GetPubFunc(); 84 | if (pubFunc != nullptr) 85 | { 86 | m_Contexts.emplace_back(std::move(sctx)); 87 | } 88 | return pubFunc; 89 | #endif 90 | } 91 | 92 | void CHookManagerAutoGen::ReleaseHookMan(HookManagerPubFunc pubFunc) 93 | { 94 | for (auto iter = m_Contexts.begin(); iter != m_Contexts.end(); ++iter) 95 | { 96 | if (iter->m_GenContext->Equal(pubFunc)) 97 | { 98 | iter->m_RefCnt--; 99 | if (iter->m_RefCnt == 0) 100 | { 101 | iter = m_Contexts.erase(iter); 102 | } 103 | break; 104 | } 105 | } 106 | } 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /core/sourcehook/sourcehook_hookmangen.h: -------------------------------------------------------------------------------- 1 | /* ======== SourceHook ======== 2 | * Copyright (C) 2004-2010 Metamod:Source Development Team 3 | * No warranties of any kind 4 | * 5 | * License: zlib/libpng 6 | * 7 | * Author(s): Pavol "PM OnoTo" Marko 8 | * ============================ 9 | */ 10 | 11 | #ifndef __SOURCEHOOK_HOOKMANGEN_H__ 12 | #define __SOURCEHOOK_HOOKMANGEN_H__ 13 | 14 | #include 15 | #include 16 | 17 | #include "sourcehook_impl_cproto.h" 18 | #include "sh_pagealloc.h" 19 | #include "sh_asm.h" 20 | 21 | namespace SourceHook 22 | { 23 | namespace Impl 24 | { 25 | 26 | // Code gen stuff 27 | #if SH_COMP == SH_COMP_GCC 28 | #include 29 | typedef int8_t jit_int8_t; 30 | typedef uint8_t jit_uint8_t; 31 | typedef int32_t jit_int32_t; 32 | typedef uint32_t jit_uint32_t; 33 | typedef int64_t jit_int64_t; 34 | typedef uint64_t jit_uint64_t; 35 | #elif SH_COMP == SH_COMP_MSVC 36 | typedef __int8 jit_int8_t; 37 | typedef unsigned __int8 jit_uint8_t; 38 | typedef __int32 jit_int32_t; 39 | typedef unsigned __int32 jit_uint32_t; 40 | typedef __int64 jit_int64_t; 41 | typedef unsigned __int64 jit_uint64_t; 42 | #endif 43 | typedef unsigned int jitoffs_t; 44 | typedef signed int jitrel_t; 45 | 46 | class IGenContext 47 | { 48 | public: 49 | virtual ~IGenContext() {}; 50 | 51 | virtual bool Equal(const CProto& proto, int vtbl_offs, int vtbl_idx) = 0; 52 | virtual bool Equal(HookManagerPubFunc other) = 0; 53 | 54 | virtual HookManagerPubFunc GetPubFunc() = 0; 55 | }; 56 | 57 | class CHookManagerAutoGen : public IHookManagerAutoGen 58 | { 59 | struct StoredContext 60 | { 61 | int m_RefCnt; 62 | std::unique_ptr m_GenContext; 63 | }; 64 | std::list m_Contexts; 65 | ISourceHook *m_pSHPtr; 66 | 67 | public: 68 | CHookManagerAutoGen(ISourceHook *pSHPtr); 69 | ~CHookManagerAutoGen(); 70 | 71 | int GetIfaceVersion(); 72 | int GetImplVersion(); 73 | 74 | HookManagerPubFunc MakeHookMan(const ProtoInfo *proto, int vtbl_offs, int vtbl_idx); 75 | void ReleaseHookMan(HookManagerPubFunc pubFunc); 76 | }; 77 | 78 | } 79 | } 80 | 81 | 82 | #endif 83 | -------------------------------------------------------------------------------- /core/sourcehook/sourcehook_hookmangen_x86_64.h: -------------------------------------------------------------------------------- 1 | /* ======== SourceHook ======== 2 | * vim: set ts=4 : 3 | * Copyright (C) 2024 AlliedModders LLC. All rights reserved. 4 | * No warranties of any kind 5 | * 6 | * License: zlib/libpng 7 | * 8 | * ============================ 9 | */ 10 | 11 | #ifndef __SOURCEHOOK_HOOKMANGEN_X86_64_H__ 12 | #define __SOURCEHOOK_HOOKMANGEN_X86_64_H__ 13 | 14 | #include 15 | #include 16 | 17 | #include "sh_asm_x86_64.h" 18 | 19 | namespace SourceHook 20 | { 21 | namespace Impl 22 | { 23 | class x64GenContext : public IGenContext 24 | { 25 | public: 26 | x64GenContext(); 27 | x64GenContext(const ProtoInfo *proto, int vtbl_offs, int vtbl_idx, ISourceHook *pSHPtr); 28 | virtual ~x64GenContext(); 29 | 30 | virtual bool Equal(const CProto &proto, int vtbl_offs, int vtbl_idx) override; 31 | virtual bool Equal(HookManagerPubFunc other) override; 32 | 33 | virtual HookManagerPubFunc GetPubFunc() override; 34 | HookManagerPubFunc Generate(); 35 | protected: 36 | friend void foo_test(); 37 | 38 | static const std::int32_t SIZE_PTR = sizeof(void*); 39 | 40 | std::int32_t AddVarToFrame(std::int32_t size); 41 | std::int32_t ComputeVarsSize(); 42 | std::int32_t x64GenContext::GetRealSize(const IntPassInfo& info); 43 | std::int32_t AlignSize(std::int32_t x, std::int32_t boundary); 44 | std::int32_t GetParamStackSize(const IntPassInfo &info); 45 | 46 | void Clear(); 47 | void AutoDetectRetType(); 48 | void AutoDetectParamFlags(); 49 | bool PassInfoSupported(const IntPassInfo& pi, bool is_ret); 50 | void BuildProtoInfo(); 51 | bool MemRetWithTempObj(); 52 | 53 | void* GeneratePubFunc(); 54 | void* GenerateHookFunc(); 55 | 56 | void CallSetupHookLoop(int v_orig_ret, int v_override_ret, int v_cur_res, int v_prev_res, int v_status, int v_vfnptr_origentry, int v_this, int v_pContext); 57 | void GenerateCallHooks(int v_status, int v_prev_res, int v_cur_res, int v_iter, 58 | int v_pContext, int v_plugin_ret, int v_mem_ret); 59 | void GenerateCallOrig(int v_status, int v_pContext, int v_this, int v_vfnptr_origentry, int v_orig_ret, int v_override_ret, int v_place_for_memret); 60 | void PrepareReturn(int v_status, int v_pContext, int v_retptr); 61 | void CallEndContext(int v_pContext); 62 | void DoReturn(int v_retptr, int v_memret_outaddr); 63 | 64 | std::int32_t PushParameters(int v_this, int v_ret); 65 | void SaveReturnValue(int v_mem_ret, int v_ret); 66 | 67 | HookManagerPubFunc m_GeneratedPubFunc; 68 | 69 | CProto m_OrigProto; 70 | CProto m_Proto; 71 | int m_VtblOffs; 72 | int m_VtblIdx; 73 | ISourceHook *m_SHPtr; 74 | 75 | Asm::x64JitWriter m_HookFunc; 76 | Asm::x64JitWriter m_PubFunc; 77 | 78 | ProtoInfo *m_BuiltPI; 79 | PassInfo *m_BuiltPI_Params; 80 | PassInfo::V2Info *m_BuiltPI_Params2; 81 | 82 | void **m_pHI; 83 | void **m_HookfuncVfnptr; 84 | 85 | std::int32_t m_HookFunc_FrameOffset; 86 | std::int32_t m_HookFunc_FrameVarsSize; 87 | }; 88 | } 89 | } 90 | 91 | #endif //__SOURCEHOOK_HOOKMANGEN_X86_64_H__ -------------------------------------------------------------------------------- /core/sourcehook/sourcehook_impl_chook.h: -------------------------------------------------------------------------------- 1 | /* ======== SourceHook ======== 2 | * Copyright (C) 2004-2010 Metamod:Source Development Team 3 | * No warranties of any kind 4 | * 5 | * License: zlib/libpng 6 | * 7 | * Author(s): Pavol "PM OnoTo" Marko 8 | * ============================ 9 | */ 10 | 11 | #ifndef __SOURCEHOOK_IMPL_CHOOK_H__ 12 | #define __SOURCEHOOK_IMPL_CHOOK_H__ 13 | 14 | #include "sourcehook.h" 15 | 16 | namespace SourceHook 17 | { 18 | namespace Impl 19 | { 20 | class CHook 21 | { 22 | // *** Data *** 23 | Plugin m_OwnerPlugin; 24 | int m_ThisPointerOffset; 25 | ISHDelegate *m_pHandler; 26 | int m_HookID; 27 | bool m_Paused; 28 | public: 29 | 30 | // *** Descriptor *** 31 | struct Descriptor 32 | { 33 | Plugin m_OwnerPlugin; 34 | int m_ThisPointerOffset; 35 | ISHDelegate *m_pHandler; 36 | 37 | Descriptor(Plugin ownerPlugin, int thisPtrOffset, ISHDelegate *pHandler) 38 | : m_OwnerPlugin(ownerPlugin), m_ThisPointerOffset(thisPtrOffset), 39 | m_pHandler(pHandler) 40 | { 41 | } 42 | }; 43 | 44 | // *** Interface *** 45 | inline CHook(Plugin ownerPlugin, int thisPtrOffset, ISHDelegate *pHandler, int hookid, bool paused=false); 46 | inline bool operator==(const Descriptor &other) const; 47 | inline bool operator==(int hookid) const; 48 | inline Plugin GetOwnerPlugin() const; 49 | inline int GetThisPointerOffset() const; 50 | inline ISHDelegate *GetHandler() const; 51 | inline void SetPaused(bool value); 52 | inline bool IsPaused() const; 53 | inline int GetID() const; 54 | }; 55 | 56 | // *** Implementation *** 57 | inline CHook::CHook(Plugin ownerPlugin, int thisPtrOffset, ISHDelegate *pHandler, int hookid, bool paused) 58 | : m_OwnerPlugin(ownerPlugin), m_ThisPointerOffset(thisPtrOffset), 59 | m_pHandler(pHandler), m_HookID(hookid), m_Paused(paused) 60 | { 61 | } 62 | 63 | inline bool CHook::operator==(const Descriptor &other) const 64 | { 65 | return m_OwnerPlugin == other.m_OwnerPlugin 66 | && m_ThisPointerOffset == other.m_ThisPointerOffset 67 | && m_pHandler == other.m_pHandler; 68 | } 69 | 70 | inline bool CHook::operator==(int hookid) const 71 | { 72 | return m_HookID == hookid; 73 | } 74 | 75 | inline Plugin CHook::GetOwnerPlugin() const 76 | { 77 | return m_OwnerPlugin; 78 | } 79 | 80 | inline int CHook::GetThisPointerOffset() const 81 | { 82 | return m_ThisPointerOffset; 83 | } 84 | 85 | inline ISHDelegate *CHook::GetHandler() const 86 | { 87 | return m_pHandler; 88 | } 89 | 90 | inline void CHook::SetPaused(bool value) 91 | { 92 | m_Paused = value; 93 | } 94 | 95 | inline bool CHook::IsPaused() const 96 | { 97 | return m_Paused; 98 | } 99 | 100 | inline int CHook::GetID() const 101 | { 102 | return m_HookID; 103 | } 104 | } 105 | } 106 | 107 | #endif 108 | 109 | -------------------------------------------------------------------------------- /core/sourcehook/sourcehook_impl_chookidman.cpp: -------------------------------------------------------------------------------- 1 | /* ======== SourceHook ======== 2 | * Copyright (C) 2004-2010 Metamod:Source Development Team 3 | * No warranties of any kind 4 | * 5 | * License: zlib/libpng 6 | * 7 | * Author(s): Pavol "PM OnoTo" Marko 8 | * Contributors: Scott "Damaged Soul" Ehlert 9 | * ============================ 10 | */ 11 | 12 | #include "sourcehook_impl.h" 13 | 14 | namespace SourceHook 15 | { 16 | namespace Impl 17 | { 18 | CHookIDManager::CHookIDManager() 19 | { 20 | } 21 | 22 | int CHookIDManager::New(const CProto &proto, int vtbl_offs, int vtbl_idx, void *vfnptr, 23 | void *adjustediface, Plugin plug, int thisptr_offs, ISHDelegate *handler, bool post) 24 | { 25 | Entry tmp(proto, vtbl_offs, vtbl_idx, vfnptr, adjustediface, plug, thisptr_offs, handler, post); 26 | 27 | size_t cursize = m_Entries.size(); 28 | for (size_t i = 0; i < cursize; ++i) 29 | { 30 | if (m_Entries[i].isfree) 31 | { 32 | m_Entries[i] = tmp; 33 | return static_cast(i) + 1; 34 | } 35 | } 36 | 37 | m_Entries.push_back(tmp); 38 | return static_cast(m_Entries.size()); // return size() because hookid = id+1 anyway 39 | } 40 | 41 | bool CHookIDManager::Remove(int hookid) 42 | { 43 | int realid = hookid - 1; 44 | if (realid < 0 || realid >= static_cast(m_Entries.size()) || m_Entries[realid].isfree) 45 | return false; 46 | 47 | m_Entries[realid].isfree = true; 48 | 49 | // :TODO: remove free ids from back sometimes ?? 50 | 51 | return true; 52 | } 53 | 54 | const CHookIDManager::Entry * CHookIDManager::QueryHook(int hookid) 55 | { 56 | int realid = hookid - 1; 57 | if (realid < 0 || realid >= static_cast(m_Entries.size()) || m_Entries[realid].isfree) 58 | return NULL; 59 | 60 | return &m_Entries[realid]; 61 | } 62 | 63 | void CHookIDManager::FindAllHooks(CVector &output, const CProto &proto, int vtbl_offs, 64 | int vtbl_idx, void *adjustediface, Plugin plug, int thisptr_offs, ISHDelegate *handler, bool post) 65 | { 66 | // oh my god, a lot of parameters... 67 | size_t cursize = m_Entries.size(); 68 | for (size_t i = 0; i < cursize; ++i) 69 | { 70 | if (!m_Entries[i].isfree && m_Entries[i].proto == proto && m_Entries[i].vtbl_offs == vtbl_offs && 71 | m_Entries[i].vtbl_idx == vtbl_idx && m_Entries[i].adjustediface == adjustediface && m_Entries[i].plug == plug && 72 | m_Entries[i].thisptr_offs == thisptr_offs && m_Entries[i].handler->IsEqual(handler) && m_Entries[i].post == post) 73 | { 74 | output.push_back(static_cast(i) + 1); 75 | } 76 | } 77 | } 78 | 79 | void CHookIDManager::FindAllHooks(CVector &output) 80 | { 81 | size_t cursize = m_Entries.size(); 82 | for (size_t i = 0; i < cursize; ++i) 83 | { 84 | if (!m_Entries[i].isfree) 85 | output.push_back(static_cast(i) + 1); 86 | } 87 | } 88 | 89 | void CHookIDManager::FindAllHooks(CVector &output, Plugin plug) 90 | { 91 | size_t cursize = m_Entries.size(); 92 | for (size_t i = 0; i < cursize; ++i) 93 | { 94 | if (!m_Entries[i].isfree && m_Entries[i].plug == plug) 95 | output.push_back(static_cast(i) + 1); 96 | } 97 | } 98 | 99 | 100 | void CHookIDManager::RemoveAll(void *vfnptr) 101 | { 102 | size_t cursize = m_Entries.size(); 103 | for (size_t i = 0; i < cursize; ++i) 104 | { 105 | if (!m_Entries[i].isfree && m_Entries[i].vfnptr == vfnptr) 106 | m_Entries[i].isfree = true; 107 | } 108 | } 109 | 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /core/sourcehook/sourcehook_impl_chookidman.h: -------------------------------------------------------------------------------- 1 | /* ======== SourceHook ======== 2 | * Copyright (C) 2004-2010 Metamod:Source Development Team 3 | * No warranties of any kind 4 | * 5 | * License: zlib/libpng 6 | * 7 | * Author(s): Pavol "PM OnoTo" Marko 8 | * ============================ 9 | */ 10 | 11 | #ifndef __SOURCEHOOK_IMPL_CHOOKIDMAN_H__ 12 | #define __SOURCEHOOK_IMPL_CHOOKIDMAN_H__ 13 | 14 | #include "sourcehook.h" 15 | #include "sourcehook_impl_cproto.h" 16 | #include "sh_vector.h" 17 | 18 | namespace SourceHook 19 | { 20 | namespace Impl 21 | { 22 | // Associates hook ids with info about the hooks 23 | // Also used to keep track of used hook ids 24 | class CHookIDManager 25 | { 26 | public: 27 | struct Entry 28 | { 29 | bool isfree; 30 | 31 | // hookman info 32 | CProto proto; 33 | int vtbl_offs; 34 | int vtbl_idx; 35 | 36 | // vfnptr 37 | void *vfnptr; 38 | 39 | // iface 40 | void* adjustediface; 41 | 42 | // hook 43 | Plugin plug; 44 | int thisptr_offs; 45 | ISHDelegate *handler; 46 | bool post; 47 | 48 | Entry(const CProto &pprt, int pvo, int pvi, void *pvp, void *pai, Plugin pplug, int pto, 49 | ISHDelegate *ph, bool ppost) 50 | : isfree(false), proto(pprt), vtbl_offs(pvo), vtbl_idx(pvi), vfnptr(pvp), 51 | adjustediface(pai), plug(pplug), thisptr_offs(pto), handler(ph), post(ppost) 52 | { 53 | } 54 | Entry() 55 | { 56 | } 57 | }; 58 | private: 59 | // Internally, hookid 1 is stored as m_Entries[0] 60 | 61 | CVector m_Entries; 62 | public: 63 | CHookIDManager(); 64 | int New(const CProto &proto, int vtbl_offs, int vtbl_idx, void *vfnptr, void *adjustediface, 65 | Plugin plug, int thisptr_offs, ISHDelegate *handler, bool post); 66 | bool Remove(int hookid); 67 | const Entry * QueryHook(int hookid); 68 | 69 | // Finds all hooks with the given info, and fills the hookids into output. 70 | void FindAllHooks(CVector &output, const CProto &proto, int vtbl_offs, int vtbl_idx, 71 | void *adjustediface, Plugin plug, int thisptr_offs, ISHDelegate *handler, bool post); 72 | 73 | // Removes all hooks with a specified vfnptr 74 | void RemoveAll(void *vfnptr); 75 | 76 | void FindAllHooks(CVector &output); 77 | void FindAllHooks(CVector &output, Plugin plug); 78 | }; 79 | } 80 | } 81 | 82 | #endif 83 | 84 | -------------------------------------------------------------------------------- /core/sourcehook/sourcehook_impl_chookmaninfo.cpp: -------------------------------------------------------------------------------- 1 | /* ======== SourceHook ======== 2 | * Copyright (C) 2004-2010 Metamod:Source Development Team 3 | * No warranties of any kind 4 | * 5 | * License: zlib/libpng 6 | * 7 | * Author(s): Pavol "PM OnoTo" Marko 8 | * Contributors: Scott "Damaged Soul" Ehlert 9 | * ============================ 10 | */ 11 | 12 | #include "sourcehook_impl.h" 13 | 14 | namespace SourceHook 15 | { 16 | namespace Impl 17 | { 18 | CHookManager::CHookManager(Plugin ownerPlugin, HookManagerPubFunc pubFunc) 19 | : m_OwnerPlugin(ownerPlugin), m_PubFunc(pubFunc), m_Version(-1) 20 | { 21 | // Query pubfunc 22 | // -> Should call SetInfo and set all the other variables! 23 | if (m_PubFunc(false, this) != 0) 24 | { 25 | // Error! 26 | m_Version = -1; 27 | } 28 | } 29 | 30 | void CHookManager::SetInfo(int hookman_version, int vtbloffs, int vtblidx, 31 | ProtoInfo *proto, void *hookfunc_vfnptr) 32 | { 33 | m_Version = hookman_version; 34 | m_VtblOffs = vtbloffs; 35 | m_VtblIdx = vtblidx; 36 | m_Proto = proto; 37 | m_HookfuncVfnptr = hookfunc_vfnptr; 38 | } 39 | 40 | void CHookManager::Register() 41 | { 42 | SH_DEBUG_LOG(VERBOSE, "CHookManager(%p)::SetInfo\n" 43 | "- hookman_version %d\n" 44 | "- vtbloffs %d\n" 45 | "- vtblidx %d\n" 46 | "- hookfunc_vfnptr %p\n\n", 47 | (void*)this, m_Version, m_VtblOffs, m_VtblIdx, m_HookfuncVfnptr); 48 | 49 | m_PubFunc(true, this); 50 | } 51 | 52 | void CHookManager::Unregister() 53 | { 54 | m_PubFunc(true, NULL); 55 | } 56 | 57 | void CHookManager::IncrRef(CVfnPtr *pVfnPtr) 58 | { 59 | SH_DEBUG_LOG(VERBOSE, "CHookManager(%p)::IncrRef\n", 60 | (void*)this); 61 | 62 | m_VfnPtrs.push_back(pVfnPtr); 63 | if (m_VfnPtrs.size() == 1) 64 | Register(); 65 | } 66 | 67 | void CHookManager::DecrRef(CVfnPtr *pVfnPtr) 68 | { 69 | SH_DEBUG_LOG(VERBOSE, "CHookManager(%p)::DecrRef\n", 70 | (void*)this); 71 | 72 | m_VfnPtrs.remove(pVfnPtr); 73 | if (m_VfnPtrs.empty()) 74 | Unregister(); 75 | } 76 | 77 | CHookManager *CHookManList::GetHookMan(Plugin plug, HookManagerPubFunc pubFunc) 78 | { 79 | CHookManager hm(plug, pubFunc); 80 | return GetHookMan(hm); 81 | } 82 | 83 | CHookManager *CHookManList::GetHookMan(CHookManager &hm) 84 | { 85 | iterator iter = find(hm); 86 | if (iter == end()) 87 | { 88 | push_back(hm); 89 | return &(back()); 90 | } 91 | else 92 | { 93 | return &(*iter); 94 | } 95 | } 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /core/sourcehook/sourcehook_impl_chookmaninfo.h: -------------------------------------------------------------------------------- 1 | /* ======== SourceHook ======== 2 | * Copyright (C) 2004-2010 Metamod:Source Development Team 3 | * No warranties of any kind 4 | * 5 | * License: zlib/libpng 6 | * 7 | * Author(s): Pavol "PM OnoTo" Marko 8 | * ============================ 9 | */ 10 | 11 | #ifndef __SOURCEHOOK_IMPL_CHOOKMANINFO_H__ 12 | #define __SOURCEHOOK_IMPL_CHOOKMANINFO_H__ 13 | 14 | #include "sh_list.h" 15 | #include "sourcehook_impl_cproto.h" 16 | 17 | namespace SourceHook 18 | { 19 | namespace Impl 20 | { 21 | class CVfnPtr; 22 | 23 | class CHookManager : public IHookManagerInfo 24 | { 25 | // *** Data *** 26 | Plugin m_OwnerPlugin; 27 | HookManagerPubFunc m_PubFunc; 28 | int m_VtblOffs; 29 | int m_VtblIdx; 30 | CProto m_Proto; 31 | int m_Version; 32 | 33 | void *m_HookfuncVfnptr; 34 | 35 | List m_VfnPtrs; 36 | public: 37 | // *** Descriptor *** 38 | struct Descriptor 39 | { 40 | Plugin m_OwnerPlugin; 41 | HookManagerPubFunc m_PubFunc; 42 | Descriptor(Plugin ownerPlugin, HookManagerPubFunc pubFunc) 43 | : m_OwnerPlugin(ownerPlugin), m_PubFunc(pubFunc) 44 | { 45 | } 46 | }; 47 | 48 | // *** Interface *** 49 | CHookManager(Plugin ownerPlugin, HookManagerPubFunc pubFunc); 50 | 51 | inline bool operator==(const Descriptor &other) const; 52 | inline bool operator==(const CHookManager &other) const; 53 | 54 | inline operator bool() const; 55 | inline Plugin GetOwnerPlugin() const; 56 | inline int GetVtblOffs() const; 57 | inline int GetVtblIdx() const; 58 | inline const CProto &GetProto() const; 59 | inline int GetVersion() const; 60 | inline void *GetHookFunc() const; 61 | inline HookManagerPubFunc GetPubFunc() const; 62 | 63 | void Register(); 64 | void Unregister(); 65 | 66 | void IncrRef(CVfnPtr *pVfnPtr); 67 | void DecrRef(CVfnPtr *pVfnPtr); 68 | 69 | List &GetVfnPtrList() 70 | { 71 | return m_VfnPtrs; 72 | } 73 | 74 | // *** IHookManagerInfo interface *** 75 | void SetInfo(int hookman_version, int vtbloffs, int vtblidx, 76 | ProtoInfo *proto, void *hookfunc_vfnptr); 77 | }; 78 | 79 | class CHookManList : public List 80 | { 81 | public: 82 | CHookManager *GetHookMan(Plugin plug, HookManagerPubFunc pubFunc); 83 | CHookManager *GetHookMan(CHookManager &hm); 84 | }; 85 | 86 | // *** Implementation **/ 87 | 88 | inline CHookManager::operator bool() const 89 | { 90 | return m_Version != -1; 91 | } 92 | 93 | inline bool CHookManager::operator==(const Descriptor &other) const 94 | { 95 | return m_OwnerPlugin == other.m_OwnerPlugin 96 | && m_PubFunc == other.m_PubFunc; 97 | } 98 | 99 | inline bool CHookManager::operator==(const CHookManager &other) const 100 | { 101 | return m_OwnerPlugin == other.m_OwnerPlugin 102 | && m_PubFunc == other.m_PubFunc; 103 | } 104 | 105 | inline Plugin CHookManager::GetOwnerPlugin() const 106 | { 107 | return m_OwnerPlugin; 108 | } 109 | 110 | inline int CHookManager::GetVtblOffs() const 111 | { 112 | return m_VtblOffs; 113 | } 114 | 115 | inline int CHookManager::GetVtblIdx() const 116 | { 117 | return m_VtblIdx; 118 | } 119 | 120 | inline const CProto &CHookManager::GetProto() const 121 | { 122 | return m_Proto; 123 | } 124 | 125 | inline int CHookManager::GetVersion() const 126 | { 127 | return m_Version; 128 | } 129 | 130 | inline void *CHookManager::GetHookFunc() const 131 | { 132 | return *reinterpret_cast(m_HookfuncVfnptr); 133 | } 134 | 135 | inline HookManagerPubFunc CHookManager::GetPubFunc() const 136 | { 137 | return m_PubFunc; 138 | } 139 | } 140 | } 141 | 142 | #endif 143 | 144 | -------------------------------------------------------------------------------- /core/sourcehook/sourcehook_impl_ciface.h: -------------------------------------------------------------------------------- 1 | /* ======== SourceHook ======== 2 | * Copyright (C) 2004-2010 Metamod:Source Development Team 3 | * No warranties of any kind 4 | * 5 | * License: zlib/libpng 6 | * 7 | * Author(s): Pavol "PM OnoTo" Marko 8 | * ============================ 9 | */ 10 | 11 | #ifndef __SOURCEHOOK_IMPL_CIFACE_H__ 12 | #define __SOURCEHOOK_IMPL_CIFACE_H__ 13 | 14 | #include "sh_list.h" 15 | #include "sourcehook_impl_chook.h" 16 | 17 | namespace SourceHook 18 | { 19 | namespace Impl 20 | { 21 | class CIface 22 | { 23 | // *** Data *** 24 | void *m_Ptr; 25 | 26 | List m_PreHooks; 27 | List m_PostHooks; 28 | public: 29 | 30 | // *** Descriptor *** 31 | typedef void* Descriptor; 32 | 33 | // *** Interface *** 34 | inline CIface(void *ptr); 35 | inline ~CIface(); 36 | inline bool operator==(const Descriptor &other); 37 | inline void *GetPtr() const; 38 | inline List &GetPreHookList(); 39 | inline List &GetPostHookList(); 40 | inline const List &GetPreHookList() const; 41 | inline const List &GetPostHookList() const; 42 | }; 43 | 44 | // *** Implementation *** 45 | inline CIface::CIface(void *ptr) 46 | : m_Ptr(ptr) 47 | { 48 | } 49 | 50 | inline CIface::~CIface() 51 | { 52 | // Before getting deleted, delete all remaining hook handlers 53 | for (List::iterator iter = m_PreHooks.begin(); iter != m_PreHooks.end(); ++iter) 54 | { 55 | iter->GetHandler()->DeleteThis(); 56 | } 57 | 58 | for (List::iterator iter = m_PostHooks.begin(); iter != m_PostHooks.end(); ++iter) 59 | { 60 | iter->GetHandler()->DeleteThis(); 61 | } 62 | } 63 | 64 | inline bool CIface::operator==(const Descriptor &other) 65 | { 66 | return m_Ptr == other; 67 | } 68 | 69 | inline void *CIface::GetPtr() const 70 | { 71 | return m_Ptr; 72 | } 73 | 74 | inline List &CIface::GetPreHookList() 75 | { 76 | return m_PreHooks; 77 | } 78 | 79 | inline List &CIface::GetPostHookList() 80 | { 81 | return m_PostHooks; 82 | } 83 | 84 | inline const List &CIface::GetPreHookList() const 85 | { 86 | return m_PreHooks; 87 | } 88 | 89 | inline const List &CIface::GetPostHookList() const 90 | { 91 | return m_PostHooks; 92 | } 93 | } 94 | } 95 | 96 | #endif 97 | 98 | -------------------------------------------------------------------------------- /core/sourcehook/sourcehook_impl_cleanuptask.h: -------------------------------------------------------------------------------- 1 | /* ======== SourceHook ======== 2 | * Copyright (C) 2004-2010 Metamod:Source Development Team 3 | * No warranties of any kind 4 | * 5 | * License: zlib/libpng 6 | * 7 | * Author(s): Pavol "PM OnoTo" Marko 8 | * ============================ 9 | */ 10 | 11 | #ifndef __SOURCEHOOK_IMPL_CLEANUPTASK_H__ 12 | #define __SOURCEHOOK_IMPL_CLEANUPTASK_H__ 13 | 14 | 15 | namespace SourceHook 16 | { 17 | namespace Impl 18 | { 19 | class ICleanupTask 20 | { 21 | public: 22 | virtual void CleanupAndDeleteThis() = 0; 23 | }; 24 | } 25 | } 26 | 27 | // __SOURCEHOOK_IMPL_CLEANUPTASK_H__ 28 | #endif 29 | 30 | -------------------------------------------------------------------------------- /core/sourcehook/sourcehook_impl_cproto.h: -------------------------------------------------------------------------------- 1 | /* ======== SourceHook ======== 2 | * Copyright (C) 2004-2010 Metamod:Source Development Team 3 | * No warranties of any kind 4 | * 5 | * License: zlib/libpng 6 | * 7 | * Author(s): Pavol "PM OnoTo" Marko 8 | * ============================ 9 | */ 10 | 11 | #ifndef __SOURCEHOOK_IMPL_CPROTO_H__ 12 | #define __SOURCEHOOK_IMPL_CPROTO_H__ 13 | 14 | #include 15 | 16 | #include "sourcehook.h" 17 | #include "sh_vector.h" 18 | 19 | namespace SourceHook 20 | { 21 | namespace Impl 22 | { 23 | // Internal representation 24 | struct IntPassInfo 25 | { 26 | size_t size; 27 | int type; 28 | unsigned int flags; 29 | 30 | void *pNormalCtor; 31 | void *pCopyCtor; 32 | void *pDtor; 33 | void *pAssignOperator; 34 | 35 | bool operator == (const IntPassInfo &other) const 36 | { 37 | return size == other.size 38 | && type == other.type 39 | && flags == other.flags 40 | && pNormalCtor == other.pNormalCtor 41 | && pDtor == other.pDtor 42 | && pAssignOperator == other.pAssignOperator; 43 | } 44 | 45 | bool operator != (const IntPassInfo &other) const 46 | { 47 | return !(*this == other); 48 | } 49 | }; 50 | 51 | class CProto 52 | { 53 | int m_Version; // -1 = invalid 54 | int m_NumOfParams; 55 | IntPassInfo m_RetPassInfo; 56 | CVector m_ParamsPassInfo; 57 | int m_Convention; 58 | 59 | void Fill(const ProtoInfo *pProto); 60 | 61 | // For old sourcehook.h: flags 0 -> assume ByVal 62 | static unsigned int GetRealFlags(const PassInfo &info) 63 | { 64 | return (info.flags == 0) ? PassInfo::PassFlag_ByVal : info.flags; 65 | } 66 | 67 | public: 68 | CProto() : m_Version(-1) 69 | { 70 | } 71 | 72 | CProto(const ProtoInfo *pProto) 73 | { 74 | Fill(pProto); 75 | } 76 | 77 | CProto(const CProto &other) : m_Version(other.m_Version), m_NumOfParams(other.m_NumOfParams), 78 | m_RetPassInfo(other.m_RetPassInfo), m_ParamsPassInfo(other.m_ParamsPassInfo), 79 | m_Convention(other.m_Convention) 80 | { 81 | 82 | } 83 | 84 | ~CProto() 85 | { 86 | } 87 | 88 | void operator = (const ProtoInfo *pProto) 89 | { 90 | Fill (pProto); 91 | } 92 | 93 | bool operator == (const CProto &other) const; 94 | 95 | bool ExactlyEqual(const CProto &other) const; 96 | 97 | int GetVersion() const 98 | { 99 | return m_Version; 100 | } 101 | 102 | int GetNumOfParams() const 103 | { 104 | return m_NumOfParams; 105 | } 106 | 107 | const IntPassInfo & GetParam(int i) const 108 | { 109 | return m_ParamsPassInfo[i]; 110 | } 111 | 112 | IntPassInfo & GetParam(int i) 113 | { 114 | return m_ParamsPassInfo[i]; 115 | } 116 | 117 | const IntPassInfo & GetRet() const 118 | { 119 | return m_RetPassInfo; 120 | } 121 | 122 | IntPassInfo & GetRet() 123 | { 124 | return m_RetPassInfo; 125 | } 126 | 127 | int GetConvention() const 128 | { 129 | return m_Convention; 130 | } 131 | 132 | static size_t GetRealSize(const IntPassInfo &info) 133 | { 134 | if (info.flags & PassInfo::PassFlag_ByRef) 135 | { 136 | return sizeof(void*); 137 | } 138 | 139 | return info.size; 140 | } 141 | }; 142 | } 143 | } 144 | 145 | #endif 146 | 147 | -------------------------------------------------------------------------------- /core/sourcehook/sourcehook_impl_cvfnptr.h: -------------------------------------------------------------------------------- 1 | /* ======== SourceHook ======== 2 | * Copyright (C) 2004-2010 Metamod:Source Development Team 3 | * No warranties of any kind 4 | * 5 | * License: zlib/libpng 6 | * 7 | * Author(s): Pavol "PM OnoTo" Marko 8 | * ============================ 9 | */ 10 | 11 | #ifndef __SOURCEHOOK_IMPL_CVFNPTR_H__ 12 | #define __SOURCEHOOK_IMPL_CVFNPTR_H__ 13 | 14 | #include "sh_list.h" 15 | #include "sh_memory.h" 16 | #include "sh_pagealloc.h" 17 | #include "sourcehook_impl_cleanuptask.h" 18 | #include "sourcehook_impl_chookmaninfo.h" 19 | #include "sourcehook_impl_ciface.h" 20 | 21 | namespace SourceHook 22 | { 23 | namespace Impl 24 | { 25 | class CVfnPtr 26 | { 27 | static CPageAlloc ms_AlignedPageAllocator; 28 | 29 | // *** Data *** 30 | void *m_Ptr; 31 | void *m_OrigEntry; 32 | void *m_OrigCallThunk; // See Init() method 33 | 34 | List m_HookMans; 35 | List m_IfaceList; 36 | public: 37 | // *** Descriptor *** 38 | typedef void* Descriptor; 39 | 40 | // *** Interface *** 41 | CVfnPtr(void *ptr); 42 | ~CVfnPtr(); 43 | bool Init(); 44 | inline bool operator==(const Descriptor &other); 45 | inline void *GetPtr() const; 46 | inline void *GetOrigEntry() const; 47 | void *GetOrigCallAddr() const; 48 | inline List &GetIfaceList(); 49 | inline const List &GetIfaceList() const; 50 | CIface *FindIface(void *iface); 51 | CIface &GetIface(void *iface); 52 | bool Patch(void *newValue); 53 | bool Revert(); 54 | 55 | ICleanupTask *GetCleanupTask(); 56 | 57 | void AddHookMan(CHookManager *pHookMan); 58 | // If this returns false, it means that there is no hook manager left 59 | // to use and that this vfnptr should be removed. 60 | bool HookManRemoved(CHookManager *pHookMan); 61 | }; 62 | 63 | // *** Implementation *** 64 | 65 | inline bool CVfnPtr::operator==(const Descriptor &other) 66 | { 67 | return m_Ptr == other; 68 | } 69 | 70 | inline void *CVfnPtr::GetPtr() const 71 | { 72 | return m_Ptr; 73 | } 74 | 75 | inline void *CVfnPtr::GetOrigEntry() const 76 | { 77 | return m_OrigEntry; 78 | } 79 | 80 | inline List &CVfnPtr::GetIfaceList() 81 | { 82 | return m_IfaceList; 83 | } 84 | 85 | inline const List &CVfnPtr::GetIfaceList() const 86 | { 87 | return m_IfaceList; 88 | } 89 | } 90 | } 91 | 92 | #endif 93 | 94 | -------------------------------------------------------------------------------- /core/sourcehook/sourcehook_pibuilder.h: -------------------------------------------------------------------------------- 1 | /* ======== SourceHook ======== 2 | * Copyright (C) 2004-2010 Metamod:Source Development Team 3 | * No warranties of any kind 4 | * 5 | * License: zlib/libpng 6 | * 7 | * Author(s): Pavol "PM OnoTo" Marko 8 | * ============================ 9 | */ 10 | 11 | #ifndef __SOURCEHOOK_PIBUILDER_H__ 12 | #define __SOURCEHOOK_PIBUILDER_H__ 13 | 14 | #include "sourcehook.h" 15 | #include "sh_vector.h" 16 | 17 | namespace SourceHook 18 | { 19 | // Helper class: protocol information builder 20 | class CProtoInfoBuilder 21 | { 22 | ProtoInfo m_PI; 23 | CVector m_Params; 24 | CVector m_Params2; 25 | public: 26 | CProtoInfoBuilder(int cc) 27 | { 28 | memset(reinterpret_cast(&m_PI), 0, sizeof(ProtoInfo)); 29 | m_PI.convention = cc; 30 | 31 | // dummy 0 params 32 | PassInfo dummy; 33 | PassInfo::V2Info dummy2; 34 | memset(reinterpret_cast(&dummy), 0, sizeof(PassInfo)); 35 | memset(reinterpret_cast(&dummy2), 0, sizeof(PassInfo::V2Info)); 36 | 37 | dummy.size = 1; // Version1 38 | 39 | m_Params.push_back(dummy); 40 | m_Params2.push_back(dummy2); 41 | } 42 | 43 | void SetReturnType(size_t size, PassInfo::PassType type, int flags, 44 | void *pNormalCtor, void *pCopyCtor, void *pDtor, void *pAssignOperator) 45 | { 46 | if (pNormalCtor) 47 | flags |= PassInfo::PassFlag_OCtor; 48 | 49 | if (pCopyCtor) 50 | flags |= PassInfo::PassFlag_CCtor; 51 | 52 | if (pDtor) 53 | flags |= PassInfo::PassFlag_ODtor; 54 | 55 | if (pAssignOperator) 56 | flags |= PassInfo::PassFlag_AssignOp; 57 | 58 | m_PI.retPassInfo.size = size; 59 | m_PI.retPassInfo.type = type; 60 | m_PI.retPassInfo.flags = flags; 61 | m_PI.retPassInfo2.pNormalCtor = pNormalCtor; 62 | m_PI.retPassInfo2.pCopyCtor = pCopyCtor; 63 | m_PI.retPassInfo2.pDtor = pDtor; 64 | m_PI.retPassInfo2.pAssignOperator = pAssignOperator; 65 | } 66 | 67 | void AddParam(size_t size, PassInfo::PassType type, int flags, 68 | void *pNormalCtor, void *pCopyCtor, void *pDtor, void *pAssignOperator) 69 | { 70 | PassInfo pi; 71 | PassInfo::V2Info pi2; 72 | 73 | if (pNormalCtor) 74 | flags |= PassInfo::PassFlag_OCtor; 75 | 76 | if (pCopyCtor) 77 | flags |= PassInfo::PassFlag_CCtor; 78 | 79 | if (pDtor) 80 | flags |= PassInfo::PassFlag_ODtor; 81 | 82 | if (pAssignOperator) 83 | flags |= PassInfo::PassFlag_AssignOp; 84 | 85 | 86 | pi.size = size; 87 | pi.type = type; 88 | pi.flags = flags; 89 | pi2.pNormalCtor = pNormalCtor; 90 | pi2.pCopyCtor = pCopyCtor; 91 | pi2.pDtor = pDtor; 92 | pi2.pAssignOperator = pAssignOperator; 93 | 94 | m_Params.push_back(pi); 95 | m_Params2.push_back(pi2); 96 | ++m_PI.numOfParams; 97 | } 98 | 99 | operator ProtoInfo*() 100 | { 101 | m_PI.paramsPassInfo = &(m_Params[0]); 102 | m_PI.paramsPassInfo2 = &(m_Params2[0]); 103 | return &m_PI; 104 | } 105 | }; 106 | } 107 | 108 | #endif 109 | 110 | -------------------------------------------------------------------------------- /core/sourcehook/test/AMBuilder: -------------------------------------------------------------------------------- 1 | # vim: set sts=2 ts=8 sw=2 tw=99 et ft=python: 2 | import os 3 | 4 | for cxx in MMS.all_targets: 5 | name = 'test_sourcehook' 6 | binary = MMS.Program(cxx, name) 7 | if binary.compiler.target.platform == 'windows': 8 | continue 9 | if binary.compiler.target.arch == 'x86_64' and binary.compiler.target.platform == 'linux': 10 | continue 11 | 12 | binary.compiler.defines += [ 13 | 'SOURCEHOOK_TESTS', 14 | ] 15 | 16 | binary.compiler.cxxincludes += [ 17 | os.path.join(builder.sourcePath, 'core'), 18 | os.path.join(builder.sourcePath, 'core', 'sourcehook'), 19 | ] 20 | if binary.compiler.version >= 'gcc-4.9': 21 | binary.compiler.cxxflags += ['-fno-devirtualize'] 22 | if binary.compiler.version >= 'clang-2.9' or binary.compiler.version >= 'apple-clang-3.0': 23 | binary.compiler.cxxflags += ['-Wno-null-dereference'] 24 | 25 | binary.sources += [ 26 | 'main.cpp', 27 | '../sourcehook.cpp', 28 | '../sourcehook_impl_chookmaninfo.cpp', 29 | '../sourcehook_impl_chookidman.cpp', 30 | '../sourcehook_impl_cproto.cpp', 31 | '../sourcehook_impl_cvfnptr.cpp', 32 | '../sourcehook_hookmangen.cpp', 33 | 'test1.cpp', 34 | 'test2.cpp', 35 | 'test3.cpp', 36 | 'test4.cpp', 37 | 'testbail.cpp', 38 | 'testbail2.cpp', 39 | 'testhookmangen.cpp', 40 | 'testlist.cpp', 41 | 'testmanual.cpp', 42 | 'testmulti.cpp', 43 | 'testoddthunks.cpp', 44 | 'testrecall.cpp', 45 | 'testreentr.cpp', 46 | 'testref.cpp', 47 | 'testrefret.cpp', 48 | 'testvphooks.cpp', 49 | ] 50 | if cxx.target.arch == 'x86': 51 | binary.sources += ['../sourcehook_hookmangen_x86.cpp'] 52 | elif binary.compiler.target.arch == 'x86_64': 53 | binary.sources += ['../sourcehook_hookmangen_x86_64.cpp'] 54 | 55 | builder.Add(binary) 56 | -------------------------------------------------------------------------------- /core/sourcehook/test/Makefile: -------------------------------------------------------------------------------- 1 | # (C)2004-2009 Metamod:Source Development Team 2 | # Makefile written by David "BAILOPAN" Anderson and Pavol Marko 3 | 4 | OPT_FLAGS = -O3 -funroll-loops -s -pipe 5 | DEBUG_FLAGS = -g -ggdb3 6 | CPP = gcc 7 | LINK = -lstdc++ 8 | INCLUDE = -I. -I.. 9 | MAX_PARAMS=20 10 | 11 | BINARY = sourcehook_test 12 | OBJECTS = main.cpp sourcehook.cpp sourcehook_hookmangen.cpp sourcehook_impl_chookmaninfo.cpp sourcehook_impl_chookidman.cpp sourcehook_impl_cproto.cpp sourcehook_impl_cvfnptr.cpp $(shell ls -t test*.cpp) 13 | HEADERS = ../sh_list.h ../sh_tinyhash.h ../sh_memory.h ../sh_string.h ../sh_vector.h ../sourcehook_impl.h ../FastDelegate.h ../sourcehook.h ../sh_memfuncinfo.h ../sh_pagealloc.h 14 | 15 | ifeq "$(DEBUG)" "true" 16 | BIN_DIR = Debug 17 | CFLAGS = $(DEBUG_FLAGS) 18 | else 19 | BIN_DIR = Release 20 | CFLAGS = $(OPT_FLAGS) 21 | endif 22 | 23 | CFLAGS += -Wall -Wno-non-virtual-dtor 24 | # Also, enable SH_ASSERT 25 | CFLAGS += -DSH_DEBUG 26 | 27 | OBJ_LINUX := $(OBJECTS:%.cpp=$(BIN_DIR)/%.o) 28 | 29 | 30 | default: all 31 | 32 | $(BIN_DIR)/%.o: %.cpp $(HEADERS) 33 | $(CPP) $(INCLUDE) $(CFLAGS) -o $@ -c $< 34 | 35 | ../sourcehook.h: ../generate/sourcehook.hxx 36 | (cd ../generate; ./shworker.bin iter sourcehook.hxx sourcehook.h $(MAX_PARAMS); cp sourcehook.h ..) 37 | 38 | ../sourcehook.hxx: ../generate/sh_memfuncinfo.hxx 39 | (cd ../generate; ./shworker.bin iter sh_memfuncinfo.hxx sh_memfuncinfo.h $(MAX_PARAMS); cp sh_memfuncino.h ..) 40 | 41 | ../FastDelegate.hxx: ../generate/FastDelegate.hxx 42 | (cd ../generate; ./shworker.bin iter FastDelegate.hxx FastDelegate.h $(MAX_PARAMS); cp FastDelegate.h ..) 43 | 44 | debug: 45 | $(MAKE) all DEBUG=true 46 | 47 | all: 48 | mkdir -p $(BIN_DIR) 49 | ln -sf ../sourcehook.cpp 50 | ln -sf ../sourcehook_hookmangen.cpp 51 | ln -sf ../sourcehook_impl_chookidman.cpp 52 | ln -sf ../sourcehook_impl_chookmaninfo.cpp 53 | ln -sf ../sourcehook_impl_cproto.cpp 54 | ln -sf ../sourcehook_impl_cvfnptr.cpp 55 | $(MAKE) $(BINARY) 56 | rm -f $(BINARY) 57 | rm -f sourcehook.cpp 58 | rm -f sourcehook_hookmangen.cpp 59 | rm -f sourcehook_impl_chookidman.cpp 60 | rm -f sourcehook_impl_chookmaninfo.cpp 61 | rm -f sourcehook_impl_cproto.cpp 62 | rm -f sourcehook_impl_cvfnptr.cpp 63 | ln -sf $(BIN_DIR)/$(BINARY) $(BINARY) 64 | 65 | 66 | $(BINARY): $(OBJ_LINUX) 67 | $(CPP) $(INCLUDE) $(CFLAGS) $(OBJ_LINUX) $(LINK) -o $(BIN_DIR)/$(BINARY) 68 | 69 | clean: 70 | rm -rf Release/*.o 71 | rm -rf Release/$(BINARY) 72 | rm -rf Debug/*.o 73 | rm -rf Debug/$(BINARY) 74 | -------------------------------------------------------------------------------- /core/sourcehook/test/generate.bat: -------------------------------------------------------------------------------- 1 | :: Generates everything 2 | :: Usage: 3 | :: generate.bat 4 | 5 | 6 | ..\generate\shworker iter testhookmangen.hxx testhookmangen.h %1 -------------------------------------------------------------------------------- /core/sourcehook/test/main.cpp: -------------------------------------------------------------------------------- 1 | // Hello BAIL! 2 | // hello pm how are you 3 | // I'm fine, what about you? 4 | // not bad, just looking for mem leaks 5 | // mem leaks in my code!? never! I have to preserve binary compatibility :( 6 | // This is a test file 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #include "sourcehook_impl.h" 15 | #include "sourcehook.h" 16 | #include "sourcehook_hookmangen.h" 17 | 18 | using namespace std; 19 | bool g_Verbose; 20 | 21 | struct Unloader : public SourceHook::Impl::UnloadListener 22 | { 23 | void ReadyToUnload(SourceHook::Plugin) { } 24 | } g_UnloadListener; 25 | 26 | #define DECL_TEST(x) bool Test##x(std::string &error); 27 | 28 | #define DO_TEST(x) \ 29 | error.clear(); \ 30 | if (Test##x(error)) \ 31 | { \ 32 | ++passed; \ 33 | cout << "Test" << #x << " passed" << endl; \ 34 | } \ 35 | else \ 36 | { \ 37 | ++failed; \ 38 | cout << "Test" << #x << " FAILED: " << error << endl; \ 39 | } \ 40 | 41 | 42 | DECL_TEST(List); 43 | DECL_TEST(Basic); 44 | DECL_TEST(VafmtAndOverload); 45 | DECL_TEST(ThisPtrOffs); 46 | DECL_TEST(PlugSys); 47 | DECL_TEST(Bail); 48 | DECL_TEST(Reentr); 49 | DECL_TEST(Manual); 50 | DECL_TEST(Recall); 51 | DECL_TEST(Multi); 52 | DECL_TEST(Ref); 53 | DECL_TEST(RefRet); 54 | DECL_TEST(VPHooks); 55 | DECL_TEST(CPageAlloc); // in testhookmangen.cpp 56 | DECL_TEST(HookManGen); 57 | DECL_TEST(OddThunks); 58 | 59 | int main(int argc, char *argv[]) 60 | { 61 | std::string error; 62 | 63 | g_Verbose = argc > 1 && strcmp(argv[1], "-v") == 0; 64 | 65 | int passed = 0, failed = 0; 66 | 67 | DO_TEST(List); 68 | DO_TEST(Basic); 69 | DO_TEST(VafmtAndOverload); 70 | DO_TEST(ThisPtrOffs); 71 | DO_TEST(PlugSys); 72 | DO_TEST(Bail); 73 | DO_TEST(Reentr); 74 | DO_TEST(Manual); 75 | DO_TEST(Recall); 76 | DO_TEST(Multi); 77 | DO_TEST(Ref); 78 | DO_TEST(RefRet); 79 | DO_TEST(VPHooks); 80 | DO_TEST(CPageAlloc); 81 | #if !defined( _M_AMD64 ) && !defined( __amd64__ ) && !defined(__x86_64__) // TODO: Fix for 64-bit 82 | DO_TEST(HookManGen); 83 | #endif 84 | DO_TEST(OddThunks); 85 | 86 | cout << endl << "----" << endl << "Passed: " << passed << endl << "Failed: " << failed << endl; 87 | cout << "Total: " << passed + failed << endl; 88 | 89 | if (failed) 90 | return 1; 91 | return 0; 92 | } 93 | 94 | SourceHook::ISourceHook *Test_Factory() 95 | { 96 | return new SourceHook::Impl::CSourceHookImpl(); 97 | } 98 | 99 | void Test_Delete(SourceHook::ISourceHook *shptr) 100 | { 101 | delete static_cast(shptr); 102 | } 103 | 104 | void Test_CompleteShutdown(SourceHook::ISourceHook *shptr) 105 | { 106 | static_cast(shptr)->CompleteShutdown(); 107 | } 108 | 109 | class Listener : public SourceHook::Impl::UnloadListener 110 | { 111 | public: 112 | void ReadyToUnload(SourceHook::Plugin plug) override { 113 | } 114 | } sListener; 115 | 116 | void Test_UnloadPlugin(SourceHook::ISourceHook *shptr, SourceHook::Plugin plug) 117 | { 118 | static_cast(shptr)->UnloadPlugin(plug, &sListener); 119 | } 120 | 121 | void Test_PausePlugin(SourceHook::ISourceHook *shptr, SourceHook::Plugin plug) 122 | { 123 | static_cast(shptr)->PausePlugin(plug); 124 | } 125 | 126 | void Test_UnpausePlugin(SourceHook::ISourceHook *shptr, SourceHook::Plugin plug) 127 | { 128 | static_cast(shptr)->UnpausePlugin(plug); 129 | } 130 | 131 | #if !defined( _M_AMD64 ) && !defined( __amd64__ ) && !defined(__x86_64__) 132 | SourceHook::IHookManagerAutoGen *Test_HMAG_Factory(SourceHook::ISourceHook *shptr) 133 | { 134 | return new SourceHook::Impl::CHookManagerAutoGen(shptr); 135 | } 136 | 137 | void Test_HMAG_Delete(SourceHook::IHookManagerAutoGen *ptr) 138 | { 139 | delete static_cast(ptr); 140 | } 141 | #endif 142 | 143 | -------------------------------------------------------------------------------- /core/sourcehook/test/msvc12/test.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.31101.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test", "test.vcxproj", "{456BBA64-FF14-4292-8443-3BA79E4D84CC}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug_NoDebugRuntimeLib|Win32 = Debug_NoDebugRuntimeLib|Win32 11 | Debug_NoDebugRuntimeLib|x64 = Debug_NoDebugRuntimeLib|x64 12 | Debug|Win32 = Debug|Win32 13 | Debug|x64 = Debug|x64 14 | DebugOpt|Win32 = DebugOpt|Win32 15 | DebugOpt|x64 = DebugOpt|x64 16 | Release|Win32 = Release|Win32 17 | Release|x64 = Release|x64 18 | EndGlobalSection 19 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 20 | {456BBA64-FF14-4292-8443-3BA79E4D84CC}.Debug_NoDebugRuntimeLib|Win32.ActiveCfg = Debug_NoDebugRuntimeLib|Win32 21 | {456BBA64-FF14-4292-8443-3BA79E4D84CC}.Debug_NoDebugRuntimeLib|Win32.Build.0 = Debug_NoDebugRuntimeLib|Win32 22 | {456BBA64-FF14-4292-8443-3BA79E4D84CC}.Debug_NoDebugRuntimeLib|x64.ActiveCfg = Debug_NoDebugRuntimeLib|x64 23 | {456BBA64-FF14-4292-8443-3BA79E4D84CC}.Debug_NoDebugRuntimeLib|x64.Build.0 = Debug_NoDebugRuntimeLib|x64 24 | {456BBA64-FF14-4292-8443-3BA79E4D84CC}.Debug|Win32.ActiveCfg = Debug|Win32 25 | {456BBA64-FF14-4292-8443-3BA79E4D84CC}.Debug|Win32.Build.0 = Debug|Win32 26 | {456BBA64-FF14-4292-8443-3BA79E4D84CC}.Debug|x64.ActiveCfg = Debug|x64 27 | {456BBA64-FF14-4292-8443-3BA79E4D84CC}.Debug|x64.Build.0 = Debug|x64 28 | {456BBA64-FF14-4292-8443-3BA79E4D84CC}.DebugOpt|Win32.ActiveCfg = DebugOpt|Win32 29 | {456BBA64-FF14-4292-8443-3BA79E4D84CC}.DebugOpt|Win32.Build.0 = DebugOpt|Win32 30 | {456BBA64-FF14-4292-8443-3BA79E4D84CC}.DebugOpt|x64.ActiveCfg = DebugOpt|x64 31 | {456BBA64-FF14-4292-8443-3BA79E4D84CC}.DebugOpt|x64.Build.0 = DebugOpt|x64 32 | {456BBA64-FF14-4292-8443-3BA79E4D84CC}.Release|Win32.ActiveCfg = Release|Win32 33 | {456BBA64-FF14-4292-8443-3BA79E4D84CC}.Release|Win32.Build.0 = Release|Win32 34 | {456BBA64-FF14-4292-8443-3BA79E4D84CC}.Release|x64.ActiveCfg = Release|x64 35 | {456BBA64-FF14-4292-8443-3BA79E4D84CC}.Release|x64.Build.0 = Release|x64 36 | EndGlobalSection 37 | GlobalSection(SolutionProperties) = preSolution 38 | HideSolutionNode = FALSE 39 | EndGlobalSection 40 | EndGlobal 41 | -------------------------------------------------------------------------------- /core/sourcehook/test/sourcehook_test.h: -------------------------------------------------------------------------------- 1 | // This file is used for backwards compatibility testing 2 | // It allows us to test binary backwards compatibility by using an older include file HERE: 3 | #include "sourcehook.h" // <-- here 4 | // There. main.cpp which implements all of the following function is always usign sourcehook.h 5 | // and the up-to-date sourcehook_impl.h/sourcehook.cpp. The tests use this file however. 6 | // If the test needs an up-to-date version (like the recall test), it can simply 7 | // #include "sourcehook.h" before including this, thus overriding our decision. 8 | 9 | 10 | SourceHook::ISourceHook *Test_Factory(); 11 | void Test_Delete(SourceHook::ISourceHook *shptr); 12 | 13 | template 14 | struct CAutoPtrDestruction 15 | { 16 | T *m_Ptr; 17 | CAutoPtrDestruction(T *p) : m_Ptr(p) { } 18 | ~CAutoPtrDestruction() { if (m_Ptr) delete m_Ptr; } 19 | void clear() { m_Ptr = NULL; } 20 | void set(T *ptr) { m_Ptr = ptr; } 21 | }; 22 | 23 | struct CSHPtrAutoDestruction 24 | { 25 | SourceHook::ISourceHook *m_SHPtr; 26 | CSHPtrAutoDestruction(SourceHook::ISourceHook *shptr) : m_SHPtr(shptr) {} 27 | ~CSHPtrAutoDestruction() { Test_Delete(m_SHPtr); } 28 | }; 29 | 30 | #define GET_SHPTR(var) var = Test_Factory(); CSHPtrAutoDestruction ___autodestruction(var); 31 | 32 | // Access to CSourceHookImpl functions 33 | void Test_CompleteShutdown(SourceHook::ISourceHook *shptr); 34 | void Test_UnloadPlugin(SourceHook::ISourceHook *shptr, SourceHook::Plugin plug); 35 | void Test_PausePlugin(SourceHook::ISourceHook *shptr, SourceHook::Plugin plug); 36 | void Test_UnpausePlugin(SourceHook::ISourceHook *shptr, SourceHook::Plugin plug); 37 | 38 | SourceHook::IHookManagerAutoGen *Test_HMAG_Factory(SourceHook::ISourceHook *pSHPtr); 39 | void Test_HMAG_Delete(SourceHook::IHookManagerAutoGen *ptr); 40 | 41 | struct CHMAGAutoDestruction 42 | { 43 | SourceHook::IHookManagerAutoGen *m_Ptr; 44 | CHMAGAutoDestruction(SourceHook::IHookManagerAutoGen *ptr) : m_Ptr(ptr) {} 45 | ~CHMAGAutoDestruction() { Test_HMAG_Delete(m_Ptr); } 46 | }; 47 | 48 | 49 | #define GET_HMAG(var, shptr) var = Test_HMAG_Factory(shptr); CHMAGAutoDestruction __hmagautodestruction(var); 50 | -------------------------------------------------------------------------------- /core/sourcehook/test/test.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 10.00 3 | # Visual Studio 2008 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test", "test.vcproj", "{456BBA64-FF14-4292-8443-3BA79E4D84CC}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug_NoDebugRuntimeLib|Win32 = Debug_NoDebugRuntimeLib|Win32 9 | Debug|Win32 = Debug|Win32 10 | DebugOpt|Win32 = DebugOpt|Win32 11 | Release|Win32 = Release|Win32 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {456BBA64-FF14-4292-8443-3BA79E4D84CC}.Debug_NoDebugRuntimeLib|Win32.ActiveCfg = Debug_NoDebugRuntimeLib|Win32 15 | {456BBA64-FF14-4292-8443-3BA79E4D84CC}.Debug_NoDebugRuntimeLib|Win32.Build.0 = Debug_NoDebugRuntimeLib|Win32 16 | {456BBA64-FF14-4292-8443-3BA79E4D84CC}.Debug|Win32.ActiveCfg = Debug|Win32 17 | {456BBA64-FF14-4292-8443-3BA79E4D84CC}.Debug|Win32.Build.0 = Debug|Win32 18 | {456BBA64-FF14-4292-8443-3BA79E4D84CC}.DebugOpt|Win32.ActiveCfg = DebugOpt|Win32 19 | {456BBA64-FF14-4292-8443-3BA79E4D84CC}.DebugOpt|Win32.Build.0 = DebugOpt|Win32 20 | {456BBA64-FF14-4292-8443-3BA79E4D84CC}.Release|Win32.ActiveCfg = Release|Win32 21 | {456BBA64-FF14-4292-8443-3BA79E4D84CC}.Release|Win32.Build.0 = Release|Win32 22 | EndGlobalSection 23 | GlobalSection(SolutionProperties) = preSolution 24 | HideSolutionNode = FALSE 25 | EndGlobalSection 26 | EndGlobal 27 | -------------------------------------------------------------------------------- /core/sourcehook/test/testbail.cpp: -------------------------------------------------------------------------------- 1 | // TESTBAIL 2 | // This test used to be a test for a bug BAIL found. 3 | // That bug is now fixed so I've granted BAIL the pleasure of being a test for 4 | // the correct priority ordering of hook managers based on their version. 5 | 6 | /* 7 | THE PROBLEM: 8 | Old hook funcs don't work right when you combine override returns and recalls. 9 | THE SOLUTION: 10 | Always use a new hook func when possible. For this, hook funcs have to be able to say 11 | " HELLO I'M NEW! " 12 | 13 | This file tests that functionality. 14 | 15 | How it works: 16 | testbail.cpp compiles with old version of sourcehook.h. 17 | It sets everything up, adds a hook on a function 18 | Then testbail2.cpp which has the new version adds a hook on the same function and 19 | does a recall and overrides the value in it. 20 | */ 21 | #include "sourcehook_test.h" 22 | #include "testbail.h" 23 | 24 | namespace N_TestBail 25 | { 26 | StateList g_States; 27 | SourceHook::ISourceHook *g_SHPtr; 28 | IGaben *g_Gabgab; 29 | } 30 | 31 | namespace 32 | { 33 | int EatYams_Handler1(int a) 34 | { 35 | ADD_STATE(State_EatYams_Handler1_Called(a)); 36 | RETURN_META_VALUE(MRES_IGNORED, 0); 37 | } 38 | } 39 | 40 | bool TestBail(std::string &error) 41 | { 42 | GET_SHPTR(g_SHPtr); 43 | g_PLID = 1; 44 | 45 | g_Gabgab = new IGaben; 46 | 47 | SH_ADD_HOOK(IGaben, EatYams, g_Gabgab, SH_STATIC(EatYams_Handler1), false); 48 | 49 | ADD_STATE(State_EatYams_Return(g_Gabgab->EatYams(0xDEAD))); 50 | 51 | CHECK_STATES((&g_States, 52 | new State_EatYams_Handler1_Called(0xDEAD), 53 | new State_EatYams_Called(0xDEAD), 54 | new State_EatYams_Return(5), 55 | NULL), "Part 1"); 56 | 57 | if (!TestBail2(error)) 58 | return false; 59 | 60 | CHECK_STATES((&g_States, 61 | new State_EatYams_Handler1_Called(0xDEAD), 62 | new State_EatYams_Handler2_Called(0xDEAD), 63 | new State_EatYams_Handler3_Called(0xBEEF), 64 | new State_EatYams_Called(0xBEEF), 65 | NULL), "Part 2.1"); 66 | 67 | // WHAT IF NOW SOMEONE UNLOADS PLUGIN 2 !?!?!?!? 68 | Test_UnloadPlugin(g_SHPtr, 2); 69 | 70 | ADD_STATE(State_EatYams_Return(g_Gabgab->EatYams(0xDEAD))); 71 | 72 | CHECK_STATES((&g_States, 73 | new State_EatYams_Handler1_Called(0xDEAD), 74 | new State_EatYams_Called(0xDEAD), 75 | new State_EatYams_Return(5), 76 | NULL), "Part 3"); 77 | 78 | SH_REMOVE_HOOK(IGaben, EatYams, g_Gabgab, SH_STATIC(EatYams_Handler1), false); 79 | 80 | ADD_STATE(State_EatYams_Return(g_Gabgab->EatYams(0xDEAD))); 81 | 82 | CHECK_STATES((&g_States, 83 | new State_EatYams_Called(0xDEAD), 84 | new State_EatYams_Return(5), 85 | NULL), "Part 4"); 86 | 87 | // Now, heh, try it the other way round. 88 | 89 | Test_CompleteShutdown(g_SHPtr); 90 | 91 | if (!TestBail2(error)) 92 | return false; 93 | 94 | CHECK_STATES((&g_States, 95 | new State_EatYams_Handler2_Called(0xDEAD), 96 | new State_EatYams_Handler3_Called(0xBEEF), 97 | new State_EatYams_Called(0xBEEF), 98 | NULL), "Part 5"); 99 | 100 | SH_ADD_HOOK(IGaben, EatYams, g_Gabgab, SH_STATIC(EatYams_Handler1), false); 101 | 102 | ADD_STATE(State_EatYams_Return(g_Gabgab->EatYams(0xDEAD))); 103 | 104 | CHECK_STATES((&g_States, 105 | new State_EatYams_Handler2_Called(0xDEAD), 106 | new State_EatYams_Handler3_Called(0xBEEF), 107 | new State_EatYams_Handler1_Called(0xBEEF), 108 | new State_EatYams_Called(0xBEEF), 109 | new State_EatYams_Return(6), 110 | NULL), "Part 6"); 111 | 112 | delete g_Gabgab; 113 | 114 | return true; 115 | } 116 | -------------------------------------------------------------------------------- /core/sourcehook/test/testbail.h: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////// 2 | // Shared data for testbail 3 | 4 | #include 5 | #include "testevents.h" 6 | 7 | namespace N_TestBail 8 | { 9 | extern StateList g_States; 10 | extern SourceHook::ISourceHook *g_SHPtr; 11 | 12 | MAKE_STATE_1(State_EatYams_Called, int); 13 | MAKE_STATE_1(State_EatYams_Handler1_Called, int); 14 | MAKE_STATE_1(State_EatYams_Handler2_Called, int); 15 | MAKE_STATE_1(State_EatYams_Handler3_Called, int); 16 | MAKE_STATE_1(State_EatYams_Return, int); 17 | 18 | class IGaben 19 | { 20 | public: 21 | virtual int EatYams(int a) 22 | { 23 | ADD_STATE(State_EatYams_Called(a)); 24 | return 5; 25 | } 26 | }; 27 | 28 | extern IGaben *g_Gabgab; 29 | 30 | bool TestBail2(std::string &error); 31 | } 32 | 33 | using namespace N_TestBail; 34 | 35 | namespace 36 | { 37 | SourceHook::Plugin g_PLID; 38 | SH_DECL_HOOK1(IGaben, EatYams, SH_NOATTRIB, 0, int, int); 39 | } 40 | -------------------------------------------------------------------------------- /core/sourcehook/test/testbail2.cpp: -------------------------------------------------------------------------------- 1 | // TESTBAIL 2 | // Different compilation unit 3 | 4 | #include "sourcehook.h" 5 | #include "sourcehook_test.h" 6 | #include "testbail.h" 7 | 8 | 9 | int EatYams_Handler2(int a) 10 | { 11 | ADD_STATE(State_EatYams_Handler2_Called(a)); 12 | RETURN_META_VALUE_NEWPARAMS(MRES_OVERRIDE, 6, &IGaben::EatYams, (0xBEEF)); 13 | } 14 | 15 | int EatYams_Handler3(int a) 16 | { 17 | ADD_STATE(State_EatYams_Handler3_Called(a)); 18 | RETURN_META_VALUE(MRES_IGNORED, 0); 19 | } 20 | 21 | namespace N_TestBail 22 | { 23 | bool TestBail2(std::string &error) 24 | { 25 | g_PLID = 2; 26 | 27 | SH_ADD_HOOK(IGaben, EatYams, g_Gabgab, SH_STATIC(EatYams_Handler2), false); 28 | SH_ADD_HOOK(IGaben, EatYams, g_Gabgab, SH_STATIC(EatYams_Handler3), false); 29 | 30 | int ret = g_Gabgab->EatYams(0xDEAD); 31 | 32 | CHECK_COND(ret == 6, "Part 2.1"); 33 | 34 | return true; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /core/sourcehook/test/testmulti.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "sourcehook.h" 3 | #include "sourcehook_test.h" 4 | #include "testevents.h" 5 | 6 | // This should probably be done the other way round! 7 | #if SH_XP == SH_XP_POSIX 8 | #define _snprintf snprintf 9 | #endif 10 | 11 | namespace 12 | { 13 | SourceHook::ISourceHook *g_SHPtr; 14 | SourceHook::Plugin g_PLID; 15 | 16 | unsigned int g_callcount[10]; 17 | 18 | class VMultiTest 19 | { 20 | public: 21 | VMultiTest(unsigned int index) : m_idx(index) 22 | { 23 | } 24 | public: 25 | virtual void HookTarget() 26 | { 27 | } 28 | virtual void Notify() 29 | { 30 | g_callcount[this->m_idx]++; 31 | } 32 | private: 33 | unsigned int m_idx; 34 | }; 35 | 36 | void HookFunction() 37 | { 38 | VMultiTest *pv = META_IFACEPTR(VMultiTest); 39 | pv->Notify(); 40 | } 41 | 42 | SH_DECL_HOOK0_void(VMultiTest, HookTarget, SH_NOATTRIB, false); 43 | }; 44 | 45 | bool TestMulti(std::string &error) 46 | { 47 | GET_SHPTR(g_SHPtr); 48 | g_PLID = 1337; 49 | 50 | VMultiTest **pv = new VMultiTest *[10]; 51 | for (unsigned int i=0; i<10; i++) 52 | pv[i] = new VMultiTest(i); 53 | 54 | 55 | for (unsigned int i=0; i<10; i++) 56 | SH_ADD_HOOK(VMultiTest, HookTarget, pv[i], SH_STATIC(HookFunction), false); 57 | 58 | pv[0]->HookTarget(); 59 | 60 | if (g_callcount[0] != 1) 61 | { 62 | error.assign("g_callcount[0] != 0"); 63 | return false; 64 | } 65 | 66 | for (unsigned int i=1; i<10; i++) 67 | { 68 | if (g_callcount[i]) 69 | { 70 | error.assign("g_callcount[n] != 0"); 71 | return false; 72 | } 73 | } 74 | 75 | SH_REMOVE_HOOK(VMultiTest, HookTarget, pv[0], SH_STATIC(HookFunction), false); 76 | 77 | for (unsigned int i=1; i<10; i++) 78 | pv[i]->HookTarget(); 79 | 80 | if (g_callcount[0] != 1) 81 | { 82 | error.assign("g_callcount[0] != 0"); 83 | return false; 84 | } 85 | 86 | for (unsigned int i=1; i<10; i++) 87 | { 88 | if (g_callcount[i] != 1) 89 | { 90 | char err[256]; 91 | _snprintf(err, sizeof(err)-1, "g_callcount[%d] != 1", i); 92 | error.assign(err); 93 | return false; 94 | } 95 | } 96 | 97 | for (unsigned int i=0; i<10; i++) 98 | { 99 | SH_REMOVE_HOOK(VMultiTest, HookTarget, pv[1], SH_STATIC(HookFunction), false); 100 | delete pv[i]; 101 | } 102 | 103 | delete [] pv; 104 | 105 | return true; 106 | } 107 | -------------------------------------------------------------------------------- /core/sourcehook/test/version.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alliedmodders/metamod-source/5d2bb7e206232879729a0b53aa6f289077977f3c/core/sourcehook/test/version.rc -------------------------------------------------------------------------------- /core/version.rc: -------------------------------------------------------------------------------- 1 | // Microsoft Visual C++ generated resource script. 2 | // 3 | 4 | #define APSTUDIO_READONLY_SYMBOLS 5 | ///////////////////////////////////////////////////////////////////////////// 6 | // 7 | // Generated from the TEXTINCLUDE 2 resource. 8 | // 9 | #include "winres.h" 10 | #include 11 | 12 | ///////////////////////////////////////////////////////////////////////////// 13 | #undef APSTUDIO_READONLY_SYMBOLS 14 | 15 | ///////////////////////////////////////////////////////////////////////////// 16 | // English (U.S.) resources 17 | 18 | #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) 19 | #ifdef _WIN32 20 | LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US 21 | #pragma code_page(1252) 22 | #endif //_WIN32 23 | 24 | ///////////////////////////////////////////////////////////////////////////// 25 | // 26 | // Version 27 | // 28 | 29 | VS_VERSION_INFO VERSIONINFO 30 | FILEVERSION MMS_VERSION_FILE 31 | PRODUCTVERSION MMS_VERSION_FILE 32 | FILEFLAGSMASK 0x17L 33 | #ifdef _DEBUG 34 | FILEFLAGS 0x1L 35 | #else 36 | FILEFLAGS 0x0L 37 | #endif 38 | FILEOS 0x4L 39 | FILETYPE 0x2L 40 | FILESUBTYPE 0x0L 41 | BEGIN 42 | BLOCK "StringFileInfo" 43 | BEGIN 44 | BLOCK "000004b0" 45 | BEGIN 46 | VALUE "Comments", "Metamod: Source" 47 | VALUE "FileDescription", "Metamod: Source" 48 | VALUE "FileVersion", MMS_VERSION_STRING 49 | VALUE "InternalName", "mmsource" 50 | VALUE "LegalCopyright", "Copyright (c) 2004-2010, Metamod: Source Development Team" 51 | VALUE "OriginalFilename", BINARY_NAME 52 | VALUE "ProductName", "Metamod:Source" 53 | VALUE "ProductVersion", MMS_VERSION_STRING 54 | END 55 | END 56 | BLOCK "VarFileInfo" 57 | BEGIN 58 | VALUE "Translation", 0x0, 1200 59 | END 60 | END 61 | 62 | 63 | #ifdef APSTUDIO_INVOKED 64 | ///////////////////////////////////////////////////////////////////////////// 65 | // 66 | // TEXTINCLUDE 67 | // 68 | 69 | 1 TEXTINCLUDE 70 | BEGIN 71 | "resource.h\0" 72 | END 73 | 74 | 2 TEXTINCLUDE 75 | BEGIN 76 | "#include ""winres.h""\r\n" 77 | "\0" 78 | END 79 | 80 | 3 TEXTINCLUDE 81 | BEGIN 82 | "\r\n" 83 | "\0" 84 | END 85 | 86 | #endif // APSTUDIO_INVOKED 87 | 88 | #endif // English (U.S.) resources 89 | ///////////////////////////////////////////////////////////////////////////// 90 | 91 | 92 | 93 | #ifndef APSTUDIO_INVOKED 94 | ///////////////////////////////////////////////////////////////////////////// 95 | // 96 | // Generated from the TEXTINCLUDE 3 resource. 97 | // 98 | 99 | 100 | ///////////////////////////////////////////////////////////////////////////// 101 | #endif // not APSTUDIO_INVOKED 102 | -------------------------------------------------------------------------------- /cruft/installer/Attach.cfg: -------------------------------------------------------------------------------- 1 | -$A8 2 | -$B- 3 | -$C+ 4 | -$D+ 5 | -$E- 6 | -$F- 7 | -$G+ 8 | -$H+ 9 | -$I+ 10 | -$J- 11 | -$K- 12 | -$L+ 13 | -$M- 14 | -$N+ 15 | -$O+ 16 | -$P+ 17 | -$Q- 18 | -$R- 19 | -$S- 20 | -$T- 21 | -$U- 22 | -$V+ 23 | -$W- 24 | -$X+ 25 | -$YD 26 | -$Z1 27 | -cg 28 | -AWinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE; 29 | -H+ 30 | -W+ 31 | -M 32 | -$M16384,1048576 33 | -K$00400000 34 | -LE"c:\program files\borland\delphi7\Projects\Bpl" 35 | -LN"c:\program files\borland\delphi7\Projects\Bpl" 36 | -w-UNSAFE_TYPE 37 | -w-UNSAFE_CODE 38 | -w-UNSAFE_CAST 39 | -------------------------------------------------------------------------------- /cruft/installer/Attach.dpr: -------------------------------------------------------------------------------- 1 | program Attach; 2 | 3 | {$APPTYPE CONSOLE} 4 | 5 | uses 6 | SysUtils, Classes, UnitPackSystem; 7 | 8 | var eStream: TMemoryStream; 9 | eFiles: TStringList; 10 | Version: String; 11 | begin 12 | WriteLn('// File attacher for the MM:S installer'); 13 | WriteLn('// by Basic-Master'); 14 | WriteLn(''); 15 | WriteLn('// Looking up files...'); 16 | { Check files } 17 | if FileExists(ExtractFilePath(ParamStr(0)) + 'files\hl2launch.exe') then 18 | WriteLn('// Found files\hl2launch.exe') 19 | else begin 20 | WriteLn('// Error: Couldn''t find files\hl2launch.exe!'); 21 | ReadLn; 22 | exit; 23 | end; 24 | if FileExists(ExtractFilePath(ParamStr(0)) + 'files\server.dll.source') then 25 | WriteLn('// Found files\server.dll.source') 26 | else begin 27 | WriteLn('// Error: Couldn''t find files\server.dll.source!'); 28 | ReadLn; 29 | exit; 30 | end; 31 | if FileExists(ExtractFilePath(ParamStr(0)) + 'files\server_i486.so.source') then 32 | WriteLn('// Found files\server_i486.so.source') 33 | else begin 34 | WriteLn('// Error: Couldn''t find files\server_i486.so.source!'); 35 | ReadLn; 36 | exit; 37 | end; 38 | if FileExists(ExtractFilePath(ParamStr(0)) + 'files\server.dll.orangebox') then 39 | WriteLn('// Found files\server.dll.orangebox') 40 | else begin 41 | WriteLn('// Error: Couldn''t find files\server.dll.orangebox!'); 42 | ReadLn; 43 | exit; 44 | end; 45 | if FileExists(ExtractFilePath(ParamStr(0)) + 'files\server_i486.so.orangebox') then 46 | WriteLn('// Found files\server_i486.so.orangebox') 47 | else begin 48 | WriteLn('// Error: Couldn''t find files\server_i486.so.orangebox!'); 49 | ReadLn; 50 | exit; 51 | end; 52 | if FileExists(ExtractFilePath(ParamStr(0)) + 'MMS_Installer.exe') then 53 | WriteLn('// Found MMS_Installer.exe') 54 | else begin 55 | WriteLn('// Error: Couldn''t find MMS_Installer.exe!'); 56 | ReadLn; 57 | exit; 58 | end; 59 | { Get version number } 60 | WriteLn('// Please enter the version number:'); 61 | ReadLn(Version); 62 | if (Trim(Version) = '') then begin 63 | WriteLn('// Error: Invalid version number!'); 64 | ReadLn; 65 | exit; 66 | end; 67 | { Compress files } 68 | WriteLn('// Compressing files...'); 69 | eFiles := TStringList.Create; 70 | eFiles.Add(ExtractFilePath(ParamStr(0)) + 'files\hl2launch.exe'); 71 | eFiles.Add(ExtractFilePath(ParamStr(0)) + 'files\server.dll.source'); 72 | eFiles.Add(ExtractFilePath(ParamStr(0)) + 'files\server_i486.so.source'); 73 | eFiles.Add(ExtractFilePath(ParamStr(0)) + 'files\server.dll.orangebox'); 74 | eFiles.Add(ExtractFilePath(ParamStr(0)) + 'files\server_i486.so.orangebox'); 75 | eStream := TMemoryStream.Create; 76 | CompressFiles(eFiles, ExtractFilePath(ParamStr(0)) + 'temp.zip'); 77 | eStream.LoadFromFile(ExtractFilePath(ParamStr(0)) + 'temp.zip'); 78 | WriteLn('// Attaching output to MMS_Installer.exe...'); 79 | AttachToFile(ExtractFilePath(ParamStr(0)) + 'MMS_Installer.exe', eStream, Version); 80 | DeleteFile(ExtractFilePath(ParamStr(0)) + 'temp.zip'); 81 | eStream.Free; 82 | eFiles.Free; 83 | WriteLn('// Done.'); 84 | ReadLn; 85 | end. 86 | -------------------------------------------------------------------------------- /cruft/installer/Attach.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alliedmodders/metamod-source/5d2bb7e206232879729a0b53aa6f289077977f3c/cruft/installer/Attach.exe -------------------------------------------------------------------------------- /cruft/installer/HL2Launch.cfg: -------------------------------------------------------------------------------- 1 | -$A8 2 | -$B- 3 | -$C+ 4 | -$D+ 5 | -$E- 6 | -$F- 7 | -$G+ 8 | -$H+ 9 | -$I+ 10 | -$J- 11 | -$K- 12 | -$L+ 13 | -$M- 14 | -$N+ 15 | -$O+ 16 | -$P+ 17 | -$Q- 18 | -$R- 19 | -$S- 20 | -$T- 21 | -$U- 22 | -$V+ 23 | -$W- 24 | -$X+ 25 | -$YD 26 | -$Z1 27 | -cg 28 | -AWinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE; 29 | -H+ 30 | -W+ 31 | -M 32 | -$M16384,1048576 33 | -K$00400000 34 | -LE"c:\programme\borland\delphi7\Projects\Bpl" 35 | -LN"c:\programme\borland\delphi7\Projects\Bpl" 36 | -w-UNSAFE_TYPE 37 | -w-UNSAFE_CODE 38 | -w-UNSAFE_CAST 39 | -------------------------------------------------------------------------------- /cruft/installer/HL2Launch.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alliedmodders/metamod-source/5d2bb7e206232879729a0b53aa6f289077977f3c/cruft/installer/HL2Launch.exe -------------------------------------------------------------------------------- /cruft/installer/MMS_Installer.cfg: -------------------------------------------------------------------------------- 1 | -$A8 2 | -$B- 3 | -$C+ 4 | -$D+ 5 | -$E- 6 | -$F- 7 | -$G+ 8 | -$H+ 9 | -$I+ 10 | -$J- 11 | -$K- 12 | -$L+ 13 | -$M- 14 | -$N+ 15 | -$O+ 16 | -$P+ 17 | -$Q- 18 | -$R- 19 | -$S- 20 | -$T- 21 | -$U- 22 | -$V+ 23 | -$W- 24 | -$X+ 25 | -$YD 26 | -$Z1 27 | -cg 28 | -AWinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE; 29 | -H+ 30 | -W+ 31 | -M 32 | -$M16384,1048576 33 | -K$00400000 34 | -LE"c:\program files\borland\delphi7\Projects\Bpl" 35 | -LN"c:\program files\borland\delphi7\Projects\Bpl" 36 | -w-UNSAFE_TYPE 37 | -w-UNSAFE_CODE 38 | -w-UNSAFE_CAST 39 | -------------------------------------------------------------------------------- /cruft/installer/MMS_Installer.dpr: -------------------------------------------------------------------------------- 1 | program MMS_Installer; 2 | 3 | { 4 | 5 | Metamod:Source installer is published under the zlib/libpng license, as well 6 | as Metamod:Source itself. You can find a copy of it below. 7 | 8 | --------- 9 | 10 | zLib/libpng License 11 | 12 | Copyright (c) 2007, Metamod:Source Development Team 13 | 14 | This software is provided 'as-is', without any express or implied warranty. 15 | In no event will the authors be held liable for any damages arising from the 16 | use of this software. 17 | 18 | Permission is granted to anyone to use this software for any purpose, 19 | including commercial applications, and to alter it and redistribute it freely, 20 | subject to the following restrictions: 21 | 22 | 1. The origin of this software must not be misrepresented; you must not 23 | claim that you wrote the original software. If you use this software in a 24 | product, an acknowledgment in the product documentation would be appreciated 25 | but is not required. 26 | 27 | 2. Altered source versions must be plainly marked as such, and must not be 28 | misrepresented as being the original software. 29 | 30 | 3. This notice may not be removed or altered from any source distribution. 31 | 32 | --------- 33 | 34 | Used components: 35 | 36 | - Indy 9 (www.indyproject.org) 37 | - FlatStyle Components (www.torry.net) 38 | - FlatPack Component Pack (www.torry.net) 39 | - JVCL Lib Pack 3.0 (jvcl.sourceforge.net) 40 | 41 | Half-Life 2 Icons by Vasili "vaksa" Vorotnikov, Thanks! 42 | Visit www.vaksa.net for further information 43 | 44 | } 45 | 46 | uses 47 | Forms, 48 | UnitfrmMain in 'UnitfrmMain.pas' {frmMain}, 49 | UnitFunctions in 'UnitFunctions.pas', 50 | UnitfrmProxy in 'UnitfrmProxy.pas' {frmProxy}, 51 | UnitInstall in 'UnitInstall.pas', 52 | UnitSelectModPath in 'UnitSelectModPath.pas' {frmSelectModPath}, 53 | UnitPackSystem in 'UnitPackSystem.pas'; 54 | 55 | {$R *.res} 56 | 57 | begin 58 | Application.Initialize; 59 | Application.Title := 'Metamod:Source Installer'; 60 | Application.CreateForm(TfrmMain, frmMain); 61 | UnitfrmMain.VERSION := GetVersion; 62 | frmMain.lblWelcome.Caption := 'Welcome to the Metamod:Source ' + VERSION + ' Setup Wizard'; 63 | frmMain.lblInfo1.Caption := 'This wizard will guide you through the installation of Metamod:Source ' + VERSION + '.'; 64 | frmMain.lblSubTitle1.Caption := 'Please review the following license terms before installing Metamod:Source ' + VERSION + '.'; 65 | frmMain.lblSelectModInfo.Caption := 'Please select the mod Metamod:Source ' + VERSION + ' shall be installed to.'; 66 | frmMain.lblTitle3.Caption := 'Installing Metamod:Source ' + VERSION + ' via FTP'; 67 | frmMain.lblTitle5.Caption := 'Installing Metamod:Source ' + VERSION; 68 | frmMain.lblSubTitle5.Caption := 'Please wait while Metamod:Source ' + VERSION + ' is being installed.'; 69 | Application.CreateForm(TfrmProxy, frmProxy); 70 | Application.CreateForm(TfrmSelectModPath, frmSelectModPath); 71 | Application.Run; 72 | end. 73 | -------------------------------------------------------------------------------- /cruft/installer/MMS_Installer.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alliedmodders/metamod-source/5d2bb7e206232879729a0b53aa6f289077977f3c/cruft/installer/MMS_Installer.exe -------------------------------------------------------------------------------- /cruft/installer/MMS_Installer.res: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alliedmodders/metamod-source/5d2bb7e206232879729a0b53aa6f289077977f3c/cruft/installer/MMS_Installer.res -------------------------------------------------------------------------------- /cruft/installer/UnitPackSystem.pas: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alliedmodders/metamod-source/5d2bb7e206232879729a0b53aa6f289077977f3c/cruft/installer/UnitPackSystem.pas -------------------------------------------------------------------------------- /cruft/installer/UnitSelectModPath.dfm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alliedmodders/metamod-source/5d2bb7e206232879729a0b53aa6f289077977f3c/cruft/installer/UnitSelectModPath.dfm -------------------------------------------------------------------------------- /cruft/installer/UnitSelectModPath.pas: -------------------------------------------------------------------------------- 1 | unit UnitSelectModPath; 2 | 3 | interface 4 | 5 | uses 6 | SysUtils, Windows, Messages, Classes, Graphics, Controls, 7 | StdCtrls, ExtCtrls, Forms, FileCtrl, ComCtrls, ShellCtrls, 8 | TFlatComboBoxUnit, TFlatButtonUnit; 9 | 10 | type 11 | TfrmSelectModPath = class(TForm) 12 | pnlDesign: TPanel; 13 | lblInfo: TLabel; 14 | trvDirectory: TShellTreeView; 15 | cmdOK: TFlatButton; 16 | cmdCancel: TFlatButton; 17 | end; 18 | 19 | var 20 | frmSelectModPath: TfrmSelectModPath; 21 | 22 | implementation 23 | 24 | {$R *.DFM} 25 | 26 | end. 27 | -------------------------------------------------------------------------------- /cruft/installer/UnitfrmProxy.dfm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alliedmodders/metamod-source/5d2bb7e206232879729a0b53aa6f289077977f3c/cruft/installer/UnitfrmProxy.dfm -------------------------------------------------------------------------------- /cruft/installer/UnitfrmProxy.pas: -------------------------------------------------------------------------------- 1 | unit UnitfrmProxy; 2 | 3 | interface 4 | 5 | uses 6 | SysUtils, Windows, Messages, Classes, Graphics, Controls, 7 | StdCtrls, ExtCtrls, Forms, TFlatButtonUnit, TFlatComboBoxUnit, 8 | TFlatEditUnit; 9 | 10 | type 11 | TfrmProxy = class(TForm) 12 | cmdClose: TFlatButton; 13 | lblProxy: TLabel; 14 | txtHost: TFlatEdit; 15 | cboProxy: TFlatComboBox; 16 | lblHost: TLabel; 17 | txtPort: TFlatEdit; 18 | lblPort: TLabel; 19 | lblUsername: TLabel; 20 | txtUsername: TFlatEdit; 21 | txtPassword: TFlatEdit; 22 | lblPassword: TLabel; 23 | procedure cboProxyChange(Sender: TObject); 24 | procedure txtPortChange(Sender: TObject); 25 | public 26 | procedure EnableControls(Enable: Boolean); 27 | end; 28 | 29 | var 30 | frmProxy: TfrmProxy; 31 | 32 | implementation 33 | 34 | {$R *.DFM} 35 | 36 | { TfrmProxy } 37 | 38 | procedure TfrmProxy.EnableControls(Enable: Boolean); 39 | begin 40 | lblHost.Enabled := Enable; 41 | lblPassword.Enabled := Enable; 42 | lblPort.Enabled := Enable; 43 | lblUsername.Enabled := Enable; 44 | txtHost.Enabled := Enable; 45 | txtPassword.Enabled := Enable; 46 | txtPort.Enabled := Enable; 47 | txtUsername.Enabled := Enable; 48 | end; 49 | 50 | procedure TfrmProxy.cboProxyChange(Sender: TObject); 51 | begin 52 | EnableControls(cboProxy.ItemIndex <> 0); // 0 = None 53 | end; 54 | 55 | procedure TfrmProxy.txtPortChange(Sender: TObject); 56 | var i: integer; 57 | begin 58 | if txtPort.Text = '' then 59 | txtPort.Text := '8080' 60 | else begin 61 | // check if value is numeric... 62 | for i := Length(txtPort.Text) downto 1 do begin 63 | if Pos(txtPort.Text[i], '0123456789') = 0 then begin 64 | txtPort.Text := '8080'; 65 | txtPort.SelStart := 4; 66 | exit; 67 | end; 68 | end; 69 | end; 70 | end; 71 | 72 | end. 73 | -------------------------------------------------------------------------------- /cruft/installer/del.bat: -------------------------------------------------------------------------------- 1 | del .\*.~pas 2 | del .\*.dcu 3 | del .\*.~ddp 4 | del .\*.ddp 5 | del .\*.~dpr 6 | del .\*.~dfm 7 | del .\*.~dpr 8 | del .\*.map 9 | del .\*.drc 10 | del .\*.~xfm 11 | del .\*.log 12 | del .\*.dof 13 | upx MMS_Installer.exe 14 | upx Attach.exe 15 | upx hl2launch.exe -------------------------------------------------------------------------------- /cruft/installer/files/Readme.txt: -------------------------------------------------------------------------------- 1 | This folder will be used by the attach binary. Make sure you have both the Source and OrangeBox binary in it. 2 | Here are some instructions on how to prepare an upcoming release: 3 | 4 | 1) Copy the latest MM:S dlls (Source+OrangeBox) and "hl2launch.exe" into this directory 5 | 2) Attach .source and .orangebox to the particular binaries. 6 | 3) Run Attach.exe 7 | 4) Test MMS_Installer.exe once (should work but nobody wants a buggy installer) 8 | 5) If everything worked fine, release it, otherwise pm me (Basic-Master) -------------------------------------------------------------------------------- /cruft/installer/install.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alliedmodders/metamod-source/5d2bb7e206232879729a0b53aa6f289077977f3c/cruft/installer/install.bmp -------------------------------------------------------------------------------- /cruft/installer/upx.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alliedmodders/metamod-source/5d2bb7e206232879729a0b53aa6f289077977f3c/cruft/installer/upx.exe -------------------------------------------------------------------------------- /loader/AMBuilder: -------------------------------------------------------------------------------- 1 | # vim: set ts=8 sts=2 sw=2 tw=99 et ft=python: 2 | import os.path 3 | 4 | def configure_library(cxx, name, linux_defines): 5 | libname = name 6 | binary = MMS.Library(cxx, libname) 7 | binary.compiler.cxxincludes += [os.path.join(builder.sourcePath, 'core', 'sourcehook')] 8 | binary.sources += [ 9 | 'loader.cpp', 10 | 'gamedll.cpp', 11 | 'serverplugin.cpp', 12 | 'utility.cpp', 13 | ] 14 | 15 | if binary.compiler.target.platform == 'linux': 16 | binary.compiler.defines += linux_defines 17 | 18 | nodes = builder.Add(binary) 19 | MMS.binaries += [nodes] 20 | 21 | for cxx in MMS.all_targets: 22 | if cxx.target.platform == 'linux': 23 | if cxx.target.arch == 'x86_64': 24 | configure_library(cxx, 'libserver', ['LIB_PREFIX="lib"', 'LIB_SUFFIX=".so"']) 25 | elif cxx.target.arch == 'x86': 26 | configure_library(cxx, 'server_i486', ['LIB_PREFIX=""', 'LIB_SUFFIX="_i486.so"']) 27 | configure_library(cxx, 'server', ['LIB_PREFIX=""', 'LIB_SUFFIX=".so"']) 28 | else: 29 | configure_library(cxx, 'server', []) 30 | -------------------------------------------------------------------------------- /loader/gamedll.h: -------------------------------------------------------------------------------- 1 | /** 2 | * vim: set ts=4 : 3 | * ====================================================== 4 | * Metamod:Source 5 | * Copyright (C) 2004-2008 AlliedModders LLC and authors. 6 | * All rights reserved. 7 | * ====================================================== 8 | * 9 | * This software is provided 'as-is', without any express or implied warranty. 10 | * In no event will the authors be held liable for any damages arising from 11 | * the use of this software. 12 | * 13 | * Permission is granted to anyone to use this software for any purpose, 14 | * including commercial applications, and to alter it and redistribute it 15 | * freely, subject to the following restrictions: 16 | * 17 | * 1. The origin of this software must not be misrepresented; you must not 18 | * claim that you wrote the original software. If you use this software in a 19 | * product, an acknowledgment in the product documentation would be 20 | * appreciated but is not required. 21 | * 2. Altered source versions must be plainly marked as such, and must not be 22 | * misrepresented as being the original software. 23 | * 3. This notice may not be removed or altered from any source distribution. 24 | * 25 | * Version: $Id$ 26 | */ 27 | 28 | #ifndef _INCLUDE_METAMOD_SOURCE_GAMEDLLS_H_ 29 | #define _INCLUDE_METAMOD_SOURCE_GAMEDLLS_H_ 30 | 31 | #include "loader_bridge.h" 32 | 33 | extern void * 34 | mm_GameDllRequest(const char *name, int *ret); 35 | 36 | extern IGameDllBridge* gamedll_bridge; 37 | 38 | #endif /* _INCLUDE_METAMOD_SOURCE_GAMEDLLS_H_ */ 39 | 40 | -------------------------------------------------------------------------------- /loader/loader.h: -------------------------------------------------------------------------------- 1 | /** 2 | * vim: set ts=4 sw=4 tw=99 noet : 3 | * ====================================================== 4 | * Metamod:Source 5 | * Copyright (C) 2004-2023 AlliedModders LLC and authors. 6 | * All rights reserved. 7 | * ====================================================== 8 | * 9 | * This software is provided 'as-is', without any express or implied warranty. 10 | * In no event will the authors be held liable for any damages arising from 11 | * the use of this software. 12 | * 13 | * Permission is granted to anyone to use this software for any purpose, 14 | * including commercial applications, and to alter it and redistribute it 15 | * freely, subject to the following restrictions: 16 | * 17 | * 1. The origin of this software must not be misrepresented; you must not 18 | * claim that you wrote the original software. If you use this software in a 19 | * product, an acknowledgment in the product documentation would be 20 | * appreciated but is not required. 21 | * 2. Altered source versions must be plainly marked as such, and must not be 22 | * misrepresented as being the original software. 23 | * 3. This notice may not be removed or altered from any source distribution. 24 | */ 25 | 26 | #ifndef _INCLUDE_METAMOD_SOURCE_LOADER_H_ 27 | #define _INCLUDE_METAMOD_SOURCE_LOADER_H_ 28 | 29 | // System 30 | #define SH_SYS_WIN32 1 31 | #define SH_SYS_LINUX 2 32 | #define SH_SYS_APPLE 3 33 | 34 | // Platform 35 | #define SH_XP_POSIX 10 36 | #define SH_XP_WINAPI 20 37 | 38 | // Compiler 39 | #define SH_COMP_GCC 1 40 | #define SH_COMP_MSVC 2 41 | 42 | #if defined WIN32 43 | #define SH_SYS SH_SYS_WIN32 44 | #define SH_XP SH_XP_WINAPI 45 | #define SH_COMP SH_COMP_MSVC 46 | #define WINDOWS_LEAN_AND_MEAN 47 | #include 48 | #include 49 | #define PLATFORM_MAX_PATH MAX_PATH 50 | #define PATH_SEP_STR "\\" 51 | #define PATH_SEP_CHAR '\\' 52 | #define ALT_SEP_CHAR '/' 53 | #elif defined __linux__ || defined __APPLE__ 54 | #if defined __linux__ 55 | #define SH_SYS SH_SYS_LINUX 56 | #elif defined __APPLE__ 57 | #define SH_SYS SH_SYS_APPLE 58 | #endif 59 | #define SH_XP SH_XP_POSIX 60 | #define SH_COMP SH_COMP_GCC 61 | #include 62 | #include 63 | #include 64 | #include 65 | #if SH_SYS == SH_SYS_APPLE 66 | #include 67 | #endif 68 | typedef void * HMODULE; 69 | #define PLATFORM_MAX_PATH PATH_MAX 70 | #define PATH_SEP_STR "/" 71 | #define PATH_SEP_CHAR '/' 72 | #define ALT_SEP_CHAR '\\' 73 | #else 74 | #error "OS detection failed" 75 | #endif 76 | 77 | #include "loader_bridge.h" 78 | 79 | #define SH_PTRSIZE sizeof(void*) 80 | 81 | enum MetamodBackend 82 | { 83 | MMBackend_Episode1 = 0, 84 | MMBackend_DarkMessiah, 85 | MMBackend_Episode2, 86 | MMBackend_BloodyGoodTime, 87 | MMBackend_EYE, 88 | MMBackend_CSS, 89 | MMBackend_Episode2Valve_OBSOLETE, 90 | MMBackend_Left4Dead, 91 | MMBackend_Left4Dead2, 92 | MMBackend_AlienSwarm, 93 | MMBackend_Portal2, 94 | MMBackend_CSGO, 95 | MMBackend_DOTA, 96 | MMBackend_HL2DM, 97 | MMBackend_DODS, 98 | MMBackend_TF2, 99 | MMBackend_NuclearDawn, 100 | MMBackend_SDK2013, 101 | MMBackend_Blade, 102 | MMBackend_Insurgency, 103 | MMBackend_Contagion, 104 | MMBackend_BMS, 105 | MMBackend_DOI, 106 | MMBackend_Mock, 107 | MMBackend_PVKII, 108 | MMBackend_MCV, 109 | MMBackend_CS2, 110 | MMBackend_Deadlock, 111 | MMBackend_UNKNOWN 112 | }; 113 | 114 | extern bool 115 | mm_LoadMetamodLibrary(MetamodBackend backend, char *buffer, size_t maxlength); 116 | 117 | extern void * 118 | mm_GetProcAddress(const char *name); 119 | 120 | extern void 121 | mm_UnloadMetamodLibrary(); 122 | 123 | extern void 124 | mm_LogFatal(const char *message, ...); 125 | 126 | extern void 127 | mm_GetGameName(char *buffer, size_t size); 128 | 129 | extern MetamodBackend 130 | mm_DetermineBackendS1(QueryValveInterface engineFactory, QueryValveInterface serverFactory, const char *game_name); 131 | 132 | extern MetamodBackend mm_backend; 133 | 134 | #endif /* _INCLUDE_METAMOD_SOURCE_LOADER_H_ */ 135 | 136 | -------------------------------------------------------------------------------- /loader/loader_bridge.h: -------------------------------------------------------------------------------- 1 | /** 2 | * vim: set ts=4 sw=4 tw=99 noet : 3 | * ====================================================== 4 | * Metamod:Source 5 | * Copyright (C) 2004-2009 AlliedModders LLC and authors. 6 | * All rights reserved. 7 | * ====================================================== 8 | * 9 | * This software is provided 'as-is', without any express or implied warranty. 10 | * In no event will the authors be held liable for any damages arising from 11 | * the use of this software. 12 | * 13 | * Permission is granted to anyone to use this software for any purpose, 14 | * including commercial applications, and to alter it and redistribute it 15 | * freely, subject to the following restrictions: 16 | * 17 | * 1. The origin of this software must not be misrepresented; you must not 18 | * claim that you wrote the original software. If you use this software in a 19 | * product, an acknowledgment in the product documentation would be 20 | * appreciated but is not required. 21 | * 2. Altered source versions must be plainly marked as such, and must not be 22 | * misrepresented as being the original software. 23 | * 3. This notice may not be removed or altered from any source distribution. 24 | */ 25 | 26 | #ifndef _INCLUDE_METAMOD_SOURCE_LOADER_BRIDGE_H_ 27 | #define _INCLUDE_METAMOD_SOURCE_LOADER_BRIDGE_H_ 28 | 29 | #include 30 | 31 | typedef void* (*QueryValveInterface)(const char *pName, int *pReturnCode); 32 | class IServerPluginCallbacks; 33 | 34 | struct vsp_bridge_info 35 | { 36 | QueryValveInterface engineFactory; 37 | QueryValveInterface gsFactory; 38 | IServerPluginCallbacks * vsp_callbacks; 39 | unsigned int vsp_version; 40 | }; 41 | 42 | class IVspBridge 43 | { 44 | public: 45 | virtual bool Load(const vsp_bridge_info *info, char *buffer, size_t maxlength) = 0; 46 | virtual void Unload() = 0; 47 | virtual const char *GetDescription() = 0; 48 | }; 49 | 50 | struct gamedll_bridge_info 51 | { 52 | QueryValveInterface engineFactory; 53 | QueryValveInterface fsFactory; 54 | QueryValveInterface physicsFactory; 55 | QueryValveInterface gsFactory; 56 | void * pGlobals; 57 | unsigned int dllVersion; 58 | const char * dllInterfaceName; 59 | void * isgd; 60 | const char * vsp_listener_path; 61 | }; 62 | 63 | class IGameDllBridge 64 | { 65 | public: 66 | virtual bool DLLInit_Pre(const gamedll_bridge_info *info, char *buffer, size_t maxlength) = 0; 67 | virtual void DLLInit_Post(int *isgdUnload) = 0; 68 | virtual void *QueryInterface(const char *name, int *ret) = 0; 69 | virtual void Unload() = 0; 70 | }; 71 | 72 | #endif /* _INCLUDE_METAMOD_SOURCE_LOADER_BRIDGE_H_ */ 73 | 74 | -------------------------------------------------------------------------------- /loader/serverplugin.h: -------------------------------------------------------------------------------- 1 | /** 2 | * vim: set ts=4 : 3 | * ====================================================== 4 | * Metamod:Source 5 | * Copyright (C) 2004-2008 AlliedModders LLC and authors. 6 | * All rights reserved. 7 | * ====================================================== 8 | * 9 | * This software is provided 'as-is', without any express or implied warranty. 10 | * In no event will the authors be held liable for any damages arising from 11 | * the use of this software. 12 | * 13 | * Permission is granted to anyone to use this software for any purpose, 14 | * including commercial applications, and to alter it and redistribute it 15 | * freely, subject to the following restrictions: 16 | * 17 | * 1. The origin of this software must not be misrepresented; you must not 18 | * claim that you wrote the original software. If you use this software in a 19 | * product, an acknowledgment in the product documentation would be 20 | * appreciated but is not required. 21 | * 2. Altered source versions must be plainly marked as such, and must not be 22 | * misrepresented as being the original software. 23 | * 3. This notice may not be removed or altered from any source distribution. 24 | * 25 | * Version: $Id$ 26 | */ 27 | 28 | #ifndef _INCLUDE_METAMOD_SOURCE_SERVERPLUGINS_H_ 29 | #define _INCLUDE_METAMOD_SOURCE_SERVERPLUGINS_H_ 30 | 31 | #include "loader_bridge.h" 32 | 33 | extern void * 34 | mm_GetVspCallbacks(unsigned int version); 35 | 36 | extern IVspBridge *vsp_bridge; 37 | 38 | #endif /* _INCLUDE_METAMOD_SOURCE_SERVERPLUGINS_H_ */ 39 | 40 | -------------------------------------------------------------------------------- /loader/test/AMBuilder: -------------------------------------------------------------------------------- 1 | # vim: set sts=2 ts=8 sw=2 tw=99 et ft=python: 2 | import os 3 | 4 | for cxx in MMS.all_targets: 5 | name = 'test_loader' 6 | binary = MMS.Program(cxx, name) 7 | 8 | # add some required defines for Linux builds 9 | if binary.compiler.target.platform == 'linux' and binary.compiler.target.arch == 'x86': 10 | binary.compiler.defines += ['LIB_PREFIX=""', 'LIB_SUFFIX="_i486.so"'] 11 | 12 | # add some required defines for Linux builds 13 | if binary.compiler.target.platform == 'linux' and binary.compiler.target.arch == 'x86_64': 14 | binary.compiler.defines += ['LIB_PREFIX="lib"', 'LIB_SUFFIX=".so"'] 15 | 16 | if binary.compiler.target.platform == 'linux': 17 | binary.compiler.linkflags += ['-ldl'] 18 | 19 | # TODO: something makes it try and compile with /SUBSYSTEM:WINDOWS which then causes it to complain that WinMain is missing 20 | if binary.compiler.target.platform == 'windows': 21 | binary.compiler.linkflags = ['kernel32.lib', 'shell32.lib'] 22 | 23 | binary.compiler.cxxincludes += [ 24 | os.path.join(builder.sourcePath, 'core'), 25 | os.path.join(builder.sourcePath, 'core', 'sourcehook'), 26 | os.path.join(builder.sourcePath, 'loader'), 27 | ] 28 | 29 | if binary.compiler.version >= 'gcc-4.9': 30 | binary.compiler.cxxflags += ['-fno-devirtualize'] 31 | if binary.compiler.version >= 'clang-2.9' or binary.compiler.version >= 'apple-clang-3.0': 32 | binary.compiler.cxxflags += ['-Wno-null-dereference'] 33 | 34 | binary.sources += [ 35 | 'main.cpp', 36 | '../gamedll.cpp', 37 | '../loader.cpp', 38 | '../serverplugin.cpp', 39 | '../utility.cpp', 40 | 'determinebackends1.cpp', 41 | 'testutility.cpp', 42 | ] 43 | 44 | builder.Add(binary) 45 | -------------------------------------------------------------------------------- /loader/test/README.md: -------------------------------------------------------------------------------- 1 | 2 | Building the tests 3 | ------------------ 4 | 5 | ``` 6 | mkdir build 7 | cd build/ 8 | python ../configure.py --sdks episode1 --enable-tests 9 | ambuild 10 | ``` 11 | 12 | Running the tests (Windows) 13 | --------------------------- 14 | 15 | ``` 16 | cd build/ 17 | loader/test/test_loader/windows-x86/test_loader.exe 18 | loader/test/test_loader/windows-x86_64/test_loader.exe 19 | ``` 20 | 21 | 22 | Runing the loader tests for `mm_DetermineBackendS1` (Windows) 23 | ------------------------------------------------------------- 24 | 25 | Using GitBash: 26 | ``` 27 | PATH="C:\Program Files (x86)\Steam\steamapps\common\Black Mesa\bin":"C:\Program Files (x86)\Steam\steamapps\common\Black Mesa\bms\bin":$PATH loader/test/test_loader/windows-x86/test_loader.exe -testdbs1 -gamedir bms -expectedbackend 21 28 | 29 | PATH="C:\Program Files (x86)\Steam\steamapps\common\Counter-Strike Global Offensive\bin":"C:\Program Files (x86)\Steam\steamapps\common\Counter-Strike Global Offensive\csgo\bin":$PATH loader/test/test_loader/windows-x86/test_loader.exe -testdbs1 -gamedir csgo -expectedbackend 11 30 | 31 | PATH="C:\Program Files (x86)\Steam\steamapps\common\Counter-Strike Source\bin\x64":"C:\Program Files (x86)\Steam\steamapps\common\Counter-Strike Source\cstrike\bin\x64":$PATH loader/test/test_loader/windows-x86_64/test_loader.exe -testdbs1 -gamedir cstrike -expectedbackend 5 32 | 33 | PATH="C:\Program Files (x86)\Steam\steamapps\common\Half-Life 2 Deathmatch\bin\x64":"C:\Program Files (x86)\Steam\steamapps\common\Half-Life 2 Deathmatch\hl2mp\bin\x64":$PATH loader/test/test_loader/windows-x86_64/test_loader.exe -testdbs1 -gamedir hl2mp -expectedbackend 13 34 | 35 | PATH="C:\Program Files (x86)\Steam\steamapps\common\Military Conflict - Vietnam\bin\win64":"C:\Program Files (x86)\Steam\steamapps\common\Military Conflict - Vietnam\vietnam\bin\win64":$PATH loader/test/test_loader/windows-x86_64/test_loader.exe -testdbs1 -gamedir vietnam -expectedbackend 25 36 | 37 | # NOTE: use Insurgency because server.dll in episodic/ doesn't load 38 | PATH="C:\Program Files (x86)\Steam\steamapps\common\Source SDK Base":"C:\Program Files (x86)\Steam\steamapps\common\Source SDK Base\bin":"C:\Program Files (x86)\Steam\steamapps\common\Source SDK Base\insurgency\bin":$PATH loader/test/test_loader/windows-x86/test_loader.exe -testdbs1 -gamedir insurgency -expectedbackend 0 39 | 40 | PATH="C:\Program Files (x86)\Steam\steamapps\common\Team Fortress 2\bin\x64":"C:\Program Files (x86)\Steam\steamapps\common\Team Fortress 2\tf\bin\x64":$PATH loader/test/test_loader/windows-x86_64/test_loader.exe -testdbs1 -gamedir tf -expectedbackend 15 41 | ``` 42 | 43 | Using PowerShell: 44 | ``` 45 | powershell -Command { $env:Path="C:\Program Files (x86)\Steam\steamapps\common\Black Mesa\bin;" + "C:\Program Files (x86)\Steam\steamapps\common\Black Mesa\bms\bin;" + $env:Path; .\loader\test\test_loader\windows-x86\test_loader.exe -testdbs1 -gamedir bms -expectedbackend 21 } 46 | 47 | powershell -Command { $env:Path="C:\Program Files (x86)\Steam\steamapps\common\Counter-Strike Source\bin\x64;" + "C:\Program Files (x86)\Steam\steamapps\common\Counter-Strike Source\cstrike\bin\x64;" + $env:Path; .\loader\test\test_loader\windows-x86_64\test_loader.exe -testdbs1 -gamedir cstrike -expectedbackend 5 } 48 | ``` -------------------------------------------------------------------------------- /loader/test/determinebackends1.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "loader.h" 4 | #include "utility.h" 5 | 6 | #if defined _WIN32 7 | #define SERVER_LIB_NAME "server.dll" 8 | #define ENGINE_LIB_NAME "engine.dll" 9 | #elif defined __linux__ 10 | #define SERVER_LIB_NAME "server" LIB_SUFFIX 11 | #define ENGINE_LIB_NAME "engine" LIB_SUFFIX 12 | #endif 13 | 14 | bool DetermineBackendS1(char *gameDir, int expectedBackend) 15 | { 16 | char errorBuffer[128]; 17 | void *serverLib = nullptr; 18 | void *engineLib = nullptr; 19 | QueryValveInterface serverQvi; 20 | QueryValveInterface engineQvi; 21 | 22 | std::cout << "Checking mm_DetermineBackendS1 with game directory " << gameDir << std::endl; 23 | 24 | // load the game code 25 | serverLib = mm_LoadLibrary(SERVER_LIB_NAME, errorBuffer, 128); 26 | 27 | if (serverLib == nullptr) 28 | { 29 | std::cout << "Error: mm_LoadLibrary server library " << SERVER_LIB_NAME << " " << errorBuffer << std::endl; 30 | return false; 31 | } 32 | 33 | serverQvi = (QueryValveInterface)mm_GetLibAddress(serverLib, "CreateInterface"); 34 | 35 | if (serverQvi == nullptr) 36 | { 37 | std::cout << "Error: Failed to find CreateInterface in server" << std::endl; 38 | return false; 39 | } 40 | 41 | // load the engine code 42 | engineLib = mm_LoadLibrary(ENGINE_LIB_NAME, errorBuffer, 128); 43 | 44 | if (engineLib == nullptr) 45 | { 46 | std::cout << "Error: mm_LoadLibrary engine library " << ENGINE_LIB_NAME << " " << errorBuffer << std::endl; 47 | return false; 48 | } 49 | 50 | engineQvi = (QueryValveInterface)mm_GetLibAddress(engineLib, "CreateInterface"); 51 | 52 | if (engineQvi == nullptr) 53 | { 54 | std::cout << "Error: Failed to find CreateInterface in engine" << std::endl; 55 | return false; 56 | } 57 | 58 | MetamodBackend actualBackend = mm_DetermineBackendS1(engineQvi, serverQvi, gameDir); 59 | 60 | if (actualBackend != expectedBackend) 61 | { 62 | std::cout << "Got MetamodBackend " << actualBackend << " instead of expected " << expectedBackend << std::endl; 63 | return false; 64 | } 65 | 66 | std::cout << "Got MetamodBackend " << expectedBackend << " as expected " << std::endl; 67 | return true; 68 | } 69 | -------------------------------------------------------------------------------- /loader/test/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #define DECL_TEST(x) bool Test##x(std::string &error); 8 | 9 | #define DO_TEST(x) \ 10 | error.clear(); \ 11 | if (Test##x(error)) \ 12 | { \ 13 | ++passed; \ 14 | std::cout << "Test" << #x << " passed" << std::endl; \ 15 | } \ 16 | else \ 17 | { \ 18 | ++failed; \ 19 | std::cout << "Test" << #x << " FAILED: " << error << std::endl; \ 20 | } \ 21 | 22 | 23 | bool DetermineBackendS1(char *gameDir, int expectedBackend); 24 | DECL_TEST(TrimComments); 25 | 26 | int main(int argc, char *argv[]) 27 | { 28 | bool testDetermineBackendS1 = false; 29 | char *gameDirectory = NULL; 30 | int expectedMetamodBackend = -1; 31 | 32 | for (int i = 0; i < argc; i++) 33 | { 34 | if (!strcmp(argv[i], "-testdbs1")) 35 | { 36 | testDetermineBackendS1 = true; 37 | } 38 | if (!strcmp(argv[i], "-gamedir") && argc > i + 1) 39 | { 40 | gameDirectory = argv[i + 1]; 41 | } 42 | if (!strcmp(argv[i], "-expectedbackend") && argc > i + 1) 43 | { 44 | expectedMetamodBackend = atoi(argv[i + 1]); 45 | } 46 | } 47 | 48 | if (testDetermineBackendS1) 49 | { 50 | bool success = DetermineBackendS1(gameDirectory, expectedMetamodBackend); 51 | // invert it because return code from main has 0 as success 52 | return success != true; 53 | } 54 | 55 | std::string error; 56 | int passed = 0, failed = 0; 57 | 58 | DO_TEST(TrimComments); 59 | 60 | std::cout << std::endl << "----" << std::endl << "Passed: " << passed << std::endl << "Failed: " << failed << std::endl; 61 | std::cout << "Total: " << passed + failed << std::endl; 62 | 63 | if (failed) 64 | return 1; 65 | return 0; 66 | } 67 | -------------------------------------------------------------------------------- /loader/test/testutility.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "utility.h" 4 | 5 | bool TestTrimComments(std::string &error) 6 | { 7 | char stringWithLeadingComment[32] = "// comment"; 8 | char stringWithTrailingComment[32] = "string //"; 9 | char stringWithNoComment[32] = "something"; 10 | 11 | mm_TrimComments(stringWithLeadingComment); 12 | 13 | if (strcmp(stringWithLeadingComment, "") !=0) 14 | { 15 | error = "Failed stringWithLeadingComment - got " + std::string(stringWithLeadingComment); 16 | return false; 17 | } 18 | 19 | mm_TrimComments(stringWithTrailingComment); 20 | 21 | if (strcmp(stringWithTrailingComment, "string ") !=0) 22 | { 23 | error = "Failed stringWithTrailingComment - got " + std::string(stringWithTrailingComment); 24 | return false; 25 | } 26 | 27 | mm_TrimComments(stringWithNoComment); 28 | 29 | if (strcmp(stringWithNoComment, "something") !=0) 30 | { 31 | error = "Failed stringWithNoComment - got " + std::string(stringWithNoComment); 32 | return false; 33 | } 34 | 35 | return true; 36 | } 37 | -------------------------------------------------------------------------------- /loader/test/version.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alliedmodders/metamod-source/5d2bb7e206232879729a0b53aa6f289077977f3c/loader/test/version.rc -------------------------------------------------------------------------------- /loader/utility.h: -------------------------------------------------------------------------------- 1 | /** 2 | * vim: set ts=4 : 3 | * ====================================================== 4 | * Metamod:Source 5 | * Copyright (C) 2004-2015 AlliedModders LLC and authors. 6 | * All rights reserved. 7 | * ====================================================== 8 | * 9 | * This software is provided 'as-is', without any express or implied warranty. 10 | * In no event will the authors be held liable for any damages arising from 11 | * the use of this software. 12 | * 13 | * Permission is granted to anyone to use this software for any purpose, 14 | * including commercial applications, and to alter it and redistribute it 15 | * freely, subject to the following restrictions: 16 | * 17 | * 1. The origin of this software must not be misrepresented; you must not 18 | * claim that you wrote the original software. If you use this software in a 19 | * product, an acknowledgment in the product documentation would be 20 | * appreciated but is not required. 21 | * 2. Altered source versions must be plainly marked as such, and must not be 22 | * misrepresented as being the original software. 23 | * 3. This notice may not be removed or altered from any source distribution. 24 | * 25 | * Version: $Id$ 26 | */ 27 | 28 | #ifndef _INCLUDE_METAMOD_SOURCE_LOADER_UTILITY_H_ 29 | #define _INCLUDE_METAMOD_SOURCE_LOADER_UTILITY_H_ 30 | 31 | #include 32 | 33 | extern size_t 34 | mm_Format(char *buffer, size_t maxlength, const char *fmt, ...); 35 | 36 | extern void * 37 | mm_LoadLibrary(const char *path, char *buffer, size_t maxlength); 38 | 39 | extern void * 40 | mm_GetLibAddress(void *lib, const char *name); 41 | 42 | extern void 43 | mm_UnloadLibrary(void *lib); 44 | 45 | extern bool 46 | mm_ResolvePath(const char *path, char *buffer, size_t maxlength, bool bSource2); 47 | 48 | extern size_t 49 | mm_PathFormat(char *buffer, size_t len, const char *fmt, ...); 50 | 51 | extern void 52 | mm_TrimLeft(char *buffer); 53 | 54 | extern void 55 | mm_TrimRight(char *buffer); 56 | 57 | extern void 58 | mm_TrimComments(char *buffer); 59 | 60 | extern void 61 | mm_KeySplit(const char *str, char *buf1, size_t len1, char *buf2, size_t len2); 62 | 63 | extern bool 64 | mm_PathCmp(const char *path1, const char *path2); 65 | 66 | extern bool 67 | mm_GetFileOfAddress(void *pAddr, char *buffer, size_t maxlength); 68 | 69 | extern void * 70 | mm_FindPattern(const void *libPtr, const char *pattern, size_t len); 71 | 72 | // True if arg is present, false if not. If arg has no value, buffer will be set to an empty string. 73 | extern bool 74 | mm_GetCommandArgument(const char *argName, char *buffer = nullptr, size_t maxlength = 0); 75 | 76 | #endif /* _INCLUDE_METAMOD_SOURCE_LOADER_UTILITY_H_ */ 77 | 78 | -------------------------------------------------------------------------------- /loader/version.rc: -------------------------------------------------------------------------------- 1 | // Microsoft Visual C++ generated resource script. 2 | // 3 | 4 | #define APSTUDIO_READONLY_SYMBOLS 5 | ///////////////////////////////////////////////////////////////////////////// 6 | // 7 | // Generated from the TEXTINCLUDE 2 resource. 8 | // 9 | #include "winres.h" 10 | #include 11 | 12 | ///////////////////////////////////////////////////////////////////////////// 13 | #undef APSTUDIO_READONLY_SYMBOLS 14 | 15 | ///////////////////////////////////////////////////////////////////////////// 16 | // English (U.S.) resources 17 | 18 | #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) 19 | #ifdef _WIN32 20 | LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US 21 | #pragma code_page(1252) 22 | #endif //_WIN32 23 | 24 | ///////////////////////////////////////////////////////////////////////////// 25 | // 26 | // Version 27 | // 28 | 29 | VS_VERSION_INFO VERSIONINFO 30 | FILEVERSION MMS_VERSION_FILE 31 | PRODUCTVERSION MMS_VERSION_FILE 32 | FILEFLAGSMASK 0x17L 33 | #ifdef _DEBUG 34 | FILEFLAGS 0x1L 35 | #else 36 | FILEFLAGS 0x0L 37 | #endif 38 | FILEOS 0x4L 39 | FILETYPE 0x2L 40 | FILESUBTYPE 0x0L 41 | BEGIN 42 | BLOCK "StringFileInfo" 43 | BEGIN 44 | BLOCK "000004b0" 45 | BEGIN 46 | VALUE "Comments", "Metamod: Source Loader" 47 | VALUE "FileDescription", "Metamod: Source Loader" 48 | VALUE "FileVersion", MMS_VERSION_STRING 49 | VALUE "InternalName", "mmsource" 50 | VALUE "LegalCopyright", "Copyright (c) 2004-2010, Metamod: Source Development Team" 51 | VALUE "OriginalFilename", BINARY_NAME 52 | VALUE "ProductName", "Metamod:Source Loader" 53 | VALUE "ProductVersion", MMS_VERSION_STRING 54 | END 55 | END 56 | BLOCK "VarFileInfo" 57 | BEGIN 58 | VALUE "Translation", 0x0, 1200 59 | END 60 | END 61 | 62 | 63 | #ifdef APSTUDIO_INVOKED 64 | ///////////////////////////////////////////////////////////////////////////// 65 | // 66 | // TEXTINCLUDE 67 | // 68 | 69 | 1 TEXTINCLUDE 70 | BEGIN 71 | "resource.h\0" 72 | END 73 | 74 | 2 TEXTINCLUDE 75 | BEGIN 76 | "#include ""winres.h""\r\n" 77 | "\0" 78 | END 79 | 80 | 3 TEXTINCLUDE 81 | BEGIN 82 | "\r\n" 83 | "\0" 84 | END 85 | 86 | #endif // APSTUDIO_INVOKED 87 | 88 | #endif // English (U.S.) resources 89 | ///////////////////////////////////////////////////////////////////////////// 90 | 91 | 92 | 93 | #ifndef APSTUDIO_INVOKED 94 | ///////////////////////////////////////////////////////////////////////////// 95 | // 96 | // Generated from the TEXTINCLUDE 3 resource. 97 | // 98 | 99 | 100 | ///////////////////////////////////////////////////////////////////////////// 101 | #endif // not APSTUDIO_INVOKED 102 | -------------------------------------------------------------------------------- /product.version: -------------------------------------------------------------------------------- 1 | 2.0.0-dev 2 | -------------------------------------------------------------------------------- /public/metamod_version.h: -------------------------------------------------------------------------------- 1 | /** 2 | * vim: set ts=4 sw=4 tw=99 noet : 3 | * ====================================================== 4 | * Metamod:Source 5 | * Copyright (C) 2004-2024 AlliedModders LLC and authors. 6 | * All rights reserved. 7 | * ====================================================== 8 | * 9 | * This software is provided 'as-is', without any express or implied warranty. 10 | * In no event will the authors be held liable for any damages arising from 11 | * the use of this software. 12 | * 13 | * Permission is granted to anyone to use this software for any purpose, 14 | * including commercial applications, and to alter it and redistribute it 15 | * freely, subject to the following restrictions: 16 | * 17 | * 1. The origin of this software must not be misrepresented; you must not 18 | * claim that you wrote the original software. If you use this software in a 19 | * product, an acknowledgment in the product documentation would be 20 | * appreciated but is not required. 21 | * 2. Altered source versions must be plainly marked as such, and must not be 22 | * misrepresented as being the original software. 23 | * 3. This notice may not be removed or altered from any source distribution. 24 | */ 25 | 26 | #ifndef _INCLUDE_METAMOD_VERSION_INFORMATION_H_ 27 | #define _INCLUDE_METAMOD_VERSION_INFORMATION_H_ 28 | 29 | /** 30 | * @file Contains Metamod version information. 31 | * @brief This file will redirect to an autogenerated version if being compiled via 32 | * the build scripts. 33 | */ 34 | 35 | #if defined MMS_GENERATED_BUILD 36 | # if defined RC_COMPILE 37 | # undef MMS_USE_VERSIONLIB 38 | # endif 39 | # if defined MMS_USE_VERSIONLIB 40 | # include "versionlib.h" 41 | # else 42 | # include "metamod_version_auto.h" 43 | # endif 44 | #else 45 | #define MMS_BUILD_TAG "manual" 46 | #define MMS_BUILD_LOCAL_REV "0" 47 | #define MMS_BUILD_CSET "0" 48 | #define MMS_BUILD_MAJOR "2" 49 | #define MMS_BUILD_MINOR "0" 50 | #define MMS_BUILD_RELEASE "0" 51 | 52 | #define MMS_BUILD_UNIQUEID MMS_BUILD_LOCAL_REV ":" MMS_BUILD_CSET 53 | 54 | #define MMS_VERSION_STRING MMS_BUILD_MAJOR "." MMS_BUILD_MINOR "." MMS_BUILD_RELEASE "-" MMS_BUILD_TAG 55 | #define MMS_VERSION_FILE 2,0,0,0 56 | #endif 57 | #define MMS_BUILD_TIMESTAMP __DATE__ " " __TIME__ 58 | 59 | #if !defined(MMS_GENERATED_BUILD) || !defined(MMS_USE_VERSIONLIB) 60 | # define METAMOD_VERSION MMS_VERSION_STRING 61 | # define METAMOD_BUILD_ID MMS_BUILD_UNIQUEID 62 | # define METAMOD_BUILD_TIME MMS_BUILD_TIMESTAMP 63 | #endif 64 | 65 | #endif /* _INCLUDE_METAMOD_VERSION_INFORMATION_H_ */ 66 | 67 | -------------------------------------------------------------------------------- /pushbuild.txt: -------------------------------------------------------------------------------- 1 | MM:S and SM load on Portal on Mac OS X. How cool is that?? 2 | It would be cool if the OS X package uploaded though. 3 | Burgledorfs and blaggermuffins are among the king's favourites. 4 | Ten ticket takers tackled two terrible tyrants. 5 | There once was a 6 | Breaking builds, one push at a time. 7 | Thanks for more IFileSystem breakage. 8 | Bloody, missing sdk! 9 | yur an ISource2Serverrr 10 | hats 11 | oh, i'll get it right this time 12 | I'd be angry. 13 | rum hom! 14 | bees 🐝 bees bees? 15 | oh, it's so cute. she calls it a mayonegg 16 | Why is Windows so awful? 17 | cleng cling clang clung clong 18 | javaliabuf™️ 19 | 🥚. 20 | pulled pork, yeah... 21 | king of the javalias 22 | ducks versus geese, who will win? 23 | more like g_pBa 24 | I didn't have any dreams. 25 | Eat your potato, Ricky! 26 | Buildbot shall pay the iron price. 27 | BMO Chop! If this was a real attack, you'd be dead. 28 | Hey Morty! 29 | jam clam! 30 | her? 31 | Confused clams claim clowns clobber clans containing cloaked clients. 32 | Beads 33 | We've have it all! 34 | dvander is one million ladies tall today... 35 | Your tier1 tower is under attack! 36 | Christmas! 37 | is Skinny Pete any relation to Sneaky Pete??? 38 | where Travis? 39 | msvc2015, take two 40 | "something witty" - Fishy! 41 | thisisawfuldotnetcom 42 | iluvwomen99 43 | Hi all, I'm new in here!!! 44 | -------------------------------------------------------------------------------- /samples/s1_sample_mm/README.md: -------------------------------------------------------------------------------- 1 | For more information on compiling and reading the plugin's source code, see: 2 | 3 | http://wiki.alliedmods.net/Category:Metamod:Source_Development 4 | 5 | Build instructions 6 | ------------------ 7 | 8 | Make sure ambuild2 is installed: https://github.com/alliedmodders/ambuild 9 | 10 | Configure the build (`--hl2sdk-root` specifies the path where the all SDKs have been installed by `support/checkout-deps.sh` and `--mms_path` is the path to Metamod: Source). 11 | 12 | If you only want to compile using a specific SDK you can hack around the requirement to build for all SDKs by modifying the calls to the SDK constructor in the assignment to `PossibleSDKs` in `AMBuildScript` and setting the `platforms` parameter to \[\] for all SDKs that you don't want to compile for. 13 | 14 | ### Windows 15 | 16 | Use Command Prompt as Gitbash doesn't handle the path arguments correctly. 17 | 18 | ``` 19 | mkdir build 20 | cd build 21 | python ../configure.py --hl2sdk-root C:\Users\user\Documents\GitHub --mms_path C:\Users\user\Documents\GitHub\metamod-source 22 | ``` 23 | 24 | Build: 25 | ``` 26 | ambuild 27 | ``` -------------------------------------------------------------------------------- /samples/s1_sample_mm/configure.py: -------------------------------------------------------------------------------- 1 | import sys 2 | try: 3 | from ambuild2 import run, util 4 | except: 5 | try: 6 | import ambuild 7 | sys.stderr.write('It looks like you have AMBuild 1 installed, but this project uses AMBuild 2.\n') 8 | sys.stderr.write('Upgrade to the latest version of AMBuild to continue.\n') 9 | except: 10 | sys.stderr.write('AMBuild must be installed to build this project.\n') 11 | sys.stderr.write('http://www.alliedmods.net/ambuild\n') 12 | sys.exit(1) 13 | 14 | def make_objdir_name(p): 15 | return 'obj-' + util.Platform() + '-' + p.target_arch 16 | 17 | parser = run.BuildParser(sourcePath=sys.path[0], api='2.1') 18 | parser.default_arch = 'x86' 19 | parser.default_build_folder = make_objdir_name 20 | parser.options.add_option('--hl2sdk-root', type=str, dest='hl2sdk_root', default=None, 21 | help='Root search folder for HL2SDKs') 22 | parser.options.add_option('--mms_path', type=str, dest='mms_path', default=None, 23 | help='Metamod:Source source tree folder') 24 | parser.options.add_option('--enable-debug', action='store_const', const='1', dest='debug', 25 | help='Enable debugging symbols') 26 | parser.options.add_option('--enable-optimize', action='store_const', const='1', dest='opt', 27 | help='Enable optimization') 28 | parser.options.add_option('-s', '--sdks', default='all', dest='sdks', 29 | help='Build against specified SDKs; valid args are "all", "present", or ' 30 | 'comma-delimited list of engine names (default: %default)') 31 | parser.options.add_option('--enable-tests', default=False, dest='enable_tests', action='store_true', 32 | help='Build tests.') 33 | parser.Configure() 34 | -------------------------------------------------------------------------------- /samples/s1_sample_mm/engine_wrappers.h: -------------------------------------------------------------------------------- 1 | /** 2 | * vim: set ts=4 sw=4 tw=99 noet : 3 | * ====================================================== 4 | * Metamod:Source Sample Plugin 5 | * Written by AlliedModders LLC. 6 | * ====================================================== 7 | * 8 | * This software is provided 'as-is', without any express or implied warranty. 9 | * In no event will the authors be held liable for any damages arising from 10 | * the use of this software. 11 | * 12 | * This sample plugin is public domain. 13 | */ 14 | 15 | #ifndef _INCLUDE_SOURCE_ENGINE_WRAPPERS_ 16 | #define _INCLUDE_SOURCE_ENGINE_WRAPPERS_ 17 | 18 | #include 19 | 20 | extern IVEngineServer *engine; 21 | extern CGlobalVars *gpGlobals; 22 | 23 | #define ENGINE_CALL(func) SH_CALL(engine, &IVEngineServer::func) 24 | 25 | /** 26 | * Wrap some API calls for legacy MM:S. 27 | */ 28 | #if !defined METAMOD_PLAPI_VERSION 29 | #define GetEngineFactory engineFactory 30 | #define GetServerFactory serverFactory 31 | #define MM_Format snprintf 32 | #define GetCGlobals pGlobals 33 | #else 34 | #define MM_Format g_SMAPI->Format 35 | #endif 36 | 37 | #if SOURCE_ENGINE <= SE_DARKMESSIAH 38 | /** 39 | * Wrap the CCommand class so our code looks the same on all engines. 40 | */ 41 | class CCommand 42 | { 43 | public: 44 | const char *ArgS() 45 | { 46 | return engine->Cmd_Args(); 47 | } 48 | int ArgC() 49 | { 50 | return engine->Cmd_Argc(); 51 | } 52 | 53 | const char *Arg(int index) 54 | { 55 | return engine->Cmd_Argv(index); 56 | } 57 | }; 58 | 59 | #define CVAR_INTERFACE_VERSION VENGINE_CVAR_INTERFACE_VERSION 60 | #endif 61 | 62 | /** 63 | * Left 4 Dead engine removed these from IVEngineServer. 64 | */ 65 | #if SOURCE_ENGINE >= SE_LEFT4DEAD 66 | 67 | inline int IndexOfEdict(const edict_t *pEdict) 68 | { 69 | return (int)(pEdict - gpGlobals->pEdicts); 70 | } 71 | inline edict_t *PEntityOfEntIndex(int iEntIndex) 72 | { 73 | if (iEntIndex >= 0 && iEntIndex < gpGlobals->maxEntities) 74 | { 75 | return (edict_t *)(gpGlobals->pEdicts + iEntIndex); 76 | } 77 | return NULL; 78 | } 79 | 80 | #else 81 | 82 | inline int IndexOfEdict(const edict_t *pEdict) 83 | { 84 | return engine->IndexOfEdict(pEdict); 85 | } 86 | inline edict_t *PEntityOfEntIndex(int iEntIndex) 87 | { 88 | return engine->PEntityOfEntIndex(iEntIndex); 89 | } 90 | 91 | #endif 92 | 93 | #endif //_INCLUDE_SOURCE_ENGINE_WRAPPERS_ 94 | 95 | -------------------------------------------------------------------------------- /samples/s1_sample_mm/msvc10/sample_mm.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | 24 | Header Files 25 | 26 | 27 | Header Files 28 | 29 | 30 | -------------------------------------------------------------------------------- /samples/s1_sample_mm/product.version: -------------------------------------------------------------------------------- 1 | 0.1.0 2 | -------------------------------------------------------------------------------- /samples/s1_sample_mm/sample_mm.h: -------------------------------------------------------------------------------- 1 | /** 2 | * vim: set ts=4 sw=4 tw=99 noet : 3 | * ====================================================== 4 | * Metamod:Source Sample Plugin 5 | * Written by AlliedModders LLC. 6 | * ====================================================== 7 | * 8 | * This software is provided 'as-is', without any express or implied warranty. 9 | * In no event will the authors be held liable for any damages arising from 10 | * the use of this software. 11 | * 12 | * This sample plugin is public domain. 13 | */ 14 | 15 | #ifndef _INCLUDE_METAMOD_SOURCE_STUB_PLUGIN_H_ 16 | #define _INCLUDE_METAMOD_SOURCE_STUB_PLUGIN_H_ 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include "engine_wrappers.h" 23 | 24 | #if defined WIN32 && !defined snprintf 25 | #define snprintf _snprintf 26 | #endif 27 | 28 | class SamplePlugin : public ISmmPlugin, public IMetamodListener 29 | { 30 | public: 31 | bool Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen, bool late); 32 | bool Unload(char *error, size_t maxlen); 33 | bool Pause(char *error, size_t maxlen); 34 | bool Unpause(char *error, size_t maxlen); 35 | void AllPluginsLoaded(); 36 | public: //IMetamodListener stuff 37 | void OnVSPListening(IServerPluginCallbacks *iface); 38 | public: //hooks 39 | void Hook_ServerActivate(edict_t *pEdictList, int edictCount, int clientMax); 40 | bool Hook_LevelInit(const char *pMapName, 41 | char const *pMapEntities, 42 | char const *pOldLevel, 43 | char const *pLandmarkName, 44 | bool loadGame, 45 | bool background); 46 | void Hook_GameFrame(bool simulating); 47 | void Hook_LevelShutdown(void); 48 | void Hook_ClientActive(edict_t *pEntity, bool bLoadGame); 49 | void Hook_ClientDisconnect(edict_t *pEntity); 50 | void Hook_ClientPutInServer(edict_t *pEntity, char const *playername); 51 | void Hook_SetCommandClient(int index); 52 | void Hook_ClientSettingsChanged(edict_t *pEdict); 53 | bool Hook_ClientConnect(edict_t *pEntity, 54 | const char *pszName, 55 | const char *pszAddress, 56 | char *reject, 57 | int maxrejectlen); 58 | #if SOURCE_ENGINE >= SE_ORANGEBOX 59 | void Hook_ClientCommand(edict_t *pEntity, const CCommand &args); 60 | #else 61 | void Hook_ClientCommand(edict_t *pEntity); 62 | #endif 63 | public: 64 | const char *GetAuthor(); 65 | const char *GetName(); 66 | const char *GetDescription(); 67 | const char *GetURL(); 68 | const char *GetLicense(); 69 | const char *GetVersion(); 70 | const char *GetDate(); 71 | const char *GetLogTag(); 72 | }; 73 | 74 | extern SamplePlugin g_SamplePlugin; 75 | 76 | PLUGIN_GLOBALVARS(); 77 | 78 | #endif //_INCLUDE_METAMOD_SOURCE_STUB_PLUGIN_H_ 79 | -------------------------------------------------------------------------------- /samples/s1_sample_mm/sample_mm.vdf: -------------------------------------------------------------------------------- 1 | "Metamod Plugin" 2 | { 3 | "alias" "sample" 4 | "file" "addons/sample_mm" 5 | } 6 | -------------------------------------------------------------------------------- /samples/s1_stub_mm/README.md: -------------------------------------------------------------------------------- 1 | For more information on compiling and reading the plugin's source code, see: 2 | 3 | http://wiki.alliedmods.net/Category:Metamod:Source_Development 4 | 5 | -------------------------------------------------------------------------------- /samples/s1_stub_mm/msvc10/stub_mm.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | 24 | Header Files 25 | 26 | 27 | -------------------------------------------------------------------------------- /samples/s1_stub_mm/stub_mm.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * vim: set ts=4 sw=4 tw=99 noet : 3 | * ====================================================== 4 | * Metamod:Source Stub Plugin 5 | * Written by AlliedModders LLC. 6 | * ====================================================== 7 | * 8 | * This software is provided 'as-is', without any express or implied warranty. 9 | * In no event will the authors be held liable for any damages arising from 10 | * the use of this software. 11 | * 12 | * This stub plugin is public domain. 13 | */ 14 | 15 | #include 16 | #include "stub_mm.h" 17 | 18 | SH_DECL_HOOK3_void(IServerGameDLL, ServerActivate, SH_NOATTRIB, 0, edict_t *, int, int); 19 | 20 | StubPlugin g_StubPlugin; 21 | IServerGameDLL *server = NULL; 22 | 23 | PLUGIN_EXPOSE(StubPlugin, g_StubPlugin); 24 | bool StubPlugin::Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen, bool late) 25 | { 26 | PLUGIN_SAVEVARS(); 27 | 28 | /* Make sure we build on MM:S 1.4 */ 29 | #if defined METAMOD_PLAPI_VERSION 30 | GET_V_IFACE_ANY(GetServerFactory, server, IServerGameDLL, INTERFACEVERSION_SERVERGAMEDLL); 31 | #else 32 | GET_V_IFACE_ANY(serverFactory, server, IServerGameDLL, INTERFACEVERSION_SERVERGAMEDLL); 33 | #endif 34 | 35 | SH_ADD_HOOK_STATICFUNC(IServerGameDLL, ServerActivate, server, Hook_ServerActivate, true); 36 | 37 | return true; 38 | } 39 | 40 | bool StubPlugin::Unload(char *error, size_t maxlen) 41 | { 42 | SH_REMOVE_HOOK_STATICFUNC(IServerGameDLL, ServerActivate, server, Hook_ServerActivate, true); 43 | 44 | return true; 45 | } 46 | 47 | void Hook_ServerActivate(edict_t *pEdictList, int edictCount, int clientMax) 48 | { 49 | META_LOG(g_PLAPI, "ServerActivate() called: edictCount = %d, clientMax = %d", edictCount, clientMax); 50 | } 51 | 52 | void StubPlugin::AllPluginsLoaded() 53 | { 54 | /* This is where we'd do stuff that relies on the mod or other plugins 55 | * being initialized (for example, cvars added and events registered). 56 | */ 57 | } 58 | 59 | bool StubPlugin::Pause(char *error, size_t maxlen) 60 | { 61 | return true; 62 | } 63 | 64 | bool StubPlugin::Unpause(char *error, size_t maxlen) 65 | { 66 | return true; 67 | } 68 | 69 | const char *StubPlugin::GetLicense() 70 | { 71 | return "Public Domain"; 72 | } 73 | 74 | const char *StubPlugin::GetVersion() 75 | { 76 | return "1.0.0.0"; 77 | } 78 | 79 | const char *StubPlugin::GetDate() 80 | { 81 | return __DATE__; 82 | } 83 | 84 | const char *StubPlugin::GetLogTag() 85 | { 86 | return "STUB"; 87 | } 88 | 89 | const char *StubPlugin::GetAuthor() 90 | { 91 | return "AlliedModders LLC"; 92 | } 93 | 94 | const char *StubPlugin::GetDescription() 95 | { 96 | return "Sample empty plugin"; 97 | } 98 | 99 | const char *StubPlugin::GetName() 100 | { 101 | return "Stub Plugin"; 102 | } 103 | 104 | const char *StubPlugin::GetURL() 105 | { 106 | return "http://www.sourcemm.net/"; 107 | } 108 | -------------------------------------------------------------------------------- /samples/s1_stub_mm/stub_mm.h: -------------------------------------------------------------------------------- 1 | /** 2 | * vim: set ts=4 sw=4 tw=99 noet : 3 | * ====================================================== 4 | * Metamod:Source Stub Plugin 5 | * Written by AlliedModders LLC. 6 | * ====================================================== 7 | * 8 | * This software is provided 'as-is', without any express or implied warranty. 9 | * In no event will the authors be held liable for any damages arising from 10 | * the use of this software. 11 | * 12 | * This stub plugin is public domain. 13 | */ 14 | 15 | #ifndef _INCLUDE_METAMOD_SOURCE_STUB_PLUGIN_H_ 16 | #define _INCLUDE_METAMOD_SOURCE_STUB_PLUGIN_H_ 17 | 18 | #include 19 | 20 | #if defined WIN32 && !defined snprintf 21 | #define snprintf _snprintf 22 | #endif 23 | 24 | class StubPlugin : public ISmmPlugin 25 | { 26 | public: 27 | bool Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen, bool late); 28 | bool Unload(char *error, size_t maxlen); 29 | bool Pause(char *error, size_t maxlen); 30 | bool Unpause(char *error, size_t maxlen); 31 | void AllPluginsLoaded(); 32 | public: 33 | const char *GetAuthor(); 34 | const char *GetName(); 35 | const char *GetDescription(); 36 | const char *GetURL(); 37 | const char *GetLicense(); 38 | const char *GetVersion(); 39 | const char *GetDate(); 40 | const char *GetLogTag(); 41 | }; 42 | 43 | void Hook_ServerActivate(edict_t *pEdictList, int edictCount, int clientMax); 44 | 45 | extern StubPlugin g_StubPlugin; 46 | 47 | PLUGIN_GLOBALVARS(); 48 | 49 | #endif //_INCLUDE_METAMOD_SOURCE_STUB_PLUGIN_H_ 50 | -------------------------------------------------------------------------------- /samples/s1_stub_mm/stub_mm.vdf: -------------------------------------------------------------------------------- 1 | "Metamod Plugin" 2 | { 3 | "alias" "stub" 4 | "file" "addons/stub_mm" 5 | } 6 | -------------------------------------------------------------------------------- /samples/s2_sample_mm/AMBuilder: -------------------------------------------------------------------------------- 1 | # vim: set sts=2 ts=8 sw=2 tw=99 et ft=python: 2 | import os 3 | 4 | # Here only one sdk should be available to generate only one executable in the end, 5 | # as multi-sdk loading isn't supported out of the box by metamod, and would require specifying the full path in the vdf 6 | # which in the end would ruin the multi-platform (unix, win etc) loading by metamod as it won't be able to append platform specific extension 7 | # so just fall back to the single binary. 8 | # Multi-sdk solutions should be manually loaded with a custom plugin loader (examples being sourcemod, stripper:source) 9 | for sdk_target in MMSPlugin.sdk_targets: 10 | sdk = sdk_target.sdk 11 | cxx = sdk_target.cxx 12 | 13 | binary = MMSPlugin.HL2Library(builder, cxx, MMSPlugin.plugin_name, sdk) 14 | 15 | binary.sources += [ 16 | 'sample_mm.cpp', 17 | ] 18 | 19 | binary.custom = [builder.tools.Protoc(protoc = sdk_target.protoc, sources = [ 20 | os.path.join(sdk['path'], 'common', 'network_connection.proto'), 21 | ])] 22 | 23 | nodes = builder.Add(binary) 24 | MMSPlugin.binaries += [nodes] 25 | -------------------------------------------------------------------------------- /samples/s2_sample_mm/PackageScript: -------------------------------------------------------------------------------- 1 | # vim: set ts=2 sw=2 tw=99 noet ft=python: 2 | import os 3 | 4 | builder.SetBuildFolder('package') 5 | 6 | metamod_folder = builder.AddFolder(os.path.join('addons', 'metamod')) 7 | bin_folder_path = os.path.join('addons', MMSPlugin.plugin_name, 'bin') 8 | bin_folder = builder.AddFolder(bin_folder_path) 9 | 10 | for cxx in MMSPlugin.all_targets: 11 | if cxx.target.arch == 'x86_64': 12 | if cxx.target.platform == 'windows': 13 | bin64_folder_path = os.path.join('addons', MMSPlugin.plugin_name, 'bin', 'win64') 14 | bin64_folder = builder.AddFolder(bin64_folder_path) 15 | elif cxx.target.platform == 'linux': 16 | bin64_folder_path = os.path.join('addons', MMSPlugin.plugin_name, 'bin', 'linuxsteamrt64') 17 | bin64_folder = builder.AddFolder(bin64_folder_path) 18 | elif cxx.target.platform == 'mac': 19 | bin64_folder_path = os.path.join('addons', MMSPlugin.plugin_name, 'bin', 'osx64') 20 | bin64_folder = builder.AddFolder(bin64_folder_path) 21 | 22 | pdb_list = [] 23 | for task in MMSPlugin.binaries: 24 | # This hardly assumes there's only 1 targetted platform and would be overwritten 25 | # with whatever comes last if multiple are used! 26 | with open(os.path.join(builder.buildPath, MMSPlugin.plugin_name + '.vdf'), 'w') as fp: 27 | fp.write('"Metamod Plugin"\n') 28 | fp.write('{\n') 29 | fp.write(f'\t"alias"\t"{MMSPlugin.plugin_alias}"\n') 30 | if task.target.arch == 'x86_64': 31 | fp.write(f'\t"file"\t"{os.path.join(bin64_folder_path, MMSPlugin.plugin_name)}"\n') 32 | else: 33 | fp.write(f'\t"file"\t"{os.path.join(bin_folder_path, MMSPlugin.plugin_name)}"\n') 34 | fp.write('}\n') 35 | 36 | if task.target.arch == 'x86_64': 37 | builder.AddCopy(task.binary, bin64_folder) 38 | else: 39 | builder.AddCopy(task.binary, bin_folder) 40 | 41 | if task.debug: 42 | pdb_list.append(task.debug) 43 | 44 | builder.AddCopy(os.path.join(builder.buildPath, MMSPlugin.plugin_name + '.vdf'), metamod_folder) 45 | 46 | # Generate PDB info. 47 | with open(os.path.join(builder.buildPath, 'pdblog.txt'), 'wt') as fp: 48 | for line in pdb_list: 49 | fp.write(line.path + '\n') -------------------------------------------------------------------------------- /samples/s2_sample_mm/configure.py: -------------------------------------------------------------------------------- 1 | # vim: set sts=2 ts=8 sw=2 tw=99 et: 2 | import sys 3 | try: 4 | from ambuild2 import run, util 5 | except: 6 | try: 7 | import ambuild 8 | sys.stderr.write('It looks like you have AMBuild 1 installed, but this project uses AMBuild 2.\n') 9 | sys.stderr.write('Upgrade to the latest version of AMBuild to continue.\n') 10 | except: 11 | sys.stderr.write('AMBuild must be installed to build this project.\n') 12 | sys.stderr.write('http://www.alliedmods.net/ambuild\n') 13 | sys.exit(1) 14 | 15 | # Hack to show a decent upgrade message, which wasn't done until 2.2. 16 | ambuild_version = getattr(run, 'CURRENT_API', '2.1') 17 | if ambuild_version.startswith('2.1'): 18 | sys.stderr.write("AMBuild 2.2 or higher is required; please update\n") 19 | sys.exit(1) 20 | 21 | parser = run.BuildParser(sourcePath=sys.path[0], api='2.2') 22 | parser.options.add_argument('-n', '--plugin-name', type=str, dest='plugin_name', default=None, 23 | help='Plugin name') 24 | parser.options.add_argument('-a', '--plugin-alias', type=str, dest='plugin_alias', default=None, 25 | help='Plugin alias') 26 | parser.options.add_argument('--hl2sdk-root', type=str, dest='hl2sdk_root', default=None, 27 | help='Root search folder for HL2SDKs') 28 | parser.options.add_argument('--hl2sdk-manifests', type=str, dest='hl2sdk_manifests', default=None, 29 | help='HL2SDK manifests source tree folder') 30 | parser.options.add_argument('--mms_path', type=str, dest='mms_path', default=None, 31 | help='Metamod:Source source tree folder') 32 | parser.options.add_argument('--enable-debug', action='store_const', const='1', dest='debug', 33 | help='Enable debugging symbols') 34 | parser.options.add_argument('--enable-optimize', action='store_const', const='1', dest='opt', 35 | help='Enable optimization') 36 | parser.options.add_argument('-s', '--sdks', default='all', dest='sdks', 37 | help='Build against specified SDKs; valid args are "all", "present", or ' 38 | 'comma-delimited list of engine names (default: "all")') 39 | parser.options.add_argument('--targets', type=str, dest='targets', default=None, 40 | help="Override the target architecture (use commas to separate multiple targets).") 41 | parser.Configure() 42 | -------------------------------------------------------------------------------- /samples/s2_sample_mm/sample_mm.h: -------------------------------------------------------------------------------- 1 | /** 2 | * vim: set ts=4 sw=4 tw=99 noet : 3 | * ====================================================== 4 | * Metamod:Source Sample Plugin 5 | * Written by AlliedModders LLC. 6 | * ====================================================== 7 | * 8 | * This software is provided 'as-is', without any express or implied warranty. 9 | * In no event will the authors be held liable for any damages arising from 10 | * the use of this software. 11 | * 12 | * This sample plugin is public domain. 13 | */ 14 | 15 | #ifndef _INCLUDE_METAMOD_SOURCE_STUB_PLUGIN_H_ 16 | #define _INCLUDE_METAMOD_SOURCE_STUB_PLUGIN_H_ 17 | 18 | #include 19 | #include 20 | #include 21 | 22 | class SamplePlugin : public ISmmPlugin, public IMetamodListener 23 | { 24 | public: 25 | bool Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen, bool late); 26 | bool Unload(char *error, size_t maxlen); 27 | bool Pause(char *error, size_t maxlen); 28 | bool Unpause(char *error, size_t maxlen); 29 | void AllPluginsLoaded(); 30 | public: //hooks 31 | void OnLevelInit( char const *pMapName, 32 | char const *pMapEntities, 33 | char const *pOldLevel, 34 | char const *pLandmarkName, 35 | bool loadGame, 36 | bool background ); 37 | void OnLevelShutdown(); 38 | void Hook_GameFrame( bool simulating, bool bFirstTick, bool bLastTick ); 39 | void Hook_ClientActive( CPlayerSlot slot, bool bLoadGame, const char *pszName, uint64 xuid ); 40 | void Hook_ClientDisconnect( CPlayerSlot slot, ENetworkDisconnectionReason reason, const char *pszName, uint64 xuid, const char *pszNetworkID ); 41 | void Hook_ClientPutInServer( CPlayerSlot slot, char const *pszName, int type, uint64 xuid ); 42 | void Hook_ClientSettingsChanged( CPlayerSlot slot ); 43 | void Hook_OnClientConnected( CPlayerSlot slot, const char *pszName, uint64 xuid, const char *pszNetworkID, const char *pszAddress, bool bFakePlayer ); 44 | bool Hook_ClientConnect( CPlayerSlot slot, const char *pszName, uint64 xuid, const char *pszNetworkID, bool unk1, CBufferString *pRejectReason ); 45 | void Hook_ClientCommand( CPlayerSlot nSlot, const CCommand &_cmd ); 46 | public: 47 | const char *GetAuthor(); 48 | const char *GetName(); 49 | const char *GetDescription(); 50 | const char *GetURL(); 51 | const char *GetLicense(); 52 | const char *GetVersion(); 53 | const char *GetDate(); 54 | const char *GetLogTag(); 55 | }; 56 | 57 | extern SamplePlugin g_SamplePlugin; 58 | 59 | PLUGIN_GLOBALVARS(); 60 | 61 | #endif //_INCLUDE_METAMOD_SOURCE_STUB_PLUGIN_H_ 62 | -------------------------------------------------------------------------------- /support/README.txt: -------------------------------------------------------------------------------- 1 | Visit: 2 | 3 | http://wiki.alliedmods.net/Category:Metamod:Source_Documentation 4 | 5 | for more information. 6 | 7 | 8 | -------------------------------------------------------------------------------- /support/buildbot/BreakpadSymbols: -------------------------------------------------------------------------------- 1 | # vim: set ts=2 sw=2 tw=99 noet ft=python: 2 | import os, sys 3 | 4 | builder.SetBuildFolder('symbols') 5 | 6 | UPLOAD_SCRIPT = os.path.join(builder.sourcePath, 'support', 'buildbot', 'upload_symbols.py') 7 | 8 | cxx_tasks = MMS.binaries 9 | for cxx_task in cxx_tasks: 10 | if cxx_task.target.platform in ['windows']: 11 | debug_entry = cxx_task.debug 12 | else: 13 | debug_entry = cxx_task.binary 14 | 15 | debug_file = os.path.join(builder.buildPath, debug_entry.path) 16 | if cxx_task.target.platform == 'linux': 17 | argv = ['dump_syms', debug_file, os.path.dirname(debug_file)] 18 | elif cxx_task.target.platform == 'mac': 19 | argv = ['dump_syms', debug_file + '.dSYM'] 20 | elif cxx_task.target.platform == 'windows': 21 | argv = ['dump_syms.exe', debug_file] 22 | 23 | plat_dir = os.path.dirname(debug_file) 24 | bin_dir = os.path.split(plat_dir)[0] 25 | 26 | symbol_file = '{}-{}-{}.breakpad'.format( 27 | os.path.split(bin_dir)[1], 28 | cxx_task.target.platform, 29 | cxx_task.target.arch) 30 | 31 | argv = [sys.executable, UPLOAD_SCRIPT, symbol_file] + argv 32 | builder.AddCommand( 33 | inputs = [UPLOAD_SCRIPT, debug_entry], 34 | argv = argv, 35 | outputs = [symbol_file] 36 | ) 37 | 38 | def run(self, master, job): 39 | ShellCommand.run(self, master, job) 40 | if self.stdout != None and len(self.stdout) > 0: 41 | request = urllib.Request(symbolServer, self.stdout.encode('utf-8')) 42 | request.add_header("Content-Type", "text/plain") 43 | self.serverResponse = urllib.urlopen(request).read().decode('utf-8') 44 | def spew(self, runner): 45 | if self.stderr != None and len(self.stderr) > 0: 46 | runner.PrintOut(self.stderr) 47 | if self.serverResponse != None and len(self.serverResponse) > 0: 48 | runner.PrintOut(self.serverResponse) 49 | -------------------------------------------------------------------------------- /support/buildbot/PackageScript: -------------------------------------------------------------------------------- 1 | # vim: set ts=2 sw=2 tw=99 noet ft=python: 2 | import os 3 | 4 | builder.SetBuildFolder('package') 5 | 6 | def deduce_target_sdk(path): 7 | for sdk_name in MMS.sdks: 8 | sdk = MMS.sdks[sdk_name] 9 | if ('metamod.' + sdk['extension']) in path: 10 | return sdk 11 | return None 12 | 13 | addons_folder = builder.AddFolder('addons') 14 | metamod_folder = builder.AddFolder(os.path.join('addons', 'metamod')) 15 | bin_folder = builder.AddFolder(os.path.join('addons', 'metamod', 'bin')) 16 | 17 | for cxx in MMS.all_targets: 18 | if cxx.target.arch == 'x86_64': 19 | if cxx.target.platform == 'windows': 20 | bin64_folder = builder.AddFolder(os.path.join('addons', 'metamod', 'bin', 'win64')) 21 | bin64_s2_folder = bin64_folder 22 | builder.AddCopy(os.path.join(builder.sourcePath, 'support', 'metamod_win64.vdf'), 23 | os.path.join('addons', 'metamod_x64.vdf')) 24 | elif cxx.target.platform == 'linux': 25 | bin64_folder = builder.AddFolder(os.path.join('addons', 'metamod', 'bin', 'linux64')) 26 | bin64_s2_folder = builder.AddFolder(os.path.join('addons', 'metamod', 'bin', 'linuxsteamrt64')) 27 | builder.AddCopy(os.path.join(builder.sourcePath, 'support', 'metamod_linux64.vdf'), 28 | os.path.join('addons', 'metamod_x64.vdf')) 29 | elif cxx.target.platform == 'mac': 30 | bin64_folder = builder.AddFolder(os.path.join('addons', 'metamod', 'bin', 'osx64')) 31 | bin64_s2_folder = bin64_folder 32 | builder.AddCopy(os.path.join(builder.sourcePath, 'support', 'metamod_osx64.vdf'), 33 | os.path.join('addons', 'metamod_x64.vdf')) 34 | 35 | builder.AddCopy(os.path.join(builder.sourcePath, 'support', 'metamod.vdf'), addons_folder) 36 | builder.AddCopy(os.path.join(builder.sourcePath, 'support', 'metaplugins.ini'), metamod_folder) 37 | builder.AddCopy(os.path.join(builder.sourcePath, 'support', 'README.txt'), metamod_folder) 38 | 39 | pdb_list = [] 40 | for task in MMS.binaries: 41 | sdk = deduce_target_sdk(task.binary.path) 42 | 43 | if task.target.arch == 'x86_64': 44 | # libserver check is a hack to make sure that binary ends up in the correct folder 45 | # as s2 folders differ to s1 layout 46 | if 'libserver' in task.binary.path or (sdk is not None and sdk.get('source2', False)): 47 | builder.AddCopy(task.binary, bin64_s2_folder) 48 | else: 49 | builder.AddCopy(task.binary, bin64_folder) 50 | else: 51 | builder.AddCopy(task.binary, bin_folder) 52 | 53 | if task.debug: 54 | pdb_list.append(task.debug) 55 | 56 | # Generate PDB info. 57 | with open(os.path.join(builder.buildPath, 'pdblog.txt'), 'wt') as fp: 58 | for line in pdb_list: 59 | fp.write(line.path + '\n') 60 | 61 | -------------------------------------------------------------------------------- /support/buildbot/Versioning: -------------------------------------------------------------------------------- 1 | # vim: set ts=8 sts=2 sw=2 tw=99 et ft=python: 2 | import os, sys 3 | import re 4 | 5 | builder.SetBuildFolder('/') 6 | 7 | includes = builder.AddFolder('includes') 8 | 9 | argv = [ 10 | sys.executable, 11 | os.path.join(builder.sourcePath, 'support', 'buildbot', 'generate_headers.py'), 12 | os.path.join(builder.sourcePath), 13 | os.path.join(builder.buildPath, 'includes') 14 | ] 15 | outputs = [ 16 | os.path.join(builder.buildFolder, 'includes', 'metamod_version_auto.h') 17 | ] 18 | 19 | with open(os.path.join(builder.sourcePath, '.git', 'HEAD'), encoding='utf-8') as fp: 20 | head_contents = fp.read().strip() 21 | if re.search('^[a-fA-F0-9]{40}$', head_contents): 22 | git_head_path = os.path.join(builder.sourcePath, '.git', 'HEAD') 23 | else: 24 | git_state = head_contents.split(':')[1].strip() 25 | git_head_path = os.path.join(builder.sourcePath, '.git', git_state) 26 | if not os.path.exists(git_head_path): 27 | git_head_path = os.path.join(builder.sourcePath, '.git', 'HEAD') 28 | 29 | sources = [ 30 | os.path.join(builder.sourcePath, 'product.version'), 31 | 32 | # This is a hack, but we need some way to only run this script when Git changes. 33 | git_head_path, 34 | 35 | # The script source is a dependency, of course... 36 | argv[1] 37 | ] 38 | output_nodes = builder.AddCommand( 39 | inputs=sources, 40 | argv=argv, 41 | outputs=outputs 42 | ) 43 | 44 | rvalue = output_nodes 45 | -------------------------------------------------------------------------------- /support/buildbot/bootstrap.py: -------------------------------------------------------------------------------- 1 | # vim: set sw=4 sts=4 ts=4 sw=99 et: 2 | from contextlib import contextmanager 3 | import argparse 4 | import json 5 | import os 6 | import platform 7 | import shutil 8 | import subprocess 9 | 10 | @contextmanager 11 | def Chdir(path): 12 | old = os.getcwd() 13 | os.chdir(path) 14 | print('> cd {} # {}'.format(path, os.getcwd())) 15 | try: 16 | yield 17 | finally: 18 | os.chdir(old) 19 | 20 | def run_shell(argv, env = None): 21 | if type(argv) is str: 22 | print('> {}'.format(argv)) 23 | shell = True 24 | else: 25 | print('> {}'.format(' '.join(argv))) 26 | shell = False 27 | try: 28 | output = subprocess.check_output(argv, stderr = subprocess.STDOUT, env = env, shell = shell) 29 | except subprocess.CalledProcessError as cpe: 30 | if not shell: 31 | print(cpe.output.decode('utf-8', 'ignore')) 32 | raise 33 | print(output.decode('utf-8', 'ignore')) 34 | 35 | def output_needs_cleaning(): 36 | if not os.path.isdir('OUTPUT'): 37 | return False 38 | amb2_dir = os.path.join('OUTPUT', '.ambuild2') 39 | if not os.path.exists(os.path.join(amb2_dir, 'graph')): 40 | return True 41 | if not os.path.exists(os.path.join(amb2_dir, 'vars')): 42 | return True 43 | return False 44 | 45 | def main(): 46 | parser = argparse.ArgumentParser() 47 | parser.add_argument('--config', type = str, required = True, 48 | help = 'Buildbot slave name') 49 | parser.add_argument('--hl2sdk-root', type = str, required = True, 50 | help = 'hl2sdk collection') 51 | parser.add_argument('--python-cmd', type = str, required = True, 52 | default = 'python3', 53 | help = 'Python command') 54 | args = parser.parse_args() 55 | 56 | run_shell("git submodule update --init --recursive") 57 | 58 | source = os.getcwd() 59 | 60 | with open(os.path.join('support', 'buildbot', 'buildconfig.json'), 'rt') as fp: 61 | config_root = json.load(fp) 62 | 63 | config = config_root.get(args.config, {}) 64 | 65 | # Set build properties. 66 | build_env = os.environ.copy() 67 | for env_var in ['CC', 'CXX']: 68 | if env_var not in config: 69 | continue 70 | build_env[env_var] = config[env_var] 71 | 72 | if platform.system() == 'Windows': 73 | hl2sdk_root = '/Volumes/hgshare' 74 | python_cmd = "C:\\Python38\\Python.exe" 75 | elif platform.system() == 'Linux': 76 | hl2sdk_root = '/hgshare' 77 | python_cmd = "python3" 78 | elif platform.system() == 'Windows': 79 | hl2sdk_root = 'H:\\' 80 | python_cmd = "python3" 81 | 82 | config_argv = [ 83 | args.python_cmd, 84 | os.path.join(source, 'configure.py'), 85 | '--enable-optimize', 86 | '--breakpad-dump', 87 | '--no-color', 88 | '--symbol-files', 89 | '--targets=x86,x86_64', 90 | '--sdks=all', 91 | '--out=OUTPUT', 92 | '--hl2sdk-root={}'.format(args.hl2sdk_root), 93 | ] 94 | 95 | print("Attempting to reconfigure...") 96 | 97 | with Chdir('..'): 98 | if output_needs_cleaning(): 99 | shutil.rmtree('OUTPUT') 100 | if not os.path.isdir('OUTPUT'): 101 | os.makedirs('OUTPUT') 102 | run_shell(config_argv, env = build_env) 103 | 104 | if __name__ == '__main__': 105 | main() 106 | -------------------------------------------------------------------------------- /support/buildbot/build_type: -------------------------------------------------------------------------------- 1 | dev 2 | -------------------------------------------------------------------------------- /support/buildbot/buildconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "debian8": { 3 | "CC": "clang-3.8", 4 | "CXX": "clang-3.8" 5 | }, 6 | "debian11": { 7 | "CC": "clang-14", 8 | "CXX": "clang++-14" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /support/buildbot/generate_headers.py: -------------------------------------------------------------------------------- 1 | # vim: set ts=8 sts=2 sw=2 tw=99 et: 2 | import re 3 | import os, sys 4 | import subprocess 5 | 6 | argv = sys.argv[1:] 7 | if len(argv) < 2: 8 | sys.stderr.write('Usage: generate_headers.py \n') 9 | sys.exit(1) 10 | 11 | SourceFolder = os.path.abspath(os.path.normpath(argv[0])) 12 | OutputFolder = os.path.normpath(argv[1]) 13 | 14 | class FolderChanger: 15 | def __init__(self, folder): 16 | self.old = os.getcwd() 17 | self.new = folder 18 | 19 | def __enter__(self): 20 | if self.new: 21 | os.chdir(self.new) 22 | 23 | def __exit__(self, type, value, traceback): 24 | os.chdir(self.old) 25 | 26 | def run_and_return(argv): 27 | # Python 2.6 doesn't have check_output. 28 | if hasattr(subprocess, 'check_output'): 29 | text = subprocess.check_output(argv) 30 | if str != bytes: 31 | text = str(text, 'utf-8') 32 | else: 33 | p = subprocess.Popen(argv, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 34 | output, ignored = p.communicate() 35 | rval = p.poll() 36 | if rval: 37 | raise subprocess.CalledProcessError(rval, argv) 38 | text = output.decode('utf8') 39 | return text.strip() 40 | 41 | def get_git_version(): 42 | revision_count = run_and_return(['git', 'rev-list', '--count', 'HEAD']) 43 | revision_hash = run_and_return(['git', 'log', '--pretty=format:%h:%H', '-n', '1']) 44 | shorthash, longhash = revision_hash.split(':') 45 | 46 | return revision_count, shorthash, longhash 47 | 48 | def output_version_header(): 49 | with FolderChanger(SourceFolder): 50 | count, shorthash, longhash = get_git_version() 51 | 52 | with open(os.path.join(SourceFolder, 'product.version')) as fp: 53 | contents = fp.read() 54 | m = re.match(r'(\d+)\.(\d+)\.(\d+)-?(.*)', contents) 55 | if m == None: 56 | raise Exception('Could not detremine product version') 57 | major, minor, release, tag = m.groups() 58 | product = "{0}.{1}.{2}".format(major, minor, release) 59 | fullstring = product 60 | if tag != "": 61 | fullstring += "-{0}".format(tag) 62 | if tag == "dev": 63 | fullstring += "+{0}".format(count) 64 | 65 | with open(os.path.join(OutputFolder, 'metamod_version_auto.h'), 'w') as fp: 66 | fp.write(""" 67 | #ifndef _METAMOD_AUTO_VERSION_INFORMATION_H_ 68 | #define _METAMOD_AUTO_VERSION_INFORMATION_H_ 69 | 70 | #define MMS_BUILD_TAG \"{0}\" 71 | #define MMS_BUILD_CSET \"{1}\" 72 | #define MMS_BUILD_MAJOR \"{2}\" 73 | #define MMS_BUILD_MINOR \"{3}\" 74 | #define MMS_BUILD_RELEASE \"{4}\" 75 | #define MMS_BUILD_LOCAL_REV \"{6}\" 76 | 77 | #define MMS_BUILD_UNIQUEID "{6}:" MMS_BUILD_CSET 78 | 79 | #define MMS_VERSION_STRING \"{5}\" 80 | #define MMS_VERSION_FILE {2},{3},{4},0 81 | 82 | #endif /* _METAMOD_AUTO_VERSION_INFORMATION_H_ */ 83 | """.format(tag, shorthash, major, minor, release, fullstring, count)) 84 | 85 | output_version_header() 86 | 87 | -------------------------------------------------------------------------------- /support/buildbot/helpers.pm: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use Cwd; 5 | 6 | package Build; 7 | 8 | our $SVN = "/usr/bin/svn"; 9 | our $SVN_USER = 'dvander'; 10 | our $SVN_ARGS = ''; 11 | 12 | sub GitRevNum 13 | { 14 | my ($path) = (@_); 15 | my ($cd, $text, $rev); 16 | 17 | $cd = Cwd::cwd(); 18 | chdir($path); 19 | $text = `git rev-list --count HEAD`; 20 | chdir($cd); 21 | 22 | chomp $text; 23 | if ($text =~ /^(\d+)/) { 24 | return $1; 25 | } 26 | 27 | return 0; 28 | } 29 | 30 | sub HgRevNum 31 | { 32 | my ($path) = (@_); 33 | my ($cd, $text, $rev); 34 | 35 | $cd = Cwd::cwd(); 36 | chdir($path); 37 | $text = `hg identify -n`; 38 | chdir($cd); 39 | 40 | chomp $text; 41 | if ($text =~ /^(\d+)/) 42 | { 43 | return $1; 44 | } 45 | 46 | return 0; 47 | } 48 | 49 | sub SvnRevNum 50 | { 51 | my ($str)=(@_); 52 | 53 | my $data = Command('svnversion -c ' . $str); 54 | if ($data =~ /(\d+):(\d+)/) 55 | { 56 | return $2; 57 | } elsif ($data =~ /(\d+)/) { 58 | return $1; 59 | } else { 60 | return 0; 61 | } 62 | } 63 | 64 | sub ProductVersion 65 | { 66 | my ($file) = (@_); 67 | my ($version); 68 | open(FILE, $file) or die "Could not open $file: $!\n"; 69 | $version = ; 70 | close(FILE); 71 | chomp $version; 72 | return $version; 73 | } 74 | 75 | sub Delete 76 | { 77 | my ($str)=(@_); 78 | if ($^O =~ /MSWin/) 79 | { 80 | Command("del /S /F /Q \"$str\""); 81 | Command("rmdir /S /Q \"$str\""); 82 | } else { 83 | Command("rm -rf $str"); 84 | } 85 | return !(-e $str); 86 | } 87 | 88 | sub Copy 89 | { 90 | my ($src,$dest)=(@_); 91 | if ($^O =~ /MSWin/) 92 | { 93 | Command("copy \"$src\" \"$dest\" /y"); 94 | } else { 95 | Command("cp \"$src\" \"$dest\""); 96 | } 97 | return (-e $dest); 98 | } 99 | 100 | sub Move 101 | { 102 | my ($src,$dest)=(@_); 103 | if ($^O =~ /MSWin/) 104 | { 105 | Command("move \"$src\" \"$dest\""); 106 | } else { 107 | Command("mv \"$src\" \"$dest\""); 108 | } 109 | return (-e $dest); 110 | } 111 | 112 | sub Command 113 | { 114 | my($cmd)=(@_); 115 | print "$cmd\n"; 116 | return `$cmd`; 117 | } 118 | 119 | sub PathFormat 120 | { 121 | my ($str)=(@_); 122 | if ($^O =~ /MSWin/) 123 | { 124 | $str =~ s#/#\\#g; 125 | } else { 126 | $str =~ s#\\#/#g; 127 | } 128 | return $str; 129 | } 130 | 131 | sub SVN_Remove 132 | { 133 | my ($file)=(@_); 134 | my ($path, $name); 135 | if ($^O =~ /MSWin/) 136 | { 137 | ($path, $name) = ($file =~ /(.+)\/([^\/]+)$/); 138 | } else { 139 | ($path, $name) = ($file =~ /(.+)\\([^\\]+)$/); 140 | } 141 | my $dir = Cwd::cwd(); 142 | chdir($path); 143 | Command($SVN . ' ' . $SVN_ARGS . ' delete ' . $name); 144 | chdir($dir); 145 | } 146 | 147 | sub SVN_Add 148 | { 149 | my ($file)=(@_); 150 | my ($path, $name); 151 | if ($^O =~ /MSWin/) 152 | { 153 | ($path, $name) = ($file =~ /(.+)\/([^\/]+)$/); 154 | } else { 155 | ($path, $name) = ($file =~ /(.+)\\([^\\]+)$/); 156 | } 157 | my $dir = Cwd::cwd(); 158 | chdir($path); 159 | Command($SVN . ' ' . $SVN_ARGS . ' add ' . $name); 160 | chdir($dir); 161 | } 162 | 163 | sub GetBuildType 164 | { 165 | my ($file)=(@_); 166 | my ($type); 167 | open(TYPE, $file) or die("Could not open file: $!\n"); 168 | $type = ; 169 | close(TYPE); 170 | chomp $type; 171 | return $type; 172 | } 173 | 174 | return 1; 175 | -------------------------------------------------------------------------------- /support/buildbot/package.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use Cwd; 5 | use File::Basename; 6 | use File::Temp qw/ tempfile :seekable/; 7 | use Net::FTP; 8 | 9 | my ($ftp_file, $ftp_host, $ftp_user, $ftp_pass, $ftp_path, $tag); 10 | 11 | $ftp_file = shift; 12 | $tag = shift; 13 | 14 | open(FTP, $ftp_file) or die "Unable to read FTP config file $ftp_file: $!\n"; 15 | $ftp_host = ; 16 | $ftp_user = ; 17 | $ftp_pass = ; 18 | $ftp_path = ; 19 | close(FTP); 20 | 21 | chomp $ftp_host; 22 | chomp $ftp_user; 23 | chomp $ftp_pass; 24 | chomp $ftp_path; 25 | 26 | my ($myself, $path) = fileparse($0); 27 | chdir($path); 28 | 29 | use FindBin; 30 | use lib $FindBin::Bin; 31 | require 'helpers.pm'; 32 | 33 | #Switch to the output folder. 34 | chdir(Build::PathFormat('../../../OUTPUT/package')); 35 | 36 | my ($version); 37 | 38 | $version = Build::ProductVersion(Build::PathFormat('../../build/product.version')); 39 | $version =~ s/-dev//g; 40 | $version .= '-git' . Build::GitRevNum('../../build'); 41 | 42 | # Append OS to package version 43 | if ($^O eq "darwin") 44 | { 45 | $version .= '-mac'; 46 | } 47 | elsif ($^O =~ /MSWin/) 48 | { 49 | $version .= '-windows'; 50 | } 51 | else 52 | { 53 | $version .= '-' . $^O; 54 | } 55 | 56 | if (defined $tag) 57 | { 58 | $version .= '-' . $tag; 59 | } 60 | 61 | my ($filename); 62 | $filename = 'mmsource-' . $version; 63 | if ($^O eq "linux") 64 | { 65 | $filename .= '.tar.gz'; 66 | print "tar zcvf $filename addons\n"; 67 | system("tar zcvf $filename addons"); 68 | } 69 | else 70 | { 71 | $filename .= '.zip'; 72 | print "zip -r $filename addons\n"; 73 | system("zip -r $filename addons"); 74 | } 75 | 76 | my ($tmpfh, $tmpfile) = tempfile(); 77 | print $tmpfh $filename; 78 | $tmpfh->seek( 0, SEEK_END ); 79 | my $latest = "mmsource-latest-"; 80 | if ($^O eq "darwin") { 81 | $latest .= "mac"; 82 | } 83 | elsif ($^O =~ /MSWin/) { 84 | $latest .= "windows"; 85 | } 86 | else { 87 | $latest .= $^O; 88 | } 89 | 90 | my ($major,$minor) = ($version =~ /^(\d+)\.(\d+)/); 91 | $ftp_path .= "/$major.$minor"; 92 | 93 | my ($ftp); 94 | 95 | $ftp = Net::FTP->new($ftp_host, Debug => 0, Passive => 1) 96 | or die "Cannot connect to host $ftp_host: $@"; 97 | 98 | $ftp->login($ftp_user, $ftp_pass) 99 | or die "Cannot connect to host $ftp_host as $ftp_user: " . $ftp->message . "\n"; 100 | 101 | if ($ftp_path ne '') 102 | { 103 | $ftp->cwd($ftp_path) 104 | or die "Cannot change to folder $ftp_path: " . $ftp->message . "\n"; 105 | } 106 | 107 | $ftp->binary(); 108 | $ftp->put($filename) 109 | or die "Cannot drop file $filename ($ftp_path): " . $ftp->message . "\n"; 110 | $ftp->put($tmpfile, $latest) 111 | or die "Cannot drop file $latest ($ftp_path): " . $ftp->message . "\n"; 112 | 113 | $ftp->close(); 114 | 115 | print "File sent to drop site as $filename -- build succeeded.\n"; 116 | 117 | exit(0); 118 | 119 | -------------------------------------------------------------------------------- /support/buildbot/startbuild.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | # vim: set ts=2 sw=2 tw=99 noet: 3 | 4 | use File::Basename; 5 | 6 | my ($myself, $path) = fileparse($0); 7 | chdir($path); 8 | 9 | use FindBin; 10 | use lib $FindBin::Bin; 11 | require 'helpers.pm'; 12 | 13 | chdir('../../../OUTPUT'); 14 | 15 | my $argn = $#ARGV + 1; 16 | if ($argn > 0) { 17 | $ENV{CC} = $ARGV[0]; 18 | $ENV{CXX} = $ARGV[0]; 19 | } 20 | 21 | if ($^O !~ /MSWin/) { 22 | system("ambuild --no-color 2>&1"); 23 | } else { 24 | system("C:\\Python38\\scripts\\ambuild --no-color 2>&1"); 25 | } 26 | 27 | if ($? != 0) 28 | { 29 | die "Build failed: $!\n"; 30 | } 31 | else 32 | { 33 | exit(0); 34 | } 35 | 36 | -------------------------------------------------------------------------------- /support/buildbot/symstore.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use File::Basename; 4 | 5 | my ($myself, $path) = fileparse($0); 6 | chdir($path); 7 | 8 | use FindBin; 9 | use lib $FindBin::Bin; 10 | require 'helpers.pm'; 11 | 12 | chdir('..'); 13 | chdir('..'); 14 | 15 | open(PDBLOG, '../OUTPUT/pdblog.txt') or die "Could not open pdblog.txt: $!\n"; 16 | 17 | #Get version info 18 | my ($version); 19 | $version = Build::ProductVersion(Build::PathFormat('product.version')); 20 | $version =~ s/-dev//g; 21 | $version .= '-git' . Build::GitRevNum('.'); 22 | 23 | my ($build_type); 24 | $build_type = Build::GetBuildType(Build::PathFormat('support/buildbot/build_type')); 25 | 26 | if ($build_type eq "dev") 27 | { 28 | $build_type = "buildbot"; 29 | } 30 | elsif ($build_type eq "rel") 31 | { 32 | $build_type = "release"; 33 | } 34 | 35 | my ($line); 36 | while () 37 | { 38 | $line = $_; 39 | $line =~ s/\.pdb/\*/; 40 | chomp $line; 41 | Build::Command("symstore add /r /f \"..\\OUTPUT\\$line\" /s \"S:\\mmsource\" /t \"Metamod:Source\" /v \"$version\" /c \"$build_type\""); 42 | } 43 | 44 | close(PDBLOG); 45 | 46 | #Lowercase DLLs. Sigh. 47 | my (@files); 48 | opendir(DIR, "S:\\mmsource") or die "Could not open mmsource symbol folder: $!\n"; 49 | @files = readdir(DIR); 50 | closedir(DIR); 51 | 52 | my ($i, $j, $file, @subdirs); 53 | for ($i = 0; $i <= $#files; $i++) 54 | { 55 | $file = $files[$i]; 56 | next unless ($file =~ /\.dll$/); 57 | next unless (-d "S:\\mmsource\\$file"); 58 | opendir(DIR, "S:\\mmsource\\$file") or die "Could not open S:\\mmsource\\$file: $!\n"; 59 | @subdirs = readdir(DIR); 60 | closedir(DIR); 61 | for ($j = 0; $j <= $#subdirs; $j++) 62 | { 63 | next unless ($subdirs[$j] =~ /[A-Z]/); 64 | Build::Command("rename S:\\mmsource\\$file\\" . $subdirs[$j] . " " . lc($subdirs[$j])); 65 | } 66 | } 67 | 68 | -------------------------------------------------------------------------------- /support/buildbot/trigger_full_rebuild: -------------------------------------------------------------------------------- 1 | Aug 19, 2020 #2 2 | -------------------------------------------------------------------------------- /support/buildbot/upload_symbols.py: -------------------------------------------------------------------------------- 1 | # vim: ts=8 sts=2 sw=2 tw=99 et ft=python: 2 | import sys 3 | import subprocess 4 | import os 5 | try: 6 | import urllib.request as urllib 7 | except ImportError: 8 | import urllib2 as urllib 9 | 10 | if len(sys.argv) < 3: 11 | sys.stderr.write('Usage: \n') 12 | sys.exit(1) 13 | 14 | SYMBOL_SERVER = os.environ['BREAKPAD_SYMBOL_SERVER'] 15 | symbol_file = sys.argv[1] 16 | cmd_argv = sys.argv[2:] 17 | 18 | sys.stdout.write(' '.join(cmd_argv)) 19 | sys.stdout.write('\n') 20 | 21 | p = subprocess.Popen( 22 | args = cmd_argv, 23 | stdout = subprocess.PIPE, 24 | stderr = subprocess.PIPE, 25 | shell = False 26 | ) 27 | stdout, stderr = p.communicate() 28 | out = stdout.decode('utf8') 29 | err = stdout.decode('utf8') 30 | 31 | with open(symbol_file, 'w') as fp: 32 | fp.write(out) 33 | fp.write(err) 34 | 35 | lines = out.splitlines() 36 | 37 | paths = set() 38 | roots = {} 39 | 40 | # Lets not even talk about this. 41 | def fixWindowsPath(path): 42 | import ctypes 43 | GetShortPathName = ctypes.windll.kernel32.GetShortPathNameW 44 | shortp = ctypes.create_unicode_buffer(260) 45 | rv = GetShortPathName(path.capitalize(), shortp, 260) 46 | if rv == 0 or rv > 260: 47 | return path 48 | GetLongPathName = ctypes.windll.kernel32.GetLongPathNameW 49 | longp = ctypes.create_unicode_buffer(260) 50 | rv = GetLongPathName(shortp, longp, 260) 51 | if rv == 0 or rv > 260: 52 | return path 53 | return longp.value 54 | 55 | for i, line in enumerate(lines): 56 | line = line.strip().split(None, 2) 57 | 58 | if line[0] != 'FILE': 59 | continue 60 | 61 | path = line[2] 62 | 63 | if os.name == 'nt' and os.path.exists(path): 64 | path = fixWindowsPath(path) 65 | line = ' '.join(['FILE', line[1], path]) 66 | lines[i] = line 67 | 68 | path = os.path.dirname(path) 69 | if path in paths: 70 | continue 71 | 72 | paths.add(path) 73 | 74 | root = None 75 | url = None 76 | rev = None 77 | 78 | with open(os.devnull, 'w') as devnull: 79 | def runCommand(argv): 80 | proc = subprocess.Popen(argv, stdout=subprocess.PIPE, stderr=devnull, cwd=path, universal_newlines=True) 81 | procout, procerr = proc.communicate() 82 | if proc.returncode: 83 | raise RuntimeError('Failed to execute \'' + ' '.join(argv) + '\' = ' + str(proc.returncode)) 84 | return procout.strip() 85 | 86 | try: 87 | root = runCommand(['git', 'rev-parse', '--show-toplevel']) 88 | root = os.path.normpath(root) 89 | 90 | if root in roots: 91 | continue 92 | 93 | url = runCommand(['git', 'ls-remote', '--get-url', 'origin']) 94 | rev = runCommand(['git', 'log', '--pretty=format:%H', '-n', '1']) 95 | except (OSError, RuntimeError) as e: 96 | #sys.stderr.write(str(e) + '\n') 97 | continue 98 | 99 | roots[root] = (url, rev) 100 | 101 | index = 1 102 | while lines[index].split(None, 1)[0] == 'INFO': 103 | index += 1; 104 | 105 | for root, info in roots.items(): 106 | lines.insert(index, 'INFO REPO ' + ' '.join([info[1], info[0], root])) 107 | index += 1; 108 | 109 | out = os.linesep.join(lines).encode('utf8') 110 | 111 | request = urllib.Request(SYMBOL_SERVER, out) 112 | request.add_header('Content-Type', 'text/plain') 113 | server_response = urllib.urlopen(request).read().decode('utf8').strip() 114 | print(server_response) 115 | -------------------------------------------------------------------------------- /support/checkout-deps.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # This should be run inside a folder that contains MM:S, otherwise, it will checkout things into "mms-dependencies". 3 | 4 | trap "exit" INT 5 | 6 | # List of HL2SDK branch names to download. 7 | # ./checkout-deps.sh -s tf2,css 8 | while getopts ":s:" opt; do 9 | case $opt in 10 | s) IFS=', ' read -r -a sdks <<< "$OPTARG" 11 | ;; 12 | \?) echo "Invalid option -$OPTARG" >&2 13 | ;; 14 | esac 15 | done 16 | 17 | ismac=0 18 | iswin=0 19 | 20 | archive_ext=tar.gz 21 | decomp="tar zxf" 22 | 23 | if [ `uname` = "Darwin" ]; then 24 | ismac=1 25 | elif [ `uname` != "Linux" ] && [ -n "${COMSPEC:+1}" ]; then 26 | iswin=1 27 | archive_ext=zip 28 | decomp=unzip 29 | fi 30 | 31 | if [ ! -d "metamod-source" ]; then 32 | echo "Could not find a Metamod:Source repository; make sure you aren't running this script inside it." 33 | exit 1 34 | fi 35 | 36 | checkout () 37 | { 38 | if [ ! -d "$name" ]; then 39 | git clone $repo -b $branch $name 40 | if [ -n "$origin" ]; then 41 | cd $name 42 | git remote set-url origin $origin 43 | cd .. 44 | fi 45 | else 46 | cd $name 47 | if [ -n "$origin" ]; then 48 | git remote set-url origin ../$repo 49 | fi 50 | git checkout $branch 51 | git pull origin $branch 52 | if [ -n "$origin" ]; then 53 | git remote set-url origin $origin 54 | fi 55 | cd .. 56 | fi 57 | } 58 | 59 | if [ -z ${sdks+x} ]; then 60 | sdks=( csgo hl2dm nucleardawn l4d2 dods l4d css tf2 insurgency sdk2013 dota doi ) 61 | 62 | # Windows/Linux only. 63 | sdks+=( orangebox blade episode1 bms pvkii mcv ) 64 | 65 | # Windows only. 66 | sdks+=( darkm swarm bgt eye contagion ) 67 | fi 68 | 69 | # Check out a local copy as a proxy. 70 | if [ ! -d "hl2sdk-proxy-repo" ]; then 71 | git clone --mirror https://github.com/alliedmodders/hl2sdk hl2sdk-proxy-repo 72 | else 73 | cd hl2sdk-proxy-repo 74 | git fetch 75 | cd .. 76 | fi 77 | 78 | for sdk in "${sdks[@]}" 79 | do 80 | repo=hl2sdk-proxy-repo 81 | origin="https://github.com/alliedmodders/hl2sdk" 82 | name=hl2sdk-$sdk 83 | branch=$sdk 84 | checkout 85 | done 86 | 87 | python_cmd=`command -v python` 88 | if [ -z "$python_cmd" ]; then 89 | python_cmd=`command -v python3` 90 | 91 | if [ -z "$python_cmd" ]; then 92 | echo "No suitable installation of Python detected" 93 | exit 1 94 | fi 95 | fi 96 | 97 | $python_cmd -c "import ambuild2" 2>&1 1>/dev/null 98 | if [ $? -eq 1 ]; then 99 | echo "AMBuild is required to build Metamod:Source" 100 | 101 | $python_cmd -m pip --version 2>&1 1>/dev/null 102 | if [ $? -eq 1 ]; then 103 | echo "The detected Python installation does not have PIP" 104 | echo "Installing the latest version of PIP available (VIA \"get-pip.py\")" 105 | 106 | get_pip="./get-pip.py" 107 | get_pip_url="https://bootstrap.pypa.io/get-pip.py" 108 | 109 | if [ `command -v wget` ]; then 110 | wget $get_pip_url -O $get_pip 111 | elif [ `command -v curl` ]; then 112 | curl -o $get_pip $get_pip_url 113 | else 114 | echo "Failed to locate wget or curl. Install one of these programs to download 'get-pip.py'." 115 | exit 1 116 | fi 117 | 118 | $python_cmd $get_pip 119 | if [ $? -eq 1 ]; then 120 | echo "Installation of PIP has failed" 121 | exit 1 122 | fi 123 | fi 124 | 125 | repo="https://github.com/alliedmodders/ambuild" 126 | origin= 127 | branch=master 128 | name=ambuild 129 | checkout 130 | 131 | if [ $iswin -eq 1 ] || [ $ismac -eq 1 ]; then 132 | $python_cmd -m pip install ./ambuild 133 | else 134 | echo "Installing AMBuild at the user level. Location can be: ~/.local/bin" 135 | $python_cmd -m pip install --user ./ambuild 136 | fi 137 | fi 138 | -------------------------------------------------------------------------------- /support/dll2lib.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Generate a .lib file for linking to a dll. 4 | .DESCRIPTION 5 | This script generates a .lib from from a dynamic link library (dll) file. 6 | 7 | The .lib file can then be linked against to resolve symbols in the dll file. 8 | .PARAMETER InputBinary 9 | The path to the dll file. 10 | .PARAMETER OutPath 11 | The output folder in which to save the .lib file. Defaults to the directory of the dll file. 12 | 13 | The folder must already exist. 14 | #> 15 | [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High')] 16 | param( 17 | [Parameter(Mandatory, ValueFromPipeline)] 18 | [ValidateScript({($_ -match '\.dll$') -and (Test-Path -Path $_ -PathType Leaf)})] 19 | [string]$InputBinary, 20 | 21 | [Parameter()] 22 | [ValidateScript({Test-Path -Path $_ -PathType Container})] 23 | [string]$OutPath, 24 | 25 | [Parameter()] 26 | [switch]$Force 27 | ) 28 | 29 | try { 30 | $dumpbinBin = (Get-Command -Name 'dumpbin.exe').Source 31 | } catch { 32 | throw 'Could not find dumpbin.exe in PATH. (Are you running from a Developer Command Prompt?)' 33 | } 34 | 35 | Write-Verbose "Found dumpbin.exe at '$dumpbinBin'" 36 | 37 | try { 38 | $libBin = (Get-Command -Name 'lib.exe').Source 39 | } catch { 40 | throw 'Could not find lib.exe in PATH. (Are you running from a Developer Command Prompt?)' 41 | } 42 | 43 | Write-Verbose "Found lib.exe at '$libBin'" 44 | 45 | $inputBinInfo = Get-Item -Path $InputBinary 46 | 47 | $defTempPath = Join-Path -Path ([System.IO.Path]::GetTempPath()) -ChildPath ('{0}.def' -f $inputBinInfo.BaseName) 48 | 49 | if (-not $OutPath) { 50 | $OutPath = $inputBinInfo.DirectoryName 51 | } 52 | 53 | Write-Verbose "Using output path '$OutPath'" 54 | 55 | $outLibFullName = Join-Path -Path $OutPath -ChildPath ('{0}.lib' -f $inputBinInfo.BaseName) 56 | if ((-not (Test-Path -Path $outLibFullName)) -or $PSCmdlet.ShouldProcess($outLibFullName, 'overwrite')) 57 | { 58 | $archCode = ((. $dumpbinBin /headers $inputBinInfo.FullName | Select-String -Context 1 -SimpleMatch -Pattern 'FILE HEADER VALUES' -CaseSensitive).Context.PostContext | Select-String -Pattern '^\s*([A-Z0-9]+) machine \(.*\)$' -CaseSensitive).Matches[0].Groups[1].Value 59 | switch ($archCode) 60 | { 61 | '14C' { $arch = 'X86' } 62 | '8664' { $arch = 'X64' } 63 | 'AA64' { $arch = 'ARM64' } 64 | default { 65 | if ([Environment]::Is64BitOperatingSystem) { 66 | $arch = 'X64' 67 | } else { 68 | $arch = 'X86' 69 | } 70 | # TODO: Add ARM64 detection fallback 71 | 72 | Write-Warning "Unable to determine arch of binary. Defaulting to $arch for lib." 73 | } 74 | } 75 | 76 | Write-Verbose "Using arch '$arch' for lib generation." 77 | 78 | $funcs = . $dumpbinBin /exports $inputBinInfo.FullName | 79 | Select-String -Pattern '^\s+\d+\s+[A-Z0-9]+\s+[A-Z0-9]+\s+(.+)$' -CaseSensitive | 80 | Select-Object -ExpandProperty 'Matches' | 81 | ForEach-Object -Process { 82 | $_.Groups[1].Value 83 | } 84 | 85 | Write-Verbose "Found $($funcs.Count) functions in '$InputBinary'" 86 | 87 | Write-Verbose "Creating def file at '$defTempPath'" 88 | 'EXPORTS' | Out-File $defTempPath -Force 89 | $funcs | Out-File $defTempPath -Append 90 | 91 | Write-Verbose "Calling lib.exe to generate '$outLibFullName'" 92 | . $libBin /def:$defTempPath /OUT:$outLibFullName /MACHINE:$arch 93 | 94 | Write-Verbose "Removing temp def file at '$defTempPath'" 95 | Remove-Item -Path $defTempPath -Confirm:$false 96 | } -------------------------------------------------------------------------------- /support/metamod.vdf: -------------------------------------------------------------------------------- 1 | "Plugin" 2 | { 3 | "file" "addons/metamod/bin/server" 4 | } 5 | 6 | -------------------------------------------------------------------------------- /support/metamod_linux64.vdf: -------------------------------------------------------------------------------- 1 | "Plugin" 2 | { 3 | "file" "addons/metamod/bin/linux64/server" 4 | } 5 | 6 | -------------------------------------------------------------------------------- /support/metamod_osx64.vdf: -------------------------------------------------------------------------------- 1 | "Plugin" 2 | { 3 | "file" "addons/metamod/bin/osx64/server" 4 | } 5 | 6 | -------------------------------------------------------------------------------- /support/metamod_win64.vdf: -------------------------------------------------------------------------------- 1 | "Plugin" 2 | { 3 | "file" "addons/metamod/bin/win64/server" 4 | } 5 | 6 | -------------------------------------------------------------------------------- /support/metaplugins.ini: -------------------------------------------------------------------------------- 1 | ;If your plugin came with a .vdf file, you do not need to use this file. 2 | ; 3 | ;List one plugin per line. Each line should contain the path to the plugin's binary. 4 | ;Any line starting with a ';' character is a comment line, and is ignored. 5 | ; 6 | ;You do not need to include the _i486.so or .dll part of the file name. Example: 7 | ; addons/sourcemod/bin/sourcemod_mm 8 | ;You may also put an alias in front of the file, for example: 9 | ; sm addons/sourcemod/bin/sourcemod_mm 10 | ;Will allow you to use "meta load sm" from the console. 11 | ; 12 | ;********* LIST PLUGINS BELOW *********** 13 | 14 | 15 | -------------------------------------------------------------------------------- /support/msvc_project_templates/VC/VCProjects/MMSProjectTemplate.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alliedmodders/metamod-source/5d2bb7e206232879729a0b53aa6f289077977f3c/support/msvc_project_templates/VC/VCProjects/MMSProjectTemplate.ico -------------------------------------------------------------------------------- /support/msvc_project_templates/VC/VCProjects/MMSProjectTemplate.vsz: -------------------------------------------------------------------------------- 1 | VSWIZARD 7.0 2 | Wizard=VsWizard.VsWizardEngine.8.0 3 | 4 | Param="WIZARD_NAME = MMSProjectTemplate" 5 | Param="RELATIVE_PATH = VCWizards\AppWiz\Metamod" 6 | Param="FALLBACK_LCID = 1033" 7 | -------------------------------------------------------------------------------- /support/msvc_project_templates/VC/VCProjects/Metamod/MMSProjectTemplate.vsdir: -------------------------------------------------------------------------------- 1 | ..\MMSProjectTemplate.vsz| |Metamod C++ Project|1|This wizard will create a Metamod Source Plugin Project.| |6777| | 2 | -------------------------------------------------------------------------------- /support/msvc_project_templates/VC/VCWizards/AppWiz/Metamod/MMSProjectTemplate/1033/Images/DottedHori.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alliedmodders/metamod-source/5d2bb7e206232879729a0b53aa6f289077977f3c/support/msvc_project_templates/VC/VCWizards/AppWiz/Metamod/MMSProjectTemplate/1033/Images/DottedHori.gif -------------------------------------------------------------------------------- /support/msvc_project_templates/VC/VCWizards/AppWiz/Metamod/MMSProjectTemplate/1033/Images/DottedVert.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alliedmodders/metamod-source/5d2bb7e206232879729a0b53aa6f289077977f3c/support/msvc_project_templates/VC/VCWizards/AppWiz/Metamod/MMSProjectTemplate/1033/Images/DottedVert.gif -------------------------------------------------------------------------------- /support/msvc_project_templates/VC/VCWizards/AppWiz/Metamod/MMSProjectTemplate/1033/Images/spacer.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alliedmodders/metamod-source/5d2bb7e206232879729a0b53aa6f289077977f3c/support/msvc_project_templates/VC/VCWizards/AppWiz/Metamod/MMSProjectTemplate/1033/Images/spacer.gif -------------------------------------------------------------------------------- /support/msvc_project_templates/VC/VCWizards/AppWiz/Metamod/MMSProjectTemplate/HTML/1033/default.htm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alliedmodders/metamod-source/5d2bb7e206232879729a0b53aa6f289077977f3c/support/msvc_project_templates/VC/VCWizards/AppWiz/Metamod/MMSProjectTemplate/HTML/1033/default.htm -------------------------------------------------------------------------------- /support/msvc_project_templates/VC/VCWizards/AppWiz/Metamod/MMSProjectTemplate/Images/MMSProjectTemplate.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alliedmodders/metamod-source/5d2bb7e206232879729a0b53aa6f289077977f3c/support/msvc_project_templates/VC/VCWizards/AppWiz/Metamod/MMSProjectTemplate/Images/MMSProjectTemplate.gif -------------------------------------------------------------------------------- /support/msvc_project_templates/VC/VCWizards/AppWiz/Metamod/MMSProjectTemplate/Images/MMSProjectTemplate_Background.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alliedmodders/metamod-source/5d2bb7e206232879729a0b53aa6f289077977f3c/support/msvc_project_templates/VC/VCWizards/AppWiz/Metamod/MMSProjectTemplate/Images/MMSProjectTemplate_Background.gif -------------------------------------------------------------------------------- /support/msvc_project_templates/VC/VCWizards/AppWiz/Metamod/MMSProjectTemplate/Templates/1033/ReadMe.txt: -------------------------------------------------------------------------------- 1 | ======================================================================== 2 | [!output PLUGIN_NAME] : Project Overview 3 | ======================================================================== 4 | 5 | MMS Plugin Project has created this [!output PLUGIN_NAME] project for you as a starting point. 6 | -------------------------------------------------------------------------------- /support/msvc_project_templates/VC/VCWizards/AppWiz/Metamod/MMSProjectTemplate/Templates/1033/StdMMS.h: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // 3 | // File: StdMMS.h 4 | // Author: [!output PLUGIN_AUTHOR] 5 | // Date: [!output CURRENT_DATE] 6 | // 7 | // License: [!output PLUGIN_LICENSE] 8 | // 9 | // This software is provided 'as-is', without any express or 10 | // implied warranty. In no event will the authors be held liable 11 | // for any damages arising from the use of this software. 12 | // 13 | // Based on code written by AlliedModders LLC. Sample Plugin 14 | // 15 | /////////////////////////////////////////////////////////////////////////////// 16 | 17 | #ifndef _StdMMS_H 18 | #define _StdMMS_H 19 | 20 | /////////////////////////////////////////////////////// 21 | // Include Standard Headers 22 | 23 | #include 24 | 25 | /////////////////////////////////////////////////////// 26 | // Include MetaMod Headers 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | /////////////////////////////////////////////////////// 34 | // Include [!output PROJECT_NAME] Headers 35 | 36 | #include "Plugin/[!output PLUGIN_CLASS]Hooks.h" 37 | #include "Plugin/[!output PLUGIN_CLASS].h" 38 | #include "Plugin/[!output PLUGIN_CLASS]Engine.h" 39 | 40 | // TODO: Add your own headers here. 41 | 42 | // ex. #include "MyCode/MyInclude.h" 43 | 44 | #endif // _StdMMS_H 45 | -------------------------------------------------------------------------------- /support/msvc_project_templates/VC/VCWizards/AppWiz/Metamod/MMSProjectTemplate/Templates/1033/Templates.inf: -------------------------------------------------------------------------------- 1 | StdMMS.h 2 | plugin_mm.h 3 | plugin_mm.cpp 4 | plugin_hooks.h 5 | plugin_hooks.cpp 6 | plugin_engine.h 7 | plugin.vdf 8 | ReadMe.txt 9 | -------------------------------------------------------------------------------- /support/msvc_project_templates/VC/VCWizards/AppWiz/Metamod/MMSProjectTemplate/Templates/1033/plugin.vdf: -------------------------------------------------------------------------------- 1 | "Metamod Plugin" 2 | { 3 | "alias" "[!output PLUGIN_NAME]" 4 | "file" "addons/metamod/plugins/[!output PLUGIN_NAME]/bin/[!output PLUGIN_DLL]" 5 | } 6 | -------------------------------------------------------------------------------- /support/msvc_project_templates/VC/VCWizards/AppWiz/Metamod/MMSProjectTemplate/Templates/1033/plugin_engine.h: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // 3 | // File: [!output PLUGIN_CLASS]Engine.h 4 | // Author: [!output PLUGIN_AUTHOR] 5 | // Date: [!output CURRENT_DATE] 6 | // 7 | // License: [!output PLUGIN_LICENSE] 8 | // 9 | // This software is provided 'as-is', without any express or 10 | // implied warranty. In no event will the authors be held liable 11 | // for any damages arising from the use of this software. 12 | // 13 | // Based on code written by AlliedModders LLC. Sample Plugin 14 | // 15 | /////////////////////////////////////////////////////////////////////////////// 16 | 17 | #ifndef _MMS_ENGINE_H 18 | #define _MMS_ENGINE_H 19 | 20 | #include 21 | 22 | ///////////////////////////////////////////////////////////////////////// 23 | // Class [!output PLUGIN_CLASS] 24 | 25 | class [!output PLUGIN_CLASS]; 26 | 27 | ///////////////////////////////////////////////////////////////////////// 28 | // Episode One 29 | 30 | #if SOURCE_ENGINE == SE_EPISODEONE && defined METAMOD_PLAPI_VERSION 31 | 32 | #error "Metamod:Source 1.6 API is not supported on the old engine." 33 | 34 | #endif 35 | 36 | ///////////////////////////////////////////////////////////////////////// 37 | // Wrap some API calls for legacy MM:S. 38 | 39 | #if !defined METAMOD_PLAPI_VERSION 40 | 41 | #define GetEngineFactory engineFactory 42 | #define GetServerFactory serverFactory 43 | 44 | #define MM_Format snprintf 45 | #define GetCGlobals pGlobals 46 | 47 | #else 48 | 49 | #define MM_Format g_SMAPI->Format 50 | 51 | #endif 52 | 53 | ///////////////////////////////////////////////////////////////////////// 54 | // Wrap the CCommand class so our code looks the same for both engines. 55 | 56 | #if SOURCE_ENGINE <= SE_DARKMESSIAH 57 | 58 | class CCommand 59 | { 60 | public: 61 | 62 | const char *ArgS() 63 | { 64 | return [!output PLUGIN_CLASS]::EngineServer->Cmd_Args(); 65 | } 66 | 67 | int ArgC() 68 | { 69 | return [!output PLUGIN_CLASS]::EngineServer->Cmd_Argc(); 70 | } 71 | 72 | const char *Arg(int index) 73 | { 74 | return [!output PLUGIN_CLASS]::EngineServer->Cmd_Argv(index); 75 | } 76 | }; 77 | 78 | #define CVAR_INTERFACE_VERSION VENGINE_CVAR_INTERFACE_VERSION 79 | 80 | #endif 81 | 82 | ///////////////////////////////////////////////////////////////////////// 83 | // Left 4 Dead engine removed these from IVEngineServer 84 | 85 | #if SOURCE_ENGINE >= SE_LEFT4DEAD 86 | 87 | inline int IndexOfEdict(const edict_t* edict) 88 | { 89 | return (int)(edict - [!output PLUGIN_CLASS]::GlobalVars->baseEdict); 90 | } 91 | 92 | inline edict_t* PEntityOfEntIndex(int entity_index) 93 | { 94 | if (entity_index >= 0 && entity_index < [!output PLUGIN_CLASS]::GlobalVars->maxEntities) 95 | { 96 | return (edict_t *)([!output PLUGIN_CLASS]::GlobalVars->baseEdict + entity_index); 97 | } 98 | return NULL; 99 | } 100 | 101 | #else 102 | 103 | inline int IndexOfEdict(const edict_t* edict) 104 | { 105 | return [!output PLUGIN_CLASS]::EngineServer->IndexOfEdict(edict); 106 | } 107 | 108 | inline edict_t* PEntityOfEntIndex(int entity_index) 109 | { 110 | return [!output PLUGIN_CLASS]::EngineServer->PEntityOfEntIndex(entity_index); 111 | } 112 | 113 | #endif 114 | 115 | ///////////////////////////////////////////////////////////////////////// 116 | // Define snprintf 117 | 118 | #if defined WIN32 && !defined snprintf 119 | #define snprintf _snprintf 120 | #endif 121 | 122 | ///////////////////////////////////////////////////////////////////////// 123 | // Define ENGINE_CALL 124 | 125 | #define ENGINE_CALL(func) SH_CALL([!output PLUGIN_CLASS]::EngineServer, &IVEngineServer::func) 126 | 127 | #endif // _MMS_ENGINE_H 128 | -------------------------------------------------------------------------------- /versionlib/AMBuildScript: -------------------------------------------------------------------------------- 1 | # vim: sts=2 ts=8 sw=2 tw=99 et ft=python: 2 | 3 | rvalue = {} 4 | for cxx in MMS.all_targets: 5 | libname = 'version' 6 | lib = MMS.StaticLibrary(cxx, libname) 7 | lib.compiler.defines.remove('MMS_USE_VERSIONLIB') 8 | lib.compiler.sourcedeps += MMS.generated_headers 9 | lib.sources += [ 10 | 'versionlib.cpp' 11 | ] 12 | 13 | cmd = builder.Add(lib) 14 | 15 | rvalue[cxx.target.arch] = cmd.binary 16 | -------------------------------------------------------------------------------- /versionlib/versionlib.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * vim: set ts=4 sw=4 tw=99 noet : 3 | * ====================================================== 4 | * Metamod:Source 5 | * Copyright (C) 2004-2010 AlliedModders LLC and authors. 6 | * All rights reserved. 7 | * ====================================================== 8 | * 9 | * This software is provided 'as-is', without any express or implied warranty. 10 | * In no event will the authors be held liable for any damages arising from 11 | * the use of this software. 12 | * 13 | * Permission is granted to anyone to use this software for any purpose, 14 | * including commercial applications, and to alter it and redistribute it 15 | * freely, subject to the following restrictions: 16 | * 17 | * 1. The origin of this software must not be misrepresented; you must not 18 | * claim that you wrote the original software. If you use this software in a 19 | * product, an acknowledgment in the product documentation would be 20 | * appreciated but is not required. 21 | * 2. Altered source versions must be plainly marked as such, and must not be 22 | * misrepresented as being the original software. 23 | * 3. This notice may not be removed or altered from any source distribution. 24 | */ 25 | 26 | #include "metamod_version.h" 27 | #include "versionlib.h" 28 | 29 | const char *METAMOD_LOCAL_REV = MMS_BUILD_LOCAL_REV; 30 | const char *METAMOD_SHA = MMS_BUILD_CSET; 31 | const char *METAMOD_VERSION = MMS_VERSION_STRING; 32 | const char *METAMOD_BUILD_TIME = __DATE__ " " __TIME__; 33 | -------------------------------------------------------------------------------- /versionlib/versionlib.h: -------------------------------------------------------------------------------- 1 | /** 2 | * vim: set ts=4 sw=4 tw=99 noet : 3 | * ====================================================== 4 | * Metamod:Source 5 | * Copyright (C) 2004-2010 AlliedModders LLC and authors. 6 | * All rights reserved. 7 | * ====================================================== 8 | * 9 | * This software is provided 'as-is', without any express or implied warranty. 10 | * In no event will the authors be held liable for any damages arising from 11 | * the use of this software. 12 | * 13 | * Permission is granted to anyone to use this software for any purpose, 14 | * including commercial applications, and to alter it and redistribute it 15 | * freely, subject to the following restrictions: 16 | * 17 | * 1. The origin of this software must not be misrepresented; you must not 18 | * claim that you wrote the original software. If you use this software in a 19 | * product, an acknowledgment in the product documentation would be 20 | * appreciated but is not required. 21 | * 2. Altered source versions must be plainly marked as such, and must not be 22 | * misrepresented as being the original software. 23 | * 3. This notice may not be removed or altered from any source distribution. 24 | */ 25 | #ifndef _INCLUDE_METAMOD_VERSIONLIB_H_ 26 | #define _INCLUDE_METAMOD_VERSIONLIB_H_ 27 | 28 | #if !defined(MMS_USE_VERSIONLIB) 29 | // These get defined in metamod_version.h since 30 | // versionlib does not use versionlib. 31 | # undef METAMOD_LOCAL_REV 32 | # undef METAMOD_CSET 33 | # undef METAMOD_VERSION 34 | # undef METAMOD_BUILD_TIME 35 | #endif 36 | 37 | #ifdef __cplusplus 38 | # define EXTERN_C extern "C" 39 | #else 40 | # define EXTERN_C extern 41 | #endif 42 | EXTERN_C const char *METAMOD_LOCAL_REV; 43 | EXTERN_C const char *METAMOD_SHA; 44 | EXTERN_C const char *METAMOD_VERSION; 45 | EXTERN_C const char *METAMOD_BUILD_TIME; 46 | 47 | #endif // _INCLUDE_METAMOD_VERSIONLIB_H_ 48 | --------------------------------------------------------------------------------