fix: crash when exiting linux listen server (#241)

fix: crash when loading on windows xp (#244)
build: switched to github hosted runners, and get rid of self-hosted
build: windows exe and dll is now code-signed
build: drop support for intel icc compiler
This commit is contained in:
dmitry 2021-09-08 20:09:23 +03:00
commit 1e9bc3cb5f
No known key found for this signature in database
GPG key ID: 8297CE728B7A7E37
9 changed files with 456 additions and 287 deletions

View file

@ -1,51 +1,154 @@
name: YaPB
name: build
on:
push:
branches: [master]
paths-ignore:
- '**.md'
pull_request:
branches: [master]
types: [opened, reopened, synchronize]
release:
types: [published]
jobs:
linux:
name: Full Build
runs-on: self-hosted
build:
strategy:
matrix:
include:
- os: windows-latest
bin: yapb.dll
name: windows
- os: ubuntu-latest
bin: yapb.so
name: linux
clang: 12
name: ${{ matrix.name }}
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v2
- name: Checkout Repository
uses: actions/checkout@v2
with:
submodules: true
fetch-depth: 0
submodules: true
- name: Setup Windows x86
if: startsWith (runner.os, 'windows')
uses: ilammy/msvc-dev-cmd@v1
with:
arch: amd64_x86
- name: Setup Linux x86
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
echo "CXX=clang-${{ matrix.clang }}" >> $GITHUB_ENV
echo "CXX_LD=lld-${{ matrix.clang }}" >> $GITHUB_ENV
- name: Setup Python
uses: actions/setup-python@v2
with:
python-version: '3.x'
- name: Setup Meson
shell: bash
run: |
meson setup build_x86_win32 --cross-file=/actions/meson/windows-msvc-32bit.txt -Db_vscrt=mt
meson setup build_x86_macos --cross-file=/actions/meson/darwin-clang-32bit.txt
CXX=clang meson setup build_x86_linux
python -m pip install --upgrade meson ninja
- name: Build Bot
shell: bash
- name: Configure Build
run: |
ninja -C build_x86_win32 -v
ninja -C build_x86_macos -v
ninja -C build_x86_linux -v
meson setup build
- name: Build Package
shell: bash
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }}
- name: Compile Source
run: |
meson compile -v -C build
- name: Upload Artifacts
uses: actions/upload-artifact@v2
with:
name: ${{ matrix.bin }}
path: build/${{ matrix.bin }}
macos:
name: macos
runs-on: ubuntu-latest
container: j4sdk/macross-x86:latest
steps:
- name: Checkout Repository
uses: actions/checkout@v2
with:
fetch-depth: 0
submodules: true
- name: Configure Build
run: |
CXX_LD=/opt/osxcross/target/bin/i386-apple-darwin15-ld meson setup build --cross-file=x86-darwin
- name: Compile Source
run: |
meson compile -v -C build
- name: Upload Artifacts
uses: actions/upload-artifact@v2
with:
name: yapb.dylib
path: build/yapb.dylib
publish:
if: |
github.event_name == 'release' &&
github.event.action == 'published'
name: publish
runs-on: ubuntu-latest
needs: [build, macos]
steps:
- name: Checkout Repository
uses: actions/checkout@v2
with:
fetch-depth: 0
submodules: true
- name: Install Signing Tools
run: |
sudo apt-get update && sudo apt-get upgrade -y
sudo apt-get install -y --no-install-recommends osslsigncode
- name: Get Artifacts
uses: actions/download-artifact@v2
with:
path: artifacts
- name: Setup Python
uses: actions/setup-python@v2
with:
python-version: '3.x'
- name: Setup Meson
run: |
python -m pip install --upgrade meson ninja urllib3
- name: Create Packages
run: |
meson setup dist
ninja -C dist package
env:
CS_CERTIFICATE: ${{ secrets.CS_CERTIFICATE }}
CS_CERTIFICATE_PASSWORD: ${{ secrets.CS_CERTIFICATE_PASSWORD }}
- uses: actions/upload-artifact@v2
name: Upload Artifacts
- name: Publish Release
uses: softprops/action-gh-release@v1
if: startsWith(github.ref, 'refs/tags/')
with:
name: yapb.zip
path: |
build_x86_win32/yapb.dll
build_x86_linux/yapb.so
build_x86_macos/yapb.dylib
files: pkg/*
env:
GITHUB_TOKEN: ${{ secrets.API_TOKEN }}

View file

@ -1,5 +1,5 @@
## YaPB
[![Latest YaPB](https://img.shields.io/github/v/release/yapb/yapb)](https://github.com/yapb/yapb/releases/latest) [![Latest YaPB](https://github.com/yapb/yapb/workflows/YaPB/badge.svg)](https://github.com/yapb/yapb/actions) [![YaPB License](https://img.shields.io/github/license/yapb/yapb)](https://github.com/yapb/yapb/blob/master/LICENSE)
[![Latest YaPB](https://img.shields.io/github/v/release/yapb/yapb)](https://github.com/yapb/yapb/releases/latest) [![Latest YaPB](https://github.com/yapb/yapb/workflows/build/badge.svg)](https://github.com/yapb/yapb/actions) [![YaPB License](https://img.shields.io/github/license/yapb/yapb)](https://github.com/yapb/yapb/blob/master/LICENSE)
## ☉ About
It's a computer controlled players (bots) for the Counter-Strike b6.6 - 1.6 and Counter-Strike: Condition Zero. Bots allows you to play that games without connecting any game server or even without internet.

View file

@ -643,10 +643,12 @@ class EntityLinkage : public Singleton <EntityLinkage> {
private:
#if defined (CR_WINDOWS)
# define DLSYM_FUNCTION GetProcAddress
# define DLCLOSE_FUNCTION FreeLibrary
# define DLSYM_RETURN FARPROC
# define DLSYM_HANDLE HMODULE
#else
# define DLSYM_FUNCTION dlsym
# define DLCLOSE_FUNCTION dlclose
# define DLSYM_RETURN SharedLibrary::Handle
# define DLSYM_HANDLE SharedLibrary::Handle
#endif
@ -655,6 +657,7 @@ private:
bool m_paused { false };
Detour <decltype (DLSYM_FUNCTION)> m_dlsym;
Detour <decltype (DLCLOSE_FUNCTION)> m_dlclose;
HashMap <StringRef, DLSYM_RETURN> m_exports;
SharedLibrary m_self;
@ -666,6 +669,15 @@ public:
void initialize ();
DLSYM_RETURN lookup (SharedLibrary::Handle module, const char *function);
int close (DLSYM_HANDLE module) {
if (m_self.handle () == module) {
disable ();
return m_dlclose (module);
}
return m_dlclose (module);
}
public:
void callPlayerFunction (edict_t *ent) {
#if defined (CR_ANDROID) && defined (CR_ARCH_ARM)
@ -699,16 +711,20 @@ public:
}
public:
static DLSYM_RETURN CR_STDCALL replacement (SharedLibrary::Handle module, const char *function) {
static DLSYM_RETURN CR_STDCALL lookupHandler (SharedLibrary::Handle module, const char *function) {
return EntityLinkage::instance ().lookup (module, function);
}
static int CR_STDCALL closeHandler (DLSYM_HANDLE module) {
return EntityLinkage::instance ().close (module);
}
public:
void clearExportTable () {
void flush () {
m_exports.clear ();
}
bool isWorkaroundNeeded () {
bool needsBypass () const {
return !plat.win && !Game::instance ().isDedicated ();
}
};

View file

@ -9,12 +9,12 @@
// generated by meson build system
#ifndef MODULE_BUILD_HASH
# define MODULE_BUILD_HASH "@commitHash@"
# define MODULE_BUILD_AUTHOR @commitAuthor@
# define MODULE_BUILD_COUNT "@commitCount@"
# define MODULE_BUILD_MACHINE "@buildMachine@"
# define MODULE_BUILD_COMPILER "@buildCompiler@"
# define MODULE_BOT_VERSION "@buildVersion@"
# define MODULE_BOT_VERSION_FILE @buildVersionWin@,@commitCount@
# define MODULE_BOT_BUILD_ID "@commitCount@:@commitHash@"
# define MODULE_BUILD_HASH "@hash@"
# define MODULE_BUILD_AUTHOR @author@
# define MODULE_BUILD_COUNT "@count@"
# define MODULE_BUILD_MACHINE "@machine@"
# define MODULE_BUILD_COMPILER "@compiler@"
# define MODULE_BOT_VERSION "@version@"
# define MODULE_BOT_VERSION_FILE @version_win@,@count@
# define MODULE_BOT_BUILD_ID "@count@:@hash@"
#endif

View file

@ -1147,12 +1147,12 @@ public:
template <typename ...Args> void issueCommand (const char *fmt, Args &&...args);
};
#include <config.h>
#include <support.h>
#include <message.h>
#include <engine.h>
#include <manager.h>
#include <control.h>
#include "config.h"
#include "support.h"
#include "message.h"
#include "engine.h"
#include "manager.h"
#include "control.h"
// very global convars
extern ConVar cv_jasonmode;

View file

@ -22,55 +22,59 @@ project (
'strip=true',
'optimization=3',
'default_library=static',
'cpp_eh=none'
'cpp_eh=none',
'b_vscrt=static_from_buildtype'
],
meson_version: '>=0.48.0')
meson_version: '>=0.56.0')
find_program ('ninja', required: true)
find_program ('git', required: true)
find_program ('hostname', required: true)
buildCompiler = meson.get_compiler ('cpp')
buildSystem = host_machine.system ()
buildVersion = meson.project_version ()
buildCount = run_command ('git', 'rev-list', '--count', 'HEAD').stdout ().strip ()
cpp = meson.get_compiler ('cpp')
sys = host_machine.system ()
version = meson.project_version ()
count = run_command ('git', 'rev-list', '--count', 'HEAD').stdout ().strip ()
compilerId = buildCompiler.get_id ()
compilerVersion = buildCompiler.version ()
cpp_id = cpp.get_id ()
cpp_version = cpp.version ()
isOptimize = get_option ('buildtype') == 'release' or get_option ('buildtype') == 'debugoptimized'
isVC = compilerId == 'msvc' or compilerId == 'intel-cl' or compilerId == 'clang-cl'
isGCC = compilerId == 'gcc'
isIntel = compilerId == 'intel' or compilerId == 'intel-cl'
isCLang = compilerId == 'clang'
isWindows = buildSystem == 'windows'
isLinux = buildSystem == 'linux'
isDarwin = buildSystem == 'darwin'
optmize = get_option ('buildtype') == 'release' or get_option ('buildtype') == 'debugoptimized'
msvc = cpp_id == 'msvc' or cpp_id == 'clang-cl'
gcc = cpp_id == 'gcc'
clang = cpp_id == 'clang'
win32 = sys == 'windows'
linux = sys == 'linux'
mac = sys == 'darwin'
ldflags = []
ccflags = []
cdata = configuration_data()
if isWindows
cdata.set ('buildVersionWin', ','.join (buildVersion.split ('.')))
if win32
cdata.set ('version_win', ','.join (version.split ('.')))
cdata.set ('machine', run_command ('hostname').stdout ().strip ())
else
cdata.set ('buildVersionWin', buildVersion)
cdata.set ('version_win', version)
cdata.set ('machine', run_command ('hostname', '-f').stdout ().strip ())
endif
cdata.set ('commitHash', run_command ('git', 'rev-parse', '--short', 'HEAD').stdout ().strip ())
cdata.set ('commitAuthor', run_command ('git', 'log', '--pretty="%ae"', '-1').stdout ().strip ())
cdata.set ('hash', run_command ('git', 'rev-parse', '--short', 'HEAD').stdout ().strip ())
cdata.set ('author', run_command ('git', 'log', '--pretty="%ae"', '-1').stdout ().strip ())
cdata.set ('commitCount', buildCount)
cdata.set ('buildVersion', buildVersion)
cdata.set ('buildMachine', run_command ('hostname', '-f').stdout ().strip ())
cdata.set ('buildCompiler', compilerId + ' ' + compilerVersion)
cdata.set ('count', count)
cdata.set ('version', version)
cdata.set ('compiler', cpp_id + ' ' + cpp_version)
configure_file (input: 'inc/version.h.in', output: 'version.build.h', configuration: cdata)
ccflags += '-DVERSION_GENERATED'
if isCLang or isGCC or (isIntel and not isWindows)
if clang or gcc
ccflags += [
'-m32',
'-fno-threadsafe-statics',
@ -78,36 +82,32 @@ if isCLang or isGCC or (isIntel and not isWindows)
'-fno-rtti'
]
if not isDarwin
if not mac
ccflags += [
'-pedantic',
]
endif
if isOptimize
ccflags += '-msse3'
if (isCLang or isGCC) and not isDarwin
if optmize
if (clang or gcc) and not mac
ccflags += [
'-flto',
'-fdata-sections',
'-ffunction-sections'
]
if isGCC
if gcc
ccflags += '-fgraphite-identity'
ldflags += '-flto-partition=none'
endif
ldflags += [
'-flto',
'-Wl,--version-script=../version_script.lds',
'-Wl,--gc-sections'
'-flto'
]
endif
endif
if isLinux
if linux
ldflags += [
'-m32',
'-lm',
@ -116,18 +116,10 @@ if isCLang or isGCC or (isIntel and not isWindows)
endif
endif
if isIntel and (isLinux or isDarwin)
ldflags += [
'-static-intel',
'-no-intel-extensions'
]
endif
if isLinux or isDarwin
if isDarwin
if linux or mac or (win32 and (gcc or clang))
if mac
ccflags += '-mmacosx-version-min=10.9'
ldflags += [
'-dynamiclib',
'-lstdc++',
'-mmacosx-version-min=10.9'
]
@ -135,7 +127,7 @@ if isLinux or isDarwin
ldflags += '-static-libgcc'
endif
if not isOptimize
if not optmize
ccflags += [
'-g3',
'-ggdb',
@ -144,7 +136,7 @@ if isLinux or isDarwin
else
ccflags += [
'-mtune=generic',
'-msse3',
'-msse2',
'-mfpmath=sse',
'-fno-builtin',
'-funroll-loops',
@ -154,38 +146,24 @@ if isLinux or isDarwin
'-fvisibility-inlines-hidden'
]
if isIntel
ccflags += [
'-ipo',
'-wd11076',
'-wd11074'
]
if clang and not mac
lld = find_program ('lld', required: false)
if lld.found () == true
ldflags += '-fuse-ld=' + lld.full_path ().split ('/')[-1]
endif
ldflags += [
'-cxxlib-nostd',
'-Wl,--no-undefined,-z,notext,--gc-sections',
'-ipo'
'-nostdlib++',
'-Wunused-command-line-argument'
]
elif isCLang and not isDarwin
llvmLinker = find_program ('lld', required: false)
if llvmLinker.found() == true
ldflags += '-fuse-ld=' + llvmLinker.path ().split ('/')[-1]
endif
ldflags += [
'-nostdlib++',
'-Wunused-command-line-argument',
'-Wl,-z,notext',
'--no-undefined'
]
elif isGCC and not isDarwin
ldflags += '-Wl,--no-undefined'
endif
elif gcc and not mac
ldflags += '-Wl,--no-undefined'
endif
endif
endif
if isWindows and (isVC or isIntel)
if win32 and msvc
ldflags += [
'/MACHINE:X86',
'user32.lib',
@ -193,32 +171,34 @@ if isWindows and (isVC or isIntel)
]
ccflags += [
'/TP'
'/TP',
'/D _WIN32_WINNT=0x0501',
'/D _USING_V110_SDK71_',
'/Zc:threadSafeInit-'
]
if isOptimize
if optmize
ccflags += [
'/GL',
'/arch:SSE2',
'/GS-',
'/Ob2',
'/Oy',
'/Oi'
'/Oi',
'/Ot',
'/fp:precise',
'/GF'
]
ldflags += '/LTCG'
endif
elif isWindows and (isCLang or isGCC)
if isCLang
ldflags += '-Wl,/MACHINE:X86'
else
ldflags += [
'-static-libgcc',
'-Wl,--kill-at'
]
'/LTCG',
'delayimp.lib',
'/DELAYLOAD:user32.dll',
'/SUBSYSTEM:WINDOWS,5.01',
]
endif
elif win32 and (clang or gcc)
ldflags += [
'-Wl,--kill-at',
'-luser32',
'-lws2_32'
]
@ -228,7 +208,6 @@ add_global_arguments (ccflags, language: 'cpp')
add_global_link_arguments (ldflags, language: 'cpp')
sources = files (
'src/android.cpp',
'src/botlib.cpp',
'src/chatlib.cpp',
'src/combat.cpp',
@ -245,10 +224,10 @@ sources = files (
)
includes = include_directories ([
'.', 'inc', 'ext',
'.', 'inc', 'ext', 'ext/crlib'
], is_system: true)
if isWindows and not isCLang
if win32
sources += import('windows').compile_resources (
'vc/yapb.rc',
include_directories: includes,
@ -260,9 +239,8 @@ shared_library (
meson.project_name (),
sources,
include_directories: includes,
gnu_symbol_visibility: 'hidden',
name_prefix: '')
run_target ('package',
command : ['python', meson.source_root() + '/package.py', '@0@.@1@'.format (buildVersion, buildCount)])
command: ['python3', meson.project_source_root () + '/package.py', '@0@.@1@'.format (version, count)])

View file

@ -6,127 +6,223 @@
# SPDX-License-Identifier: MIT
#
import os, sys, subprocess
from genericpath import isdir
import os, sys, subprocess, base64
import locale, urllib3
import pathlib, shutil
import zipfile, tarfile
import datetime, calendar
from github import Github
class CodeSign (object):
def __init__(self, product, url, verify_signature=False):
self.signing = True
self.ossl_path = "/usr/bin/osslsigncode"
self.local_key = os.path.join (pathlib.Path ().absolute (), "key.pfx");
self.product = product
self.url = url
self.verify_signature = verify_signature
if not os.path.exists (self.ossl_path):
self.signing = False
if not "CS_CERTIFICATE" in os.environ:
self.signing = False
if not "CS_CERTIFICATE_PASSWORD" in os.environ:
self.signing = False
if self.signing:
self.password = os.environ.get ("CS_CERTIFICATE_PASSWORD")
encoded = os.environ.get ("CS_CERTIFICATE")
if len (encoded) < 64:
print ('Damaged certificate. Signing disabled.')
self.signing = False
return
decoded = base64.b64decode (encoded)
with open (self.local_key, "wb") as key:
key.write (decoded)
def has(self):
return self.signing
def sign_file_inplace (self, filename):
signed_filename = filename + ".signed"
sign = []
sign.append (self.ossl_path)
sign.append ("sign")
sign.append ("-pkcs12")
sign.append (self.local_key)
sign.append ("-pass")
sign.append (self.password)
sign.append ("-n")
sign.append (self.product)
sign.append ("-i")
sign.append (self.url)
sign.append ("-h")
sign.append ("sha256")
sign.append ("-t")
sign.append ("http://timestamp.sectigo.com")
sign.append ("-in")
sign.append (filename)
sign.append ("-out")
sign.append (signed_filename)
result = subprocess.run (sign, capture_output=True, text=True)
if result.returncode == 0:
os.unlink (filename)
shutil.move (signed_filename, filename)
print ("Signing result: {}".format (result.stdout))
if self.verify_signature:
verify = []
verify.append (self.ossl_path)
verify.append ("verify")
verify.append (filename)
verify = subprocess.run (verify, capture_output=True, text=True)
print (verify.stdout)
else:
print (result.stdout)
class BotRelease (object):
def __init__(self):
print ("Initializing Packaging")
self.workDir = os.path.join (pathlib.Path ().absolute (), 'cfg')
self.botDir = os.path.join (self.workDir, 'addons', 'yapb')
self.distDir = os.path.join (pathlib.Path ().absolute (), 'dist');
meson_src_root_env = "MESON_SOURCE_ROOT"
if meson_src_root_env in os.environ:
os.chdir (os.environ.get (meson_src_root_env))
self.work_dir = os.path.join (pathlib.Path ().absolute (), "cfg")
self.bot_dir = os.path.join (self.work_dir, "addons", "yapb")
self.pkg_dir = os.path.join (pathlib.Path ().absolute (), "pkg")
if len (sys.argv) < 2:
raise Exception('Missing required parameters.')
raise Exception("Missing required parameters.")
self.version = sys.argv[1]
self.artifacts = 'artifacts'
os.makedirs (self.distDir, exist_ok=True)
self.cs = CodeSign ("YaPB", "https://yapb.ru/")
self.outFileWin32 = os.path.join (self.distDir, "yapb-{}-windows.zip".format (self.version))
self.outFileLinux = os.path.join (self.distDir, "yapb-{}-linux.tar.xz".format (self.version))
self.outFileMacOS = os.path.join (self.distDir, "yapb-{}-macos.zip".format (self.version))
if self.cs.has ():
print ("Code Signing Enabled")
else:
print ("Code Signing Disabled")
self.outFileWin32Setup = self.outFileWin32.replace ("zip", "exe")
self.win32SetupUrl = "https://github.com/yapb/setup/releases/latest/download/botsetup.exe"
os.makedirs (self.pkg_dir, exist_ok=True)
def makeDirs (self):
self.pkg_win32 = os.path.join (self.pkg_dir, "yapb-{}-windows.zip".format (self.version))
self.pkg_linux = os.path.join (self.pkg_dir, "yapb-{}-linux.tar.xz".format (self.version))
self.pkg_macos = os.path.join (self.pkg_dir, "yapb-{}-macos.zip".format (self.version))
self.pkg_win32_sfx = self.pkg_win32.replace ("zip", "exe")
self.pkg_win32_sfx_url = "https://github.com/yapb/setup/releases/latest/download/botsetup.exe"
def make_directories (self):
dirs = [
'bin',
os.path.join ('data', 'pwf'),
os.path.join ('data', 'train'),
os.path.join ('data', 'graph'),
os.path.join ('data', 'logs')
"bin",
os.path.join ("data", "pwf"),
os.path.join ("data", "train"),
os.path.join ("data", "graph"),
os.path.join ("data", "logs")
]
for dir in dirs:
os.makedirs (os.path.join (self.botDir, dir), exist_ok=True)
os.makedirs (os.path.join (self.bot_dir, dir), exist_ok=True)
def download (self, fromWhere, toFile):
def http_pull (self, url, local_file):
http = urllib3.PoolManager (10, headers = {"user-agent": "YaPB"})
data = http.urlopen ('GET', fromWhere)
data = http.urlopen ("GET", url)
with open (toFile, "wb") as file:
with open (local_file, "wb") as file:
file.write (data.data)
def getGraph (self, name):
file = os.path.join (self.botDir, 'data', 'graph', "{}.graph".format (name))
url = "http://graph.yapb.ru/graph/{}.graph".format (name);
def get_graph_file (self, name):
file = os.path.join (self.bot_dir, "data", "graph", "{}.graph".format (name))
url = "http://graph.yapb.ru/graph/{}.graph".format (name)
if os.path.exists (file):
return
self.download (url, file)
self.http_pull (url, file)
def getGraphs (self):
def get_default_graphs (self):
print ("Downloading graphs: ")
files = ['as_oilrig', 'cs_747', 'cs_estate', 'cs_assault', 'cs_office',
'cs_italy', 'cs_havana', 'cs_siege', 'cs_backalley', 'cs_militia',
'cs_downed_cz', 'cs_havana_cz', 'cs_italy_cz', 'cs_militia_cz',
'cs_office_cz', 'de_airstrip_cz', 'de_aztec_cz', 'de_cbble_cz',
'de_chateau_cz', 'de_corruption_cz', 'de_dust_cz', 'de_dust2_cz',
'de_fastline_cz', 'de_inferno_cz', 'de_piranesi_cz', 'de_prodigy_cz',
'de_sienna_cz', 'de_stadium_cz', 'de_tides_cz', 'de_torn_cz',
'de_truth_cz', 'de_vostok_cz', 'de_inferno', 'de_aztec', 'de_dust',
'de_dust2', 'de_torn', 'de_storm', 'de_airstrip', 'de_piranesi',
'de_prodigy', 'de_chateau', 'de_cbble', 'de_nuke', 'de_survivor',
'de_vertigo', 'de_train']
default_list = "default.graph.txt"
self.http_pull ("http://graph.yapb.ru/DEFAULT.txt", default_list)
with open (default_list) as file:
files = [line.rstrip () for line in file.readlines ()]
for file in files:
print (" " + file)
self.getGraph (file)
self.get_graph_file (file)
def unlinkBinaries (self):
libs = ['yapb.so', 'yapb.dll', 'yapb.dylib']
def unlink_binaries (self):
libs = ["yapb.so", "yapb.dll", "yapb.dylib"]
for lib in libs:
path = os.path.join (self.botDir, 'bin', lib)
path = os.path.join (self.bot_dir, "bin", lib)
if os.path.exists (path):
os.remove (path)
def copyBinary (self, path):
shutil.copy (path, os.path.join (self.botDir, 'bin'))
def sign_binary (self, binary):
if self.cs.has () and (binary.endswith ("dll") or binary.endswith ("exe")):
print ("Signing {}".format (binary))
self.cs.sign_file_inplace (binary)
def zipDir (self, path, handle):
def copy_binary (self, binary):
dest_path = os.path.join (self.bot_dir, "bin", os.path.basename (binary))
shutil.copy (binary, dest_path)
self.sign_binary (dest_path)
def compress_directory (self, path, handle):
length = len (path) + 1
emptyDirs = []
empty_dirs = []
for root, dirs, files in os.walk (path):
emptyDirs.extend ([dir for dir in dirs if os.listdir (os.path.join (root, dir)) == []])
empty_dirs.extend ([dir for dir in dirs if os.listdir (os.path.join (root, dir)) == []])
for file in files:
filePath = os.path.join (root, file)
handle.write (filePath, filePath[length:])
file_path = os.path.join (root, file)
handle.write (file_path, file_path[length:])
for dir in emptyDirs:
dirPath = os.path.join (root, dir)
for dir in empty_dirs:
dir_path = os.path.join (root, dir)
zif = zipfile.ZipInfo (dirPath[length:] + "/")
zif = zipfile.ZipInfo (dir_path[length:] + "/")
handle.writestr (zif, "")
emptyDirs = []
empty_dirs = []
def generateZip (self, dir):
zipFile = zipfile.ZipFile (dir, 'w', zipfile.ZIP_DEFLATED)
zipFile.comment = bytes (self.version, encoding = "ascii")
def create_zip (self, dir):
zf = zipfile.ZipFile (dir, "w", zipfile.ZIP_DEFLATED, compresslevel=9)
zf.comment = bytes (self.version, encoding = "ascii")
self.zipDir (self.workDir, zipFile)
zipFile.close ()
self.compress_directory (self.work_dir, zf)
zf.close ()
def convertZipToTXZ (self, zip, txz):
def convert_zip_txz (self, zip, txz):
timeshift = int ((datetime.datetime.now () - datetime.datetime.utcnow ()).total_seconds ())
with zipfile.ZipFile (zip) as zipf:
with tarfile.open (txz, 'w:xz') as tarf:
with tarfile.open (txz, "w:xz") as tarf:
for zif in zipf.infolist ():
tif = tarfile.TarInfo (name = zif.filename)
tif.size = zif.file_size
@ -136,90 +232,66 @@ class BotRelease (object):
os.remove (zip)
def generateWin32 (self):
print ("Generating Win32 ZIP")
def install_binary (self, ext):
lib = "yapb.{}".format (ext)
binary = os.path.join (self.artifacts, lib)
binary = os.path.join ('build_x86_win32', 'yapb.dll')
if os.path.isdir (binary):
binary = os.path.join (binary, lib)
if not os.path.exists (binary):
print ("Packaging failed for {}. Skipping...", lib)
return False
self.unlink_binaries ()
self.copy_binary (binary)
return True
def create_pkg_win32 (self):
print ("Generating Win32 ZIP")
if not self.install_binary ("dll"):
return
self.unlinkBinaries ()
self.copyBinary (binary)
self.generateZip (self.outFileWin32)
self.download (self.win32SetupUrl, "botsetup.exe")
self.create_zip (self.pkg_win32)
self.http_pull (self.pkg_win32_sfx_url, "botsetup.exe")
print ("Generating Win32 EXE")
with open ("botsetup.exe", "rb") as sfx, open (self.outFileWin32, "rb") as zip, open (self.outFileWin32Setup, "wb") as exe:
with open ("botsetup.exe", "rb") as sfx, open (self.pkg_win32, "rb") as zip, open (self.pkg_win32_sfx, "wb") as exe:
exe.write (sfx.read ())
exe.write (zip.read ())
def generateLinux (self):
self.sign_binary (self.pkg_win32_sfx)
def create_pkg_linux (self):
print ("Generating Linux TXZ")
binary = os.path.join ('build_x86_linux', 'yapb.so');
if not os.path.exists (binary):
if not self.install_binary ("so"):
return
self.unlinkBinaries ()
self.copyBinary (binary)
tmp_file = "tmp.zip"
tmpFile = "tmp.zip"
self.create_zip (tmp_file)
self.convert_zip_txz (tmp_file, self.pkg_linux)
self.generateZip (tmpFile)
self.convertZipToTXZ (tmpFile, self.outFileLinux)
def generateMac (self):
def create_pkg_macos (self):
print ("Generating macOS ZIP")
binary = os.path.join ('build_x86_macos', 'yapb.dylib')
if not os.path.exists (binary):
if not self.install_binary ("dylib"):
return
self.unlinkBinaries ()
self.copyBinary (binary)
self.create_zip (self.pkg_macos)
self.generateZip (self.outFileMacOS)
def generate (self):
self.generateWin32 ()
self.generateLinux ()
self.generateMac ()
def createRelease (self, repository, version):
print ("Creating Github Tag")
releases = [self.outFileLinux, self.outFileWin32, self.outFileMacOS, self.outFileWin32Setup]
for release in releases:
if not os.path.exists (release):
return
releaseName = "YaPB " + version
releaseMessage = repository.get_commits()[0].commit.message
releaseSha = repository.get_commits()[0].sha;
ghr = repository.create_git_tag_and_release (tag = version, tag_message = version, release_name = releaseName, release_message = releaseMessage, type='commit', object = releaseSha, draft = False)
print ("Uploading packages to Github")
for release in releases:
ghr.upload_asset( path = release, label = os.path.basename (release))
def uploadGithub (self):
gh = Github (os.environ["GITHUB_TOKEN"])
repo = gh.get_repo ("yapb/yapb")
self.createRelease (repo, self.version)
def create_pkgs (self):
self.create_pkg_linux ()
self.create_pkg_win32 ()
self.create_pkg_macos ()
release = BotRelease ()
release.makeDirs ()
release.getGraphs ()
release.generate ()
release.uploadGithub ()
release.make_directories ()
release.get_default_graphs ()
release.create_pkgs ()

View file

@ -354,7 +354,7 @@ CR_EXPORT int GetEntityAPI (gamefuncs_t *table, int) {
dllapi.pfnServerDeactivate ();
// refill export table
ents.clearExportTable ();
ents.flush ();
};
table->pfnStartFrame = [] () {
@ -500,7 +500,7 @@ CR_LINKAGE_C int GetEngineFunctions (enginefuncs_t *table, int *) {
plat.bzero (table, sizeof (enginefuncs_t));
}
if (ents.isWorkaroundNeeded () && !game.is (GameFlags::Metamod)) {
if (ents.needsBypass () && !game.is (GameFlags::Metamod)) {
table->pfnCreateNamedEntity = [] (int classname) -> edict_t * {
if (ents.isPaused ()) {
@ -987,7 +987,7 @@ DLSYM_RETURN EntityLinkage::lookup (SharedLibrary::Handle module, const char *fu
return reinterpret_cast <DLSYM_RETURN> (m_dlsym (static_cast <DLSYM_HANDLE> (handle), function));
};
if (ents.isWorkaroundNeeded () && !strcmp (function, "CreateInterface")) {
if (ents.needsBypass () && !strcmp (function, "CreateInterface")) {
ents.setPaused (true);
auto ret = resolve (module);
@ -1025,8 +1025,12 @@ void EntityLinkage::initialize () {
}
m_dlsym.initialize ("kernel32.dll", "GetProcAddress", DLSYM_FUNCTION);
m_dlsym.install (reinterpret_cast <void *> (EntityLinkage::replacement), true);
m_dlsym.install (reinterpret_cast <void *> (EntityLinkage::lookupHandler), true);
if (needsBypass ()) {
m_dlclose.initialize ("kernel32.dll", "FreeLibrary", DLCLOSE_FUNCTION);
m_dlclose.install (reinterpret_cast <void *> (EntityLinkage::closeHandler), true);
}
m_self.locate (&engfuncs);
}

View file

@ -1,10 +1,6 @@
YAPB_ABI_1.0 {
global:
Meta_*;
GiveFnptrsToDll;
GetBotAPI;
GetEntityAPI;
GetNewDLLFunctions;
*;
local:
*;
};