From bad8c99a0b473ac28f2e289d6d0fe998f11c2c5d Mon Sep 17 00:00:00 2001 From: Asher Baker Date: Thu, 16 May 2013 07:18:31 +0100 Subject: [PATCH] Initial commit. --- .hgignore | 24 ++ AMBuildScript | 424 ++++++++++++++++++++++++++++++ buildbot/BreakpadSymbols | 41 +++ buildbot/PackageScript | 107 ++++++++ buildbot/Versioning | 55 ++++ buildbot/pushbuild.txt | 1 + configure.py | 10 + extension/AMBuilder | 44 ++++ extension/MemoryDownloader.cpp | 85 ++++++ extension/MemoryDownloader.h | 62 +++++ extension/extension.cpp | 182 +++++++++++++ extension/extension.h | 104 ++++++++ extension/sdk/smsdk_config.hpp | 80 ++++++ extension/sdk/smsdk_ext.cpp | 465 +++++++++++++++++++++++++++++++++ extension/sdk/smsdk_ext.hpp | 339 ++++++++++++++++++++++++ extension/version.h | 27 ++ extension/version.rc | 45 ++++ extension/version_auto.h | 12 + product.version | 1 + upload.py | 71 +++++ 20 files changed, 2179 insertions(+) create mode 100644 .hgignore create mode 100644 AMBuildScript create mode 100644 buildbot/BreakpadSymbols create mode 100644 buildbot/PackageScript create mode 100644 buildbot/Versioning create mode 100644 buildbot/pushbuild.txt create mode 100644 configure.py create mode 100644 extension/AMBuilder create mode 100644 extension/MemoryDownloader.cpp create mode 100644 extension/MemoryDownloader.h create mode 100644 extension/extension.cpp create mode 100644 extension/extension.h create mode 100644 extension/sdk/smsdk_config.hpp create mode 100644 extension/sdk/smsdk_ext.cpp create mode 100644 extension/sdk/smsdk_ext.hpp create mode 100644 extension/version.h create mode 100644 extension/version.rc create mode 100644 extension/version_auto.h create mode 100644 product.version create mode 100644 upload.py diff --git a/.hgignore b/.hgignore new file mode 100644 index 0000000..9af9aca --- /dev/null +++ b/.hgignore @@ -0,0 +1,24 @@ +syntax: glob +build +google-breakpad/android +google-breakpad/codereview.settings +google-breakpad/README.ANDROID +google-breakpad/src/client/apple +google-breakpad/src/client/ios +google-breakpad/src/client/mac +google-breakpad/src/client/solaris +google-breakpad/src/client/windows +google-breakpad/src/common/android +google-breakpad/src/common/mac +google-breakpad/src/common/solaris +google-breakpad/src/common/testdata +google-breakpad/src/common/tests +google-breakpad/src/common/windows +google-breakpad/src/processor +google-breakpad/src/testing +google-breakpad/src/third_party/curl +google-breakpad/src/third_party/glog +google-breakpad/src/third_party/libdisasm +google-breakpad/src/third_party/linux +google-breakpad/src/third_party/protobuf +google-breakpad/src/tools diff --git a/AMBuildScript b/AMBuildScript new file mode 100644 index 0000000..cb222e7 --- /dev/null +++ b/AMBuildScript @@ -0,0 +1,424 @@ +# vim: set ts=2 sw=2 tw=99 noet ft=python: +import os +import sys +from ambuild.command import Command +from ambuild.command import ShellCommand +from ambuild.command import SymlinkCommand + +class ExtractDebugInfoCommand(Command): + def __init__(self, binary, outfile): + Command.__init__(self) + self.binary = binary + self.outfile = outfile + + def run(self, runner, job): + if not self.binary.NeedsRelink(self.outfile): + return + + if AMBuild.target['platform'] == 'linux': + job.AddCommand(ShellCommand('objcopy --only-keep-debug ' + self.outfile + ' ' + self.outfile + '.dbg')) + job.AddCommand(ShellCommand('objcopy --strip-debug ' + self.outfile)) + job.AddCommand(ShellCommand('objcopy --add-gnu-debuglink=' + os.path.basename(self.outfile) + '.dbg ' + self.outfile)) + elif AMBuild.target['platform'] == 'darwin': + job.AddCommand(ShellCommand('dsymutil ' + self.outfile)) + job.AddCommand(ShellCommand('strip -S ' + self.outfile)) + +class SM: + def __init__(self): + self.compiler = Cpp.Compiler() + + #Build SDK info + self.possibleSdks = { } + self.possibleSdks['ep1'] = {'sdk': 'HL2SDK', 'ext': '1.ep1', 'def': '1', + 'name': 'EPISODEONE', 'platform': []} + self.possibleSdks['ep2'] = {'sdk': 'HL2SDKOB', 'ext': '2.ep2', 'def': '3', + 'name': 'ORANGEBOX', 'platform': []} + self.possibleSdks['css'] = {'sdk': 'HL2SDKCSS', 'ext': '2.css', 'def': '6', + 'name': 'CSS', 'platform': []} + self.possibleSdks['ep2v'] = {'sdk': 'HL2SDKOBVALVE', 'ext': '2.ep2v', 'def': '7', + 'name': 'ORANGEBOXVALVE', 'platform': ['linux']} + self.possibleSdks['l4d'] = {'sdk': 'HL2SDKL4D', 'ext': '2.l4d', 'def': '8', + 'name': 'LEFT4DEAD', 'platform': []} + self.possibleSdks['l4d2'] = {'sdk': 'HL2SDKL4D2', 'ext': '2.l4d2', 'def': '9', + 'name': 'LEFT4DEAD2', 'platform': []} + self.possibleSdks['darkm'] = {'sdk': 'HL2SDK-DARKM', 'ext': '2.darkm', 'def': '2', + 'name': 'DARKMESSIAH', 'platform': []} + self.possibleSdks['swarm'] = {'sdk': 'HL2SDK-SWARM', 'ext': '2.swarm', 'def': '10', + 'name': 'ALIENSWARM', 'platform': []} + self.possibleSdks['bgt'] = {'sdk': 'HL2SDK-BGT', 'ext': '2.bgt', 'def': '4', + 'name': 'BLOODYGOODTIME', 'platform': []} + self.possibleSdks['eye'] = {'sdk': 'HL2SDK-EYE', 'ext': '2.eye', 'def': '5', + 'name': 'EYE', 'platform': []} + self.possibleSdks['csgo'] = {'sdk': 'HL2SDKCSGO', 'ext': '2.csgo', 'def': '12', + 'name': 'CSGO', 'platform': []} + + self.sdkInfo = { } + + if AMBuild.mode == 'config': + #Detect compilers + self.compiler.DetectAll(AMBuild) + + #Detect variables + envvars = { 'MMSOURCE19': 'mmsource-1.9', + 'SOURCEMOD15': 'sourcemod-central', + 'BREAKPAD': 'google-breakpad', + 'HL2SDKCSS': 'hl2sdk-css', + 'HL2SDKOBVALVE': 'hl2sdk-ob-valve', + 'HL2SDKL4D': 'hl2sdk-l4d', + 'HL2SDKL4D2': 'hl2sdk-l4d2', + 'HL2SDKCSGO': 'hl2sdk-csgo' + } + + if AMBuild.target['platform'] != 'darwin': + envvars['HL2SDK'] = 'hl2sdk' + envvars['HL2SDKOB'] = 'hl2sdk-ob' + + if AMBuild.target['platform'] == 'windows': + envvars['HL2SDK-DARKM'] = 'hl2sdk-darkm' + envvars['HL2SDK-SWARM'] = 'hl2sdk-swarm' + envvars['HL2SDK-BGT'] = 'hl2sdk-bgt' + envvars['HL2SDK-EYE'] = 'hl2sdk-eye' + + # Finds if a dict with `key` set to `value` is present on the dict of dicts `dictionary` + def findDictByKey(dictionary, key, value): + for index in dictionary: + elem = dictionary[index] + if elem[key] == value: + return (elem, index) + return None + + for i in envvars: + if i in os.environ: + path = os.environ[i] + if not os.path.isdir(path): + raise Exception('Path for {0} was not found: {1}'.format(i, path)) + elif i.startswith('HL2SDK'): + (info, sdk) = findDictByKey(self.possibleSdks, 'sdk', i) + self.sdkInfo[sdk] = info + else: + head = os.getcwd() + oldhead = None + while head != None and head != oldhead: + path = os.path.join(head, envvars[i]) + if os.path.isdir(path): + break + oldhead = head + head, tail = os.path.split(head) + if i.startswith('HL2SDK'): + if head != None and head != oldhead: + (info, sdk) = findDictByKey(self.possibleSdks, 'sdk', i) + self.sdkInfo[sdk] = info + elif head == None or head == oldhead: + raise Exception('Could not find a valid path for {0}'.format(i)) + AMBuild.cache.CacheVariable(i, path) + + if len(self.sdkInfo) < 1: + raise Exception('At least one SDK must be available.') + + AMBuild.cache.CacheVariable('sdkInfo', self.sdkInfo) + + #Set up defines + cxx = self.compiler.cxx + if isinstance(cxx, Cpp.CompatGCC): + if isinstance(cxx, Cpp.GCC): + self.vendor = 'gcc' + elif isinstance(cxx, Cpp.Clang): + self.vendor = 'clang' + self.compiler.AddToListVar('CDEFINES', 'stricmp=strcasecmp') + self.compiler.AddToListVar('CDEFINES', '_stricmp=strcasecmp') + self.compiler.AddToListVar('CDEFINES', '_snprintf=snprintf') + self.compiler.AddToListVar('CDEFINES', '_vsnprintf=vsnprintf') + self.compiler.AddToListVar('CFLAGS', '-pipe') + self.compiler.AddToListVar('CFLAGS', '-fno-strict-aliasing') + if (self.vendor == 'gcc' and cxx.majorVersion >= 4) or self.vendor == 'clang': + self.compiler.AddToListVar('CFLAGS', '-fvisibility=hidden') + self.compiler.AddToListVar('CXXFLAGS', '-fvisibility-inlines-hidden') + self.compiler.AddToListVar('CFLAGS', '-Wall') + self.compiler.AddToListVar('CFLAGS', '-Werror') + self.compiler.AddToListVar('CFLAGS', '-Wno-uninitialized') + self.compiler.AddToListVar('CFLAGS', '-Wno-unused') + self.compiler.AddToListVar('CFLAGS', '-Wno-switch') + self.compiler.AddToListVar('CFLAGS', '-msse') + self.compiler.AddToListVar('CFLAGS', '-g3') + self.compiler.AddToListVar('CFLAGS', '-m32') + self.compiler.AddToListVar('POSTLINKFLAGS', '-m32') + self.compiler.AddToListVar('CXXFLAGS', '-fno-exceptions') + self.compiler.AddToListVar('CXXFLAGS', '-fno-threadsafe-statics') + self.compiler.AddToListVar('CXXFLAGS', '-Wno-non-virtual-dtor') + self.compiler.AddToListVar('CXXFLAGS', '-Wno-overloaded-virtual') + if (self.vendor == 'gcc' and cxx.majorVersion >= 4 and cxx.minorVersion >= 3) or \ + (self.vendor == 'clang' and cxx.majorVersion >= 3): + self.compiler.AddToListVar('CXXFLAGS', '-Wno-delete-non-virtual-dtor') + self.compiler.AddToListVar('CDEFINES', 'HAVE_STDINT_H') + self.compiler.AddToListVar('CDEFINES', 'GNUC') + if self.vendor == 'gcc': + self.compiler.AddToListVar('CFLAGS', '-mfpmath=sse') + elif isinstance(cxx, Cpp.MSVC): + self.vendor = 'msvc' + if AMBuild.options.debug == '1': + self.compiler.AddToListVar('CFLAGS', '/MTd') + self.compiler.AddToListVar('POSTLINKFLAGS', '/NODEFAULTLIB:libcmt') + else: + self.compiler.AddToListVar('CFLAGS', '/MT') + self.compiler.AddToListVar('CDEFINES', '_CRT_SECURE_NO_DEPRECATE') + self.compiler.AddToListVar('CDEFINES', '_CRT_SECURE_NO_WARNINGS') + self.compiler.AddToListVar('CDEFINES', '_CRT_NONSTDC_NO_DEPRECATE') + self.compiler.AddToListVar('CXXFLAGS', '/EHsc') + self.compiler.AddToListVar('CFLAGS', '/W3') + self.compiler.AddToListVar('CFLAGS', '/nologo') + self.compiler.AddToListVar('CFLAGS', '/Zi') + self.compiler.AddToListVar('CXXFLAGS', '/TP') + self.compiler.AddToListVar('POSTLINKFLAGS', '/DEBUG') + self.compiler.AddToListVar('POSTLINKFLAGS', '/MACHINE:X86') + self.compiler.AddToListVar('POSTLINKFLAGS', '/SUBSYSTEM:WINDOWS') + self.compiler.AddToListVar('POSTLINKFLAGS', 'kernel32.lib') + self.compiler.AddToListVar('POSTLINKFLAGS', 'user32.lib') + self.compiler.AddToListVar('POSTLINKFLAGS', 'gdi32.lib') + self.compiler.AddToListVar('POSTLINKFLAGS', 'winspool.lib') + self.compiler.AddToListVar('POSTLINKFLAGS', 'comdlg32.lib') + self.compiler.AddToListVar('POSTLINKFLAGS', 'advapi32.lib') + self.compiler.AddToListVar('POSTLINKFLAGS', 'shell32.lib') + self.compiler.AddToListVar('POSTLINKFLAGS', 'ole32.lib') + self.compiler.AddToListVar('POSTLINKFLAGS', 'oleaut32.lib') + self.compiler.AddToListVar('POSTLINKFLAGS', 'uuid.lib') + self.compiler.AddToListVar('POSTLINKFLAGS', 'odbc32.lib') + self.compiler.AddToListVar('POSTLINKFLAGS', 'odbccp32.lib') + + #Optimization + if AMBuild.options.opt == '1': + self.compiler.AddToListVar('CDEFINES', 'NDEBUG') + if self.vendor == 'gcc' or self.vendor == 'clang': + self.compiler.AddToListVar('CFLAGS', '-O3') + elif self.vendor == 'msvc': + self.compiler.AddToListVar('CFLAGS', '/Ox') + self.compiler.AddToListVar('POSTLINKFLAGS', '/OPT:ICF') + self.compiler.AddToListVar('POSTLINKFLAGS', '/OPT:REF') + + #Debugging + if AMBuild.options.debug == '1': + self.compiler.AddToListVar('CDEFINES', 'DEBUG') + self.compiler.AddToListVar('CDEFINES', '_DEBUG') + if self.vendor == 'msvc': + self.compiler.AddToListVar('CFLAGS', '/Od') + self.compiler.AddToListVar('CFLAGS', '/RTC1') + + #Platform-specifics + if AMBuild.target['platform'] == 'linux': + self.compiler.AddToListVar('CDEFINES', '_LINUX') + if self.vendor == 'gcc': + self.compiler.AddToListVar('POSTLINKFLAGS', '-static-libgcc') + if self.vendor == 'clang': + self.compiler.AddToListVar('POSTLINKFLAGS', '-lgcc_eh') + elif AMBuild.target['platform'] == 'darwin': + self.compiler.AddToListVar('CDEFINES', 'OSX') + self.compiler.AddToListVar('CDEFINES', '_OSX') + self.compiler.AddToListVar('POSTLINKFLAGS', '-mmacosx-version-min=10.5') + self.compiler.AddToListVar('POSTLINKFLAGS', ['-arch', 'i386']) + self.compiler.AddToListVar('POSTLINKFLAGS', '-lstdc++') + + # For OS X dylib versioning + import re + productFile = open(os.path.join(AMBuild.sourceFolder, 'product.version'), 'r') + productContents = productFile.read() + productFile.close() + m = re.match('(\d+)\.(\d+)\.(\d+).*', productContents) + if m == None: + self.version = '1.0.0' + else: + major, minor, release = m.groups() + self.version = '{0}.{1}.{2}'.format(major, minor, release) + AMBuild.cache.CacheVariable('version', self.version) + elif AMBuild.target['platform'] == 'windows': + self.compiler.AddToListVar('CDEFINES', 'WIN32') + self.compiler.AddToListVar('CDEFINES', '_WINDOWS') + + #Finish up + self.compiler.AddToListVar('CDEFINES', 'SOURCEMOD_BUILD') + self.compiler.AddToListVar('CDEFINES', 'SM_GENERATED_BUILD') + self.compiler.AddToListVar('CINCLUDES', + os.path.join(AMBuild.outputFolder, 'includes')) + self.compiler.ToConfig(AMBuild, 'compiler') + AMBuild.cache.CacheVariable('vendor', self.vendor) + self.targetMap = { } + AMBuild.cache.CacheVariable('targetMap', self.targetMap) + else: + self.sdkInfo = AMBuild.cache['sdkInfo'] + self.compiler.FromConfig(AMBuild, 'compiler') + self.targetMap = AMBuild.cache['targetMap'] + + if AMBuild.target['platform'] == 'windows': + self.compiler.AddToListVar('RCINCLUDES', os.path.join(AMBuild.sourceFolder, 'extension')) + self.mmsPath = AMBuild.cache['MMSOURCE19'] + + def DefaultCompiler(self): + return self.compiler.Clone() + + def JobMatters(self, jobname): + file = sys._getframe().f_code.co_filename + if AMBuild.mode == 'config': + self.targetMap[jobname] = file + return True + if len(AMBuild.args) == 0: + return True + if not jobname in AMBuild.args: + return False + + def AutoVersion(self, folder, binary): + if AMBuild.target['platform'] == 'windows': + env = {'RCDEFINES': ['BINARY_NAME="' + binary.binaryFile + '"', 'SM_GENERATED_BUILD']} + binary.AddResourceFile(os.path.join(folder, 'version.rc' ), env) + elif AMBuild.target['platform'] == 'darwin' and isinstance(binary, Cpp.LibraryBuilder): + binary.compiler['POSTLINKFLAGS'].extend(['-compatibility_version', '1.0.0']) + binary.compiler['POSTLINKFLAGS'].extend(['-current_version', AMBuild.cache['version']]) + else: + return + + def ExtractDebugInfo(self, job, binary): + src = os.path.join('..', AMBuild.outputFolder, job.workFolder, binary.binaryFile) + job.AddCommand(ExtractDebugInfoCommand(binary, src)) + + def PreSetupHL2Job(self, job, builder, sdk): + info = self.sdkInfo[sdk] + sdkPath = AMBuild.cache[info['sdk']] + if AMBuild.target['platform'] == 'linux': + if sdk == 'ep1': + staticLibs = os.path.join(sdkPath, 'linux_sdk') + else: + staticLibs = os.path.join(sdkPath, 'lib', 'linux') + workFolder = os.path.join(AMBuild.outputFolder, job.workFolder) + if sdk in ['ep2v', 'css']: + libs = ['tier1_i486.a', 'mathlib_i486.a', 'libvstdlib_srv.so', 'libtier0_srv.so'] + for lib in libs: + link = os.path.join(workFolder, lib) + target = os.path.join(staticLibs, lib) + try: + os.lstat(link) + except: + job.AddCommand(SymlinkCommand(link, target)) + elif sdk in ['l4d', 'l4d2', 'csgo']: + libs = ['tier1_i486.a', 'mathlib_i486.a', 'libvstdlib.so', 'libtier0.so'] + if sdk == 'csgo': + libs.append('interfaces_i486.a') + for lib in libs: + link = os.path.join(workFolder, lib) + target = os.path.join(staticLibs, lib) + try: + os.lstat(link) + except: + job.AddCommand(SymlinkCommand(link, target)) + else: + libs = ['tier1_i486.a', 'mathlib_i486.a', 'vstdlib_i486.so', 'tier0_i486.so'] + for lib in libs: + link = os.path.join(workFolder, lib) + target = os.path.join(staticLibs, lib) + try: + os.lstat(link) + except: + job.AddCommand(SymlinkCommand(link, target)) + elif AMBuild.target['platform'] == 'darwin': + staticLibs = os.path.join(sdkPath, 'lib', 'mac') + workFolder = os.path.join(AMBuild.outputFolder, job.workFolder) + libs = ['tier1_i486.a', 'mathlib_i486.a', 'libvstdlib.dylib', 'libtier0.dylib'] + if sdk == 'csgo': + libs.append('interfaces_i486.a') + for lib in libs: + link = os.path.join(workFolder, lib) + target = os.path.join(staticLibs, lib) + try: + os.lstat(link) + except: + job.AddCommand(SymlinkCommand(link, target)) + elif AMBuild.target['platform'] == 'windows': + libs = ['tier0', 'tier1', 'vstdlib', 'mathlib'] + if sdk in ['swarm', 'csgo']: + libs.append('interfaces') + for lib in libs: + libPath = os.path.join(sdkPath, 'lib', 'public', lib) + '.lib' + builder.RebuildIfNewer(libPath) + builder['POSTLINKFLAGS'].append(libPath) + + def PostSetupHL2Job(self, job, builder, sdk): + if AMBuild.target['platform'] in ['linux', 'darwin']: + builder.AddObjectFiles(['tier1_i486.a', 'mathlib_i486.a']) + if sdk == 'csgo': + builder.AddObjectFiles(['interfaces_i486.a']) + + def DefaultHL2Compiler(self, path, sdk, noLink = False, oldMms = '-legacy'): + compiler = self.DefaultCompiler() + + mms = 'core' + if sdk == 'ep1': + mms += oldMms + + compiler['CXXINCLUDES'].append(os.path.join(self.mmsPath, mms)) + compiler['CXXINCLUDES'].append(os.path.join(self.mmsPath, mms, 'sourcehook')) + + info = self.possibleSdks + compiler['CDEFINES'].extend(['SE_' + info[i]['name'] + '=' + info[i]['def'] for i in info]) + + paths = [['public'], ['public', 'engine'], ['public', 'mathlib'], ['public', 'vstdlib'], ['public', 'tier0'], ['public', 'tier1']] + if sdk == 'ep1' or sdk == 'darkm': + paths.append(['public', 'dlls']) + paths.append(['game_shared']) + else: + paths.append(['public', 'game', 'server']) + paths.append(['public', 'toolframework']) + paths.append(['game', 'shared']) + paths.append(['common']) + + info = self.sdkInfo[sdk] + sdkPath = AMBuild.cache[info['sdk']] + + compiler['CDEFINES'].append('SOURCE_ENGINE=' + info['def']) + + if sdk in ['swarm','csgo']: + if AMBuild.target['platform'] == 'windows': + compiler['CDEFINES'].extend(['COMPILER_MSVC', 'COMPILER_MSVC32']) + else: + compiler['CDEFINES'].extend(['COMPILER_GCC', 'POSIX']) + + if sdk == 'ep1': + if AMBuild.target['platform'] == 'linux': + staticLibs = os.path.join(sdkPath, 'linux_sdk') + else: + if AMBuild.target['platform'] == 'linux': + staticLibs = os.path.join(sdkPath, 'lib', 'linux') + elif AMBuild.target['platform'] == 'darwin': + staticLibs = os.path.join(sdkPath, 'lib', 'mac') + + for i in paths: + compiler['CXXINCLUDES'].append(os.path.join(sdkPath, *i)) + + if not noLink: + if AMBuild.target['platform'] == 'linux': + compiler['POSTLINKFLAGS'][0:0] = ['-lm'] + if sdk in ['ep2v', 'css']: + compiler['POSTLINKFLAGS'][0:0] = ['libtier0_srv.so'] + compiler['POSTLINKFLAGS'][0:0] = ['libvstdlib_srv.so'] + elif sdk in ['l4d', 'l4d2', 'csgo']: + compiler['POSTLINKFLAGS'][0:0] = ['libtier0.so'] + compiler['POSTLINKFLAGS'][0:0] = ['libvstdlib.so'] + else: + compiler['POSTLINKFLAGS'][0:0] = ['tier0_i486.so'] + compiler['POSTLINKFLAGS'][0:0] = ['vstdlib_i486.so'] + elif AMBuild.target['platform'] == 'darwin': + compiler['POSTLINKFLAGS'][0:0] = ['libtier0.dylib'] + compiler['POSTLINKFLAGS'][0:0] = ['libvstdlib.dylib'] + + return compiler + +sm = SM() +globals = { + 'SM': sm +} + +AMBuild.Include(os.path.join('buildbot', 'Versioning'), globals) + +FileList = [ + ['extension', 'AMBuilder'], + ['buildbot', 'PackageScript'], + ['buildbot', 'BreakpadSymbols'] + ] + +for parts in FileList: + AMBuild.Include(os.path.join(*parts), globals) diff --git a/buildbot/BreakpadSymbols b/buildbot/BreakpadSymbols new file mode 100644 index 0000000..7d40e8e --- /dev/null +++ b/buildbot/BreakpadSymbols @@ -0,0 +1,41 @@ +# vim: set ts=2 sw=2 tw=99 noet ft=python: +import os +import urllib.request +from ambuild.command import Command +from ambuild.command import ShellCommand + +class IterateDebugInfoCommand(Command): + def run(self, master, job): + pdblog = open(os.path.join(AMBuild.outputFolder, 'pdblog.txt'), 'rt') + for debug_info in pdblog: + debug_info = os.path.join(AMBuild.outputFolder, debug_info.strip()) + job.AddCommand(SymbolCommand(debug_info, symbolServer)) + pdblog.close() + +class SymbolCommand(ShellCommand): + def __init__(self, debugFile, symbolServer): + self.serverResponse = None + self.symbolServer = symbolServer + if AMBuild.target['platform'] == 'linux': + cmdstring = "dump_syms {0} {1}".format(debugFile, os.path.dirname(debugFile)) + elif AMBuild.target['platform'] == 'darwin': + cmdstring = "dump_syms {0}".format(debugFile) + elif AMBuild.target['platform'] == 'windows': + cmdstring = "dump_syms.exe {0}".format(debugFile) + ShellCommand.__init__(self, cmdstring) + def run(self, master, job): + ShellCommand.run(self, master, job) + if self.stdout != None and len(self.stdout) > 0: + request = urllib.request.Request(symbolServer, self.stdout.encode('utf-8')) + request.add_header("Content-Type", "text/plain") + self.serverResponse = urllib.request.urlopen(request).read().decode('utf-8') + def spew(self, runner): + if self.stderr != None and len(self.stderr) > 0: + runner.PrintOut(self.stderr) + if self.serverResponse != None and len(self.serverResponse) > 0: + runner.PrintOut(self.serverResponse) + +if 'BREAKPAD_SYMBOL_SERVER' in os.environ: + symbolServer = os.environ['BREAKPAD_SYMBOL_SERVER'] + job = AMBuild.AddJob('breakpad-symbols') + job.AddCommand(IterateDebugInfoCommand()) diff --git a/buildbot/PackageScript b/buildbot/PackageScript new file mode 100644 index 0000000..60263b4 --- /dev/null +++ b/buildbot/PackageScript @@ -0,0 +1,107 @@ +# 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 + +job = AMBuild.AddJob('package') + +class DestroyPath(Command): + def __init__(self, folder): + Command.__init__(self) + self.folder = folder + + def destroy(self, path): + entries = os.listdir(path) + for entry in entries: + newpath = os.path.join(path, entry) + if os.path.isdir(newpath): + self.destroy(newpath) + os.rmdir(newpath) + elif os.path.isfile(newpath): + os.remove(newpath) + + def run(self, runner, job): + runner.PrintOut('rm -rf {0}/*'.format(self.folder)) + self.destroy(self.folder) + +class CreateFolders(Command): + def __init__(self, folders): + Command.__init__(self) + self.folders = folders + + def run(self, runner, job): + for folder in self.folders: + path = os.path.join(*folder) + runner.PrintOut('mkdir {0}'.format(path)) + os.makedirs(path) + +#Shallow folder copy +class CopyFolder(Command): + def __init__(self, fromList, toList, excludes = []): + Command.__init__(self) + self.fromPath = os.path.join(AMBuild.sourceFolder, *fromList) + self.toPath = os.path.join(*toList) + self.excludes = excludes + + def run(self, runner, job): + entries = os.listdir(self.fromPath) + for entry in entries: + if entry in self.excludes: + continue + path = os.path.join(self.fromPath, entry) + if not os.path.isfile(path): + continue + runner.PrintOut('copy {0} to {1}'.format(path, self.toPath)) + shutil.copy(path, self.toPath) + +#Single file copy +class CopyFile(Command): + def __init__(self, fromFile, toPath): + Command.__init__(self) + self.fromFile = fromFile + self.toPath = toPath + + def run(self, runner, job): + runner.PrintOut('copy {0} to {1}'.format(self.fromFile, self.toPath)) + shutil.copy(self.fromFile, self.toPath) + + +folders = [['addons', 'sourcemod', 'extensions']] + +#Setup +job.AddCommand(DestroyPath(os.path.join(AMBuild.outputFolder, 'package'))) +job.AddCommand(CreateFolders(folders)) + +bincopies = [] + +def AddNormalLibrary(name, dest): + dest = os.path.join('addons', 'sourcemod', dest) + bincopies.append(CopyFile(os.path.join('..', name, name + osutil.SharedLibSuffix()), dest)) + + # Each platform's version of dump_syms needs the path in a different format. + if AMBuild.target['platform'] == 'linux': + debug_info.append(name + '/' + name + '.so') + elif AMBuild.target['platform'] == 'darwin': + debug_info.append(name + '/' + name + '.dylib.dSYM') + elif AMBuild.target['platform'] == 'windows': + debug_info.append(name + '\\' + name + '.pdb') + +def AddHL2Library(name, dest): + for i in SM.sdkInfo: + sdk = SM.sdkInfo[i] + if AMBuild.target['platform'] not in sdk['platform']: + continue + AddNormalLibrary(name + '.ext.' + sdk['ext'], dest) + +debug_info = [] + +AddHL2Library('accelerator', 'extensions') + +job.AddCommandGroup(bincopies) + +pdblog = open(os.path.join(AMBuild.outputFolder, 'pdblog.txt'), 'wt') +for pdb in debug_info: + pdblog.write(pdb + '\n') +pdblog.close() + diff --git a/buildbot/Versioning b/buildbot/Versioning new file mode 100644 index 0000000..c5c731b --- /dev/null +++ b/buildbot/Versioning @@ -0,0 +1,55 @@ +# vim: set ts=2 sw=2 tw=99 noet ft=python: +import os +import re +import subprocess +from ambuild.cache import Cache +import ambuild.command as command + +#Quickly try to ascertain the current repository revision +def GetVersion(): + args = ['hg', 'parent', '-R', AMBuild.sourceFolder] + p = command.RunDirectCommand(AMBuild, args) + m = re.match('changeset:\s+(\d+):(.+)', p.stdoutText) + if m == None: + raise Exception('Could not determine repository version') + return m.groups() + +def PerformReversioning(): + rev, cset = GetVersion() + cacheFile = os.path.join(AMBuild.outputFolder, '.ambuild', 'hgcache') + cache = Cache(cacheFile) + if os.path.isfile(cacheFile): + cache.LoadCache() + if cache.HasVariable('cset') and cache['cset'] == cset: + return False + cache.CacheVariable('cset', cset) + + productFile = open(os.path.join(AMBuild.sourceFolder, 'product.version'), 'r') + productContents = productFile.read() + productFile.close() + m = re.match('(\d+)\.(\d+)\.(\d+)(.*)', productContents) + if m == None: + raise Exception('Could not detremine product version') + major, minor, release, tag = m.groups() + + incFolder = os.path.join(AMBuild.sourceFolder, 'extension') + incFile = open(os.path.join(incFolder, 'version_auto.h'), 'w') + incFile.write(""" +#ifndef _AUTO_VERSION_INFORMATION_H_ +#define _AUTO_VERSION_INFORMATION_H_ + +#define SM_BUILD_TAG \"{0}\" +#define SM_BUILD_UNIQUEID \"{1}:{2}\" SM_BUILD_TAG +#define SM_VERSION \"{3}.{4}.{5}\" +#define SM_FULL_VERSION SM_VERSION SM_BUILD_TAG +#define SM_FILE_VERSION {6},{7},{8},0 + +#endif /* _AUTO_VERSION_INFORMATION_H_ */ + +""".format(tag, rev, cset, major, minor, release, major, minor, release)) + incFile.close() + cache.WriteCache() + +PerformReversioning() + + diff --git a/buildbot/pushbuild.txt b/buildbot/pushbuild.txt new file mode 100644 index 0000000..87e1ac9 --- /dev/null +++ b/buildbot/pushbuild.txt @@ -0,0 +1 @@ +Lemons. diff --git a/configure.py b/configure.py new file mode 100644 index 0000000..f0f2aa0 --- /dev/null +++ b/configure.py @@ -0,0 +1,10 @@ +# vim: set ts=2 sw=2 tw=99 noet: +import sys +import ambuild.runner as runner + +run = runner.Runner() +run.options.add_option('--enable-debug', action='store_const', const='1', dest='debug', + help='Enable debugging symbols') +run.options.add_option('--enable-optimize', action='store_const', const='1', dest='opt', + help='Enable optimization') +run.Configure(sys.path[0]) diff --git a/extension/AMBuilder b/extension/AMBuilder new file mode 100644 index 0000000..f3c2969 --- /dev/null +++ b/extension/AMBuilder @@ -0,0 +1,44 @@ +# vim: set ts=2 sw=2 tw=99 noet ft=python: +import os +from ambuild.command import SymlinkCommand + +for i in SM.sdkInfo: + sdk = SM.sdkInfo[i] + if AMBuild.target['platform'] not in sdk['platform']: + continue + + compiler = SM.DefaultHL2Compiler('extension', i) + + compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, 'extension')) + compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, 'extension', 'sdk')) + + compiler['CXXINCLUDES'].append(os.path.join(AMBuild.cache['SOURCEMOD15'], 'public')) + compiler['CXXINCLUDES'].append(os.path.join(AMBuild.cache['SOURCEMOD15'], 'public', 'extensions')) + compiler['CXXINCLUDES'].append(os.path.join(AMBuild.cache['SOURCEMOD15'], 'public', 'sourcepawn')) + + compiler['CXXINCLUDES'].append(os.path.join(AMBuild.cache['BREAKPAD'], 'src')) + + name = 'accelerator.ext.' + sdk['ext'] + extension = AMBuild.AddJob(name) + binary = Cpp.LibraryBuilder(name, AMBuild, extension, compiler) + SM.PreSetupHL2Job(extension, binary, i) + binary.AddSourceFiles('extension', [ + 'extension.cpp', + 'MemoryDownloader.cpp', + 'sdk/smsdk_ext.cpp' + ]) + SM.PostSetupHL2Job(extension, binary, i) + + link = os.path.join(AMBuild.outputFolder, extension.workFolder, 'libbreakpad_client.a') + target = os.path.join(AMBuild.cache['BREAKPAD'], 'src', 'client', 'linux', 'libbreakpad_client.a') + try: + os.lstat(link) + except: + extension.AddCommand(SymlinkCommand(link, target)) + + binary.AddObjectFiles(['libbreakpad_client.a']) + + SM.AutoVersion('extension', binary) + SM.ExtractDebugInfo(extension, binary) + binary.SendToJob() + diff --git a/extension/MemoryDownloader.cpp b/extension/MemoryDownloader.cpp new file mode 100644 index 0000000..af5b470 --- /dev/null +++ b/extension/MemoryDownloader.cpp @@ -0,0 +1,85 @@ +/** + * vim: set ts=4 : + * ============================================================================= + * SourceMod Updater Extension + * Copyright (C) 2004-2009 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$ + */ + +#include +#include +#include +#include "MemoryDownloader.h" + +using namespace SourceMod; + +MemoryDownloader::MemoryDownloader() : buffer(NULL), bufsize(0), bufpos(0) +{ +} + +MemoryDownloader::~MemoryDownloader() +{ + free(buffer); +} + +DownloadWriteStatus MemoryDownloader::OnDownloadWrite(IWebTransfer *session, + void *userdata, + void *ptr, + size_t size, + size_t nmemb) +{ + size_t total = size * nmemb; + + if (bufpos + total > bufsize) + { + size_t rem = (bufpos + total) - bufsize; + bufsize += rem + (rem / 2); + buffer = (char *)realloc(buffer, bufsize); + } + + assert(bufpos + total <= bufsize); + + memcpy(&buffer[bufpos], ptr, total); + bufpos += total; + + return DownloadWrite_Okay; +} + +void MemoryDownloader::Reset() +{ + bufpos = 0; +} + +char *MemoryDownloader::GetBuffer() +{ + return buffer; +} + +size_t MemoryDownloader::GetSize() +{ + return bufpos; +} + diff --git a/extension/MemoryDownloader.h b/extension/MemoryDownloader.h new file mode 100644 index 0000000..7ac64e0 --- /dev/null +++ b/extension/MemoryDownloader.h @@ -0,0 +1,62 @@ +/** + * vim: set ts=4 : + * ============================================================================= + * SourceMod Updater Extension + * Copyright (C) 2004-2009 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$ + */ + +#ifndef _INCLUDE_SOURCEMOD_UPDATER_MEMORY_DOWNLOADER_H_ +#define _INCLUDE_SOURCEMOD_UPDATER_MEMORY_DOWNLOADER_H_ + +#include + +namespace SourceMod +{ + class MemoryDownloader : public ITransferHandler + { + public: + MemoryDownloader(); + ~MemoryDownloader(); + public: + DownloadWriteStatus OnDownloadWrite(IWebTransfer *session, + void *userdata, + void *ptr, + size_t size, + size_t nmemb); + public: + void Reset(); + char *GetBuffer(); + size_t GetSize(); + private: + char *buffer; + size_t bufsize; + size_t bufpos; + }; +} + +#endif /* _INCLUDE_SOURCEMOD_UPDATER_MEMORY_DOWNLOADER_H_ */ + diff --git a/extension/extension.cpp b/extension/extension.cpp new file mode 100644 index 0000000..b086d6d --- /dev/null +++ b/extension/extension.cpp @@ -0,0 +1,182 @@ +/* + * ============================================================================= + * Accelerator Extension + * Copyright (C) 2011 Asher Baker (asherkin). 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 . + */ + +#include "extension.h" + +#include +#include "MemoryDownloader.h" + +#include "client/linux/handler/exception_handler.h" + +#include +#include +#include + +Accelerator g_accelerator; +SMEXT_LINK(&g_accelerator); + +IWebternet *webternet; +static IThreadHandle *uploadThread; + +ConVar acceleratorVersion("accelerator_version", SMEXT_CONF_VERSION, FCVAR_SPONLY|FCVAR_REPLICATED|FCVAR_NOTIFY, SMEXT_CONF_DESCRIPTION " Version"); + +char buffer[255]; +google_breakpad::ExceptionHandler *handler = NULL; + +void (*SignalHandler)(int, siginfo_t *, void *); + +const int kExceptionSignals[] = { + SIGSEGV, SIGABRT, SIGFPE, SIGILL, SIGBUS +}; + +const int kNumHandledSignals = sizeof(kExceptionSignals) / sizeof(kExceptionSignals[0]); + +static bool dumpCallback(const google_breakpad::MinidumpDescriptor& descriptor, void* context, bool succeeded) +{ + printf("Dump path: %s\n", descriptor.path()); + return succeeded; +} + +void OnGameFrame(bool simulating) +{ + bool weHaveBeenFuckedOver = false; + struct sigaction oact; + + for (int i = 0; i < kNumHandledSignals; ++i) { + sigaction(kExceptionSignals[i], NULL, &oact); + + if (oact.sa_sigaction != SignalHandler) { + weHaveBeenFuckedOver = true; + break; + } + } + + if (!weHaveBeenFuckedOver) { + return; + } + + META_CONPRINTF(">>> SOME BITCH OVERWROTE OUR HANDLER\n"); + + struct sigaction act; + memset(&act, 0, sizeof(act)); + sigemptyset(&act.sa_mask); + + for (int i = 0; i < kNumHandledSignals; ++i) { + sigaddset(&act.sa_mask, kExceptionSignals[i]); + } + + act.sa_sigaction = SignalHandler; + act.sa_flags = SA_ONSTACK | SA_SIGINFO; + + for (int i = 0; i < kNumHandledSignals; ++i) { + sigaction(kExceptionSignals[i], &act, NULL); + } +} + +void UploadCrashDump(const char *path) +{ + IWebForm *form = webternet->CreateForm(); + + form->AddString("UserID", g_pSM->GetCoreConfigValue("MinidumpAccount")); + + form->AddFile("upload_file_minidump", path); + + MemoryDownloader data; + IWebTransfer *xfer = webternet->CreateSession(); + xfer->SetFailOnHTTPError(true); + + if (!xfer->PostAndDownload("http://crash.limetech.org/submit", form, &data, NULL)) + { + META_CONPRINTF(">>> UPLOAD FAILED\n"); + } else { + META_CONPRINTF(">>> UPLOADED CRASH DUMP"); + META_CONPRINTF("%s", data.GetBuffer()); + } +} + +void Accelerator::OnCoreMapStart(edict_t *pEdictList, int edictCount, int clientMax) +{ + META_CONPRINTF(">>> MinidumpAccount: %s\n", g_pSM->GetCoreConfigValue("MinidumpAccount")); + + DIR *dumps = opendir(buffer); + dirent *dump; + + char path[512]; + + while ((dump = readdir(dumps)) != NULL) + { + if (dump->d_type == DT_DIR) + continue; + + META_CONPRINTF(">>> UPLOADING %s\n", dump->d_name); + + g_pSM->Format(path, sizeof(path), "%s/%s", buffer, dump->d_name); + + UploadCrashDump(path); + unlink(path); + } + + closedir(dumps); +} + +bool Accelerator::SDK_OnLoad(char *error, size_t maxlength, bool late) +{ + sharesys->AddDependency(myself, "webternet.ext", true, true); + SM_GET_IFACE(WEBTERNET, webternet); + + g_pSM->BuildPath(Path_SM, buffer, 255, "data/dumps"); + + google_breakpad::MinidumpDescriptor descriptor(buffer); + handler = new google_breakpad::ExceptionHandler(descriptor, NULL, dumpCallback, NULL, true, -1); + + struct sigaction oact; + sigaction(SIGSEGV, NULL, &oact); + SignalHandler = oact.sa_sigaction; + + g_pSM->AddGameFrameHook(OnGameFrame); + + return true; +} + +bool Accelerator::SDK_OnMetamodLoad(ISmmAPI *ismm, char *error, size_t maxlen, bool late) +{ + GET_V_IFACE_CURRENT(GetEngineFactory, g_pCVar, ICvar, CVAR_INTERFACE_VERSION); + + ConVar_Register(0, this); + + return true; +} + +void Accelerator::SDK_OnUnload() +{ + g_pSM->RemoveGameFrameHook(OnGameFrame); +} + +bool Accelerator::SDK_OnMetamodUnload(char *error, size_t maxlen) +{ + return true; +} + +bool Accelerator::RegisterConCommandBase(ConCommandBase *pCommand) +{ + META_REGCVAR(pCommand); + + return true; +} + diff --git a/extension/extension.h b/extension/extension.h new file mode 100644 index 0000000..040049f --- /dev/null +++ b/extension/extension.h @@ -0,0 +1,104 @@ +/** + * ============================================================================= + * TF2 Items Extension + * Copyright (C) 2009-2010 AzuiSleet, Asher Baker (asherkin). 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 . + * + */ + +#ifndef _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_ +#define _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_ + +/** + * @file extension.hpp + * @brief Accelerator extension code header. + */ + +#include "smsdk_ext.hpp" + +/** + * @brief Sample implementation of the SDK Extension. + * Note: Uncomment one of the pre-defined virtual functions in order to use it. + */ +class Accelerator : public SDKExtension, public IConCommandBaseAccessor +{ +public: + /** + * @brief This is called after the initial loading sequence has been processed. + * + * @param error Error message buffer. + * @param maxlength Size of error message buffer. + * @param late Whether or not the module was loaded after map load. + * @return True to succeed loading, false to fail. + */ + virtual bool SDK_OnLoad(char *error, size_t maxlen, bool late); + + /** + * @brief This is called right before the extension is unloaded. + */ + virtual void SDK_OnUnload(); + + /** + * @brief Called when the pause state is changed. + */ + //virtual void SDK_OnPauseChange(bool paused); + + /** + * @brief this is called when Core wants to know if your extension is working. + * + * @param error Error message buffer. + * @param maxlength Size of error message buffer. + * @return True if working, false otherwise. + */ + //virtual bool QueryRunning(char *error, size_t maxlen); +public: +#if defined SMEXT_CONF_METAMOD + /** + * @brief Called when Metamod is attached, before the extension version is called. + * + * @param error Error buffer. + * @param maxlength Maximum size of error buffer. + * @param late Whether or not Metamod considers this a late load. + * @return True to succeed, false to fail. + */ + virtual bool SDK_OnMetamodLoad(ISmmAPI *ismm, char *error, size_t maxlen, bool late); + + /** + * @brief Called when Metamod is detaching, after the extension version is called. + * NOTE: By default this is blocked unless sent from SourceMod. + * + * @param error Error buffer. + * @param maxlength Maximum size of error buffer. + * @return True to succeed, false to fail. + */ + virtual bool SDK_OnMetamodUnload(char *error, size_t maxlen); + + /** + * @brief Called when Metamod's pause state is changing. + * NOTE: By default this is blocked unless sent from SourceMod. + * + * @param paused Pause state being set. + * @param error Error buffer. + * @param maxlength Maximum size of error buffer. + * @return True to succeed, false to fail. + */ + //virtual bool SDK_OnMetamodPauseChange(bool paused, char *error, size_t maxlen); +#endif + virtual void OnCoreMapStart(edict_t *pEdictList, int edictCount, int clientMax); +public: //IConCommandBaseAccessor + bool RegisterConCommandBase(ConCommandBase *pCommand); +}; + +#endif // _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_ diff --git a/extension/sdk/smsdk_config.hpp b/extension/sdk/smsdk_config.hpp new file mode 100644 index 0000000..f1a9886 --- /dev/null +++ b/extension/sdk/smsdk_config.hpp @@ -0,0 +1,80 @@ +/** + * ============================================================================= + * connect Extension + * Copyright (C) 2011 Asher Baker (asherkin). 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 . + */ + +#ifndef _INCLUDE_SOURCEMOD_EXTENSION_CONFIG_H_ +#define _INCLUDE_SOURCEMOD_EXTENSION_CONFIG_H_ + +/** + * @file smsdk_config.hpp + * @brief Contains macros for configuring basic extension information. + */ + + #include "version.h" // SM_FULL_VERSION + +/* Basic information exposed publicly */ +#define SMEXT_CONF_NAME "Accelerator" +#define SMEXT_CONF_DESCRIPTION "Take back control" +#define SMEXT_CONF_VERSION SM_FULL_VERSION +#define SMEXT_CONF_AUTHOR "Asher \"asherkin\" Baker" +#define SMEXT_CONF_URL "http://limetech.org/" +#define SMEXT_CONF_LOGTAG "CRASH" +#define SMEXT_CONF_LICENSE "GPL" +#define SMEXT_CONF_DATESTRING __DATE__ + +/** + * @brief Exposes plugin's main interface. + */ +#define SMEXT_LINK(name) SDKExtension *g_pExtensionIface = name; + +/** + * @brief Sets whether or not this plugin required Metamod. + * NOTE: Uncomment to enable, comment to disable. + */ +#define SMEXT_CONF_METAMOD + +/** Enable interfaces you want to use here by uncommenting lines */ +//#define SMEXT_ENABLE_FORWARDSYS +//#define SMEXT_ENABLE_HANDLESYS +//#define SMEXT_ENABLE_PLAYERHELPERS +//#define SMEXT_ENABLE_DBMANAGER +//#define SMEXT_ENABLE_GAMECONF +//#define SMEXT_ENABLE_MEMUTILS +//#define SMEXT_ENABLE_GAMEHELPERS +//#define SMEXT_ENABLE_TIMERSYS +#define SMEXT_ENABLE_THREADER +//#define SMEXT_ENABLE_LIBSYS +//#define SMEXT_ENABLE_MENUS +//#define SMEXT_ENABLE_ADTFACTORY +//#define SMEXT_ENABLE_PLUGINSYS +//#define SMEXT_ENABLE_ADMINSYS +//#define SMEXT_ENABLE_TEXTPARSERS +//#define SMEXT_ENABLE_USERMSGS +//#define SMEXT_ENABLE_TRANSLATOR +//#define SMEXT_ENABLE_NINVOKE + +#endif // _INCLUDE_SOURCEMOD_EXTENSION_CONFIG_H_ diff --git a/extension/sdk/smsdk_ext.cpp b/extension/sdk/smsdk_ext.cpp new file mode 100644 index 0000000..23cccb2 --- /dev/null +++ b/extension/sdk/smsdk_ext.cpp @@ -0,0 +1,465 @@ +/** + * vim: set ts=4 : + * ============================================================================= + * SourceMod Base Extension Code + * 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$ + */ + +#include +#include +#include "smsdk_ext.hpp" + +/** + * @file smsdk_ext.cpp + * @brief Contains wrappers for making Extensions easier to write. + */ + +IExtension *myself = NULL; /**< Ourself */ +IShareSys *g_pShareSys = NULL; /**< Share system */ +IShareSys *sharesys = NULL; /**< Share system */ +ISourceMod *g_pSM = NULL; /**< SourceMod helpers */ +ISourceMod *smutils = NULL; /**< SourceMod helpers */ + +#if defined SMEXT_ENABLE_FORWARDSYS +IForwardManager *g_pForwards = NULL; /**< Forward system */ +IForwardManager *forwards = NULL; /**< Forward system */ +#endif +#if defined SMEXT_ENABLE_HANDLESYS +IHandleSys *g_pHandleSys = NULL; /**< Handle system */ +IHandleSys *handlesys = NULL; /**< Handle system */ +#endif +#if defined SMEXT_ENABLE_PLAYERHELPERS +IPlayerManager *playerhelpers = NULL; /**< Player helpers */ +#endif //SMEXT_ENABLE_PLAYERHELPERS +#if defined SMEXT_ENABLE_DBMANAGER +IDBManager *dbi = NULL; /**< DB Manager */ +#endif //SMEXT_ENABLE_DBMANAGER +#if defined SMEXT_ENABLE_GAMECONF +IGameConfigManager *gameconfs = NULL; /**< Game config manager */ +#endif //SMEXT_ENABLE_DBMANAGER +#if defined SMEXT_ENABLE_MEMUTILS +IMemoryUtils *memutils = NULL; +#endif //SMEXT_ENABLE_DBMANAGER +#if defined SMEXT_ENABLE_GAMEHELPERS +IGameHelpers *gamehelpers = NULL; +#endif +#if defined SMEXT_ENABLE_TIMERSYS +ITimerSystem *timersys = NULL; +#endif +#if defined SMEXT_ENABLE_ADTFACTORY +IADTFactory *adtfactory = NULL; +#endif +#if defined SMEXT_ENABLE_THREADER +IThreader *threader = NULL; +#endif +#if defined SMEXT_ENABLE_LIBSYS +ILibrarySys *libsys = NULL; +#endif +#if defined SMEXT_ENABLE_PLUGINSYS +SourceMod::IPluginManager *plsys; +#endif +#if defined SMEXT_ENABLE_MENUS +IMenuManager *menus = NULL; +#endif +#if defined SMEXT_ENABLE_ADMINSYS +IAdminSystem *adminsys = NULL; +#endif +#if defined SMEXT_ENABLE_TEXTPARSERS +ITextParsers *textparsers = NULL; +#endif +#if defined SMEXT_ENABLE_USERMSGS +IUserMessages *usermsgs = NULL; +#endif +#if defined SMEXT_ENABLE_TRANSLATOR +ITranslator *translator = NULL; +#endif +#if defined SMEXT_ENABLE_NINVOKE +INativeInterface *ninvoke = NULL; +#endif + +/** Exports the main interface */ +PLATFORM_EXTERN_C IExtensionInterface *GetSMExtAPI() +{ + return g_pExtensionIface; +} + +SDKExtension::SDKExtension() +{ +#if defined SMEXT_CONF_METAMOD + m_SourceMMLoaded = false; + m_WeAreUnloaded = false; + m_WeGotPauseChange = false; +#endif +} + +bool SDKExtension::OnExtensionLoad(IExtension *me, IShareSys *sys, char *error, size_t maxlength, bool late) +{ + g_pShareSys = sharesys = sys; + myself = me; + +#if defined SMEXT_CONF_METAMOD + m_WeAreUnloaded = true; + + if (!m_SourceMMLoaded) + { + if (error) + { + snprintf(error, maxlength, "Metamod attach failed"); + } + return false; + } +#endif + SM_GET_IFACE(SOURCEMOD, g_pSM); + smutils = g_pSM; +#if defined SMEXT_ENABLE_HANDLESYS + SM_GET_IFACE(HANDLESYSTEM, g_pHandleSys); + handlesys = g_pHandleSys; +#endif +#if defined SMEXT_ENABLE_FORWARDSYS + SM_GET_IFACE(FORWARDMANAGER, g_pForwards); + forwards = g_pForwards; +#endif +#if defined SMEXT_ENABLE_PLAYERHELPERS + SM_GET_IFACE(PLAYERMANAGER, playerhelpers); +#endif +#if defined SMEXT_ENABLE_DBMANAGER + SM_GET_IFACE(DBI, dbi); +#endif +#if defined SMEXT_ENABLE_GAMECONF + SM_GET_IFACE(GAMECONFIG, gameconfs); +#endif +#if defined SMEXT_ENABLE_MEMUTILS + SM_GET_IFACE(MEMORYUTILS, memutils); +#endif +#if defined SMEXT_ENABLE_GAMEHELPERS + SM_GET_IFACE(GAMEHELPERS, gamehelpers); +#endif +#if defined SMEXT_ENABLE_TIMERSYS + SM_GET_IFACE(TIMERSYS, timersys); +#endif +#if defined SMEXT_ENABLE_ADTFACTORY + SM_GET_IFACE(ADTFACTORY, adtfactory); +#endif +#if defined SMEXT_ENABLE_THREADER + SM_GET_IFACE(THREADER, threader); +#endif +#if defined SMEXT_ENABLE_LIBSYS + SM_GET_IFACE(LIBRARYSYS, libsys); +#endif +#if defined SMEXT_ENABLE_PLUGINSYS + SM_GET_IFACE(PLUGINSYSTEM, plsys); +#endif +#if defined SMEXT_ENABLE_MENUS + SM_GET_IFACE(MENUMANAGER, menus); +#endif +#if defined SMEXT_ENABLE_ADMINSYS + SM_GET_IFACE(ADMINSYS, adminsys); +#endif +#if defined SMEXT_ENABLE_TEXTPARSERS + SM_GET_IFACE(TEXTPARSERS, textparsers); +#endif +#if defined SMEXT_ENABLE_USERMSGS + SM_GET_IFACE(USERMSGS, usermsgs); +#endif +#if defined SMEXT_ENABLE_TRANSLATOR + SM_GET_IFACE(TRANSLATOR, translator); +#endif + + if (SDK_OnLoad(error, maxlength, late)) + { +#if defined SMEXT_CONF_METAMOD + m_WeAreUnloaded = true; +#endif + return true; + } + + return false; +} + +bool SDKExtension::IsMetamodExtension() +{ +#if defined SMEXT_CONF_METAMOD + return true; +#else + return false; +#endif +} + +void SDKExtension::OnExtensionPauseChange(bool state) +{ +#if defined SMEXT_CONF_METAMOD + m_WeGotPauseChange = true; +#endif + SDK_OnPauseChange(state); +} + +void SDKExtension::OnExtensionsAllLoaded() +{ + SDK_OnAllLoaded(); +} + +void SDKExtension::OnExtensionUnload() +{ +#if defined SMEXT_CONF_METAMOD + m_WeAreUnloaded = true; +#endif + SDK_OnUnload(); +} + +const char *SDKExtension::GetExtensionAuthor() +{ + return SMEXT_CONF_AUTHOR; +} + +const char *SDKExtension::GetExtensionDateString() +{ + return SMEXT_CONF_DATESTRING; +} + +const char *SDKExtension::GetExtensionDescription() +{ + return SMEXT_CONF_DESCRIPTION; +} + +const char *SDKExtension::GetExtensionVerString() +{ + return SMEXT_CONF_VERSION; +} + +const char *SDKExtension::GetExtensionName() +{ + return SMEXT_CONF_NAME; +} + +const char *SDKExtension::GetExtensionTag() +{ + return SMEXT_CONF_LOGTAG; +} + +const char *SDKExtension::GetExtensionURL() +{ + return SMEXT_CONF_URL; +} + +bool SDKExtension::SDK_OnLoad(char *error, size_t maxlength, bool late) +{ + return true; +} + +void SDKExtension::SDK_OnUnload() +{ +} + +void SDKExtension::SDK_OnPauseChange(bool paused) +{ +} + +void SDKExtension::SDK_OnAllLoaded() +{ +} + +#if defined SMEXT_CONF_METAMOD + +PluginId g_PLID = 0; /**< Metamod plugin ID */ +ISmmPlugin *g_PLAPI = NULL; /**< Metamod plugin API */ +SourceHook::ISourceHook *g_SHPtr = NULL; /**< SourceHook pointer */ +ISmmAPI *g_SMAPI = NULL; /**< SourceMM API pointer */ + +IVEngineServer *engine = NULL; /**< IVEngineServer pointer */ +IServerGameDLL *gamedll = NULL; /**< IServerGameDLL pointer */ + +/** Exposes the extension to Metamod */ +SMM_API void *PL_EXPOSURE(const char *name, int *code) +{ +#if defined METAMOD_PLAPI_VERSION + if (name && !strcmp(name, METAMOD_PLAPI_NAME)) +#else + if (name && !strcmp(name, PLAPI_NAME)) +#endif + { + if (code) + { + *code = IFACE_OK; + } + return static_cast(g_pExtensionIface); + } + + if (code) + { + *code = IFACE_FAILED; + } + + return NULL; +} + +bool SDKExtension::Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen, bool late) +{ + PLUGIN_SAVEVARS(); + +#if !defined METAMOD_PLAPI_VERSION + GET_V_IFACE_ANY(serverFactory, gamedll, IServerGameDLL, INTERFACEVERSION_SERVERGAMEDLL); + GET_V_IFACE_CURRENT(engineFactory, engine, IVEngineServer, INTERFACEVERSION_VENGINESERVER); +#else + GET_V_IFACE_ANY(GetServerFactory, gamedll, IServerGameDLL, INTERFACEVERSION_SERVERGAMEDLL); + GET_V_IFACE_CURRENT(GetEngineFactory, engine, IVEngineServer, INTERFACEVERSION_VENGINESERVER); +#endif + + m_SourceMMLoaded = true; + + return SDK_OnMetamodLoad(ismm, error, maxlen, late); +} + +bool SDKExtension::Unload(char *error, size_t maxlen) +{ + if (!m_WeAreUnloaded) + { + if (error) + { + snprintf(error, maxlen, "This extension must be unloaded by SourceMod."); + } + return false; + } + + return SDK_OnMetamodUnload(error, maxlen); +} + +bool SDKExtension::Pause(char *error, size_t maxlen) +{ + if (!m_WeGotPauseChange) + { + if (error) + { + snprintf(error, maxlen, "This extension must be paused by SourceMod."); + } + return false; + } + + m_WeGotPauseChange = false; + + return SDK_OnMetamodPauseChange(true, error, maxlen); +} + +bool SDKExtension::Unpause(char *error, size_t maxlen) +{ + if (!m_WeGotPauseChange) + { + if (error) + { + snprintf(error, maxlen, "This extension must be unpaused by SourceMod."); + } + return false; + } + + m_WeGotPauseChange = false; + + return SDK_OnMetamodPauseChange(false, error, maxlen); +} + +const char *SDKExtension::GetAuthor() +{ + return GetExtensionAuthor(); +} + +const char *SDKExtension::GetDate() +{ + return GetExtensionDateString(); +} + +const char *SDKExtension::GetDescription() +{ + return GetExtensionDescription(); +} + +const char *SDKExtension::GetLicense() +{ + return SMEXT_CONF_LICENSE; +} + +const char *SDKExtension::GetLogTag() +{ + return GetExtensionTag(); +} + +const char *SDKExtension::GetName() +{ + return GetExtensionName(); +} + +const char *SDKExtension::GetURL() +{ + return GetExtensionURL(); +} + +const char *SDKExtension::GetVersion() +{ + return GetExtensionVerString(); +} + +bool SDKExtension::SDK_OnMetamodLoad(ISmmAPI *ismm, char *error, size_t maxlength, bool late) +{ + return true; +} + +bool SDKExtension::SDK_OnMetamodUnload(char *error, size_t maxlength) +{ + return true; +} + +bool SDKExtension::SDK_OnMetamodPauseChange(bool paused, char *error, size_t maxlength) +{ + return true; +} + +#endif + +/* Overload a few things to prevent libstdc++ linking */ +#if defined __linux__ || defined __APPLE__ +extern "C" void __cxa_pure_virtual(void) +{ +} + +void *operator new(size_t size) +{ + return malloc(size); +} + +void *operator new[](size_t size) +{ + return malloc(size); +} + +void operator delete(void *ptr) +{ + free(ptr); +} + +void operator delete[](void * ptr) +{ + free(ptr); +} +#endif + diff --git a/extension/sdk/smsdk_ext.hpp b/extension/sdk/smsdk_ext.hpp new file mode 100644 index 0000000..a3de9b3 --- /dev/null +++ b/extension/sdk/smsdk_ext.hpp @@ -0,0 +1,339 @@ +/** + * vim: set ts=4 : + * ============================================================================= + * SourceMod Base Extension Code + * 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$ + */ + +#ifndef _INCLUDE_SOURCEMOD_EXTENSION_BASESDK_H_ +#define _INCLUDE_SOURCEMOD_EXTENSION_BASESDK_H_ + +/** + * @file smsdk_ext.hpp + * @brief Contains wrappers for making Extensions easier to write. + */ + +#include "smsdk_config.hpp" +#include +#include +#include +#include +#include +#if defined SMEXT_ENABLE_FORWARDSYS +#include +#endif //SMEXT_ENABLE_FORWARDSYS +#if defined SMEXT_ENABLE_PLAYERHELPERS +#include +#endif //SMEXT_ENABLE_PlAYERHELPERS +#if defined SMEXT_ENABLE_DBMANAGER +#include +#endif //SMEXT_ENABLE_DBMANAGER +#if defined SMEXT_ENABLE_GAMECONF +#include +#endif +#if defined SMEXT_ENABLE_MEMUTILS +#include +#endif +#if defined SMEXT_ENABLE_GAMEHELPERS +#include +#endif +#if defined SMEXT_ENABLE_TIMERSYS +#include +#endif +#if defined SMEXT_ENABLE_ADTFACTORY +#include +#endif +#if defined SMEXT_ENABLE_THREADER +#include +#endif +#if defined SMEXT_ENABLE_LIBSYS +#include +#endif +#if defined SMEXT_ENABLE_PLUGINSYS +#include +#endif +#if defined SMEXT_ENABLE_MENUS +#include +#endif +#if defined SMEXT_ENABLE_ADMINSYS +#include +#endif +#if defined SMEXT_ENABLE_TEXTPARSERS +#include +#endif +#if defined SMEXT_ENABLE_USERMSGS +#include +#endif +#if defined SMEXT_ENABLE_TRANSLATOR +#include +#endif +#if defined SMEXT_ENABLE_NINVOKE +#include +#endif + +#if defined SMEXT_CONF_METAMOD +#include +#include +#endif + +using namespace SourceMod; +using namespace SourcePawn; + +class SDKExtension : +#if defined SMEXT_CONF_METAMOD + public ISmmPlugin, +#endif + public IExtensionInterface +{ +public: + /** Constructor */ + SDKExtension(); +public: + /** + * @brief This is called after the initial loading sequence has been processed. + * + * @param error Error message buffer. + * @param maxlength Size of error message buffer. + * @param late Whether or not the module was loaded after map load. + * @return True to succeed loading, false to fail. + */ + virtual bool SDK_OnLoad(char *error, size_t maxlength, bool late); + + /** + * @brief This is called right before the extension is unloaded. + */ + virtual void SDK_OnUnload(); + + /** + * @brief This is called once all known extensions have been loaded. + */ + virtual void SDK_OnAllLoaded(); + + /** + * @brief Called when the pause state is changed. + */ + virtual void SDK_OnPauseChange(bool paused); + +#if defined SMEXT_CONF_METAMOD + /** + * @brief Called when Metamod is attached, before the extension version is called. + * + * @param error Error buffer. + * @param maxlength Maximum size of error buffer. + * @param late Whether or not Metamod considers this a late load. + * @return True to succeed, false to fail. + */ + virtual bool SDK_OnMetamodLoad(ISmmAPI *ismm, char *error, size_t maxlength, bool late); + + /** + * @brief Called when Metamod is detaching, after the extension version is called. + * NOTE: By default this is blocked unless sent from SourceMod. + * + * @param error Error buffer. + * @param maxlength Maximum size of error buffer. + * @return True to succeed, false to fail. + */ + virtual bool SDK_OnMetamodUnload(char *error, size_t maxlength); + + /** + * @brief Called when Metamod's pause state is changing. + * NOTE: By default this is blocked unless sent from SourceMod. + * + * @param paused Pause state being set. + * @param error Error buffer. + * @param maxlength Maximum size of error buffer. + * @return True to succeed, false to fail. + */ + virtual bool SDK_OnMetamodPauseChange(bool paused, char *error, size_t maxlength); +#endif + +public: //IExtensionInterface + virtual bool OnExtensionLoad(IExtension *me, IShareSys *sys, char *error, size_t maxlength, bool late); + virtual void OnExtensionUnload(); + virtual void OnExtensionsAllLoaded(); + + /** Returns whether or not this is a Metamod-based extension */ + virtual bool IsMetamodExtension(); + + /** + * @brief Called when the pause state changes. + * + * @param state True if being paused, false if being unpaused. + */ + virtual void OnExtensionPauseChange(bool state); + + /** Returns name */ + virtual const char *GetExtensionName(); + /** Returns URL */ + virtual const char *GetExtensionURL(); + /** Returns log tag */ + virtual const char *GetExtensionTag(); + /** Returns author */ + virtual const char *GetExtensionAuthor(); + /** Returns version string */ + virtual const char *GetExtensionVerString(); + /** Returns description string */ + virtual const char *GetExtensionDescription(); + /** Returns date string */ + virtual const char *GetExtensionDateString(); +#if defined SMEXT_CONF_METAMOD +public: //ISmmPlugin + /** Called when the extension is attached to Metamod. */ + virtual bool Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlength, bool late); + /** Returns the author to MM */ + virtual const char *GetAuthor(); + /** Returns the name to MM */ + virtual const char *GetName(); + /** Returns the description to MM */ + virtual const char *GetDescription(); + /** Returns the URL to MM */ + virtual const char *GetURL(); + /** Returns the license to MM */ + virtual const char *GetLicense(); + /** Returns the version string to MM */ + virtual const char *GetVersion(); + /** Returns the date string to MM */ + virtual const char *GetDate(); + /** Returns the logtag to MM */ + virtual const char *GetLogTag(); + /** Called on unload */ + virtual bool Unload(char *error, size_t maxlength); + /** Called on pause */ + virtual bool Pause(char *error, size_t maxlength); + /** Called on unpause */ + virtual bool Unpause(char *error, size_t maxlength); +private: + bool m_SourceMMLoaded; + bool m_WeAreUnloaded; + bool m_WeGotPauseChange; +#endif +}; + +extern SDKExtension *g_pExtensionIface; +extern IExtension *myself; + +extern IShareSys *g_pShareSys; +extern IShareSys *sharesys; /* Note: Newer name */ +extern ISourceMod *g_pSM; +extern ISourceMod *smutils; /* Note: Newer name */ + +/* Optional interfaces are below */ +#if defined SMEXT_ENABLE_FORWARDSYS +extern IForwardManager *g_pForwards; +extern IForwardManager *forwards; /* Note: Newer name */ +#endif //SMEXT_ENABLE_FORWARDSYS +#if defined SMEXT_ENABLE_HANDLESYS +extern IHandleSys *g_pHandleSys; +extern IHandleSys *handlesys; /* Note: Newer name */ +#endif //SMEXT_ENABLE_HANDLESYS +#if defined SMEXT_ENABLE_PLAYERHELPERS +extern IPlayerManager *playerhelpers; +#endif //SMEXT_ENABLE_PLAYERHELPERS +#if defined SMEXT_ENABLE_DBMANAGER +extern IDBManager *dbi; +#endif //SMEXT_ENABLE_DBMANAGER +#if defined SMEXT_ENABLE_GAMECONF +extern IGameConfigManager *gameconfs; +#endif //SMEXT_ENABLE_DBMANAGER +#if defined SMEXT_ENABLE_MEMUTILS +extern IMemoryUtils *memutils; +#endif +#if defined SMEXT_ENABLE_GAMEHELPERS +extern IGameHelpers *gamehelpers; +#endif +#if defined SMEXT_ENABLE_TIMERSYS +extern ITimerSystem *timersys; +#endif +#if defined SMEXT_ENABLE_ADTFACTORY +extern IADTFactory *adtfactory; +#endif +#if defined SMEXT_ENABLE_THREADER +extern IThreader *threader; +#endif +#if defined SMEXT_ENABLE_LIBSYS +extern ILibrarySys *libsys; +#endif +#if defined SMEXT_ENABLE_PLUGINSYS +extern SourceMod::IPluginManager *plsys; +#endif +#if defined SMEXT_ENABLE_MENUS +extern IMenuManager *menus; +#endif +#if defined SMEXT_ENABLE_ADMINSYS +extern IAdminSystem *adminsys; +#endif +#if defined SMEXT_ENABLE_USERMSGS +extern IUserMessages *usermsgs; +#endif +#if defined SMEXT_ENABLE_TRANSLATOR +extern ITranslator *translator; +#endif +#if defined SMEXT_ENABLE_NINVOKE +extern INativeInterface *ninvoke; +#endif + +#if defined SMEXT_CONF_METAMOD +PLUGIN_GLOBALVARS(); +extern IVEngineServer *engine; +extern IServerGameDLL *gamedll; +#endif + +/** Creates a SourceMod interface macro pair */ +#define SM_MKIFACE(name) SMINTERFACE_##name##_NAME, SMINTERFACE_##name##_VERSION +/** Automates retrieving SourceMod interfaces */ +#define SM_GET_IFACE(prefix, addr) \ + if (!g_pShareSys->RequestInterface(SM_MKIFACE(prefix), myself, (SMInterface **)&addr)) \ + { \ + if (error != NULL && maxlength) \ + { \ + size_t len = snprintf(error, maxlength, "Could not find interface: %s", SMINTERFACE_##prefix##_NAME); \ + if (len >= maxlength) \ + { \ + error[maxlength - 1] = '\0'; \ + } \ + } \ + return false; \ + } +/** Automates retrieving SourceMod interfaces when needed outside of SDK_OnLoad() */ +#define SM_GET_LATE_IFACE(prefix, addr) \ + g_pShareSys->RequestInterface(SM_MKIFACE(prefix), myself, (SMInterface **)&addr) +/** Validates a SourceMod interface pointer */ +#define SM_CHECK_IFACE(prefix, addr) \ + if (!addr) \ + { \ + if (error != NULL && maxlength) \ + { \ + size_t len = snprintf(error, maxlength, "Could not find interface: %s", SMINTERFACE_##prefix##_NAME); \ + if (len >= maxlength) \ + { \ + error[maxlength - 1] = '\0'; \ + } \ + } \ + return false; \ + } + +#endif // _INCLUDE_SOURCEMOD_EXTENSION_BASESDK_H_ diff --git a/extension/version.h b/extension/version.h new file mode 100644 index 0000000..92e4769 --- /dev/null +++ b/extension/version.h @@ -0,0 +1,27 @@ +#ifndef _INCLUDE_VERSION_INFORMATION_H_ +#define _INCLUDE_VERSION_INFORMATION_H_ + +/** + * @file Contains version information. + * @brief This file will redirect to an autogenerated version if being compiled via + * the build scripts. + */ + +#if defined SM_GENERATED_BUILD +#include "version_auto.h" +#else + +#ifndef SM_GENERATED_BUILD +#undef BINARY_NAME +#define BINARY_NAME "accelerator.ext.dll\0" +#endif + +#define SM_BUILD_TAG "-manual" +#define SM_BUILD_UNIQUEID "[MANUAL BUILD]" +#define SM_VERSION "1.2.0" +#define SM_FULL_VERSION SM_VERSION SM_BUILD_TAG +#define SM_FILE_VERSION 1,2,0,0 + +#endif + +#endif /* _INCLUDE_VERSION_INFORMATION_H_ */ diff --git a/extension/version.rc b/extension/version.rc new file mode 100644 index 0000000..4a8a50e --- /dev/null +++ b/extension/version.rc @@ -0,0 +1,45 @@ +#include "winres.h" + +#include + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif + +#ifndef SM_GENERATED_BUILD +#define BINARY_NAME "accelerator.ext.dll\0" +#endif + +VS_VERSION_INFO VERSIONINFO + FILEVERSION SM_FILE_VERSION + PRODUCTVERSION SM_FILE_VERSION + FILEFLAGSMASK 0x17L +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "Comments", "Accelerator Extension" + VALUE "FileDescription", "SourceMod Accelerator Extension" + VALUE "FileVersion", SM_BUILD_UNIQUEID + VALUE "InternalName", "Accelerator" + VALUE "LegalCopyright", "Copyright (c) 2012, Asher Baker" + VALUE "OriginalFilename", BINARY_NAME + VALUE "ProductName", "Accelerator Extension" + VALUE "ProductVersion", SM_FULL_VERSION + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0409, 0x04B0 + END +END diff --git a/extension/version_auto.h b/extension/version_auto.h new file mode 100644 index 0000000..a8f2e80 --- /dev/null +++ b/extension/version_auto.h @@ -0,0 +1,12 @@ + +#ifndef _AUTO_VERSION_INFORMATION_H_ +#define _AUTO_VERSION_INFORMATION_H_ + +#define SM_BUILD_TAG "" +#define SM_BUILD_UNIQUEID "38:7b77e54e78c1" SM_BUILD_TAG +#define SM_VERSION "1.0.0" +#define SM_FULL_VERSION SM_VERSION SM_BUILD_TAG +#define SM_FILE_VERSION 1,0,0,0 + +#endif /* _AUTO_VERSION_INFORMATION_H_ */ + diff --git a/product.version b/product.version new file mode 100644 index 0000000..3eefcb9 --- /dev/null +++ b/product.version @@ -0,0 +1 @@ +1.0.0 diff --git a/upload.py b/upload.py new file mode 100644 index 0000000..968768d --- /dev/null +++ b/upload.py @@ -0,0 +1,71 @@ +import re, os, sys +import subprocess + +import zipfile +import ftplib + +platform = 'unknown' +if sys.platform.startswith('linux'): + platform = 'linux' +elif sys.platform.startswith('win32'): + platform = 'windows' +elif sys.platform.startswith('darwin'): + platform = 'mac' + +def HGVersion(): + p = subprocess.Popen(['hg', 'identify', '-n'], stdout = subprocess.PIPE, stderr = subprocess.PIPE) + (stdout, stderr) = p.communicate() + stdout = stdout.decode('UTF-8') + + return stdout.rstrip('+\r\n') + +def ReleaseVersion(): + productFile = open('product.version', 'r') + productContents = productFile.read() + productFile.close() + + m = re.match('(\d+)\.(\d+)\.(\d+)(.*)', productContents) + if m == None: + raise Exception('Could not detremine product version') + + major, minor, release, tag = m.groups() + return '.'.join([major, minor, release]) + +filename = '-'.join(['accelerator', ReleaseVersion(), 'hg' + HGVersion(), platform]) + +debug_build = os.environ.get('is_debug_build', False) == "1" + +if debug_build: + filename += '-debug' + +filename += '.zip' + +zip = zipfile.ZipFile(filename, 'w', zipfile.ZIP_DEFLATED) + +for base, dirs, files in os.walk('package'): + for file in files: + fn = os.path.join(base, file) + fns = fn[(len('package') + 1):] + + zip.write(fn, fns) + +print("%-33s %-10s %21s %12s" % ("File Name", "CRC32", "Modified ", "Size")) +for zinfo in zip.infolist(): + date = "%d-%02d-%02d %02d:%02d:%02d" % zinfo.date_time[:6] + print("%-33s %-10d %21s %12d" % (zinfo.filename, zinfo.CRC, date, zinfo.file_size)) + +zip.close() + +if 'ftp_hostname' in os.environ: + print('') + + ftp = ftplib.FTP(os.environ['ftp_hostname'], os.environ['ftp_username'], os.environ['ftp_password']) + print('Connected to server, uploading build...') + ftp.cwd(os.environ['ftp_directory']) + print(ftp.storbinary('STOR ' + filename, open(filename, 'rb'))) + ftp.quit() + + print('Uploaded as \'' + filename + '\'') + + os.unlink(filename) +