From 39fcfa564ee880e895b44c1d292150cf9a1b43fb Mon Sep 17 00:00:00 2001 From: Nicholas Hastings Date: Sun, 12 Jul 2026 10:56:36 -0400 Subject: [PATCH] Modernize build/CI, support SourceMod 1.13, deprecate ForceHeartbeat Rework the build and CI: swap to SourceMod's safetyhook-based CDetour and drop the vendored CDetour/asm sources, the old Makefile, Travis config, and buildbot perl scripts. Add GitHub Actions building and releasing x86 and x86_64 against SM 1.12 and 1.13, plus dependabot. Split the Windows and Linux packages and tidy naming. Gate IPluginManager::FindPluginByContext on the extension API version so the extension builds against both SM 1.12 (API 8) and 1.13 (API 9), and shim DETOUR_CREATE_STATIC_FIXED over the address overload safetyhook exposes. Deprecate SteamWorks_ForceHeartbeat: newer Steamworks SDKs removed ISteamGameServer::ForceHeartbeat, so make the native a no-op and mark it deprecated in the include. --- .github/dependabot.yml | 6 + .github/workflows/c-cpp.yml | 52 ---- .github/workflows/ci.yml | 161 ++++++++++++ .gitignore | 6 +- .travis.yml | 67 ----- AMBuildScript | 120 +++------ Extension/AMBuilder | 90 +++++-- Extension/CDetour/detourhelpers.h | 100 ------- Extension/CDetour/detours.cpp | 228 ---------------- Extension/CDetour/detours.h | 249 ------------------ Extension/Makefile | 252 ------------------ Extension/asm/asm.c | 418 ------------------------------ Extension/asm/asm.h | 40 --- Extension/gsnatives.cpp | 12 +- Extension/swgsdetours.h | 6 + Extension/swhttprequest.cpp | 13 +- Pawn/includes/SteamWorks.inc | 1 + buildbot/PackageScript | 68 ++--- buildbot/helpers.pm | 174 ------------- buildbot/package_script.pl | 106 -------- configure.py | 5 - 21 files changed, 332 insertions(+), 1842 deletions(-) create mode 100644 .github/dependabot.yml delete mode 100644 .github/workflows/c-cpp.yml create mode 100644 .github/workflows/ci.yml delete mode 100644 .travis.yml delete mode 100644 Extension/CDetour/detourhelpers.h delete mode 100644 Extension/CDetour/detours.cpp delete mode 100644 Extension/CDetour/detours.h delete mode 100644 Extension/Makefile delete mode 100644 Extension/asm/asm.c delete mode 100644 Extension/asm/asm.h delete mode 100644 buildbot/helpers.pm delete mode 100644 buildbot/package_script.pl diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..5ace460 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,6 @@ +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml deleted file mode 100644 index bd15101..0000000 --- a/.github/workflows/c-cpp.yml +++ /dev/null @@ -1,52 +0,0 @@ -name: SteamWorks.ext Build - -on: - push: - branches: [ master, windows98 ] - pull_request: - branches: [ master, windows98 ] - -jobs: - build: - runs-on: ${{ matrix.os }} - strategy: - matrix: - python-version: [2.7, 3.3, 3.8] - os: [ubuntu-18.04, macos-latest, windows-2019] - exclude: - - os: macos-latest - python-version: 3.3 - - os: windows-2019 - python-version: 3.3 - - steps: - - uses: actions/checkout@v2 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 - with: - python-version: ${{ matrix.python-version }} - - name: Install Deps - if: runner.os == 'Linux' - run: | - sudo dpkg --add-architecture i386 - sudo apt-get install lib32stdc++-7-dev lib32z1-dev libc6-dev-i386 - sudo apt-get install g++-multilib - - name: install AMBuild - run: | - mkdir assets - cd assets - git clone --depth 1 --recurse-submodules -j8 --shallow-submodules -b fix-deps https://github.com/alliedmodders/ambuild.git - pip install ./ambuild - - name: Clone Dependencies - run: | - git clone --depth 1 --recurse-submodules -j8 --shallow-submodules https://$OAUTH@github.com/SteamDatabase/SteamworksSDK.git SteamworksSDK - git clone --depth 1 --recurse-submodules -j8 --shallow-submodules -b sdk2013 https://github.com/alliedmodders/hl2sdk.git hl2sdk-sdk2013 - git clone --depth 1 --recurse-submodules -j8 --shallow-submodules -b 1.10-dev https://github.com/alliedmodders/metamod-source.git mmsource-central - git clone --depth 1 --recurse-submodules -j8 --shallow-submodules -b 1.7-dev https://github.com/alliedmodders/sourcemod.git sourcemod-central - - name: Run Build - run: | - mkdir build - cd build - cp ../AMBuildScript ../../ - python ../configure.py -s sdk2013 --hl2sdk-root ../assets --sm-path ../assets/sourcemod-central --mms-path ../assets/mmsource-central --steamworks-path ../assets/SteamworksSD - ambuild diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..8f07dc6 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,161 @@ +name: CI + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + build: + name: sm${{ matrix.sm.label }}-${{ matrix.target.os_name }}-${{ matrix.target.arch }} + runs-on: ${{ matrix.target.os }} + container: ${{ matrix.target.container }} + strategy: + fail-fast: false + matrix: + sm: + - label: "1.12" + branch: "1.12-dev" + - label: "1.13" + branch: "master" + target: + - os: ubuntu-latest + os_name: linux + arch: x86 + container: ghcr.io/alliedmodders/build-containers/debian11-clang22:latest + - os: ubuntu-latest + os_name: linux + arch: x86_64 + container: ghcr.io/alliedmodders/build-containers/debian11-clang22:latest + - os: windows-latest + os_name: windows + arch: x86 + msvc_arch: x86 + - os: windows-latest + os_name: windows + arch: x86_64 + msvc_arch: amd64 + + steps: + - name: Checkout + uses: actions/checkout@v7 + + - name: Setup Python (Windows) + if: matrix.target.os_name == 'windows' + uses: actions/setup-python@v6 + with: + python-version: '3.12' + + - name: Setup MSVC (Windows) + if: matrix.target.os_name == 'windows' + uses: ilammy/msvc-dev-cmd@v1 + with: + arch: ${{ matrix.target.msvc_arch }} + + - name: Install AMBuild + if: matrix.target.os_name == 'windows' + shell: bash + run: python -m pip install --upgrade git+https://github.com/alliedmodders/ambuild.git + + - name: Clone dependencies + shell: bash + run: | + git config --global --add safe.directory '*' + git clone --depth 1 --recurse-submodules -j8 --shallow-submodules https://github.com/rlabrecque/SteamworksSDK.git SteamworksSDK + git clone --depth 1 --recurse-submodules -j8 --shallow-submodules -b 1.12-dev https://github.com/alliedmodders/metamod-source.git mmsource + git clone --depth 1 --recurse-submodules -j8 --shallow-submodules -b ${{ matrix.sm.branch }} https://github.com/alliedmodders/sourcemod.git sourcemod + + - name: Build (Linux) + if: matrix.target.os_name == 'linux' + env: + CC: clang-22 + CXX: clang++-22 + run: | + mkdir build && cd build + python3 ../configure.py \ + --sm-path ../sourcemod \ + --mms-path ../mmsource \ + --steamworks-path ../SteamworksSDK \ + --target ${{ matrix.target.arch }} \ + --enable-optimize + ambuild + + - name: Build (Windows) + if: matrix.target.os_name == 'windows' + shell: bash + run: | + mkdir build && cd build + python ../configure.py \ + --sm-path ../sourcemod \ + --mms-path ../mmsource \ + --steamworks-path ../SteamworksSDK \ + --target ${{ matrix.target.arch }} \ + --enable-optimize + ambuild + + - name: Upload package artifact + uses: actions/upload-artifact@v7 + with: + name: pkg-sm${{ matrix.sm.label }}-${{ matrix.target.os_name }}-${{ matrix.target.arch }} + path: build/package/addons + if-no-files-found: error + + release: + name: Release + needs: build + if: github.event_name == 'push' && github.ref == 'refs/heads/master' + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - name: Checkout + uses: actions/checkout@v7 + with: + fetch-depth: 0 + + - name: Download artifacts + uses: actions/download-artifact@v8 + with: + path: artifacts + + - name: Assemble packages + id: package + run: | + base_version=$(grep -oP 'SMEXT_CONF_VERSION\s+"\K[^"]+' Extension/sdk/smsdk_config.h) + build_number=$(git rev-list --count HEAD) + version="${base_version}-git${build_number}" + echo "version=${version}" >> "$GITHUB_OUTPUT" + + # One package per SourceMod version per OS: Windows as .zip, Linux as + # .tar.gz. Each merges that combination's per-arch slices (the include + # file rides along in every slice). + assets="" + for label in 1.12 1.13; do + for os_name in windows linux; do + dest="package-sm${label}-${os_name}/addons" + mkdir -p "${dest}" + for dir in artifacts/pkg-sm${label}-${os_name}-*/; do + cp -a "${dir}." "${dest}/" + done + if [ "${os_name}" = "windows" ]; then + asset="SteamWorks-${version}-sm${label}-windows.zip" + (cd "package-sm${label}-${os_name}" && zip -r "../${asset}" addons) + else + asset="SteamWorks-${version}-sm${label}-linux.tar.gz" + tar -czf "${asset}" -C "package-sm${label}-${os_name}" addons + fi + assets="${assets} ${asset}" + done + done + echo "assets=${assets# }" >> "$GITHUB_OUTPUT" + + - name: Create release + env: + GH_TOKEN: ${{ github.token }} + run: | + gh release create "v${{ steps.package.outputs.version }}" \ + ${{ steps.package.outputs.assets }} \ + --target "${GITHUB_SHA}" \ + --title "SteamWorks ${{ steps.package.outputs.version }}" \ + --notes "Automated release built from ${GITHUB_SHA}." diff --git a/.gitignore b/.gitignore index 114c66c..4b90c07 100644 --- a/.gitignore +++ b/.gitignore @@ -25,4 +25,8 @@ [Dd]ebug - */ [Rr]elease - */ [Dd]ebug/ -[Rr]elease/ \ No newline at end of file +[Rr]elease/ + +# ambuild output directories +/build/ +/build-*/ \ No newline at end of file diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 20fbad2..0000000 --- a/.travis.yml +++ /dev/null @@ -1,67 +0,0 @@ -git: - depth: 1 - -env: - global: - - secure: "VsvGz6WqBVbT+RpnaWwYb16mVvQHQMvzfRxLlUEnYBVkKCWBgyECDXRL/ShBwGW+aMYW25ZPt/aJNk7rN/wvTrgGU2N9X6CrfVyGPp94HPSYPzEbZSXRoCGex30HkVVITYUBDd06CWuMMIOgS7At/XdJIR1ZjZpOr91Oze3YbGA=" - -matrix: - fast_finish: true - include: - - os: linux - dist: trusty - language: cpp - compiler: gcc - addons: - apt: - sources: ['ubuntu-toolchain-r-test'] - packages: ['lib32stdc++6', 'lib32z1-dev', 'libc6-dev-i386', 'linux-libc-dev', 'g++-multilib'] - env: - - AMB="install --user" - - PATH="~/.local/bin:$PATH" - - RELEASE_PKG_FILE="package-lin.tgz" -# - os: windows -# language: cpp -# env: -# - AMB="install" -# - PATH="$PATH:/C/ProgramData/chocolatey/bin:/C/ProgramData/chocolatey/lib/mingw/tools/install/mingw64/opt/bin" -# - RELEASE_PKG_FILE="package-win.tgz" - - os: mac - osx_image: xcode7.2 - language: cpp - compiler: clang - env: - - AMB="install" - - PATH="~/.local/bin:$PATH" - - RELEASE_PKG_FILE="package-mac.tgz" - -before_script: - - mkdir assets && cd assets - - git clone https://github.com/alliedmodders/ambuild.git - - cd ambuild - - python setup.py build - - python setup.py $AMB - - cd .. - - git clone --depth 1 --recurse-submodules -j8 --shallow-submodules https://$OAUTH@github.com/SteamDatabase/SteamworksSDK.git SteamworksSDK - - git clone --depth 1 --recurse-submodules -j8 --shallow-submodules -b sdk2013 https://github.com/alliedmodders/hl2sdk.git hl2sdk-sdk2013 - - git clone --depth 1 --recurse-submodules -j8 --shallow-submodules -b 1.10-dev https://github.com/alliedmodders/metamod-source.git mmsource-central - - git clone --depth 1 --recurse-submodules -j8 --shallow-submodules -b 1.7-dev https://github.com/alliedmodders/sourcemod.git sourcemod-central - - cd .. - -script: - - mkdir build - - cd build - - cp ../AMBuildScript ../../ - - python2 ../configure.py -s sdk2013 --hl2sdk-root ../assets --sm-path ../assets/sourcemod-central --mms-path ../assets/mmsource-central --steamworks-path ../assets/SteamworksSDK - - ambuild - - tar czvf ${RELEASE_PKG_FILE} package - -deploy: - provider: releases - api_key: - secure: "Px60/dTgw3w6ZvxzyuilYaHHWFHWQ1rONhpbWJbxzz5+dfkmiqVyYLszlBrbS6tbyOv/oBMqcaOXsB7mv4OOlvKQPOjc8siS8ux1Ows8WL+yvRR/rGS0j28pP6HKN11hBerxOps3sqiCyNa2gNJ+3vX987SIekpIb5nqzuqg+yQ=" - file_glob: true - file: "${RELEASE_PKG_FILE}" - skip_cleanup: true - on: - tags: true diff --git a/AMBuildScript b/AMBuildScript index db084e2..24a3682 100644 --- a/AMBuildScript +++ b/AMBuildScript @@ -1,24 +1,5 @@ # vim: set sts=2 ts=8 sw=2 tw=99 et ft=python: -import os, sys - -class SDK(object): - def __init__(self, sdk, ext, aDef, name, platform, dir): - self.folder = 'hl2sdk-' + dir - self.envvar = sdk - self.ext = ext - self.code = aDef - self.define = name - self.platform = platform - self.name = dir - self.path = None # Actual path - -WinOnly = ['windows'] -WinLinux = ['windows', 'linux'] -WinLinuxMac = ['windows', 'linux', 'mac'] - -PossibleSDKs = { - 'sdk2013': SDK('HL2SDK2013', '2.sdk2013', '9', 'SDK2013', WinLinuxMac, 'sdk2013'), -} +import os def ResolveEnvPath(env, folder): if env in os.environ: @@ -43,7 +24,6 @@ def Normalize(path): class SteamWorksConfig(object): def __init__(self): - self.sdks = {} self.binaries = [] self.mms_root = None self.sm_root = None @@ -62,29 +42,7 @@ class SteamWorksConfig(object): return 'Debug' return 'Release' - def detectSDKs(self): - sdk_list = builder.options.sdks.split(',') - use_all = sdk_list[0] == 'all' - use_present = sdk_list[0] == 'present' - - for sdk_name in PossibleSDKs: - sdk = PossibleSDKs[sdk_name] - if builder.cxx.target.platform in sdk.platform: - if builder.options.hl2sdk_root: - sdk_path = os.path.join(builder.options.hl2sdk_root, sdk.folder) - else: - sdk_path = ResolveEnvPath(sdk.envvar, sdk.folder) - if sdk_path is None or not os.path.isdir(sdk_path): - if use_all or sdk_name in sdk_list: - raise Exception('Could not find a valid path for {0}'.format(sdk.envvar)) - continue - if use_all or use_present or sdk_name in sdk_list: - sdk.path = Normalize(sdk_path) - self.sdks[sdk_name] = sdk - - if len(self.sdks) < 1: - raise Exception('At least one SDK must be available.') - + def detectDeps(self): #METAMOD:SOURCE if builder.options.mms_path: self.mms_root = builder.options.mms_path @@ -153,15 +111,22 @@ class SteamWorksConfig(object): '-Wno-format', '-Wno-format-security', '-Wno-array-bounds', - '-msse', - '-m32', ] cxx.cxxflags += [ - '-std=c++11', + '-std=c++17', ] - have_gcc = cxx.vendor == 'gcc' - have_clang = cxx.vendor == 'clang' + if cxx.target.arch == 'x86': + cxx.cflags += ['-msse', '-m32'] + cxx.linkflags += ['-m32'] + if cxx.family == 'gcc': + cxx.cflags += ['-mfpmath=sse'] + elif cxx.target.arch == 'x86_64': + cxx.cflags += ['-m64'] + cxx.linkflags += ['-m64'] + + have_gcc = cxx.family == 'gcc' + have_clang = cxx.family == 'clang' if have_clang or (have_gcc and cxx.version >= '4'): cxx.cflags += ['-fvisibility=hidden'] cxx.cxxflags += ['-fvisibility-inlines-hidden'] @@ -179,17 +144,13 @@ class SteamWorksConfig(object): cxx.cxxflags += ['-Wno-deprecated'] cxx.cflags += ['-Wno-sometimes-uninitialized'] - cxx.linkflags += ['-m32'] cxx.cxxflags += [ '-fno-exceptions', '-fno-threadsafe-statics', '-Wno-non-virtual-dtor', '-Wno-overloaded-virtual', ] - - if have_gcc: - cxx.cflags += ['-mfpmath=sse'] - elif cxx.vendor == 'msvc': + elif cxx.like('msvc'): if builder.options.debug == '1': cxx.cflags += ['/MTd'] cxx.linkflags += ['/NODEFAULTLIB:libcmt'] @@ -208,9 +169,10 @@ class SteamWorksConfig(object): '/EHsc', '/GR-', '/TP', + '/std:c++17', ] cxx.linkflags += [ - '/MACHINE:X86', + '/MACHINE:X64' if cxx.target.arch == 'x86_64' else '/MACHINE:X86', '/SUBSYSTEM:WINDOWS', 'kernel32.lib', 'user32.lib', @@ -244,27 +206,17 @@ class SteamWorksConfig(object): cxx.cflags += ['/d2Zi+'] # This needs to be after our optimization flags which could otherwise disable it. - if cxx.vendor == 'msvc': + if cxx.like('msvc'): # Don't omit the frame pointer. cxx.cflags += ['/Oy-'] # Platform-specifics if cxx.target.platform == 'linux': cxx.defines += ['_LINUX', 'POSIX'] - if cxx.vendor == 'gcc': + if cxx.family == 'gcc': cxx.linkflags += ['-static-libgcc'] - elif cxx.vendor == 'clang': + elif cxx.family == 'clang': cxx.linkflags += ['-lgcc_eh'] - elif cxx.target.platform == 'mac': - cxx.defines += ['OSX', '_OSX', 'POSIX'] - cxx.cflags += ['-mmacosx-version-min=10.5'] - cxx.linkflags += [ - '-mmacosx-version-min=10.5', - '-arch', 'i386', - '-static', - '-stdlib=libc++' - ] - cxx.cxxflags += ['-stdlib=libstdc++'] elif cxx.target.platform == 'windows': cxx.defines += ['WIN32', '_WINDOWS'] @@ -274,49 +226,35 @@ class SteamWorksConfig(object): os.path.join(context.currentSourcePath, 'sdk'), os.path.join(self.sm_root, 'public'), os.path.join(self.sm_root, 'public', 'extensions'), - os.path.join(self.sm_root, 'public', 'sourcepawn'), + os.path.join(self.sm_root, 'sourcepawn', 'include'), + os.path.join(self.sm_root, 'public', 'amtl', 'amtl'), + os.path.join(self.sm_root, 'public', 'amtl'), ] return compiler - def ConfigureForHL2(self, binary, sdk): + def ConfigureForHL2(self, binary): compiler = binary.compiler - if sdk.name == 'episode1': - mms_path = os.path.join(self.mms_root, 'core-legacy') - else: - mms_path = os.path.join(self.mms_root, 'core') + mms_path = os.path.join(self.mms_root, 'core') compiler.cxxincludes += [ os.path.join(mms_path), os.path.join(mms_path, 'sourcehook'), ] - defines = ['SE_' + PossibleSDKs[i].define + '=' + PossibleSDKs[i].code for i in PossibleSDKs] - compiler.defines += defines - - if compiler.like('msvc'): - compiler.defines += ['COMPILER_MSVC', 'COMPILER_MSVC32'] - else: - compiler.defines += ['COMPILER_GCC'] - return binary - def HL2Library(self, context, name, sdk): - binary = context.compiler.Library(name) - self.ConfigureForExtension(context, binary.compiler) - return self.ConfigureForHL2(binary, sdk) - def HL2Project(self, context, name): project = context.LibraryProject(name) self.ConfigureForExtension(context, context.cxx) return project - def HL2Config(self, project, cxx, name, sdk): - binary = project.Configure(cxx, name, '{0} - {1}'.format(self.tag, sdk.name)) - return self.ConfigureForHL2(binary, sdk) + def HL2Config(self, project, cxx, name): + binary = project.Configure(cxx, name, '{0}'.format(self.tag)) + return self.ConfigureForHL2(binary) SteamWorks = SteamWorksConfig() -SteamWorks.detectSDKs() +SteamWorks.detectDeps() SteamWorks.configure() BuildScripts = ['Extension/AMBuilder'] diff --git a/Extension/AMBuilder b/Extension/AMBuilder index 64d57e0..c364657 100644 --- a/Extension/AMBuilder +++ b/Extension/AMBuilder @@ -1,6 +1,51 @@ # vim: set sts=2 ts=8 sw=2 tw=99 et ft=python: import os +# --- SafetyHook ----------------------------------------------------------------- +# The extension's detours use SourceMod's safetyhook-based CDetour, which handles +# both x86 and x86_64, replacing the old x86-only asm trampolines. Build safetyhook +# as a static library straight out of the SourceMod tree. +sh_root = os.path.join(SteamWorks.sm_root, 'public', 'safetyhook') + +libsafetyhook = builder.StaticLibraryProject('safetyhook') +libsafetyhook.sources += [ + os.path.join(sh_root, 'src', 'allocator.cpp'), + os.path.join(sh_root, 'src', 'easy.cpp'), + os.path.join(sh_root, 'src', 'inline_hook.cpp'), + os.path.join(sh_root, 'src', 'mid_hook.cpp'), + os.path.join(sh_root, 'src', 'utility.cpp'), + os.path.join(sh_root, 'src', 'vmt_hook.cpp'), + os.path.join(sh_root, 'zydis', 'Zydis.c'), +] + +sh_binary = libsafetyhook.Configure(builder.cxx, 'safetyhook', + 'Release - {0}'.format(builder.cxx.target.arch)) +sh_cxx = sh_binary.compiler +# safetyhook is third-party; compile it with its own flag set. +sh_cxx.cxxflags = [] +sh_cxx.cflags = [] +sh_cxx.defines = [] +sh_cxx.includes = [] +sh_cxx.cxxincludes = [] + +if builder.options.debug != '1': + sh_cxx.defines += ['NDEBUG'] + +if sh_cxx.target.platform == 'windows': + sh_cxx.cflags += ['/W4'] + sh_cxx.cflags += ['/MTd' if builder.options.debug == '1' else '/MT'] + sh_cxx.cxxflags += ['/EHsc', '/permissive-', '/std:c++17'] + sh_binary.sources += [os.path.join(sh_root, 'src', 'os.windows.cpp')] +elif sh_cxx.target.platform == 'linux': + sh_cxx.cflags += ['-fPIC', '-Wall', '-Wno-unused-function', '-Wno-unused-const-variable'] + sh_cxx.cflags += ['-m64' if sh_cxx.target.arch == 'x86_64' else '-m32'] + sh_cxx.cxxflags += ['-std=c++17', '-Wno-format'] + sh_binary.sources += [os.path.join(sh_root, 'src', 'os.linux.cpp')] + +sh_cxx.includes += [os.path.join(sh_root, 'include'), os.path.join(sh_root, 'zydis')] +safetyhook_tasks = builder.Add(libsafetyhook) + +# --- SteamWorks extension ------------------------------------------------------- project = SteamWorks.HL2Project(builder, 'SteamWorks.ext') project.sources += [ 'extension.cpp', @@ -16,25 +61,36 @@ project.sources += [ 'swhttprequest.cpp', 'swgchooks.cpp', 'sdk/smsdk_ext.cpp', - 'CDetour/detours.cpp', - 'asm/asm.c' + os.path.join(SteamWorks.sm_root, 'public', 'CDetour', 'detours.cpp'), ] -for sdk_name in SteamWorks.sdks: - sdk = SteamWorks.sdks[sdk_name] +binary = SteamWorks.HL2Config(project, builder.cxx, 'SteamWorks.ext') - binary = SteamWorks.HL2Config(project, builder.cxx, 'SteamWorks.ext', sdk) - - binary.compiler.defines += ['META_NO_HL2SDK', 'SOURCEMOD_BUILD', 'VERSION_SAFE_STEAM_API_INTERFACES'] - binary.compiler.cxxincludes += [os.path.join(SteamWorks.steamworks_root, 'public', 'steam'), os.path.join(sdk.path, 'public', 'steam')]; - - if binary.compiler.target.platform == 'linux': - binary.compiler.postlink += os.path.join(SteamWorks.steamworks_root, 'redistributable_bin', 'linux32', 'libsteam_api.so'),; - - if binary.compiler.target.platform == 'windows': - binary.compiler.postlink += os.path.join(SteamWorks.steamworks_root, 'redistributable_bin', 'steam_api.lib'),; - - if binary.compiler.target.platform == 'mac': - binary.compiler.postlink += os.path.join(SteamWorks.steamworks_root, 'redistributable_bin', 'osx', 'libsteam_api.dylib'),; +# The Steam API headers all come from the SteamWorks SDK; the extension is built +# with META_NO_HL2SDK, so no HL2SDK is required. +binary.compiler.defines += ['META_NO_HL2SDK', 'SOURCEMOD_BUILD', 'VERSION_SAFE_STEAM_API_INTERFACES'] +binary.compiler.cxxincludes += [os.path.join(SteamWorks.steamworks_root, 'public', 'steam')] +binary.compiler.cxxincludes += [os.path.join(SteamWorks.sm_root, 'public', 'safetyhook', 'include')] + +# Link the matching-arch safetyhook static library. +for task in safetyhook_tasks: + if task.target.arch == binary.compiler.target.arch: + binary.compiler.linkflags += [task.binary] + break + +steamworks_bin = os.path.join(SteamWorks.steamworks_root, 'redistributable_bin') +arch = binary.compiler.target.arch + +if binary.compiler.target.platform == 'linux': + if arch == 'x86_64': + binary.compiler.postlink += [os.path.join(steamworks_bin, 'linux64', 'libsteam_api.so')] + else: + binary.compiler.postlink += [os.path.join(steamworks_bin, 'linux32', 'libsteam_api.so')] + +if binary.compiler.target.platform == 'windows': + if arch == 'x86_64': + binary.compiler.postlink += [os.path.join(steamworks_bin, 'win64', 'steam_api64.lib')] + else: + binary.compiler.postlink += [os.path.join(steamworks_bin, 'steam_api.lib')] SteamWorks.extensions += builder.Add(project) diff --git a/Extension/CDetour/detourhelpers.h b/Extension/CDetour/detourhelpers.h deleted file mode 100644 index cff73cc..0000000 --- a/Extension/CDetour/detourhelpers.h +++ /dev/null @@ -1,100 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod - * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id: detourhelpers.h 248 2008-08-27 00:56:22Z pred $ - */ - -#ifndef _INCLUDE_SOURCEMOD_DETOURHELPERS_H_ -#define _INCLUDE_SOURCEMOD_DETOURHELPERS_H_ - -#if defined PLATFORM_POSIX -#include -#ifndef PAGE_SIZE -#define PAGE_SIZE 4096 -#endif -#define ALIGN(ar) ((long)ar & ~(PAGE_SIZE-1)) -#define PAGE_EXECUTE_READWRITE PROT_READ|PROT_WRITE|PROT_EXEC -#endif - -struct patch_t -{ - patch_t() - { - patch[0] = 0; - bytes = 0; - } - unsigned char patch[20]; - size_t bytes; -}; - -inline void ProtectMemory(void *addr, int length, int prot) -{ -#if defined PLATFORM_POSIX - void *addr2 = (void *)ALIGN(addr); - mprotect(addr2, sysconf(_SC_PAGESIZE), prot); -#elif defined PLATFORM_WINDOWS - DWORD old_prot; - VirtualProtect(addr, length, prot, &old_prot); -#endif -} - -inline void SetMemPatchable(void *address, size_t size) -{ - ProtectMemory(address, (int)size, PAGE_EXECUTE_READWRITE); -} - -inline void DoGatePatch(unsigned char *target, void *callback) -{ - SetMemPatchable(target, 20); - - target[0] = 0xFF; /* JMP */ - target[1] = 0x25; /* MEM32 */ - *(void **)(&target[2]) = callback; -} - -inline void ApplyPatch(void *address, int offset, const patch_t *patch, patch_t *restore) -{ - ProtectMemory(address, 20, PAGE_EXECUTE_READWRITE); - - unsigned char *addr = (unsigned char *)address + offset; - if (restore) - { - for (size_t i=0; ibytes; i++) - { - restore->patch[i] = addr[i]; - } - restore->bytes = patch->bytes; - } - - for (size_t i=0; ibytes; i++) - { - addr[i] = patch->patch[i]; - } -} - -#endif //_INCLUDE_SOURCEMOD_DETOURHELPERS_H_ diff --git a/Extension/CDetour/detours.cpp b/Extension/CDetour/detours.cpp deleted file mode 100644 index 9e30414..0000000 --- a/Extension/CDetour/detours.cpp +++ /dev/null @@ -1,228 +0,0 @@ -/** -* vim: set ts=4 : -* ============================================================================= -* SourceMod -* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. -* ============================================================================= -* -* This program is free software; you can redistribute it and/or modify it under -* the terms of the GNU General Public License, version 3.0, as published by the -* Free Software Foundation. -* -* This program is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more -* details. -* -* You should have received a copy of the GNU General Public License along with -* this program. If not, see . -* -* As a special exception, AlliedModders LLC gives you permission to link the -* code of this program (as well as its derivative works) to "Half-Life 2," the -* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software -* by the Valve Corporation. You must obey the GNU General Public License in -* all respects for all other code used. Additionally, AlliedModders LLC grants -* this exception to all derivative works. AlliedModders LLC defines further -* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), -* or . -* -* Version: $Id: detours.cpp 248 2008-08-27 00:56:22Z pred $ -*/ - -#include "detours.h" -#include - -ISourcePawnEngine *CDetourManager::spengine = NULL; -IGameConfig *CDetourManager::gameconf = NULL; - -void CDetourManager::Init(ISourcePawnEngine *spengine, IGameConfig *gameconf) -{ - CDetourManager::spengine = spengine; - CDetourManager::gameconf = gameconf; -} - -CDetour *CDetourManager::CreateDetour(void *callbackfunction, void **trampoline, const char *signame) -{ - CDetour *detour = new CDetour(callbackfunction, trampoline, signame); - if (detour) - { - if (!detour->Init(spengine, gameconf)) - { - delete detour; - return NULL; - } - - return detour; - } - - return NULL; -} - -CDetour *CDetourManager::CreateDetour(void *callbackfunction, void **trampoline, void *address) -{ - CDetour *detour = new CDetour(callbackfunction, trampoline, address); - if (detour) - { - if (!detour->Init(spengine, gameconf)) - { - delete detour; - return NULL; - } - - return detour; - } - - return NULL; -} - -CDetour::CDetour(void *callbackfunction, void **trampoline, const char *signame) -{ - enabled = false; - detoured = false; - detour_address = NULL; - detour_trampoline = NULL; - this->signame = signame; - this->address = NULL; - this->detour_callback = callbackfunction; - spengine = NULL; - gameconf = NULL; - this->trampoline = trampoline; -} - -CDetour::CDetour(void *callbackfunction, void **trampoline, void *pAddress) -{ - enabled = false; - detoured = false; - detour_address = NULL; - detour_trampoline = NULL; - this->signame = NULL; - this->address = pAddress; - this->detour_callback = callbackfunction; - spengine = NULL; - gameconf = NULL; - this->trampoline = trampoline; -} - -bool CDetour::Init(ISourcePawnEngine *spengine, IGameConfig *gameconf) -{ - this->spengine = spengine; - this->gameconf = gameconf; - - if (!CreateDetour()) - { - enabled = false; - return enabled; - } - - enabled = true; - - return enabled; -} - -void CDetour::Destroy() -{ - DeleteDetour(); - delete this; -} - -bool CDetour::IsEnabled() -{ - return enabled; -} - -bool CDetour::CreateDetour() -{ - if (signame != NULL && !gameconf->GetMemSig(signame, &detour_address)) - { - g_pSM->LogError(myself, "Could not locate %s - Disabling detour", signame); - return false; - } - else if (address != NULL) - { - detour_address = address; - } - - if (!detour_address) - { - g_pSM->LogError(myself, "Sigscan for %s failed - Disabling detour to prevent crashes", signame); - return false; - } - - detour_restore.bytes = copy_bytes((unsigned char *)detour_address, NULL, OP_JMP_SIZE+1); - - /* First, save restore bits */ - for (size_t i=0; iAllocatePageMemory(CodeSize); - spengine->SetReadWrite(wr.outbase); - wr.outptr = wr.outbase; - detour_trampoline = wr.outbase; - goto jit_rewind; - } - - spengine->SetReadExecute(wr.outbase); - - *trampoline = detour_trampoline; - - return true; -} - -void CDetour::DeleteDetour() -{ - if (detoured) - { - DisableDetour(); - } - - if (detour_trampoline) - { - /* Free the allocated trampoline memory */ - spengine->FreePageMemory(detour_trampoline); - detour_trampoline = NULL; - } -} - -void CDetour::EnableDetour() -{ - if (!detoured) - { - DoGatePatch((unsigned char *)detour_address, &detour_callback); - detoured = true; - } -} - -void CDetour::DisableDetour() -{ - if (detoured) - { - /* Remove the patch */ - ApplyPatch(detour_address, 0, &detour_restore, NULL); - detoured = false; - } -} diff --git a/Extension/CDetour/detours.h b/Extension/CDetour/detours.h deleted file mode 100644 index c68d299..0000000 --- a/Extension/CDetour/detours.h +++ /dev/null @@ -1,249 +0,0 @@ -/** -* vim: set ts=4 : -* ============================================================================= -* SourceMod -* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. -* ============================================================================= -* -* This program is free software; you can redistribute it and/or modify it under -* the terms of the GNU General Public License, version 3.0, as published by the -* Free Software Foundation. -* -* This program is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more -* details. -* -* You should have received a copy of the GNU General Public License along with -* this program. If not, see . -* -* As a special exception, AlliedModders LLC gives you permission to link the -* code of this program (as well as its derivative works) to "Half-Life 2," the -* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software -* by the Valve Corporation. You must obey the GNU General Public License in -* all respects for all other code used. Additionally, AlliedModders LLC grants -* this exception to all derivative works. AlliedModders LLC defines further -* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), -* or . -* -* Version: $Id: detours.h 257 2008-09-23 03:12:13Z pred $ -*/ - -#ifndef _INCLUDE_SOURCEMOD_DETOURS_H_ -#define _INCLUDE_SOURCEMOD_DETOURS_H_ - -#include "smsdk_ext.h" -#include -#include -#include "detourhelpers.h" - -/** - * CDetours class for SourceMod Extensions by pRED* - * detourhelpers.h entirely stolen from CSS:DM and were written by BAILOPAN (I assume). - * asm.h/c from devmaster.net (thanks cybermind) edited by pRED* to handle gcc -fPIC thunks correctly - * Concept by Nephyrin Zey (http://www.doublezen.net/) and Windows Detour Library (http://research.microsoft.com/sn/detours/) - * Member function pointer ideas by Don Clugston (http://www.codeproject.com/cpp/FastDelegate.asp) - */ - -#define DETOUR_MEMBER_CALL(name) (this->*name##_Actual) -#define DETOUR_STATIC_CALL(name) (name##_Actual) - -#define DETOUR_DECL_STATIC0(name, ret) \ -ret (*name##_Actual)(void) = NULL; \ -ret name(void) - -#define DETOUR_DECL_STATIC1(name, ret, p1type, p1name) \ -ret (*name##_Actual)(p1type) = NULL; \ -ret name(p1type p1name) - -#define DETOUR_DECL_STATIC4(name, ret, p1type, p1name, p2type, p2name, p3type, p3name, p4type, p4name) \ -ret (*name##_Actual)(p1type, p2type, p3type, p4type) = NULL; \ -ret name(p1type p1name, p2type p2name, p3type p3name, p4type p4name) - -#define DETOUR_DECL_STATIC6(name, ret, p1type, p1name, p2type, p2name, p3type, p3name, p4type, p4name, p5type, p5name, p6type, p6name) \ -ret (*name##_Actual)(p1type, p2type, p3type, p4type, p5type, p6type) = NULL; \ -ret name(p1type p1name, p2type p2name, p3type p3name, p4type p4name, p5type p5name, p6type p6name) - -#define DETOUR_DECL_MEMBER0(name, ret) \ -class name##Class \ -{ \ -public: \ - ret name(); \ - static ret (name##Class::* name##_Actual)(void); \ -}; \ -ret (name##Class::* name##Class::name##_Actual)(void) = NULL; \ -ret name##Class::name() - -#define DETOUR_DECL_MEMBER1(name, ret, p1type, p1name) \ -class name##Class \ -{ \ -public: \ - ret name(p1type p1name); \ - static ret (name##Class::* name##_Actual)(p1type); \ -}; \ -ret (name##Class::* name##Class::name##_Actual)(p1type) = NULL; \ -ret name##Class::name(p1type p1name) - -#define DETOUR_DECL_MEMBER2(name, ret, p1type, p1name, p2type, p2name) \ -class name##Class \ -{ \ -public: \ - ret name(p1type p1name, p2type p2name); \ - static ret (name##Class::* name##_Actual)(p1type, p2type); \ -}; \ -ret (name##Class::* name##Class::name##_Actual)(p1type, p2type) = NULL; \ -ret name##Class::name(p1type p1name, p2type p2name) - -#define DETOUR_DECL_MEMBER3(name, ret, p1type, p1name, p2type, p2name, p3type, p3name) \ -class name##Class \ -{ \ -public: \ - ret name(p1type p1name, p2type p2name, p3type p3name); \ - static ret (name##Class::* name##_Actual)(p1type, p2type, p3type); \ -}; \ -ret (name##Class::* name##Class::name##_Actual)(p1type, p2type, p3type) = NULL; \ -ret name##Class::name(p1type p1name, p2type p2name, p3type p3name) - -#define DETOUR_DECL_MEMBER4(name, ret, p1type, p1name, p2type, p2name, p3type, p3name, p4type, p4name) \ -class name##Class \ -{ \ -public: \ - ret name(p1type p1name, p2type p2name, p3type p3name, p4type p4name); \ - static ret (name##Class::* name##_Actual)(p1type, p2type, p3type, p4type); \ -}; \ -ret (name##Class::* name##Class::name##_Actual)(p1type, p2type, p3type, p4type) = NULL; \ -ret name##Class::name(p1type p1name, p2type p2name, p3type p3name, p4type p4name) - - -#define GET_MEMBER_CALLBACK(name) (void *)GetCodeAddress(&name##Class::name) -#define GET_MEMBER_TRAMPOLINE(name) (void **)(&name##Class::name##_Actual) - -#define GET_STATIC_CALLBACK(name) (void *)&name -#define GET_STATIC_TRAMPOLINE(name) (void **)&name##_Actual - -#define DETOUR_CREATE_MEMBER(name, gamedata) CDetourManager::CreateDetour(GET_MEMBER_CALLBACK(name), GET_MEMBER_TRAMPOLINE(name), gamedata); -#define DETOUR_CREATE_STATIC(name, gamedata) CDetourManager::CreateDetour(GET_STATIC_CALLBACK(name), GET_STATIC_TRAMPOLINE(name), gamedata); -#define DETOUR_CREATE_STATIC_FIXED(name, address) CDetourManager::CreateDetour(GET_STATIC_CALLBACK(name), GET_STATIC_TRAMPOLINE(name), address); - - -class GenericClass {}; -typedef void (GenericClass::*VoidFunc)(); - -inline void *GetCodeAddr(VoidFunc mfp) -{ - return *(void **)&mfp; -} - -/** - * Converts a member function pointer to a void pointer. - * This relies on the assumption that the code address lies at mfp+0 - * This is the case for both g++ and later MSVC versions on non virtual functions but may be different for other compilers - * Based on research by Don Clugston : http://www.codeproject.com/cpp/FastDelegate.asp - */ -#define GetCodeAddress(mfp) GetCodeAddr(reinterpret_cast(mfp)) - -class CDetourManager; - -class CDetour -{ -public: - - bool IsEnabled(); - - /** - * These would be somewhat self-explanatory I hope - */ - void EnableDetour(); - void DisableDetour(); - - void Destroy(); - - friend class CDetourManager; - -protected: - CDetour(void *callbackfunction, void **trampoline, const char *signame); - CDetour(void *callbackfunction, void **trampoline, void *address); - - bool Init(ISourcePawnEngine *spengine, IGameConfig *gameconf); -private: - - /* These create/delete the allocated memory */ - bool CreateDetour(); - void DeleteDetour(); - - bool enabled; - bool detoured; - - patch_t detour_restore; - /* Address of the detoured function */ - void *detour_address; - /* Address of the allocated trampoline function */ - void *detour_trampoline; - /* Address of the callback handler */ - void *detour_callback; - /* The function pointer used to call our trampoline */ - void **trampoline; - - const char *signame; - void *address; - ISourcePawnEngine *spengine; - IGameConfig *gameconf; -}; - -class CDetourManager -{ -public: - - static void Init(ISourcePawnEngine *spengine, IGameConfig *gameconf); - - /** - * Creates a new detour - * - * @param callbackfunction Void pointer to your detour callback function. - * @param trampoline Address of the trampoline pointer - * @param signame Section name containing a signature to fetch from the gamedata file. - * @return A new CDetour pointer to control your detour. - * - * Example: - * - * CBaseServer::ConnectClient(netadr_s &, int, int, int, char const*, char const*, char const*, int) - * - * Define a new class with the required function and a member function pointer to the same type: - * - * class CBaseServerDetour - * { - * public: - * bool ConnectClient(void *netaddr_s, int, int, int, char const*, char const*, char const*, int); - * static bool (CBaseServerDetour::* ConnectClient_Actual)(void *netaddr_s, int, int, int, char const*, char const*, char const*, int); - * } - * - * void *callbackfunc = GetCodeAddress(&CBaseServerDetour::ConnectClient); - * void **trampoline = (void **)(&CBaseServerDetour::ConnectClient_Actual); - * - * Creation: - * CDetourManager::CreateDetour(callbackfunc, trampoline, "ConnectClient"); - * - * Usage: - * - * CBaseServerDetour::ConnectClient(void *netaddr_s, int, int, int, char const*, char const*, char const*, int) - * { - * //pre hook code - * bool result = (this->*ConnectClient_Actual)(netaddr_s, rest of params); - * //post hook code - * return result; - * } - * - * Note we changed the netadr_s reference into a void* to avoid needing to define the type - */ - static CDetour *CreateDetour(void *callbackfunction, void **trampoline, const char *signame); - static CDetour *CreateDetour(void *callbackfunction, void **trampoline, void *address); - - friend class CBlocker; - friend class CDetour; - -private: - static ISourcePawnEngine *spengine; - static IGameConfig *gameconf; -}; - -#endif // _INCLUDE_SOURCEMOD_DETOURS_H_ diff --git a/Extension/Makefile b/Extension/Makefile deleted file mode 100644 index 338ba59..0000000 --- a/Extension/Makefile +++ /dev/null @@ -1,252 +0,0 @@ -# (C)2004-2010 SourceMod Development Team -# Makefile written by David "BAILOPAN" Anderson - -########################################### -### EDIT THESE PATHS FOR YOUR OWN SETUP ### -########################################### - -SMSDK = ../.. -HL2SDK_ORIG = ../../../hl2sdk -HL2SDK_OB = ../../../hl2sdk-ob -HL2SDK_CSS = ../../../hl2sdk-css -HL2SDK_OB_VALVE = ../../../hl2sdk-2013 -HL2SDK_L4D = ../../../hl2sdk-l4d -HL2SDK_L4D2 = ../../../hl2sdk-l4d2 -HL2SDK_CSGO = ../../../hl2sdk-csgo -MMSOURCE19 = ../../../mmsource-1.9 -STEAMWORKS = ../../../opensteamworks - -##################################### -### EDIT BELOW FOR OTHER PROJECTS ### -##################################### - -PROJECT = SteamWorks - -#Uncomment for Metamod: Source enabled extension -#USEMETA = true -USESH = true -USECD = true - -OBJECTS = sdk/smsdk_ext.cpp extension.cpp swgameserver.cpp swgamedata.cpp swforwards.cpp gsnatives.cpp swgshooks.cpp swgsdetours.cpp ssnatives.cpp swhttp.cpp swhttprequest.cpp - -ifeq "$(USECD)" "true" - OBJECTS += CDetour/detours.cpp asm/asm.c -endif - -############################################## -### CONFIGURE ANY OTHER FLAGS/OPTIONS HERE ### -############################################## - -C_OPT_FLAGS = -DNDEBUG -O3 -funroll-loops -pipe -fno-strict-aliasing -C_DEBUG_FLAGS = -D_DEBUG -DDEBUG -g -ggdb3 -C_GCC4_FLAGS = -fvisibility=hidden -CPP_GCC4_FLAGS = -fvisibility-inlines-hidden -CPP = gcc -CPP_OSX = clang - -########################## -### SDK CONFIGURATIONS ### -########################## - -override ENGSET = false - -# Check for valid list of engines -ifneq (,$(filter original orangebox orangeboxvalve css left4dead left4dead2 csgo,$(ENGINE))) - override ENGSET = true -endif - -ifeq "$(ENGINE)" "original" - HL2SDK = $(HL2SDK_ORIG) - CFLAGS += -DSOURCE_ENGINE=1 -endif -ifeq "$(ENGINE)" "orangebox" - HL2SDK = $(HL2SDK_OB) - CFLAGS += -DSOURCE_ENGINE=3 -endif -ifeq "$(ENGINE)" "css" - HL2SDK = $(HL2SDK_CSS) - CFLAGS += -DSOURCE_ENGINE=6 -endif -ifeq "$(ENGINE)" "orangeboxvalve" - HL2SDK = $(HL2SDK_OB_VALVE) - CFLAGS += -DSOURCE_ENGINE=7 -endif -ifeq "$(ENGINE)" "left4dead" - HL2SDK = $(HL2SDK_L4D) - CFLAGS += -DSOURCE_ENGINE=8 -endif -ifeq "$(ENGINE)" "left4dead2" - HL2SDK = $(HL2SDK_L4D2) - CFLAGS += -DSOURCE_ENGINE=9 -endif -ifeq "$(ENGINE)" "csgo" - HL2SDK = $(HL2SDK_CSGO) - CFLAGS += -DSOURCE_ENGINE=12 -endif - -HL2PUB = $(HL2SDK)/public - -ifeq "$(ENGINE)" "original" - INCLUDE += -I$(HL2SDK)/public/dlls - METAMOD = $(MMSOURCE19)/core-legacy -else - INCLUDE += -I$(HL2SDK)/public/game/server - METAMOD = $(MMSOURCE19)/core -endif - -OS := $(shell uname -s) - -ifeq "$(OS)" "Darwin" - LIB_EXT = dylib - HL2LIB = $(HL2SDK)/lib/mac -else - LIB_EXT = so - ifeq "$(ENGINE)" "original" - HL2LIB = $(HL2SDK)/linux_sdk - else - HL2LIB = $(HL2SDK)/lib/linux - endif -endif - -# if ENGINE is original or OB -ifneq (,$(filter original orangebox,$(ENGINE))) - LIB_SUFFIX = _i486.$(LIB_EXT) -else - LIB_PREFIX = lib - LIB_SUFFIX = .$(LIB_EXT) -endif - -INCLUDE += -I. -I.. -Isdk -I$(SMSDK)/public -I$(SMSDK)/public/sourcepawn - -ifeq "$(USEMETA)" "true" - LINK_HL2 = $(HL2LIB)/tier1_i486.a $(LIB_PREFIX)vstdlib$(LIB_SUFFIX) $(LIB_PREFIX)tier0$(LIB_SUFFIX) - ifeq "$(ENGINE)" "csgo" - LINK_HL2 += $(HL2LIB)/interfaces_i486.a - endif - - LINK += $(LINK_HL2) - - INCLUDE += -I$(HL2PUB) -I$(HL2PUB)/engine -I$(HL2PUB)/tier0 -I$(HL2PUB)/tier1 -I$(METAMOD) \ - -I$(METAMOD)/sourcehook - CFLAGS += -DSE_EPISODEONE=1 -DSE_DARKMESSIAH=2 -DSE_ORANGEBOX=3 -DSE_BLOODYGOODTIME=4 -DSE_EYE=5 \ - -DSE_CSS=6 -DSE_ORANGEBOXVALVE=7 -DSE_LEFT4DEAD=8 -DSE_LEFT4DEAD2=9 -DSE_ALIENSWARM=10 \ - -DSE_PORTAL2=11 -DSE_CSGO=12 -endif - -ifeq "$(USESH)" "true" - INCLUDE += -I$(METAMOD) -I$(METAMOD)/sourcehook - CFLAGS += -DMETA_NO_HL2SDK -endif - -LINK += -m32 -lm -ldl -LINK += $(STEAMWORKS)/redistributable_bin/linux32/libsteam_api.so - -CFLAGS += -DPOSIX -Dstricmp=strcasecmp -D_stricmp=strcasecmp -D_strnicmp=strncasecmp -Dstrnicmp=strncasecmp \ - -D_snprintf=snprintf -D_vsnprintf=vsnprintf -D_alloca=alloca -Dstrcmpi=strcasecmp -DCOMPILER_GCC -Wall -Werror \ - -Wno-overloaded-virtual -Wno-switch -Wno-unused -msse -DSOURCEMOD_BUILD -DHAVE_STDINT_H -m32 -CPPFLAGS += -Wno-non-virtual-dtor -fno-exceptions -fno-rtti - -INCLUDE += -I$(STEAMWORKS)/public/steam -INCLUDE += -I$(HL2SDK)/public/steam - -CFLAGS += -DVERSION_SAFE_STEAM_API_INTERFACES - -################################################ -### DO NOT EDIT BELOW HERE FOR MOST PROJECTS ### -################################################ - -BINARY = $(PROJECT).ext.$(LIB_EXT) - -ifeq "$(DEBUG)" "true" - BIN_DIR = Debug - CFLAGS += $(C_DEBUG_FLAGS) -else - BIN_DIR = Release - CFLAGS += $(C_OPT_FLAGS) -endif - -ifeq "$(USEMETA)" "true" - BIN_DIR := $(BIN_DIR).$(ENGINE) -endif - -ifeq "$(OS)" "Darwin" - CPP = $(CPP_OSX) - LIB_EXT = dylib - CFLAGS += -DOSX -D_OSX - LINK += -dynamiclib -lstdc++ -mmacosx-version-min=10.5 -else - LIB_EXT = so - CFLAGS += -D_LINUX - LINK += -shared -endif - -IS_CLANG := $(shell $(CPP) --version | head -1 | grep clang > /dev/null && echo "1" || echo "0") - -ifeq "$(IS_CLANG)" "1" - CPP_MAJOR := $(shell $(CPP) --version | grep clang | sed "s/.*version \([0-9]\)*\.[0-9]*.*/\1/") - CPP_MINOR := $(shell $(CPP) --version | grep clang | sed "s/.*version [0-9]*\.\([0-9]\)*.*/\1/") -else - CPP_MAJOR := $(shell $(CPP) -dumpversion >&1 | cut -b1) - CPP_MINOR := $(shell $(CPP) -dumpversion >&1 | cut -b3) -endif - -# If not clang -ifeq "$(IS_CLANG)" "0" - CFLAGS += -mfpmath=sse -endif - -# Clang || GCC >= 4 -ifeq "$(shell expr $(IS_CLANG) \| $(CPP_MAJOR) \>= 4)" "1" - CFLAGS += $(C_GCC4_FLAGS) - CPPFLAGS += $(CPP_GCC4_FLAGS) -endif - -# Clang >= 3 || GCC >= 4.7 -ifeq "$(shell expr $(IS_CLANG) \& $(CPP_MAJOR) \>= 3 \| $(CPP_MAJOR) \>= 4 \& $(CPP_MINOR) \>= 7)" "1" - CFLAGS += -Wno-delete-non-virtual-dtor -endif - -# OS is Linux and not using clang -ifeq "$(shell expr $(OS) \= Linux \& $(IS_CLANG) \= 0)" "1" - LINK += -static-libgcc -endif - -OBJ_BIN := $(OBJECTS:%.cpp=$(BIN_DIR)/%.o) - -# This will break if we include other Makefiles, but is fine for now. It allows -# us to make a copy of this file that uses altered paths (ie. Makefile.mine) -# or other changes without mucking up the original. -MAKEFILE_NAME := $(CURDIR)/$(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST)) - -$(BIN_DIR)/%.o: %.cpp - $(CPP) $(INCLUDE) $(CFLAGS) $(CPPFLAGS) -o $@ -c $< - -all: check - mkdir -p $(BIN_DIR)/sdk - mkdir -p $(BIN_DIR)/CDetour - if [ "$(USEMETA)" = "true" ]; then \ - ln -sf $(HL2LIB)/$(LIB_PREFIX)vstdlib$(LIB_SUFFIX); \ - ln -sf $(HL2LIB)/$(LIB_PREFIX)tier0$(LIB_SUFFIX); \ - fi - $(MAKE) -f $(MAKEFILE_NAME) extension - -check: - if [ "$(USEMETA)" = "true" ] && [ "$(ENGSET)" = "false" ]; then \ - echo "You must supply one of the following values for ENGINE:"; \ - echo "csgo, left4dead2, left4dead, css, orangeboxvalve, orangebox, or original"; \ - exit 1; \ - fi - -extension: check $(OBJ_BIN) - $(CPP) $(INCLUDE) $(OBJ_BIN) $(LINK) -o $(BIN_DIR)/$(BINARY) - -debug: - $(MAKE) -f $(MAKEFILE_NAME) all DEBUG=true - -default: all - -clean: check - rm -rf $(BIN_DIR)/*.o - rm -rf $(BIN_DIR)/sdk/*.o - rm -rf $(BIN_DIR)/$(BINARY) - diff --git a/Extension/asm/asm.c b/Extension/asm/asm.c deleted file mode 100644 index 7e92d23..0000000 --- a/Extension/asm/asm.c +++ /dev/null @@ -1,418 +0,0 @@ -#include "asm.h" - -#ifndef WIN32 -#define _GNU_SOURCE -#include -#include - -#define REG_EAX 0 -#define REG_ECX 1 -#define REG_EDX 2 -#define REG_EBX 3 - -#define IA32_MOV_REG_IMM 0xB8 // encoding is +r -#endif - -/** -* Checks if a call to a fpic thunk has just been written into dest. -* If found replaces it with a direct mov that sets the required register to the value of pc. -* -* @param dest Destination buffer where a call opcode + addr (5 bytes) has just been written. -* @param pc The program counter value that needs to be set (usually the next address from the source). -* @noreturn -*/ -void check_thunks(unsigned char *dest, unsigned char *pc) -{ -#if defined WIN32 - return; -#else - /* Step write address back 4 to the start of the function address */ - unsigned char *writeaddr = dest - 4; - unsigned char *calloffset = *(unsigned char **)writeaddr; - unsigned char *calladdr = (unsigned char *)(dest + (unsigned int)calloffset); - - /* Lookup name of function being called */ - if ((*calladdr == 0x8B) && (*(calladdr+2) == 0x24) && (*(calladdr+3) == 0xC3)) - { - //a thunk maybe? - char movByte = IA32_MOV_REG_IMM; - - /* Calculate the correct mov opcode */ - switch (*(calladdr+1)) - { - case 0x04: - { - movByte += REG_EAX; - break; - } - case 0x1C: - { - movByte += REG_EBX; - break; - } - case 0x0C: - { - movByte += REG_ECX; - break; - } - case 0x14: - { - movByte += REG_EDX; - break; - } - default: - { - break; - } - } - - /* Move our write address back one to where the call opcode was */ - writeaddr--; - - - /* Write our mov */ - *writeaddr = movByte; - writeaddr++; - - /* Write the value - The provided program counter value */ - *(void **)writeaddr = (void *)pc; - writeaddr += 4; - } - - return; -#endif -} - -//if dest is NULL, returns minimum number of bytes needed to be copied -//if dest is not NULL, it will copy the bytes to dest as well as fix CALLs and JMPs -//http://www.devmaster.net/forums/showthread.php?t=2311 -int copy_bytes(unsigned char *func, unsigned char* dest, int required_len) { - int bytecount = 0; - - while(bytecount < required_len && *func != 0xCC) - { - // prefixes F0h, F2h, F3h, 66h, 67h, D8h-DFh, 2Eh, 36h, 3Eh, 26h, 64h and 65h - int operandSize = 4; - int FPU = 0; - int twoByte = 0; - unsigned char opcode = 0x90; - unsigned char modRM = 0xFF; - while(*func == 0xF0 || - *func == 0xF2 || - *func == 0xF3 || - (*func & 0xFC) == 0x64 || - (*func & 0xF8) == 0xD8 || - (*func & 0x7E) == 0x62) - { - if(*func == 0x66) - { - operandSize = 2; - } - else if((*func & 0xF8) == 0xD8) - { - FPU = *func; - if (dest) - *dest++ = *func++; - else - func++; - bytecount++; - break; - } - - if (dest) - *dest++ = *func++; - else - func++; - bytecount++; - } - - // two-byte opcode byte - if(*func == 0x0F) - { - twoByte = 1; - if (dest) - *dest++ = *func++; - else - func++; - bytecount++; - } - - // opcode byte - opcode = *func++; - if (dest) *dest++ = opcode; - bytecount++; - - // mod R/M byte - modRM = 0xFF; - if(FPU) - { - if((opcode & 0xC0) != 0xC0) - { - modRM = opcode; - } - } - else if(!twoByte) - { - if((opcode & 0xC4) == 0x00 || - ((opcode & 0xF4) == 0x60 && ((opcode & 0x0A) == 0x02 || (opcode & 0x09) == 0x09)) || - (opcode & 0xF0) == 0x80 || - ((opcode & 0xF8) == 0xC0 && (opcode & 0x0E) != 0x02) || - (opcode & 0xFC) == 0xD0 || - (opcode & 0xF6) == 0xF6) - { - modRM = *func++; - if (dest) *dest++ = modRM; - bytecount++; - } - } - else - { - if(((opcode & 0xF0) == 0x00 && (opcode & 0x0F) >= 0x04 && (opcode & 0x0D) != 0x0D) || - (opcode & 0xF0) == 0x30 || - opcode == 0x77 || - (opcode & 0xF0) == 0x80 || - ((opcode & 0xF0) == 0xA0 && (opcode & 0x07) <= 0x02) || - (opcode & 0xF8) == 0xC8) - { - // No mod R/M byte - } - else - { - modRM = *func++; - if (dest) *dest++ = modRM; - bytecount++; - } - } - - // SIB - if((modRM & 0x07) == 0x04 && - (modRM & 0xC0) != 0xC0) - { - if (dest) - *dest++ = *func++; //SIB - else - func++; - bytecount++; - } - - // mod R/M displacement - - // Dword displacement, no base - if((modRM & 0xC5) == 0x05) { - if (dest) { - *(unsigned int*)dest = *(unsigned int*)func; - dest += 4; - } - func += 4; - bytecount += 4; - } - - // Byte displacement - if((modRM & 0xC0) == 0x40) { - if (dest) - *dest++ = *func++; - else - func++; - bytecount++; - } - - // Dword displacement - if((modRM & 0xC0) == 0x80) { - if (dest) { - *(unsigned int*)dest = *(unsigned int*)func; - dest += 4; - } - func += 4; - bytecount += 4; - } - - // immediate - if(FPU) - { - // Can't have immediate operand - } - else if(!twoByte) - { - if((opcode & 0xC7) == 0x04 || - (opcode & 0xFE) == 0x6A || // PUSH/POP/IMUL - (opcode & 0xF0) == 0x70 || // Jcc - opcode == 0x80 || - opcode == 0x83 || - (opcode & 0xFD) == 0xA0 || // MOV - opcode == 0xA8 || // TEST - (opcode & 0xF8) == 0xB0 || // MOV - (opcode & 0xFE) == 0xC0 || // RCL - opcode == 0xC6 || // MOV - opcode == 0xCD || // INT - (opcode & 0xFE) == 0xD4 || // AAD/AAM - (opcode & 0xF8) == 0xE0 || // LOOP/JCXZ - opcode == 0xEB || - (opcode == 0xF6 && (modRM & 0x30) == 0x00)) // TEST - { - if (dest) - *dest++ = *func++; - else - func++; - bytecount++; - } - else if((opcode & 0xF7) == 0xC2) // RET - { - if (dest) { - *(unsigned short*)dest = *(unsigned short*)func; - dest += 2; - } - func += 2; - bytecount += 2; - } - else if((opcode & 0xFC) == 0x80 || - (opcode & 0xC7) == 0x05 || - (opcode & 0xF8) == 0xB8 || - (opcode & 0xFE) == 0xE8 || // CALL/Jcc - (opcode & 0xFE) == 0x68 || - (opcode & 0xFC) == 0xA0 || - (opcode & 0xEE) == 0xA8 || - opcode == 0xC7 || - (opcode == 0xF7 && (modRM & 0x30) == 0x00)) - { - if (dest) { - //Fix CALL/JMP offset - if ((opcode & 0xFE) == 0xE8) { - if (operandSize == 4) - { - *(long*)dest = ((func + *(long*)func) - dest); - - //pRED* edit. func is the current address of the call address, +4 is the next instruction, so the value of $pc - check_thunks(dest+4, func+4); - } - else - *(short*)dest = ((func + *(short*)func) - dest); - - } else { - if (operandSize == 4) - *(unsigned long*)dest = *(unsigned long*)func; - else - *(unsigned short*)dest = *(unsigned short*)func; - } - dest += operandSize; - } - func += operandSize; - bytecount += operandSize; - - } - } - else - { - if(opcode == 0xBA || // BT - opcode == 0x0F || // 3DNow! - (opcode & 0xFC) == 0x70 || // PSLLW - (opcode & 0xF7) == 0xA4 || // SHLD - opcode == 0xC2 || - opcode == 0xC4 || - opcode == 0xC5 || - opcode == 0xC6) - { - if (dest) - *dest++ = *func++; - else - func++; - } - else if((opcode & 0xF0) == 0x80) // Jcc -i - { - if (dest) { - if (operandSize == 4) - *(unsigned long*)dest = *(unsigned long*)func; - else - *(unsigned short*)dest = *(unsigned short*)func; - - dest += operandSize; - } - func += operandSize; - bytecount += operandSize; - } - } - } - - return bytecount; -} - -//insert a specific JMP instruction at the given location -void inject_jmp(void* src, void* dest) { - *(unsigned char*)src = OP_JMP; - *(long*)((unsigned char*)src+1) = (long)((unsigned char*)dest - ((unsigned char*)src + OP_JMP_SIZE)); -} - -//fill a given block with NOPs -void fill_nop(void* src, unsigned int len) { - unsigned char* src2 = (unsigned char*)src; - while (len) { - *src2++ = OP_NOP; - --len; - } -} - -void* eval_jump(void* src) { - unsigned char* addr = (unsigned char*)src; - - if (!addr) return 0; - - //import table jump - if (addr[0] == OP_PREFIX && addr[1] == OP_JMP_SEG) { - addr += 2; - addr = *(unsigned char**)addr; - //TODO: if addr points into the IAT - return *(void**)addr; - } - - //8bit offset - else if (addr[0] == OP_JMP_BYTE) { - addr = &addr[OP_JMP_BYTE_SIZE] + *(char*)&addr[1]; - //mangled 32bit jump? - if (addr[0] == OP_JMP) { - addr = addr + *(int*)&addr[1]; - } - return addr; - } - /* - //32bit offset - else if (addr[0] == OP_JMP) { - addr = &addr[OP_JMP_SIZE] + *(int*)&addr[1]; - } - */ - - return addr; -} -/* -from ms detours package -static bool detour_is_imported(PBYTE pbCode, PBYTE pbAddress) -{ - MEMORY_BASIC_INFORMATION mbi; - VirtualQuery((PVOID)pbCode, &mbi, sizeof(mbi)); - __try { - PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)mbi.AllocationBase; - if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE) { - return false; - } - - PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)((PBYTE)pDosHeader + - pDosHeader->e_lfanew); - if (pNtHeader->Signature != IMAGE_NT_SIGNATURE) { - return false; - } - - if (pbAddress >= ((PBYTE)pDosHeader + - pNtHeader->OptionalHeader - .DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress) && - pbAddress < ((PBYTE)pDosHeader + - pNtHeader->OptionalHeader - .DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress + - pNtHeader->OptionalHeader - .DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].Size)) { - return true; - } - return false; - } - __except(EXCEPTION_EXECUTE_HANDLER) { - return false; - } -} -*/ diff --git a/Extension/asm/asm.h b/Extension/asm/asm.h deleted file mode 100644 index 838e691..0000000 --- a/Extension/asm/asm.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef __ASM_H__ -#define __ASM_H__ - -#define OP_JMP 0xE9 -#define OP_JMP_SIZE 5 - -#define OP_NOP 0x90 -#define OP_NOP_SIZE 1 - -#define OP_PREFIX 0xFF -#define OP_JMP_SEG 0x25 - -#define OP_JMP_BYTE 0xEB -#define OP_JMP_BYTE_SIZE 2 - -#ifdef __cplusplus -extern "C" { -#endif - -void check_thunks(unsigned char *dest, unsigned char *pc); - -//if dest is NULL, returns minimum number of bytes needed to be copied -//if dest is not NULL, it will copy the bytes to dest as well as fix CALLs and JMPs -//http://www.devmaster.net/forums/showthread.php?t=2311 -int copy_bytes(unsigned char *func, unsigned char* dest, int required_len); - -//insert a specific JMP instruction at the given location -void inject_jmp(void* src, void* dest); - -//fill a given block with NOPs -void fill_nop(void* src, unsigned int len); - -//evaluate a JMP at the target -void* eval_jump(void* src); - -#ifdef __cplusplus -} -#endif - -#endif //__ASM_H__ diff --git a/Extension/gsnatives.cpp b/Extension/gsnatives.cpp index 9c0db4c..a06efb9 100644 --- a/Extension/gsnatives.cpp +++ b/Extension/gsnatives.cpp @@ -192,15 +192,9 @@ static cell_t sm_ClearRules(IPluginContext *pContext, const cell_t *params) static cell_t sm_ForceHeartbeat(IPluginContext *pContext, const cell_t *params) { - ISteamGameServer *pServer = GetGSPointer(); - - if (pServer == NULL) - { - return 0; - } - - pServer->ForceHeartbeat(); - return 1; + /* Deprecated no-op: newer Steamworks SDKs removed ISteamGameServer::ForceHeartbeat(); + server list heartbeats are now sent implicitly by Steam. */ + return 0; } static cell_t sm_UserHasLicenseForApp(IPluginContext *pContext, const cell_t *params) diff --git a/Extension/swgsdetours.h b/Extension/swgsdetours.h index 48aebb0..11b8a7b 100644 --- a/Extension/swgsdetours.h +++ b/Extension/swgsdetours.h @@ -21,6 +21,12 @@ #include "steam_gameserver.h" #include "CDetour/detours.h" +/* SourceMod's safetyhook-based CDetour doesn't ship the "fixed address" helper the + old vendored copy had, so define it in terms of the address overload it does expose. */ +#ifndef DETOUR_CREATE_STATIC_FIXED +#define DETOUR_CREATE_STATIC_FIXED(name, address) CDetourManager::CreateDetour(GET_STATIC_CALLBACK(name), GET_STATIC_TRAMPOLINE(name), address); +#endif + class SteamWorksGSDetours { public: diff --git a/Extension/swhttprequest.cpp b/Extension/swhttprequest.cpp index 46a949d..17704ee 100644 --- a/Extension/swhttprequest.cpp +++ b/Extension/swhttprequest.cpp @@ -20,6 +20,15 @@ #include +/* SourceMod 1.13 (extension API 9) changed IPluginManager::FindPluginByContext() + to take an IPluginContext* directly; older SM (API 8) takes the low-level + sp_context_t* from IPluginContext::GetContext(). */ +#if SMINTERFACE_EXTENSIONAPI_VERSION >= 9 +#define SW_PLUGIN_CTX(ctx) (ctx) +#else +#define SW_PLUGIN_CTX(ctx) ((ctx)->GetContext()) +#endif + static ISteamHTTP *GetHTTPPointer(void) { return g_SteamWorks.pSWGameServer->GetHTTP(); @@ -220,7 +229,7 @@ static cell_t sm_SetCallbacks(IPluginContext *pContext, const cell_t *params) IPlugin *pPlugin; if (params[5] == BAD_HANDLE) { - pPlugin = plsys->FindPluginByContext(pContext->GetContext()); + pPlugin = plsys->FindPluginByContext(SW_PLUGIN_CTX(pContext)); } else { HandleError err; pPlugin = plsys->PluginFromHandle(params[5], &err); @@ -518,7 +527,7 @@ static cell_t sm_GetHTTPResponseBodyCallback(IPluginContext *pContext, const cel IPlugin *pPlugin; if (params[4] == BAD_HANDLE) { - pPlugin = plsys->FindPluginByContext(pContext->GetContext()); + pPlugin = plsys->FindPluginByContext(SW_PLUGIN_CTX(pContext)); } else { HandleError err; pPlugin = plsys->PluginFromHandle(params[4], &err); diff --git a/Pawn/includes/SteamWorks.inc b/Pawn/includes/SteamWorks.inc index bebbb3f..b2c8fed 100644 --- a/Pawn/includes/SteamWorks.inc +++ b/Pawn/includes/SteamWorks.inc @@ -222,6 +222,7 @@ native bool:SteamWorks_SetMapName(const String:sMapName[]); native bool:SteamWorks_IsConnected(); native bool:SteamWorks_SetRule(const String:sKey[], const String:sValue[]); native bool:SteamWorks_ClearRules(); +#pragma deprecated This function is deprecated in the SDK and no longer does anything in this extension native bool:SteamWorks_ForceHeartbeat(); native bool:SteamWorks_GetUserGroupStatus(client, groupid); native bool:SteamWorks_GetUserGroupStatusAuthID(authid, groupid); diff --git a/buildbot/PackageScript b/buildbot/PackageScript index 66e3c16..9221390 100644 --- a/buildbot/PackageScript +++ b/buildbot/PackageScript @@ -1,31 +1,37 @@ -# vim: set ts=8 sts=2 sw=2 tw=99 et ft=python: -import os - -builder.SetBuildFolder('package') - -folder_list = [ - 'addons/sourcemod/extensions', - 'addons/sourcemod/scripting', - 'addons/sourcemod/scripting/include', -] - -# Create the distribution folder hierarchy. -folder_map = {} -for folder in folder_list: - norm_folder = os.path.normpath(folder) - folder_map[folder] = builder.AddFolder(norm_folder) - -for extension in SteamWorks.extensions: - builder.AddCopy(extension.binary, folder_map['addons/sourcemod/extensions']) - -# Do all straight-up file copies from the source tree. -def CopyFiles(src, dest, files): - if not dest: - dest = src - dest_entry = folder_map[dest] - for source_file in files: - source_path = os.path.join(builder.sourcePath, src, source_file) - builder.AddCopy(source_path, dest_entry) - -CopyFiles('Pawn', 'addons/sourcemod/scripting', ['swag.sp']) -CopyFiles('Pawn/includes', 'addons/sourcemod/scripting/include', ['SteamWorks.inc']) \ No newline at end of file +# vim: set ts=8 sts=2 sw=2 tw=99 et ft=python: +import os + +builder.SetBuildFolder('package') + +# 64-bit extensions live under an x64/ subfolder; 32-bit sit directly in +# extensions/. Only one architecture is built per configure, so pick the +# matching destination here. +if builder.cxx.target.arch == 'x86_64': + ext_folder = 'addons/sourcemod/extensions/x64' +else: + ext_folder = 'addons/sourcemod/extensions' + +folder_list = [ + ext_folder, + 'addons/sourcemod/scripting/include', +] + +# Create the distribution folder hierarchy. +folder_map = {} +for folder in folder_list: + norm_folder = os.path.normpath(folder) + folder_map[folder] = builder.AddFolder(norm_folder) + +for extension in SteamWorks.extensions: + builder.AddCopy(extension.binary, folder_map[ext_folder]) + +# Do all straight-up file copies from the source tree. +def CopyFiles(src, dest, files): + if not dest: + dest = src + dest_entry = folder_map[dest] + for source_file in files: + source_path = os.path.join(builder.sourcePath, src, source_file) + builder.AddCopy(source_path, dest_entry) + +CopyFiles('Pawn/includes', 'addons/sourcemod/scripting/include', ['SteamWorks.inc']) diff --git a/buildbot/helpers.pm b/buildbot/helpers.pm deleted file mode 100644 index 1e3e13e..0000000 --- a/buildbot/helpers.pm +++ /dev/null @@ -1,174 +0,0 @@ -#!/usr/bin/perl - -use strict; -use Cwd; - -package Build; - -our $SVN = "/usr/bin/svn"; -our $SVN_USER = 'dvander'; -our $SVN_ARGS = ''; - -sub GitRevNum -{ - my ($path) = (@_); - my ($cd, $text, $rev); - - $cd = Cwd::cwd(); - chdir($path); - $text = `git rev-list --count HEAD`; - chdir($cd); - - chomp $text; - if ($text =~ /^(\d+)/) { - return $1; - } - - return 0; -} - -sub HgRevNum -{ - my ($path) = (@_); - my ($cd, $text, $rev); - - $cd = Cwd::cwd(); - chdir($path); - $text = `hg identify -n`; - chdir($cd); - - chomp $text; - if ($text =~ /^(\d+)/) - { - return $1; - } - - return 0; -} - -sub SvnRevNum -{ - my ($str)=(@_); - - my $data = Command('svnversion -c ' . $str); - if ($data =~ /(\d+):(\d+)/) - { - return $2; - } elsif ($data =~ /(\d+)/) { - return $1; - } else { - return 0; - } -} - -sub ProductVersion -{ - my ($file) = (@_); - my ($version); - open(FILE, $file) or die "Could not open $file: $!\n"; - $version = ; - close(FILE); - chomp $version; - return $version; -} - -sub Delete -{ - my ($str)=(@_); - if ($^O =~ /MSWin/) - { - Command("del /S /F /Q \"$str\""); - Command("rmdir /S /Q \"$str\""); - } else { - Command("rm -rf $str"); - } - return !(-e $str); -} - -sub Copy -{ - my ($src,$dest)=(@_); - if ($^O =~ /MSWin/) - { - Command("copy \"$src\" \"$dest\" /y"); - } else { - Command("cp \"$src\" \"$dest\""); - } - return (-e $dest); -} - -sub Move -{ - my ($src,$dest)=(@_); - if ($^O =~ /MSWin/) - { - Command("move \"$src\" \"$dest\""); - } else { - Command("mv \"$src\" \"$dest\""); - } - return (-e $dest); -} - -sub Command -{ - my($cmd)=(@_); - print "$cmd\n"; - return `$cmd`; -} - -sub PathFormat -{ - my ($str)=(@_); - if ($^O =~ /MSWin/) - { - $str =~ s#/#\\#g; - } else { - $str =~ s#\\#/#g; - } - return $str; -} - -sub SVN_Remove -{ - my ($file)=(@_); - my ($path, $name); - if ($^O =~ /MSWin/) - { - ($path, $name) = ($file =~ /(.+)\/([^\/]+)$/); - } else { - ($path, $name) = ($file =~ /(.+)\\([^\\]+)$/); - } - my $dir = Cwd::cwd(); - chdir($path); - Command($SVN . ' ' . $SVN_ARGS . ' delete ' . $name); - chdir($dir); -} - -sub SVN_Add -{ - my ($file)=(@_); - my ($path, $name); - if ($^O =~ /MSWin/) - { - ($path, $name) = ($file =~ /(.+)\/([^\/]+)$/); - } else { - ($path, $name) = ($file =~ /(.+)\\([^\\]+)$/); - } - my $dir = Cwd::cwd(); - chdir($path); - Command($SVN . ' ' . $SVN_ARGS . ' add ' . $name); - chdir($dir); -} - -sub GetBuildType -{ - my ($file)=(@_); - my ($type); - open(TYPE, $file) or die("Could not open file: $!\n"); - $type = ; - close(TYPE); - chomp $type; - return $type; -} - -return 1; diff --git a/buildbot/package_script.pl b/buildbot/package_script.pl deleted file mode 100644 index 63d2816..0000000 --- a/buildbot/package_script.pl +++ /dev/null @@ -1,106 +0,0 @@ -# Pastebin eziGmKtQ -#!/usr/bin/perl - -use strict; -use Cwd; -use File::Basename; -use File::Copy; -use File::Path; -use Net::FTP; - -my ($ftp_file, $ftp_host, $ftp_user, $ftp_pass, $ftp_path, $tag); - -$ftp_file = shift; -$tag = shift; - -open(FTP, $ftp_file) or die "Unable to read FTP config file $ftp_file: $!\n"; -$ftp_host = ; -$ftp_user = ; -$ftp_pass = ; -$ftp_path = ; -close(FTP); - -chomp $ftp_host; -chomp $ftp_user; -chomp $ftp_pass; -chomp $ftp_path; - -my ($myself, $path) = fileparse($0); -chdir($path); - -require 'helpers.pm'; - -my ($version, $ext); -$version .= '-git' . Build::GitRevNum('.'); - -# Append OS to package version -if ($^O eq "darwin") -{ - $ext = ".dylib"; - $version .= '-mac'; -} -elsif ($^O =~ /MSWin/) -{ - $ext = ".dll"; - $version .= '-windows'; -} -elsif ($^O eq "linux") -{ - $ext = ".so"; - $version .= '-linux'; -} -else -{ - $version .= '-' . $^O; -} - -#Switch to the output folder. -chdir(Build::PathFormat('../build/package')); - -my ($dirlist, $filename, $cmd); -$dirlist = "addons"; -$filename = 'SteamWorks' . $version; - -if ($^O eq "linux") -{ - $filename .= '.tar.gz'; - $cmd = "tar zcvf $filename $dirlist"; -} -else -{ - $filename .= '.zip'; - $cmd = "zip -r $filename $dirlist"; -} - -print "$cmd\n"; -system($cmd); - -$ftp_path .= "/SteamWorks"; - -my ($ftp); - -$ftp = Net::FTP->new($ftp_host, Debug => 0, Passive => 1) - or die "Cannot connect to host $ftp_host: $@"; - -$ftp->login($ftp_user, $ftp_pass) - or die "Cannot connect to host $ftp_host as $ftp_user: " . $ftp->message . "\n"; - -if ($ftp_path ne '') -{ - # YOU LEAVE ME NO CHOICE - $ftp->mkdir($ftp_path, 1); - - $ftp->cwd($ftp_path) - or die "Cannot change to folder $ftp_path: " . $ftp->message . "\n"; -} - -$ftp->binary(); -$ftp->put($filename) - or die "Cannot drop file $filename ($ftp_path): " . $ftp->message . "\n"; - -$ftp->close(); - -print "File sent to drop site as $filename -- build succeeded.\n"; - -exit(0); - diff --git a/configure.py b/configure.py index d27f552..39ba9e3 100644 --- a/configure.py +++ b/configure.py @@ -19,8 +19,6 @@ if ambuild_version.startswith('2.1'): sys.exit(1) run = run.BuildParser(sourcePath=sys.path[0], api='2.2') -run.options.add_argument('--hl2sdk-root', type=str, dest='hl2sdk_root', default=None, - help='Root search folder for HL2SDKs') run.options.add_argument('--mms-path', type=str, dest='mms_path', default=None, help='Path to Metamod:Source') run.options.add_argument('--sm-path', type=str, dest='sm_path', default=None, @@ -31,8 +29,5 @@ run.options.add_argument('--enable-debug', action='store_const', const='1', dest help='Enable debugging symbols') run.options.add_argument('--enable-optimize', action='store_const', const='1', dest='opt', help='Enable optimization') -run.options.add_argument('-s', '--sdks', default='all', dest='sdks', - help='Build against specified SDKs; valid args are "all", "present", or ' - 'comma-delimited list of engine names') run.options.add_argument('--target', default=None, help='Override the default build target') run.Configure()