feat: update sdks, builders, ci, proper secure data (#10)

This commit is contained in:
Maxime Leroy
2025-02-21 00:47:09 +01:00
committed by GitHub
parent 05149c6656
commit 25286e2f04
9 changed files with 460 additions and 270 deletions
+125 -59
View File
@@ -1,81 +1,147 @@
name: CI
name: Extension builder
on: [push, pull_request, workflow_dispatch]
on:
push:
branches:
- master
tags:
- "*"
pull_request:
branches:
- master
jobs:
build:
name: Build
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-20.04]
sourcemod-version: [1.11-dev]
include:
- os: ubuntu-20.04
target-archs: x86,x86_64
sdks: sdk2013,csgo
cc: clang-10
cxx: clang++-10
fail-fast: false
name: ${{ matrix.os }} - ${{ matrix.cc }}
runs-on: ${{ matrix.os }}
env:
PROJECT: 'a2sqcache'
SDKS: 'css'
MMSOURCE_VERSION: '1.12'
SOURCEMOD_VERSION: '1.12'
CACHE_PATH: ${{ github.workspace }}/cache
steps:
- name: Install Linux packages
if: runner.os == 'Linux'
run: |
sudo apt update
sudo apt install -yq --no-install-recommends g++-multilib
- name: Set up Python
uses: actions/setup-python@v5
- name: Checkout
uses: actions/checkout@v4
with:
path: extension
- name: Checkout SourceMod
uses: actions/checkout@v4
with:
repository: alliedmodders/sourcemod
ref: ${{ matrix.sourcemod-version }}
path: sourcemod
submodules: recursive
- name: Checkout AMBuild
uses: actions/checkout@v4
with:
repository: alliedmodders/ambuild
path: ambuild
- name: Checkout sm-ext-common
uses: actions/checkout@v4
with:
repository: srcdslab/sm-ext-common
path: sourcemod/extensions/sm-ext-common
- name: Install sourcemod dependencies
run: |
bash sourcemod/tools/checkout-deps.sh -m -s ${{ matrix.sdks }}
- name: Install AMBuild
uses: BSFishy/pip-action@v1
with:
packages: ./ambuild
- name: Build
working-directory: extension
- name: Concatenate SDK Names
shell: bash
env:
BREAKPAD_SYMBOL_SERVER: ${{ secrets.BREAKPAD_SYMBOL_SERVER }}
run: |
mkdir build && cd build
python ../configure.py --enable-optimize --targets=${{ matrix.target-archs }} --sdks=${{ matrix.sdks }}
# Paranoia
SDKS_VAR="${{env.SDKS}}"
# This will be used in our cache key
echo "SDKS_KEY=${SDKS_VAR//[[:blank:]]/}" >> $GITHUB_ENV
- name: Linux dependencies
if: startsWith(runner.os, 'Linux')
run: |
sudo dpkg --add-architecture i386
sudo apt-get update
sudo apt-get install -y --no-install-recommends \
gcc-multilib g++-multilib libstdc++6 lib32stdc++6 \
libc6-dev libc6-dev-i386 linux-libc-dev \
linux-libc-dev:i386 lib32z1-dev ${{ matrix.cc }}
- uses: actions/setup-python@v4
name: Setup Python 3.9
with:
python-version: 3.9
- name: Install Python dependencies
run: |
python -m pip install --upgrade pip setuptools wheel
- uses: actions/checkout@v3
name: Repository checkout
with:
fetch-depth: 0
path: extension
- uses: actions/cache@v3
name: Cache dependencies
if: ${{ ! startsWith(github.ref, 'refs/tags/') }}
env:
cache-name: cache
with:
path: ${{ env.CACHE_PATH }}
key: ${{ runner.os }}-build-${{ env.cache-name }}-sm${{ env.SOURCEMOD_VERSION }}-mmsource${{ env.MMSOURCE_VERSION }}-${{ env.SDKS_KEY }}
- shell: bash
name: Install dependencies
run: |
mkdir -p "${{ env.CACHE_PATH }}"
cd "${{ env.CACHE_PATH }}"
shallow_checkout () {
# Param 1 is origin
# Param 2 is branch
# Param 3 is name
if [ ! -d "$3" ]; then
git clone "$1" --depth 1 --branch "$2" "$3"
fi
cd "$3"
git remote set-url origin "$1"
git fetch --depth 1 origin "$2"
git checkout --force --recurse-submodules FETCH_HEAD
git submodule init
git submodule update --depth 1
cd ..
}
# We are aware of what we are doing!
git config --global advice.detachedHead false
# Verify github cache, and see if we don't have the sdks already cloned and update them
for sdk in ${{ env.SDKS }}
do
shallow_checkout "https://github.com/alliedmodders/hl2sdk" "${sdk}" "hl2sdk-${sdk}"
done
shallow_checkout "https://github.com/alliedmodders/ambuild" "master" "ambuild"
shallow_checkout "https://github.com/alliedmodders/sourcemod" "${{env.SOURCEMOD_VERSION}}-dev" "sourcemod"
shallow_checkout "https://github.com/alliedmodders/metamod-source/" "${{env.MMSOURCE_VERSION}}-dev" "metamod-source"
shallow_checkout "https://github.com/srcdslab/sm-ext-common" "master" "sourcemod/public/sm-ext-common"
# But maybe others aren't (also probably unnecessary because git actions but paranoia)
git config --global advice.detachedHead true
- name: Setup AMBuild
shell: bash
run: |
cd "${{ env.CACHE_PATH }}"
python -m pip install ./ambuild
- name: Select clang compiler
if: startsWith(runner.os, 'Linux')
run: |
echo "CC=${{ matrix.cc }}" >> $GITHUB_ENV
echo "CXX=${{ matrix.cxx }}" >> $GITHUB_ENV
${{ matrix.cc }} --version
${{ matrix.cxx }} --version
- name: Build
shell: bash
working-directory: extension
run: |
mkdir build
cd build
python ../configure.py --enable-optimize --sdks="${{ env.SDKS }}" --mms-path="${{ env.CACHE_PATH }}/metamod-source" --hl2sdk-root="${{ env.CACHE_PATH }}" --sm-path="${{ env.CACHE_PATH }}/sourcemod" --targets=x86,x86_64
ambuild
- name: Upload artifact
- name: Upload a Build Artifact
uses: actions/upload-artifact@v4
with:
# Artifact name
name: ${{ runner.os }}
# optional, default is artifact
# A file, directory or wildcard pattern that describes what to upload
path: extension/build/package
# The desired behavior if no files are found using the provided path.
if-no-files-found: error
# Duration after which artifact will expire in days. 0 means using default retention.
retention-days: 14
release:
name: Release
+4
View File
@@ -0,0 +1,4 @@
build
Containerfile
.venv
safetyhook
+173 -114
View File
@@ -1,6 +1,5 @@
# vim: set sts=2 ts=8 sw=2 tw=99 et ft=python:
import os, sys
import traceback
import os, sys, shutil
class SDK(object):
def __init__(self, sdk, ext, aDef, name, platform, dir):
@@ -27,13 +26,49 @@ class SDK(object):
return True
return False
WinOnly = ['windows']
WinLinux = ['windows', 'linux']
WinLinuxMac = ['windows', 'linux', 'mac']
CSS = {
'windows': ['x86', 'x86_64'],
'linux': ['x86', 'x86_64']
}
HL2DM = {
'windows': ['x86', 'x86_64'],
'linux': ['x86', 'x86_64']
}
DODS = {
'windows': ['x86', 'x86_64'],
'linux': ['x86', 'x86_64']
}
TF2 = {
'windows': ['x86', 'x86_64'],
'linux': ['x86', 'x86_64']
}
CSGO = {
'windows': ['x86'],
'linux': ['x86', 'x86_64']
}
PossibleSDKs = {
'sdk2013': SDK('HL2SDK2013', '2.sdk2013', '9', 'SDK2013', WinLinuxMac, 'sdk2013'),
'csgo': SDK('HL2SDKCSGO', '2.csgo', '21', 'CSGO', WinLinuxMac, 'csgo'),
# 'episode1': SDK('HL2SDK', '1.ep1', '1', 'EPISODEONE', WinLinux, 'episode1'),
# 'darkm': SDK('HL2SDK-DARKM', '2.darkm', '2', 'DARKMESSIAH', WinOnly, 'darkm'),
# 'orangebox': SDK('HL2SDKOB', '2.ep2', '3', 'ORANGEBOX', WinLinux, 'orangebox'),
# 'bgt': SDK('HL2SDK-BGT', '2.bgt', '4', 'BLOODYGOODTIME', WinOnly, 'bgt'),
# 'eye': SDK('HL2SDK-EYE', '2.eye', '5', 'EYE', WinOnly, 'eye'),
'css': SDK('HL2SDKCSS', '2.css', '6', 'CSS', CSS, 'css'),
# 'hl2dm': SDK('HL2SDKHL2DM', '2.hl2dm', '7', 'HL2DM', HL2DM, 'hl2dm'),
# 'dods': SDK('HL2SDKDODS', '2.dods', '8', 'DODS', DODS, 'dods'),
# 'sdk2013': SDK('HL2SDK2013', '2.sdk2013', '9', 'SDK2013', WinLinux, 'sdk2013'),
# 'bms': SDK('HL2SDKBMS', '2.bms', '11', 'BMS', WinLinux, 'bms'),
# 'tf2': SDK('HL2SDKTF2', '2.tf2', '12', 'TF2', TF2, 'tf2'),
# 'l4d': SDK('HL2SDKL4D', '2.l4d', '13', 'LEFT4DEAD', WinLinux, 'l4d'),
# 'nucleardawn': SDK('HL2SDKND', '2.nd', '14', 'NUCLEARDAWN', WinLinuxMac, 'nucleardawn'),
# 'contagion': SDK('HL2SDKCONTAGION', '2.contagion', '15', 'CONTAGION', WinOnly, 'contagion'),
# 'l4d2': SDK('HL2SDKL4D2', '2.l4d2', '16', 'LEFT4DEAD2', WinLinux, 'l4d2'),
# 'swarm': SDK('HL2SDK-SWARM', '2.swarm', '17', 'ALIENSWARM', WinOnly, 'swarm'),
# 'portal2': SDK('HL2SDKPORTAL2', '2.portal2', '18', 'PORTAL2', [], 'portal2'),
# 'insurgency': SDK('HL2SDKINSURGENCY', '2.insurgency', '19', 'INSURGENCY', WinLinuxMac, 'insurgency'),
# 'blade': SDK('HL2SDKBLADE', '2.blade', '21', 'BLADE', WinLinux, 'blade'),
'csgo': SDK('HL2SDKCSGO', '2.csgo', '23', 'CSGO', CSGO, 'csgo'),
}
def ResolveEnvPath(env, folder):
@@ -56,7 +91,7 @@ def ResolveEnvPath(env, folder):
def Normalize(path):
return os.path.abspath(os.path.normpath(path))
def SetArchFlags(compiler):
if compiler.behavior == 'gcc':
if compiler.target.arch == 'x86_64':
@@ -69,19 +104,13 @@ class ExtensionConfig(object):
def __init__(self):
self.sdks = {}
self.binaries = []
self.spvm = []
self.extensions = []
self.generated_headers = None
self.sm_root = None
self.mms_root = None
self.mysql_root = {}
self.spcomp = None
self.spcomp_bins = None
self.smx_files = {}
self.versionlib = None
self.sm_root = None
self.all_targets = []
self.target_archs = set()
self.libsafetyhook = {}
if builder.options.targets:
target_archs = builder.options.targets.split(',')
@@ -105,6 +134,26 @@ class ExtensionConfig(object):
if not self.all_targets:
raise Exception('No suitable C/C++ compiler was found.')
def use_auto_versioning(self):
return not getattr(builder.options, 'disable_auto_versioning', True)
def AddVersioning(self, binary):
if binary.compiler.target.platform == 'windows':
binary.sources += ['version.rc']
binary.compiler.rcdefines += [
'BINARY_NAME="{0}"'.format(binary.outputFile),
'RC_COMPILE',
]
elif binary.compiler.target.platform == 'mac':
if binary.type == 'library':
binary.compiler.postlink += [
'-compatibility_version', '1.0.0',
'-current_version', self.productVersion
]
if self.use_auto_versioning():
binary.compiler.sourcedeps += self.generated_headers
return binary
@property
def tag(self):
if builder.options.debug == '1':
@@ -118,7 +167,7 @@ class ExtensionConfig(object):
import re
with open(os.path.join(builder.sourcePath, 'product.version'), 'r') as fp:
productContents = fp.read()
m = re.match('(\d+)\.(\d+)\.(\d+).*', productContents)
m = re.match('(\\d+)\.(\\d+)\.(\\d+).*', productContents)
if m == None:
self.productVersion = '1.0.0'
else:
@@ -126,7 +175,7 @@ class ExtensionConfig(object):
self.productVersion = '{0}.{1}.{2}'.format(major, minor, release)
def detectSDKs(self):
sdk_list = builder.options.sdks.split(',')
sdk_list = builder.options.sdks.split(' ')
use_none = sdk_list[0] == 'none'
use_all = sdk_list[0] == 'all'
use_present = sdk_list[0] == 'present'
@@ -152,28 +201,24 @@ class ExtensionConfig(object):
if builder.options.sm_path:
self.sm_root = builder.options.sm_path
else:
self.sm_root = ResolveEnvPath('SOURCEMOD18', 'sourcemod-1.10')
if not self.sm_root:
self.sm_root = ResolveEnvPath('SOURCEMOD', 'sourcemod-source')
if not self.sm_root:
self.sm_root = ResolveEnvPath('SOURCEMOD_DEV', 'sourcemod-central')
self.sm_root = ResolveEnvPath('SOURCEMOD112', 'sourcemod-1.12')
if not self.sm_root:
self.sm_root = ResolveEnvPath('SOURCEMOD', 'sourcemod')
if not self.sm_root:
self.sm_root = ResolveEnvPath('SOURCEMOD_DEV', 'sourcemod-central')
if not self.sm_root or not os.path.isdir(self.sm_root):
raise Exception('Could not find a source copy of Sourcemod')
raise Exception('Could not find a source copy of SourceMod')
self.sm_root = Normalize(self.sm_root)
if builder.options.mms_path:
self.mms_root = builder.options.mms_path
else:
self.mms_root = ResolveEnvPath('MMSOURCE110', 'mmsource-1.10')
self.mms_root = ResolveEnvPath('MMSOURCE112', 'mmsource-1.12')
if not self.mms_root:
self.mms_root = ResolveEnvPath('MMSOURCE_DEV', 'metamod-source')
if not self.mms_root:
self.mms_root = ResolveEnvPath('MMSOURCE_DEV', 'mmsource-central')
if not self.mms_root:
self.mms_root = ResolveEnvPath('MMSOURCE_DEV', 'metamod')
if not self.mms_root or not os.path.isdir(self.mms_root):
raise Exception('Could not find a source copy of Metamod:Source')
@@ -188,14 +233,14 @@ class ExtensionConfig(object):
def configure_cxx(self, cxx):
if cxx.family == 'msvc':
if cxx.version < 1900:
raise Exception('Only MSVC 2015 and later are supported, c++14 support is required.')
if cxx.family == 'gcc':
if cxx.version < 'gcc-4.9':
raise Exception('Only GCC versions 4.9 or greater are supported, c++14 support is required.')
if cxx.family == 'clang':
if cxx.version < 'clang-3.4':
raise Exception('Only clang versions 3.4 or greater are supported, c++14 support is required.')
if cxx.version < 1914 and builder.options.generator != 'vs':
raise Exception(f'Only MSVC 2017 15.7 and later are supported, full C++17 support is required. ({str(cxx.version)} < 1914)')
elif cxx.family == 'gcc':
if cxx.version < 'gcc-9':
raise Exception('Only GCC versions 9 or later are supported, full C++17 support is required.')
elif cxx.family == 'clang':
if cxx.version < 'clang-5':
raise Exception('Only clang versions 5 or later are supported, full C++17 support is required.')
if cxx.like('gcc'):
self.configure_gcc(cxx)
@@ -223,6 +268,12 @@ class ExtensionConfig(object):
os.path.join(self.sm_root, 'public'),
]
if self.use_auto_versioning():
cxx.defines += ['SM_GENERATED_BUILD']
cxx.includes += [
os.path.join(builder.buildPath, 'includes')
]
def configure_gcc(self, cxx):
cxx.defines += [
'stricmp=strcasecmp',
@@ -240,19 +291,19 @@ class ExtensionConfig(object):
'-Wno-unused',
'-Wno-switch',
'-Wno-array-bounds',
'-msse',
'-Wno-unknown-pragmas',
'-Wno-dangling-else',
'-fvisibility=hidden',
]
if cxx.version == 'apple-clang-6.0' or cxx.version == 'clang-3.4':
cxx.cxxflags += ['-std=c++1y']
else:
cxx.cxxflags += ['-std=c++14']
if cxx.target.arch in ['x86', 'x86_64']:
cxx.cflags += ['-msse']
cxx.cxxflags += [
'-std=c++17',
'-fno-threadsafe-statics',
'-Wno-non-virtual-dtor',
'-Wno-overloaded-virtual',
'-Wno-register',
'-fvisibility-inlines-hidden',
]
@@ -283,26 +334,18 @@ class ExtensionConfig(object):
cxx.cflags += ['-Wno-sometimes-uninitialized']
# Work around SDK warnings.
if cxx.version >= 'clang-10.0':
cxx.cflags += [
'-Wno-implicit-int-float-conversion',
'-Wno-tautological-overlap-compare',
]
if cxx.version >= 'clang-10.0' or cxx.version >= 'apple-clang-12.0':
cxx.cflags += [
'-Wno-implicit-int-float-conversion',
'-Wno-tautological-overlap-compare',
]
if have_gcc:
cxx.cflags += ['-mfpmath=sse']
cxx.cflags += ['-Wno-maybe-uninitialized']
if builder.options.opt == '1':
cxx.cflags += [
'-O3',
'-fexperimental-new-pass-manager',
'-mllvm',
'-inline-threshold=1000',
'-mllvm',
'-vectorize-loops',
'-ftree-vectorize',
]
cxx.cflags += ['-O3']
# Don't omit the frame pointer.
cxx.cflags += ['-fno-omit-frame-pointer']
@@ -326,6 +369,7 @@ class ExtensionConfig(object):
'/EHsc',
'/GR-',
'/TP',
'/std:c++17',
]
cxx.linkflags += [
'kernel32.lib',
@@ -354,13 +398,12 @@ class ExtensionConfig(object):
cxx.cflags += ['/Oy-']
def configure_linux(self, cxx):
cxx.defines += ['_LINUX', 'POSIX', '_FILE_OFFSET_BITS=64']
cxx.defines += ['LINUX', '_LINUX', 'POSIX', '_FILE_OFFSET_BITS=64']
cxx.linkflags += ['-lm']
if cxx.family == 'gcc':
cxx.linkflags += ['-static-libgcc']
elif cxx.family == 'clang':
cxx.linkflags += ['-lgcc_eh']
cxx.linkflags += ['-static-libstdc++']
def configure_mac(self, cxx):
cxx.defines += ['OSX', '_OSX', 'POSIX', 'KE_ABSOLUTELY_NO_STL']
@@ -373,43 +416,16 @@ class ExtensionConfig(object):
cxx.cxxflags += ['-stdlib=libc++']
def configure_windows(self, cxx):
cxx.defines += ['WIN32', '_WINDOWS']
def add_libamtl(self):
# Add libamtl.
self.libamtl = {}
for cxx in self.all_targets:
def get_configure_fn(cxx):
return lambda builder, name: self.StaticLibrary(builder, cxx, name)
extra_vars = {'Configure': get_configure_fn(cxx)}
libamtl = builder.Build('public/amtl/amtl/AMBuilder', extra_vars)
self.libamtl[cxx.target.arch] = libamtl.binary
def AddVersioning(self, binary):
if binary.compiler.target.platform == 'windows':
binary.sources += ['version.rc']
binary.compiler.rcdefines += [
'BINARY_NAME="{0}"'.format(binary.outputFile),
'RC_COMPILE',
]
elif binary.compiler.target.platform == 'mac':
if binary.type == 'library':
binary.compiler.postlink += [
'-compatibility_version', '1.0.0',
'-current_version', self.productVersion
]
return binary
cxx.defines += ['WIN32', '_WINDOWS', 'PLATFORM_WINDOWS_PC']
def LibraryBuilder(self, compiler, name):
binary = compiler.Library(name)
self.AddVersioning(binary)
if binary.compiler.like('msvc'):
binary.compiler.linkflags += ['/SUBSYSTEM:WINDOWS']
return binary
def ProgramBuilder(self, compiler, name):
binary = compiler.Program(name)
self.AddVersioning(binary)
if '-static-libgcc' in binary.compiler.linkflags:
binary.compiler.linkflags.remove('-static-libgcc')
if '-lgcc_eh' in binary.compiler.linkflags:
@@ -444,10 +460,10 @@ class ExtensionConfig(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, 'sourcepawn', 'include'),
os.path.join(self.sm_root, 'public', 'amtl', 'amtl'),
os.path.join(self.sm_root, 'public', 'amtl'),
os.path.join(self.sm_root, 'extensions', 'sm-ext-common', 'include'),
os.path.join(self.sm_root, 'sourcepawn', 'include'),
os.path.join(self.sm_root, 'public', 'sm-ext-common', 'include'),
]
return compiler
@@ -466,7 +482,8 @@ class ExtensionConfig(object):
os.path.join(self.mms_root, 'core', 'sourcehook'),
]
defines = ['SE_' + PossibleSDKs[i].define + '=' + PossibleSDKs[i].code for i in PossibleSDKs]
defines = ['RAD_TELEMETRY_DISABLED']
defines += ['SE_' + PossibleSDKs[i].define + '=' + PossibleSDKs[i].code for i in PossibleSDKs]
compiler.defines += defines
paths = [
@@ -475,8 +492,7 @@ class ExtensionConfig(object):
['public', 'mathlib'],
['public', 'vstdlib'],
['public', 'tier0'],
['public', 'tier1'],
['public', 'appframework']
['public', 'tier1']
]
if sdk.name == 'episode1' or sdk.name == 'darkm':
paths.append(['public', 'dlls'])
@@ -489,7 +505,7 @@ class ExtensionConfig(object):
compiler.defines += ['SOURCE_ENGINE=' + sdk.code]
if sdk.name in ['sdk2013', 'bms'] and compiler.like('gcc'):
if sdk.name in ['sdk2013', 'bms', 'css', 'tf2', 'dods', 'hl2dm'] and compiler.like('gcc'):
# The 2013 SDK already has these in public/tier0/basetypes.h
compiler.defines.remove('stricmp=strcasecmp')
compiler.defines.remove('_stricmp=strcasecmp')
@@ -520,7 +536,6 @@ class ExtensionConfig(object):
if compiler.target.platform == 'linux':
if sdk.name in ['csgo', 'blade']:
compiler.linkflags.remove('-static-libstdc++')
compiler.defines += ['_GLIBCXX_USE_CXX11_ABI=0']
for path in paths:
@@ -532,16 +547,16 @@ class ExtensionConfig(object):
elif sdk.name in ['sdk2013', 'bms']:
lib_folder = os.path.join(sdk.path, 'lib', 'public', 'linux32')
elif compiler.target.arch == 'x86_64':
lib_folder = os.path.join(sdk.path, 'lib', 'linux64')
lib_folder = os.path.join(sdk.path, 'lib', 'public', 'linux64')
else:
lib_folder = os.path.join(sdk.path, 'lib', 'linux')
lib_folder = os.path.join(sdk.path, 'lib', 'public', 'linux')
elif compiler.target.platform == 'mac':
if sdk.name in ['sdk2013', 'bms']:
lib_folder = os.path.join(sdk.path, 'lib', 'public', 'osx32')
elif compiler.target.arch == 'x86_64':
lib_folder = os.path.join(sdk.path, 'lib', 'osx64')
lib_folder = os.path.join(sdk.path, 'lib', 'public', 'osx64')
else:
lib_folder = os.path.join(sdk.path, 'lib', 'mac')
lib_folder = os.path.join(sdk.path, 'lib', 'public', 'mac')
if compiler.target.platform in ['linux', 'mac']:
if sdk.name in ['sdk2013', 'bms'] or compiler.target.arch == 'x86_64':
@@ -580,9 +595,9 @@ class ExtensionConfig(object):
libs.append('interfaces')
for lib in libs:
if compiler.target.arch == 'x86':
lib_path = os.path.join(sdk.path, 'lib', 'public', lib) + '.lib'
lib_path = os.path.join(sdk.path, 'lib', 'public', 'x86', lib) + '.lib'
elif compiler.target.arch == 'x86_64':
lib_path = os.path.join(sdk.path, 'lib', 'public', 'win64', lib) + '.lib'
lib_path = os.path.join(sdk.path, 'lib', 'public', 'x64', lib) + '.lib'
compiler.linkflags.append(lib_path)
for library in dynamic_libs:
@@ -598,16 +613,41 @@ class ExtensionConfig(object):
return binary
def AddCDetour(self, binary):
sm_public_path = os.path.join(self.sm_root, 'public')
if os.path.exists(os.path.join(sm_public_path, 'safetyhook')):
binary.sources += [ os.path.join(sm_public_path, 'CDetour', 'detours.cpp') ]
binary.compiler.cxxincludes += [ os.path.join(builder.sourcePath, 'safetyhook', 'include') ]
for task in self.libsafetyhook:
if task.target.arch == binary.compiler.target.arch:
binary.compiler.linkflags += [task.binary]
return
raise Exception('No suitable build of safetyhook was found.')
else:
binary.sources += [
os.path.join(sm_public_path, 'CDetour', 'detours.cpp'),
os.path.join(sm_public_path, 'asm', 'asm.c'),
]
# sm1.10+
libudis_folder = os.path.join(sm_public_path, 'libudis86')
if os.path.isdir(libudis_folder):
binary.compiler.defines += ['HAVE_STRING_H']
binary.sources += [
os.path.join(libudis_folder, 'decode.c'),
os.path.join(libudis_folder, 'itab.c'),
os.path.join(libudis_folder, 'syn-att.c'),
os.path.join(libudis_folder, 'syn-intel.c'),
os.path.join(libudis_folder, 'syn.c'),
os.path.join(libudis_folder, 'udis86.c'),
]
def HL2Library(self, context, compiler, name, sdk):
binary = self.Library(context, compiler, name)
self.ConfigureForExtension(context, binary.compiler)
return self.ConfigureForHL2(context, binary, sdk)
def HL2Project(self, context, compiler, name):
project = context.LibraryProject(name)
self.ConfigureForExtension(context, compiler)
return project
def HL2Config(self, project, context, compiler, name, sdk):
binary = project.Configure(compiler, name,
'{0} - {1} {2}'.format(self.tag, sdk.name, compiler.target.arch))
@@ -622,24 +662,43 @@ class ExtensionConfig(object):
self.ConfigureForExtension(context, binary.compiler)
return binary
class SafetyHookShim(object):
def __init__(self):
self.all_targets = {}
self.libsafetyhook = {}
if getattr(builder, 'target', None) is not None:
sys.stderr.write("Your output folder was configured for AMBuild 2.1, and SourceMod is now\n")
sys.stderr.write("configured to use AMBuild 2.2. Please remove your output folder and\n")
sys.stderr.write("reconfigure to continue.\n")
sys.stderr.write("Your output folder was configured for AMBuild 2.1.\n")
sys.stderr.write("Please remove your output folder and reconfigure to continue.\n")
os._exit(1)
SM = ExtensionConfig()
SM.detectSDKs()
SM.configure()
Extension = ExtensionConfig()
Extension.detectProductVersion()
Extension.detectSDKs()
Extension.configure()
if os.path.exists(os.path.join(Extension.sm_root, 'public', 'safetyhook')):
# we need to pull safetyhook in locally because ambuild does not take kindly to outside relpaths
safetyhook_dest = Normalize(builder.sourcePath + '/safetyhook/')
shutil.copytree(os.path.join(Extension.sm_root, 'public', 'safetyhook'), safetyhook_dest, dirs_exist_ok=True)
SafetyHook = SafetyHookShim()
SafetyHook.all_targets = Extension.all_targets
builder.Build('safetyhook/AMBuilder', {'SafetyHook': SafetyHook })
Extension.libsafetyhook = SafetyHook.libsafetyhook
# This will clone the list and each cxx object as we recurse, preventing child
# scripts from messing up global state.
builder.targets = builder.CloneableList(SM.all_targets)
builder.targets = builder.CloneableList(Extension.all_targets)
# Add additional buildscripts here
BuildScripts = [
'AMBuilder',
]
if builder.backend == 'amb2':
BuildScripts = [
'AMBuilder',
'PackageScript',
]
BuildScripts += [
'PackageScript',
]
builder.Build(BuildScripts, { 'SM': SM})
builder.Build(BuildScripts, { 'Extension': Extension })
+15 -41
View File
@@ -1,48 +1,22 @@
# vim: set sts=2 ts=8 sw=2 tw=99 et ft=python:
import os
import os, sys
projectName = 'a2sqcache'
projectname = 'a2sqcache'
for cxx in builder.targets:
for sdk_name in SM.sdks:
sdk = SM.sdks[sdk_name]
project = builder.LibraryProject(projectname + '.ext')
project.sources = [
'extension.cpp',
os.path.join(Extension.sm_root, 'public', 'smsdk_ext.cpp'),
]
for sdk_name in Extension.sdks:
sdk = Extension.sdks[sdk_name]
for cxx in builder.targets:
if not cxx.target.arch in sdk.platformSpec[cxx.target.platform]:
continue
binary = Extension.HL2ExtConfig(project, builder, cxx, projectname + '.ext.' + sdk.ext, sdk)
Extension.AddCDetour(binary)
sdk.ext = "." + sdk.ext
if "sdk2013" in sdk.ext:
sdk.ext = ""
binary = SM.HL2Library(builder, cxx, projectName + ".ext" + sdk.ext, sdk)
binary.compiler.defines += [
'HAVE_STRING_H',
]
if cxx.target.platform == 'linux':
cxx.postlink += ['-lpthread', '-lrt']
elif cxx.target.platform == 'mac':
cxx.cflags += ['-Wno-deprecated-declarations']
cxx.postlink += ['-framework', 'CoreServices']
if cxx.family == 'gcc' or cxx.family == 'clang':
cxx.cxxflags += ['-fno-rtti']
elif cxx.family == 'msvc':
cxx.cxxflags += ['/GR-']
binary.sources += [
'extension.cpp',
os.path.join(SM.sm_root, 'extensions', 'sm-ext-common', 'mathstubs.c'),
os.path.join(SM.sm_root, 'public', 'smsdk_ext.cpp'),
os.path.join(SM.sm_root, 'public', 'CDetour', 'detours.cpp'),
os.path.join(SM.sm_root, 'public', 'asm', 'asm.c'),
os.path.join(SM.sm_root, 'public', 'libudis86', 'decode.c'),
os.path.join(SM.sm_root, 'public', 'libudis86', 'itab.c'),
os.path.join(SM.sm_root, 'public', 'libudis86', 'syn-att.c'),
os.path.join(SM.sm_root, 'public', 'libudis86', 'syn-intel.c'),
os.path.join(SM.sm_root, 'public', 'libudis86', 'syn.c'),
os.path.join(SM.sm_root, 'public', 'libudis86', 'udis86.c'),
]
SM.extensions += [builder.Add(binary)]
Extension.extensions = builder.Add(project)
+36 -46
View File
@@ -1,57 +1,47 @@
# vim: set ts=8 sts=2 sw=2 tw=99 et ft=python:
# vim: set ts=2 sw=2 tw=99 noet ft=python:
import os
import shutil
import ambuild.osutil as osutil
from ambuild.command import Command
# This is where the files will be output to
# package is the default
builder.SetBuildFolder('package')
# Add any folders you need to this list
folder_list = [
'addons/sourcemod/extensions',
'addons/sourcemod/scripting/include',
'addons/sourcemod/gamedata'
]
def CreateFolders(folders):
dict = {}
for folder in folders:
path = os.path.normpath(folder)
dict[folder] = builder.AddFolder(path)
return dict
if 'x86_64' in SM.target_archs:
folder_list.extend([
'addons/sourcemod/extensions/x64',
])
def CopyFiles(src, dest, filter_ext=None):
source_path = os.path.join(builder.sourcePath, src)
if os.path.isfile(source_path):
builder.AddCopy(source_path, dest)
return
for entry in os.listdir(source_path):
entry_path = os.path.join(source_path, entry)
if not os.path.isfile(entry_path):
continue
if filter_ext:
_, ext = os.path.splitext(entry)
if filter_ext != ext:
continue
builder.AddCopy(entry_path, dest)
# 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)
# Copy binaries.
for cxx_task in SM.extensions:
folders = CreateFolders(['addons/sourcemod/extensions', 'addons/sourcemod/extensions/x64', 'addons/sourcemod/gamedata', 'addons/sourcemod/scripting', 'addons/sourcemod/scripting/include'])
pdblog = open(os.path.join(builder.buildPath, 'pdblog.txt'), 'wt')
for cxx_task in Extension.extensions:
if cxx_task.target.arch == 'x86_64':
builder.AddCopy(cxx_task.binary, folder_map['addons/sourcemod/extensions/x64'])
builder.AddCopy(cxx_task.binary, folders['addons/sourcemod/extensions/x64'])
else:
builder.AddCopy(cxx_task.binary, folder_map['addons/sourcemod/extensions'])
builder.AddCopy(cxx_task.binary, folders['addons/sourcemod/extensions'])
pdblog.write(cxx_task.debug.path + '\n')
pdblog.close()
# 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)
dest_path = os.path.join(dest_entry.path, source_file)
if not os.path.isfile(str(dest_path)):
builder.AddCopy(source_path, dest_entry)
CopyFiles('addons/sourcemod/gamedata/a2sqcache.games.txt', folders['addons/sourcemod/gamedata'])
CopyFiles('addons/sourcemod/scripting/include/a2sqcache.inc', folders['addons/sourcemod/scripting/include'])
CopyFiles('addons/sourcemod/extensions/a2sqcache.autoload', folders['addons/sourcemod/extensions'])
# Gamedata (custom so updater doesn't replace it)
CopyFiles('addons/sourcemod/gamedata', 'addons/sourcemod/gamedata',
[ 'a2sqcache.games.txt' ]
)
# Include file
CopyFiles('addons/sourcemod/scripting/include', 'addons/sourcemod/scripting/include',
[ 'a2sqcache.inc' ]
)
# Autoload extension
CopyFiles('addons/sourcemod/extensions', 'addons/sourcemod/extensions',
[ 'a2sqcache.autoload' ]
)
debug_info = []
@@ -37,6 +37,19 @@
"Signatures"
{
"Steam3Server"
{
"library" "engine"
"linux" "@_Z12Steam3Serverv"
"linux64" "@_Z12Steam3Serverv"
}
"CBaseServer__CheckMasterServerRequestRestart"
{
"library" "engine"
"windows" "\xE8\x2A\x2A\x2A\x2A\x83\x78\x04\x00\x74\x2A\xE8\x2A\x2A\x2A\x2A\x8B\x48\x04\x8B\x01\x8B\x40\x2C\xFF\xD0\x84\xC0\x74\x2A\x56"
}
"net_sockets"
{
"library" "engine"
@@ -75,6 +88,11 @@
"windows" "1"
"linux" "2"
}
"CheckMasterServerRequestRestart_Steam3ServerFuncOffset"
{
"windows" "1"
}
}
}
+87 -9
View File
@@ -52,6 +52,19 @@
#include <sys/socket.h>
#include <netinet/in.h>
enum
{
NS_CLIENT = 0, // client socket
NS_SERVER, // server socket
NS_HLTV,
NS_MATCHMAKING,
NS_SYSTEMLINK,
#ifdef LINUX
NS_SVLAN, // LAN udp port for Linux. See NET_OpenSockets for info.
#endif
MAX_SOCKETS
};
size_t
strlcpy(char *dst, const char *src, size_t dsize)
{
@@ -156,6 +169,32 @@ typedef struct
#endif
} netsocket_t;
class CSteam3Server
{
public:
void *m_pSteamClient;
ISteamGameServer *m_pSteamGameServer;
void *m_pSteamGameServerUtils;
void *m_pSteamGameServerNetworking;
void *m_pSteamGameServerStats;
void *m_pSteamHTTP;
void *m_pSteamInventory;
void *m_pSteamUGC;
void *m_pSteamApps;
} *g_pSteam3Server;
typedef CSteam3Server *(*Steam3ServerFunc)();
Steam3ServerFunc g_pSteam3ServerFunc = NULL;
CSteam3Server *Steam3Server()
{
if (!g_pSteam3ServerFunc)
return NULL;
return g_pSteam3ServerFunc();
}
CUtlVector<netsocket_t> *net_sockets;
int g_ServerUDPSocket = 0;
@@ -256,7 +295,7 @@ void UpdateQueryCache()
#endif
info.nPassword = iserver->GetPassword() ? 1 : 0;
info.bIsSecure = true;
info.bIsSecure = g_pSteam3Server->m_pSteamGameServer->BSecure() ? 1 : 0;
if(!(info.nNewFlags & S2A_EXTRA_DATA_HAS_STEAMID) && engine->GetGameServerSteamID())
{
@@ -276,7 +315,7 @@ void UpdateQueryCache()
IServer *ihltvserver = hltv->GetBaseServer();
if(ihltvserver)
{
info.iHLTVUDPPort = ihltvserver->GetUDPPort();
info.iHLTVUDPPort = ihltvserver->GetLocalUDPPort();
info.aHLTVNameLen = strlcpy(info.aHLTVName, ihltvserver->GetName(), sizeof(info.aHLTVName));
info.nNewFlags |= S2A_EXTRA_DATA_HAS_SPECTATOR_DATA;
}
@@ -416,10 +455,8 @@ void SendA2S_Info(netpacket_t * packet)
// Password?
buf.PutUnsignedChar( iserver->GetPassword() ? 1 : 0 );
// buf.PutUnsignedChar( Steam3Server().BSecure() ? 1 : 0 );
// Secure?
buf.PutUnsignedChar( 1 );
buf.PutUnsignedChar( g_pSteam3Server->m_pSteamGameServer->BSecure() ? 1 : 0 );
buf.PutString( g_QueryCache.info.aVersion );
@@ -432,7 +469,7 @@ void SendA2S_Info(netpacket_t * packet)
// Write the rest of the data.
if ( g_QueryCache.info.nNewFlags & S2A_EXTRA_DATA_HAS_GAME_PORT )
{
buf.PutShort( LittleWord( iserver->GetUDPPort() ) );
buf.PutShort( LittleWord( iserver->GetLocalUDPPort() ) );
}
#if SOURCE_ENGINE <= SE_CSGO
@@ -604,6 +641,48 @@ bool A2SQCache::SDK_OnLoad(char *error, size_t maxlen, bool late)
}
#endif
#ifndef WIN32
if (!g_pGameConf->GetMemSig("Steam3Server", (void **)(&g_pSteam3ServerFunc)) || !g_pSteam3ServerFunc)
{
snprintf(error, maxlen, "Failed to find Steam3Server function.\n");
return false;
}
#else
void *address;
if (!g_pGameConf->GetMemSig("CBaseServer__CheckMasterServerRequestRestart", &address) || !address)
{
snprintf(error, maxlen, "Failed to find CBaseServer__CheckMasterServerRequestRestart function.\n");
return false;
}
int steam3ServerFuncOffset = 0;
if (!g_pGameConf->GetOffset("CheckMasterServerRequestRestart_Steam3ServerFuncOffset", &steam3ServerFuncOffset) || steam3ServerFuncOffset == 0)
{
snprintf(error, maxlen, "Failed to find CheckMasterServerRequestRestart_Steam3ServerFuncOffset offset.\n");
return false;
}
//META_CONPRINTF("CheckMasterServerRequestRestart: %p\n", address);
address = (void *)((intptr_t)address + steam3ServerFuncOffset);
intptr_t offset = (intptr_t)(*(void **)address); // Get offset
g_pSteam3ServerFunc = (Steam3ServerFunc)((intptr_t)address + offset + sizeof(intptr_t));
//META_CONPRINTF("Steam3Server: %p\n", g_pSteam3ServerFunc);
#endif
g_pSteam3Server = Steam3Server();
if (!g_pSteam3Server)
{
snprintf(error, maxlen, "Unable to get Steam3Server singleton.\n");
return false;
}
if (!g_pSteam3Server->m_pSteamGameServer)
{
snprintf(error, maxlen, "Unable to get Steam Game Server.\n");
return false;
}
CDetourManager::Init(g_pSM->GetScriptingEngine(), g_pGameConf);
g_Detour_CBaseServer__InactivateClients = DETOUR_CREATE_MEMBER(CBaseServer__InactivateClients, "CBaseServer__InactivateClients");
@@ -680,8 +759,7 @@ void A2SQCache::SDK_OnAllLoaded()
return;
}
int socknum = 1; // NS_SERVER
g_ServerUDPSocket = (*net_sockets)[socknum].hUDP;
g_ServerUDPSocket = (*net_sockets)[NS_SERVER].hUDP;
if(!g_ServerUDPSocket)
{
@@ -715,7 +793,7 @@ void A2SQCache::SDK_OnAllLoaded()
info.aVersionLen = snprintf(info.aVersion, sizeof(info.aVersion), "%d", engine->GetServerVersion());
#endif
info.iUDPPort = iserver->GetUDPPort();
info.iUDPPort = iserver->GetLocalUDPPort();
info.nNewFlags |= S2A_EXTRA_DATA_HAS_GAME_PORT;
info.iGameID = info.iSteamAppID;
+1
View File
@@ -0,0 +1 @@
1.1.1
+1 -1
View File
@@ -40,7 +40,7 @@
/* Basic information exposed publicly */
#define SMEXT_CONF_NAME "A2SQCache"
#define SMEXT_CONF_DESCRIPTION "A2S_INFO + A2S_PLAYER cache"
#define SMEXT_CONF_VERSION "1.1"
#define SMEXT_CONF_VERSION "1.1.1"
#define SMEXT_CONF_AUTHOR "BotoX, maxime1907"
#define SMEXT_CONF_URL "https://git.botox.bz/CSSZombieEscape/sm-ext-A2SQCache"
#define SMEXT_CONF_LOGTAG "A2SQCACHE"