mirror of
https://github.com/alliedmodders/metamod-source.git
synced 2025-12-09 11:28:33 +00:00
Add s2_sample_mm & Move samples to a sub folder
This commit is contained in:
parent
0807f197cc
commit
339d8a90c8
526
samples/s2_sample_mm/AMBuildScript
Normal file
526
samples/s2_sample_mm/AMBuildScript
Normal file
@ -0,0 +1,526 @@
|
|||||||
|
# vim: set sts=2 ts=8 sw=2 tw=99 et ft=python:
|
||||||
|
import os, sys
|
||||||
|
|
||||||
|
additional_libs = [
|
||||||
|
# Path should be relative either to hl2sdk folder or to build folder
|
||||||
|
#'path/to/lib/example.lib',
|
||||||
|
]
|
||||||
|
|
||||||
|
additional_defines = [
|
||||||
|
#'EXAMPLE_DEFINE=2'
|
||||||
|
]
|
||||||
|
|
||||||
|
additional_includes = [
|
||||||
|
# Path should be absolute only!
|
||||||
|
#'D:/absolute/path/to/include/folder/'
|
||||||
|
]
|
||||||
|
|
||||||
|
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.name = dir
|
||||||
|
self.path = None # Actual path
|
||||||
|
self.platformSpec = platform
|
||||||
|
|
||||||
|
# By default, nothing supports x64.
|
||||||
|
if type(platform) is list:
|
||||||
|
self.platformSpec = {p: ['x86'] for p in platform}
|
||||||
|
else:
|
||||||
|
self.platformSpec = platform
|
||||||
|
|
||||||
|
def shouldBuild(self, targets):
|
||||||
|
for cxx in targets:
|
||||||
|
if cxx.target.platform in self.platformSpec:
|
||||||
|
if cxx.target.arch in self.platformSpec[cxx.target.platform]:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
WinOnly = ['windows']
|
||||||
|
WinLinux = ['windows', 'linux']
|
||||||
|
WinLinuxMac = ['windows', 'linux', 'mac']
|
||||||
|
CSGO = {
|
||||||
|
'windows': ['x86'],
|
||||||
|
'linux': ['x86', 'x86_64'],
|
||||||
|
'mac': ['x86_64']
|
||||||
|
}
|
||||||
|
Source2 = {
|
||||||
|
'windows': ['x86_64'],
|
||||||
|
'linux': ['x86_64'],
|
||||||
|
}
|
||||||
|
Insurgency = {
|
||||||
|
'windows': ['x86', 'x86_64'],
|
||||||
|
'linux': ['x86'],
|
||||||
|
'mac': ['x86', 'x86_64'],
|
||||||
|
}
|
||||||
|
Blade = {
|
||||||
|
'windows': ['x86', 'x86_64'],
|
||||||
|
'linux': ['x86_64']
|
||||||
|
}
|
||||||
|
Mock = {
|
||||||
|
'windows': ['x86', 'x86_64'],
|
||||||
|
'linux': ['x86', 'x86_64'],
|
||||||
|
'mac': ['x86_64']
|
||||||
|
}
|
||||||
|
|
||||||
|
PossibleSDKs = {
|
||||||
|
'episode1': SDK('HL2SDK', '2.ep1', '1', 'EPISODEONE', WinLinux, 'episode1'),
|
||||||
|
'ep2': SDK('HL2SDKOB', '2.ep2', '3', 'ORANGEBOX', WinLinux, 'orangebox'),
|
||||||
|
'css': SDK('HL2SDKCSS', '2.css', '6', 'CSS', WinLinuxMac, 'css'),
|
||||||
|
'hl2dm': SDK('HL2SDKHL2DM', '2.hl2dm', '7', 'HL2DM', WinLinuxMac, 'hl2dm'),
|
||||||
|
'dods': SDK('HL2SDKDODS', '2.dods', '8', 'DODS', WinLinuxMac, 'dods'),
|
||||||
|
'sdk2013': SDK('HL2SDK2013', '2.sdk2013', '9', 'SDK2013', WinLinuxMac, 'sdk2013'),
|
||||||
|
'tf2': SDK('HL2SDKTF2', '2.tf2', '12', 'TF2', WinLinuxMac, 'tf2'),
|
||||||
|
'l4d': SDK('HL2SDKL4D', '2.l4d', '13', 'LEFT4DEAD', WinLinuxMac, 'l4d'),
|
||||||
|
'nucleardawn': SDK('HL2SDKND', '2.nd', '14', 'NUCLEARDAWN', WinLinuxMac, 'nucleardawn'),
|
||||||
|
'l4d2': SDK('HL2SDKL4D2', '2.l4d2', '16', 'LEFT4DEAD2', WinLinuxMac, 'l4d2'),
|
||||||
|
'darkm': SDK('HL2SDK-DARKM', '2.darkm', '2', 'DARKMESSIAH', WinOnly, 'darkm'),
|
||||||
|
'swarm': SDK('HL2SDK-SWARM', '2.swarm', '17', 'ALIENSWARM', WinOnly, 'swarm'),
|
||||||
|
'bgt': SDK('HL2SDK-BGT', '2.bgt', '4', 'BLOODYGOODTIME', WinOnly, 'bgt'),
|
||||||
|
'eye': SDK('HL2SDK-EYE', '2.eye', '5', 'EYE', WinOnly, 'eye'),
|
||||||
|
'mcv': SDK('HL2SDKMCV', '2.mcv', '22', 'MCV', WinOnly, 'mcv'),
|
||||||
|
'csgo': SDK('HL2SDKCSGO', '2.csgo', '23', 'CSGO', CSGO, 'csgo'),
|
||||||
|
'portal2': SDK('HL2SDKPORTAL2', '2.portal2', '18', 'PORTAL2', [], 'portal2'),
|
||||||
|
'blade': SDK('HL2SDKBLADE', '2.blade', '19', 'BLADE', Blade, 'blade'),
|
||||||
|
'insurgency': SDK('HL2SDKINSURGENCY', '2.insurgency', '20', 'INSURGENCY', Insurgency, 'insurgency'),
|
||||||
|
'doi': SDK('HL2SDKDOI', '2.doi', '21', 'DOI', WinLinuxMac, 'doi'),
|
||||||
|
'contagion': SDK('HL2SDKCONTAGION', '2.contagion', '15', 'CONTAGION', WinOnly, 'contagion'),
|
||||||
|
'bms': SDK('HL2SDKBMS', '2.bms', '11', 'BMS', WinLinux, 'bms'),
|
||||||
|
'mock': SDK('HL2SDK-MOCK', '2.mock', '999', 'MOCK', Mock, 'mock'),
|
||||||
|
'pvkii': SDK('HL2SDKPVKII', '2.pvkii', '10', 'PVKII', WinLinux, 'pvkii'),
|
||||||
|
'dota': SDK('HL2SDKDOTA', '2.dota', '24', 'DOTA', Source2, 'dota'),
|
||||||
|
'cs2': SDK('HL2SDKCS2', '2.cs2', '25', 'CS2', Source2, 'cs2'),
|
||||||
|
}
|
||||||
|
|
||||||
|
def ResolveEnvPath(env, folder):
|
||||||
|
if env in os.environ:
|
||||||
|
path = os.environ[env]
|
||||||
|
if os.path.isdir(path):
|
||||||
|
return path
|
||||||
|
else:
|
||||||
|
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 MMSPluginConfig(object):
|
||||||
|
def __init__(self):
|
||||||
|
self.sdks = {}
|
||||||
|
self.binaries = []
|
||||||
|
self.mms_root = None
|
||||||
|
self.all_targets = []
|
||||||
|
self.target_archs = set()
|
||||||
|
|
||||||
|
if builder.options.plugin_name is not None:
|
||||||
|
self.plugin_name = builder.options.plugin_name
|
||||||
|
else:
|
||||||
|
self.plugin_name = 'sample_mm'
|
||||||
|
|
||||||
|
if builder.options.plugin_alias is not None:
|
||||||
|
self.plugin_alias = builder.options.plugin_alias
|
||||||
|
else:
|
||||||
|
self.plugin_alias = 'sample'
|
||||||
|
|
||||||
|
if builder.options.targets:
|
||||||
|
target_archs = builder.options.targets.split(',')
|
||||||
|
else:
|
||||||
|
target_archs = ['x86']
|
||||||
|
target_archs.append('x86_64')
|
||||||
|
|
||||||
|
for arch in target_archs:
|
||||||
|
try:
|
||||||
|
cxx = builder.DetectCxx(target_arch = arch)
|
||||||
|
self.target_archs.add(cxx.target.arch)
|
||||||
|
except Exception as e:
|
||||||
|
# Error if archs were manually overridden.
|
||||||
|
if builder.options.targets:
|
||||||
|
raise
|
||||||
|
print('Skipping target {}: {}'.format(arch, e))
|
||||||
|
continue
|
||||||
|
self.all_targets.append(cxx)
|
||||||
|
|
||||||
|
if not self.all_targets:
|
||||||
|
raise Exception('No suitable C/C++ compiler was found.')
|
||||||
|
|
||||||
|
def detectSDKs(self):
|
||||||
|
sdk_list = builder.options.sdks.split(',')
|
||||||
|
use_all = sdk_list[0] == 'all'
|
||||||
|
use_present = sdk_list[0] == 'present'
|
||||||
|
if sdk_list[0] == '':
|
||||||
|
sdk_list = []
|
||||||
|
|
||||||
|
not_found = []
|
||||||
|
for sdk_name in PossibleSDKs:
|
||||||
|
sdk = PossibleSDKs[sdk_name]
|
||||||
|
if sdk.shouldBuild(self.all_targets):
|
||||||
|
if builder.options.hl2sdk_root:
|
||||||
|
sdk_path = os.path.join(builder.options.hl2sdk_root, sdk.folder)
|
||||||
|
if not os.path.exists(sdk_path):
|
||||||
|
sdk_path = None
|
||||||
|
else:
|
||||||
|
sdk_path = ResolveEnvPath(sdk.envvar, sdk.folder)
|
||||||
|
if sdk_path is None:
|
||||||
|
if (use_all and sdk_name != 'mock') or sdk_name in sdk_list:
|
||||||
|
raise Exception('Could not find a valid path for {0}'.format(sdk.envvar))
|
||||||
|
not_found.append(sdk_name)
|
||||||
|
continue
|
||||||
|
if use_all or use_present or sdk_name in sdk_list:
|
||||||
|
sdk.path = sdk_path
|
||||||
|
self.sdks[sdk_name] = sdk
|
||||||
|
|
||||||
|
if len(self.sdks) < 1 and len(sdk_list):
|
||||||
|
raise Exception('No SDKs were found, nothing to build.')
|
||||||
|
|
||||||
|
if len(self.sdks) > 1:
|
||||||
|
raise Exception('Only one sdk at a time is supported, for multi-sdk approach use loader based solution.')
|
||||||
|
|
||||||
|
if builder.options.mms_path:
|
||||||
|
self.mms_root = builder.options.mms_path
|
||||||
|
else:
|
||||||
|
self.mms_root = ResolveEnvPath('MMSOURCE112', 'mmsource-1.12')
|
||||||
|
if not self.mms_root:
|
||||||
|
self.mms_root = ResolveEnvPath('MMSOURCE111', 'mmsource-1.11')
|
||||||
|
if not self.mms_root:
|
||||||
|
self.mms_root = ResolveEnvPath('MMSOURCE110', 'mmsource-1.10')
|
||||||
|
if not self.mms_root:
|
||||||
|
self.mms_root = ResolveEnvPath('MMSOURCE_DEV', 'metamod-source')
|
||||||
|
if not self.mms_root:
|
||||||
|
self.mms_root = ResolveEnvPath('MMSOURCE_DEV', 'mmsource-central')
|
||||||
|
if not self.mms_root 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)
|
||||||
|
|
||||||
|
if use_present:
|
||||||
|
for sdk in not_found:
|
||||||
|
print('Warning: hl2sdk-{} was not found, and will not be included in build.'.format(sdk))
|
||||||
|
|
||||||
|
def configure(self):
|
||||||
|
for cxx in self.all_targets:
|
||||||
|
if cxx.target.arch not in ['x86', 'x86_64']:
|
||||||
|
raise Exception('Unknown target architecture: {0}'.format(arch))
|
||||||
|
|
||||||
|
self.configure_cxx(cxx)
|
||||||
|
|
||||||
|
def configure_cxx(self, cxx):
|
||||||
|
if cxx.behavior == 'gcc':
|
||||||
|
cxx.defines += [
|
||||||
|
'stricmp=strcasecmp',
|
||||||
|
'_stricmp=strcasecmp',
|
||||||
|
'_snprintf=snprintf',
|
||||||
|
'_vsnprintf=vsnprintf',
|
||||||
|
'HAVE_STDINT_H',
|
||||||
|
'GNUC',
|
||||||
|
]
|
||||||
|
cxx.cflags += [
|
||||||
|
'-pipe',
|
||||||
|
'-fno-strict-aliasing',
|
||||||
|
'-Wall',
|
||||||
|
'-Werror',
|
||||||
|
'-Wno-uninitialized',
|
||||||
|
'-Wno-unused',
|
||||||
|
'-Wno-switch',
|
||||||
|
'-msse',
|
||||||
|
'-fPIC',
|
||||||
|
]
|
||||||
|
|
||||||
|
if cxx.version == 'apple-clang-6.0' or cxx.version == 'clang-3.4':
|
||||||
|
cxx.cxxflags += ['-std=c++1y']
|
||||||
|
else:
|
||||||
|
cxx.cxxflags += ['-std=c++14']
|
||||||
|
if (cxx.version >= 'gcc-4.0') or cxx.family == 'clang':
|
||||||
|
cxx.cflags += ['-fvisibility=hidden']
|
||||||
|
cxx.cxxflags += ['-fvisibility-inlines-hidden']
|
||||||
|
cxx.cxxflags += [
|
||||||
|
'-fno-exceptions',
|
||||||
|
'-fno-rtti',
|
||||||
|
'-fno-threadsafe-statics',
|
||||||
|
'-Wno-non-virtual-dtor',
|
||||||
|
'-Wno-overloaded-virtual',
|
||||||
|
]
|
||||||
|
if (cxx.version >= 'gcc-4.7' or cxx.family == 'clang'):
|
||||||
|
cxx.cxxflags += ['-Wno-delete-non-virtual-dtor']
|
||||||
|
if cxx.family == 'gcc':
|
||||||
|
cxx.cflags += ['-mfpmath=sse']
|
||||||
|
if cxx.family == 'clang':
|
||||||
|
cxx.cxxflags += ['-Wno-implicit-exception-spec-mismatch']
|
||||||
|
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' or cxx.version >= 'apple-clang-7.0':
|
||||||
|
cxx.cxxflags += ['-Wno-inconsistent-missing-override']
|
||||||
|
if cxx.version >= 'apple-clang-5.1' or cxx.version >= 'clang-3.4':
|
||||||
|
cxx.cxxflags += ['-Wno-deprecated-register']
|
||||||
|
else:
|
||||||
|
cxx.cxxflags += ['-Wno-deprecated']
|
||||||
|
|
||||||
|
# Work around SDK warnings.
|
||||||
|
if cxx.version >= 'clang-10.0' or cxx.version >= 'apple-clang-12.0':
|
||||||
|
cxx.cflags += [
|
||||||
|
'-Wno-implicit-int-float-conversion',
|
||||||
|
'-Wno-tautological-overlap-compare',
|
||||||
|
]
|
||||||
|
|
||||||
|
elif cxx.like('msvc'):
|
||||||
|
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',
|
||||||
|
]
|
||||||
|
cxx.cflags += [
|
||||||
|
'/W3',
|
||||||
|
'/Zi',
|
||||||
|
]
|
||||||
|
cxx.cxxflags += ['/TP']
|
||||||
|
|
||||||
|
cxx.linkflags += [
|
||||||
|
'/SUBSYSTEM:WINDOWS',
|
||||||
|
'kernel32.lib',
|
||||||
|
'user32.lib',
|
||||||
|
'gdi32.lib',
|
||||||
|
'winspool.lib',
|
||||||
|
'comdlg32.lib',
|
||||||
|
'advapi32.lib',
|
||||||
|
'shell32.lib',
|
||||||
|
'ole32.lib',
|
||||||
|
'oleaut32.lib',
|
||||||
|
'uuid.lib',
|
||||||
|
'odbc32.lib',
|
||||||
|
'odbccp32.lib',
|
||||||
|
]
|
||||||
|
|
||||||
|
# Optimization
|
||||||
|
if builder.options.opt == '1':
|
||||||
|
cxx.defines += ['NDEBUG']
|
||||||
|
if cxx.behavior == 'gcc':
|
||||||
|
cxx.cflags += ['-O3']
|
||||||
|
elif cxx.behavior == 'msvc':
|
||||||
|
cxx.cflags += ['/Ox', '/Zo']
|
||||||
|
cxx.linkflags += ['/OPT:ICF', '/OPT:REF']
|
||||||
|
|
||||||
|
# Debugging
|
||||||
|
if builder.options.debug == '1':
|
||||||
|
cxx.defines += ['DEBUG', '_DEBUG']
|
||||||
|
if cxx.behavior == 'gcc':
|
||||||
|
cxx.cflags += ['-g3']
|
||||||
|
elif cxx.behavior == 'msvc':
|
||||||
|
cxx.cflags += ['/Od', '/RTC1']
|
||||||
|
|
||||||
|
# Don't omit the frame pointer.
|
||||||
|
# This needs to be after our optimization flags which could otherwise disable it.
|
||||||
|
if cxx.behavior == 'gcc':
|
||||||
|
cxx.cflags += ['-fno-omit-frame-pointer']
|
||||||
|
elif cxx.behavior == 'msvc':
|
||||||
|
cxx.cflags += ['/Oy-']
|
||||||
|
|
||||||
|
# Platform-specifics
|
||||||
|
if cxx.target.platform == 'linux':
|
||||||
|
cxx.defines += ['_LINUX', 'POSIX', '_FILE_OFFSET_BITS=64']
|
||||||
|
if cxx.family == 'gcc':
|
||||||
|
cxx.linkflags += ['-static-libgcc']
|
||||||
|
elif cxx.family == 'clang':
|
||||||
|
cxx.linkflags += ['-lgcc_eh']
|
||||||
|
elif cxx.target.platform == 'mac':
|
||||||
|
cxx.defines += ['OSX', '_OSX', 'POSIX']
|
||||||
|
|
||||||
|
if cxx.version >= 'apple-clang-10.0':
|
||||||
|
cxx.cflags += ['-mmacosx-version-min=10.9', '-stdlib=libc++']
|
||||||
|
cxx.linkflags += [
|
||||||
|
'-mmacosx-version-min=10.9',
|
||||||
|
]
|
||||||
|
else:
|
||||||
|
cxx.cflags += ['-mmacosx-version-min=10.5']
|
||||||
|
cxx.linkflags += [
|
||||||
|
'-mmacosx-version-min=10.5',
|
||||||
|
]
|
||||||
|
|
||||||
|
cxx.linkflags += [
|
||||||
|
'-lc++',
|
||||||
|
]
|
||||||
|
elif cxx.target.platform == 'windows':
|
||||||
|
cxx.defines += ['WIN32', '_WINDOWS']
|
||||||
|
|
||||||
|
# Finish up.
|
||||||
|
# Custom defines here
|
||||||
|
cxx.defines += [ ]
|
||||||
|
# Custom includes here
|
||||||
|
cxx.includes += [ ]
|
||||||
|
|
||||||
|
def HL2Compiler(self, context, cxx, sdk):
|
||||||
|
compiler = cxx.clone()
|
||||||
|
mms_core_path = os.path.join(self.mms_root, 'core')
|
||||||
|
compiler.cxxincludes += [
|
||||||
|
os.path.join(mms_core_path),
|
||||||
|
os.path.join(mms_core_path, 'sourcehook'),
|
||||||
|
os.path.join(context.currentSourcePath),
|
||||||
|
]
|
||||||
|
|
||||||
|
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(['game', 'shared'])
|
||||||
|
paths.append(['common'])
|
||||||
|
compiler.defines += ['SOURCE_ENGINE=' + sdk.code]
|
||||||
|
|
||||||
|
if sdk.name in ['sdk2013', 'bms', 'pvkii'] 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.family == 'msvc':
|
||||||
|
compiler.defines += ['COMPILER_MSVC']
|
||||||
|
if compiler.target.arch == 'x86':
|
||||||
|
compiler.defines += ['COMPILER_MSVC32']
|
||||||
|
elif compiler.target.arch == 'x86_64':
|
||||||
|
compiler.defines += ['COMPILER_MSVC64']
|
||||||
|
|
||||||
|
if compiler.version >= 1900:
|
||||||
|
compiler.linkflags += ['legacy_stdio_definitions.lib']
|
||||||
|
else:
|
||||||
|
compiler.defines += ['COMPILER_GCC']
|
||||||
|
|
||||||
|
if compiler.target.arch == 'x86_64':
|
||||||
|
compiler.defines += ['X64BITS', 'PLATFORM_64BITS']
|
||||||
|
|
||||||
|
if sdk.name in ['css', 'hl2dm', 'dods', 'sdk2013', 'bms', 'tf2', 'l4d', 'nucleardawn', 'l4d2', 'dota', 'cs2', 'pvkii']:
|
||||||
|
if compiler.target.platform in ['linux', 'mac']:
|
||||||
|
compiler.defines += ['NO_HOOK_MALLOC', 'NO_MALLOC_OVERRIDE']
|
||||||
|
|
||||||
|
if sdk.name in ['csgo', 'blade', 'pvkii'] and compiler.target.platform == 'linux':
|
||||||
|
compiler.linkflags += ['-lstdc++']
|
||||||
|
|
||||||
|
if sdk.name in ['dota', 'cs2']:
|
||||||
|
compiler.defines += ['META_IS_SOURCE2']
|
||||||
|
|
||||||
|
for path in paths:
|
||||||
|
compiler.cxxincludes += [os.path.join(sdk.path, *path)]
|
||||||
|
|
||||||
|
compiler.linkflags += additional_libs
|
||||||
|
compiler.defines += additional_defines
|
||||||
|
compiler.cxxincludes += additional_includes
|
||||||
|
|
||||||
|
return compiler
|
||||||
|
|
||||||
|
def Library(self, cxx, name):
|
||||||
|
binary = cxx.Library(name)
|
||||||
|
return binary
|
||||||
|
|
||||||
|
def HL2Library(self, context, compiler, name, sdk):
|
||||||
|
compiler = self.HL2Compiler(context, compiler, sdk)
|
||||||
|
|
||||||
|
if compiler.target.platform == 'linux':
|
||||||
|
if sdk.name == 'episode1':
|
||||||
|
lib_folder = os.path.join(sdk.path, 'linux_sdk')
|
||||||
|
elif sdk.name in ['sdk2013', 'bms', 'pvkii']:
|
||||||
|
lib_folder = os.path.join(sdk.path, 'lib', 'public', 'linux32')
|
||||||
|
elif compiler.target.arch == 'x86_64':
|
||||||
|
lib_folder = os.path.join(sdk.path, 'lib', 'linux64')
|
||||||
|
else:
|
||||||
|
lib_folder = os.path.join(sdk.path, 'lib', 'linux')
|
||||||
|
elif compiler.target.platform == 'mac':
|
||||||
|
if sdk.name in ['sdk2013', 'bms']:
|
||||||
|
lib_folder = os.path.join(sdk.path, 'lib', 'public', 'osx32')
|
||||||
|
elif compiler.target.arch == 'x86_64':
|
||||||
|
lib_folder = os.path.join(sdk.path, 'lib', 'osx64')
|
||||||
|
else:
|
||||||
|
lib_folder = os.path.join(sdk.path, 'lib', 'mac')
|
||||||
|
|
||||||
|
if compiler.target.platform in ['linux', 'mac']:
|
||||||
|
if sdk.name in ['sdk2013', 'bms', 'pvkii'] or compiler.target.arch == 'x86_64':
|
||||||
|
tier1 = os.path.join(lib_folder, 'tier1.a')
|
||||||
|
else:
|
||||||
|
tier1 = os.path.join(lib_folder, 'tier1_i486.a')
|
||||||
|
if sdk.name == 'mock' and compiler.target.platform == 'linux':
|
||||||
|
compiler.linkflags += ['-Wl,-z,origin']
|
||||||
|
compiler.postlink += [tier1]
|
||||||
|
|
||||||
|
if sdk.name in ['blade', 'insurgency', 'doi', 'csgo', 'cs2', 'dota']:
|
||||||
|
if compiler.target.arch == 'x86_64':
|
||||||
|
compiler.postlink += [os.path.join(lib_folder, 'interfaces.a')]
|
||||||
|
else:
|
||||||
|
compiler.postlink += [os.path.join(lib_folder, 'interfaces_i486.a')]
|
||||||
|
|
||||||
|
if sdk.name == 'bms':
|
||||||
|
compiler.postlink += [os.path.join(lib_folder, 'mathlib.a')]
|
||||||
|
|
||||||
|
binary = self.Library(compiler, name)
|
||||||
|
compiler = binary.compiler
|
||||||
|
|
||||||
|
dynamic_libs = []
|
||||||
|
if compiler.target.platform == 'linux':
|
||||||
|
compiler.linkflags[0:0] = ['-lm']
|
||||||
|
if sdk.name in ['css', 'hl2dm', 'dods', 'tf2', 'sdk2013', 'bms', 'nucleardawn', 'l4d2', 'insurgency', 'doi']:
|
||||||
|
dynamic_libs = ['libtier0_srv.so', 'libvstdlib_srv.so']
|
||||||
|
elif compiler.target.arch == 'x86_64' and sdk.name in ['csgo', 'mock']:
|
||||||
|
dynamic_libs = ['libtier0_client.so', 'libvstdlib_client.so']
|
||||||
|
elif sdk.name in ['l4d', 'blade', 'insurgency', 'doi', 'csgo', 'cs2', 'dota', 'pvkii']:
|
||||||
|
dynamic_libs = ['libtier0.so']
|
||||||
|
if sdk.name not in ['dota', 'cs2']:
|
||||||
|
dynamic_libs += ['libvstdlib.so']
|
||||||
|
else:
|
||||||
|
dynamic_libs = ['tier0_i486.so', 'vstdlib_i486.so']
|
||||||
|
if sdk.name in ['csgo', 'blade']:
|
||||||
|
compiler.defines += ['_GLIBCXX_USE_CXX11_ABI=0']
|
||||||
|
elif compiler.target.platform == 'mac':
|
||||||
|
binary.compiler.linkflags.append('-liconv')
|
||||||
|
dynamic_libs = ['libtier0.dylib', 'libvstdlib.dylib']
|
||||||
|
elif compiler.target.platform == 'windows':
|
||||||
|
libs = ['tier0', 'tier1', 'mathlib']
|
||||||
|
if sdk.name not in ['dota', 'cs2']:
|
||||||
|
libs += ['vstdlib']
|
||||||
|
if sdk.name in ['swarm', 'blade', 'insurgency', 'doi', 'mcv', 'csgo', 'cs2', 'dota']:
|
||||||
|
libs.append('interfaces')
|
||||||
|
for lib in libs:
|
||||||
|
if compiler.target.arch == 'x86':
|
||||||
|
lib_path = os.path.join(sdk.path, 'lib', 'public', lib) + '.lib'
|
||||||
|
elif compiler.target.arch == 'x86_64':
|
||||||
|
lib_path = os.path.join(sdk.path, 'lib', 'public', 'win64', lib) + '.lib'
|
||||||
|
binary.compiler.linkflags.append(lib_path)
|
||||||
|
|
||||||
|
for library in dynamic_libs:
|
||||||
|
source_path = os.path.join(lib_folder, library)
|
||||||
|
output_path = os.path.join(binary.localFolder, library)
|
||||||
|
|
||||||
|
context.AddFolder(binary.localFolder)
|
||||||
|
output = context.AddSymlink(source_path, output_path)
|
||||||
|
|
||||||
|
binary.compiler.weaklinkdeps += [output]
|
||||||
|
binary.compiler.linkflags[0:0] = [library]
|
||||||
|
|
||||||
|
return binary
|
||||||
|
|
||||||
|
MMSPlugin = MMSPluginConfig()
|
||||||
|
MMSPlugin.detectSDKs()
|
||||||
|
MMSPlugin.configure()
|
||||||
|
|
||||||
|
BuildScripts = [
|
||||||
|
'AMBuilder',
|
||||||
|
'PackageScript',
|
||||||
|
]
|
||||||
|
|
||||||
|
builder.Build(BuildScripts, { 'MMSPlugin': MMSPlugin })
|
||||||
33
samples/s2_sample_mm/AMBuilder
Normal file
33
samples/s2_sample_mm/AMBuilder
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
# vim: set sts=2 ts=8 sw=2 tw=99 et ft=python:
|
||||||
|
import os
|
||||||
|
|
||||||
|
# Here only one sdk should be available to generate only one executable in the end,
|
||||||
|
# as multi-sdk loading isn't supported out of the box by metamod, and would require specifying the full path in the vdf
|
||||||
|
# which in the end would ruin the multi-platform (unix, win etc) loading by metamod as it won't be able to append platform specific extension
|
||||||
|
# so just fall back to the single binary.
|
||||||
|
# Multi-sdk solutions should be manually loaded with a custom plugin loader (examples being sourcemod, stripper:source)
|
||||||
|
for sdk_name in MMSPlugin.sdks:
|
||||||
|
for cxx in MMSPlugin.all_targets:
|
||||||
|
sdk = MMSPlugin.sdks[sdk_name]
|
||||||
|
|
||||||
|
if not cxx.target.arch in sdk.platformSpec[cxx.target.platform]:
|
||||||
|
continue
|
||||||
|
|
||||||
|
binary = MMSPlugin.HL2Library(builder, cxx, MMSPlugin.plugin_name, sdk)
|
||||||
|
|
||||||
|
binary.sources += [
|
||||||
|
'sample_mm.cpp',
|
||||||
|
]
|
||||||
|
|
||||||
|
if sdk_name in ['dota', 'cs2']:
|
||||||
|
binary.sources += [
|
||||||
|
os.path.join(sdk.path, 'tier1', 'convar.cpp'),
|
||||||
|
os.path.join(sdk.path, 'public', 'tier0', 'memoverride.cpp'),
|
||||||
|
]
|
||||||
|
|
||||||
|
if cxx.target.arch == 'x86':
|
||||||
|
binary.sources += ['sourcehook/sourcehook_hookmangen.cpp']
|
||||||
|
nodes = builder.Add(binary)
|
||||||
|
MMSPlugin.binaries += [nodes]
|
||||||
|
|
||||||
|
break
|
||||||
49
samples/s2_sample_mm/PackageScript
Normal file
49
samples/s2_sample_mm/PackageScript
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
# vim: set ts=2 sw=2 tw=99 noet ft=python:
|
||||||
|
import os
|
||||||
|
|
||||||
|
builder.SetBuildFolder('package')
|
||||||
|
|
||||||
|
metamod_folder = builder.AddFolder(os.path.join('addons', 'metamod'))
|
||||||
|
bin_folder_path = os.path.join('addons', MMSPlugin.plugin_name, 'bin')
|
||||||
|
bin_folder = builder.AddFolder(bin_folder_path)
|
||||||
|
|
||||||
|
for cxx in MMSPlugin.all_targets:
|
||||||
|
if cxx.target.arch == 'x86_64':
|
||||||
|
if cxx.target.platform == 'windows':
|
||||||
|
bin64_folder_path = os.path.join('addons', MMSPlugin.plugin_name, 'bin', 'win64')
|
||||||
|
bin64_folder = builder.AddFolder(bin64_folder_path)
|
||||||
|
elif cxx.target.platform == 'linux':
|
||||||
|
bin64_folder_path = os.path.join('addons', MMSPlugin.plugin_name, 'bin', 'win64')
|
||||||
|
bin64_folder = builder.AddFolder(bin64_folder_path)
|
||||||
|
elif cxx.target.platform == 'mac':
|
||||||
|
bin64_folder_path = os.path.join('addons', MMSPlugin.plugin_name, 'bin', 'win64')
|
||||||
|
bin64_folder = builder.AddFolder(bin64_folder_path)
|
||||||
|
|
||||||
|
pdb_list = []
|
||||||
|
for task in MMSPlugin.binaries:
|
||||||
|
# This hardly assumes there's only 1 targetted platform and would be overwritten
|
||||||
|
# with whatever comes last if multiple are used!
|
||||||
|
with open(os.path.join(builder.buildPath, MMSPlugin.plugin_name + '.vdf'), 'w') as fp:
|
||||||
|
fp.write('"Metamod Plugin"\n')
|
||||||
|
fp.write('{\n')
|
||||||
|
fp.write(f'\t"alias"\t"{MMSPlugin.plugin_alias}"\n')
|
||||||
|
if task.target.arch == 'x86_64':
|
||||||
|
fp.write(f'\t"file"\t"{os.path.join(bin64_folder_path, MMSPlugin.plugin_name)}"\n')
|
||||||
|
else:
|
||||||
|
fp.write(f'\t"file"\t"{os.path.join(bin_folder_path, MMSPlugin.plugin_name)}"\n')
|
||||||
|
fp.write('}\n')
|
||||||
|
|
||||||
|
if task.target.arch == 'x86_64':
|
||||||
|
builder.AddCopy(task.binary, bin64_folder)
|
||||||
|
else:
|
||||||
|
builder.AddCopy(task.binary, bin_folder)
|
||||||
|
|
||||||
|
if task.debug:
|
||||||
|
pdb_list.append(task.debug)
|
||||||
|
|
||||||
|
builder.AddCopy(os.path.join(builder.buildPath, MMSPlugin.plugin_name + '.vdf'), metamod_folder)
|
||||||
|
|
||||||
|
# Generate PDB info.
|
||||||
|
with open(os.path.join(builder.buildPath, 'pdblog.txt'), 'wt') as fp:
|
||||||
|
for line in pdb_list:
|
||||||
|
fp.write(line.path + '\n')
|
||||||
37
samples/s2_sample_mm/README.md
Normal file
37
samples/s2_sample_mm/README.md
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
## Manual building example
|
||||||
|
|
||||||
|
### Prerequisites
|
||||||
|
* [hl2sdk](https://github.com/alliedmodders/hl2sdk) of the game you plan on writing plugin for (the current plugin build scripts allows only for 1 sdk and 1 platform at a time!);
|
||||||
|
* [metamod-source](https://github.com/alliedmodders/metamod-source);
|
||||||
|
* [python3](https://www.python.org/)
|
||||||
|
* [ambuild](https://github.com/alliedmodders/ambuild), make sure ``ambuild`` command is available via the ``PATH`` environment variable;
|
||||||
|
|
||||||
|
### Setting up
|
||||||
|
* ``mkdir build`` & ``cd build`` in the root of the plugin folder.
|
||||||
|
* Open the [MSVC developer console](https://learn.microsoft.com/en-us/cpp/build/building-on-the-command-line) with the correct platform (x86 or x86_64) that you plan on targetting.
|
||||||
|
* Run ``python3 ../configure.py --plugin-name={PLUGIN_NAME} --plugin-alias={PLUGIN_ALIAS} -s {SDKNAME} --targets={TARGET} --mms_path={MMS_PATH} --hl2sdk-root {HL2SDKROOT} `` where:
|
||||||
|
* ``{PLUGIN_NAME}`` should be the plugin name which is used for the resulting binary name and folder naming scheme (this doesn't affect the plugin name you'd see in the plugin list if you don't modify the base plugin functions);
|
||||||
|
* ``{PLUGIN_ALIAS}`` should be used to set the plugin alias that is used as a short hand version to load, unload, list info etc via the metamod-source menu (example being ``meta unload sample``, where ``sample`` is the alias);
|
||||||
|
* ``{SDKNAME}`` should be the hl2sdk game name that you are building for;
|
||||||
|
* ``{TARGET}`` should be the target platform you are targeting (``x86`` or ``x86_64``);
|
||||||
|
* ``{MMS_PATH}`` should point to the root of the metamod-source folder;
|
||||||
|
* ``{HL2SDKROOT}`` should point to the root of the hl2sdk's folders, note that it should not point to the actual ``hl2sdk-GAME`` folder but a root parent of it;
|
||||||
|
* Alternatively ``{MMS_PATH}`` & ``{HL2SDKROOT}`` could be put as a ``PATH`` environment variables, like ``MMSOURCE112=D:\mmsource-1.12`` & ``HL2SDKCS2=D:\hl2sdks\hl2sdk-cs2`` (note the metamod version and that here hl2sdk environment variable should point directly to the game's hl2sdk folder and not to the root of it!)
|
||||||
|
* Example: ``python3 ../configure.py --plugin-name=sample_mm --plugin-alias=sample -s cs2 --targets=x86_64 --mms_path=D:\mmsource-1.12 --hl2sdk-root=D:\hl2sdks``
|
||||||
|
* If the process of configuring was successful, you should be able to run ``ambuild`` in the ``\build`` folder to compile the plugin.
|
||||||
|
* Once the plugin is compiled the files would be packaged and placed in ``\build\package`` folder.
|
||||||
|
* To run the plugin on the server, place the files preserving the layout provided in ``\package``. Be aware that plugins get loaded either by corresponding ``.vdf`` files (automatic step) in the metamod folder, or by listing them in ``addons/metamod/metaplugins.ini`` file (manual step).
|
||||||
|
|
||||||
|
## Points of interest
|
||||||
|
* To generate the VS solution of the plugin with the correct setup, use ``python3 ../configure {CONFIGURE_OPTIONS} --gen=vs``, where ``{CONFIGURE_OPTIONS}`` is your default configuring options that are used when building. As a result ``.vcxproj`` file would be created in the folder where the command was executed.
|
||||||
|
* To update which ``.cpp`` files gets compiled in or to add new ones, look at ``AMBuilder`` script which has the ``sample_mm.cpp`` being built initially, you can add or edit this however you want to, running ``ambuild`` after editing this script would automatically catch up the changes, no need for the reconfiguration.
|
||||||
|
* To change the name/version/author/etc that's displayed in the metamod-source menu, make sure to correctly overload and provide the wanted info to the metamod-source, like ``ISmmPlugin::GetAuthor``, ``ISmmPlugin::GetName`` and so on.
|
||||||
|
* There are also additional arguments for the configuration step that aren't covered here, you can see them by running ``python3 ../configure -h`` from within the ``\build`` folder.
|
||||||
|
* To add additional linking ``.libs``/defines/include directories, open ``AMBuildScript`` and at the top edit corresponding arrays.
|
||||||
|
* Sometimes there could be problems with ``ambuild`` not catching up the changes in ``.h`` files, thus producing incorrect (outdated) binaries or even doesn't compile with the new changes. As there's [no full rebuild option](https://github.com/alliedmodders/ambuild/issues/145) to combat this, go to the ``/build`` folder and locate the folder named after the plugin name you've used, deleting that folder and building after should provide the clean build of the project and the described issues should be eliminated.
|
||||||
|
|
||||||
|
|
||||||
|
## For more information on compiling and reading the plugin's source code, see:
|
||||||
|
|
||||||
|
http://wiki.alliedmods.net/Category:Metamod:Source_Development
|
||||||
|
|
||||||
39
samples/s2_sample_mm/configure.py
Normal file
39
samples/s2_sample_mm/configure.py
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
# vim: set sts=2 ts=8 sw=2 tw=99 et:
|
||||||
|
import sys
|
||||||
|
try:
|
||||||
|
from ambuild2 import run, util
|
||||||
|
except:
|
||||||
|
try:
|
||||||
|
import ambuild
|
||||||
|
sys.stderr.write('It looks like you have AMBuild 1 installed, but this project uses AMBuild 2.\n')
|
||||||
|
sys.stderr.write('Upgrade to the latest version of AMBuild to continue.\n')
|
||||||
|
except:
|
||||||
|
sys.stderr.write('AMBuild must be installed to build this project.\n')
|
||||||
|
sys.stderr.write('http://www.alliedmods.net/ambuild\n')
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
# Hack to show a decent upgrade message, which wasn't done until 2.2.
|
||||||
|
ambuild_version = getattr(run, 'CURRENT_API', '2.1')
|
||||||
|
if ambuild_version.startswith('2.1'):
|
||||||
|
sys.stderr.write("AMBuild 2.2 or higher is required; please update\n")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
parser = run.BuildParser(sourcePath=sys.path[0], api='2.2')
|
||||||
|
parser.options.add_argument('-n', '--plugin-name', type=str, dest='plugin_name', default=None,
|
||||||
|
help='Plugin name')
|
||||||
|
parser.options.add_argument('-a', '--plugin-alias', type=str, dest='plugin_alias', default=None,
|
||||||
|
help='Plugin alias')
|
||||||
|
parser.options.add_argument('--hl2sdk-root', type=str, dest='hl2sdk_root', default=None,
|
||||||
|
help='Root search folder for HL2SDKs')
|
||||||
|
parser.options.add_argument('--mms_path', type=str, dest='mms_path', default=None,
|
||||||
|
help='Metamod:Source source tree folder')
|
||||||
|
parser.options.add_argument('--enable-debug', action='store_const', const='1', dest='debug',
|
||||||
|
help='Enable debugging symbols')
|
||||||
|
parser.options.add_argument('--enable-optimize', action='store_const', const='1', dest='opt',
|
||||||
|
help='Enable optimization')
|
||||||
|
parser.options.add_argument('-s', '--sdks', default='all', dest='sdks',
|
||||||
|
help='Build against specified SDKs; valid args are "all", "present", or '
|
||||||
|
'comma-delimited list of engine names (default: "all")')
|
||||||
|
parser.options.add_argument('--targets', type=str, dest='targets', default=None,
|
||||||
|
help="Override the target architecture (use commas to separate multiple targets).")
|
||||||
|
parser.Configure()
|
||||||
225
samples/s2_sample_mm/sample_mm.cpp
Normal file
225
samples/s2_sample_mm/sample_mm.cpp
Normal file
@ -0,0 +1,225 @@
|
|||||||
|
/**
|
||||||
|
* vim: set ts=4 sw=4 tw=99 noet :
|
||||||
|
* ======================================================
|
||||||
|
* Metamod:Source Sample Plugin
|
||||||
|
* Written by AlliedModders LLC.
|
||||||
|
* ======================================================
|
||||||
|
*
|
||||||
|
* This software is provided 'as-is', without any express or implied warranty.
|
||||||
|
* In no event will the authors be held liable for any damages arising from
|
||||||
|
* the use of this software.
|
||||||
|
*
|
||||||
|
* This sample plugin is public domain.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "sample_mm.h"
|
||||||
|
#include "iserver.h"
|
||||||
|
|
||||||
|
SH_DECL_HOOK3_void(IServerGameDLL, GameFrame, SH_NOATTRIB, 0, bool, bool, bool);
|
||||||
|
SH_DECL_HOOK4_void(IServerGameClients, ClientActive, SH_NOATTRIB, 0, CPlayerSlot, bool, const char *, uint64);
|
||||||
|
SH_DECL_HOOK5_void(IServerGameClients, ClientDisconnect, SH_NOATTRIB, 0, CPlayerSlot, int, const char *, uint64, const char *);
|
||||||
|
SH_DECL_HOOK4_void(IServerGameClients, ClientPutInServer, SH_NOATTRIB, 0, CPlayerSlot, char const *, int, uint64);
|
||||||
|
SH_DECL_HOOK1_void(IServerGameClients, ClientSettingsChanged, SH_NOATTRIB, 0, CPlayerSlot );
|
||||||
|
SH_DECL_HOOK6_void(IServerGameClients, OnClientConnected, SH_NOATTRIB, 0, CPlayerSlot, const char*, uint64, const char *, const char *, bool);
|
||||||
|
SH_DECL_HOOK6(IServerGameClients, ClientConnect, SH_NOATTRIB, 0, bool, CPlayerSlot, const char*, uint64, const char *, bool, CBufferString *);
|
||||||
|
SH_DECL_HOOK2(IGameEventManager2, FireEvent, SH_NOATTRIB, 0, bool, IGameEvent *, bool);
|
||||||
|
|
||||||
|
SH_DECL_HOOK2_void( IServerGameClients, ClientCommand, SH_NOATTRIB, 0, CPlayerSlot, const CCommand & );
|
||||||
|
|
||||||
|
SamplePlugin g_SamplePlugin;
|
||||||
|
IServerGameDLL *server = NULL;
|
||||||
|
IServerGameClients *gameclients = NULL;
|
||||||
|
IVEngineServer *engine = NULL;
|
||||||
|
IGameEventManager2 *gameevents = NULL;
|
||||||
|
ICvar *icvar = NULL;
|
||||||
|
|
||||||
|
// Should only be called within the active game loop (i e map should be loaded and active)
|
||||||
|
// otherwise that'll be nullptr!
|
||||||
|
CGlobalVars *GetGameGlobals()
|
||||||
|
{
|
||||||
|
INetworkGameServer *server = g_pNetworkServerService->GetIGameServer();
|
||||||
|
|
||||||
|
if(!server)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return g_pNetworkServerService->GetIGameServer()->GetGlobals();
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
// Currently unavailable, requires hl2sdk work!
|
||||||
|
ConVar sample_cvar("sample_cvar", "42", 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
CON_COMMAND_F(sample_command, "Sample command", FCVAR_NONE)
|
||||||
|
{
|
||||||
|
META_CONPRINTF( "Sample command called by %d. Command: %s\n", context.GetPlayerSlot(), args.GetCommandString() );
|
||||||
|
}
|
||||||
|
|
||||||
|
PLUGIN_EXPOSE(SamplePlugin, g_SamplePlugin);
|
||||||
|
bool SamplePlugin::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_ANY(GetServerFactory, server, IServerGameDLL, INTERFACEVERSION_SERVERGAMEDLL);
|
||||||
|
GET_V_IFACE_ANY(GetServerFactory, gameclients, IServerGameClients, INTERFACEVERSION_SERVERGAMECLIENTS);
|
||||||
|
GET_V_IFACE_ANY(GetEngineFactory, g_pNetworkServerService, INetworkServerService, NETWORKSERVERSERVICE_INTERFACE_VERSION);
|
||||||
|
|
||||||
|
// Currently doesn't work from within mm side, use GetGameGlobals() in the mean time instead
|
||||||
|
// gpGlobals = ismm->GetCGlobals();
|
||||||
|
|
||||||
|
META_CONPRINTF( "Starting plugin.\n" );
|
||||||
|
|
||||||
|
SH_ADD_HOOK_MEMFUNC(IServerGameDLL, GameFrame, server, this, &SamplePlugin::Hook_GameFrame, true);
|
||||||
|
SH_ADD_HOOK_MEMFUNC(IServerGameClients, ClientActive, gameclients, this, &SamplePlugin::Hook_ClientActive, true);
|
||||||
|
SH_ADD_HOOK_MEMFUNC(IServerGameClients, ClientDisconnect, gameclients, this, &SamplePlugin::Hook_ClientDisconnect, true);
|
||||||
|
SH_ADD_HOOK_MEMFUNC(IServerGameClients, ClientPutInServer, gameclients, this, &SamplePlugin::Hook_ClientPutInServer, true);
|
||||||
|
SH_ADD_HOOK_MEMFUNC(IServerGameClients, ClientSettingsChanged, gameclients, this, &SamplePlugin::Hook_ClientSettingsChanged, false);
|
||||||
|
SH_ADD_HOOK_MEMFUNC(IServerGameClients, OnClientConnected, gameclients, this, &SamplePlugin::Hook_OnClientConnected, false);
|
||||||
|
SH_ADD_HOOK_MEMFUNC( IServerGameClients, ClientConnect, gameclients, this, &SamplePlugin::Hook_ClientConnect, false );
|
||||||
|
SH_ADD_HOOK_MEMFUNC(IServerGameClients, ClientCommand, gameclients, this, &SamplePlugin::Hook_ClientCommand, false);
|
||||||
|
|
||||||
|
META_CONPRINTF( "All hooks started!\n" );
|
||||||
|
|
||||||
|
g_pCVar = icvar;
|
||||||
|
ConVar_Register( FCVAR_RELEASE | FCVAR_CLIENT_CAN_EXECUTE | FCVAR_GAMEDLL );
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SamplePlugin::Unload(char *error, size_t maxlen)
|
||||||
|
{
|
||||||
|
SH_REMOVE_HOOK_MEMFUNC(IServerGameDLL, GameFrame, server, this, &SamplePlugin::Hook_GameFrame, true);
|
||||||
|
SH_REMOVE_HOOK_MEMFUNC(IServerGameClients, ClientActive, gameclients, this, &SamplePlugin::Hook_ClientActive, true);
|
||||||
|
SH_REMOVE_HOOK_MEMFUNC(IServerGameClients, ClientDisconnect, gameclients, this, &SamplePlugin::Hook_ClientDisconnect, true);
|
||||||
|
SH_REMOVE_HOOK_MEMFUNC(IServerGameClients, ClientPutInServer, gameclients, this, &SamplePlugin::Hook_ClientPutInServer, true);
|
||||||
|
SH_REMOVE_HOOK_MEMFUNC(IServerGameClients, ClientSettingsChanged, gameclients, this, &SamplePlugin::Hook_ClientSettingsChanged, false);
|
||||||
|
SH_REMOVE_HOOK_MEMFUNC(IServerGameClients, OnClientConnected, gameclients, this, &SamplePlugin::Hook_OnClientConnected, false);
|
||||||
|
SH_REMOVE_HOOK_MEMFUNC(IServerGameClients, ClientConnect, gameclients, this, &SamplePlugin::Hook_ClientConnect, false);
|
||||||
|
SH_REMOVE_HOOK_MEMFUNC(IServerGameClients, ClientCommand, gameclients, this, &SamplePlugin::Hook_ClientCommand, false);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SamplePlugin::AllPluginsLoaded()
|
||||||
|
{
|
||||||
|
/* This is where we'd do stuff that relies on the mod or other plugins
|
||||||
|
* being initialized (for example, cvars added and events registered).
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
void SamplePlugin::Hook_ClientActive( CPlayerSlot slot, bool bLoadGame, const char *pszName, uint64 xuid )
|
||||||
|
{
|
||||||
|
META_CONPRINTF( "Hook_ClientActive(%d, %d, \"%s\", %d)\n", slot, bLoadGame, pszName, xuid );
|
||||||
|
}
|
||||||
|
|
||||||
|
void SamplePlugin::Hook_ClientCommand( CPlayerSlot slot, const CCommand &args )
|
||||||
|
{
|
||||||
|
META_CONPRINTF( "Hook_ClientCommand(%d, \"%s\")\n", slot, args.GetCommandString() );
|
||||||
|
}
|
||||||
|
|
||||||
|
void SamplePlugin::Hook_ClientSettingsChanged( CPlayerSlot slot )
|
||||||
|
{
|
||||||
|
META_CONPRINTF( "Hook_ClientSettingsChanged(%d)\n", slot );
|
||||||
|
}
|
||||||
|
|
||||||
|
void SamplePlugin::Hook_OnClientConnected( CPlayerSlot slot, const char *pszName, uint64 xuid, const char *pszNetworkID, const char *pszAddress, bool bFakePlayer )
|
||||||
|
{
|
||||||
|
META_CONPRINTF( "Hook_OnClientConnected(%d, \"%s\", %d, \"%s\", \"%s\", %d)\n", slot, pszName, xuid, pszNetworkID, pszAddress, bFakePlayer );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SamplePlugin::Hook_ClientConnect( CPlayerSlot slot, const char *pszName, uint64 xuid, const char *pszNetworkID, bool unk1, CBufferString *pRejectReason )
|
||||||
|
{
|
||||||
|
META_CONPRINTF( "Hook_ClientConnect(%d, \"%s\", %d, \"%s\", %d, \"%s\")\n", slot, pszName, xuid, pszNetworkID, unk1, pRejectReason->ToGrowable()->Get() );
|
||||||
|
|
||||||
|
RETURN_META_VALUE(MRES_IGNORED, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SamplePlugin::Hook_ClientPutInServer( CPlayerSlot slot, char const *pszName, int type, uint64 xuid )
|
||||||
|
{
|
||||||
|
META_CONPRINTF( "Hook_ClientPutInServer(%d, \"%s\", %d, %d, %d)\n", slot, pszName, type, xuid );
|
||||||
|
}
|
||||||
|
|
||||||
|
void SamplePlugin::Hook_ClientDisconnect( CPlayerSlot slot, int reason, const char *pszName, uint64 xuid, const char *pszNetworkID )
|
||||||
|
{
|
||||||
|
META_CONPRINTF( "Hook_ClientDisconnect(%d, %d, \"%s\", %d, \"%s\")\n", slot, reason, pszName, xuid, pszNetworkID );
|
||||||
|
}
|
||||||
|
|
||||||
|
void SamplePlugin::Hook_GameFrame( bool simulating, bool bFirstTick, bool bLastTick )
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* simulating:
|
||||||
|
* ***********
|
||||||
|
* true | game is ticking
|
||||||
|
* false | game is not ticking
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
// Potentially might not work
|
||||||
|
void SamplePlugin::OnLevelInit( char const *pMapName,
|
||||||
|
char const *pMapEntities,
|
||||||
|
char const *pOldLevel,
|
||||||
|
char const *pLandmarkName,
|
||||||
|
bool loadGame,
|
||||||
|
bool background )
|
||||||
|
{
|
||||||
|
META_CONPRINTF("OnLevelInit(%s)\n", pMapName);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Potentially might not work
|
||||||
|
void SamplePlugin::OnLevelShutdown()
|
||||||
|
{
|
||||||
|
META_CONPRINTF("OnLevelShutdown()\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SamplePlugin::Pause(char *error, size_t maxlen)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SamplePlugin::Unpause(char *error, size_t maxlen)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *SamplePlugin::GetLicense()
|
||||||
|
{
|
||||||
|
return "Public Domain";
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *SamplePlugin::GetVersion()
|
||||||
|
{
|
||||||
|
return "1.0.0.0";
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *SamplePlugin::GetDate()
|
||||||
|
{
|
||||||
|
return __DATE__;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *SamplePlugin::GetLogTag()
|
||||||
|
{
|
||||||
|
return "SAMPLE";
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *SamplePlugin::GetAuthor()
|
||||||
|
{
|
||||||
|
return "AlliedModders LLC";
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *SamplePlugin::GetDescription()
|
||||||
|
{
|
||||||
|
return "Sample basic plugin";
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *SamplePlugin::GetName()
|
||||||
|
{
|
||||||
|
return "Sample Plugin";
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *SamplePlugin::GetURL()
|
||||||
|
{
|
||||||
|
return "http://www.sourcemm.net/";
|
||||||
|
}
|
||||||
62
samples/s2_sample_mm/sample_mm.h
Normal file
62
samples/s2_sample_mm/sample_mm.h
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
/**
|
||||||
|
* vim: set ts=4 sw=4 tw=99 noet :
|
||||||
|
* ======================================================
|
||||||
|
* Metamod:Source Sample Plugin
|
||||||
|
* Written by AlliedModders LLC.
|
||||||
|
* ======================================================
|
||||||
|
*
|
||||||
|
* This software is provided 'as-is', without any express or implied warranty.
|
||||||
|
* In no event will the authors be held liable for any damages arising from
|
||||||
|
* the use of this software.
|
||||||
|
*
|
||||||
|
* This sample plugin is public domain.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _INCLUDE_METAMOD_SOURCE_STUB_PLUGIN_H_
|
||||||
|
#define _INCLUDE_METAMOD_SOURCE_STUB_PLUGIN_H_
|
||||||
|
|
||||||
|
#include <ISmmPlugin.h>
|
||||||
|
#include <igameevents.h>
|
||||||
|
#include <iplayerinfo.h>
|
||||||
|
#include <sh_vector.h>
|
||||||
|
|
||||||
|
class SamplePlugin : public ISmmPlugin, public IMetamodListener
|
||||||
|
{
|
||||||
|
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 AllPluginsLoaded();
|
||||||
|
public: //hooks
|
||||||
|
void OnLevelInit( char const *pMapName,
|
||||||
|
char const *pMapEntities,
|
||||||
|
char const *pOldLevel,
|
||||||
|
char const *pLandmarkName,
|
||||||
|
bool loadGame,
|
||||||
|
bool background );
|
||||||
|
void OnLevelShutdown();
|
||||||
|
void Hook_GameFrame( bool simulating, bool bFirstTick, bool bLastTick );
|
||||||
|
void Hook_ClientActive( CPlayerSlot slot, bool bLoadGame, const char *pszName, uint64 xuid );
|
||||||
|
void Hook_ClientDisconnect( CPlayerSlot slot, int reason, const char *pszName, uint64 xuid, const char *pszNetworkID );
|
||||||
|
void Hook_ClientPutInServer( CPlayerSlot slot, char const *pszName, int type, uint64 xuid );
|
||||||
|
void Hook_ClientSettingsChanged( CPlayerSlot slot );
|
||||||
|
void Hook_OnClientConnected( CPlayerSlot slot, const char *pszName, uint64 xuid, const char *pszNetworkID, const char *pszAddress, bool bFakePlayer );
|
||||||
|
bool Hook_ClientConnect( CPlayerSlot slot, const char *pszName, uint64 xuid, const char *pszNetworkID, bool unk1, CBufferString *pRejectReason );
|
||||||
|
void Hook_ClientCommand( CPlayerSlot nSlot, const CCommand &_cmd );
|
||||||
|
public:
|
||||||
|
const char *GetAuthor();
|
||||||
|
const char *GetName();
|
||||||
|
const char *GetDescription();
|
||||||
|
const char *GetURL();
|
||||||
|
const char *GetLicense();
|
||||||
|
const char *GetVersion();
|
||||||
|
const char *GetDate();
|
||||||
|
const char *GetLogTag();
|
||||||
|
};
|
||||||
|
|
||||||
|
extern SamplePlugin g_SamplePlugin;
|
||||||
|
|
||||||
|
PLUGIN_GLOBALVARS();
|
||||||
|
|
||||||
|
#endif //_INCLUDE_METAMOD_SOURCE_STUB_PLUGIN_H_
|
||||||
Loading…
Reference in New Issue
Block a user