diff --git a/AMBuildScript b/AMBuildScript new file mode 100644 index 0000000..5745de2 --- /dev/null +++ b/AMBuildScript @@ -0,0 +1,417 @@ +# vim: set sts=2 ts=8 sw=2 tw=99 et ft=python: +import os, sys + +# Simple extensions do not need to modify this file. + +class SDK(object): + def __init__(self, sdk, ext, aDef, name, platform, dir): + self.folder = 'hl2sdk-' + dir + self.envvar = sdk + self.ext = ext + self.code = aDef + self.define = name + self.platform = platform + self.name = dir + self.path = None # Actual path + +WinOnly = ['windows'] +WinLinux = ['windows', 'linux'] +WinLinuxMac = ['windows', 'linux', 'mac'] + +PossibleSDKs = { + 'l4d': SDK('HL2SDKL4D', '_mm', '12', 'LEFT4DEAD', WinLinuxMac, 'l4d'), + 'l4d2': SDK('HL2SDKL4D2', '_mm', '15', 'LEFT4DEAD2', WinLinuxMac, 'l4d2'), +} + +def ResolveEnvPath(env, folder): + if env in os.environ: + path = os.environ[env] + if os.path.isdir(path): + return path + return None + + head = os.getcwd() + oldhead = None + while head != None and head != oldhead: + path = os.path.join(head, folder) + if os.path.isdir(path): + return path + oldhead = head + head, tail = os.path.split(head) + + return None + +def Normalize(path): + return os.path.abspath(os.path.normpath(path)) + +class ExtensionConfig(object): + def __init__(self): + self.sdks = {} + self.binaries = [] + self.extensions = [] + self.generated_headers = None + self.mms_root = None + + @property + def tag(self): + if builder.options.debug == '1': + return 'Debug' + return 'Release' + + def detectSDKs(self): + sdk_list = builder.options.sdks.split(',') + use_all = sdk_list[0] == 'all' + use_present = sdk_list[0] == 'present' + + for sdk_name in PossibleSDKs: + sdk = PossibleSDKs[sdk_name] + if builder.target_platform in sdk.platform: + if builder.options.hl2sdk_root: + sdk_path = os.path.join(builder.options.hl2sdk_root, sdk.folder) + else: + sdk_path = ResolveEnvPath(sdk.envvar, sdk.folder) + if sdk_path is None or not os.path.isdir(sdk_path): + if use_all or sdk_name in sdk_list: + raise Exception('Could not find a valid path for {0}'.format(sdk.envvar)) + continue + if use_all or use_present or sdk_name in sdk_list: + sdk.path = Normalize(sdk_path) + self.sdks[sdk_name] = sdk + + if len(self.sdks) < 1: + raise Exception('At least one SDK must be available.') + + if builder.options.mms_path: + self.mms_root = builder.options.mms_path + else: + self.mms_root = ResolveEnvPath('MMSOURCE110', 'mmsource-1.10') + if not self.mms_root: + self.mms_root = ResolveEnvPath('MMSOURCE', 'metamod-source') + if not self.mms_root: + self.mms_root = ResolveEnvPath('MMSOURCE_DEV', 'mmsource-central') + + if not self.mms_root or not os.path.isdir(self.mms_root): + raise Exception('Could not find a source copy of Metamod:Source') + self.mms_root = Normalize(self.mms_root) + + def configure(self): + cxx = builder.DetectCompilers() + + if cxx.like('gcc'): + self.configure_gcc(cxx) + elif cxx.vendor == 'msvc': + self.configure_msvc(cxx) + + # Optimizaiton + if builder.options.opt == '1': + cxx.defines += ['NDEBUG'] + + # Debugging + if builder.options.debug == '1': + cxx.defines += ['DEBUG', '_DEBUG'] + + # Platform-specifics + if builder.target_platform == 'linux': + self.configure_linux(cxx) + elif builder.target_platform == 'mac': + self.configure_mac(cxx) + elif builder.target_platform == 'windows': + self.configure_windows(cxx) + + def configure_gcc(self, cxx): + cxx.defines += [ + 'stricmp=strcasecmp', + '_stricmp=strcasecmp', + '_snprintf=snprintf', + '_vsnprintf=vsnprintf', + 'HAVE_STDINT_H', + 'GNUC', + ] + cxx.cflags += [ + '-pipe', + '-fno-strict-aliasing', + '-Wall', + '-Werror', + '-Wno-unused', + '-Wno-switch', + '-Wno-array-bounds', + '-msse', + '-m32', + '-fvisibility=hidden', + ] + cxx.cxxflags += [ + '-std=c++14', + '-fno-exceptions', + '-fno-threadsafe-statics', + '-Wno-non-virtual-dtor', + '-Wno-overloaded-virtual', + '-fvisibility-inlines-hidden', + ] + cxx.linkflags += ['-m32'] + + have_gcc = cxx.vendor == 'gcc' + have_clang = cxx.vendor == 'clang' + if cxx.version >= 'clang-3.9' or cxx.version >= 'apple-clang-10.0': + cxx.cxxflags += ['-Wno-expansion-to-defined'] + if cxx.version >= 'clang-3.6': + cxx.cxxflags += ['-Wno-inconsistent-missing-override'] + if have_clang or (cxx.version >= 'gcc-4.6'): + cxx.cflags += ['-Wno-narrowing'] + if have_clang or (cxx.version >= 'gcc-4.7'): + cxx.cxxflags += ['-Wno-delete-non-virtual-dtor'] + if cxx.version >= 'gcc-4.8': + cxx.cflags += ['-Wno-unused-result'] + + if have_clang: + cxx.cxxflags += ['-Wno-implicit-exception-spec-mismatch'] + if cxx.version >= 'apple-clang-5.1' or cxx.version >= 'clang-3.4': + cxx.cxxflags += ['-Wno-deprecated-register'] + else: + cxx.cxxflags += ['-Wno-deprecated'] + cxx.cflags += ['-Wno-sometimes-uninitialized'] + + # Work around SDK warnings. + if cxx.version >= 'clang-10.0': + cxx.cflags += [ + '-Wno-implicit-int-float-conversion', + '-Wno-tautological-overlap-compare', + ] + + if have_gcc: + cxx.cflags += ['-mfpmath=sse'] + + if builder.options.opt == '1': + cxx.cflags += ['-O3'] + + # Don't omit the frame pointer. + cxx.cflags += ['-fno-omit-frame-pointer'] + + def configure_msvc(self, cxx): + if builder.options.debug == '1': + cxx.cflags += ['/MTd'] + cxx.linkflags += ['/NODEFAULTLIB:libcmt'] + else: + cxx.cflags += ['/MT'] + cxx.defines += [ + '_CRT_SECURE_NO_DEPRECATE', + '_CRT_SECURE_NO_WARNINGS', + '_CRT_NONSTDC_NO_DEPRECATE', + '_ITERATOR_DEBUG_LEVEL=0', + ] + cxx.cflags += [ + '/W3', + ] + cxx.cxxflags += [ + '/EHsc', + '/GR-', + '/TP', + ] + cxx.linkflags += [ + '/MACHINE:X86', + 'kernel32.lib', + 'user32.lib', + 'gdi32.lib', + 'winspool.lib', + 'comdlg32.lib', + 'advapi32.lib', + 'shell32.lib', + 'ole32.lib', + 'oleaut32.lib', + 'uuid.lib', + 'odbc32.lib', + 'odbccp32.lib', + ] + + if builder.options.opt == '1': + cxx.cflags += ['/Ox', '/Zo'] + cxx.linkflags += ['/OPT:ICF', '/OPT:REF'] + + if builder.options.debug == '1': + cxx.cflags += ['/Od', '/RTC1'] + + # This needs to be after our optimization flags which could otherwise disable it. + # Don't omit the frame pointer. + cxx.cflags += ['/Oy-'] + + def configure_linux(self, cxx): + cxx.defines += ['_LINUX', 'POSIX'] + cxx.linkflags += ['-lm'] + if cxx.vendor == 'gcc': + cxx.linkflags += ['-static-libgcc'] + elif cxx.vendor == 'clang': + cxx.linkflags += ['-lgcc_eh'] + + def configure_mac(self, cxx): + cxx.defines += ['OSX', '_OSX', 'POSIX'] + cxx.cflags += ['-mmacosx-version-min=10.5'] + cxx.linkflags += [ + '-mmacosx-version-min=10.5', + '-arch', 'i386', + '-lstdc++', + '-stdlib=libstdc++', + ] + cxx.cxxflags += ['-stdlib=libstdc++'] + + def configure_windows(self, cxx): + cxx.defines += ['WIN32', '_WINDOWS'] + + def ConfigureForExtension(self, context, compiler): + compiler.cxxincludes += [ + os.path.join(context.currentSourcePath), + ] + return compiler + + def ConfigureForHL2(self, binary, sdk): + compiler = binary.compiler + + if sdk.name == 'episode1': + mms_path = os.path.join(self.mms_root, 'core-legacy') + else: + mms_path = os.path.join(self.mms_root, 'core') + + compiler.cxxincludes += [ + os.path.join(mms_path), + os.path.join(mms_path, 'sourcehook'), + ] + + defines = ['SE_' + PossibleSDKs[i].define + '=' + PossibleSDKs[i].code for i in PossibleSDKs] + compiler.defines += defines + + paths = [ + ['public'], + ['public', 'engine'], + ['public', 'mathlib'], + ['public', 'vstdlib'], + ['public', 'tier0'], + ['public', 'tier1'] + ] + if sdk.name == 'episode1' or sdk.name == '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']) + + compiler.defines += ['SOURCE_ENGINE=' + sdk.code] + + if sdk.name in ['sdk2013', 'bms'] and compiler.like('gcc'): + # The 2013 SDK already has these in public/tier0/basetypes.h + compiler.defines.remove('stricmp=strcasecmp') + compiler.defines.remove('_stricmp=strcasecmp') + compiler.defines.remove('_snprintf=snprintf') + compiler.defines.remove('_vsnprintf=vsnprintf') + + if compiler.like('msvc'): + compiler.defines += ['COMPILER_MSVC', 'COMPILER_MSVC32'] + compiler.linkflags += ['legacy_stdio_definitions.lib'] + else: + compiler.defines += ['COMPILER_GCC'] + + # For everything after Swarm, this needs to be defined for entity networking + # to work properly with sendprop value changes. + if sdk.name in ['blade', 'insurgency', 'csgo', 'dota']: + compiler.defines += ['NETWORK_VARS_ENABLED'] + + if sdk.name in ['css', 'hl2dm', 'dods', 'sdk2013', 'bms', 'tf2', 'l4d', 'nucleardawn', 'l4d2', 'dota']: + if builder.target_platform in ['linux', 'mac']: + compiler.defines += ['NO_HOOK_MALLOC', 'NO_MALLOC_OVERRIDE'] + + if sdk.name == 'csgo' and builder.target_platform == 'linux': + compiler.linkflags += ['-lstdc++'] + + for path in paths: + compiler.cxxincludes += [os.path.join(sdk.path, *path)] + + if builder.target_platform == 'linux': + if sdk.name == 'episode1': + lib_folder = os.path.join(sdk.path, 'linux_sdk') + elif sdk.name in ['sdk2013', 'bms']: + lib_folder = os.path.join(sdk.path, 'lib', 'public', 'linux32') + else: + lib_folder = os.path.join(sdk.path, 'lib', 'linux') + elif builder.target_platform == 'mac': + if sdk.name in ['sdk2013', 'bms']: + lib_folder = os.path.join(sdk.path, 'lib', 'public', 'osx32') + else: + lib_folder = os.path.join(sdk.path, 'lib', 'mac') + + if builder.target_platform in ['linux', 'mac']: + if sdk.name in ['sdk2013', 'bms']: + compiler.postlink += [ + compiler.Dep(os.path.join(lib_folder, 'tier1.a')), + compiler.Dep(os.path.join(lib_folder, 'mathlib.a')) + ] + else: + compiler.postlink += [ + compiler.Dep(os.path.join(lib_folder, 'tier1_i486.a')), + compiler.Dep(os.path.join(lib_folder, 'mathlib_i486.a')) + ] + + if sdk.name in ['blade', 'insurgency', 'csgo', 'dota']: + compiler.postlink += [compiler.Dep(os.path.join(lib_folder, 'interfaces_i486.a'))] + + dynamic_libs = [] + if builder.target_platform == 'linux': + if sdk.name in ['css', 'hl2dm', 'dods', 'tf2', 'sdk2013', 'bms', 'nucleardawn', 'l4d2', 'insurgency']: + dynamic_libs = ['libtier0_srv.so', 'libvstdlib_srv.so'] + elif sdk.name in ['l4d', 'blade', 'insurgency', 'csgo', 'dota']: + dynamic_libs = ['libtier0.so', 'libvstdlib.so'] + else: + dynamic_libs = ['tier0_i486.so', 'vstdlib_i486.so'] + elif builder.target_platform == 'mac': + compiler.linkflags.append('-liconv') + dynamic_libs = ['libtier0.dylib', 'libvstdlib.dylib'] + elif builder.target_platform == 'windows': + libs = ['tier0', 'tier1', 'vstdlib', 'mathlib'] + if sdk.name in ['swarm', 'blade', 'insurgency', 'csgo', 'dota']: + libs.append('interfaces') + for lib in libs: + lib_path = os.path.join(sdk.path, 'lib', 'public', lib) + '.lib' + compiler.linkflags.append(compiler.Dep(lib_path)) + + for library in dynamic_libs: + source_path = os.path.join(lib_folder, library) + output_path = os.path.join(binary.localFolder, library) + + def make_linker(source_path, output_path): + def link(context, binary): + cmd_node, (output,) = context.AddSymlink(source_path, output_path) + return output + return link + + linker = make_linker(source_path, output_path) + compiler.linkflags[0:0] = [compiler.Dep(library, linker)] + + return binary + + def HL2Library(self, context, name, sdk): + binary = context.compiler.Library(name) + self.ConfigureForExtension(context, binary.compiler) + return self.ConfigureForHL2(binary, sdk) + + def HL2Project(self, context, name): + project = context.compiler.LibraryProject(name) + self.ConfigureForExtension(context, project.compiler) + return project + + def HL2Config(self, project, name, sdk): + binary = project.Configure(name, '{0} - {1}'.format(self.tag, sdk.name)) + return self.ConfigureForHL2(binary, sdk) + +Extension = ExtensionConfig() +Extension.detectSDKs() +Extension.configure() + +# Add additional buildscripts here +BuildScripts = [ + 'AMBuilder', +] + +if builder.backend == 'amb2': + BuildScripts += [ + 'PackageScript', + ] + +builder.RunBuildScripts(BuildScripts, { 'Extension': Extension}) diff --git a/AMBuilder b/AMBuilder new file mode 100644 index 0000000..cdf485c --- /dev/null +++ b/AMBuilder @@ -0,0 +1,23 @@ +# vim: set sts=2 ts=8 sw=2 tw=99 et ft=python: +projectName = 'l4dtoolz' + +# smsdk_ext.cpp will be automatically added later +sourceFiles = [ + 'l4dtoolz_mm.cpp', + 'signature.cpp', +] + +############### +# Make sure to edit PackageScript, which copies your files to their appropriate locations +# Simple extensions do not need to modify past this point. + +project = Extension.HL2Project(builder, projectName) + +project.sources += sourceFiles + +for sdk_name in Extension.sdks: + sdk = Extension.sdks[sdk_name] + + binary = Extension.HL2Config(project, projectName + sdk.ext, sdk) + +Extension.extensions = builder.Add(project) diff --git a/Makefile_l4d b/Makefile_l4d index 10e203d..0d4c92e 100644 --- a/Makefile_l4d +++ b/Makefile_l4d @@ -15,8 +15,7 @@ HX_INCLUDE = -I. \ -I$(HX_SDK)/public/mathlib # -HX_FLAGS = -DSOURCE_ENGINE=8 \ - -DL4D1 +HX_FLAGS = -DSOURCE_ENGINE=8 # HX_FLAGS += -DSE_EPISODEONE=1 \ diff --git a/PackageScript b/PackageScript new file mode 100644 index 0000000..8191d6c --- /dev/null +++ b/PackageScript @@ -0,0 +1,36 @@ +# vim: set ts=8 sts=2 sw=2 tw=99 et ft=python: +import os + +# This is where the files will be output to +# package is the default +builder.SetBuildFolder('package') + +# Add any folders you need to this list +folder_list = [ + 'addons/l4dtoolz', + 'addons/metamod', +] + +# Create the distribution folder hierarchy. +folder_map = {} +for folder in folder_list: + norm_folder = os.path.normpath(folder) + folder_map[folder] = builder.AddFolder(norm_folder) + +# Do all straight-up file copies from the source tree. +def CopyFiles(src, dest, files): + if not dest: + dest = src + dest_entry = folder_map[dest] + for source_file in files: + source_path = os.path.join(builder.sourcePath, src, source_file) + builder.AddCopy(source_path, dest_entry) + +# Copy binaries. +for cxx_task in Extension.extensions: + builder.AddCopy(cxx_task.binary, folder_map['addons/l4dtoolz']) + +# VDF file +CopyFiles('', 'addons/metamod', + [ 'l4dtoolz.vdf' ] +) diff --git a/configure.py b/configure.py new file mode 100644 index 0000000..c4ecfcc --- /dev/null +++ b/configure.py @@ -0,0 +1,21 @@ +# vim: set sts=2 ts=8 sw=2 tw=99 et: +import sys +from ambuild2 import run + +# Simple extensions do not need to modify this file. + +builder = run.PrepareBuild(sourcePath = sys.path[0]) + +builder.options.add_option('--hl2sdk-root', type=str, dest='hl2sdk_root', default=None, + help='Root search folder for HL2SDKs') +builder.options.add_option('--mms-path', type=str, dest='mms_path', default=None, + help='Path to Metamod:Source') +builder.options.add_option('--enable-debug', action='store_const', const='1', dest='debug', + help='Enable debugging symbols') +builder.options.add_option('--enable-optimize', action='store_const', const='1', dest='opt', + help='Enable optimization') +builder.options.add_option('-s', '--sdks', default='all', dest='sdks', + help='Build against specified SDKs; valid args are "all", "present", or ' + 'comma-delimited list of engine names (default: %default)') + +builder.Configure() diff --git a/game_signature.h b/game_signature.h index d697d02..f9c6dec 100644 --- a/game_signature.h +++ b/game_signature.h @@ -2,13 +2,13 @@ #define _INCLUDE_GAME_SIGNATURE_ #ifdef WIN32 -#ifdef L4D1 +#if SOURCE_ENGINE == SE_LEFT4DEAD #include "l4d1_signature_win32.h" #else #include "l4d2_signature_win32.h" #endif #else -#ifdef L4D1 +#if SOURCE_ENGINE == SE_LEFT4DEAD #include "l4d1_signature_linux.h" #else #include "l4d2_signature_linux.h" diff --git a/l4d1_signature_linux.h b/l4d1_signature_linux.h index e8f99bb..1415f84 100644 --- a/l4d1_signature_linux.h +++ b/l4d1_signature_linux.h @@ -12,13 +12,13 @@ unsigned char friends_lobby_new[] = {0x06, 0x00, 0xB8, 0x3C, 0x00, 0x00, 0x00, 0 void* friends_lobby_org = NULL; //CBaseServer::ConnectClient(netadr_s &, int, int, int, char const*, char const*, char const*, int, CUtlVector> &, bool) -//fuction is in engine.so +//fuction is in engine.so, loc jz/jnz, above #Valve_Reject_Hidden_Game const char* lobby_sux = "\x0A\x8B\x86\x78\x01\x00\x00\x85\xC0\x0F\x85"; const char* lobby_sux_new = "\x06\x00\xB8\x01\x00\x00\x00\x90"; void* lobby_sux_org = NULL; //CBaseServer::ConnectClient(netadr_s &, int, int, int, char const*, char const*, char const*, int, CUtlVector> &, bool) -//fuction is in engine.so +//fuction is in engine.so, above #Valve_Reject_Server_Full const char* max_players = "\x0F\xFF\x50\xC3\x29\xC7\x01\xEF\x3B\xC3\xC3\xC3\x00\x00\x0F\x8E"; unsigned char max_players_new[]= {0x06, 0x07, 0x83, 0xFF, 0x3C, 0x90, 0x90, 0x90}; void* max_players_org = NULL; @@ -35,22 +35,20 @@ const char* human_limit = "\x12\x8B\x54\xC3\xC3\x8B\x02\x89\x14\xC3\xFF\x90\xC3\ const char* human_limit_new = "\x02\x11\x90\x90"; void* human_limit_org = NULL; -//_ZL10maxplayersRK8CCommand +//CGameServer::SetMaxClients(int) //fuction is in engine.so const char* players = "\x13\x83\xBB\xC3\xC3\xC3\xC3\x01\x7F\xC3\x8B\x80\x0C\xC3\xC3\x00\x89\xC3\xC3\xE8"; -const char* players_new = "\x02\x07\x90\x90"; +const char* players_new = "\x03\x1D\x89\xC2\xEB"; void* players_org = NULL; -const char* players2 = "\x13\x83\xBB\xC3\xC3\xC3\xC3\x01\x7F\xC3\x8B\x80\x0C\xC3\xC3\x00\x89\xC3\xC3\xE8"; -const char* players_new2 = "\x03\x1D\x89\xC2\xEB"; -void* players_org2 = NULL; - //CBaseServer::SetReservationCookie(unsigned long long, char const*, ...) //function in engine.so const char* unreserved = "\x1F\x55\x57\x56\x53\x81\xEC\xC3\xC3\x00\x00\xE8\xC3\xC3\xC3\xC3\x81\xC3\xC3\xC3\xC3\xC3\x8B\xB4\x24\x60\x01\x00\x00\x8B\xAC\x24"; const char* unreserved_new = "\x01\x00\xC3"; void* unreserved_org = NULL; +//CMatchTitle::GetTotalNumPlayersSupported(void) +//function in matchmaking_ds.so const char* lobby_match = "\x06\xB8\x08\x00\x00\x00\xC3"; unsigned char lobby_match_new[] = {0x01, 0x02, 0xC3}; void* lobby_match_org = NULL; diff --git a/l4d1_signature_win32.h b/l4d1_signature_win32.h index 778b0f4..681920c 100644 --- a/l4d1_signature_win32.h +++ b/l4d1_signature_win32.h @@ -24,14 +24,10 @@ const char* human_limit = "\x15\x8B\x13\x8B\x82\xC3\xC3\x00\x00\x8B\xCB\xFF\xD0\ const char* human_limit_new = "\x01\x0E\xEB"; void* human_limit_org = NULL; -const char* players = "\x15\x83\x3D\xC3\xC3\xC3\xC3\x02\x7C\xC3\x83\xC4\x08\xC7\x44\xC3\xC3\xC3\xC3\xC3\xC3\xFF"; -const char* players_new = "\x01\x07\xEB"; +const char* players = "\x10\x56\x8B\xF1\x8B\x86\xC3\x02\x00\x00\x8B\x4C\x24\x08\x3B\xC8\x7F"; +const char* players_new = "\x02\x0F\x90\x90"; void* players_org = NULL; -const char* players2 = "\x10\x56\x8B\xF1\x8B\x86\xC3\x02\x00\x00\x8B\x4C\x24\x08\x3B\xC8\x7F"; -const char* players_new2 = "\x02\x0F\x90\x90"; -void* players_org2 = NULL; - const char* unreserved = "\x1E\x81\xEC\xC3\xC3\x00\x00\x55\x8B\xAC\xC3\xC3\xC3\x00\x00\x56\x8B\xB4\xC3\xC3\xC3\x00\x00\x57\x8B\xBC\xC3\xC3\xC3\x00\x00"; const char* unreserved_new = "\x01\x00\xC3"; void* unreserved_org = NULL; diff --git a/l4d2_signature_linux.h b/l4d2_signature_linux.h index 19f1276..197a78e 100644 --- a/l4d2_signature_linux.h +++ b/l4d2_signature_linux.h @@ -17,14 +17,10 @@ const char* server_bplayers = "\x16\x55\x89\xE5\x83\xEC\x08\xE8\xC3\xC3\xC3\xC3\ unsigned char server_bplayers_new[] = {0x06, 0x00, 0xB8, 0x3C, 0x00, 0x00, 0x00, 0xC3}; void *server_bplayers_org = NULL; -const char* players = "\x13\x83\x3D\xC3\xC3\xC3\xC3\x01\x7F\xC3\x8B\x80\xC3\xC3\x00\x00\x89\x04\x24\xE8"; -const char* players_new = "\x02\x07\x90\x90"; +const char* players = "\x23\x55\x89\xE5\x53\x83\xEC\xC3\x8B\x5D\x08\x8B\x55\x0C\x8B\x83\xC3\xC3\x00\x00\x39\xD0\x7C\x0B\x8B\x83\xC3\xC3\x00\x00\x39\xC2\x0F\x4D\xC2\x8B"; +const char* players_new = "\x01\x13\x89\xD0\xEB"; void *players_org = NULL; -const char* players2 = "\x23\x55\x89\xE5\x53\x83\xEC\xC3\x8B\x5D\x08\x8B\x55\x0C\x8B\x83\xC3\xC3\x00\x00\x39\xD0\x7C\x0B\x8B\x83\xC3\xC3\x00\x00\x39\xC2\x0F\x4D\xC2\x8B"; -const char* players_new2 = "\x01\x13\x89\xD0\xEB"; -void *players_org2 = NULL; - const char* unreserved = "\x0F\x55\x89\xE5\x57\x56\x53\x81\xEC\x3C\x01\x00\x00\x8B\x5D\x08"; const char* unreserved_new = "\x01\x00\xC3"; void *unreserved_org = NULL; diff --git a/l4d2_signature_win32.h b/l4d2_signature_win32.h index 7ef0bdb..f879e4c 100644 --- a/l4d2_signature_win32.h +++ b/l4d2_signature_win32.h @@ -1,36 +1,32 @@ -#ifndef _INCLUDE_L4D2_SIGNATURE_WIN32_ -#define _INCLUDE_L4D2_SIGNATURE_WIN32_ - -const char* server_dll[] = {"server.dll", 0}; -const char* engine_dll[] = {"engine.dll", 0}; -const char* matchmaking_dll[] = {"matchmaking_ds.dll", "matchmaking.dll", 0}; - -const char* max_players = "\x27\x83\xBE\xC3\xC3\x00\x00\x00\x74\xC3\x8B\xC3\xC3\x8B\x06\x8B\x7A\xC3\x8B\x50\x10\x8B\xCE\xFF\xD2\x2B\xF8\x8B\x06\x8B\x50\x08\x8B\xCE\xFF\xD2\x03\xC7\x3B\x86"; -unsigned char max_players_new[]= {0x06, 0x25, 0x83, 0xF8, 0x3C, 0x90, 0x90, 0x90}; -void* max_players_org = NULL; - -const char* lobby_sux_new = "\x02\x07\x90\x90"; -void* lobby_sux_org = NULL; - +#ifndef _INCLUDE_L4D2_SIGNATURE_WIN32_ +#define _INCLUDE_L4D2_SIGNATURE_WIN32_ + +const char* server_dll[] = {"server.dll", 0}; +const char* engine_dll[] = {"engine.dll", 0}; +const char* matchmaking_dll[] = {"matchmaking_ds.dll", "matchmaking.dll", 0}; + +const char* max_players = "\x27\x83\xBE\xC3\xC3\x00\x00\x00\x74\xC3\x8B\xC3\xC3\x8B\x06\x8B\x7A\xC3\x8B\x50\x10\x8B\xCE\xFF\xD2\x2B\xF8\x8B\x06\x8B\x50\x08\x8B\xCE\xFF\xD2\x03\xC7\x3B\x86"; +unsigned char max_players_new[]= {0x06, 0x25, 0x83, 0xF8, 0x3C, 0x90, 0x90, 0x90}; +void* max_players_org = NULL; + +const char* lobby_sux_new = "\x02\x07\x90\x90"; +void* lobby_sux_org = NULL; + const char* server_bplayers = "\x36\xF7\x05\xC3\xC3\xC3\xC3\x00\x10\x00\x00\x74\x07\xB8\xC3\xC3\xC3\xC3\xEB\x11\xA1\xC3\xC3\xC3\xC3\x8B\x40\x24\x85\xC0\x75\x05\xB8\xC3\xC3\xC3\xC3\x8B\x0D\xC3\xC3\xC3\xC3\x8B\x11\x50\x8B\x42\x10\xFF\xD0\x85\xC0\x74\x17"; -unsigned char server_bplayers_new[] = {0x06, 0x00, 0xB8, 0x3C, 0x00, 0x00, 0x00, 0xC3}; -void* server_bplayers_org = NULL; - -const char* players = "\x15\x83\x3D\xC3\xC3\xC3\xC3\x02\x7C\xC3\x68\xC3\xC3\xC3\xC3\xFF\x15\xC3\xC3\xC3\xC3\x83"; -const char* players_new = "\x01\x07\xEB"; -void* players_org = NULL; - -const char* players2 = "\x0F\x56\x8B\xF1\x8B\x86\xC3\x02\x00\x00\x8B\x4D\xC3\x3B\xC8\x7F"; -const char* players_new2 = "\x02\x0E\x90\x90"; -void* players_org2 = NULL; - -const char* unreserved = "\x21\x55\x8B\xEC\x81\xEC\xC3\xC3\x00\x00\xA1\xC3\xC3\xC3\xC3\x33\xC5\x89\xC3\xC3\x53\x8B\xC3\xC3\x56\x8B\xC3\xC3\x57\x8B\xC3\xC3\x3B\xBE"; -const char* unreserved_new = "\x01\x00\xC3"; -void* unreserved_org = NULL; - -const char* lobby_match = "\x06\xB8\x08\x00\x00\x00\xC3"; -unsigned char lobby_match_new[] = {0x01, 0x01, 0xC3}; -void* lobby_match_org = NULL; - -#endif //_INCLUDE_L4D2_SIGNATURE_WIN32_ - +unsigned char server_bplayers_new[] = {0x06, 0x00, 0xB8, 0x3C, 0x00, 0x00, 0x00, 0xC3}; +void* server_bplayers_org = NULL; + +const char* players = "\x0F\x56\x8B\xF1\x8B\x86\xC3\x02\x00\x00\x8B\x4D\xC3\x3B\xC8\x7F"; +const char* players_new = "\x02\x0E\x90\x90"; +void* players_org = NULL; + +const char* unreserved = "\x21\x55\x8B\xEC\x81\xEC\xC3\xC3\x00\x00\xA1\xC3\xC3\xC3\xC3\x33\xC5\x89\xC3\xC3\x53\x8B\xC3\xC3\x56\x8B\xC3\xC3\x57\x8B\xC3\xC3\x3B\xBE"; +const char* unreserved_new = "\x01\x00\xC3"; +void* unreserved_org = NULL; + +const char* lobby_match = "\x06\xB8\x08\x00\x00\x00\xC3"; +unsigned char lobby_match_new[] = {0x01, 0x01, 0xC3}; +void* lobby_match_org = NULL; + +#endif //_INCLUDE_L4D2_SIGNATURE_WIN32_ + diff --git a/l4dtoolz.vdf b/l4dtoolz.vdf new file mode 100644 index 0000000..5dce052 --- /dev/null +++ b/l4dtoolz.vdf @@ -0,0 +1,5 @@ +"Metamod Plugin" +{ + "alias" "l4dtoolz" + "file" "addons/l4dtoolz/l4dtoolz_mm" +} diff --git a/l4dtoolz_mm.cpp b/l4dtoolz_mm.cpp index e2a09ad..c7a235e 100644 --- a/l4dtoolz_mm.cpp +++ b/l4dtoolz_mm.cpp @@ -4,10 +4,9 @@ l4dtoolz g_l4dtoolz; IVEngineServer* engine = NULL; -IServerPluginCallbacks* vsp_callbacks = NULL; -ICvar* icvar = NULL; +ICvar* g_pCVar = NULL; -#ifdef L4D1 +#if SOURCE_ENGINE == SE_LEFT4DEAD void* l4dtoolz::max_players_friend_lobby = NULL; void* l4dtoolz::chuman_limit = NULL; #endif @@ -16,33 +15,31 @@ void* l4dtoolz::max_players_connect = NULL; void* l4dtoolz::max_players_server_browser = NULL; void* l4dtoolz::lobby_sux_ptr = NULL; void* l4dtoolz::tmp_player = NULL; -void* l4dtoolz::tmp_player2 = NULL; void* l4dtoolz::unreserved_ptr = NULL; void* l4dtoolz::lobby_match_ptr = NULL; ConVar sv_maxplayers("sv_maxplayers", "-1", 0, "Max Human Players", true, -1, true, 32, l4dtoolz::OnChangeMaxplayers); -#ifdef L4D1 +#if SOURCE_ENGINE == SE_LEFT4DEAD ConVar sv_removehumanlimit("sv_removehumanlimit", "0", 0, "Remove Human limit reached kick", true, 0, true, 1, l4dtoolz::OnChangeRemovehumanlimit); #endif -ConVar L4DToolZ("L4DToolZ", "",0,"L4DToolZ Author",l4dtoolz::OnChangeIvailosp); ConVar sv_force_unreserved("sv_force_unreserved", "0", 0, "Disallow lobby reservation cookie", true, 0, true, 1, l4dtoolz::OnChangeUnreserved); void l4dtoolz::OnChangeMaxplayers ( IConVar *var, const char *pOldValue, float flOldValue ) { int new_value = ((ConVar*)var)->GetInt(); int old_value = atoi(pOldValue); -#ifdef L4D1 +#if SOURCE_ENGINE == SE_LEFT4DEAD if (max_players_friend_lobby == NULL || max_players_connect == NULL || max_players_server_browser == NULL || lobby_sux_ptr == NULL) { #else if (max_players_connect == NULL || max_players_server_browser == NULL || lobby_sux_ptr == NULL) { #endif - Msg("sv_maxplayers init error\n"); + Msg("sv_maxplayers init error\n"); return; } if(new_value != old_value) { if(new_value >= 0) { -#ifdef L4D1 - max_players_new[4] = friends_lobby_new[3] = server_bplayers_new[3] = new_value; +#if SOURCE_ENGINE == SE_LEFT4DEAD + max_players_new[4] = friends_lobby_new[3] = server_bplayers_new[3] = (unsigned char)new_value; #else max_players_new[4] = server_bplayers_new[3] = (unsigned char)new_value; #endif @@ -52,14 +49,14 @@ void l4dtoolz::OnChangeMaxplayers ( IConVar *var, const char *pOldValue, float f } else { Msg("sv_maxplayers MS init error\n"); } -#ifdef L4D1 +#if SOURCE_ENGINE == SE_LEFT4DEAD write_signature(max_players_friend_lobby, friends_lobby_new); #endif write_signature(max_players_connect, max_players_new); write_signature(lobby_sux_ptr, lobby_sux_new); write_signature(max_players_server_browser, server_bplayers_new); } else { -#ifdef L4D1 +#if SOURCE_ENGINE == SE_LEFT4DEAD write_signature(max_players_friend_lobby, friends_lobby_org); #endif write_signature(max_players_connect, max_players_org); @@ -72,7 +69,7 @@ void l4dtoolz::OnChangeMaxplayers ( IConVar *var, const char *pOldValue, float f } } -#ifdef L4D1 +#if SOURCE_ENGINE == SE_LEFT4DEAD void l4dtoolz::OnChangeRemovehumanlimit ( IConVar *var, const char *pOldValue, float flOldValue ) { int new_value = ((ConVar*)var)->GetInt(); @@ -91,19 +88,6 @@ void l4dtoolz::OnChangeRemovehumanlimit ( IConVar *var, const char *pOldValue, f } #endif -void l4dtoolz::OnChangeIvailosp ( IConVar *var, const char *pOldValue, float flOldValue ) -{ - if(tmp_player == NULL || tmp_player2 == NULL) { - return; - } - write_signature(tmp_player, players_org); - free(players_org); - players_org = NULL; - write_signature(tmp_player2, players_org2); - free(players_org2); - players_org2 = NULL; -} - void l4dtoolz::OnChangeUnreserved ( IConVar *var, const char *pOldValue, float flOldValue ) { int new_value = ((ConVar*)var)->GetInt(); @@ -115,52 +99,23 @@ void l4dtoolz::OnChangeUnreserved ( IConVar *var, const char *pOldValue, float f if(new_value != old_value) { if(new_value == 1) { write_signature(unreserved_ptr, unreserved_new); - engine->ServerCommand("sv_allow_lobby_connect_only 0\n"); + engine->ServerCommand("sv_allow_lobby_connect_only 0"); } else { write_signature(unreserved_ptr, unreserved_org); } } } -class BaseAccessor : public IConCommandBaseAccessor -{ -public: - bool RegisterConCommandBase(ConCommandBase *pCommandBase) - { - return META_REGCVAR(pCommandBase); - } -} s_BaseAccessor; - PLUGIN_EXPOSE(l4dtoolz, g_l4dtoolz); bool l4dtoolz::Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen, bool late) { - PLUGIN_SAVEVARS(); GET_V_IFACE_CURRENT(GetEngineFactory, engine, IVEngineServer, INTERFACEVERSION_VENGINESERVER); - GET_V_IFACE_CURRENT(GetEngineFactory, icvar, ICvar, CVAR_INTERFACE_VERSION); + GET_V_IFACE_CURRENT(GetEngineFactory, g_pCVar, ICvar, CVAR_INTERFACE_VERSION); - -#if defined METAMOD_PLAPI_VERSION - if ((vsp_callbacks = ismm->GetVSPInfo(NULL)) == NULL) -#endif - { - ismm->AddListener(this, this); - ismm->EnableVSPListener(); - } - - -#if !defined METAMOD_PLAPI_VERSION - m_EngineCC = SH_GET_CALLCLASS(engine); -#endif - -#if SOURCE_ENGINE >= SE_ORANGEBOX - g_pCVar = icvar; - ConVar_Register(0, &s_BaseAccessor); -#else - ConCommandBaseMgr::OneTimeInit(&s_BaseAccessor); -#endif + ConVar_Register(0, this); struct base_addr_t base_addr; base_addr.addr = NULL; @@ -174,7 +129,7 @@ bool l4dtoolz::Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen, bool } find_base_from_list(engine_dll, &base_addr); -#ifdef L4D1 +#if SOURCE_ENGINE == SE_LEFT4DEAD if(!max_players_friend_lobby) { max_players_friend_lobby = find_signature(friends_lobby, &base_addr, 0); get_original_signature(max_players_friend_lobby, friends_lobby_new, friends_lobby_org); @@ -185,7 +140,6 @@ bool l4dtoolz::Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen, bool get_original_signature(max_players_connect, max_players_new, max_players_org); } if(!lobby_sux_ptr) { - #ifdef WIN32 lobby_sux_ptr = max_players_connect; #else @@ -193,7 +147,7 @@ bool l4dtoolz::Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen, bool #endif get_original_signature(lobby_sux_ptr, lobby_sux_new, lobby_sux_org); } -#ifdef L4D1 +#if SOURCE_ENGINE == SE_LEFT4DEAD #ifdef WIN32 if(!max_players_server_browser) { max_players_server_browser = find_signature(server_bplayers, &base_addr, 0); @@ -204,15 +158,13 @@ bool l4dtoolz::Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen, bool if(!tmp_player) { tmp_player = find_signature(players, &base_addr, 0); if(tmp_player) { - tmp_player2 = find_signature(players2, &base_addr, 0); - if(tmp_player2) { - get_original_signature(tmp_player, players_new, players_org); - write_signature(tmp_player, players_new); - get_original_signature(tmp_player2, players_new2, players_org2); - write_signature(tmp_player2, players_new2); - engine->ServerCommand("maxplayers 32\n"); - engine->ServerCommand("L4DToolZ ivailosp@abv.bg\n"); - } + get_original_signature(tmp_player, players_new, players_org); + write_signature(tmp_player, players_new); + engine->ServerCommand("maxplayers 32"); + engine->ServerExecute(); + write_signature(tmp_player, players_org); + free(players_org); + players_org = NULL; } } if(!unreserved_ptr) { @@ -221,7 +173,7 @@ bool l4dtoolz::Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen, bool } find_base_from_list(server_dll, &base_addr); -#ifdef L4D1 +#if SOURCE_ENGINE == SE_LEFT4DEAD if(!chuman_limit) { chuman_limit = find_signature(human_limit, &base_addr, 0); get_original_signature(chuman_limit, human_limit_new, human_limit_org); @@ -244,12 +196,7 @@ bool l4dtoolz::Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen, bool bool l4dtoolz::Unload(char *error, size_t maxlen) { - -#if !defined METAMOD_PLAPI_VERSION - SH_RELEASE_CALLCLASS(m_EngineCC); -#endif - -#ifdef L4D1 +#if SOURCE_ENGINE == SE_LEFT4DEAD write_signature(max_players_friend_lobby, friends_lobby_org); write_signature(chuman_limit, human_limit_org); free(friends_lobby_org); @@ -271,34 +218,14 @@ bool l4dtoolz::Unload(char *error, size_t maxlen) return true; } -void l4dtoolz::OnVSPListening(IServerPluginCallbacks *iface) -{ - vsp_callbacks = iface; -} - - -bool l4dtoolz::Pause(char *error, size_t maxlen) -{ - return true; -} - -bool l4dtoolz::Unpause(char *error, size_t maxlen) -{ - return true; -} - const char *l4dtoolz::GetLicense() { - return ""; + return "GPLv3"; } const char *l4dtoolz::GetVersion() { -#ifdef __GIT_VERSION - return __GIT_VERSION; -#else - return "1.0.0.9r1"; -#endif + return "1.1.0.0"; } const char *l4dtoolz::GetDate() @@ -313,12 +240,12 @@ const char *l4dtoolz::GetLogTag() const char *l4dtoolz::GetAuthor() { - return "Ivailosp"; + return "Accelerator, Ivailosp"; } const char *l4dtoolz::GetDescription() { - return "Ivailosp plugin"; + return "Unlock the max player limit on L4D and L4D2"; } const char *l4dtoolz::GetName() @@ -328,5 +255,10 @@ const char *l4dtoolz::GetName() const char *l4dtoolz::GetURL() { - return "n/a"; + return "https://github.com/Accelerator74/l4dtoolz"; +} + +bool l4dtoolz::RegisterConCommandBase(ConCommandBase *pVar) +{ + return META_REGCVAR(pVar); } diff --git a/l4dtoolz_mm.h b/l4dtoolz_mm.h index 4431d07..b8712c6 100644 --- a/l4dtoolz_mm.h +++ b/l4dtoolz_mm.h @@ -3,15 +3,11 @@ #include -class l4dtoolz : public ISmmPlugin, public IMetamodListener +class l4dtoolz : public ISmmPlugin, public IConCommandBaseAccessor { public: bool Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen, bool late); bool Unload(char *error, size_t maxlen); - bool Pause(char *error, size_t maxlen); - bool Unpause(char *error, size_t maxlen); - - void OnVSPListening(IServerPluginCallbacks *iface); public: const char *GetAuthor(); const char *GetName(); @@ -21,13 +17,15 @@ public: const char *GetVersion(); const char *GetDate(); const char *GetLogTag(); +public: //IConCommandBaseAccessor + bool RegisterConCommandBase(ConCommandBase *pVar); public: static void OnChangeMaxplayers ( IConVar *var, const char *pOldValue, float flOldValue ); static void OnChangeUnreserved ( IConVar *var, const char *pOldValue, float flOldValue ); static void OnChangeIvailosp ( IConVar *var, const char *pOldValue, float flOldValue ); -#ifdef L4D1 +#if SOURCE_ENGINE == SE_LEFT4DEAD static void OnChangeRemovehumanlimit ( IConVar *var, const char *pOldValue, float flOldValue ); static void* max_players_friend_lobby; static void* chuman_limit; @@ -37,17 +35,10 @@ public: static void* max_players_server_browser; static void* lobby_sux_ptr; static void* tmp_player; - static void* tmp_player2; static void* unreserved_ptr; static void* lobby_match_ptr; -private: - -#if !defined METAMOD_PLAPI_VERSION - SourceHook::CallClass *m_EngineCC; -#endif }; - extern l4dtoolz g_l4dtoolz; PLUGIN_GLOBALVARS(); diff --git a/signature.cpp b/signature.cpp index 1a731cc..611325c 100644 --- a/signature.cpp +++ b/signature.cpp @@ -12,7 +12,7 @@ #include #endif -#define SIGN_HEADER_LEN 2 +#define SIGN_HEADER_LEN 2 #define SIGN_LEN_BYTE 0 #define SIGN_OFFSET_BYTE 1 @@ -121,7 +121,6 @@ static int callback(struct dl_phdr_info *info, size_t size, void *data) int find_base(const char* name, struct base_addr_t *base_addr) { #ifdef WIN32 -/* HANDLE hModuleSnap = INVALID_HANDLE_VALUE; */ MODULEENTRY32 modent; HANDLE hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0); if(hModuleSnap == INVALID_HANDLE_VALUE) { @@ -196,12 +195,11 @@ int write_signature(const void* addr, const void* signature) WriteProcessMemory(h_process, (void *)(u_addr+sign_off), (void *)(u_addr_sign+SIGN_HEADER_LEN), sign_len, NULL); CloseHandle(h_process); #else - lock_region(addr, sign_len, sign_off, 1); memcpy((void *)(u_addr+sign_off), (void *)(u_addr_sign+SIGN_HEADER_LEN), sign_len); lock_region(addr, sign_len, sign_off, 0); - #endif + return 1; } @@ -226,6 +224,7 @@ int read_signature(const void *addr, void *signature) memcpy((void *)(u_addr_sign+SIGN_HEADER_LEN), (void *)(u_addr+sign_off), sign_len); lock_region(addr, sign_len, sign_off, 0); #endif + return 0; }