Compare commits
76 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
078e754a82 | ||
|
a776c14cf8 | ||
|
bd296a27f8 | ||
|
2e9619ff67 | ||
|
67a0d18ce7 | ||
|
c5428a8726 | ||
|
8db2132856 | ||
|
2e28df3dc6 | ||
|
b362abf4b2 | ||
|
da1cd9eb11 | ||
|
82628cfc5a | ||
|
690b3c5a28 | ||
|
865fa37ed9 | ||
|
6fae1811d9 | ||
|
7b476e4532 | ||
|
ba7fedca6e | ||
|
b2b29cb33f | ||
|
c5efe48aa3 | ||
|
c2d4643204 | ||
|
328fbf3f19 | ||
|
b5119201ff | ||
|
fe2a488f30 | ||
|
2bfc349952 | ||
|
eb6a39ecde | ||
|
266532f18c | ||
|
95027e0ae8 | ||
|
b5a0332181 | ||
|
ff935b4707 | ||
|
793c603826 | ||
|
03b270cf18 | ||
|
3c1c6f6c79 | ||
|
81766d31f7 | ||
|
cb886d4524 | ||
|
31836d2667 | ||
|
5dcd01801c | ||
|
5215abe5c5 | ||
|
d34d232682 | ||
|
a084b3295e | ||
|
48f7e6bcd5 | ||
|
74195870e2 | ||
|
e27e75b197 | ||
|
0cdc3616f2 | ||
|
92e9ca7153 | ||
|
ff727d537a | ||
|
8803219dd5 | ||
|
ada56b06bb | ||
|
14eaa097cb | ||
|
98be188cbe | ||
|
3a61446626 | ||
|
dd456dcb19 | ||
|
c6303d1ec3 | ||
|
ece57df986 | ||
|
3803fbfe20 | ||
|
50b5bb1970 | ||
|
047e0280ca | ||
|
afc493394d | ||
|
54a32e979f | ||
|
07f8043bce | ||
|
0a7a01e617 | ||
|
a68b21369c | ||
|
9a53fc4425 | ||
|
ab68d046c8 | ||
|
cdb9851da6 | ||
|
93e9a29353 | ||
|
fba6997c67 | ||
|
880f8869a6 | ||
|
e71497eaa6 | ||
|
256b33f75a | ||
|
c316d8fccd | ||
|
bc09b06166 | ||
|
208299f703 | ||
|
523befc238 | ||
|
2098a36d4b | ||
|
083ab81035 | ||
|
847261b6c9 | ||
|
309e6ae959 |
.gitattributes
.github
.travis.ymlAMBuildScriptREADME.mdbridge/include
configure.pycore
AMBuilderConCmdManager.cppConCmdManager.hEventManager.cppHalfLife2.cppHalfLife2.hMenuStyle_Base.hMenuStyle_Radio.cppNextMap.cppPlayerManager.cppPlayerManager.hUserMessagePBHelpers.h
logic
AMBuilderAdminCache.cppCDataPack.cppCDataPack.hCellArray.hDatabase.cppDatabase.hDatabaseConfBuilder.cppDatabaseConfBuilder.hDebugReporter.cppDebugReporter.hExtensionSys.cppGameConfigs.cppGameConfigs.hHandleSys.hLibrarySys.cppLogger.cppLogger.hMemoryUtils.cppNative.hPluginSys.cppPluginSys.hPseudoAddrManager.cppPseudoAddrManager.hRootConsoleMenu.cppShareSys.cppTextParsers.cppTranslator.cppcommon_logic.cppcommon_logic.hsmn_adt_trie.cppsmn_core.cppsmn_database.cppsmn_datapacks.cppsmn_fakenatives.cppsmn_filesystem.cppsmn_functions.cppsmn_gameconfigs.cppsmn_lang.cppsmn_maplists.cppsmn_players.cppsmn_profiler.cppsmn_sorting.cppsprintf.cppstringutil.cpp
logic_bridge.cppsmn_console.cppsmn_entities.cppsmn_events.cppsmn_keyvalues.cppsmn_protobuf.cppsourcemm_api.cppsourcemod.cppsourcemod.hextensions
bintools
AMBuilderCallMaker.cppCallMaker.hCallWrapper.cppCallWrapper.hextension.cppjit_call_x64.cppjit_compile.hjit_hook.cppx64_macros.h
clientprefs
cstrike
curl
geoip
mysql
12
.gitattributes
vendored
12
.gitattributes
vendored
@ -1,12 +0,0 @@
|
||||
# GitHub views all .h files as C, let's assume it's C++
|
||||
*.h linguist-language=c++
|
||||
|
||||
# Internal tools overriding
|
||||
tools/* linguist-vendored
|
||||
editor/* linguist-vendored
|
||||
|
||||
# Third-party overriding
|
||||
extensions/curl/curl-src/* linguist-vendored
|
||||
extensions/geoip/GeoIP.c linguist-vendored
|
||||
extensions/geoip/GeoIP.h linguist-vendored
|
||||
extensions/sqlite/sqlite-source/* linguist-vendored
|
14
.github/CONTRIBUTING.md
vendored
14
.github/CONTRIBUTING.md
vendored
@ -7,17 +7,17 @@ Please consider the following guidelines when reporting an issue.
|
||||
#### Not for general support
|
||||
This is not the right place to get help with using or installing SourceMod, or for issues with specific, third-party SourceMod plugins or extensions.
|
||||
|
||||
For help with SourceMod, please consult the [AlliedModders forums](https://forums.alliedmods.net/forumdisplay.php?f=52). Similarly, for assistance with, or to report issues with, third-party SourceMod plugins or extensions, you should post in the existing thread for that plugin or extension on the [AlliedModders forums](https://forums.alliedmods.net/forumdisplay.php?f=52).
|
||||
For help with SourceMod, please consult the [AlliedModders forums](https://forums.alliedmods.net/forumdisplay.php?f=52). Similary, for assistance with, or to report issues with third-party SourceMod plugins or extension, you should post in the existing thread for the plugin or extension at the [AlliedModders forums](https://forums.alliedmods.net/forumdisplay.php?f=52).
|
||||
|
||||
#### Details, details, details
|
||||
Provide as much detail as possible when reporting an issue.
|
||||
|
||||
For bugs or other undesired behavior, answers to the following questions are a great start:
|
||||
For bugs or other undesired behavior, answers to the follow questions are a great start.
|
||||
* What is the issue?
|
||||
* What behavior are you expecting instead?
|
||||
* On what operating system is the game server running?
|
||||
* What game is the game server running?
|
||||
* What exact version (full x.y.z.a version number) of Metamod:Source and SourceMod are installed on the game server?
|
||||
* What exact (full x.y.z.a version number) version of Metamod:Source and SourceMod are installed on the game server?
|
||||
* What is the specific, shortest path to reproducing this issue? If this issue can be reproduced with plugin code, please try to shorten it to the minimum required to trigger the problem.
|
||||
|
||||
If this is a feature request, the following are helpful. Generally, not all will apply, but whatever you can answer ahead of time will shorten back and forth conversation.
|
||||
@ -29,18 +29,18 @@ If this is a feature request, the following are helpful. Generally, not all will
|
||||
Please report any security bugs to [security@alliedmods.net](mailto:security@alliedmods.net) rather than to this public issue tracker.
|
||||
|
||||
#### We're only human
|
||||
Please keep in mind that we maintain this project in our spare time, at no cost. There is no SLA, and you are not owed a response or a fix.
|
||||
Please keep in mind that we maintain the project in our spare time, at no cost. There is no SLA, and you are not owed a response or fix.
|
||||
|
||||
#### Conduct
|
||||
Please refer to the [AlliedModders forum rules.](https://forums.alliedmods.net/misc.php?do=showrules)
|
||||
|
||||
## Pull Requests
|
||||
|
||||
Firstly, thank you for considering contributing changes to the project!
|
||||
Firstly, thank you for considering to contribute changes to the project!
|
||||
|
||||
However, if this is anything more than a small fix such as a gamedata update, a glaring code flaw, or a simple typo in a file like this one, please file an issue first so that it can be discussed, unless you have already spoken to multiple members of the development team about it on IRC or the AlliedModders forums.
|
||||
However, if this is anything more than a small fix such an a gamedata update, a glaring code flaw, or a simple typo in a file like this one, please file an issue first so that it can be discussed, unless you have already spoken to multiple members of the development team about it on IRC or the AlliedModders forums.
|
||||
|
||||
We don't like to have to reject pull requests, so we want to avoid those scenarios. We wouldn't want you to feel like you wasted your time writing something only for us to shoot it down.
|
||||
We don't like to have to reject pull requests, so we want to avoid those scenarios. We wouldn't want you to feel that you wasted your time writing something only for us to have it then be shot down.
|
||||
|
||||
#### Rejection
|
||||
*Copied from Phabricator's [Contributing Code guidelines](https://secure.phabricator.com/book/phabcontrib/article/contributing_code/#rejecting-patches), as we largely feel the same way about this.*
|
||||
|
8
.github/FUNDING.yml
vendored
8
.github/FUNDING.yml
vendored
@ -1,8 +0,0 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
|
||||
patreon: # Replace with a single Patreon username
|
||||
open_collective: # Replace with a single Open Collective username
|
||||
ko_fi: # Replace with a single Ko-fi username
|
||||
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
||||
custom: https://www.sourcemod.net/donate.php
|
26
.github/ISSUE_TEMPLATE.md
vendored
26
.github/ISSUE_TEMPLATE.md
vendored
@ -1,26 +0,0 @@
|
||||
# Help us help you
|
||||
- [ ] I have checked that my issue [doesn't exist yet](https://github.com/alliedmodders/sourcemod/issues).
|
||||
- [ ] I have tried my absolute best to reduce the problem-space and have provided the absolute smallest test-case possible.
|
||||
- [ ] I can always reproduce the issue with the provided description below.
|
||||
|
||||
# Environment
|
||||
* Operating System version:
|
||||
* Game/AppID (with version if applicable):
|
||||
* Current SourceMod version:
|
||||
* Current SourceMod snapshot:
|
||||
* Current Metamod: Source snapshot:
|
||||
- [ ] I have updated SourceMod to the [latest version](https://www.sourcemod.net/downloads.php) and it still happens.
|
||||
- [ ] I have updated SourceMod to the [latest snapshot](https://www.sourcemod.net/downloads.php?branch=dev) and it still happens.
|
||||
- [ ] I have updated SourceMM to the [latest snapshot](https://sourcemm.net/downloads.php?branch=dev) and it still happens.
|
||||
|
||||
# Description
|
||||
|
||||
|
||||
# Problematic Code (or Steps to Reproduce)
|
||||
```
|
||||
// TODO(you): code here to reproduce the problem
|
||||
```
|
||||
|
||||
# Logs
|
||||
* Please attach in separate files: game output, library logs, kernel logs, and any other supporting information.
|
||||
* In case of a crash, please attach minidump or dump analyze output.
|
@ -9,7 +9,6 @@ addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- llvm-toolchain-trusty-3.9
|
||||
- llvm-toolchain-trusty-4.0
|
||||
- llvm-toolchain-trusty-5.0
|
||||
packages:
|
||||
@ -24,7 +23,6 @@ addons:
|
||||
# - clang-5.0
|
||||
# - g++-6
|
||||
# - g++-6-multilib
|
||||
- clang-3.9
|
||||
- g++-4.8-multilib
|
||||
- g++-4.8
|
||||
- g++-4.9-multilib
|
||||
@ -114,5 +112,5 @@ script:
|
||||
- mkdir build && cd build
|
||||
- PATH="~/.local/bin:$PATH"
|
||||
- eval "${MATRIX_EVAL}"
|
||||
- python ../configure.py --enable-optimize --sdks=episode1,css,tf2,l4d2,csgo,dota
|
||||
- python ../configure.py --enable-optimize --sdks=episode1,tf2,l4d2,csgo,dota
|
||||
- ambuild
|
||||
|
177
AMBuildScript
177
AMBuildScript
@ -11,29 +11,10 @@ class SDK(object):
|
||||
self.platform = platform
|
||||
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, target, archs):
|
||||
if target.platform not in self.platformSpec:
|
||||
return False
|
||||
if not len([i for i in self.platformSpec[target.platform] if i in archs]):
|
||||
return False
|
||||
return True
|
||||
|
||||
WinOnly = ['windows']
|
||||
WinLinux = ['windows', 'linux']
|
||||
WinLinuxMac = ['windows', 'linux', 'mac']
|
||||
CSGO = {
|
||||
'windows': ['x86'],
|
||||
'linux': ['x86', 'x64'],
|
||||
'mac': ['x64']
|
||||
}
|
||||
|
||||
PossibleSDKs = {
|
||||
'episode1': SDK('HL2SDK', '2.ep1', '1', 'EPISODEONE', WinLinux, 'episode1'),
|
||||
@ -50,7 +31,7 @@ PossibleSDKs = {
|
||||
'swarm': SDK('HL2SDK-SWARM', '2.swarm', '16', 'ALIENSWARM', WinOnly, 'swarm'),
|
||||
'bgt': SDK('HL2SDK-BGT', '2.bgt', '4', 'BLOODYGOODTIME', WinOnly, 'bgt'),
|
||||
'eye': SDK('HL2SDK-EYE', '2.eye', '5', 'EYE', WinOnly, 'eye'),
|
||||
'csgo': SDK('HL2SDKCSGO', '2.csgo', '21', 'CSGO', CSGO, 'csgo'),
|
||||
'csgo': SDK('HL2SDKCSGO', '2.csgo', '21', 'CSGO', WinLinux, 'csgo'),
|
||||
'portal2': SDK('HL2SDKPORTAL2', '2.portal2', '17', 'PORTAL2', [], 'portal2'),
|
||||
'blade': SDK('HL2SDKBLADE', '2.blade', '18', 'BLADE', WinLinux, 'blade'),
|
||||
'insurgency': SDK('HL2SDKINSURGENCY', '2.insurgency', '19', 'INSURGENCY', WinLinuxMac, 'insurgency'),
|
||||
@ -80,28 +61,6 @@ def ResolveEnvPath(env, folder):
|
||||
def Normalize(path):
|
||||
return os.path.abspath(os.path.normpath(path))
|
||||
|
||||
def SetArchFlags(compiler, arch, platform):
|
||||
if compiler.behavior == 'gcc':
|
||||
if arch == 'x86':
|
||||
compiler.cflags += ['-m32']
|
||||
compiler.linkflags += ['-m32']
|
||||
if platform == 'mac':
|
||||
compiler.linkflags += ['-arch', 'i386']
|
||||
elif arch == 'x64':
|
||||
compiler.cflags += ['-m64', '-fPIC']
|
||||
compiler.linkflags += ['-m64']
|
||||
if platform == 'mac':
|
||||
compiler.linkflags += ['-arch', 'x86_64']
|
||||
elif compiler.like('msvc'):
|
||||
if builder.target.arch == 'x86':
|
||||
compiler.linkflags += ['/MACHINE:X86']
|
||||
elif builder.target.arch == 'x64':
|
||||
compiler.linkflags += ['/MACHINE:X64']
|
||||
|
||||
def AppendArchSuffix(binary, name, arch):
|
||||
if arch == 'x64':
|
||||
binary.localFolder = name + '.x64'
|
||||
|
||||
class SMConfig(object):
|
||||
def __init__(self):
|
||||
self.sdks = {}
|
||||
@ -109,12 +68,10 @@ class SMConfig(object):
|
||||
self.extensions = []
|
||||
self.generated_headers = None
|
||||
self.mms_root = None
|
||||
self.mysql_root = {}
|
||||
self.mysql_root = None
|
||||
self.spcomp = None
|
||||
self.spcomp_bins = None
|
||||
self.smx_files = {}
|
||||
self.versionlib = None
|
||||
self.archs = builder.target.arch.replace('x86_64', 'x64').split(',')
|
||||
|
||||
def use_auto_versioning(self):
|
||||
if builder.backend != 'amb2':
|
||||
@ -148,7 +105,7 @@ class SMConfig(object):
|
||||
|
||||
for sdk_name in PossibleSDKs:
|
||||
sdk = PossibleSDKs[sdk_name]
|
||||
if sdk.shouldBuild(builder.target, self.archs):
|
||||
if builder.target.platform in sdk.platform:
|
||||
if builder.options.hl2sdk_root:
|
||||
sdk_path = os.path.join(builder.options.hl2sdk_root, sdk.folder)
|
||||
else:
|
||||
@ -161,9 +118,8 @@ class SMConfig(object):
|
||||
sdk.path = Normalize(sdk_path)
|
||||
self.sdks[sdk_name] = sdk
|
||||
|
||||
if len(self.sdks) < 1 and len(sdk_list):
|
||||
raise Exception('No SDKs were found that build on {0}-{1}, nothing to do.'.format(
|
||||
builder.target.platform, builder.target.arch))
|
||||
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
|
||||
@ -180,40 +136,21 @@ class SMConfig(object):
|
||||
|
||||
if builder.options.hasMySql:
|
||||
if builder.options.mysql_path:
|
||||
self.mysql_root['x86'] = builder.options.mysql_path
|
||||
self.mysql_root = builder.options.mysql_path
|
||||
else:
|
||||
for i in range(10):
|
||||
self.mysql_root['x86'] = ResolveEnvPath('MYSQL55', 'mysql-5.' + str(i))
|
||||
if self.mysql_root['x86']:
|
||||
for i in range(7):
|
||||
self.mysql_root = ResolveEnvPath('MYSQL5', 'mysql-5.' + str(i))
|
||||
if self.mysql_root:
|
||||
break
|
||||
if not self.mysql_root['x86'] or not os.path.isdir(self.mysql_root['x86']):
|
||||
if not self.mysql_root or not os.path.isdir(self.mysql_root):
|
||||
raise Exception('Could not find a path to MySQL!')
|
||||
self.mysql_root['x86'] = Normalize(self.mysql_root['x86'])
|
||||
|
||||
# For now, ignore 64-bit MySQL on Windows
|
||||
if 'x64' in self.archs and builder.target.platform != 'windows':
|
||||
if builder.options.mysql64_path:
|
||||
self.mysql_root['x64'] = builder.options.mysql64_path
|
||||
else:
|
||||
for i in range(10):
|
||||
self.mysql_root['x64'] = ResolveEnvPath('MYSQL55_64', 'mysql-5.' + str(i) + '-x86_64')
|
||||
if self.mysql_root['x64']:
|
||||
break
|
||||
if not self.mysql_root['x64'] or not os.path.isdir(self.mysql_root['x64']):
|
||||
raise Exception('Could not find a path to 64-bit MySQL!')
|
||||
self.mysql_root['x64'] = Normalize(self.mysql_root['x64'])
|
||||
self.mysql_root = Normalize(self.mysql_root)
|
||||
|
||||
def configure(self):
|
||||
builder.AddConfigureFile('pushbuild.txt')
|
||||
|
||||
if not set(self.archs).issubset(['x86', 'x64']):
|
||||
raise Exception('Unknown target architecture: {0}'.format(builder.target.arch))
|
||||
|
||||
cxx = builder.DetectCxx()
|
||||
|
||||
if cxx.like('msvc') and len(self.archs) > 1:
|
||||
raise Exception('Building multiple archs with MSVC is not currently supported')
|
||||
|
||||
if cxx.like('gcc'):
|
||||
self.configure_gcc(cxx)
|
||||
elif cxx.family == 'msvc':
|
||||
@ -263,11 +200,12 @@ class SMConfig(object):
|
||||
'-pipe',
|
||||
'-fno-strict-aliasing',
|
||||
'-Wall',
|
||||
'-Werror',
|
||||
# '-Werror',
|
||||
'-Wno-unused',
|
||||
'-Wno-switch',
|
||||
'-Wno-array-bounds',
|
||||
'-msse',
|
||||
'-m32',
|
||||
'-fvisibility=hidden',
|
||||
]
|
||||
cxx.cxxflags += [
|
||||
@ -278,6 +216,7 @@ class SMConfig(object):
|
||||
'-Wno-overloaded-virtual',
|
||||
'-fvisibility-inlines-hidden',
|
||||
]
|
||||
cxx.linkflags += ['-m32']
|
||||
|
||||
have_gcc = cxx.family == 'gcc'
|
||||
have_clang = cxx.family == 'clang'
|
||||
@ -295,8 +234,7 @@ class SMConfig(object):
|
||||
cxx.cxxflags += ['-Wno-delete-non-virtual-dtor']
|
||||
if cxx.version >= 'gcc-4.8':
|
||||
cxx.cflags += ['-Wno-unused-result']
|
||||
if cxx.version >= 'gcc-9.0':
|
||||
cxx.cxxflags += ['-Wno-class-memaccess', '-Wno-packed-not-aligned']
|
||||
|
||||
if have_clang:
|
||||
cxx.cxxflags += ['-Wno-implicit-exception-spec-mismatch']
|
||||
if cxx.version >= 'apple-clang-5.1' or cxx.version >= 'clang-3.4':
|
||||
@ -333,6 +271,7 @@ class SMConfig(object):
|
||||
'/TP',
|
||||
]
|
||||
cxx.linkflags += [
|
||||
'/MACHINE:X86',
|
||||
'kernel32.lib',
|
||||
'user32.lib',
|
||||
'gdi32.lib',
|
||||
@ -371,6 +310,7 @@ class SMConfig(object):
|
||||
cxx.cflags += ['-mmacosx-version-min=10.5']
|
||||
cxx.linkflags += [
|
||||
'-mmacosx-version-min=10.5',
|
||||
'-arch', 'i386',
|
||||
'-lstdc++',
|
||||
'-stdlib=libstdc++',
|
||||
]
|
||||
@ -379,7 +319,7 @@ class SMConfig(object):
|
||||
def configure_windows(self, cxx):
|
||||
cxx.defines += ['WIN32', '_WINDOWS']
|
||||
|
||||
def AddVersioning(self, binary, arch):
|
||||
def AddVersioning(self, binary):
|
||||
if builder.target.platform == 'windows':
|
||||
binary.sources += ['version.rc']
|
||||
binary.compiler.rcdefines += [
|
||||
@ -395,51 +335,45 @@ class SMConfig(object):
|
||||
'-current_version', self.productVersion
|
||||
]
|
||||
if self.use_auto_versioning():
|
||||
binary.compiler.linkflags += [self.versionlib[arch]]
|
||||
binary.compiler.linkflags += [self.versionlib]
|
||||
binary.compiler.sourcedeps += SM.generated_headers
|
||||
return binary
|
||||
|
||||
def LibraryBuilder(self, compiler, name, arch):
|
||||
def LibraryBuilder(self, compiler, name):
|
||||
binary = compiler.Library(name)
|
||||
AppendArchSuffix(binary, name, arch)
|
||||
self.AddVersioning(binary, arch)
|
||||
self.AddVersioning(binary)
|
||||
if binary.compiler.like('msvc'):
|
||||
binary.compiler.linkflags += ['/SUBSYSTEM:WINDOWS']
|
||||
return binary
|
||||
|
||||
def ProgramBuilder(self, compiler, name, arch):
|
||||
def ProgramBuilder(self, compiler, name):
|
||||
binary = compiler.Program(name)
|
||||
AppendArchSuffix(binary, name, arch)
|
||||
self.AddVersioning(binary, arch)
|
||||
self.AddVersioning(binary)
|
||||
if '-static-libgcc' in binary.compiler.linkflags:
|
||||
binary.compiler.linkflags.remove('-static-libgcc')
|
||||
if '-lgcc_eh' in binary.compiler.linkflags:
|
||||
binary.compiler.linkflags.remove('-lgcc_eh')
|
||||
if binary.compiler.like('gcc'):
|
||||
binary.compiler.linkflags += ['-lstdc++', '-lpthread']
|
||||
binary.compiler.linkflags += ['-lstdc++']
|
||||
if binary.compiler.like('msvc'):
|
||||
binary.compiler.linkflags += ['/SUBSYSTEM:CONSOLE']
|
||||
return binary
|
||||
|
||||
def StaticLibraryBuilder(self, compiler, name, arch):
|
||||
def StaticLibraryBuilder(self, compiler, name):
|
||||
binary = compiler.StaticLibrary(name)
|
||||
AppendArchSuffix(binary, name, arch)
|
||||
return binary;
|
||||
|
||||
def Library(self, context, name, arch):
|
||||
def Library(self, context, name):
|
||||
compiler = context.cxx.clone()
|
||||
SetArchFlags(compiler, arch, builder.target.platform)
|
||||
return self.LibraryBuilder(compiler, name, arch)
|
||||
return self.LibraryBuilder(compiler, name)
|
||||
|
||||
def Program(self, context, name, arch):
|
||||
def Program(self, context, name):
|
||||
compiler = context.cxx.clone()
|
||||
SetArchFlags(compiler, arch, builder.target.platform)
|
||||
return self.ProgramBuilder(compiler, name, arch)
|
||||
return self.ProgramBuilder(compiler, name)
|
||||
|
||||
def StaticLibrary(self, context, name, arch):
|
||||
def StaticLibrary(self, context, name):
|
||||
compiler = context.cxx.clone()
|
||||
SetArchFlags(compiler, arch, builder.target.platform)
|
||||
return self.StaticLibraryBuilder(compiler, name, arch)
|
||||
return self.StaticLibraryBuilder(compiler, name)
|
||||
|
||||
def ConfigureForExtension(self, context, compiler):
|
||||
compiler.cxxincludes += [
|
||||
@ -452,16 +386,14 @@ class SMConfig(object):
|
||||
]
|
||||
return compiler
|
||||
|
||||
def ExtLibrary(self, context, name, arch):
|
||||
binary = self.Library(context, name, arch)
|
||||
def ExtLibrary(self, context, name):
|
||||
binary = self.Library(context, name)
|
||||
self.ConfigureForExtension(context, binary.compiler)
|
||||
return binary
|
||||
|
||||
def ConfigureForHL2(self, binary, sdk, arch):
|
||||
def ConfigureForHL2(self, binary, sdk):
|
||||
compiler = binary.compiler
|
||||
|
||||
SetArchFlags(compiler, arch, builder.target.platform)
|
||||
|
||||
compiler.cxxincludes += [
|
||||
os.path.join(self.mms_root, 'core'),
|
||||
os.path.join(self.mms_root, 'core', 'sourcehook'),
|
||||
@ -503,9 +435,6 @@ class SMConfig(object):
|
||||
else:
|
||||
compiler.defines += ['COMPILER_GCC']
|
||||
|
||||
if arch == 'x64':
|
||||
compiler.defines += ['X64BITS', 'PLATFORM_64BITS']
|
||||
|
||||
# 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', 'doi', 'csgo']:
|
||||
@ -517,7 +446,6 @@ class SMConfig(object):
|
||||
|
||||
if sdk.name == 'csgo' and builder.target.platform == 'linux':
|
||||
compiler.linkflags += ['-lstdc++']
|
||||
compiler.defines += ['_GLIBCXX_USE_CXX11_ABI=0']
|
||||
|
||||
for path in paths:
|
||||
compiler.cxxincludes += [os.path.join(sdk.path, *path)]
|
||||
@ -527,20 +455,16 @@ class SMConfig(object):
|
||||
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')
|
||||
elif arch == 'x64':
|
||||
lib_folder = os.path.join(sdk.path, 'lib', 'linux64')
|
||||
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')
|
||||
elif arch == 'x64':
|
||||
lib_folder = os.path.join(sdk.path, 'lib', 'osx64')
|
||||
else:
|
||||
lib_folder = os.path.join(sdk.path, 'lib', 'mac')
|
||||
|
||||
if builder.target.platform in ['linux', 'mac']:
|
||||
if sdk.name in ['sdk2013', 'bms'] or arch == 'x64':
|
||||
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'))
|
||||
@ -552,17 +476,12 @@ class SMConfig(object):
|
||||
]
|
||||
|
||||
if sdk.name in ['blade', 'insurgency', 'doi', 'csgo']:
|
||||
if arch == 'x64':
|
||||
compiler.postlink += [compiler.Dep(os.path.join(lib_folder, 'interfaces.a'))]
|
||||
else:
|
||||
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', 'doi']:
|
||||
dynamic_libs = ['libtier0_srv.so', 'libvstdlib_srv.so']
|
||||
elif arch == 'x64' and sdk.name == 'csgo':
|
||||
dynamic_libs = ['libtier0_client.so', 'libvstdlib_client.so']
|
||||
elif sdk.name in ['l4d', 'blade', 'insurgency', 'doi', 'csgo']:
|
||||
dynamic_libs = ['libtier0.so', 'libvstdlib.so']
|
||||
else:
|
||||
@ -593,21 +512,20 @@ class SMConfig(object):
|
||||
|
||||
return binary
|
||||
|
||||
def HL2Library(self, context, name, sdk, arch):
|
||||
binary = self.Library(context, name, arch)
|
||||
def HL2Library(self, context, name, sdk):
|
||||
binary = self.Library(context, name)
|
||||
self.ConfigureForExtension(context, binary.compiler)
|
||||
return self.ConfigureForHL2(binary, sdk, arch)
|
||||
return self.ConfigureForHL2(binary, sdk)
|
||||
|
||||
def HL2Project(self, context, name):
|
||||
project = context.cxx.LibraryProject(name)
|
||||
self.ConfigureForExtension(context, project.compiler)
|
||||
return project
|
||||
|
||||
def HL2Config(self, project, name, sdk, arch):
|
||||
def HL2Config(self, project, name, sdk):
|
||||
binary = project.Configure(name, '{0} - {1}'.format(self.tag, sdk.name))
|
||||
AppendArchSuffix(binary, name, arch)
|
||||
self.AddVersioning(binary, arch)
|
||||
return self.ConfigureForHL2(binary, sdk, arch)
|
||||
self.AddVersioning(binary)
|
||||
return self.ConfigureForHL2(binary, sdk)
|
||||
|
||||
SM = SMConfig()
|
||||
SM.detectProductVersion()
|
||||
@ -630,15 +548,10 @@ SP = builder.Build('sourcepawn/AMBuildScript', {
|
||||
'external_amtl': os.path.join(builder.sourcePath, 'public', 'amtl'),
|
||||
'external_build': ['core'],
|
||||
})
|
||||
if len(SP.spcomp) > 1:
|
||||
SM.spcomp = SP.spcomp['x86']
|
||||
else:
|
||||
SM.spcomp = SP.spcomp[list(SP.spcomp.keys())[0]]
|
||||
SM.spcomp_bins = list(SP.spcomp.values())
|
||||
for arch in SM.archs:
|
||||
SM.binaries += [
|
||||
SP.libsourcepawn[arch]
|
||||
]
|
||||
SM.spcomp = SP.spcomp
|
||||
SM.binaries += [
|
||||
SP.libsourcepawn
|
||||
]
|
||||
|
||||
BuildScripts = [
|
||||
'loader/AMBuilder',
|
||||
|
10
README.md
10
README.md
@ -14,14 +14,4 @@ Development
|
||||
- [Issue tracker](https://github.com/alliedmodders/sourcemod/issues): Issues that require back and forth communication
|
||||
- [Building SourceMod](https://wiki.alliedmods.net/Building_SourceMod): Instructions on how to build SourceMod itself using [AMBuild](https://github.com/alliedmodders/ambuild)
|
||||
- [SourcePawn scripting](https://wiki.alliedmods.net/Category:SourceMod_Scripting): SourcePawn examples and introduction to the language
|
||||
- [SourceMod plugin API](https://sm.alliedmods.net/new-api): Online SourceMod plugin API reference generated from the include files
|
||||
- [SourceMod extension development](https://wiki.alliedmods.net/Category:SourceMod_Development): C++ examples and introduction to various extension interfaces
|
||||
|
||||
Contact
|
||||
-------
|
||||
- Connect with us on [GameSurge](https://gamesurge.net) IRC in #sourcemod
|
||||
- Alternatively feel free to join our [Discord](https://discord.gg/HgZctSS) server
|
||||
|
||||
License
|
||||
-------
|
||||
SourceMod is licensed under the GNU General Public License version 3. Special exceptions are outlined in the LICENSE.txt file inside of the licenses folder.
|
||||
|
@ -35,7 +35,7 @@ namespace SourceMod {
|
||||
|
||||
// Add 1 to the RHS of this expression to bump the intercom file
|
||||
// This is to prevent mismatching core/logic binaries
|
||||
static const uint32_t SM_LOGIC_MAGIC = 0x0F47C0DE - 57;
|
||||
static const uint32_t SM_LOGIC_MAGIC = 0x0F47C0DE - 55;
|
||||
|
||||
} // namespace SourceMod
|
||||
|
||||
|
@ -50,6 +50,7 @@ class IProviderCallbacks;
|
||||
class IExtensionSys;
|
||||
class ITextParsers;
|
||||
class ILogger;
|
||||
class IDataPack;
|
||||
class ICellArray;
|
||||
|
||||
struct sm_logic_t
|
||||
@ -69,10 +70,10 @@ struct sm_logic_t
|
||||
void (*GenerateError)(IPluginContext *, cell_t, int, const char *, ...);
|
||||
void (*AddNatives)(sp_nativeinfo_t *natives);
|
||||
void (*RegisterProfiler)(IProfilingTool *tool);
|
||||
IDataPack * (*CreateDataPack)();
|
||||
void (*FreeDataPack)(IDataPack *pack);
|
||||
ICellArray * (*CreateCellArray)(size_t blocksize);
|
||||
void (*FreeCellArray)(ICellArray *arr);
|
||||
void * (*FromPseudoAddress)(uint32_t pseudoAddr);
|
||||
uint32_t (*ToPseudoAddress)(void *addr);
|
||||
IScriptManager *scripts;
|
||||
IShareSys *sharesys;
|
||||
IExtensionSys *extsys;
|
||||
|
@ -22,8 +22,6 @@ parser.options.add_option('--hl2sdk-root', type=str, dest='hl2sdk_root', default
|
||||
help='Root search folder for HL2SDKs')
|
||||
parser.options.add_option('--mysql-path', type=str, dest='mysql_path', default=None,
|
||||
help='Path to MySQL 5')
|
||||
parser.options.add_option('--mysql64-path', type=str, dest='mysql64_path', default=None,
|
||||
help='Path to 64-bit MySQL 5')
|
||||
parser.options.add_option('--mms-path', type=str, dest='mms_path', default=None,
|
||||
help='Path to Metamod:Source')
|
||||
parser.options.add_option('--enable-debug', action='store_const', const='1', dest='debug',
|
||||
|
@ -44,13 +44,9 @@ project.sources += [
|
||||
|
||||
for sdk_name in SM.sdks:
|
||||
sdk = SM.sdks[sdk_name]
|
||||
for arch in SM.archs:
|
||||
if not arch in sdk.platformSpec[builder.target.platform]:
|
||||
continue
|
||||
|
||||
binary_name = 'sourcemod.' + sdk.ext
|
||||
|
||||
binary = SM.HL2Config(project, binary_name, sdk, arch)
|
||||
binary = SM.HL2Config(project, binary_name, sdk)
|
||||
compiler = binary.compiler
|
||||
|
||||
compiler.cxxincludes += [
|
||||
@ -65,22 +61,17 @@ for sdk_name in SM.sdks:
|
||||
]
|
||||
|
||||
if compiler.like('msvc'):
|
||||
compiler.defines += ['_ALLOW_KEYWORD_MACROS']
|
||||
compiler.defines += ['_XKEYCHECK_H']
|
||||
|
||||
if builder.target.platform == 'linux':
|
||||
compiler.postlink += ['-lpthread', '-lrt']
|
||||
|
||||
if sdk.name == 'csgo':
|
||||
if builder.target.platform == 'linux':
|
||||
if arch == 'x86':
|
||||
lib_path = os.path.join(sdk.path, 'lib', 'linux32', 'release', 'libprotobuf.a')
|
||||
elif arch == 'x64':
|
||||
lib_path = os.path.join(sdk.path, 'lib', 'linux64', 'release', 'libprotobuf.a')
|
||||
compiler.linkflags += ['-Wl,--exclude-libs=libprotobuf.a']
|
||||
elif builder.target.platform == 'mac':
|
||||
if arch == 'x86':
|
||||
lib_path = os.path.join(sdk.path, 'lib', 'osx32', 'release', 'libprotobuf.a')
|
||||
elif arch == 'x64':
|
||||
lib_path = os.path.join(sdk.path, 'lib', 'osx64', 'release', 'libprotobuf.a')
|
||||
elif builder.target.platform == 'windows':
|
||||
msvc_ver = compiler.version
|
||||
vs_year = ''
|
||||
|
@ -317,7 +317,7 @@ bool ConCmdManager::CheckAccess(int client, const char *cmd, AdminCmdInfo *pAdmi
|
||||
char buffer[128];
|
||||
if (!logicore.CoreTranslate(buffer, sizeof(buffer), "%T", 2, NULL, "No Access", &client))
|
||||
{
|
||||
ke::SafeStrcpy(buffer, sizeof(buffer), "You do not have access to this command");
|
||||
ke::SafeSprintf(buffer, sizeof(buffer), "You do not have access to this command");
|
||||
}
|
||||
|
||||
unsigned int replyto = g_ChatTriggers.GetReplyTo();
|
||||
@ -342,10 +342,9 @@ bool ConCmdManager::AddAdminCommand(IPluginFunction *pFunction,
|
||||
const char *group,
|
||||
int adminflags,
|
||||
const char *description,
|
||||
int flags,
|
||||
IPlugin *pPlugin)
|
||||
int flags)
|
||||
{
|
||||
ConCmdInfo *pInfo = AddOrFindCommand(name, description, flags, pPlugin);
|
||||
ConCmdInfo *pInfo = AddOrFindCommand(name, description, flags);
|
||||
|
||||
if (!pInfo)
|
||||
return false;
|
||||
@ -389,11 +388,10 @@ bool ConCmdManager::AddAdminCommand(IPluginFunction *pFunction,
|
||||
bool ConCmdManager::AddServerCommand(IPluginFunction *pFunction,
|
||||
const char *name,
|
||||
const char *description,
|
||||
int flags,
|
||||
IPlugin *pPlugin)
|
||||
int flags)
|
||||
|
||||
{
|
||||
ConCmdInfo *pInfo = AddOrFindCommand(name, description, flags, pPlugin);
|
||||
ConCmdInfo *pInfo = AddOrFindCommand(name, description, flags);
|
||||
|
||||
if (!pInfo)
|
||||
return false;
|
||||
@ -557,7 +555,7 @@ bool ConCmdManager::LookForCommandAdminFlags(const char *cmd, FlagBits *pFlags)
|
||||
return true;
|
||||
}
|
||||
|
||||
ConCmdInfo *ConCmdManager::AddOrFindCommand(const char *name, const char *description, int flags, IPlugin *pPlugin)
|
||||
ConCmdInfo *ConCmdManager::AddOrFindCommand(const char *name, const char *description, int flags)
|
||||
{
|
||||
ConCmdInfo *pInfo;
|
||||
if (!m_Cmds.retrieve(name, &pInfo))
|
||||
@ -582,7 +580,6 @@ ConCmdInfo *ConCmdManager::AddOrFindCommand(const char *name, const char *descri
|
||||
char *new_name = sm_strdup(name);
|
||||
char *new_help = sm_strdup(description);
|
||||
pCmd = new ConCommand(new_name, CommandCallback, new_help, flags);
|
||||
pInfo->pPlugin = pPlugin;
|
||||
pInfo->sourceMod = true;
|
||||
}
|
||||
else
|
||||
|
@ -41,7 +41,6 @@
|
||||
#include <IAdminSystem.h>
|
||||
#include "concmd_cleaner.h"
|
||||
#include "GameHooks.h"
|
||||
#include <am-autoptr.h>
|
||||
#include <sm_stringhashmap.h>
|
||||
#include <am-utility.h>
|
||||
#include <am-inlinelist.h>
|
||||
@ -99,9 +98,8 @@ struct ConCmdInfo
|
||||
{
|
||||
ConCmdInfo()
|
||||
{
|
||||
pPlugin = nullptr;
|
||||
sourceMod = false;
|
||||
pCmd = nullptr;
|
||||
pCmd = NULL;
|
||||
eflags = 0;
|
||||
}
|
||||
bool sourceMod; /**< Determines whether or not concmd was created by a SourceMod plugin */
|
||||
@ -109,7 +107,6 @@ struct ConCmdInfo
|
||||
CmdHookList hooks; /**< Hook list */
|
||||
FlagBits eflags; /**< Effective admin flags */
|
||||
ke::RefPtr<CommandHook> sh_hook; /**< SourceHook hook, if any. */
|
||||
IPlugin *pPlugin; /**< Owning plugin handle. */
|
||||
};
|
||||
|
||||
typedef List<ConCmdInfo *> ConCmdList;
|
||||
@ -134,14 +131,13 @@ public: //IRootConsoleCommand
|
||||
public: //IConCommandTracker
|
||||
void OnUnlinkConCommandBase(ConCommandBase *pBase, const char *name) override;
|
||||
public:
|
||||
bool AddServerCommand(IPluginFunction *pFunction, const char *name, const char *description, int flags, IPlugin *pPlugin);
|
||||
bool AddServerCommand(IPluginFunction *pFunction, const char *name, const char *description, int flags);
|
||||
bool AddAdminCommand(IPluginFunction *pFunction,
|
||||
const char *name,
|
||||
const char *group,
|
||||
int adminflags,
|
||||
const char *description,
|
||||
int flags,
|
||||
IPlugin *pPlugin);
|
||||
int flags);
|
||||
ResultType DispatchClientCommand(int client, const char *cmd, int args, ResultType type);
|
||||
void UpdateAdminCmdFlags(const char *cmd, OverrideType type, FlagBits bits, bool remove);
|
||||
bool LookForSourceModCommand(const char *cmd);
|
||||
@ -149,7 +145,7 @@ public:
|
||||
private:
|
||||
bool InternalDispatch(int client, const ICommandArgs *args);
|
||||
ResultType RunAdminCommand(ConCmdInfo *pInfo, int client, int args);
|
||||
ConCmdInfo *AddOrFindCommand(const char *name, const char *description, int flags, IPlugin *pPlugin);
|
||||
ConCmdInfo *AddOrFindCommand(const char *name, const char *description, int flags);
|
||||
void AddToCmdList(ConCmdInfo *info);
|
||||
void RemoveConCmd(ConCmdInfo *info, const char *cmd, bool untrack);
|
||||
bool CheckAccess(int client, const char *cmd, AdminCmdInfo *pAdmin);
|
||||
|
@ -364,8 +364,8 @@ void EventManager::FireEvent(EventInfo *pInfo, bool bDontBroadcast)
|
||||
|
||||
void EventManager::FireEventToClient(EventInfo *pInfo, IClient *pClient)
|
||||
{
|
||||
// The IClient vtable is +sizeof(void *) from the IGameEventListener2 (CBaseClient) vtable due to multiple inheritance.
|
||||
IGameEventListener2 *pGameClient = (IGameEventListener2 *)((intptr_t)pClient - sizeof(void *));
|
||||
// The IClient vtable is +4 from the IGameEventListener2 (CBaseClient) vtable due to multiple inheritance.
|
||||
IGameEventListener2 *pGameClient = (IGameEventListener2 *)((intptr_t)pClient - 4);
|
||||
pGameClient->FireGameEvent(pInfo->pEvent);
|
||||
}
|
||||
|
||||
|
@ -50,8 +50,8 @@
|
||||
|
||||
typedef ICommandLine *(*FakeGetCommandLine)();
|
||||
|
||||
#define TIER0_NAME FORMAT_SOURCE_BIN_NAME("tier0")
|
||||
#define VSTDLIB_NAME FORMAT_SOURCE_BIN_NAME("vstdlib")
|
||||
#define TIER0_NAME SOURCE_BIN_PREFIX "tier0" SOURCE_BIN_SUFFIX SOURCE_BIN_EXT
|
||||
#define VSTDLIB_NAME SOURCE_BIN_PREFIX "vstdlib" SOURCE_BIN_SUFFIX SOURCE_BIN_EXT
|
||||
|
||||
CHalfLife2 g_HL2;
|
||||
ConVar *sv_lan = NULL;
|
||||
@ -139,7 +139,6 @@ void CHalfLife2::OnSourceModAllInitialized_Post()
|
||||
m_CSGOBadList.add("m_flFallbackWear");
|
||||
m_CSGOBadList.add("m_nFallbackStatTrak");
|
||||
m_CSGOBadList.add("m_iCompetitiveRanking");
|
||||
m_CSGOBadList.add("m_iCompetitiveRankType");
|
||||
m_CSGOBadList.add("m_nActiveCoinRank");
|
||||
m_CSGOBadList.add("m_nMusicID");
|
||||
#endif
|
||||
@ -163,7 +162,7 @@ ConfigResult CHalfLife2::OnSourceModConfigChanged(const char *key, const char *v
|
||||
}
|
||||
else
|
||||
{
|
||||
ke::SafeStrcpy(error, maxlength, "Invalid value: must be \"yes\" or \"no\"");
|
||||
ke::SafeSprintf(error, maxlength, "Invalid value: must be \"yes\" or \"no\"");
|
||||
return ConfigResult_Reject;
|
||||
}
|
||||
#endif
|
||||
@ -228,12 +227,7 @@ void CHalfLife2::InitLogicalEntData()
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef PLATFORM_X86
|
||||
g_EntList = *reinterpret_cast<void **>(addr + offset);
|
||||
#elif defined PLATFORM_X64
|
||||
int32_t varOffset = *reinterpret_cast<int32_t *>(addr + offset);
|
||||
g_EntList = reinterpret_cast<void *>(addr + offset + sizeof(int32_t) + varOffset);
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
@ -833,7 +827,7 @@ void CHalfLife2::AddDelayedKick(int client, int userid, const char *msg)
|
||||
|
||||
kick.client = client;
|
||||
kick.userid = userid;
|
||||
ke::SafeStrcpy(kick.buffer, sizeof(kick.buffer), msg);
|
||||
ke::SafeSprintf(kick.buffer, sizeof(kick.buffer), "%s", msg);
|
||||
|
||||
m_DelayedKicks.push(kick);
|
||||
}
|
||||
@ -1200,7 +1194,7 @@ bool IsWindowsReservedDeviceName(const char *pMapname)
|
||||
};
|
||||
|
||||
size_t reservedCount = sizeof(reservedDeviceNames) / sizeof(reservedDeviceNames[0]);
|
||||
for (size_t i = 0; i < reservedCount; ++i)
|
||||
for (int i = 0; i < reservedCount; ++i)
|
||||
{
|
||||
if (CheckReservedFilename(pMapname, reservedDeviceNames[i]))
|
||||
{
|
||||
@ -1266,11 +1260,7 @@ SMFindMapResult CHalfLife2::FindMap(const char *pMapName, char *pFoundMap, size_
|
||||
return SMFindMapResult::FuzzyMatch;
|
||||
}
|
||||
|
||||
#elif SOURCE_ENGINE == SE_TF2 || SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_HL2DM \
|
||||
|| SOURCE_ENGINE == SE_SDK2013 || SOURCE_ENGINE == SE_BMS
|
||||
static IVEngineServer *engine23 = (IVEngineServer *)(g_SMAPI->GetEngineFactory()("VEngineServer023", nullptr));
|
||||
if (engine23)
|
||||
{
|
||||
#elif SOURCE_ENGINE == SE_TF2 || SOURCE_ENGINE == SE_BMS
|
||||
static char szTemp[PLATFORM_MAX_PATH];
|
||||
if (pFoundMap == NULL)
|
||||
{
|
||||
@ -1280,12 +1270,9 @@ SMFindMapResult CHalfLife2::FindMap(const char *pMapName, char *pFoundMap, size_
|
||||
}
|
||||
|
||||
return static_cast<SMFindMapResult>(engine->FindMap(pFoundMap, static_cast<int>(nMapNameMax)));
|
||||
}
|
||||
else
|
||||
{
|
||||
#elif SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_SDK2013
|
||||
static IVEngineServer *engine21 = (IVEngineServer *)(g_SMAPI->GetEngineFactory()("VEngineServer021", nullptr));
|
||||
return engine21->IsMapValid(pMapName) == 0 ? SMFindMapResult::NotFound : SMFindMapResult::Found;
|
||||
}
|
||||
#else
|
||||
return engine->IsMapValid(pMapName) == 0 ? SMFindMapResult::NotFound : SMFindMapResult::Found;
|
||||
#endif
|
||||
@ -1313,7 +1300,7 @@ bool CHalfLife2::IsMapValid(const char *map)
|
||||
if (!map || !map[0])
|
||||
return false;
|
||||
|
||||
return FindMap(map) == SMFindMapResult::Found;
|
||||
return FindMap(map) != SMFindMapResult::NotFound;
|
||||
}
|
||||
|
||||
// TODO: Add ep1 support for this. (No IServerTools available there)
|
||||
@ -1352,7 +1339,7 @@ string_t CHalfLife2::AllocPooledString(const char *pszValue)
|
||||
|
||||
bool CHalfLife2::GetServerSteam3Id(char *pszOut, size_t len) const
|
||||
{
|
||||
CSteamID sid((uint64)GetServerSteamId64());
|
||||
CSteamID sid(GetServerSteamId64());
|
||||
|
||||
switch (sid.GetEAccountType())
|
||||
{
|
||||
|
@ -84,9 +84,6 @@ using namespace SourceMod;
|
||||
#define SOURCE_BIN_EXT ".so"
|
||||
#endif
|
||||
|
||||
#define FORMAT_SOURCE_BIN_NAME(basename) \
|
||||
(SOURCE_BIN_PREFIX basename SOURCE_BIN_SUFFIX SOURCE_BIN_EXT)
|
||||
|
||||
struct DataTableInfo
|
||||
{
|
||||
struct SendPropPolicy
|
||||
|
@ -34,7 +34,6 @@
|
||||
|
||||
#include <IMenuManager.h>
|
||||
#include <IPlayerHelpers.h>
|
||||
#include <am-autoptr.h>
|
||||
#include <am-string.h>
|
||||
#include <am-vector.h>
|
||||
#include "sm_fastlink.h"
|
||||
|
@ -458,8 +458,9 @@ void CRadioMenuPlayer::Radio_Init(int keys, const char *title, const char *text)
|
||||
}
|
||||
else
|
||||
{
|
||||
display_len = ke::SafeStrcpy(display_pkt,
|
||||
display_len = ke::SafeSprintf(display_pkt,
|
||||
sizeof(display_pkt),
|
||||
"%s",
|
||||
text);
|
||||
}
|
||||
display_keys = keys;
|
||||
|
@ -138,8 +138,8 @@ void NextMapManager::HookChangeLevel(const char *map, const char *unknown, const
|
||||
|
||||
logger->LogMessage("[SM] Changed map to \"%s\"", newmap);
|
||||
|
||||
ke::SafeStrcpy(m_tempChangeInfo.m_mapName, sizeof(m_tempChangeInfo.m_mapName), newmap);
|
||||
ke::SafeStrcpy(m_tempChangeInfo.m_changeReason, sizeof(m_tempChangeInfo.m_changeReason), "Normal level change");
|
||||
ke::SafeSprintf(m_tempChangeInfo.m_mapName, sizeof(m_tempChangeInfo.m_mapName), newmap);
|
||||
ke::SafeSprintf(m_tempChangeInfo.m_changeReason, sizeof(m_tempChangeInfo.m_changeReason), "Normal level change");
|
||||
|
||||
#if SOURCE_ENGINE != SE_DARKMESSIAH
|
||||
RETURN_META_NEWPARAMS(MRES_IGNORED, &IVEngineServer::ChangeLevel, (newmap, unknown));
|
||||
@ -184,14 +184,14 @@ void NextMapManager::OnSourceModLevelChange( const char *mapName )
|
||||
m_tempChangeInfo.m_mapName[0] ='\0';
|
||||
m_tempChangeInfo.m_changeReason[0] = '\0';
|
||||
m_tempChangeInfo.startTime = time(NULL);
|
||||
ke::SafeStrcpy(lastMap, sizeof(lastMap), mapName);
|
||||
ke::SafeSprintf(lastMap, sizeof(lastMap), "%s", mapName);
|
||||
}
|
||||
|
||||
void NextMapManager::ForceChangeLevel( const char *mapName, const char* changeReason )
|
||||
{
|
||||
/* Store the mapname and reason */
|
||||
ke::SafeStrcpy(m_tempChangeInfo.m_mapName, sizeof(m_tempChangeInfo.m_mapName), mapName);
|
||||
ke::SafeStrcpy(m_tempChangeInfo.m_changeReason, sizeof(m_tempChangeInfo.m_changeReason), changeReason);
|
||||
ke::SafeSprintf(m_tempChangeInfo.m_mapName, sizeof(m_tempChangeInfo.m_mapName), "%s", mapName);
|
||||
ke::SafeSprintf(m_tempChangeInfo.m_changeReason, sizeof(m_tempChangeInfo.m_changeReason), "%s", changeReason);
|
||||
|
||||
/* Change level and skip our hook */
|
||||
g_forcedChange = true;
|
||||
@ -221,7 +221,7 @@ void CmdChangeLevelCallback()
|
||||
|
||||
if (g_NextMap.m_tempChangeInfo.m_mapName[0] == '\0')
|
||||
{
|
||||
ke::SafeStrcpy(g_NextMap.m_tempChangeInfo.m_mapName, sizeof(g_NextMap.m_tempChangeInfo.m_mapName), command.Arg(1));
|
||||
ke::SafeStrcpy(g_NextMap.m_tempChangeInfo.m_changeReason, sizeof(g_NextMap.m_tempChangeInfo.m_changeReason), "changelevel Command");
|
||||
ke::SafeSprintf(g_NextMap.m_tempChangeInfo.m_mapName, sizeof(g_NextMap.m_tempChangeInfo.m_mapName), command.Arg(1));
|
||||
ke::SafeSprintf(g_NextMap.m_tempChangeInfo.m_changeReason, sizeof(g_NextMap.m_tempChangeInfo.m_changeReason), "changelevel Command");
|
||||
}
|
||||
}
|
||||
|
@ -64,7 +64,7 @@ const unsigned int *g_NumPlayersToAuth = NULL;
|
||||
int lifestate_offset = -1;
|
||||
List<ICommandTargetProcessor *> target_processors;
|
||||
|
||||
ConVar sm_debug_connect("sm_debug_connect", "1", 0, "Log Debug information about potential connection issues.");
|
||||
ConVar sm_debug_connect("sm_debug_connect", "0", 0, "Log Debug information about potential connection issues.");
|
||||
|
||||
SH_DECL_HOOK5(IServerGameClients, ClientConnect, SH_NOATTRIB, 0, bool, edict_t *, const char *, const char *, char *, int);
|
||||
SH_DECL_HOOK2_void(IServerGameClients, ClientPutInServer, SH_NOATTRIB, 0, edict_t *, const char *);
|
||||
@ -109,7 +109,7 @@ class KickPlayerTimer : public ITimedEvent
|
||||
public:
|
||||
ResultType OnTimer(ITimer *pTimer, void *pData)
|
||||
{
|
||||
int userid = (int)(intptr_t)pData;
|
||||
int userid = (int)pData;
|
||||
int client = g_Players.GetClientOfUserId(userid);
|
||||
if (client)
|
||||
{
|
||||
@ -212,9 +212,6 @@ void PlayerManager::OnSourceModAllInitialized()
|
||||
SH_ADD_HOOK(ConCommand, Dispatch, pCmd, SH_STATIC(CmdMaxplayersCallback), true);
|
||||
maxplayersCmd = pCmd;
|
||||
}
|
||||
|
||||
gameevents->AddListener(this, "player_connect", true);
|
||||
gameevents->AddListener(this, "player_disconnect", true);
|
||||
}
|
||||
|
||||
void PlayerManager::OnSourceModShutdown()
|
||||
@ -262,8 +259,6 @@ void PlayerManager::OnSourceModShutdown()
|
||||
{
|
||||
SH_REMOVE_HOOK(ConCommand, Dispatch, maxplayersCmd, SH_STATIC(CmdMaxplayersCallback), true);
|
||||
}
|
||||
|
||||
gameevents->RemoveListener(this);
|
||||
}
|
||||
|
||||
ConfigResult PlayerManager::OnSourceModConfigChanged(const char *key,
|
||||
@ -286,7 +281,7 @@ ConfigResult PlayerManager::OnSourceModConfigChanged(const char *key,
|
||||
} else if (strcasecmp(value, "off") == 0) {
|
||||
m_QueryLang = false;
|
||||
} else {
|
||||
ke::SafeStrcpy(error, maxlength, "Invalid value: must be \"on\" or \"off\"");
|
||||
ke::SafeSprintf(error, maxlength, "Invalid value: must be \"on\" or \"off\"");
|
||||
return ConfigResult_Reject;
|
||||
}
|
||||
return ConfigResult_Accept;
|
||||
@ -297,7 +292,7 @@ ConfigResult PlayerManager::OnSourceModConfigChanged(const char *key,
|
||||
} else if ( strcasecmp(value, "no") == 0) {
|
||||
m_bAuthstringValidation = false;
|
||||
} else {
|
||||
ke::SafeStrcpy(error, maxlength, "Invalid value: must be \"yes\" or \"no\"");
|
||||
ke::SafeSprintf(error, maxlength, "Invalid value: must be \"yes\" or \"no\"");
|
||||
return ConfigResult_Reject;
|
||||
}
|
||||
return ConfigResult_Accept;
|
||||
@ -1429,11 +1424,6 @@ int PlayerManager::GetNumPlayers()
|
||||
return m_PlayerCount;
|
||||
}
|
||||
|
||||
int PlayerManager::GetNumClients()
|
||||
{
|
||||
return m_ClientCount;
|
||||
}
|
||||
|
||||
int PlayerManager::GetClientOfUserId(int userid)
|
||||
{
|
||||
if (userid < 0 || userid > USHRT_MAX)
|
||||
@ -2029,27 +2019,6 @@ bool PlayerManager::HandleConVarQuery(QueryCvarCookie_t cookie, int client, EQue
|
||||
}
|
||||
#endif
|
||||
|
||||
/* IGameEventListener2::FireGameEvent */
|
||||
void PlayerManager::FireGameEvent(IGameEvent *pEvent)
|
||||
{
|
||||
const char *name = pEvent->GetName();
|
||||
|
||||
if (strcmp(name, "player_connect") == 0)
|
||||
{
|
||||
const int client = pEvent->GetInt("index") + 1;
|
||||
const int userid = pEvent->GetInt("userid");
|
||||
|
||||
m_ClientCount++;
|
||||
}
|
||||
else if (strcmp(name, "player_disconnect") == 0)
|
||||
{
|
||||
const int userid = pEvent->GetInt("userid");
|
||||
const int client = m_UserIdLookUp[userid];
|
||||
|
||||
m_ClientCount--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*******************
|
||||
*** PLAYER CODE ***
|
||||
@ -2172,18 +2141,18 @@ void CPlayer::UpdateAuthIds()
|
||||
}
|
||||
|
||||
char szAuthBuffer[64];
|
||||
ke::SafeSprintf(szAuthBuffer, sizeof(szAuthBuffer), "STEAM_%u:%u:%u", steam2universe, m_SteamId.GetAccountID() & 1, m_SteamId.GetAccountID() >> 1);
|
||||
snprintf(szAuthBuffer, sizeof(szAuthBuffer), "STEAM_%u:%u:%u", steam2universe, m_SteamId.GetAccountID() & 1, m_SteamId.GetAccountID() >> 1);
|
||||
|
||||
m_Steam2Id = szAuthBuffer;
|
||||
|
||||
// TODO: make sure all hl2sdks' steamclientpublic.h have k_unSteamUserDesktopInstance.
|
||||
if (m_SteamId.GetUnAccountInstance() == 1 /* k_unSteamUserDesktopInstance */)
|
||||
{
|
||||
ke::SafeSprintf(szAuthBuffer, sizeof(szAuthBuffer), "[U:%u:%u]", m_SteamId.GetEUniverse(), m_SteamId.GetAccountID());
|
||||
snprintf(szAuthBuffer, sizeof(szAuthBuffer), "[U:%u:%u]", m_SteamId.GetEUniverse(), m_SteamId.GetAccountID());
|
||||
}
|
||||
else
|
||||
{
|
||||
ke::SafeSprintf(szAuthBuffer, sizeof(szAuthBuffer), "[U:%u:%u:%u]", m_SteamId.GetEUniverse(), m_SteamId.GetAccountID(), m_SteamId.GetUnAccountInstance());
|
||||
snprintf(szAuthBuffer, sizeof(szAuthBuffer), "[U:%u:%u:%u]", m_SteamId.GetEUniverse(), m_SteamId.GetAccountID(), m_SteamId.GetUnAccountInstance());
|
||||
}
|
||||
|
||||
m_Steam3Id = szAuthBuffer;
|
||||
@ -2609,7 +2578,7 @@ void CPlayer::DoBasicAdminChecks()
|
||||
if (!g_Players.CheckSetAdminName(client, this, id))
|
||||
{
|
||||
int userid = engine->GetPlayerUserId(m_pEdict);
|
||||
g_Timers.CreateTimer(&s_KickPlayerTimer, 0.1f, (void *)(intptr_t)userid, 0);
|
||||
g_Timers.CreateTimer(&s_KickPlayerTimer, 0.1f, (void *)userid, 0);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -159,8 +159,7 @@ private:
|
||||
|
||||
class PlayerManager :
|
||||
public SMGlobalClass,
|
||||
public IPlayerManager,
|
||||
public IGameEventListener2
|
||||
public IPlayerManager
|
||||
{
|
||||
friend class CPlayer;
|
||||
public:
|
||||
@ -203,7 +202,6 @@ public: //IPlayerManager
|
||||
IGamePlayer *GetGamePlayer(edict_t *pEdict);
|
||||
int GetMaxClients();
|
||||
int GetNumPlayers();
|
||||
int GetNumClients();
|
||||
int GetClientOfUserId(int userid);
|
||||
bool IsServerActivated();
|
||||
int FilterCommandTarget(IGamePlayer *pAdmin, IGamePlayer *pTarget, int flags);
|
||||
@ -214,8 +212,6 @@ public: //IPlayerManager
|
||||
int GetClientFromSerial(unsigned int serial);
|
||||
void ClearAdminId(AdminId id);
|
||||
void RecheckAnyAdmins();
|
||||
public: // IGameEventListener2
|
||||
void FireGameEvent(IGameEvent *pEvent);
|
||||
public:
|
||||
inline int MaxClients()
|
||||
{
|
||||
@ -276,7 +272,6 @@ private:
|
||||
int m_SourceTVUserId;
|
||||
int m_ReplayUserId;
|
||||
bool m_bInCCKVHook;
|
||||
int m_ClientCount;
|
||||
private:
|
||||
static const int NETMSG_TYPE_BITS = 5; // SVC_Print overhead for netmsg type
|
||||
static const int SVC_Print_BufferSize = 2048 - 1; // -1 for terminating \0
|
||||
|
@ -118,13 +118,6 @@ public:
|
||||
return msg;
|
||||
}
|
||||
|
||||
inline bool HasField(const char *pszFieldName)
|
||||
{
|
||||
GETCHECK_FIELD();
|
||||
CHECK_FIELD_NOT_REPEATED();
|
||||
return msg->GetReflection()->HasField(*msg, field);
|
||||
}
|
||||
|
||||
inline bool GetInt32(const char *pszFieldName, int32 *out)
|
||||
{
|
||||
GETCHECK_FIELD();
|
||||
@ -349,20 +342,6 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool GetInt64OrUnsigned(const char *pszFieldName, int64 *out)
|
||||
{
|
||||
GETCHECK_FIELD();
|
||||
CHECK_FIELD_TYPE2(INT64, UINT64);
|
||||
CHECK_FIELD_NOT_REPEATED();
|
||||
|
||||
if (fieldType == protobuf::FieldDescriptor::CPPTYPE_UINT64)
|
||||
*out = (int64)msg->GetReflection()->GetUInt64(*msg, field);
|
||||
else
|
||||
*out = msg->GetReflection()->GetInt64(*msg, field);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool SetInt32OrUnsignedOrEnum(const char *pszFieldName, int32 value)
|
||||
{
|
||||
GETCHECK_FIELD();
|
||||
@ -389,24 +368,6 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool SetInt64OrUnsigned(const char *pszFieldName, int64 value)
|
||||
{
|
||||
GETCHECK_FIELD();
|
||||
CHECK_FIELD_TYPE2(INT64, UINT64);
|
||||
CHECK_FIELD_NOT_REPEATED();
|
||||
|
||||
if (fieldType == protobuf::FieldDescriptor::CPPTYPE_UINT64)
|
||||
{
|
||||
msg->GetReflection()->SetUInt64(msg, field, (uint64)value);
|
||||
}
|
||||
else
|
||||
{
|
||||
msg->GetReflection()->SetInt64(msg, field, value);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool GetRepeatedInt32OrUnsignedOrEnum(const char *pszFieldName, int index, int32 *out)
|
||||
{
|
||||
GETCHECK_FIELD();
|
||||
@ -424,21 +385,6 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool GetRepeatedInt64OrUnsigned(const char *pszFieldName, int index, int64 *out)
|
||||
{
|
||||
GETCHECK_FIELD();
|
||||
CHECK_FIELD_TYPE2(INT64, UINT64);
|
||||
CHECK_FIELD_REPEATED();
|
||||
CHECK_REPEATED_ELEMENT(index);
|
||||
|
||||
if (fieldType == protobuf::FieldDescriptor::CPPTYPE_UINT64)
|
||||
*out = (int64)msg->GetReflection()->GetRepeatedUInt64(*msg, field, index);
|
||||
else
|
||||
*out = msg->GetReflection()->GetRepeatedInt64(*msg, field, index);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool SetRepeatedInt32OrUnsignedOrEnum(const char *pszFieldName, int index, int32 value)
|
||||
{
|
||||
GETCHECK_FIELD();
|
||||
@ -466,25 +412,6 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool SetRepeatedInt64OrUnsigned(const char *pszFieldName, int index, int64 value)
|
||||
{
|
||||
GETCHECK_FIELD();
|
||||
CHECK_FIELD_TYPE2(INT64, UINT64);
|
||||
CHECK_FIELD_REPEATED();
|
||||
CHECK_REPEATED_ELEMENT(index);
|
||||
|
||||
if (fieldType == protobuf::FieldDescriptor::CPPTYPE_UINT64)
|
||||
{
|
||||
msg->GetReflection()->SetRepeatedUInt64(msg, field, index, (uint64)value);
|
||||
}
|
||||
else
|
||||
{
|
||||
msg->GetReflection()->SetRepeatedInt64(msg, field, index, value);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool AddInt32OrUnsignedOrEnum(const char *pszFieldName, int32 value)
|
||||
{
|
||||
GETCHECK_FIELD();
|
||||
@ -511,24 +438,6 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool AddInt64OrUnsigned(const char *pszFieldName, int64 value)
|
||||
{
|
||||
GETCHECK_FIELD();
|
||||
CHECK_FIELD_TYPE2(INT64, UINT64);
|
||||
CHECK_FIELD_REPEATED();
|
||||
|
||||
if (fieldType == protobuf::FieldDescriptor::CPPTYPE_UINT64)
|
||||
{
|
||||
msg->GetReflection()->AddUInt64(msg, field, (uint64)value);
|
||||
}
|
||||
else
|
||||
{
|
||||
msg->GetReflection()->AddInt64(msg, field, value);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool GetBool(const char *pszFieldName, bool *out)
|
||||
{
|
||||
GETCHECK_FIELD();
|
||||
|
@ -1,9 +1,8 @@
|
||||
# vim: set sts=2 ts=8 sw=2 tw=99 et ft=python:
|
||||
import os
|
||||
|
||||
for arch in SM.archs:
|
||||
binary = SM.Library(builder, 'sourcemod.logic', arch)
|
||||
binary.compiler.cxxincludes += [
|
||||
binary = SM.Library(builder, 'sourcemod.logic')
|
||||
binary.compiler.cxxincludes += [
|
||||
builder.sourcePath,
|
||||
os.path.join(builder.sourcePath, 'core', 'logic'),
|
||||
os.path.join(builder.sourcePath, 'public'),
|
||||
@ -11,24 +10,24 @@ for arch in SM.archs:
|
||||
os.path.join(builder.sourcePath, 'public', 'amtl', 'amtl'),
|
||||
os.path.join(builder.sourcePath, 'public', 'amtl'),
|
||||
os.path.join(SM.mms_root, 'core', 'sourcehook')
|
||||
]
|
||||
binary.compiler.defines += [
|
||||
]
|
||||
binary.compiler.defines += [
|
||||
'SM_DEFAULT_THREADER',
|
||||
'SM_LOGIC'
|
||||
]
|
||||
]
|
||||
|
||||
if builder.target.platform == 'linux':
|
||||
if builder.target.platform == 'linux':
|
||||
binary.compiler.postlink += ['-lpthread', '-lrt']
|
||||
elif builder.target.platform == 'mac':
|
||||
elif builder.target.platform == 'mac':
|
||||
binary.compiler.cflags += ['-Wno-deprecated-declarations']
|
||||
binary.compiler.postlink += ['-framework', 'CoreServices']
|
||||
|
||||
if binary.compiler.family == 'gcc' or binary.compiler.family == 'clang':
|
||||
if binary.compiler.family == 'gcc' or binary.compiler.family == 'clang':
|
||||
binary.compiler.cxxflags += ['-fno-rtti']
|
||||
elif binary.compiler.family == 'msvc':
|
||||
elif binary.compiler.family == 'msvc':
|
||||
binary.compiler.cxxflags += ['/GR-']
|
||||
|
||||
binary.sources += [
|
||||
binary.sources += [
|
||||
'common_logic.cpp',
|
||||
'smn_adt_array.cpp',
|
||||
'smn_sorting.cpp',
|
||||
@ -84,16 +83,12 @@ for arch in SM.archs:
|
||||
'frame_tasks.cpp',
|
||||
'smn_halflife.cpp',
|
||||
'FrameIterator.cpp',
|
||||
'DatabaseConfBuilder.cpp',
|
||||
'NativeInvoker.cpp',
|
||||
]
|
||||
|
||||
if arch == 'x64':
|
||||
binary.sources += ['PseudoAddrManager.cpp']
|
||||
|
||||
if builder.target.platform == 'windows':
|
||||
]
|
||||
if builder.target.platform == 'windows':
|
||||
binary.sources += ['thread/WinThreads.cpp']
|
||||
else:
|
||||
else:
|
||||
binary.sources += ['thread/PosixThreads.cpp']
|
||||
|
||||
SM.binaries += [builder.Add(binary)]
|
||||
|
||||
SM.binaries += [builder.Add(binary)]
|
||||
|
@ -1090,14 +1090,14 @@ bool AdminCache::GetUnifiedSteamIdentity(const char *ident, char *out, size_t ma
|
||||
else if (len >= 11 && !strncmp(ident, "STEAM_", 6) && ident[8] != '_')
|
||||
{
|
||||
// non-bot/lan Steam2 Id, strip off the STEAM_* part
|
||||
ke::SafeStrcpy(out, maxlen, &ident[8]);
|
||||
snprintf(out, maxlen, "%s", &ident[8]);
|
||||
return true;
|
||||
}
|
||||
else if (len >= 7 && !strncmp(ident, "[U:", 3) && ident[len-1] == ']')
|
||||
{
|
||||
// Steam3 Id, replicate the Steam2 Post-"STEAM_" part
|
||||
uint32_t accountId = strtoul(&ident[5], nullptr, 10);
|
||||
ke::SafeSprintf(out, maxlen, "%u:%u", accountId & 1, accountId >> 1);
|
||||
snprintf(out, maxlen, "%u:%u", accountId & 1, accountId >> 1);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
@ -1124,7 +1124,7 @@ bool AdminCache::GetUnifiedSteamIdentity(const char *ident, char *out, size_t ma
|
||||
&& accountType == k_EAccountTypeIndividual && accountInstance <= k_unSteamUserWebInstance
|
||||
)
|
||||
{
|
||||
ke::SafeSprintf(out, maxlen, "%u:%u", accountId & 1, accountId >> 1);
|
||||
snprintf(out, maxlen, "%u:%u", accountId & 1, accountId >> 1);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -33,20 +33,27 @@
|
||||
#include <string.h>
|
||||
#include "CDataPack.h"
|
||||
#include <amtl/am-autoptr.h>
|
||||
#include <amtl/am-vector.h>
|
||||
|
||||
using namespace ke;
|
||||
|
||||
#define DATAPACK_INITIAL_SIZE 64
|
||||
|
||||
CDataPack::CDataPack()
|
||||
{
|
||||
m_pBase = (char *)malloc(DATAPACK_INITIAL_SIZE);
|
||||
m_capacity = DATAPACK_INITIAL_SIZE;
|
||||
Initialize();
|
||||
}
|
||||
|
||||
CDataPack::~CDataPack()
|
||||
{
|
||||
Initialize();
|
||||
free(m_pBase);
|
||||
}
|
||||
|
||||
static ke::Vector<ke::AutoPtr<CDataPack>> sDataPackCache;
|
||||
static Vector<AutoPtr<CDataPack>> sDataPackCache;
|
||||
|
||||
CDataPack *CDataPack::New()
|
||||
IDataPack * CDataPack::New()
|
||||
{
|
||||
if (sDataPackCache.empty())
|
||||
return new CDataPack();
|
||||
@ -58,187 +65,293 @@ CDataPack *CDataPack::New()
|
||||
}
|
||||
|
||||
void
|
||||
CDataPack::Free(CDataPack *pack)
|
||||
CDataPack::Free(IDataPack *pack)
|
||||
{
|
||||
sDataPackCache.append(static_cast<CDataPack *>(pack));
|
||||
}
|
||||
|
||||
void CDataPack::Initialize()
|
||||
{
|
||||
m_curptr = m_pBase;
|
||||
m_size = 0;
|
||||
}
|
||||
|
||||
void CDataPack::CheckSize(size_t typesize)
|
||||
{
|
||||
if (m_curptr - m_pBase + typesize <= m_capacity)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
size_t pos = m_curptr - m_pBase;
|
||||
do
|
||||
{
|
||||
} while (this->RemoveItem());
|
||||
m_capacity *= 2;
|
||||
} while (pos + typesize > m_capacity);
|
||||
|
||||
elements.clear();
|
||||
position = 0;
|
||||
m_pBase = (char *)realloc(m_pBase, m_capacity);
|
||||
m_curptr = m_pBase + pos;
|
||||
}
|
||||
|
||||
void CDataPack::ResetSize()
|
||||
{
|
||||
Initialize();
|
||||
m_size = 0;
|
||||
}
|
||||
|
||||
size_t CDataPack::CreateMemory(size_t size, void **addr)
|
||||
{
|
||||
InternalPack val;
|
||||
val.type = CDataPackType::Raw;
|
||||
val.pData.vval = new uint8_t[size + sizeof(size)];
|
||||
reinterpret_cast<size_t *>(val.pData.vval)[0] = size;
|
||||
elements.insert(position, val);
|
||||
CheckSize(sizeof(char) + sizeof(size_t) + size);
|
||||
size_t pos = m_curptr - m_pBase;
|
||||
|
||||
return position++;
|
||||
*(char *)m_curptr = Raw;
|
||||
m_curptr += sizeof(char);
|
||||
|
||||
*(size_t *)m_curptr = size;
|
||||
m_curptr += sizeof(size_t);
|
||||
|
||||
if (addr)
|
||||
{
|
||||
*addr = m_curptr;
|
||||
}
|
||||
|
||||
m_curptr += size;
|
||||
m_size += sizeof(char) + sizeof(size_t) + size;
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
void CDataPack::PackCell(cell_t cell)
|
||||
{
|
||||
InternalPack val;
|
||||
val.type = CDataPackType::Cell;
|
||||
val.pData.cval = cell;
|
||||
elements.insert(position++, val);
|
||||
CheckSize(sizeof(char) + sizeof(size_t) + sizeof(cell_t));
|
||||
|
||||
*(char *)m_curptr = Cell;
|
||||
m_curptr += sizeof(char);
|
||||
|
||||
*(size_t *)m_curptr = sizeof(cell_t);
|
||||
m_curptr += sizeof(size_t);
|
||||
|
||||
*(cell_t *)m_curptr = cell;
|
||||
m_curptr += sizeof(cell_t);
|
||||
|
||||
m_size += sizeof(char) + sizeof(size_t) + sizeof(cell_t);
|
||||
}
|
||||
|
||||
void CDataPack::PackFunction(cell_t function)
|
||||
void CDataPack::PackFloat(float val)
|
||||
{
|
||||
InternalPack val;
|
||||
val.type = CDataPackType::Function;
|
||||
val.pData.cval = function;
|
||||
elements.insert(position++, val);
|
||||
}
|
||||
CheckSize(sizeof(char) + sizeof(size_t) + sizeof(float));
|
||||
|
||||
void CDataPack::PackFloat(float floatval)
|
||||
{
|
||||
InternalPack val;
|
||||
val.type = CDataPackType::Float;
|
||||
val.pData.fval = floatval;
|
||||
elements.insert(position++, val);
|
||||
*(char *)m_curptr = Float;
|
||||
m_curptr += sizeof(char);
|
||||
|
||||
*(size_t *)m_curptr = sizeof(float);
|
||||
m_curptr += sizeof(size_t);
|
||||
|
||||
*(float *)m_curptr = val;
|
||||
m_curptr += sizeof(float);
|
||||
|
||||
m_size += sizeof(char) + sizeof(size_t) + sizeof(float);
|
||||
}
|
||||
|
||||
void CDataPack::PackString(const char *string)
|
||||
{
|
||||
InternalPack val;
|
||||
val.type = CDataPackType::String;
|
||||
ke::AString *sval = new ke::AString(string);
|
||||
val.pData.sval = sval;
|
||||
elements.insert(position++, val);
|
||||
size_t len = strlen(string);
|
||||
size_t maxsize = sizeof(char) + sizeof(size_t) + len + 1;
|
||||
CheckSize(maxsize);
|
||||
|
||||
*(char *)m_curptr = String;
|
||||
m_curptr += sizeof(char);
|
||||
|
||||
// Pack the string length first for buffer overrun checking.
|
||||
*(size_t *)m_curptr = len;
|
||||
m_curptr += sizeof(size_t);
|
||||
|
||||
// Now pack the string.
|
||||
memcpy(m_curptr, string, len);
|
||||
m_curptr[len] = '\0';
|
||||
m_curptr += len + 1;
|
||||
|
||||
m_size += maxsize;
|
||||
}
|
||||
|
||||
void CDataPack::Reset() const
|
||||
{
|
||||
position = 0;
|
||||
m_curptr = m_pBase;
|
||||
}
|
||||
|
||||
size_t CDataPack::GetPosition() const
|
||||
{
|
||||
return position;
|
||||
return static_cast<size_t>(m_curptr - m_pBase);
|
||||
}
|
||||
|
||||
bool CDataPack::SetPosition(size_t pos) const
|
||||
{
|
||||
if (pos > elements.length())
|
||||
if (pos > m_size)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
m_curptr = m_pBase + pos;
|
||||
|
||||
position = pos;
|
||||
return true;
|
||||
}
|
||||
|
||||
cell_t CDataPack::ReadCell() const
|
||||
{
|
||||
if (!IsReadable() || elements[position].type != CDataPackType::Cell)
|
||||
if (!IsReadable(sizeof(char) + sizeof(size_t) + sizeof(cell_t)))
|
||||
{
|
||||
return 0;
|
||||
|
||||
return elements[position++].pData.cval;
|
||||
}
|
||||
|
||||
cell_t CDataPack::ReadFunction() const
|
||||
{
|
||||
if (!IsReadable() || elements[position].type != CDataPackType::Function)
|
||||
}
|
||||
if (*reinterpret_cast<char *>(m_curptr) != Cell)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
m_curptr += sizeof(char);
|
||||
|
||||
return elements[position++].pData.cval;
|
||||
if (*reinterpret_cast<size_t *>(m_curptr) != sizeof(cell_t))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
m_curptr += sizeof(size_t);
|
||||
|
||||
cell_t val = *reinterpret_cast<cell_t *>(m_curptr);
|
||||
m_curptr += sizeof(cell_t);
|
||||
return val;
|
||||
}
|
||||
|
||||
float CDataPack::ReadFloat() const
|
||||
{
|
||||
if (!IsReadable() || elements[position].type != CDataPackType::Float)
|
||||
if (!IsReadable(sizeof(char) + sizeof(size_t) + sizeof(float)))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (*reinterpret_cast<char *>(m_curptr) != Float)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
m_curptr += sizeof(char);
|
||||
|
||||
return elements[position++].pData.fval;
|
||||
if (*reinterpret_cast<size_t *>(m_curptr) != sizeof(float))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
m_curptr += sizeof(size_t);
|
||||
|
||||
float val = *reinterpret_cast<float *>(m_curptr);
|
||||
m_curptr += sizeof(float);
|
||||
return val;
|
||||
}
|
||||
|
||||
bool CDataPack::IsReadable(size_t bytes) const
|
||||
{
|
||||
return (position < elements.length());
|
||||
return (bytes + (m_curptr - m_pBase) > m_size) ? false : true;
|
||||
}
|
||||
|
||||
const char *CDataPack::ReadString(size_t *len) const
|
||||
{
|
||||
if (!IsReadable() || elements[position].type != CDataPackType::String)
|
||||
if (!IsReadable(sizeof(char) + sizeof(size_t)))
|
||||
{
|
||||
if (len)
|
||||
*len = 0;
|
||||
return NULL;
|
||||
}
|
||||
if (*reinterpret_cast<char *>(m_curptr) != String)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
m_curptr += sizeof(char);
|
||||
|
||||
return nullptr;
|
||||
size_t real_len = *(size_t *)m_curptr;
|
||||
|
||||
m_curptr += sizeof(size_t);
|
||||
char *str = (char *)m_curptr;
|
||||
|
||||
if ((strlen(str) != real_len) || !(IsReadable(real_len+1)))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const ke::AString &val = *elements[position++].pData.sval;
|
||||
if (len)
|
||||
*len = val.length();
|
||||
{
|
||||
*len = real_len;
|
||||
}
|
||||
|
||||
return val.chars();
|
||||
m_curptr += real_len + 1;
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
void *CDataPack::GetMemory() const
|
||||
{
|
||||
return m_curptr;
|
||||
}
|
||||
|
||||
void *CDataPack::ReadMemory(size_t *size) const
|
||||
{
|
||||
void *ptr = nullptr;
|
||||
if (!IsReadable() || elements[position].type != CDataPackType::Raw)
|
||||
return ptr;
|
||||
if (!IsReadable(sizeof(size_t)))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
if (*reinterpret_cast<char *>(m_curptr) != Raw)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
m_curptr += sizeof(char);
|
||||
|
||||
size_t *val = reinterpret_cast<size_t *>(elements[position].pData.vval);
|
||||
ptr = &(val[1]);
|
||||
++position;
|
||||
size_t bytecount = *(size_t *)m_curptr;
|
||||
m_curptr += sizeof(size_t);
|
||||
|
||||
if (!IsReadable(bytecount))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *ptr = m_curptr;
|
||||
|
||||
if (size)
|
||||
*size = val[0]; /* Egor!!!! */
|
||||
{
|
||||
*size = bytecount;
|
||||
}
|
||||
|
||||
m_curptr += bytecount;
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
bool CDataPack::RemoveItem(size_t pos)
|
||||
void CDataPack::PackFunction(cell_t function)
|
||||
{
|
||||
if (!elements.length())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
CheckSize(sizeof(char) + sizeof(size_t) + sizeof(cell_t));
|
||||
|
||||
if (pos == static_cast<size_t>(-1))
|
||||
{
|
||||
pos = position;
|
||||
}
|
||||
if (pos >= elements.length())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
*(char *)m_curptr = Function;
|
||||
m_curptr += sizeof(char);
|
||||
|
||||
if (pos < position) // we're deleting under us, step back
|
||||
{
|
||||
--position;
|
||||
}
|
||||
*(size_t *)m_curptr = sizeof(cell_t);
|
||||
m_curptr += sizeof(size_t);
|
||||
|
||||
switch (elements[pos].type)
|
||||
{
|
||||
case CDataPackType::Raw:
|
||||
{
|
||||
delete elements[pos].pData.vval;
|
||||
break;
|
||||
}
|
||||
*(cell_t *)m_curptr = function;
|
||||
m_curptr += sizeof(cell_t);
|
||||
|
||||
case CDataPackType::String:
|
||||
{
|
||||
delete elements[pos].pData.sval;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
elements.remove(pos);
|
||||
return true;
|
||||
m_size += sizeof(char) + sizeof(size_t) + sizeof(cell_t);
|
||||
}
|
||||
|
||||
cell_t CDataPack::ReadFunction() const
|
||||
{
|
||||
if (!IsReadable(sizeof(char) + sizeof(size_t) + sizeof(cell_t)))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (*reinterpret_cast<char *>(m_curptr) != Function)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
m_curptr += sizeof(char);
|
||||
|
||||
if (*reinterpret_cast<size_t *>(m_curptr) != sizeof(cell_t))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
m_curptr += sizeof(size_t);
|
||||
|
||||
cell_t val = *reinterpret_cast<cell_t *>(m_curptr);
|
||||
m_curptr += sizeof(cell_t);
|
||||
return val;
|
||||
}
|
||||
|
@ -32,165 +32,54 @@
|
||||
#ifndef _INCLUDE_SOURCEMOD_CDATAPACK_H_
|
||||
#define _INCLUDE_SOURCEMOD_CDATAPACK_H_
|
||||
|
||||
#include <ISourceMod.h>
|
||||
#include <amtl/am-vector.h>
|
||||
#include <amtl/am-string.h>
|
||||
#include <IDataPack.h>
|
||||
|
||||
using namespace SourceMod;
|
||||
|
||||
enum CDataPackType {
|
||||
Raw,
|
||||
Cell,
|
||||
Float,
|
||||
String,
|
||||
Function
|
||||
};
|
||||
|
||||
class CDataPack
|
||||
class CDataPack : public IDataPack
|
||||
{
|
||||
public:
|
||||
CDataPack();
|
||||
~CDataPack();
|
||||
|
||||
static CDataPack *New();
|
||||
static void Free(CDataPack *pack);
|
||||
|
||||
public: // Originally IDataReader
|
||||
/**
|
||||
* @brief Resets the position in the data stream to the beginning.
|
||||
*/
|
||||
static IDataPack *New();
|
||||
static void Free(IDataPack *pack);
|
||||
public: //IDataReader
|
||||
void Reset() const;
|
||||
|
||||
/**
|
||||
* @brief Retrieves the current stream position.
|
||||
*
|
||||
* @return Index into the stream.
|
||||
*/
|
||||
size_t GetPosition() const;
|
||||
|
||||
/**
|
||||
* @brief Sets the current stream position.
|
||||
*
|
||||
* @param pos Index to set the stream at.
|
||||
* @return True if succeeded, false if out of bounds.
|
||||
*/
|
||||
bool SetPosition(size_t pos) const;
|
||||
|
||||
/**
|
||||
* @brief Reads one cell from the data stream.
|
||||
*
|
||||
* @return A cell read from the current position.
|
||||
*/
|
||||
cell_t ReadCell() const;
|
||||
|
||||
/**
|
||||
* @brief Reads one float from the data stream.
|
||||
*
|
||||
* @return A float read from the current position.
|
||||
*/
|
||||
float ReadFloat() const;
|
||||
|
||||
/**
|
||||
* @brief Returns whether or not a specified number of bytes from the current stream
|
||||
* position to the end can be read.
|
||||
*
|
||||
* @param bytes Number of bytes to simulate reading.
|
||||
* @return True if can be read, false otherwise.
|
||||
*/
|
||||
bool IsReadable(size_t bytes = 0) const;
|
||||
|
||||
/**
|
||||
* @brief Reads a string from the data stream.
|
||||
*
|
||||
* @param len Optional pointer to store the string length.
|
||||
* @return Pointer to the string, or NULL if out of bounds.
|
||||
*/
|
||||
bool IsReadable(size_t bytes) const;
|
||||
const char *ReadString(size_t *len) const;
|
||||
|
||||
/**
|
||||
* @brief Reads the current position as a generic data type.
|
||||
*
|
||||
* @param size Optional pointer to store the size of the data type.
|
||||
* @return Pointer to the data, or NULL if out of bounds.
|
||||
*/
|
||||
void *GetMemory() const;
|
||||
void *ReadMemory(size_t *size) const;
|
||||
|
||||
/**
|
||||
* @brief Reads a function pointer from the data stream.
|
||||
*
|
||||
* @return A function pointer read from the current position.
|
||||
*/
|
||||
cell_t ReadFunction() const;
|
||||
|
||||
public: // Originally IDataPack
|
||||
/**
|
||||
* @brief Resets the used size of the stream back to zero.
|
||||
*/
|
||||
public: //IDataPack
|
||||
void ResetSize();
|
||||
|
||||
/**
|
||||
* @brief Packs one cell into the data stream.
|
||||
*
|
||||
* @param cell Cell value to write.
|
||||
*/
|
||||
void PackCell(cell_t cell);
|
||||
|
||||
/**
|
||||
* @brief Packs one float into the data stream.
|
||||
*
|
||||
* @param val Float value to write.
|
||||
*/
|
||||
void PackFloat(float val);
|
||||
|
||||
/**
|
||||
* @brief Packs one string into the data stream.
|
||||
* The length is recorded as well for buffer overrun protection.
|
||||
*
|
||||
* @param string String to write.
|
||||
*/
|
||||
void PackString(const char *string);
|
||||
|
||||
/**
|
||||
* @brief Creates a generic block of memory in the stream.
|
||||
*
|
||||
* Note that the pointer it returns can be invalidated on further
|
||||
* writing, since the stream size may grow. You may need to double back
|
||||
* and fetch the pointer again.
|
||||
*
|
||||
* @param size Size of the memory to create in the stream.
|
||||
* @param addr Optional pointer to store the relocated memory address.
|
||||
* @return Current position of the stream beforehand.
|
||||
*/
|
||||
size_t CreateMemory(size_t size, void **addr);
|
||||
|
||||
/**
|
||||
* @brief Packs one function pointer into the data stream.
|
||||
*
|
||||
* @param function The function pointer to write.
|
||||
*/
|
||||
void PackFunction(cell_t function);
|
||||
|
||||
public:
|
||||
void Initialize();
|
||||
inline size_t GetCapacity() const { return this->elements.length(); };
|
||||
inline CDataPackType GetCurrentType(void) const { return this->elements[this->position].type; };
|
||||
bool RemoveItem(size_t pos = -1);
|
||||
|
||||
inline size_t GetCapacity() const { return m_capacity; }
|
||||
private:
|
||||
typedef union {
|
||||
cell_t cval;
|
||||
float fval;
|
||||
uint8_t *vval;
|
||||
ke::AString *sval;
|
||||
} InternalPackValue;
|
||||
void CheckSize(size_t sizetype);
|
||||
private:
|
||||
char *m_pBase;
|
||||
mutable char *m_curptr;
|
||||
size_t m_capacity;
|
||||
size_t m_size;
|
||||
|
||||
typedef struct {
|
||||
InternalPackValue pData;
|
||||
CDataPackType type;
|
||||
} InternalPack;
|
||||
|
||||
ke::Vector<InternalPack> elements;
|
||||
mutable size_t position;
|
||||
enum DataPackType {
|
||||
Raw,
|
||||
Cell,
|
||||
Float,
|
||||
String,
|
||||
Function
|
||||
};
|
||||
};
|
||||
|
||||
#endif //_INCLUDE_SOURCEMOD_CDATAPACK_H_
|
||||
|
@ -227,17 +227,11 @@ private:
|
||||
/* finally, allocate the new block */
|
||||
if (m_Data)
|
||||
{
|
||||
cell_t *data = static_cast<cell_t*>(realloc(m_Data, sizeof(cell_t) * m_BlockSize * m_AllocSize));
|
||||
if (!data) // allocation failure
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
m_Data = data;
|
||||
m_Data = (cell_t *)realloc(m_Data, sizeof(cell_t) * m_BlockSize * m_AllocSize);
|
||||
} else {
|
||||
m_Data = static_cast<cell_t*>(malloc(sizeof(cell_t) * m_BlockSize * m_AllocSize));
|
||||
m_Data = (cell_t *)malloc(sizeof(cell_t) * m_BlockSize * m_AllocSize);
|
||||
}
|
||||
return (m_Data != nullptr);
|
||||
return (m_Data != NULL);
|
||||
}
|
||||
private:
|
||||
cell_t *m_Data;
|
||||
|
@ -37,7 +37,6 @@
|
||||
#include <stdlib.h>
|
||||
#include <IThreader.h>
|
||||
#include <bridge/include/ILogger.h>
|
||||
#include <bridge/include/CoreProvider.h>
|
||||
|
||||
#define DBPARSE_LEVEL_NONE 0
|
||||
#define DBPARSE_LEVEL_MAIN 1
|
||||
@ -48,6 +47,8 @@ static bool s_OneTimeThreaderErrorMsg = false;
|
||||
|
||||
DBManager::DBManager()
|
||||
: m_Terminate(false),
|
||||
m_ParseLevel(0),
|
||||
m_ParseState(0),
|
||||
m_pDefault(NULL)
|
||||
{
|
||||
}
|
||||
@ -71,22 +72,31 @@ void DBManager::OnSourceModAllInitialized()
|
||||
g_ShareSys.AddInterface(NULL, this);
|
||||
|
||||
g_pSM->BuildPath(Path_SM, m_Filename, sizeof(m_Filename), "configs/databases.cfg");
|
||||
m_Builder.SetPath(m_Filename);
|
||||
|
||||
g_PluginSys.AddPluginsListener(this);
|
||||
|
||||
g_pSM->AddGameFrameHook(&FrameHook);
|
||||
|
||||
auto sm_reload_databases = [this] (int client, const ICommandArgs *args) -> bool {
|
||||
m_Builder.StartParse();
|
||||
return true;
|
||||
};
|
||||
bridge->DefineCommand("sm_reload_databases", "Reparse database configurations file", sm_reload_databases);
|
||||
}
|
||||
|
||||
void DBManager::OnSourceModLevelChange(const char *mapName)
|
||||
{
|
||||
m_Builder.StartParse();
|
||||
SMCError err;
|
||||
SMCStates states = {0, 0};
|
||||
|
||||
/* We lock and don't give up the lock until we're done.
|
||||
* This way the thread's search won't be searching through a
|
||||
* potentially empty/corrupt list, which would be very bad.
|
||||
*/
|
||||
ke::AutoLock lock(&m_ConfigLock);
|
||||
if ((err = textparsers->ParseFile_SMC(m_Filename, this, &states)) != SMCError_Okay)
|
||||
{
|
||||
logger->LogError("[SM] Detected parse error(s) in file \"%s\"", m_Filename);
|
||||
if (err != SMCError_Custom)
|
||||
{
|
||||
const char *txt = textparsers->GetSMCErrorString(err);
|
||||
logger->LogError("[SM] Line %d: %s", states.line, txt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DBManager::OnSourceModShutdown()
|
||||
@ -96,6 +106,7 @@ void DBManager::OnSourceModShutdown()
|
||||
g_PluginSys.RemovePluginsListener(this);
|
||||
g_HandleSys.RemoveType(m_DatabaseType, g_pCoreIdent);
|
||||
g_HandleSys.RemoveType(m_DriverType, g_pCoreIdent);
|
||||
ClearConfigs();
|
||||
}
|
||||
|
||||
unsigned int DBManager::GetInterfaceVersion()
|
||||
@ -123,10 +134,136 @@ void DBManager::OnHandleDestroy(HandleType_t type, void *object)
|
||||
}
|
||||
}
|
||||
|
||||
void DBManager::ReadSMC_ParseStart()
|
||||
{
|
||||
ClearConfigs();
|
||||
m_ParseLevel = 0;
|
||||
m_ParseState = DBPARSE_LEVEL_NONE;
|
||||
m_DefDriver.clear();
|
||||
}
|
||||
|
||||
void DBManager::ClearConfigs()
|
||||
{
|
||||
List<ConfDbInfo *>::iterator iter;
|
||||
for (iter=m_confs.begin(); iter!=m_confs.end(); iter++)
|
||||
delete (*iter);
|
||||
m_confs.clear();
|
||||
}
|
||||
|
||||
ConfDbInfo s_CurInfo;
|
||||
SMCResult DBManager::ReadSMC_NewSection(const SMCStates *states, const char *name)
|
||||
{
|
||||
if (m_ParseLevel)
|
||||
{
|
||||
m_ParseLevel++;
|
||||
return SMCResult_Continue;
|
||||
}
|
||||
|
||||
if (m_ParseState == DBPARSE_LEVEL_NONE)
|
||||
{
|
||||
if (strcmp(name, "Databases") == 0)
|
||||
{
|
||||
m_ParseState = DBPARSE_LEVEL_MAIN;
|
||||
} else {
|
||||
m_ParseLevel++;
|
||||
}
|
||||
} else if (m_ParseState == DBPARSE_LEVEL_MAIN) {
|
||||
s_CurInfo = ConfDbInfo();
|
||||
s_CurInfo.name = name;
|
||||
m_ParseState = DBPARSE_LEVEL_DATABASE;
|
||||
} else if (m_ParseState == DBPARSE_LEVEL_DATABASE) {
|
||||
m_ParseLevel++;
|
||||
}
|
||||
|
||||
return SMCResult_Continue;
|
||||
}
|
||||
|
||||
SMCResult DBManager::ReadSMC_KeyValue(const SMCStates *states, const char *key, const char *value)
|
||||
{
|
||||
if (m_ParseLevel)
|
||||
{
|
||||
return SMCResult_Continue;
|
||||
}
|
||||
|
||||
if (m_ParseState == DBPARSE_LEVEL_MAIN)
|
||||
{
|
||||
if (strcmp(key, "driver_default") == 0)
|
||||
{
|
||||
m_DefDriver.assign(value);
|
||||
}
|
||||
} else if (m_ParseState == DBPARSE_LEVEL_DATABASE) {
|
||||
if (strcmp(key, "driver") == 0)
|
||||
{
|
||||
if (strcmp(value, "default") != 0)
|
||||
{
|
||||
s_CurInfo.driver = value;
|
||||
}
|
||||
} else if (strcmp(key, "database") == 0) {
|
||||
s_CurInfo.database = value;
|
||||
} else if (strcmp(key, "host") == 0) {
|
||||
s_CurInfo.host = value;
|
||||
} else if (strcmp(key, "user") == 0) {
|
||||
s_CurInfo.user = value;
|
||||
} else if (strcmp(key, "pass") == 0) {
|
||||
s_CurInfo.pass = value;
|
||||
} else if (strcmp(key, "timeout") == 0) {
|
||||
s_CurInfo.info.maxTimeout = atoi(value);
|
||||
} else if (strcmp(key, "port") == 0) {
|
||||
s_CurInfo.info.port = atoi(value);
|
||||
}
|
||||
}
|
||||
|
||||
return SMCResult_Continue;
|
||||
}
|
||||
|
||||
SMCResult DBManager::ReadSMC_LeavingSection(const SMCStates *states)
|
||||
{
|
||||
if (m_ParseLevel)
|
||||
{
|
||||
m_ParseLevel--;
|
||||
return SMCResult_Continue;
|
||||
}
|
||||
|
||||
if (m_ParseState == DBPARSE_LEVEL_DATABASE)
|
||||
{
|
||||
ConfDbInfo *cdb = new ConfDbInfo();
|
||||
|
||||
cdb->name = s_CurInfo.name;
|
||||
cdb->driver = s_CurInfo.driver;
|
||||
cdb->host = s_CurInfo.host;
|
||||
cdb->user = s_CurInfo.user;
|
||||
cdb->pass = s_CurInfo.pass;
|
||||
cdb->database = s_CurInfo.database;
|
||||
cdb->realDriver = s_CurInfo.realDriver;
|
||||
cdb->info.maxTimeout = s_CurInfo.info.maxTimeout;
|
||||
cdb->info.port = s_CurInfo.info.port;
|
||||
|
||||
cdb->info.driver = cdb->driver.c_str();
|
||||
cdb->info.database = cdb->database.c_str();
|
||||
cdb->info.host = cdb->host.c_str();
|
||||
cdb->info.user = cdb->user.c_str();
|
||||
cdb->info.pass = cdb->pass.c_str();
|
||||
|
||||
/* Save it.. */
|
||||
m_confs.push_back(cdb);
|
||||
|
||||
/* Go up one level */
|
||||
m_ParseState = DBPARSE_LEVEL_MAIN;
|
||||
} else if (m_ParseState == DBPARSE_LEVEL_MAIN) {
|
||||
m_ParseState = DBPARSE_LEVEL_NONE;
|
||||
return SMCResult_Halt;
|
||||
}
|
||||
|
||||
return SMCResult_Continue;
|
||||
}
|
||||
|
||||
void DBManager::ReadSMC_ParseEnd(bool halted, bool failed)
|
||||
{
|
||||
}
|
||||
|
||||
bool DBManager::Connect(const char *name, IDBDriver **pdr, IDatabase **pdb, bool persistent, char *error, size_t maxlength)
|
||||
{
|
||||
ConfDbInfoList *list = m_Builder.GetConfigList();
|
||||
ke::RefPtr<ConfDbInfo> pInfo = list->GetDatabaseConf(name);
|
||||
ConfDbInfo *pInfo = GetDatabaseConf(name);
|
||||
|
||||
if (!pInfo)
|
||||
{
|
||||
@ -145,12 +282,11 @@ bool DBManager::Connect(const char *name, IDBDriver **pdr, IDatabase **pdb, bool
|
||||
/* Try to assign a real driver pointer */
|
||||
if (pInfo->info.driver[0] == '\0')
|
||||
{
|
||||
ke::AString defaultDriver = list->GetDefaultDriver();
|
||||
if (!m_pDefault && defaultDriver.length() > 0)
|
||||
if (!m_pDefault && m_DefDriver.size() > 0)
|
||||
{
|
||||
m_pDefault = FindOrLoadDriver(defaultDriver.chars());
|
||||
m_pDefault = FindOrLoadDriver(m_DefDriver.c_str());
|
||||
}
|
||||
dname = defaultDriver.length() ? defaultDriver.chars() : "default";
|
||||
dname = m_DefDriver.size() ? m_DefDriver.c_str() : "default";
|
||||
pInfo->realDriver = m_pDefault;
|
||||
} else {
|
||||
pInfo->realDriver = FindOrLoadDriver(pInfo->info.driver);
|
||||
@ -174,6 +310,7 @@ bool DBManager::Connect(const char *name, IDBDriver **pdr, IDatabase **pdb, bool
|
||||
*pdb = NULL;
|
||||
|
||||
g_pSM->Format(error, maxlength, "Driver \"%s\" not found", dname);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -206,17 +343,17 @@ void DBManager::RemoveDriver(IDBDriver *pDriver)
|
||||
}
|
||||
}
|
||||
|
||||
ConfDbInfoList *list = m_Builder.GetConfigList();
|
||||
for (size_t i = 0; i < list->length(); i++)
|
||||
/* Make sure NOTHING references this! */
|
||||
List<ConfDbInfo *>::iterator iter;
|
||||
for (iter=m_confs.begin(); iter!=m_confs.end(); iter++)
|
||||
{
|
||||
ke::RefPtr<ConfDbInfo> current = list->at(i);
|
||||
if (current->realDriver == pDriver)
|
||||
ConfDbInfo &db = *(*iter);
|
||||
if (db.realDriver == pDriver)
|
||||
{
|
||||
current->realDriver = NULL;
|
||||
db.realDriver = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Someone unloaded the default driver? Silly.. */
|
||||
if (pDriver == m_pDefault)
|
||||
{
|
||||
@ -252,11 +389,9 @@ void DBManager::RemoveDriver(IDBDriver *pDriver)
|
||||
|
||||
IDBDriver *DBManager::GetDefaultDriver()
|
||||
{
|
||||
ConfDbInfoList *list = m_Builder.GetConfigList();
|
||||
ke::AString defaultDriver = list->GetDefaultDriver();
|
||||
if (!m_pDefault && defaultDriver.length() > 0)
|
||||
if (!m_pDefault && m_DefDriver.size() > 0)
|
||||
{
|
||||
m_pDefault = FindOrLoadDriver(defaultDriver.chars());
|
||||
m_pDefault = FindOrLoadDriver(m_DefDriver.c_str());
|
||||
}
|
||||
|
||||
return m_pDefault;
|
||||
@ -319,26 +454,29 @@ IDBDriver *DBManager::GetDriver(unsigned int index)
|
||||
|
||||
const DatabaseInfo *DBManager::FindDatabaseConf(const char *name)
|
||||
{
|
||||
ConfDbInfoList *list = m_Builder.GetConfigList();
|
||||
ke::RefPtr<ConfDbInfo> info = list->GetDatabaseConf(name);
|
||||
if (!info)
|
||||
{
|
||||
// couldn't find requested conf, return default if exists
|
||||
info = list->GetDefaultConfiguration();
|
||||
ConfDbInfo *info = GetDatabaseConf(name);
|
||||
if (!info)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return &info->info;
|
||||
}
|
||||
|
||||
ConfDbInfo *DBManager::GetDatabaseConf(const char *name)
|
||||
{
|
||||
ConfDbInfoList *list = m_Builder.GetConfigList();
|
||||
ke::RefPtr<ConfDbInfo> info(list->GetDatabaseConf(name));
|
||||
return info;
|
||||
List<ConfDbInfo *>::iterator iter;
|
||||
|
||||
for (iter=m_confs.begin(); iter!=m_confs.end(); iter++)
|
||||
{
|
||||
ConfDbInfo &conf = *(*iter);
|
||||
if (conf.name == name)
|
||||
{
|
||||
return &conf;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
IDBDriver *DBManager::FindOrLoadDriver(const char *name)
|
||||
@ -591,13 +729,23 @@ void DBManager::OnPluginWillUnload(IPlugin *plugin)
|
||||
}
|
||||
}
|
||||
|
||||
ke::AString DBManager::GetDefaultDriverName()
|
||||
void DBManager::LockConfig()
|
||||
{
|
||||
ConfDbInfoList *list = m_Builder.GetConfigList();
|
||||
return list->GetDefaultDriver();
|
||||
m_ConfigLock.Lock();
|
||||
}
|
||||
|
||||
void DBManager::UnlockConfig()
|
||||
{
|
||||
m_ConfigLock.Unlock();
|
||||
}
|
||||
|
||||
const char *DBManager::GetDefaultDriverName()
|
||||
{
|
||||
return m_DefDriver.c_str();
|
||||
}
|
||||
|
||||
void DBManager::AddDependency(IExtension *myself, IDBDriver *driver)
|
||||
{
|
||||
g_Extensions.AddRawDependency(myself, driver->GetIdentity(), driver);
|
||||
}
|
||||
|
||||
|
@ -32,24 +32,39 @@
|
||||
#ifndef _INCLUDE_DATABASE_MANAGER_H_
|
||||
#define _INCLUDE_DATABASE_MANAGER_H_
|
||||
|
||||
#include <IDBDriver.h>
|
||||
#include "common_logic.h"
|
||||
#include <sh_vector.h>
|
||||
#include <am-string.h>
|
||||
#include <sh_string.h>
|
||||
#include <sh_list.h>
|
||||
#include <ITextParsers.h>
|
||||
#include <IThreader.h>
|
||||
#include <IPluginSys.h>
|
||||
#include <am-thread-utils.h>
|
||||
#include "sm_simple_prioqueue.h"
|
||||
#include <am-refcounting.h>
|
||||
#include "DatabaseConfBuilder.h"
|
||||
|
||||
using namespace SourceHook;
|
||||
|
||||
struct ConfDbInfo
|
||||
{
|
||||
ConfDbInfo() : realDriver(NULL)
|
||||
{
|
||||
}
|
||||
String name;
|
||||
String driver;
|
||||
String host;
|
||||
String user;
|
||||
String pass;
|
||||
String database;
|
||||
IDBDriver *realDriver;
|
||||
DatabaseInfo info;
|
||||
};
|
||||
|
||||
class DBManager :
|
||||
public IDBManager,
|
||||
public SMGlobalClass,
|
||||
public IHandleTypeDispatch,
|
||||
public ITextListener_SMC,
|
||||
public IPluginsListener
|
||||
{
|
||||
public:
|
||||
@ -68,7 +83,6 @@ public: //IDBManager
|
||||
void AddDriver(IDBDriver *pDrivera);
|
||||
void RemoveDriver(IDBDriver *pDriver);
|
||||
const DatabaseInfo *FindDatabaseConf(const char *name);
|
||||
ConfDbInfo *GetDatabaseConf(const char *name);
|
||||
bool Connect(const char *name, IDBDriver **pdr, IDatabase **pdb, bool persistent, char *error, size_t maxlength);
|
||||
unsigned int GetDriverCount();
|
||||
IDBDriver *GetDriver(unsigned int index);
|
||||
@ -76,16 +90,25 @@ public: //IDBManager
|
||||
HandleError ReadHandle(Handle_t hndl, DBHandleType type, void **ptr);
|
||||
HandleError ReleaseHandle(Handle_t hndl, DBHandleType type, IdentityToken_t *token);
|
||||
void AddDependency(IExtension *myself, IDBDriver *driver);
|
||||
public: //ITextListener_SMC
|
||||
void ReadSMC_ParseStart();
|
||||
SMCResult ReadSMC_NewSection(const SMCStates *states, const char *name);
|
||||
SMCResult ReadSMC_KeyValue(const SMCStates *states, const char *key, const char *value);
|
||||
SMCResult ReadSMC_LeavingSection(const SMCStates *states);
|
||||
void ReadSMC_ParseEnd(bool halted, bool failed);
|
||||
public: //ke::IRunnable
|
||||
void Run();
|
||||
void ThreadMain();
|
||||
public: //IPluginsListener
|
||||
void OnPluginWillUnload(IPlugin *plugin);
|
||||
public:
|
||||
ConfDbInfo *GetDatabaseConf(const char *name);
|
||||
IDBDriver *FindOrLoadDriver(const char *name);
|
||||
IDBDriver *GetDefaultDriver();
|
||||
ke::AString GetDefaultDriverName();
|
||||
const char *GetDefaultDriverName();
|
||||
bool AddToThreadQueue(IDBThreadOperation *op, PrioQueueLevel prio);
|
||||
void LockConfig();
|
||||
void UnlockConfig();
|
||||
void RunFrame();
|
||||
inline HandleType_t GetDatabaseType()
|
||||
{
|
||||
@ -103,13 +126,17 @@ private:
|
||||
CVector<bool> m_drSafety; /* which drivers are safe? */
|
||||
ke::AutoPtr<ke::Thread> m_Worker;
|
||||
ke::ConditionVariable m_QueueEvent;
|
||||
ke::Mutex m_ConfigLock;
|
||||
ke::Mutex m_ThinkLock;
|
||||
bool m_Terminate;
|
||||
|
||||
DatabaseConfBuilder m_Builder;
|
||||
List<ConfDbInfo *> m_confs;
|
||||
HandleType_t m_DriverType;
|
||||
HandleType_t m_DatabaseType;
|
||||
String m_DefDriver;
|
||||
char m_Filename[PLATFORM_MAX_PATH];
|
||||
unsigned int m_ParseLevel;
|
||||
unsigned int m_ParseState;
|
||||
IDBDriver *m_pDefault;
|
||||
};
|
||||
|
||||
|
@ -1,184 +0,0 @@
|
||||
/**
|
||||
* vim: set ts=4 sw=4 tw=99 noet :
|
||||
* =============================================================================
|
||||
* SourceMod
|
||||
* Copyright (C) 2004-2018 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* 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 <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
#include "DatabaseConfBuilder.h"
|
||||
#include <bridge/include/ILogger.h>
|
||||
|
||||
#define DBPARSE_LEVEL_NONE 0
|
||||
#define DBPARSE_LEVEL_MAIN 1
|
||||
#define DBPARSE_LEVEL_DATABASE 2
|
||||
|
||||
DatabaseConfBuilder::DatabaseConfBuilder()
|
||||
: m_ParseList(nullptr),
|
||||
m_InfoList(new ConfDbInfoList())
|
||||
{
|
||||
}
|
||||
|
||||
void DatabaseConfBuilder::SetPath(char *str)
|
||||
{
|
||||
m_Filename = str;
|
||||
}
|
||||
|
||||
DatabaseConfBuilder::~DatabaseConfBuilder()
|
||||
{
|
||||
}
|
||||
|
||||
ConfDbInfoList *DatabaseConfBuilder::GetConfigList()
|
||||
{
|
||||
return m_InfoList;
|
||||
}
|
||||
|
||||
void DatabaseConfBuilder::StartParse()
|
||||
{
|
||||
SMCError err;
|
||||
SMCStates states = {0, 0};
|
||||
if ((err = textparsers->ParseFile_SMC(m_Filename.chars(), this, &states)) != SMCError_Okay)
|
||||
{
|
||||
logger->LogError("[SM] Detected parse error(s) in file \"%s\"", m_Filename.chars());
|
||||
if (err != SMCError_Custom)
|
||||
{
|
||||
const char *txt = textparsers->GetSMCErrorString(err);
|
||||
logger->LogError("[SM] Line %d: %s", states.line, txt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DatabaseConfBuilder::ReadSMC_ParseStart()
|
||||
{
|
||||
m_ParseLevel = 0;
|
||||
m_ParseState = DBPARSE_LEVEL_NONE;
|
||||
|
||||
m_ParseList = new ConfDbInfoList();
|
||||
}
|
||||
|
||||
SMCResult DatabaseConfBuilder::ReadSMC_NewSection(const SMCStates *states, const char *name)
|
||||
{
|
||||
if (m_ParseLevel)
|
||||
{
|
||||
m_ParseLevel++;
|
||||
return SMCResult_Continue;
|
||||
}
|
||||
|
||||
if (m_ParseState == DBPARSE_LEVEL_NONE)
|
||||
{
|
||||
if (strcmp(name, "Databases") == 0)
|
||||
{
|
||||
m_ParseState = DBPARSE_LEVEL_MAIN;
|
||||
} else {
|
||||
m_ParseLevel++;
|
||||
}
|
||||
} else if (m_ParseState == DBPARSE_LEVEL_MAIN) {
|
||||
m_ParseCurrent = new ConfDbInfo();
|
||||
m_ParseCurrent->name = name;
|
||||
m_ParseState = DBPARSE_LEVEL_DATABASE;
|
||||
} else if (m_ParseState == DBPARSE_LEVEL_DATABASE) {
|
||||
m_ParseLevel++;
|
||||
}
|
||||
|
||||
return SMCResult_Continue;
|
||||
}
|
||||
|
||||
SMCResult DatabaseConfBuilder::ReadSMC_KeyValue(const SMCStates *states, const char *key, const char *value)
|
||||
{
|
||||
if (m_ParseLevel)
|
||||
{
|
||||
return SMCResult_Continue;
|
||||
}
|
||||
|
||||
if (m_ParseState == DBPARSE_LEVEL_MAIN)
|
||||
{
|
||||
if (strcmp(key, "driver_default") == 0)
|
||||
{
|
||||
m_ParseList->SetDefaultDriver(value);
|
||||
}
|
||||
} else if (m_ParseState == DBPARSE_LEVEL_DATABASE) {
|
||||
if (strcmp(key, "driver") == 0)
|
||||
{
|
||||
if (strcmp(value, "default") != 0)
|
||||
{
|
||||
m_ParseCurrent->driver = value;
|
||||
}
|
||||
} else if (strcmp(key, "database") == 0) {
|
||||
m_ParseCurrent->database = value;
|
||||
} else if (strcmp(key, "host") == 0) {
|
||||
m_ParseCurrent->host = value;
|
||||
} else if (strcmp(key, "user") == 0) {
|
||||
m_ParseCurrent->user = value;
|
||||
} else if (strcmp(key, "pass") == 0) {
|
||||
m_ParseCurrent->pass = value;
|
||||
} else if (strcmp(key, "timeout") == 0) {
|
||||
m_ParseCurrent->info.maxTimeout = atoi(value);
|
||||
} else if (strcmp(key, "port") == 0) {
|
||||
m_ParseCurrent->info.port = atoi(value);
|
||||
}
|
||||
}
|
||||
|
||||
return SMCResult_Continue;
|
||||
}
|
||||
|
||||
SMCResult DatabaseConfBuilder::ReadSMC_LeavingSection(const SMCStates *states)
|
||||
{
|
||||
if (m_ParseLevel)
|
||||
{
|
||||
m_ParseLevel--;
|
||||
return SMCResult_Continue;
|
||||
}
|
||||
|
||||
if (m_ParseState == DBPARSE_LEVEL_DATABASE)
|
||||
{
|
||||
m_ParseCurrent->info.driver = m_ParseCurrent->driver.chars();
|
||||
m_ParseCurrent->info.database = m_ParseCurrent->database.chars();
|
||||
m_ParseCurrent->info.host = m_ParseCurrent->host.chars();
|
||||
m_ParseCurrent->info.user = m_ParseCurrent->user.chars();
|
||||
m_ParseCurrent->info.pass = m_ParseCurrent->pass.chars();
|
||||
|
||||
/* Save it.. */
|
||||
m_ParseCurrent->AddRef();
|
||||
m_ParseList->append(m_ParseCurrent);
|
||||
m_ParseCurrent = nullptr;
|
||||
|
||||
/* Go up one level */
|
||||
m_ParseState = DBPARSE_LEVEL_MAIN;
|
||||
} else if (m_ParseState == DBPARSE_LEVEL_MAIN) {
|
||||
m_ParseState = DBPARSE_LEVEL_NONE;
|
||||
return SMCResult_Halt;
|
||||
}
|
||||
|
||||
return SMCResult_Continue;
|
||||
}
|
||||
|
||||
void DatabaseConfBuilder::ReadSMC_ParseEnd(bool halted, bool failed)
|
||||
{
|
||||
m_InfoList->ReleaseMembers();
|
||||
delete m_InfoList;
|
||||
m_InfoList = m_ParseList;
|
||||
|
||||
m_ParseList = nullptr;
|
||||
}
|
@ -1,129 +0,0 @@
|
||||
/**
|
||||
* vim: set ts=4 sw=4 tw=99 noet :
|
||||
* =============================================================================
|
||||
* SourceMod
|
||||
* Copyright (C) 2004-2018 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* 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 <http://www.sourcemod.net/license.php>.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE_DATABASE_CONF_BUILDER_H_
|
||||
#define _INCLUDE_DATABASE_CONF_BUILDER_H_
|
||||
|
||||
#include <IDBDriver.h>
|
||||
#include <ITextParsers.h>
|
||||
#include "common_logic.h"
|
||||
|
||||
#include <am-vector.h>
|
||||
#include <am-string.h>
|
||||
#include <am-refcounting-threadsafe.h>
|
||||
|
||||
class ConfDbInfo : public ke::RefcountedThreadsafe<ConfDbInfo>
|
||||
{
|
||||
public:
|
||||
ConfDbInfo() : realDriver(NULL)
|
||||
{
|
||||
}
|
||||
ke::AString name;
|
||||
ke::AString driver;
|
||||
ke::AString host;
|
||||
ke::AString user;
|
||||
ke::AString pass;
|
||||
ke::AString database;
|
||||
IDBDriver *realDriver;
|
||||
DatabaseInfo info;
|
||||
};
|
||||
|
||||
class ConfDbInfoList : public ke::Vector<ConfDbInfo *>
|
||||
{
|
||||
/* Allow internal usage of ConfDbInfoList */
|
||||
friend class DBManager;
|
||||
friend class DatabaseConfBuilder;
|
||||
private:
|
||||
ke::AString& GetDefaultDriver() {
|
||||
return m_DefDriver;
|
||||
}
|
||||
|
||||
ConfDbInfo *GetDatabaseConf(const char *name) {
|
||||
for (size_t i = 0; i < this->length(); i++)
|
||||
{
|
||||
ConfDbInfo *current = this->at(i);
|
||||
/* If we run into the default configuration, then we'll save it
|
||||
* for the next call to GetDefaultConfiguration */
|
||||
if (strcmp(current->name.chars(), "default") == 0)
|
||||
{
|
||||
m_DefaultConfig = current;
|
||||
}
|
||||
if (strcmp(current->name.chars(), name) == 0)
|
||||
{
|
||||
return current;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
ConfDbInfo *GetDefaultConfiguration() {
|
||||
return m_DefaultConfig;
|
||||
}
|
||||
void SetDefaultDriver(const char *input) {
|
||||
m_DefDriver = ke::AString(input);
|
||||
}
|
||||
void ReleaseMembers() {
|
||||
for (size_t i = 0; i < this->length(); i++) {
|
||||
ConfDbInfo *current = this->at(i);
|
||||
current->Release();
|
||||
}
|
||||
}
|
||||
private:
|
||||
ConfDbInfo *m_DefaultConfig;
|
||||
ke::AString m_DefDriver;
|
||||
};
|
||||
|
||||
|
||||
class DatabaseConfBuilder : public ITextListener_SMC
|
||||
{
|
||||
public:
|
||||
DatabaseConfBuilder();
|
||||
~DatabaseConfBuilder();
|
||||
void StartParse();
|
||||
void SetPath(char* path);
|
||||
ConfDbInfoList *GetConfigList();
|
||||
public: //ITextListener_SMC
|
||||
void ReadSMC_ParseStart();
|
||||
SMCResult ReadSMC_NewSection(const SMCStates *states, const char *name);
|
||||
SMCResult ReadSMC_KeyValue(const SMCStates *states, const char *key, const char *value);
|
||||
SMCResult ReadSMC_LeavingSection(const SMCStates *states);
|
||||
void ReadSMC_ParseEnd(bool halted, bool failed);
|
||||
|
||||
private:
|
||||
unsigned int m_ParseLevel;
|
||||
unsigned int m_ParseState;
|
||||
ConfDbInfo *m_ParseCurrent;
|
||||
ConfDbInfoList *m_ParseList;
|
||||
private:
|
||||
ke::AString m_Filename;
|
||||
ConfDbInfoList *m_InfoList;
|
||||
};
|
||||
|
||||
#endif //_INCLUDE_DATABASE_CONF_BUILDER_H_
|
@ -29,11 +29,11 @@
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#include <ISourceMod.h>
|
||||
#include <IPluginSys.h>
|
||||
#include <stdarg.h>
|
||||
#include "DebugReporter.h"
|
||||
#include "Logger.h"
|
||||
#include <am-string.h>
|
||||
|
||||
DebugReport g_DbgReporter;
|
||||
|
||||
@ -194,53 +194,35 @@ void DebugReport::ReportError(const IErrorReport &report, IFrameIterator &iter)
|
||||
g_Logger.LogError("[SM] Blaming: %s", blame);
|
||||
}
|
||||
|
||||
ke::Vector<ke::AString> arr = GetStackTrace(&iter);
|
||||
for (size_t i = 0; i < arr.length(); i++)
|
||||
if (!iter.Done())
|
||||
{
|
||||
g_Logger.LogError("%s", arr[i].chars());
|
||||
}
|
||||
}
|
||||
g_Logger.LogError("[SM] Call stack trace:");
|
||||
|
||||
ke::Vector<ke::AString> DebugReport::GetStackTrace(IFrameIterator *iter)
|
||||
{
|
||||
char temp[3072];
|
||||
ke::Vector<ke::AString> trace;
|
||||
iter->Reset();
|
||||
|
||||
if (!iter->Done())
|
||||
for (int index = 0; !iter.Done(); iter.Next(), index++)
|
||||
{
|
||||
trace.append("[SM] Call stack trace:");
|
||||
|
||||
for (int index = 0; !iter->Done(); iter->Next(), index++)
|
||||
{
|
||||
const char *fn = iter->FunctionName();
|
||||
const char *fn = iter.FunctionName();
|
||||
if (!fn)
|
||||
{
|
||||
fn = "<unknown function>";
|
||||
}
|
||||
if (iter->IsNativeFrame())
|
||||
if (iter.IsNativeFrame())
|
||||
{
|
||||
g_pSM->Format(temp, sizeof(temp), "[SM] [%d] %s", index, fn);
|
||||
trace.append(temp);
|
||||
g_Logger.LogError("[SM] [%d] %s", index, fn);
|
||||
continue;
|
||||
}
|
||||
if (iter->IsScriptedFrame())
|
||||
if (iter.IsScriptedFrame())
|
||||
{
|
||||
const char *file = iter->FilePath();
|
||||
const char *file = iter.FilePath();
|
||||
if (!file)
|
||||
{
|
||||
file = "<unknown>";
|
||||
}
|
||||
g_pSM->Format(temp, sizeof(temp), "[SM] [%d] Line %d, %s::%s",
|
||||
g_Logger.LogError("[SM] [%d] Line %d, %s::%s",
|
||||
index,
|
||||
iter->LineNumber(),
|
||||
iter.LineNumber(),
|
||||
file,
|
||||
fn);
|
||||
|
||||
trace.append(temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return trace;
|
||||
}
|
||||
|
@ -34,8 +34,6 @@
|
||||
|
||||
#include "sp_vm_api.h"
|
||||
#include "common_logic.h"
|
||||
#include <am-vector.h>
|
||||
#include <am-string.h>
|
||||
|
||||
class DebugReport :
|
||||
public SMGlobalClass,
|
||||
@ -50,7 +48,6 @@ public:
|
||||
void GenerateError(IPluginContext *ctx, cell_t func_idx, int err, const char *message, ...);
|
||||
void GenerateErrorVA(IPluginContext *ctx, cell_t func_idx, int err, const char *message, va_list ap);
|
||||
void GenerateCodeError(IPluginContext *ctx, uint32_t code_addr, int err, const char *message, ...);
|
||||
ke::Vector<ke::AString> GetStackTrace(IFrameIterator *iter);
|
||||
private:
|
||||
int _GetPluginIndex(IPluginContext *ctx);
|
||||
};
|
||||
|
@ -73,14 +73,9 @@ CLocalExtension::CLocalExtension(const char *filename, bool bRequired)
|
||||
/* Special case for new bintools binary */
|
||||
if (strcmp(filename, "bintools.ext") == 0)
|
||||
{
|
||||
g_pSM->BuildPath(Path_SM,
|
||||
path,
|
||||
PLATFORM_MAX_PATH,
|
||||
"extensions/%s." PLATFORM_LIB_EXT,
|
||||
filename);
|
||||
goto normal;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Zeroth, see if there is an engine specific build in the new place. */
|
||||
g_pSM->BuildPath(Path_SM,
|
||||
path,
|
||||
@ -89,8 +84,11 @@ CLocalExtension::CLocalExtension(const char *filename, bool bRequired)
|
||||
filename,
|
||||
bridge->gamesuffix);
|
||||
|
||||
if (!libsys->IsPathFile(path))
|
||||
if (libsys->IsPathFile(path))
|
||||
{
|
||||
goto found;
|
||||
}
|
||||
|
||||
/* COMPAT HACK: One-halfth, if ep2v, see if there is an engine specific build in the new place with old naming */
|
||||
if (strcmp(bridge->gamesuffix, "2.tf2") == 0
|
||||
|| strcmp(bridge->gamesuffix, "2.dods") == 0
|
||||
@ -102,6 +100,11 @@ CLocalExtension::CLocalExtension(const char *filename, bool bRequired)
|
||||
PLATFORM_MAX_PATH,
|
||||
"extensions/%s.2.ep2v." PLATFORM_LIB_EXT,
|
||||
filename);
|
||||
|
||||
if (libsys->IsPathFile(path))
|
||||
{
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
else if (strcmp(bridge->gamesuffix, "2.nd") == 0)
|
||||
{
|
||||
@ -110,11 +113,13 @@ CLocalExtension::CLocalExtension(const char *filename, bool bRequired)
|
||||
PLATFORM_MAX_PATH,
|
||||
"extensions/%s.2.l4d2." PLATFORM_LIB_EXT,
|
||||
filename);
|
||||
|
||||
if (libsys->IsPathFile(path))
|
||||
{
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
|
||||
//Try further
|
||||
if (!libsys->IsPathFile(path))
|
||||
{
|
||||
/* First see if there is an engine specific build! */
|
||||
g_pSM->BuildPath(Path_SM,
|
||||
path,
|
||||
@ -126,15 +131,15 @@ CLocalExtension::CLocalExtension(const char *filename, bool bRequired)
|
||||
/* Try the "normal" version */
|
||||
if (!libsys->IsPathFile(path))
|
||||
{
|
||||
normal:
|
||||
g_pSM->BuildPath(Path_SM,
|
||||
path,
|
||||
PLATFORM_MAX_PATH,
|
||||
"extensions/%s." PLATFORM_LIB_EXT,
|
||||
filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
found:
|
||||
Initialize(filename, path, bRequired);
|
||||
}
|
||||
|
||||
@ -171,7 +176,7 @@ bool CLocalExtension::Load(char *error, size_t maxlength)
|
||||
{
|
||||
m_pLib->CloseLibrary();
|
||||
m_pLib = NULL;
|
||||
ke::SafeStrcpy(error, maxlength, "Unable to find extension entry point");
|
||||
snprintf(error, maxlength, "Unable to find extension entry point");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -241,7 +246,7 @@ void CLocalExtension::Unload()
|
||||
|
||||
bool CRemoteExtension::Reload(char *error, size_t maxlength)
|
||||
{
|
||||
ke::SafeStrcpy(error, maxlength, "Remote extensions do not support reloading");
|
||||
snprintf(error, maxlength, "Remote extensions do not support reloading");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -275,13 +280,13 @@ bool CExtension::PerformAPICheck(char *error, size_t maxlength)
|
||||
{
|
||||
if (!m_pAPI)
|
||||
{
|
||||
ke::SafeStrcpy(error, maxlength, "No IExtensionInterface instance provided");
|
||||
snprintf(error, maxlength, "No IExtensionInterface instance provided");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_pAPI->GetExtensionVersion() > SMINTERFACE_EXTENSIONAPI_VERSION)
|
||||
{
|
||||
ke::SafeSprintf(error, maxlength, "Extension version is too new to load (%d, max is %d)", m_pAPI->GetExtensionVersion(), SMINTERFACE_EXTENSIONAPI_VERSION);
|
||||
snprintf(error, maxlength, "Extension version is too new to load (%d, max is %d)", m_pAPI->GetExtensionVersion(), SMINTERFACE_EXTENSIONAPI_VERSION);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -416,20 +421,65 @@ void CExtension::AddChildDependent(CExtension *pOther, SMInterface *iface)
|
||||
m_ChildDeps.push_back(info);
|
||||
}
|
||||
|
||||
// note: dependency iteration deprecated since 1.10
|
||||
ITERATOR *CExtension::FindFirstDependency(IExtension **pOwner, SMInterface **pInterface)
|
||||
{
|
||||
return nullptr;
|
||||
List<IfaceInfo>::iterator iter = m_Deps.begin();
|
||||
|
||||
if (iter == m_Deps.end())
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (pOwner)
|
||||
{
|
||||
*pOwner = (*iter).owner;
|
||||
}
|
||||
if (pInterface)
|
||||
{
|
||||
*pInterface = (*iter).iface;
|
||||
}
|
||||
|
||||
List<IfaceInfo>::iterator *pIter = new List<IfaceInfo>::iterator(iter);
|
||||
|
||||
return (ITERATOR *)pIter;
|
||||
}
|
||||
|
||||
bool CExtension::FindNextDependency(ITERATOR *iter, IExtension **pOwner, SMInterface **pInterface)
|
||||
{
|
||||
List<IfaceInfo>::iterator *pIter = (List<IfaceInfo>::iterator *)iter;
|
||||
List<IfaceInfo>::iterator _iter;
|
||||
|
||||
if (_iter == m_Deps.end())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
_iter++;
|
||||
|
||||
if (pOwner)
|
||||
{
|
||||
*pOwner = (*_iter).owner;
|
||||
}
|
||||
if (pInterface)
|
||||
{
|
||||
*pInterface = (*_iter).iface;
|
||||
}
|
||||
|
||||
*pIter = _iter;
|
||||
|
||||
if (_iter == m_Deps.end())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CExtension::FreeDependencyIterator(ITERATOR *iter)
|
||||
{
|
||||
List<IfaceInfo>::iterator *pIter = (List<IfaceInfo>::iterator *)iter;
|
||||
|
||||
delete pIter;
|
||||
}
|
||||
|
||||
void CExtension::AddInterface(SMInterface *pInterface)
|
||||
@ -443,7 +493,7 @@ bool CExtension::IsRunning(char *error, size_t maxlength)
|
||||
{
|
||||
if (error)
|
||||
{
|
||||
ke::SafeStrcpy(error, maxlength, m_Error.c_str());
|
||||
snprintf(error, maxlength, "%s", m_Error.c_str());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -525,7 +575,7 @@ void CExtensionManager::TryAutoload()
|
||||
}
|
||||
|
||||
char file[PLATFORM_MAX_PATH];
|
||||
len = ke::SafeStrcpy(file, sizeof(file), lfile);
|
||||
len = ke::SafeSprintf(file, sizeof(file), "%s", lfile);
|
||||
strcpy(&file[len - 9], ".ext");
|
||||
|
||||
LoadAutoExtension(file);
|
||||
@ -541,7 +591,7 @@ IExtension *CExtensionManager::LoadAutoExtension(const char *path, bool bErrorOn
|
||||
if (strcmp(ext, PLATFORM_LIB_EXT) == 0)
|
||||
{
|
||||
char path2[PLATFORM_MAX_PATH];
|
||||
ke::SafeStrcpy(path2, sizeof(path2), path);
|
||||
ke::SafeSprintf(path2, sizeof(path2), "%s", path);
|
||||
path2[strlen(path) - strlen(PLATFORM_LIB_EXT) - 1] = '\0';
|
||||
return LoadAutoExtension(path2, bErrorOnMissing);
|
||||
}
|
||||
@ -633,7 +683,7 @@ IExtension *CExtensionManager::LoadExtension(const char *file, char *error, size
|
||||
if (strcmp(ext, PLATFORM_LIB_EXT) == 0)
|
||||
{
|
||||
char path2[PLATFORM_MAX_PATH];
|
||||
ke::SafeStrcpy(path2, sizeof(path2), file);
|
||||
ke::SafeSprintf(path2, sizeof(path2), "%s", file);
|
||||
path2[strlen(file) - strlen(PLATFORM_LIB_EXT) - 1] = '\0';
|
||||
return LoadExtension(path2, error, maxlength);
|
||||
}
|
||||
@ -1086,7 +1136,7 @@ void CExtensionManager::OnRootConsoleCommand(const char *cmdname, const ICommand
|
||||
if (pExt->unload_code == (unsigned)atoi(unload))
|
||||
{
|
||||
char filename[PLATFORM_MAX_PATH];
|
||||
ke::SafeStrcpy(filename, PLATFORM_MAX_PATH, pExt->GetFilename());
|
||||
snprintf(filename, PLATFORM_MAX_PATH, "%s", pExt->GetFilename());
|
||||
UnloadExtension(pExt);
|
||||
rootmenu->ConsolePrint("[SM] Extension %s is now unloaded.", filename);
|
||||
}
|
||||
@ -1101,7 +1151,7 @@ void CExtensionManager::OnRootConsoleCommand(const char *cmdname, const ICommand
|
||||
|| (!pExt->m_ChildDeps.size() && !pExt->m_Dependents.size()))
|
||||
{
|
||||
char filename[PLATFORM_MAX_PATH];
|
||||
ke::SafeStrcpy(filename, PLATFORM_MAX_PATH, pExt->GetFilename());
|
||||
snprintf(filename, PLATFORM_MAX_PATH, "%s", pExt->GetFilename());
|
||||
UnloadExtension(pExt);
|
||||
rootmenu->ConsolePrint("[SM] Extension %s is now unloaded.", filename);
|
||||
return;
|
||||
@ -1202,7 +1252,7 @@ void CExtensionManager::OnRootConsoleCommand(const char *cmdname, const ICommand
|
||||
char filename[PLATFORM_MAX_PATH];
|
||||
char error[255];
|
||||
|
||||
ke::SafeStrcpy(filename, PLATFORM_MAX_PATH, pExt->GetFilename());
|
||||
snprintf(filename, PLATFORM_MAX_PATH, "%s", pExt->GetFilename());
|
||||
|
||||
if (pExt->Reload(error, sizeof(error)))
|
||||
{
|
||||
|
@ -66,33 +66,26 @@ static const char *g_pParseEngine = NULL;
|
||||
#define PSTATE_GAMEDEFS_OFFSETS 3
|
||||
#define PSTATE_GAMEDEFS_OFFSETS_OFFSET 4
|
||||
#define PSTATE_GAMEDEFS_KEYS 5
|
||||
#define PSTATE_GAMEDEFS_KEYS_PLATFORM 6
|
||||
#define PSTATE_GAMEDEFS_SUPPORTED 7
|
||||
#define PSTATE_GAMEDEFS_SIGNATURES 8
|
||||
#define PSTATE_GAMEDEFS_SIGNATURES_SIG 9
|
||||
#define PSTATE_GAMEDEFS_CRC 10
|
||||
#define PSTATE_GAMEDEFS_CRC_BINARY 11
|
||||
#define PSTATE_GAMEDEFS_CUSTOM 12
|
||||
#define PSTATE_GAMEDEFS_ADDRESSES 13
|
||||
#define PSTATE_GAMEDEFS_ADDRESSES_ADDRESS 14
|
||||
#define PSTATE_GAMEDEFS_ADDRESSES_ADDRESS_READ 15
|
||||
|
||||
#if defined PLATFORM_X86
|
||||
#define PLATFORM_ARCH_SUFFIX ""
|
||||
#elif defined PLATFORM_X64
|
||||
#define PLATFORM_ARCH_SUFFIX "64"
|
||||
#endif
|
||||
#define PSTATE_GAMEDEFS_SUPPORTED 6
|
||||
#define PSTATE_GAMEDEFS_SIGNATURES 7
|
||||
#define PSTATE_GAMEDEFS_SIGNATURES_SIG 8
|
||||
#define PSTATE_GAMEDEFS_CRC 9
|
||||
#define PSTATE_GAMEDEFS_CRC_BINARY 10
|
||||
#define PSTATE_GAMEDEFS_CUSTOM 11
|
||||
#define PSTATE_GAMEDEFS_ADDRESSES 12
|
||||
#define PSTATE_GAMEDEFS_ADDRESSES_ADDRESS 13
|
||||
#define PSTATE_GAMEDEFS_ADDRESSES_ADDRESS_READ 14
|
||||
|
||||
#if defined PLATFORM_WINDOWS
|
||||
#define PLATFORM_NAME "windows" PLATFORM_ARCH_SUFFIX
|
||||
#define PLATFORM_NAME "windows"
|
||||
#define PLATFORM_SERVER_BINARY "server.dll"
|
||||
#elif defined PLATFORM_LINUX
|
||||
#define PLATFORM_NAME "linux" PLATFORM_ARCH_SUFFIX
|
||||
#define PLATFORM_COMPAT_ALT "mac" PLATFORM_ARCH_SUFFIX /* Alternate platform name if game data is missing for primary one */
|
||||
#define PLATFORM_NAME "linux"
|
||||
#define PLATFORM_COMPAT_ALT "mac" /* Alternate platform name if game data is missing for primary one */
|
||||
#define PLATFORM_SERVER_BINARY "server_i486.so"
|
||||
#elif defined PLATFORM_APPLE
|
||||
#define PLATFORM_NAME "mac" PLATFORM_ARCH_SUFFIX
|
||||
#define PLATFORM_COMPAT_ALT "linux" PLATFORM_ARCH_SUFFIX
|
||||
#define PLATFORM_NAME "mac"
|
||||
#define PLATFORM_COMPAT_ALT "linux"
|
||||
#define PLATFORM_SERVER_BINARY "server.dylib"
|
||||
#endif
|
||||
|
||||
@ -259,13 +252,6 @@ SMCResult CGameConfig::ReadSMC_NewSection(const SMCStates *states, const char *n
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PSTATE_GAMEDEFS_KEYS:
|
||||
{
|
||||
strncopy(m_Key, name, sizeof(m_Key));
|
||||
m_ParseState = PSTATE_GAMEDEFS_KEYS_PLATFORM;
|
||||
matched_platform = false;
|
||||
break;
|
||||
}
|
||||
case PSTATE_GAMEDEFS_OFFSETS:
|
||||
{
|
||||
m_Prop[0] = '\0';
|
||||
@ -352,8 +338,7 @@ SMCResult CGameConfig::ReadSMC_NewSection(const SMCStates *states, const char *n
|
||||
}
|
||||
else
|
||||
{
|
||||
if (strcmp(name, "linux") != 0 && strcmp(name, "windows") != 0 && strcmp(name, "mac") != 0 &&
|
||||
strcmp(name, "linux64") != 0 && strcmp(name, "windows64") != 0 && strcmp(name, "mac64") != 0)
|
||||
if (strcmp(name, "linux") != 0 && strcmp(name, "windows") != 0 && strcmp(name, "mac") != 0)
|
||||
{
|
||||
logger->LogError("[SM] Error while parsing Address section for \"%s\" (%s):", m_Address, m_CurFile);
|
||||
logger->LogError("[SM] Unrecognized platform \"%s\"", name);
|
||||
@ -364,7 +349,7 @@ SMCResult CGameConfig::ReadSMC_NewSection(const SMCStates *states, const char *n
|
||||
}
|
||||
/* No sub-sections allowed:
|
||||
case PSTATE_GAMEDEFS_OFFSETS_OFFSET:
|
||||
case PSTATE_GAMEDEFS_KEYS_PLATFORM:
|
||||
case PSTATE_GAMEDEFS_KEYS:
|
||||
case PSTATE_GAMEDEFS_SUPPORTED:
|
||||
case PSTATE_GAMEDEFS_SIGNATURES_SIG:
|
||||
case PSTATE_GAMEDEFS_CRC_BINARY:
|
||||
@ -401,13 +386,6 @@ SMCResult CGameConfig::ReadSMC_KeyValue(const SMCStates *states, const char *key
|
||||
} else if (m_ParseState == PSTATE_GAMEDEFS_KEYS) {
|
||||
ke::AString vstr(value);
|
||||
m_Keys.replace(key, ke::Move(vstr));
|
||||
}
|
||||
else if (m_ParseState == PSTATE_GAMEDEFS_KEYS_PLATFORM) {
|
||||
if (IsPlatformCompatible(key, &matched_platform))
|
||||
{
|
||||
ke::AString vstr(value);
|
||||
m_Keys.replace(m_Key, ke::Move(vstr));
|
||||
}
|
||||
} else if (m_ParseState == PSTATE_GAMEDEFS_SUPPORTED) {
|
||||
if (strcmp(key, "game") == 0)
|
||||
{
|
||||
@ -521,11 +499,6 @@ SMCResult CGameConfig::ReadSMC_LeavingSection(const SMCStates *states)
|
||||
m_ParseState = PSTATE_GAMEDEFS;
|
||||
break;
|
||||
}
|
||||
case PSTATE_GAMEDEFS_KEYS_PLATFORM:
|
||||
{
|
||||
m_ParseState = PSTATE_GAMEDEFS_KEYS;
|
||||
break;
|
||||
}
|
||||
case PSTATE_GAMEDEFS_OFFSETS_OFFSET:
|
||||
{
|
||||
/* Parse the offset... */
|
||||
|
@ -90,7 +90,6 @@ private:
|
||||
char m_Prop[64];
|
||||
char m_offset[64];
|
||||
char m_Game[256];
|
||||
char m_Key[64];
|
||||
bool bShouldBeReadingDefault;
|
||||
bool had_game;
|
||||
bool matched_game;
|
||||
|
@ -35,7 +35,6 @@
|
||||
#include <IHandleSys.h>
|
||||
#include <stdio.h>
|
||||
#include <sm_namehashset.h>
|
||||
#include <amtl/am-autoptr.h>
|
||||
#include <amtl/am-string.h>
|
||||
#include <amtl/am-function.h>
|
||||
#include "common_logic.h"
|
||||
|
@ -66,7 +66,7 @@ CDirectory::CDirectory(const char *path)
|
||||
{
|
||||
#if defined PLATFORM_WINDOWS
|
||||
char newpath[PLATFORM_MAX_PATH];
|
||||
ke::SafeSprintf(newpath, sizeof(newpath), "%s\\*.*", path);
|
||||
snprintf(newpath, sizeof(newpath), "%s\\*.*", path);
|
||||
m_dir = FindFirstFileA(newpath, &m_fd);
|
||||
if (!IsValid())
|
||||
{
|
||||
@ -78,7 +78,7 @@ CDirectory::CDirectory(const char *path)
|
||||
{
|
||||
/* :TODO: we need to read past "." and ".."! */
|
||||
ep = readdir(m_dir);
|
||||
ke::SafeStrcpy(m_origpath, PLATFORM_MAX_PATH, path);
|
||||
snprintf(m_origpath, PLATFORM_MAX_PATH, "%s", path);
|
||||
} else {
|
||||
ep = NULL;
|
||||
}
|
||||
@ -125,9 +125,7 @@ bool CDirectory::IsEntryDirectory()
|
||||
return ((m_fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY);
|
||||
#elif defined PLATFORM_POSIX
|
||||
char temppath[PLATFORM_MAX_PATH];
|
||||
int ret = ke::SafeSprintf(temppath, sizeof(temppath), "%s/%s", m_origpath, GetEntryName());
|
||||
if (static_cast<size_t>(ret) >= sizeof(temppath))
|
||||
return false;
|
||||
snprintf(temppath, sizeof(temppath), "%s/%s", m_origpath, GetEntryName());
|
||||
return ke::file::IsDirectory(temppath);
|
||||
#endif
|
||||
}
|
||||
@ -138,9 +136,7 @@ bool CDirectory::IsEntryFile()
|
||||
return !(m_fd.dwFileAttributes & (FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_DEVICE));
|
||||
#elif defined PLATFORM_POSIX
|
||||
char temppath[PLATFORM_MAX_PATH];
|
||||
int ret = ke::SafeSprintf(temppath, sizeof(temppath), "%s/%s", m_origpath, GetEntryName());
|
||||
if (static_cast<size_t>(ret) >= sizeof(temppath))
|
||||
return false;
|
||||
snprintf(temppath, sizeof(temppath), "%s/%s", m_origpath, GetEntryName());
|
||||
return ke::file::IsFile(temppath);
|
||||
#endif
|
||||
}
|
||||
@ -230,7 +226,7 @@ void LibrarySystem::GetPlatformErrorEx(int code, char *error, size_t maxlength)
|
||||
const char *ae = strerror_r(code, error, maxlength);
|
||||
if (ae != error)
|
||||
{
|
||||
ke::SafeStrcpy(error, maxlength, ae);
|
||||
ke::SafeSprintf(error, maxlength, "%s", ae);
|
||||
}
|
||||
#elif defined PLATFORM_POSIX
|
||||
strerror_r(code, error, maxlength);
|
||||
@ -309,12 +305,12 @@ size_t LibrarySystem::GetFileFromPath(char *buffer, size_t maxlength, const char
|
||||
#endif
|
||||
)
|
||||
{
|
||||
return ke::SafeStrcpy(buffer, maxlength, &path[i+1]);
|
||||
return ke::SafeSprintf(buffer, maxlength, "%s", &path[i+1]);
|
||||
}
|
||||
}
|
||||
|
||||
/* We scanned and found no path separator */
|
||||
return ke::SafeStrcpy(buffer, maxlength, path);
|
||||
return ke::SafeSprintf(buffer, maxlength, "%s", path);
|
||||
}
|
||||
|
||||
bool LibrarySystem::FileTime(const char *path, FileTimeType type, time_t *pTime)
|
||||
|
@ -40,6 +40,10 @@
|
||||
|
||||
Logger g_Logger;
|
||||
|
||||
/**
|
||||
* :TODO: This should be creating the log folder if it doesn't exist
|
||||
*/
|
||||
|
||||
ConfigResult Logger::OnSourceModConfigChanged(const char *key,
|
||||
const char *value,
|
||||
ConfigSource source,
|
||||
@ -56,7 +60,7 @@ ConfigResult Logger::OnSourceModConfigChanged(const char *key,
|
||||
} else if (strcasecmp(value, "off") == 0) {
|
||||
state = false;
|
||||
} else {
|
||||
ke::SafeStrcpy(error, maxlength, "Invalid value: must be \"on\" or \"off\"");
|
||||
ke::SafeSprintf(error, maxlength, "Invalid value: must be \"on\" or \"off\"");
|
||||
return ConfigResult_Reject;
|
||||
}
|
||||
|
||||
@ -64,7 +68,7 @@ ConfigResult Logger::OnSourceModConfigChanged(const char *key,
|
||||
{
|
||||
state ? EnableLogging() : DisableLogging();
|
||||
} else {
|
||||
m_Active = state;
|
||||
m_InitialState = state;
|
||||
}
|
||||
|
||||
return ConfigResult_Accept;
|
||||
@ -77,7 +81,7 @@ ConfigResult Logger::OnSourceModConfigChanged(const char *key,
|
||||
} else if (strcasecmp(value, "game") == 0) {
|
||||
m_Mode = LoggingMode_Game;
|
||||
} else {
|
||||
ke::SafeStrcpy(error, maxlength, "Invalid value: must be [daily|map|game]");
|
||||
ke::SafeSprintf(error, maxlength, "Invalid value: must be [daily|map|game]");
|
||||
return ConfigResult_Reject;
|
||||
}
|
||||
|
||||
@ -89,12 +93,7 @@ ConfigResult Logger::OnSourceModConfigChanged(const char *key,
|
||||
|
||||
void Logger::OnSourceModStartup(bool late)
|
||||
{
|
||||
char buff[PLATFORM_MAX_PATH];
|
||||
g_pSM->BuildPath(Path_SM, buff, sizeof(buff), "logs");
|
||||
if (!libsys->IsPathDirectory(buff))
|
||||
{
|
||||
libsys->CreateFolder(buff);
|
||||
}
|
||||
InitLogger(m_Mode);
|
||||
}
|
||||
|
||||
void Logger::OnSourceModAllShutdown()
|
||||
@ -104,7 +103,127 @@ void Logger::OnSourceModAllShutdown()
|
||||
|
||||
void Logger::OnSourceModLevelChange(const char *mapName)
|
||||
{
|
||||
_MapChange(mapName);
|
||||
MapChange(mapName);
|
||||
}
|
||||
|
||||
void Logger::_NewMapFile()
|
||||
{
|
||||
if (!m_Active)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Append "Log file closed" to previous log file */
|
||||
_CloseFile();
|
||||
|
||||
char _filename[256];
|
||||
int i = 0;
|
||||
|
||||
time_t t = g_pSM->GetAdjustedTime();
|
||||
tm *curtime = localtime(&t);
|
||||
|
||||
while (true)
|
||||
{
|
||||
g_pSM->BuildPath(Path_SM, _filename, sizeof(_filename), "logs/L%02d%02d%03d.log", curtime->tm_mon + 1, curtime->tm_mday, i);
|
||||
FILE *fp = fopen(_filename, "r");
|
||||
if (!fp)
|
||||
{
|
||||
break;
|
||||
}
|
||||
fclose(fp);
|
||||
i++;
|
||||
}
|
||||
m_NrmFileName.assign(_filename);
|
||||
|
||||
FILE *fp = fopen(m_NrmFileName.c_str(), "w");
|
||||
if (!fp)
|
||||
{
|
||||
char error[255];
|
||||
libsys->GetPlatformError(error, sizeof(error));
|
||||
LogFatal("[SM] Unexpected fatal logging error (file \"%s\")", m_NrmFileName.c_str());
|
||||
LogFatal("[SM] Platform returned error: \"%s\"", error);
|
||||
LogFatal("[SM] Logging has been disabled.");
|
||||
m_Active = false;
|
||||
return;
|
||||
} else {
|
||||
char date[32];
|
||||
strftime(date, sizeof(date), "%m/%d/%Y - %H:%M:%S", curtime);
|
||||
fprintf(fp, "L %s: SourceMod log file started (file \"L%02d%02d%03d.log\") (Version \"%s\")\n", date, curtime->tm_mon + 1, curtime->tm_mday, i, SOURCEMOD_VERSION);
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
|
||||
void Logger::_CloseFile()
|
||||
{
|
||||
if (!m_Active)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
FILE *fp = NULL;
|
||||
if (!m_NrmFileName.empty())
|
||||
{
|
||||
fp = fopen(m_NrmFileName.c_str(), "r+");
|
||||
if (fp)
|
||||
{
|
||||
fseek(fp, 0, SEEK_END);
|
||||
LogMessage("Log file closed.");
|
||||
fclose(fp);
|
||||
}
|
||||
m_NrmFileName.clear();
|
||||
}
|
||||
|
||||
if (!m_ErrMapStart)
|
||||
{
|
||||
return;
|
||||
}
|
||||
fp = fopen(m_ErrFileName.c_str(), "r+");
|
||||
if (fp)
|
||||
{
|
||||
fseek(fp, 0, SEEK_END);
|
||||
LogError("Error log file session closed.");
|
||||
fclose(fp);
|
||||
}
|
||||
m_ErrFileName.clear();
|
||||
}
|
||||
|
||||
void Logger::InitLogger(LoggingMode mode)
|
||||
{
|
||||
m_Mode = mode;
|
||||
m_Active = m_InitialState;
|
||||
|
||||
time_t t = g_pSM->GetAdjustedTime();
|
||||
tm *curtime = localtime(&t);
|
||||
m_NrmCurDay = curtime->tm_mday;
|
||||
m_ErrCurDay = curtime->tm_mday;
|
||||
|
||||
char _filename[256];
|
||||
g_pSM->BuildPath(Path_SM, _filename, sizeof(_filename), "logs/errors_%04d%02d%02d.log", curtime->tm_year + 1900, curtime->tm_mon + 1, curtime->tm_mday);
|
||||
m_ErrFileName.assign(_filename);
|
||||
|
||||
switch (m_Mode)
|
||||
{
|
||||
case LoggingMode_PerMap:
|
||||
{
|
||||
if (!m_Active)
|
||||
{
|
||||
m_DelayedStart = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case LoggingMode_Daily:
|
||||
{
|
||||
g_pSM->BuildPath(Path_SM, _filename, sizeof(_filename), "logs/L%04d%02d%02d.log", curtime->tm_year + 1900, curtime->tm_mon + 1, curtime->tm_mday);
|
||||
m_NrmFileName.assign(_filename);
|
||||
m_DailyPrintHdr = true;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
/* do nothing... */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Logger::CloseLogger()
|
||||
@ -112,13 +231,6 @@ void Logger::CloseLogger()
|
||||
_CloseFile();
|
||||
}
|
||||
|
||||
void Logger::_CloseFile()
|
||||
{
|
||||
_CloseNormal();
|
||||
_CloseError();
|
||||
_CloseFatal();
|
||||
}
|
||||
|
||||
void Logger::LogToOpenFile(FILE *fp, const char *msg, ...)
|
||||
{
|
||||
if (!m_Active)
|
||||
@ -147,6 +259,11 @@ void Logger::LogToFileOnly(FILE *fp, const char *msg, ...)
|
||||
|
||||
void Logger::LogToOpenFileEx(FILE *fp, const char *msg, va_list ap)
|
||||
{
|
||||
if (!m_Active)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static ConVar *sv_logecho = bridge->FindConVar("sv_logecho");
|
||||
|
||||
char buffer[3072];
|
||||
@ -165,12 +282,15 @@ void Logger::LogToOpenFileEx(FILE *fp, const char *msg, va_list ap)
|
||||
ke::SafeSprintf(conBuffer, sizeof(conBuffer), "L %s: %s\n", date, buffer);
|
||||
bridge->ConPrint(conBuffer);
|
||||
}
|
||||
|
||||
fflush(fp);
|
||||
}
|
||||
|
||||
void Logger::LogToFileOnlyEx(FILE *fp, const char *msg, va_list ap)
|
||||
{
|
||||
if (!m_Active)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
char buffer[3072];
|
||||
ke::SafeVsprintf(buffer, sizeof(buffer), msg, ap);
|
||||
|
||||
@ -178,8 +298,8 @@ void Logger::LogToFileOnlyEx(FILE *fp, const char *msg, va_list ap)
|
||||
time_t t = g_pSM->GetAdjustedTime();
|
||||
tm *curtime = localtime(&t);
|
||||
strftime(date, sizeof(date), "%m/%d/%Y - %H:%M:%S", curtime);
|
||||
fprintf(fp, "L %s: %s\n", date, buffer);
|
||||
|
||||
fprintf(fp, "L %s: %s\n", date, buffer);
|
||||
fflush(fp);
|
||||
}
|
||||
|
||||
@ -204,14 +324,63 @@ void Logger::LogMessageEx(const char *vafmt, va_list ap)
|
||||
return;
|
||||
}
|
||||
|
||||
FILE *pFile = _OpenNormal();
|
||||
if (!pFile)
|
||||
if (m_DelayedStart)
|
||||
{
|
||||
return;
|
||||
m_DelayedStart = false;
|
||||
_NewMapFile();
|
||||
}
|
||||
|
||||
LogToOpenFileEx(pFile, vafmt, ap);
|
||||
fclose(pFile);
|
||||
time_t t = g_pSM->GetAdjustedTime();
|
||||
tm *curtime = localtime(&t);
|
||||
|
||||
FILE *fp = NULL;
|
||||
if (m_Mode == LoggingMode_PerMap)
|
||||
{
|
||||
fp = fopen(m_NrmFileName.c_str(), "a+");
|
||||
if (!fp)
|
||||
{
|
||||
_NewMapFile();
|
||||
fp = fopen(m_NrmFileName.c_str(), "a+");
|
||||
if (!fp)
|
||||
{
|
||||
goto print_error;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (m_NrmCurDay != curtime->tm_mday)
|
||||
{
|
||||
char _filename[256];
|
||||
g_pSM->BuildPath(Path_SM, _filename, sizeof(_filename), "logs/L%04d%02d%02d.log", curtime->tm_year + 1900, curtime->tm_mon + 1, curtime->tm_mday);
|
||||
m_NrmFileName.assign(_filename);
|
||||
m_NrmCurDay = curtime->tm_mday;
|
||||
m_DailyPrintHdr = true;
|
||||
}
|
||||
fp = fopen(m_NrmFileName.c_str(), "a+");
|
||||
}
|
||||
|
||||
if (fp)
|
||||
{
|
||||
if (m_DailyPrintHdr)
|
||||
{
|
||||
char date[32];
|
||||
m_DailyPrintHdr = false;
|
||||
strftime(date, sizeof(date), "%m/%d/%Y - %H:%M:%S", curtime);
|
||||
fprintf(fp, "L %s: SourceMod log file session started (file \"L%04d%02d%02d.log\") (Version \"%s\")\n", date, curtime->tm_year + 1900, curtime->tm_mon + 1, curtime->tm_mday, SOURCEMOD_VERSION);
|
||||
}
|
||||
LogToOpenFileEx(fp, vafmt, ap);
|
||||
fclose(fp);
|
||||
} else {
|
||||
goto print_error;
|
||||
}
|
||||
|
||||
return;
|
||||
print_error:
|
||||
char error[255];
|
||||
libsys->GetPlatformError(error, sizeof(error));
|
||||
LogFatal("[SM] Unexpected fatal logging error (file \"%s\")", m_NrmFileName.c_str());
|
||||
LogFatal("[SM] Platform returned error: \"%s\"", error);
|
||||
LogFatal("[SM] Logging has been disabled.");
|
||||
m_Active = false;
|
||||
}
|
||||
|
||||
void Logger::LogError(const char *vafmt, ...)
|
||||
@ -229,20 +398,72 @@ void Logger::LogErrorEx(const char *vafmt, va_list ap)
|
||||
return;
|
||||
}
|
||||
|
||||
FILE *pFile = _OpenError();
|
||||
if (!pFile)
|
||||
time_t t = g_pSM->GetAdjustedTime();
|
||||
tm *curtime = localtime(&t);
|
||||
|
||||
if (curtime->tm_mday != m_ErrCurDay)
|
||||
{
|
||||
return;
|
||||
char _filename[256];
|
||||
g_pSM->BuildPath(Path_SM, _filename, sizeof(_filename), "logs/errors_%04d%02d%02d.log", curtime->tm_year + 1900, curtime->tm_mon + 1, curtime->tm_mday);
|
||||
m_ErrFileName.assign(_filename);
|
||||
m_ErrCurDay = curtime->tm_mday;
|
||||
m_ErrMapStart = false;
|
||||
}
|
||||
|
||||
LogToOpenFileEx(pFile, vafmt, ap);
|
||||
fclose(pFile);
|
||||
FILE *fp = fopen(m_ErrFileName.c_str(), "a+");
|
||||
if (fp)
|
||||
{
|
||||
if (!m_ErrMapStart)
|
||||
{
|
||||
char date[32];
|
||||
strftime(date, sizeof(date), "%m/%d/%Y - %H:%M:%S", curtime);
|
||||
fprintf(fp, "L %s: SourceMod error session started\n", date);
|
||||
fprintf(fp, "L %s: Info (map \"%s\") (file \"errors_%04d%02d%02d.log\")\n", date, m_CurMapName.c_str(), curtime->tm_year + 1900, curtime->tm_mon + 1, curtime->tm_mday);
|
||||
m_ErrMapStart = true;
|
||||
}
|
||||
LogToOpenFileEx(fp, vafmt, ap);
|
||||
fclose(fp);
|
||||
}
|
||||
else
|
||||
{
|
||||
char error[255];
|
||||
libsys->GetPlatformError(error, sizeof(error));
|
||||
LogFatal("[SM] Unexpected fatal logging error (file \"%s\")", m_NrmFileName.c_str());
|
||||
LogFatal("[SM] Platform returned error: \"%s\"", error);
|
||||
LogFatal("[SM] Logging has been disabled.");
|
||||
m_Active = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void Logger::_MapChange(const char *mapname)
|
||||
void Logger::MapChange(const char *mapname)
|
||||
{
|
||||
m_CurrentMapName = mapname;
|
||||
_UpdateFiles(true);
|
||||
m_CurMapName.assign(mapname);
|
||||
|
||||
switch (m_Mode)
|
||||
{
|
||||
case LoggingMode_Daily:
|
||||
{
|
||||
LogMessage("-------- Mapchange to %s --------", mapname);
|
||||
break;
|
||||
}
|
||||
case LoggingMode_PerMap:
|
||||
{
|
||||
_NewMapFile();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
/* Do nothing... */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_ErrMapStart)
|
||||
{
|
||||
LogError("Error log file session closed.");
|
||||
}
|
||||
m_ErrMapStart = false;
|
||||
}
|
||||
|
||||
void Logger::_PrintToGameLog(const char *fmt, va_list ap)
|
||||
@ -259,6 +480,30 @@ void Logger::_PrintToGameLog(const char *fmt, va_list ap)
|
||||
bridge->LogToGame(msg);
|
||||
}
|
||||
|
||||
const char *Logger::GetLogFileName(LogType type) const
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case LogType_Normal:
|
||||
{
|
||||
return m_NrmFileName.c_str();
|
||||
}
|
||||
case LogType_Error:
|
||||
{
|
||||
return m_ErrFileName.c_str();
|
||||
}
|
||||
default:
|
||||
{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LoggingMode Logger::GetLoggingMode() const
|
||||
{
|
||||
return m_Mode;
|
||||
}
|
||||
|
||||
void Logger::EnableLogging()
|
||||
{
|
||||
if (m_Active)
|
||||
@ -294,161 +539,16 @@ void Logger::LogFatalEx(const char *msg, va_list ap)
|
||||
* It's already implemented twice which is bad.
|
||||
*/
|
||||
|
||||
FILE *pFile = _OpenFatal();
|
||||
if (!pFile)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
LogToOpenFileEx(pFile, msg, ap);
|
||||
fclose(pFile);
|
||||
}
|
||||
|
||||
void Logger::_UpdateFiles(bool bLevelChange)
|
||||
{
|
||||
time_t t = g_pSM->GetAdjustedTime();
|
||||
tm *curtime = localtime(&t);
|
||||
|
||||
if (!bLevelChange && curtime->tm_mday == m_Day)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_Day = curtime->tm_mday;
|
||||
|
||||
char buff[PLATFORM_MAX_PATH];
|
||||
ke::SafeSprintf(buff, sizeof(buff), "%04d%02d%02d", curtime->tm_year + 1900, curtime->tm_mon + 1, curtime->tm_mday);
|
||||
|
||||
ke::AString currentDate(buff);
|
||||
|
||||
if (m_Mode == LoggingMode_PerMap)
|
||||
{
|
||||
if (bLevelChange)
|
||||
{
|
||||
for (size_t iter = 0; iter < static_cast<size_t>(-1); ++iter)
|
||||
{
|
||||
g_pSM->BuildPath(Path_SM, buff, sizeof(buff), "logs/L%s%u.log", currentDate.chars(), iter);
|
||||
if (!libsys->IsPathFile(buff))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ke::SafeStrcpy(buff, sizeof(buff), m_NormalFileName.chars());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
g_pSM->BuildPath(Path_SM, buff, sizeof(buff), "logs/L%s.log", currentDate.chars());
|
||||
}
|
||||
|
||||
if (m_NormalFileName.compare(buff))
|
||||
{
|
||||
_CloseNormal();
|
||||
m_NormalFileName = buff;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bLevelChange)
|
||||
{
|
||||
LogMessage("-------- Mapchange to %s --------", m_CurrentMapName.chars());
|
||||
}
|
||||
}
|
||||
|
||||
g_pSM->BuildPath(Path_SM, buff, sizeof(buff), "logs/errors_%s.log", currentDate.chars());
|
||||
if (bLevelChange || m_ErrorFileName.compare(buff))
|
||||
{
|
||||
_CloseError();
|
||||
m_ErrorFileName = buff;
|
||||
}
|
||||
}
|
||||
|
||||
FILE *Logger::_OpenNormal()
|
||||
{
|
||||
_UpdateFiles();
|
||||
|
||||
FILE *pFile = fopen(m_NormalFileName.chars(), "a+");
|
||||
if (pFile == NULL)
|
||||
{
|
||||
_LogFatalOpen(m_NormalFileName);
|
||||
return pFile;
|
||||
}
|
||||
|
||||
if (!m_DamagedNormalFile)
|
||||
{
|
||||
time_t t = g_pSM->GetAdjustedTime();
|
||||
tm *curtime = localtime(&t);
|
||||
char date[32];
|
||||
|
||||
strftime(date, sizeof(date), "%m/%d/%Y - %H:%M:%S", curtime);
|
||||
fprintf(pFile, "L %s: SourceMod log file session started (file \"%s\") (Version \"%s\")\n", date, m_NormalFileName.chars(), SOURCEMOD_VERSION);
|
||||
m_DamagedNormalFile = true;
|
||||
}
|
||||
|
||||
return pFile;
|
||||
}
|
||||
|
||||
FILE *Logger::_OpenError()
|
||||
{
|
||||
_UpdateFiles();
|
||||
|
||||
FILE *pFile = fopen(m_ErrorFileName.chars(), "a+");
|
||||
if (pFile == NULL)
|
||||
{
|
||||
_LogFatalOpen(m_ErrorFileName);
|
||||
return pFile;
|
||||
}
|
||||
|
||||
if (!m_DamagedErrorFile)
|
||||
{
|
||||
time_t t = g_pSM->GetAdjustedTime();
|
||||
tm *curtime = localtime(&t);
|
||||
|
||||
char date[32];
|
||||
strftime(date, sizeof(date), "%m/%d/%Y - %H:%M:%S", curtime);
|
||||
fprintf(pFile, "L %s: SourceMod error session started\n", date);
|
||||
fprintf(pFile, "L %s: Info (map \"%s\") (file \"%s\")\n", date, m_CurrentMapName.chars(), m_ErrorFileName.chars());
|
||||
m_DamagedErrorFile = true;
|
||||
}
|
||||
|
||||
return pFile;
|
||||
}
|
||||
|
||||
FILE *Logger::_OpenFatal()
|
||||
{
|
||||
char path[PLATFORM_MAX_PATH];
|
||||
|
||||
g_pSM->BuildPath(Path_Game, path, sizeof(path), "sourcemod_fatal.log");
|
||||
return fopen(path, "at");
|
||||
}
|
||||
|
||||
void Logger::_LogFatalOpen(ke::AString &str)
|
||||
{
|
||||
char error[255];
|
||||
libsys->GetPlatformError(error, sizeof(error));
|
||||
LogFatal("[SM] Unexpected fatal logging error (file \"%s\")", str.chars());
|
||||
LogFatal("[SM] Platform returned error: \"%s\"", error);
|
||||
}
|
||||
|
||||
void Logger::_CloseNormal()
|
||||
{
|
||||
if (m_DamagedNormalFile)
|
||||
FILE *fp = fopen(path, "at");
|
||||
if (fp)
|
||||
{
|
||||
LogMessage("Log file closed.");
|
||||
m_DamagedNormalFile = false;
|
||||
m_Active = true;
|
||||
LogToOpenFileEx(fp, msg, ap);
|
||||
m_Active = false;
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
|
||||
void Logger::_CloseError()
|
||||
{
|
||||
if (m_DamagedErrorFile)
|
||||
{
|
||||
LogError("Error log file session closed.");
|
||||
m_DamagedErrorFile = false;
|
||||
}
|
||||
}
|
||||
|
||||
void Logger::_CloseFatal()
|
||||
{
|
||||
}
|
||||
|
@ -34,9 +34,11 @@
|
||||
|
||||
#include "common_logic.h"
|
||||
#include <stdio.h>
|
||||
#include <amtl/am-string.h>
|
||||
#include <sh_string.h>
|
||||
#include <bridge/include/ILogger.h>
|
||||
|
||||
using namespace SourceHook;
|
||||
|
||||
enum LogType
|
||||
{
|
||||
LogType_Normal,
|
||||
@ -53,7 +55,9 @@ enum LoggingMode
|
||||
class Logger : public SMGlobalClass, public ILogger
|
||||
{
|
||||
public:
|
||||
Logger() : m_Day(-1), m_Mode(LoggingMode_Daily), m_Active(true), m_DamagedNormalFile(false), m_DamagedErrorFile(false)
|
||||
Logger() : m_Mode(LoggingMode_Daily), m_ErrMapStart(false),
|
||||
m_Active(false), m_DelayedStart(false), m_DailyPrintHdr(false),
|
||||
m_InitialState(true)
|
||||
{
|
||||
}
|
||||
public: //SMGlobalClass
|
||||
@ -66,6 +70,7 @@ public: //SMGlobalClass
|
||||
void OnSourceModAllShutdown();
|
||||
void OnSourceModLevelChange(const char *mapName);
|
||||
public:
|
||||
void InitLogger(LoggingMode mode);
|
||||
void CloseLogger();
|
||||
void EnableLogging();
|
||||
void DisableLogging();
|
||||
@ -80,32 +85,25 @@ public:
|
||||
/* This version does not print to console, and is thus thread-safe */
|
||||
void LogToFileOnly(FILE *fp, const char *msg, ...);
|
||||
void LogToFileOnlyEx(FILE *fp, const char *msg, va_list ap);
|
||||
void MapChange(const char *mapname);
|
||||
const char *GetLogFileName(LogType type) const;
|
||||
LoggingMode GetLoggingMode() const;
|
||||
private:
|
||||
void _MapChange(const char *mapname);
|
||||
|
||||
void _CloseFile();
|
||||
void _CloseNormal();
|
||||
void _CloseError();
|
||||
void _CloseFatal();
|
||||
|
||||
FILE *_OpenNormal();
|
||||
FILE *_OpenError();
|
||||
FILE *_OpenFatal();
|
||||
|
||||
void _LogFatalOpen(ke::AString &str);
|
||||
void _NewMapFile();
|
||||
void _PrintToGameLog(const char *fmt, va_list ap);
|
||||
void _UpdateFiles(bool bLevelChange = false);
|
||||
private:
|
||||
ke::AString m_NormalFileName;
|
||||
ke::AString m_ErrorFileName;
|
||||
ke::AString m_CurrentMapName;
|
||||
|
||||
int m_Day;
|
||||
|
||||
String m_NrmFileName;
|
||||
String m_ErrFileName;
|
||||
String m_CurMapName;
|
||||
LoggingMode m_Mode;
|
||||
int m_NrmCurDay;
|
||||
int m_ErrCurDay;
|
||||
bool m_ErrMapStart;
|
||||
bool m_Active;
|
||||
bool m_DamagedNormalFile;
|
||||
bool m_DamagedErrorFile;
|
||||
bool m_DelayedStart;
|
||||
bool m_DailyPrintHdr;
|
||||
bool m_InitialState;
|
||||
};
|
||||
|
||||
extern Logger g_Logger;
|
||||
|
@ -43,6 +43,18 @@
|
||||
#include <mach-o/dyld_images.h>
|
||||
#include <mach-o/loader.h>
|
||||
#include <mach-o/nlist.h>
|
||||
|
||||
/* Define things from 10.6 SDK for older SDKs */
|
||||
#ifndef MAC_OS_X_VERSION_10_6
|
||||
struct task_dyld_info
|
||||
{
|
||||
mach_vm_address_t all_image_info_addr;
|
||||
mach_vm_size_t all_image_info_size;
|
||||
};
|
||||
typedef struct task_dyld_info task_dyld_info_data_t;
|
||||
#define TASK_DYLD_INFO 17
|
||||
#define TASK_DYLD_INFO_COUNT (sizeof(task_dyld_info_data_t) / sizeof(natural_t))
|
||||
#endif // MAC_OS_X_VERSION_10_6
|
||||
#endif // PLATFORM_APPLE
|
||||
|
||||
MemoryUtils g_MemUtils;
|
||||
@ -51,10 +63,25 @@ MemoryUtils::MemoryUtils()
|
||||
{
|
||||
#ifdef PLATFORM_APPLE
|
||||
|
||||
Gestalt(gestaltSystemVersionMajor, &m_OSXMajor);
|
||||
Gestalt(gestaltSystemVersionMinor, &m_OSXMinor);
|
||||
|
||||
/* Get pointer to struct that describes all loaded mach-o images in process */
|
||||
if ((m_OSXMajor == 10 && m_OSXMinor >= 6) || m_OSXMajor > 10)
|
||||
{
|
||||
task_dyld_info_data_t dyld_info;
|
||||
mach_msg_type_number_t count = TASK_DYLD_INFO_COUNT;
|
||||
task_info(mach_task_self(), TASK_DYLD_INFO, (task_info_t)&dyld_info, &count);
|
||||
m_ImageList = (struct dyld_all_image_infos *)dyld_info.all_image_info_addr;
|
||||
}
|
||||
else
|
||||
{
|
||||
struct nlist list[2];
|
||||
memset(list, 0, sizeof(list));
|
||||
list[0].n_un.n_name = (char *)"_dyld_all_image_infos";
|
||||
nlist("/usr/lib/dyld", list);
|
||||
m_ImageList = (struct dyld_all_image_infos *)list[0].n_value;
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
@ -120,25 +147,13 @@ void *MemoryUtils::ResolveSymbol(void *handle, const char *symbol)
|
||||
|
||||
#elif defined PLATFORM_LINUX
|
||||
|
||||
#ifdef PLATFORM_X86
|
||||
typedef Elf32_Ehdr ElfHeader;
|
||||
typedef Elf32_Shdr ElfSHeader;
|
||||
typedef Elf32_Sym ElfSymbol;
|
||||
#define ELF_SYM_TYPE ELF32_ST_TYPE
|
||||
#else
|
||||
typedef Elf64_Ehdr ElfHeader;
|
||||
typedef Elf64_Shdr ElfSHeader;
|
||||
typedef Elf64_Sym ElfSymbol;
|
||||
#define ELF_SYM_TYPE ELF64_ST_TYPE
|
||||
#endif
|
||||
|
||||
struct link_map *dlmap;
|
||||
struct stat dlstat;
|
||||
int dlfile;
|
||||
uintptr_t map_base;
|
||||
ElfHeader *file_hdr;
|
||||
ElfSHeader *sections, *shstrtab_hdr, *symtab_hdr, *strtab_hdr;
|
||||
ElfSymbol *symtab;
|
||||
Elf32_Ehdr *file_hdr;
|
||||
Elf32_Shdr *sections, *shstrtab_hdr, *symtab_hdr, *strtab_hdr;
|
||||
Elf32_Sym *symtab;
|
||||
const char *shstrtab, *strtab;
|
||||
uint16_t section_count;
|
||||
uint32_t symbol_count;
|
||||
@ -189,7 +204,7 @@ void *MemoryUtils::ResolveSymbol(void *handle, const char *symbol)
|
||||
}
|
||||
|
||||
/* Map library file into memory */
|
||||
file_hdr = (ElfHeader *)mmap(NULL, dlstat.st_size, PROT_READ, MAP_PRIVATE, dlfile, 0);
|
||||
file_hdr = (Elf32_Ehdr *)mmap(NULL, dlstat.st_size, PROT_READ, MAP_PRIVATE, dlfile, 0);
|
||||
map_base = (uintptr_t)file_hdr;
|
||||
if (file_hdr == MAP_FAILED)
|
||||
{
|
||||
@ -204,7 +219,7 @@ void *MemoryUtils::ResolveSymbol(void *handle, const char *symbol)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sections = (ElfSHeader *)(map_base + file_hdr->e_shoff);
|
||||
sections = (Elf32_Shdr *)(map_base + file_hdr->e_shoff);
|
||||
section_count = file_hdr->e_shnum;
|
||||
/* Get ELF section header string table */
|
||||
shstrtab_hdr = §ions[file_hdr->e_shstrndx];
|
||||
@ -213,7 +228,7 @@ void *MemoryUtils::ResolveSymbol(void *handle, const char *symbol)
|
||||
/* Iterate sections while looking for ELF symbol table and string table */
|
||||
for (uint16_t i = 0; i < section_count; i++)
|
||||
{
|
||||
ElfSHeader &hdr = sections[i];
|
||||
Elf32_Shdr &hdr = sections[i];
|
||||
const char *section_name = shstrtab + hdr.sh_name;
|
||||
|
||||
if (strcmp(section_name, ".symtab") == 0)
|
||||
@ -233,15 +248,15 @@ void *MemoryUtils::ResolveSymbol(void *handle, const char *symbol)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
symtab = (ElfSymbol *)(map_base + symtab_hdr->sh_offset);
|
||||
symtab = (Elf32_Sym *)(map_base + symtab_hdr->sh_offset);
|
||||
strtab = (const char *)(map_base + strtab_hdr->sh_offset);
|
||||
symbol_count = symtab_hdr->sh_size / symtab_hdr->sh_entsize;
|
||||
|
||||
/* Iterate symbol table starting from the position we were at last time */
|
||||
for (uint32_t i = libtable->last_pos; i < symbol_count; i++)
|
||||
{
|
||||
ElfSymbol &sym = symtab[i];
|
||||
unsigned char sym_type = ELF_SYM_TYPE(sym.st_info);
|
||||
Elf32_Sym &sym = symtab[i];
|
||||
unsigned char sym_type = ELF32_ST_TYPE(sym.st_info);
|
||||
const char *sym_name = strtab + sym.st_name;
|
||||
Symbol *cur_sym;
|
||||
|
||||
@ -266,28 +281,13 @@ void *MemoryUtils::ResolveSymbol(void *handle, const char *symbol)
|
||||
|
||||
#elif defined PLATFORM_APPLE
|
||||
|
||||
#ifdef PLATFORM_X86
|
||||
typedef struct mach_header MachHeader;
|
||||
typedef struct segment_command MachSegment;
|
||||
typedef struct nlist MachSymbol;
|
||||
const uint32_t MACH_LOADCMD_SEGMENT = LC_SEGMENT;
|
||||
#else
|
||||
typedef struct mach_header_64 MachHeader;
|
||||
typedef struct segment_command_64 MachSegment;
|
||||
typedef struct nlist_64 MachSymbol;
|
||||
const uint32_t MACH_LOADCMD_SEGMENT = LC_SEGMENT_64;
|
||||
#endif
|
||||
|
||||
typedef struct load_command MachLoadCmd;
|
||||
typedef struct symtab_command MachSymHeader;
|
||||
|
||||
uintptr_t dlbase, linkedit_addr;
|
||||
uint32_t image_count;
|
||||
MachHeader *file_hdr;
|
||||
MachLoadCmd *loadcmds;
|
||||
MachSegment *linkedit_hdr;
|
||||
MachSymHeader *symtab_hdr;
|
||||
MachSymbol *symtab;
|
||||
struct mach_header *file_hdr;
|
||||
struct load_command *loadcmds;
|
||||
struct segment_command *linkedit_hdr;
|
||||
struct symtab_command *symtab_hdr;
|
||||
struct nlist *symtab;
|
||||
const char *strtab;
|
||||
uint32_t loadcmd_count;
|
||||
uint32_t symbol_count;
|
||||
@ -357,16 +357,16 @@ void *MemoryUtils::ResolveSymbol(void *handle, const char *symbol)
|
||||
|
||||
/* If symbol isn't in our table, then we have to locate it in memory */
|
||||
|
||||
file_hdr = (MachHeader *)dlbase;
|
||||
loadcmds = (MachLoadCmd *)(dlbase + sizeof(MachHeader));
|
||||
file_hdr = (struct mach_header *)dlbase;
|
||||
loadcmds = (struct load_command *)(dlbase + sizeof(struct mach_header));
|
||||
loadcmd_count = file_hdr->ncmds;
|
||||
|
||||
/* Loop through load commands until we find the ones for the symbol table */
|
||||
for (uint32_t i = 0; i < loadcmd_count; i++)
|
||||
{
|
||||
if (loadcmds->cmd == MACH_LOADCMD_SEGMENT && !linkedit_hdr)
|
||||
if (loadcmds->cmd == LC_SEGMENT && !linkedit_hdr)
|
||||
{
|
||||
MachSegment *seg = (MachSegment *)loadcmds;
|
||||
struct segment_command *seg = (struct segment_command *)loadcmds;
|
||||
if (strcmp(seg->segname, "__LINKEDIT") == 0)
|
||||
{
|
||||
linkedit_hdr = seg;
|
||||
@ -378,7 +378,7 @@ void *MemoryUtils::ResolveSymbol(void *handle, const char *symbol)
|
||||
}
|
||||
else if (loadcmds->cmd == LC_SYMTAB)
|
||||
{
|
||||
symtab_hdr = (MachSymHeader *)loadcmds;
|
||||
symtab_hdr = (struct symtab_command *)loadcmds;
|
||||
if (linkedit_hdr)
|
||||
{
|
||||
break;
|
||||
@ -386,7 +386,7 @@ void *MemoryUtils::ResolveSymbol(void *handle, const char *symbol)
|
||||
}
|
||||
|
||||
/* Load commands are not of a fixed size which is why we add the size */
|
||||
loadcmds = (MachLoadCmd *)((uintptr_t)loadcmds + loadcmds->cmdsize);
|
||||
loadcmds = (struct load_command *)((uintptr_t)loadcmds + loadcmds->cmdsize);
|
||||
}
|
||||
|
||||
if (!linkedit_hdr || !symtab_hdr || !symtab_hdr->symoff || !symtab_hdr->stroff)
|
||||
@ -396,14 +396,14 @@ void *MemoryUtils::ResolveSymbol(void *handle, const char *symbol)
|
||||
}
|
||||
|
||||
linkedit_addr = dlbase + linkedit_hdr->vmaddr;
|
||||
symtab = (MachSymbol *)(linkedit_addr + symtab_hdr->symoff - linkedit_hdr->fileoff);
|
||||
symtab = (struct nlist *)(linkedit_addr + symtab_hdr->symoff - linkedit_hdr->fileoff);
|
||||
strtab = (const char *)(linkedit_addr + symtab_hdr->stroff - linkedit_hdr->fileoff);
|
||||
symbol_count = symtab_hdr->nsyms;
|
||||
|
||||
/* Iterate symbol table starting from the position we were at last time */
|
||||
for (uint32_t i = libtable->last_pos; i < symbol_count; i++)
|
||||
{
|
||||
MachSymbol &sym = symtab[i];
|
||||
struct nlist &sym = symtab[i];
|
||||
/* Ignore the prepended underscore on all symbols, so +1 here */
|
||||
const char *sym_name = strtab + sym.n_un.n_strx + 1;
|
||||
Symbol *cur_sym;
|
||||
@ -440,12 +440,6 @@ bool MemoryUtils::GetLibraryInfo(const void *libPtr, DynLibInfo &lib)
|
||||
|
||||
#ifdef PLATFORM_WINDOWS
|
||||
|
||||
#ifdef PLATFORM_X86
|
||||
const WORD PE_FILE_MACHINE = IMAGE_FILE_MACHINE_I386;
|
||||
#else
|
||||
const WORD PE_FILE_MACHINE = IMAGE_FILE_MACHINE_AMD64;
|
||||
#endif
|
||||
|
||||
MEMORY_BASIC_INFORMATION info;
|
||||
IMAGE_DOS_HEADER *dos;
|
||||
IMAGE_NT_HEADERS *pe;
|
||||
@ -471,8 +465,10 @@ bool MemoryUtils::GetLibraryInfo(const void *libPtr, DynLibInfo &lib)
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Check architecture */
|
||||
if (file->Machine != PE_FILE_MACHINE)
|
||||
/* Check architecture, which is 32-bit/x86 right now
|
||||
* Should change this for 64-bit if Valve gets their act together
|
||||
*/
|
||||
if (file->Machine != IMAGE_FILE_MACHINE_I386)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -488,21 +484,9 @@ bool MemoryUtils::GetLibraryInfo(const void *libPtr, DynLibInfo &lib)
|
||||
|
||||
#elif defined PLATFORM_LINUX
|
||||
|
||||
#ifdef PLATFORM_X86
|
||||
typedef Elf32_Ehdr ElfHeader;
|
||||
typedef Elf32_Phdr ElfPHeader;
|
||||
const unsigned char ELF_CLASS = ELFCLASS32;
|
||||
const uint16_t ELF_MACHINE = EM_386;
|
||||
#else
|
||||
typedef Elf64_Ehdr ElfHeader;
|
||||
typedef Elf64_Phdr ElfPHeader;
|
||||
const unsigned char ELF_CLASS = ELFCLASS64;
|
||||
const uint16_t ELF_MACHINE = EM_X86_64;
|
||||
#endif
|
||||
|
||||
Dl_info info;
|
||||
ElfHeader *file;
|
||||
ElfPHeader *phdr;
|
||||
Elf32_Ehdr *file;
|
||||
Elf32_Phdr *phdr;
|
||||
uint16_t phdrCount;
|
||||
|
||||
if (!dladdr(libPtr, &info))
|
||||
@ -517,7 +501,7 @@ bool MemoryUtils::GetLibraryInfo(const void *libPtr, DynLibInfo &lib)
|
||||
|
||||
/* This is for our insane sanity checks :o */
|
||||
baseAddr = reinterpret_cast<uintptr_t>(info.dli_fbase);
|
||||
file = reinterpret_cast<ElfHeader *>(baseAddr);
|
||||
file = reinterpret_cast<Elf32_Ehdr *>(baseAddr);
|
||||
|
||||
/* Check ELF magic */
|
||||
if (memcmp(ELFMAG, file->e_ident, SELFMAG) != 0)
|
||||
@ -531,14 +515,10 @@ bool MemoryUtils::GetLibraryInfo(const void *libPtr, DynLibInfo &lib)
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Check ELF endianness */
|
||||
if (file->e_ident[EI_DATA] != ELFDATA2LSB)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Check ELF architecture */
|
||||
if (file->e_ident[EI_CLASS] != ELF_CLASS || file->e_machine != ELF_MACHINE)
|
||||
/* Check ELF architecture, which is 32-bit/x86 right now
|
||||
* Should change this for 64-bit if Valve gets their act together
|
||||
*/
|
||||
if (file->e_ident[EI_CLASS] != ELFCLASS32 || file->e_machine != EM_386 || file->e_ident[EI_DATA] != ELFDATA2LSB)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -550,11 +530,11 @@ bool MemoryUtils::GetLibraryInfo(const void *libPtr, DynLibInfo &lib)
|
||||
}
|
||||
|
||||
phdrCount = file->e_phnum;
|
||||
phdr = reinterpret_cast<ElfPHeader *>(baseAddr + file->e_phoff);
|
||||
phdr = reinterpret_cast<Elf32_Phdr *>(baseAddr + file->e_phoff);
|
||||
|
||||
for (uint16_t i = 0; i < phdrCount; i++)
|
||||
{
|
||||
ElfPHeader &hdr = phdr[i];
|
||||
Elf32_Phdr &hdr = phdr[i];
|
||||
|
||||
/* We only really care about the segment with executable code */
|
||||
if (hdr.p_type == PT_LOAD && hdr.p_flags == (PF_X|PF_R))
|
||||
@ -573,25 +553,9 @@ bool MemoryUtils::GetLibraryInfo(const void *libPtr, DynLibInfo &lib)
|
||||
|
||||
#elif defined PLATFORM_APPLE
|
||||
|
||||
#ifdef PLATFORM_X86
|
||||
typedef struct mach_header MachHeader;
|
||||
typedef struct segment_command MachSegment;
|
||||
const uint32_t MACH_MAGIC = MH_MAGIC;
|
||||
const uint32_t MACH_LOADCMD_SEGMENT = LC_SEGMENT;
|
||||
const cpu_type_t MACH_CPU_TYPE = CPU_TYPE_I386;
|
||||
const cpu_subtype_t MACH_CPU_SUBTYPE = CPU_SUBTYPE_I386_ALL;
|
||||
#else
|
||||
typedef struct mach_header_64 MachHeader;
|
||||
typedef struct segment_command_64 MachSegment;
|
||||
const uint32_t MACH_MAGIC = MH_MAGIC_64;
|
||||
const uint32_t MACH_LOADCMD_SEGMENT = LC_SEGMENT_64;
|
||||
const cpu_type_t MACH_CPU_TYPE = CPU_TYPE_X86_64;
|
||||
const cpu_subtype_t MACH_CPU_SUBTYPE = CPU_SUBTYPE_X86_64_ALL;
|
||||
#endif
|
||||
|
||||
Dl_info info;
|
||||
MachHeader *file;
|
||||
MachSegment *seg;
|
||||
struct mach_header *file;
|
||||
struct segment_command *seg;
|
||||
uint32_t cmd_count;
|
||||
|
||||
if (!dladdr(libPtr, &info))
|
||||
@ -606,16 +570,16 @@ bool MemoryUtils::GetLibraryInfo(const void *libPtr, DynLibInfo &lib)
|
||||
|
||||
/* This is for our insane sanity checks :o */
|
||||
baseAddr = (uintptr_t)info.dli_fbase;
|
||||
file = (MachHeader *)baseAddr;
|
||||
file = (struct mach_header *)baseAddr;
|
||||
|
||||
/* Check Mach-O magic */
|
||||
if (file->magic != MACH_MAGIC)
|
||||
if (file->magic != MH_MAGIC)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Check architecture */
|
||||
if (file->cputype != MACH_CPU_TYPE || file->cpusubtype != MACH_CPU_SUBTYPE)
|
||||
/* Check architecture (32-bit/x86) */
|
||||
if (file->cputype != CPU_TYPE_I386 || file->cpusubtype != CPU_SUBTYPE_I386_ALL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -627,17 +591,17 @@ bool MemoryUtils::GetLibraryInfo(const void *libPtr, DynLibInfo &lib)
|
||||
}
|
||||
|
||||
cmd_count = file->ncmds;
|
||||
seg = (MachSegment *)(baseAddr + sizeof(MachHeader));
|
||||
seg = (struct segment_command *)(baseAddr + sizeof(struct mach_header));
|
||||
|
||||
/* Add up memory sizes of mapped segments */
|
||||
for (uint32_t i = 0; i < cmd_count; i++)
|
||||
{
|
||||
if (seg->cmd == MACH_LOADCMD_SEGMENT)
|
||||
if (seg->cmd == LC_SEGMENT)
|
||||
{
|
||||
lib.memorySize += seg->vmsize;
|
||||
}
|
||||
|
||||
seg = (MachSegment *)((uintptr_t)seg + seg->cmdsize);
|
||||
seg = (struct segment_command *)((uintptr_t)seg + seg->cmdsize);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -33,7 +33,6 @@
|
||||
|
||||
#include <IShareSys.h>
|
||||
#include <IHandleSys.h>
|
||||
#include <am-autoptr.h>
|
||||
#include <am-string.h>
|
||||
#include <am-utility.h>
|
||||
#include <am-refcounting.h>
|
||||
|
@ -75,7 +75,7 @@ CPlugin::CPlugin(const char *file)
|
||||
m_serial = ++MySerial;
|
||||
m_errormsg[0] = '\0';
|
||||
m_DateTime[0] = '\0';
|
||||
ke::SafeStrcpy(m_filename, sizeof(m_filename), file);
|
||||
ke::SafeSprintf(m_filename, sizeof(m_filename), "%s", file);
|
||||
|
||||
memset(&m_info, 0, sizeof(m_info));
|
||||
|
||||
@ -905,7 +905,7 @@ void CPluginManager::LoadPluginsFromDir(const char *basedir, const char *localpa
|
||||
if (localpath == NULL)
|
||||
{
|
||||
/* If no path yet, don't add a former slash */
|
||||
ke::SafeStrcpy(new_local, sizeof(new_local), dir->GetEntryName());
|
||||
ke::SafeSprintf(new_local, sizeof(new_local), "%s", dir->GetEntryName());
|
||||
} else {
|
||||
libsys->PathFormat(new_local, sizeof(new_local), "%s/%s", localpath, dir->GetEntryName());
|
||||
}
|
||||
@ -920,7 +920,7 @@ void CPluginManager::LoadPluginsFromDir(const char *basedir, const char *localpa
|
||||
char plugin[PLATFORM_MAX_PATH];
|
||||
if (localpath == NULL)
|
||||
{
|
||||
ke::SafeStrcpy(plugin, sizeof(plugin), name);
|
||||
ke::SafeSprintf(plugin, sizeof(plugin), "%s", name);
|
||||
} else {
|
||||
libsys->PathFormat(plugin, sizeof(plugin), "%s/%s", localpath, name);
|
||||
}
|
||||
@ -994,9 +994,9 @@ IPlugin *CPluginManager::LoadPlugin(const char *path, bool debug, PluginType typ
|
||||
|
||||
if (res == LoadRes_NeverLoad) {
|
||||
if (m_LoadingLocked)
|
||||
ke::SafeStrcpy(error, maxlength, "There is a global plugin loading lock in effect");
|
||||
ke::SafeSprintf(error, maxlength, "There is a global plugin loading lock in effect");
|
||||
else
|
||||
ke::SafeStrcpy(error, maxlength, "This plugin is blocked from loading (see plugin_settings.cfg)");
|
||||
ke::SafeSprintf(error, maxlength, "This plugin is blocked from loading (see plugin_settings.cfg)");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -1277,7 +1277,7 @@ bool CPluginManager::MalwareCheckPass(CPlugin *pPlugin)
|
||||
unsigned char *pCodeHash = pPlugin->GetRuntime()->GetCodeHash();
|
||||
|
||||
char codeHashBuf[40];
|
||||
ke::SafeStrcpy(codeHashBuf, sizeof(codeHashBuf), "plugin_");
|
||||
ke::SafeSprintf(codeHashBuf, 40, "plugin_");
|
||||
for (int i = 0; i < 16; i++)
|
||||
ke::SafeSprintf(codeHashBuf + 7 + (i * 2), 3, "%02x", pCodeHash[i]);
|
||||
|
||||
@ -1607,7 +1607,7 @@ ConfigResult CPluginManager::OnSourceModConfigChanged(const char *key,
|
||||
} else if (strcasecmp(value, "no") == 0) {
|
||||
m_bBlockBadPlugins = false;
|
||||
} else {
|
||||
ke::SafeStrcpy(error, maxlength, "Invalid value: must be \"yes\" or \"no\"");
|
||||
ke::SafeSprintf(error, maxlength, "Invalid value: must be \"yes\" or \"no\"");
|
||||
return ConfigResult_Reject;
|
||||
}
|
||||
return ConfigResult_Accept;
|
||||
@ -1701,9 +1701,6 @@ void CPluginManager::OnRootConsoleCommand(const char *cmdname, const ICommandArg
|
||||
char buffer[256];
|
||||
unsigned int id = 1;
|
||||
int plnum = GetPluginCount();
|
||||
char plstr[10];
|
||||
ke::SafeSprintf(plstr, sizeof(plstr), "%d", plnum);
|
||||
int plpadding = strlen(plstr);
|
||||
|
||||
if (!plnum)
|
||||
{
|
||||
@ -1712,7 +1709,7 @@ void CPluginManager::OnRootConsoleCommand(const char *cmdname, const ICommandArg
|
||||
}
|
||||
else
|
||||
{
|
||||
rootmenu->ConsolePrint("[SM] Listing %d plugin%s:", plnum, (plnum > 1) ? "s" : "");
|
||||
rootmenu->ConsolePrint("[SM] Listing %d plugin%s:", GetPluginCount(), (plnum > 1) ? "s" : "");
|
||||
}
|
||||
|
||||
ke::LinkedList<CPlugin *> fail_list;
|
||||
@ -1724,19 +1721,19 @@ void CPluginManager::OnRootConsoleCommand(const char *cmdname, const ICommandArg
|
||||
const sm_plugininfo_t *info = pl->GetPublicInfo();
|
||||
if (pl->GetStatus() != Plugin_Running && !pl->IsSilentlyFailed())
|
||||
{
|
||||
len += ke::SafeSprintf(buffer, sizeof(buffer), " %0*d <%s>", plpadding, id, GetStatusText(pl->GetDisplayStatus()));
|
||||
len += ke::SafeSprintf(buffer, sizeof(buffer), " %02d <%s>", id, GetStatusText(pl->GetDisplayStatus()));
|
||||
|
||||
/* Plugin has failed to load. */
|
||||
fail_list.append(pl);
|
||||
}
|
||||
else
|
||||
{
|
||||
len += ke::SafeSprintf(buffer, sizeof(buffer), " %0*d", plpadding, id);
|
||||
len += ke::SafeSprintf(buffer, sizeof(buffer), " %02d", id);
|
||||
}
|
||||
if (pl->GetStatus() < Plugin_Created || pl->GetStatus() == Plugin_Evicted)
|
||||
{
|
||||
if (pl->IsSilentlyFailed())
|
||||
len += ke::SafeStrcpy(&buffer[len], sizeof(buffer)-len, " Disabled:");
|
||||
len += ke::SafeSprintf(&buffer[len], sizeof(buffer)-len, " Disabled:");
|
||||
len += ke::SafeSprintf(&buffer[len], sizeof(buffer)-len, " \"%s\"", (IS_STR_FILLED(info->name)) ? info->name : pl->GetFilename());
|
||||
if (IS_STR_FILLED(info->version))
|
||||
{
|
||||
@ -1845,11 +1842,11 @@ void CPluginManager::OnRootConsoleCommand(const char *cmdname, const ICommandArg
|
||||
if (pl->GetStatus() < Plugin_Created)
|
||||
{
|
||||
const sm_plugininfo_t *info = pl->GetPublicInfo();
|
||||
ke::SafeStrcpy(name, sizeof(name), (IS_STR_FILLED(info->name)) ? info->name : pl->GetFilename());
|
||||
ke::SafeSprintf(name, sizeof(name), (IS_STR_FILLED(info->name)) ? info->name : pl->GetFilename());
|
||||
}
|
||||
else
|
||||
{
|
||||
ke::SafeStrcpy(name, sizeof(name), pl->GetFilename());
|
||||
ke::SafeSprintf(name, sizeof(name), "%s", pl->GetFilename());
|
||||
}
|
||||
|
||||
if (UnloadPlugin(pl))
|
||||
|
@ -55,6 +55,9 @@
|
||||
#include <bridge/include/IScriptManager.h>
|
||||
#include <am-function.h>
|
||||
#include <ReentrantList.h>
|
||||
#ifdef PLATFORM_APPLE
|
||||
#include <cctype>
|
||||
#endif
|
||||
|
||||
class CPlayer;
|
||||
|
||||
@ -484,10 +487,17 @@ private:
|
||||
{
|
||||
/* For windows & mac, we convert the path to lower-case in order to avoid duplicate plugin loading */
|
||||
#if defined PLATFORM_WINDOWS || defined PLATFORM_APPLE
|
||||
ke::AString original(key.chars());
|
||||
ke::AString lower = original.lowercase();
|
||||
const char *original = key.chars();
|
||||
char *copy = strdup(original);
|
||||
|
||||
return detail::CharsAndLength(lower.chars()).hash();
|
||||
for (size_t i = 0; copy[i]; ++i)
|
||||
{
|
||||
copy[i] = tolower(copy[i]);
|
||||
}
|
||||
|
||||
uint32_t hash = detail::CharsAndLength(copy).hash();
|
||||
free(copy);
|
||||
return hash;
|
||||
#else
|
||||
return key.hash();
|
||||
#endif
|
||||
@ -495,14 +505,25 @@ private:
|
||||
|
||||
static inline bool matches(const char *file, const CPlugin *plugin)
|
||||
{
|
||||
const char *pluginFileChars = const_cast<CPlugin*>(plugin)->GetFilename();
|
||||
const char *pluginFile = const_cast<CPlugin*>(plugin)->GetFilename();
|
||||
#if defined PLATFORM_WINDOWS || defined PLATFORM_APPLE
|
||||
ke::AString pluginFile = ke::AString(pluginFileChars).lowercase();
|
||||
ke::AString input = ke::AString(file).lowercase();
|
||||
size_t fileLen = strlen(file);
|
||||
if (fileLen != strlen(pluginFile))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return pluginFile == input;
|
||||
for (size_t i = 0; i < fileLen; ++i)
|
||||
{
|
||||
if (tolower(file[i]) != tolower(pluginFile[i]))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
#else
|
||||
return strcmp(pluginFileChars, file) == 0;
|
||||
return strcmp(pluginFile, file) == 0;
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
@ -1,169 +0,0 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod
|
||||
* Copyright (C) 2004-2017 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* 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 <http://www.sourcemod.net/license.php>.
|
||||
*/
|
||||
|
||||
#include "PseudoAddrManager.h"
|
||||
#ifdef PLATFORM_APPLE
|
||||
#include <mach/mach.h>
|
||||
#include <mach/vm_region.h>
|
||||
#endif
|
||||
#ifdef PLATFORM_LINUX
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
|
||||
PseudoAddressManager::PseudoAddressManager() : m_NumEntries(0)
|
||||
{
|
||||
}
|
||||
|
||||
// A pseudo address consists of a table index in the upper 6 bits and an offset in the
|
||||
// lower 26 bits. The table consists of memory allocation base addresses.
|
||||
void *PseudoAddressManager::FromPseudoAddress(uint32_t paddr)
|
||||
{
|
||||
#ifdef PLATFORM_X64
|
||||
uint8_t index = paddr >> PSEUDO_OFFSET_BITS;
|
||||
uint32_t offset = paddr & ((1 << PSEUDO_OFFSET_BITS) - 1);
|
||||
|
||||
if (index >= m_NumEntries)
|
||||
return nullptr;
|
||||
|
||||
return reinterpret_cast<void *>(uintptr_t(m_AllocBases[index]) + offset);
|
||||
#else
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
uint32_t PseudoAddressManager::ToPseudoAddress(void *addr)
|
||||
{
|
||||
#ifdef PLATFORM_X64
|
||||
uint8_t index = 0;
|
||||
uint32_t offset = 0;
|
||||
bool hasEntry = false;
|
||||
void *base = GetAllocationBase(addr);
|
||||
|
||||
if (base) {
|
||||
for (int i = 0; i < m_NumEntries; i++) {
|
||||
if (m_AllocBases[i] == base) {
|
||||
index = i;
|
||||
hasEntry = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!hasEntry) {
|
||||
index = m_NumEntries;
|
||||
if (m_NumEntries < SM_ARRAYSIZE(m_AllocBases))
|
||||
m_AllocBases[m_NumEntries++] = base;
|
||||
else
|
||||
return 0; // Table is full
|
||||
}
|
||||
|
||||
ptrdiff_t diff = uintptr_t(addr) - uintptr_t(base);
|
||||
|
||||
// Ensure difference fits in 26 bits
|
||||
if (diff > (UINT32_MAX >> PSEUDO_INDEX_BITS))
|
||||
return 0;
|
||||
|
||||
return (index << PSEUDO_OFFSET_BITS) | diff;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void *PseudoAddressManager::GetAllocationBase(void *ptr)
|
||||
{
|
||||
#if defined PLATFORM_WINDOWS
|
||||
|
||||
MEMORY_BASIC_INFORMATION info;
|
||||
if (!VirtualQuery(ptr, &info, sizeof(MEMORY_BASIC_INFORMATION)))
|
||||
return nullptr;
|
||||
return info.AllocationBase;
|
||||
|
||||
#elif defined PLATFORM_APPLE
|
||||
|
||||
#ifdef PLATFORM_X86
|
||||
typedef vm_region_info_t mach_vm_region_info_t;
|
||||
typedef vm_region_basic_info_data_t mach_vm_region_basic_info_data_t;
|
||||
const vm_region_flavor_t MACH_VM_REGION_BASIC_INFO = VM_REGION_BASIC_INFO;
|
||||
const mach_msg_type_number_t MACH_VM_REGION_BASIC_INFO_COUNT = VM_REGION_BASIC_INFO_COUNT;
|
||||
#define mach_vm_region vm_region
|
||||
#elif defined PLATFORM_X64
|
||||
typedef vm_region_info_64_t mach_vm_region_info_t ;
|
||||
typedef vm_region_basic_info_data_64_t mach_vm_region_basic_info_data_t;
|
||||
const vm_region_flavor_t MACH_VM_REGION_BASIC_INFO = VM_REGION_BASIC_INFO_64;
|
||||
const mach_msg_type_number_t MACH_VM_REGION_BASIC_INFO_COUNT = VM_REGION_BASIC_INFO_COUNT_64;
|
||||
#define mach_vm_region vm_region_64
|
||||
#endif
|
||||
vm_size_t size;
|
||||
vm_address_t vmaddr = reinterpret_cast<vm_address_t>(ptr);
|
||||
mach_vm_region_basic_info_data_t info;
|
||||
memory_object_name_t obj;
|
||||
vm_region_flavor_t flavor = MACH_VM_REGION_BASIC_INFO;
|
||||
mach_msg_type_number_t count = MACH_VM_REGION_BASIC_INFO_COUNT;
|
||||
|
||||
kern_return_t kr = mach_vm_region(mach_task_self(), &vmaddr, &size, flavor,
|
||||
reinterpret_cast<mach_vm_region_info_t>(&info),
|
||||
&count, &obj);
|
||||
|
||||
if (kr != KERN_SUCCESS)
|
||||
return nullptr;
|
||||
|
||||
return reinterpret_cast<void *>(vmaddr);
|
||||
|
||||
#elif defined PLATFORM_LINUX
|
||||
|
||||
uintptr_t addr = reinterpret_cast<uintptr_t>(ptr);
|
||||
|
||||
// Format:
|
||||
// lower upper prot stuff path
|
||||
// 08048000-0804c000 r-xp 00000000 03:03 1010107 /bin/cat
|
||||
FILE *fp = fopen("/proc/self/maps", "r");
|
||||
if (fp) {
|
||||
uintptr_t lower, upper;
|
||||
while (fscanf(fp, "%" PRIxPTR "-%" PRIxPTR, &lower, &upper) != EOF) {
|
||||
if (addr >= lower && addr <= upper) {
|
||||
fclose(fp);
|
||||
return reinterpret_cast<void *>(lower);
|
||||
}
|
||||
|
||||
// Read to end of line
|
||||
int c;
|
||||
while ((c = fgetc(fp)) != '\n') {
|
||||
if (c == EOF)
|
||||
break;
|
||||
}
|
||||
if (c == EOF)
|
||||
break;
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod
|
||||
* Copyright (C) 2004-2017 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* 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 <http://www.sourcemod.net/license.php>.
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE_SOURCEMOD_PSEUDOADDRESSMANAGER_H_
|
||||
#define _INCLUDE_SOURCEMOD_PSEUDOADDRESSMANAGER_H_
|
||||
|
||||
#include "common_logic.h"
|
||||
|
||||
class PseudoAddressManager
|
||||
{
|
||||
public:
|
||||
PseudoAddressManager();
|
||||
public:
|
||||
void *FromPseudoAddress(uint32_t paddr);
|
||||
uint32_t ToPseudoAddress(void *addr);
|
||||
private:
|
||||
void *GetAllocationBase(void *ptr);
|
||||
private:
|
||||
static constexpr uint8_t PSEUDO_OFFSET_BITS = 26;
|
||||
static constexpr uint8_t PSEUDO_INDEX_BITS = sizeof(uint32_t) * 8 - PSEUDO_OFFSET_BITS;
|
||||
void *m_AllocBases[1 << PSEUDO_INDEX_BITS];
|
||||
uint8_t m_NumEntries;
|
||||
};
|
||||
|
||||
#endif // _INCLUDE_SOURCEMOD_PSEUDOADDRESSMANAGER_H_
|
@ -166,7 +166,7 @@ void RootConsoleMenu::DrawGenericOption(const char *cmd, const char *text)
|
||||
{
|
||||
buffer[len++] = ' ';
|
||||
}
|
||||
len += ke::SafeSprintf(&buffer[len], sizeof(buffer) - len, " - %s", text);
|
||||
len += snprintf(&buffer[len], sizeof(buffer) - len, " - %s", text);
|
||||
ConsolePrint("%s", buffer);
|
||||
}
|
||||
}
|
||||
@ -256,7 +256,7 @@ static bool sm_dump_handles(int client, const ICommandArgs *args)
|
||||
auto write_handles_to_game = [] (const char *str) -> void
|
||||
{
|
||||
char buffer[1024];
|
||||
size_t len = ke::SafeStrcpy(buffer, sizeof(buffer)-2, str);
|
||||
size_t len = ke::SafeSprintf(buffer, sizeof(buffer)-2, "%s", str);
|
||||
|
||||
buffer[len] = '\n';
|
||||
buffer[len+1] = '\0';
|
||||
|
@ -162,16 +162,18 @@ bool ShareSystem::RequestInterface(const char *iface_name,
|
||||
SMInterface **pIface)
|
||||
{
|
||||
/* See if the interface exists */
|
||||
List<IfaceInfo>::iterator iter;
|
||||
SMInterface *iface;
|
||||
IExtension *iface_owner = nullptr;
|
||||
IExtension *iface_owner;
|
||||
bool found = false;
|
||||
for (auto iter = m_Interfaces.begin(); iter!=m_Interfaces.end(); iter++)
|
||||
for (iter=m_Interfaces.begin(); iter!=m_Interfaces.end(); iter++)
|
||||
{
|
||||
IfaceInfo &info = *iter;
|
||||
IfaceInfo &info = (*iter);
|
||||
iface = info.iface;
|
||||
if (strcmp(iface->GetInterfaceName(), iface_name) == 0)
|
||||
{
|
||||
if (iface->GetInterfaceVersion() == iface_vers || iface->IsVersionCompatible(iface_vers))
|
||||
if (iface->GetInterfaceVersion() == iface_vers
|
||||
|| iface->IsVersionCompatible(iface_vers))
|
||||
{
|
||||
iface_owner = info.owner;
|
||||
found = true;
|
||||
|
@ -144,7 +144,7 @@ SMCError TextParsers::ParseSMCFile(const char *file,
|
||||
fclose(fp);
|
||||
|
||||
errstr = GetSMCErrorString(result);
|
||||
ke::SafeStrcpy(buffer, maxsize, errstr != NULL ? errstr : "Unknown error");
|
||||
ke::SafeSprintf(buffer, maxsize, "%s", errstr != NULL ? errstr : "Unknown error");
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -195,7 +195,7 @@ SMCError TextParsers::ParseSMCStream(const char *stream,
|
||||
result = ParseStream_SMC(&rs, RawStreamReader, smc_listener, states);
|
||||
|
||||
const char *errstr = GetSMCErrorString(result);
|
||||
ke::SafeStrcpy(buffer, maxsize, errstr != NULL ? errstr : "Unknown error");
|
||||
ke::SafeSprintf(buffer, maxsize, "%s", errstr != NULL ? errstr : "Unknown error");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -940,7 +940,7 @@ bool Translator::AddLanguage(const char *langcode, const char *description)
|
||||
Language *pLanguage = new Language;
|
||||
idx = m_Languages.size();
|
||||
|
||||
ke::SafeStrcpy(pLanguage->m_code2, sizeof(pLanguage->m_code2), langcode);
|
||||
ke::SafeSprintf(pLanguage->m_code2, sizeof(pLanguage->m_code2), "%s", langcode);
|
||||
pLanguage->m_CanonicalName = m_pStringTab->AddString(lower);
|
||||
|
||||
m_LCodeLookup.insert(langcode, idx);
|
||||
|
@ -55,6 +55,7 @@
|
||||
#include "sprintf.h"
|
||||
#include "LibrarySys.h"
|
||||
#include "RootConsoleMenu.h"
|
||||
#include "CDataPack.h"
|
||||
#include "CellArray.h"
|
||||
#include <bridge/include/BridgeAPI.h>
|
||||
#include <bridge/include/IProviderCallbacks.h>
|
||||
@ -85,9 +86,6 @@ IScriptManager *scripts = &g_PluginSys;
|
||||
IExtensionSys *extsys = &g_Extensions;
|
||||
ILogger *logger = &g_Logger;
|
||||
CNativeOwner g_CoreNatives;
|
||||
#ifdef PLATFORM_X64
|
||||
PseudoAddressManager pseudoAddr;
|
||||
#endif
|
||||
|
||||
static void AddCorePhraseFile(const char *filename)
|
||||
{
|
||||
@ -117,24 +115,6 @@ static void RegisterProfiler(IProfilingTool *tool)
|
||||
g_ProfileToolManager.RegisterTool(tool);
|
||||
}
|
||||
|
||||
static void *FromPseudoAddress(uint32_t paddr)
|
||||
{
|
||||
#ifdef PLATFORM_X64
|
||||
return pseudoAddr.FromPseudoAddress(paddr);
|
||||
#else
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
static uint32_t ToPseudoAddress(void *addr)
|
||||
{
|
||||
#ifdef PLATFORM_X64
|
||||
return pseudoAddr.ToPseudoAddress(addr);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Defined in smn_filesystem.cpp.
|
||||
extern bool OnLogPrint(const char *msg);
|
||||
|
||||
@ -166,10 +146,10 @@ static sm_logic_t logic =
|
||||
GenerateError,
|
||||
AddNatives,
|
||||
RegisterProfiler,
|
||||
CDataPack::New,
|
||||
CDataPack::Free,
|
||||
CellArray::New,
|
||||
CellArray::Free,
|
||||
FromPseudoAddress,
|
||||
ToPseudoAddress,
|
||||
&g_PluginSys,
|
||||
&g_ShareSys,
|
||||
&g_Extensions,
|
||||
|
@ -33,9 +33,6 @@
|
||||
#define _INCLUDE_SOURCEMOD_COMMON_LOGIC_H_
|
||||
|
||||
#include "../sm_globals.h"
|
||||
#ifdef PLATFORM_X64
|
||||
#include "PseudoAddrManager.h"
|
||||
#endif
|
||||
|
||||
namespace SourceMod {
|
||||
class CoreProvider;
|
||||
@ -60,7 +57,6 @@ class IVEngineServerBridge;
|
||||
#endif
|
||||
} // namespace SourceMod
|
||||
struct ServerGlobals;
|
||||
class PseudoAddressManager;
|
||||
|
||||
extern SourceMod::CoreProvider *bridge;
|
||||
extern SourceMod::IHandleSys *handlesys;
|
||||
@ -80,7 +76,6 @@ extern SourceMod::IScriptManager *scripts;
|
||||
extern SourceMod::IExtensionSys *extsys;
|
||||
extern SourceMod::ILogger *logger;
|
||||
extern SourceMod::IMenuManager *menus;
|
||||
extern PseudoAddressManager pseudoAddr;
|
||||
|
||||
#if defined SM_LOGIC
|
||||
extern SourceMod::IVEngineServerBridge *engine;
|
||||
|
@ -31,7 +31,6 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "common_logic.h"
|
||||
#include <am-autoptr.h>
|
||||
#include <am-moveable.h>
|
||||
#include <am-refcounting.h>
|
||||
#include <sm_stringhashmap.h>
|
||||
|
@ -708,11 +708,7 @@ enum NumberType
|
||||
|
||||
static cell_t LoadFromAddress(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
#ifdef PLATFORM_X86
|
||||
void *addr = reinterpret_cast<void*>(params[1]);
|
||||
#else
|
||||
void *addr = pseudoAddr.FromPseudoAddress(params[1]);
|
||||
#endif
|
||||
|
||||
if (addr == NULL)
|
||||
{
|
||||
@ -740,11 +736,7 @@ static cell_t LoadFromAddress(IPluginContext *pContext, const cell_t *params)
|
||||
|
||||
static cell_t StoreToAddress(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
#ifdef PLATFORM_X86
|
||||
void *addr = reinterpret_cast<void*>(params[1]);
|
||||
#else
|
||||
void *addr = pseudoAddr.FromPseudoAddress(params[1]);
|
||||
#endif
|
||||
|
||||
if (addr == NULL)
|
||||
{
|
||||
@ -937,26 +929,6 @@ static cell_t FrameIterator_GetFilePath(IPluginContext *pContext, const cell_t *
|
||||
return 0;
|
||||
}
|
||||
|
||||
static cell_t LogStackTrace(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
char buffer[512];
|
||||
g_pSM->FormatString(buffer, sizeof(buffer), pContext, params, 1);
|
||||
|
||||
IFrameIterator *it = pContext->CreateFrameIterator();
|
||||
ke::Vector<ke::AString> arr = g_DbgReporter.GetStackTrace(it);
|
||||
pContext->DestroyFrameIterator(it);
|
||||
|
||||
IPlugin *pPlugin = scripts->FindPluginByContext(pContext->GetContext());
|
||||
|
||||
g_Logger.LogError("[SM] Stack trace requested: %s", buffer);
|
||||
g_Logger.LogError("[SM] Called from: %s", pPlugin->GetFilename());
|
||||
for (size_t i = 0; i < arr.length(); ++i)
|
||||
{
|
||||
g_Logger.LogError("%s", arr[i].chars());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
REGISTER_NATIVES(coreNatives)
|
||||
{
|
||||
{"ThrowError", ThrowError},
|
||||
@ -987,7 +959,6 @@ REGISTER_NATIVES(coreNatives)
|
||||
{"StoreToAddress", StoreToAddress},
|
||||
{"IsNullVector", IsNullVector},
|
||||
{"IsNullString", IsNullString},
|
||||
{"LogStackTrace", LogStackTrace},
|
||||
|
||||
{"FrameIterator.FrameIterator", FrameIterator_Create},
|
||||
{"FrameIterator.Next", FrameIterator_Next},
|
||||
|
@ -314,12 +314,6 @@ public:
|
||||
error[0] = '\0';
|
||||
strncopy(dbname, _dbname, sizeof(dbname));
|
||||
me = scripts->FindPluginByContext(m_pFunction->GetParentContext()->GetContext());
|
||||
|
||||
m_pInfo = g_DBMan.GetDatabaseConf(dbname);
|
||||
if (!m_pInfo)
|
||||
{
|
||||
g_pSM->Format(error, sizeof(error), "Could not find database config \"%s\"", dbname);
|
||||
}
|
||||
}
|
||||
IdentityToken_t *GetOwner()
|
||||
{
|
||||
@ -331,10 +325,15 @@ public:
|
||||
}
|
||||
void RunThreadPart()
|
||||
{
|
||||
if (m_pInfo)
|
||||
g_DBMan.LockConfig();
|
||||
const DatabaseInfo *pInfo = g_DBMan.FindDatabaseConf(dbname);
|
||||
if (!pInfo)
|
||||
{
|
||||
m_pDatabase = m_pDriver->Connect(&m_pInfo->info, false, error, sizeof(error));
|
||||
g_pSM->Format(error, sizeof(error), "Could not find database config \"%s\"", dbname);
|
||||
} else {
|
||||
m_pDatabase = m_pDriver->Connect(pInfo, false, error, sizeof(error));
|
||||
}
|
||||
g_DBMan.UnlockConfig();
|
||||
}
|
||||
void CancelThinkPart()
|
||||
{
|
||||
@ -384,7 +383,6 @@ public:
|
||||
delete this;
|
||||
}
|
||||
private:
|
||||
ke::RefPtr<ConfDbInfo> m_pInfo;
|
||||
IPlugin *me;
|
||||
IPluginFunction *m_pFunction;
|
||||
IDBDriver *m_pDriver;
|
||||
@ -455,7 +453,7 @@ static cell_t ConnectToDbAsync(IPluginContext *pContext, const cell_t *params, A
|
||||
g_pSM->Format(error,
|
||||
sizeof(error),
|
||||
"Could not find driver \"%s\"",
|
||||
pInfo->driver[0] == '\0' ? g_DBMan.GetDefaultDriverName().chars() : pInfo->driver);
|
||||
pInfo->driver[0] == '\0' ? g_DBMan.GetDefaultDriverName() : pInfo->driver);
|
||||
} else if (!driver->IsThreadSafe()) {
|
||||
g_pSM->Format(error,
|
||||
sizeof(error),
|
||||
@ -1425,7 +1423,7 @@ static cell_t SQL_CheckConfig(IPluginContext *pContext, const cell_t *params)
|
||||
char *name;
|
||||
pContext->LocalToString(params[1], &name);
|
||||
|
||||
return (g_DBMan.GetDatabaseConf(name) != nullptr) ? 1 : 0;
|
||||
return (g_DBMan.FindDatabaseConf(name) != NULL) ? 1 : 0;
|
||||
}
|
||||
|
||||
static cell_t SQL_ConnectCustom(IPluginContext *pContext, const cell_t *params)
|
||||
|
@ -61,7 +61,7 @@ public:
|
||||
}
|
||||
void OnHandleDestroy(HandleType_t type, void *object)
|
||||
{
|
||||
CDataPack::Free(reinterpret_cast<CDataPack *>(object));
|
||||
CDataPack::Free(reinterpret_cast<IDataPack *>(object));
|
||||
}
|
||||
bool GetHandleApproxSize(HandleType_t type, void *object, unsigned int *pSize)
|
||||
{
|
||||
@ -73,7 +73,7 @@ public:
|
||||
|
||||
static cell_t smn_CreateDataPack(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
CDataPack *pDataPack = CDataPack::New();
|
||||
IDataPack *pDataPack = CDataPack::New();
|
||||
|
||||
if (!pDataPack)
|
||||
{
|
||||
@ -88,7 +88,7 @@ static cell_t smn_WritePackCell(IPluginContext *pContext, const cell_t *params)
|
||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||
HandleError herr;
|
||||
HandleSecurity sec;
|
||||
CDataPack *pDataPack;
|
||||
IDataPack *pDataPack;
|
||||
|
||||
sec.pOwner = pContext->GetIdentity();
|
||||
sec.pIdentity = g_pCoreIdent;
|
||||
@ -96,13 +96,7 @@ static cell_t smn_WritePackCell(IPluginContext *pContext, const cell_t *params)
|
||||
if ((herr=handlesys->ReadHandle(hndl, g_DataPackType, &sec, (void **)&pDataPack))
|
||||
!= HandleError_None)
|
||||
{
|
||||
return pContext->ThrowNativeError("Invalid data pack handle %x (error %d).", hndl, herr);
|
||||
}
|
||||
|
||||
bool insert = (params[0] >= 3) ? params[3] : false;
|
||||
if (!insert)
|
||||
{
|
||||
pDataPack->RemoveItem();
|
||||
return pContext->ThrowNativeError("Invalid data pack handle %x (error %d)", hndl, herr);
|
||||
}
|
||||
|
||||
pDataPack->PackCell(params[2]);
|
||||
@ -115,7 +109,7 @@ static cell_t smn_WritePackFloat(IPluginContext *pContext, const cell_t *params)
|
||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||
HandleError herr;
|
||||
HandleSecurity sec;
|
||||
CDataPack *pDataPack;
|
||||
IDataPack *pDataPack;
|
||||
|
||||
sec.pOwner = pContext->GetIdentity();
|
||||
sec.pIdentity = g_pCoreIdent;
|
||||
@ -123,13 +117,7 @@ static cell_t smn_WritePackFloat(IPluginContext *pContext, const cell_t *params)
|
||||
if ((herr=handlesys->ReadHandle(hndl, g_DataPackType, &sec, (void **)&pDataPack))
|
||||
!= HandleError_None)
|
||||
{
|
||||
return pContext->ThrowNativeError("Invalid data pack handle %x (error %d).", hndl, herr);
|
||||
}
|
||||
|
||||
bool insert = (params[0] >= 3) ? params[3] : false;
|
||||
if (!insert)
|
||||
{
|
||||
pDataPack->RemoveItem();
|
||||
return pContext->ThrowNativeError("Invalid data pack handle %x (error %d)", hndl, herr);
|
||||
}
|
||||
|
||||
pDataPack->PackFloat(sp_ctof(params[2]));
|
||||
@ -142,7 +130,7 @@ static cell_t smn_WritePackString(IPluginContext *pContext, const cell_t *params
|
||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||
HandleError herr;
|
||||
HandleSecurity sec;
|
||||
CDataPack *pDataPack;
|
||||
IDataPack *pDataPack;
|
||||
|
||||
sec.pOwner = pContext->GetIdentity();
|
||||
sec.pIdentity = g_pCoreIdent;
|
||||
@ -150,13 +138,7 @@ static cell_t smn_WritePackString(IPluginContext *pContext, const cell_t *params
|
||||
if ((herr=handlesys->ReadHandle(hndl, g_DataPackType, &sec, (void **)&pDataPack))
|
||||
!= HandleError_None)
|
||||
{
|
||||
return pContext->ThrowNativeError("Invalid data pack handle %x (error %d).", hndl, herr);
|
||||
}
|
||||
|
||||
bool insert = (params[0] >= 3) ? params[3] : false;
|
||||
if (!insert)
|
||||
{
|
||||
pDataPack->RemoveItem();
|
||||
return pContext->ThrowNativeError("Invalid data pack handle %x (error %d)", hndl, herr);
|
||||
}
|
||||
|
||||
char *str;
|
||||
@ -171,7 +153,7 @@ static cell_t smn_WritePackFunction(IPluginContext *pContext, const cell_t *para
|
||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||
HandleError herr;
|
||||
HandleSecurity sec;
|
||||
CDataPack *pDataPack;
|
||||
IDataPack *pDataPack;
|
||||
|
||||
sec.pOwner = pContext->GetIdentity();
|
||||
sec.pIdentity = g_pCoreIdent;
|
||||
@ -179,13 +161,7 @@ static cell_t smn_WritePackFunction(IPluginContext *pContext, const cell_t *para
|
||||
if ((herr = handlesys->ReadHandle(hndl, g_DataPackType, &sec, (void **)&pDataPack))
|
||||
!= HandleError_None)
|
||||
{
|
||||
return pContext->ThrowNativeError("Invalid data pack handle %x (error %d).", hndl, herr);
|
||||
}
|
||||
|
||||
bool insert = (params[0] >= 3) ? params[3] : false;
|
||||
if (!insert)
|
||||
{
|
||||
pDataPack->RemoveItem();
|
||||
return pContext->ThrowNativeError("Invalid data pack handle %x (error %d)", hndl, herr);
|
||||
}
|
||||
|
||||
pDataPack->PackFunction(params[2]);
|
||||
@ -198,7 +174,7 @@ static cell_t smn_ReadPackCell(IPluginContext *pContext, const cell_t *params)
|
||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||
HandleError herr;
|
||||
HandleSecurity sec;
|
||||
CDataPack *pDataPack;
|
||||
IDataPack *pDataPack;
|
||||
|
||||
sec.pOwner = pContext->GetIdentity();
|
||||
sec.pIdentity = g_pCoreIdent;
|
||||
@ -206,17 +182,12 @@ static cell_t smn_ReadPackCell(IPluginContext *pContext, const cell_t *params)
|
||||
if ((herr=handlesys->ReadHandle(hndl, g_DataPackType, &sec, (void **)&pDataPack))
|
||||
!= HandleError_None)
|
||||
{
|
||||
return pContext->ThrowNativeError("Invalid data pack handle %x (error %d).", hndl, herr);
|
||||
return pContext->ThrowNativeError("Invalid data pack handle %x (error %d)", hndl, herr);
|
||||
}
|
||||
|
||||
if (!pDataPack->IsReadable())
|
||||
if (!pDataPack->IsReadable(sizeof(char) + sizeof(size_t) + sizeof(cell_t)))
|
||||
{
|
||||
return pContext->ThrowNativeError("Data pack operation is out of bounds.");
|
||||
}
|
||||
|
||||
if (pDataPack->GetCurrentType() != CDataPackType::Cell)
|
||||
{
|
||||
return pContext->ThrowNativeError("Invalid data pack type (got %d / expected %d).", pDataPack->GetCurrentType(), CDataPackType::Cell);
|
||||
return pContext->ThrowNativeError("DataPack operation is out of bounds.");
|
||||
}
|
||||
|
||||
return pDataPack->ReadCell();
|
||||
@ -227,7 +198,7 @@ static cell_t smn_ReadPackFloat(IPluginContext *pContext, const cell_t *params)
|
||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||
HandleError herr;
|
||||
HandleSecurity sec;
|
||||
CDataPack *pDataPack;
|
||||
IDataPack *pDataPack;
|
||||
|
||||
sec.pOwner = pContext->GetIdentity();
|
||||
sec.pIdentity = g_pCoreIdent;
|
||||
@ -235,17 +206,12 @@ static cell_t smn_ReadPackFloat(IPluginContext *pContext, const cell_t *params)
|
||||
if ((herr=handlesys->ReadHandle(hndl, g_DataPackType, &sec, (void **)&pDataPack))
|
||||
!= HandleError_None)
|
||||
{
|
||||
return pContext->ThrowNativeError("Invalid data pack handle %x (error %d).", hndl, herr);
|
||||
return pContext->ThrowNativeError("Invalid data pack handle %x (error %d)", hndl, herr);
|
||||
}
|
||||
|
||||
if (!pDataPack->IsReadable())
|
||||
if (!pDataPack->IsReadable(sizeof(char) + sizeof(size_t) + sizeof(float)))
|
||||
{
|
||||
return pContext->ThrowNativeError("Data pack operation is out of bounds.");
|
||||
}
|
||||
|
||||
if (pDataPack->GetCurrentType() != CDataPackType::Float)
|
||||
{
|
||||
return pContext->ThrowNativeError("Invalid data pack type (got %d / expected %d).", pDataPack->GetCurrentType(), CDataPackType::Float);
|
||||
return pContext->ThrowNativeError("DataPack operation is out of bounds.");
|
||||
}
|
||||
|
||||
return sp_ftoc(pDataPack->ReadFloat());
|
||||
@ -256,7 +222,7 @@ static cell_t smn_ReadPackString(IPluginContext *pContext, const cell_t *params)
|
||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||
HandleError herr;
|
||||
HandleSecurity sec;
|
||||
CDataPack *pDataPack;
|
||||
IDataPack *pDataPack;
|
||||
|
||||
sec.pOwner = pContext->GetIdentity();
|
||||
sec.pIdentity = g_pCoreIdent;
|
||||
@ -264,20 +230,15 @@ static cell_t smn_ReadPackString(IPluginContext *pContext, const cell_t *params)
|
||||
if ((herr=handlesys->ReadHandle(hndl, g_DataPackType, &sec, (void **)&pDataPack))
|
||||
!= HandleError_None)
|
||||
{
|
||||
return pContext->ThrowNativeError("Invalid data pack handle %x (error %d).", hndl, herr);
|
||||
return pContext->ThrowNativeError("Invalid data pack handle %x (error %d)", hndl, herr);
|
||||
}
|
||||
|
||||
if (!pDataPack->IsReadable())
|
||||
const char *str;
|
||||
if (!(str=pDataPack->ReadString(NULL)))
|
||||
{
|
||||
return pContext->ThrowNativeError("Data pack operation is out of bounds.");
|
||||
return pContext->ThrowNativeError("DataPack operation is out of bounds.");
|
||||
}
|
||||
|
||||
if (pDataPack->GetCurrentType() != CDataPackType::String)
|
||||
{
|
||||
return pContext->ThrowNativeError("Invalid data pack type (got %d / expected %d).", pDataPack->GetCurrentType(), CDataPackType::String);
|
||||
}
|
||||
|
||||
const char *str = pDataPack->ReadString(NULL);
|
||||
pContext->StringToLocal(params[2], params[3], str);
|
||||
|
||||
return 1;
|
||||
@ -288,7 +249,7 @@ static cell_t smn_ReadPackFunction(IPluginContext *pContext, const cell_t *param
|
||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||
HandleError herr;
|
||||
HandleSecurity sec;
|
||||
CDataPack *pDataPack;
|
||||
IDataPack *pDataPack;
|
||||
|
||||
sec.pOwner = pContext->GetIdentity();
|
||||
sec.pIdentity = g_pCoreIdent;
|
||||
@ -296,17 +257,12 @@ static cell_t smn_ReadPackFunction(IPluginContext *pContext, const cell_t *param
|
||||
if ((herr = handlesys->ReadHandle(hndl, g_DataPackType, &sec, (void **)&pDataPack))
|
||||
!= HandleError_None)
|
||||
{
|
||||
return pContext->ThrowNativeError("Invalid data pack handle %x (error %d).", hndl, herr);
|
||||
return pContext->ThrowNativeError("Invalid data pack handle %x (error %d)", hndl, herr);
|
||||
}
|
||||
|
||||
if (!pDataPack->IsReadable())
|
||||
if (!pDataPack->IsReadable(sizeof(char) + sizeof(size_t) + sizeof(cell_t)))
|
||||
{
|
||||
return pContext->ThrowNativeError("Data pack operation is out of bounds.");
|
||||
}
|
||||
|
||||
if (pDataPack->GetCurrentType() != CDataPackType::Function)
|
||||
{
|
||||
return pContext->ThrowNativeError("Invalid data pack type (got %d / expected %d).", pDataPack->GetCurrentType(), CDataPackType::Function);
|
||||
return pContext->ThrowNativeError("DataPack operation is out of bounds.");
|
||||
}
|
||||
|
||||
return pDataPack->ReadFunction();
|
||||
@ -317,7 +273,7 @@ static cell_t smn_ResetPack(IPluginContext *pContext, const cell_t *params)
|
||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||
HandleError herr;
|
||||
HandleSecurity sec;
|
||||
CDataPack *pDataPack;
|
||||
IDataPack *pDataPack;
|
||||
|
||||
sec.pOwner = pContext->GetIdentity();
|
||||
sec.pIdentity = g_pCoreIdent;
|
||||
@ -325,17 +281,14 @@ static cell_t smn_ResetPack(IPluginContext *pContext, const cell_t *params)
|
||||
if ((herr=handlesys->ReadHandle(hndl, g_DataPackType, &sec, (void **)&pDataPack))
|
||||
!= HandleError_None)
|
||||
{
|
||||
return pContext->ThrowNativeError("Invalid data pack handle %x (error %d).", hndl, herr);
|
||||
return pContext->ThrowNativeError("Invalid data pack handle %x (error %d)", hndl, herr);
|
||||
}
|
||||
|
||||
pDataPack->Reset();
|
||||
if (params[2])
|
||||
{
|
||||
pDataPack->ResetSize();
|
||||
}
|
||||
else
|
||||
{
|
||||
pDataPack->Reset();
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -345,7 +298,7 @@ static cell_t smn_GetPackPosition(IPluginContext *pContext, const cell_t *params
|
||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||
HandleError herr;
|
||||
HandleSecurity sec;
|
||||
CDataPack *pDataPack;
|
||||
IDataPack *pDataPack;
|
||||
|
||||
sec.pOwner = pContext->GetIdentity();
|
||||
sec.pIdentity = g_pCoreIdent;
|
||||
@ -353,7 +306,7 @@ static cell_t smn_GetPackPosition(IPluginContext *pContext, const cell_t *params
|
||||
if ((herr=handlesys->ReadHandle(hndl, g_DataPackType, &sec, (void **)&pDataPack))
|
||||
!= HandleError_None)
|
||||
{
|
||||
return pContext->ThrowNativeError("Invalid data pack handle %x (error %d).", hndl, herr);
|
||||
return pContext->ThrowNativeError("Invalid data pack handle %x (error %d)", hndl, herr);
|
||||
}
|
||||
|
||||
return static_cast<cell_t>(pDataPack->GetPosition());
|
||||
@ -364,7 +317,7 @@ static cell_t smn_SetPackPosition(IPluginContext *pContext, const cell_t *params
|
||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||
HandleError herr;
|
||||
HandleSecurity sec;
|
||||
CDataPack *pDataPack;
|
||||
IDataPack *pDataPack;
|
||||
|
||||
sec.pOwner = pContext->GetIdentity();
|
||||
sec.pIdentity = g_pCoreIdent;
|
||||
@ -372,12 +325,12 @@ static cell_t smn_SetPackPosition(IPluginContext *pContext, const cell_t *params
|
||||
if ((herr=handlesys->ReadHandle(hndl, g_DataPackType, &sec, (void **)&pDataPack))
|
||||
!= HandleError_None)
|
||||
{
|
||||
return pContext->ThrowNativeError("Invalid data pack handle %x (error %d).", hndl, herr);
|
||||
return pContext->ThrowNativeError("Invalid data pack handle %x (error %d)", hndl, herr);
|
||||
}
|
||||
|
||||
if (!pDataPack->SetPosition(params[2]))
|
||||
{
|
||||
return pContext->ThrowNativeError("Invalid data pack position, %d is out of bounds (%d)", params[2], pDataPack->GetCapacity());
|
||||
return pContext->ThrowNativeError("Invalid DataPack position, %d is out of bounds", params[2]);
|
||||
}
|
||||
|
||||
return 1;
|
||||
@ -388,7 +341,7 @@ static cell_t smn_IsPackReadable(IPluginContext *pContext, const cell_t *params)
|
||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||
HandleError herr;
|
||||
HandleSecurity sec;
|
||||
CDataPack *pDataPack;
|
||||
IDataPack *pDataPack;
|
||||
|
||||
sec.pOwner = pContext->GetIdentity();
|
||||
sec.pIdentity = g_pCoreIdent;
|
||||
@ -396,7 +349,7 @@ static cell_t smn_IsPackReadable(IPluginContext *pContext, const cell_t *params)
|
||||
if ((herr=handlesys->ReadHandle(hndl, g_DataPackType, &sec, (void **)&pDataPack))
|
||||
!= HandleError_None)
|
||||
{
|
||||
return pContext->ThrowNativeError("Invalid data pack handle %x (error %d).", hndl, herr);
|
||||
return pContext->ThrowNativeError("Invalid data pack handle %x (error %d)", hndl, herr);
|
||||
}
|
||||
|
||||
return pDataPack->IsReadable(params[2]) ? 1 : 0;
|
||||
|
@ -113,14 +113,14 @@ static cell_t CreateNative(IPluginContext *pContext, const cell_t *params)
|
||||
IPluginFunction *pFunction = pContext->GetFunctionById(params[2]);
|
||||
if (!pFunction)
|
||||
{
|
||||
return pContext->ThrowNativeError("Failed to create native \"%s\", function %x is not a valid function", name, params[2]);
|
||||
return pContext->ThrowNativeError("Function %x is not a valid function", params[2]);
|
||||
}
|
||||
|
||||
pPlugin = g_PluginSys.GetPluginByCtx(pContext->GetContext());
|
||||
|
||||
if (!pPlugin->AddFakeNative(pFunction, name, FakeNativeRouter))
|
||||
{
|
||||
return pContext->ThrowNativeError("Failed to create native \"%s\", name is probably already in use", name);
|
||||
return pContext->ThrowNativeError("Fatal error creating dynamic native!");
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
@ -321,7 +321,7 @@ static cell_t sm_OpenDirectory(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
size_t len = strlen(path);
|
||||
char wildcardedPath[PLATFORM_MAX_PATH];
|
||||
ke::SafeSprintf(wildcardedPath, sizeof(wildcardedPath), "%s%s*", path, (path[len-1] != '/' && path[len-1] != '\\') ? "/" : "");
|
||||
snprintf(wildcardedPath, sizeof(wildcardedPath), "%s%s*", path, (path[len-1] != '/' && path[len-1] != '\\') ? "/" : "");
|
||||
|
||||
char *pathID;
|
||||
if ((err=pContext->LocalToStringNULL(params[3], &pathID)) != SP_ERROR_NONE)
|
||||
@ -1195,7 +1195,6 @@ REGISTER_NATIVES(filesystem)
|
||||
{"File.WriteLine", sm_WriteFileLine},
|
||||
{"File.EndOfFile", sm_IsEndOfFile},
|
||||
{"File.Seek", sm_FileSeek},
|
||||
{"File.Flush", sm_FlushFile},
|
||||
{"File.Position.get", sm_FilePosition},
|
||||
{"File.ReadInt8", File_ReadTyped<int8_t>},
|
||||
{"File.ReadUint8", File_ReadTyped<uint8_t>},
|
||||
|
@ -817,14 +817,5 @@ REGISTER_NATIVES(functionNatives)
|
||||
{"Call_FinishEx", sm_CallFinishEx},
|
||||
{"Call_Cancel", sm_CallCancel},
|
||||
{"RequestFrame", sm_AddFrameAction},
|
||||
|
||||
{"GlobalForward.GlobalForward", sm_CreateGlobalForward},
|
||||
{"GlobalForward.FunctionCount.get", sm_GetForwardFunctionCount},
|
||||
|
||||
{"PrivateForward.PrivateForward", sm_CreateForward},
|
||||
{"PrivateForward.AddFunction", sm_AddToForward},
|
||||
{"PrivateForward.RemoveFunction", sm_RemoveFromForward},
|
||||
{"PrivateForward.RemoveAllFunctions", sm_RemoveAllFromForward},
|
||||
|
||||
{NULL, NULL},
|
||||
};
|
||||
|
@ -67,10 +67,7 @@ static cell_t smn_LoadGameConfigFile(IPluginContext *pCtx, const cell_t *params)
|
||||
return pCtx->ThrowNativeError("Unable to open %s: %s", filename, error);
|
||||
}
|
||||
|
||||
Handle_t hndl = handlesys->CreateHandle(g_GameConfigsType, gc, pCtx->GetIdentity(), g_pCoreIdent, NULL);
|
||||
if (hndl == BAD_HANDLE)
|
||||
g_GameConfigs.CloseGameConfigFile(gc);
|
||||
return hndl;
|
||||
return handlesys->CreateHandle(g_GameConfigsType, gc, pCtx->GetIdentity(), g_pCoreIdent, NULL);
|
||||
}
|
||||
|
||||
static cell_t smn_GameConfGetOffset(IPluginContext *pCtx, const cell_t *params)
|
||||
@ -155,11 +152,7 @@ static cell_t smn_GameConfGetAddress(IPluginContext *pCtx, const cell_t *params)
|
||||
if (!gc->GetAddress(key, &val))
|
||||
return 0;
|
||||
|
||||
#ifdef PLATFORM_X86
|
||||
return (cell_t)val;
|
||||
#else
|
||||
return pseudoAddr.ToPseudoAddress(val);
|
||||
#endif
|
||||
}
|
||||
|
||||
static GameConfigsNatives s_GameConfigsNatives;
|
||||
@ -170,11 +163,5 @@ REGISTER_NATIVES(gameconfignatives)
|
||||
{"GameConfGetOffset", smn_GameConfGetOffset},
|
||||
{"GameConfGetKeyValue", smn_GameConfGetKeyValue},
|
||||
{"GameConfGetAddress", smn_GameConfGetAddress},
|
||||
|
||||
// Transitional syntax support.
|
||||
{"GameData.GameData", smn_LoadGameConfigFile},
|
||||
{"GameData.GetOffset", smn_GameConfGetOffset},
|
||||
{"GameData.GetKeyValue", smn_GameConfGetKeyValue},
|
||||
{"GameData.GetAddress", smn_GameConfGetAddress},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
@ -68,7 +68,7 @@ static cell_t sm_LoadTranslations(IPluginContext *pCtx, const cell_t *params)
|
||||
IPlugin *pl = pluginsys->FindPluginByContext(pCtx->GetContext());
|
||||
|
||||
pCtx->LocalToString(params[1], &filename);
|
||||
ke::SafeStrcpy(buffer, sizeof(buffer), filename);
|
||||
ke::SafeSprintf(buffer, sizeof(buffer), "%s", filename);
|
||||
|
||||
/* Make sure there is no extension */
|
||||
if ((ext = strstr(buffer, ".txt")) != NULL
|
||||
|
@ -321,109 +321,9 @@ public:
|
||||
delete m_pCurMapList;
|
||||
m_pCurMapList = NULL;
|
||||
}
|
||||
static bool alphanum_isdigit(const char c)
|
||||
{
|
||||
return c >= '0' && c <= '9';
|
||||
}
|
||||
static int alphanum_impl(const char *l, const char *r)
|
||||
{
|
||||
/**
|
||||
* http://www.davekoelle.com/files/alphanum.hpp
|
||||
*
|
||||
* compare l and r with strcmp() semantics, but using
|
||||
* the "Alphanum Algorithm". This function is designed to read
|
||||
* through the l and r strings only one time, for
|
||||
* maximum performance. It does not allocate memory for
|
||||
* substrings.
|
||||
*
|
||||
* Released under the MIT License - https://opensource.org/licenses/MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
* USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
enum mode_t { STRING, NUMBER } mode = STRING;
|
||||
|
||||
while (*l && *r)
|
||||
{
|
||||
if (mode == STRING)
|
||||
{
|
||||
char l_char, r_char;
|
||||
while ((l_char = *l) && (r_char = *r))
|
||||
{
|
||||
// check if this are digit characters
|
||||
const bool l_digit = alphanum_isdigit(l_char), r_digit = alphanum_isdigit(r_char);
|
||||
// if both characters are digits, we continue in NUMBER mode
|
||||
if (l_digit && r_digit)
|
||||
{
|
||||
mode = NUMBER;
|
||||
break;
|
||||
}
|
||||
// if only the left character is a digit, we have a result
|
||||
if (l_digit) return -1;
|
||||
// if only the right character is a digit, we have a result
|
||||
if (r_digit) return +1;
|
||||
// compute the difference of both characters
|
||||
const int diff = l_char - r_char;
|
||||
// if they differ we have a result
|
||||
if (diff != 0) return diff;
|
||||
// otherwise process the next characters
|
||||
++l;
|
||||
++r;
|
||||
}
|
||||
}
|
||||
else // mode == NUMBER
|
||||
{
|
||||
// get the left number
|
||||
unsigned long l_int = 0;
|
||||
while (*l && alphanum_isdigit(*l))
|
||||
{
|
||||
// TODO: this can overflow
|
||||
l_int = l_int * 10 + *l - '0';
|
||||
++l;
|
||||
}
|
||||
|
||||
// get the right number
|
||||
unsigned long r_int = 0;
|
||||
while (*r && alphanum_isdigit(*r))
|
||||
{
|
||||
// TODO: this can overflow
|
||||
r_int = r_int * 10 + *r - '0';
|
||||
++r;
|
||||
}
|
||||
|
||||
// if the difference is not equal to zero, we have a comparison result
|
||||
const long diff = l_int - r_int;
|
||||
if (diff != 0)
|
||||
return diff;
|
||||
|
||||
// otherwise we process the next substring in STRING mode
|
||||
mode = STRING;
|
||||
}
|
||||
}
|
||||
|
||||
if (*r) return -1;
|
||||
if (*l) return +1;
|
||||
return 0;
|
||||
}
|
||||
static int sort_maps_in_adt_array(const void *str1, const void *str2)
|
||||
{
|
||||
return alphanum_impl(static_cast<const char *>(str1), static_cast<const char *>(str2));
|
||||
return strcmp((char *)str1, (char *)str2);
|
||||
}
|
||||
ICellArray *UpdateMapList(ICellArray *pUseArray, const char *name, int *pSerial, unsigned int flags)
|
||||
{
|
||||
@ -441,7 +341,7 @@ public:
|
||||
*/
|
||||
if (strcmp(name, "default") != 0)
|
||||
{
|
||||
success = GetMapList(&pNewArray, "default", &change_serial);
|
||||
success = GetMapList(&pNewArray, name, &change_serial);
|
||||
}
|
||||
/* If either of the last two conditions failed, try again if we can. */
|
||||
if (!success && strcmp(name, "mapcyclefile") != 0)
|
||||
|
@ -64,13 +64,10 @@ static const int kActivityAdmins = 4; // Show admin activity to admins anonymo
|
||||
static const int kActivityAdminsNames = 8; // If 4 is specified, admin names will be shown.
|
||||
static const int kActivityRootNames = 16; // Always show admin names to root users.
|
||||
|
||||
#define FEATURECAP_MULTITARGETFILTER_CLIENTPARAM "SourceMod MultiTargetFilter ClientParam"
|
||||
|
||||
class PlayerLogicHelpers :
|
||||
public SMGlobalClass,
|
||||
public IPluginsListener,
|
||||
public ICommandTargetProcessor,
|
||||
public IFeatureProvider
|
||||
public ICommandTargetProcessor
|
||||
{
|
||||
struct SimpleMultiTargetFilter
|
||||
{
|
||||
@ -189,7 +186,6 @@ public: //SMGlobalClass
|
||||
void OnSourceModAllInitialized()
|
||||
{
|
||||
pluginsys->AddPluginsListener(this);
|
||||
sharesys->AddCapabilityProvider(NULL, this, FEATURECAP_MULTITARGETFILTER_CLIENTPARAM);
|
||||
}
|
||||
|
||||
void OnSourceModShutdown()
|
||||
@ -199,7 +195,6 @@ public: //SMGlobalClass
|
||||
playerhelpers->UnregisterCommandTargetProcessor(this);
|
||||
filterEnabled = false;
|
||||
}
|
||||
sharesys->DropCapabilityProvider(NULL, this, FEATURECAP_MULTITARGETFILTER_CLIENTPARAM);
|
||||
}
|
||||
|
||||
public: //IPluginsListener
|
||||
@ -217,13 +212,6 @@ public: //IPluginsListener
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public: //IFeatureProvider
|
||||
|
||||
FeatureStatus GetFeatureStatus(FeatureType type, const char *name)
|
||||
{
|
||||
return FeatureStatus_Available;
|
||||
}
|
||||
} s_PlayerLogicHelpers;
|
||||
|
||||
static cell_t
|
||||
@ -270,7 +258,18 @@ static cell_t sm_GetClientCount(IPluginContext *pCtx, const cell_t *params)
|
||||
return playerhelpers->GetNumPlayers();
|
||||
}
|
||||
|
||||
return playerhelpers->GetNumClients();
|
||||
int maxplayers = playerhelpers->GetMaxClients();
|
||||
int count = 0;
|
||||
for (int i = 1; i <= maxplayers; ++i)
|
||||
{
|
||||
IGamePlayer *pPlayer = playerhelpers->GetGamePlayer(i);
|
||||
if ((pPlayer->IsConnected()) && !(pPlayer->IsInGame()))
|
||||
{
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
return (playerhelpers->GetNumPlayers() + count);
|
||||
}
|
||||
|
||||
static cell_t sm_GetMaxClients(IPluginContext *pCtx, const cell_t *params)
|
||||
@ -399,7 +398,7 @@ static cell_t SteamIdToLocal(IPluginContext *pCtx, int index, AuthIdType authTyp
|
||||
}
|
||||
|
||||
char szAuth[64];
|
||||
ke::SafeSprintf(szAuth, sizeof(szAuth), "%" PRIu64, steamId);
|
||||
snprintf(szAuth, sizeof(szAuth), "%" PRIu64, steamId);
|
||||
|
||||
pCtx->StringToLocal(local_addr, bytes, szAuth);
|
||||
}
|
||||
@ -1125,6 +1124,7 @@ static cell_t _ShowActivity(IPluginContext *pContext,
|
||||
{
|
||||
IGamePlayer *pPlayer = playerhelpers->GetGamePlayer(i);
|
||||
if (!pPlayer->IsInGame()
|
||||
|| pPlayer->IsFakeClient()
|
||||
|| (display_in_chat && i == client))
|
||||
{
|
||||
continue;
|
||||
@ -1251,6 +1251,7 @@ static cell_t _ShowActivity2(IPluginContext *pContext,
|
||||
{
|
||||
IGamePlayer *pPlayer = playerhelpers->GetGamePlayer(i);
|
||||
if (!pPlayer->IsInGame()
|
||||
|| pPlayer->IsFakeClient()
|
||||
|| i == client)
|
||||
{
|
||||
continue;
|
||||
|
@ -223,11 +223,6 @@ REGISTER_NATIVES(profilerNatives)
|
||||
{"EnterProfilingEvent", EnterProfilingEvent},
|
||||
{"LeaveProfilingEvent", LeaveProfilingEvent},
|
||||
{"IsProfilingActive", IsProfilingActive},
|
||||
|
||||
{"Profiler.Profiler", CreateProfiler},
|
||||
{"Profiler.Time.get", GetProfilerTime},
|
||||
{"Profiler.Start", StartProfiling},
|
||||
{"Profiler.Stop", StopProfiling},
|
||||
{NULL, NULL},
|
||||
};
|
||||
|
||||
|
@ -591,9 +591,5 @@ REGISTER_NATIVES(sortNatives)
|
||||
{"SortCustom2D", sm_SortCustom2D},
|
||||
{"SortADTArray", sm_SortADTArray},
|
||||
{"SortADTArrayCustom", sm_SortADTArrayCustom},
|
||||
|
||||
{"ArrayList.Sort", sm_SortADTArray},
|
||||
{"ArrayList.SortCustom", sm_SortADTArrayCustom},
|
||||
|
||||
{NULL, NULL},
|
||||
};
|
||||
|
@ -1171,12 +1171,18 @@ reswitch:
|
||||
int userid;
|
||||
if (!bridge->DescribePlayer(*value, &name, &auth, &userid))
|
||||
return pCtx->ThrowNativeError("Client index %d is invalid (arg %d)", *value, arg);
|
||||
|
||||
ke::SafeSprintf(buffer, sizeof(buffer), "%s<%d><%s><>", name, userid, auth);
|
||||
ke::SafeSprintf(buffer,
|
||||
sizeof(buffer),
|
||||
"%s<%d><%s><>",
|
||||
name,
|
||||
userid,
|
||||
auth);
|
||||
}
|
||||
else
|
||||
{
|
||||
ke::SafeStrcpy(buffer, sizeof(buffer), "Console<0><Console><Console>");
|
||||
ke::SafeSprintf(buffer,
|
||||
sizeof(buffer),
|
||||
"Console<0><Console><Console>");
|
||||
}
|
||||
if (!AddString(&buf_p, llen, buffer, width, prec, flags))
|
||||
return pCtx->ThrowNativeError("Escaped string would be truncated (arg %d)", arg);
|
||||
|
@ -381,11 +381,7 @@ public:
|
||||
{
|
||||
if (len > max_size)
|
||||
{
|
||||
auto *newbuffer = static_cast<char *>(realloc(buffer, len));
|
||||
if (!newbuffer)
|
||||
return nullptr;
|
||||
|
||||
buffer = newbuffer;
|
||||
buffer = (char *)realloc(buffer, len);
|
||||
max_size = len;
|
||||
}
|
||||
return buffer;
|
||||
@ -424,11 +420,7 @@ cell_t InternalFormat(IPluginContext *pCtx, const cell_t *params, int start)
|
||||
{
|
||||
if (maxlen > sizeof(g_formatbuf))
|
||||
{
|
||||
char *tmpbuff = g_extrabuf.GetWithSize(maxlen);
|
||||
if (!tmpbuff)
|
||||
return pCtx->ThrowNativeError("Unable to allocate buffer with a size of \"%u\"", maxlen);
|
||||
|
||||
__copy_buf = tmpbuff;
|
||||
__copy_buf = g_extrabuf.GetWithSize(maxlen);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -52,6 +52,8 @@
|
||||
#include <bridge/include/IPlayerInfoBridge.h>
|
||||
#include <bridge/include/IFileSystemBridge.h>
|
||||
|
||||
#define MATCHMAKINGDS_NAME "matchmaking_ds" SOURCE_BIN_SUFFIX SOURCE_BIN_EXT
|
||||
|
||||
sm_logic_t logicore;
|
||||
|
||||
IThreader *g_pThreader = nullptr;
|
||||
@ -627,7 +629,13 @@ void CoreProviderImpl::InitializeBridge()
|
||||
this->serverFactory = (void *)g_SMAPI->GetServerFactory(false);
|
||||
this->listeners = SMGlobalClass::head;
|
||||
|
||||
if (ke::RefPtr<ke::SharedLib> mmlib = ke::SharedLib::Open(FORMAT_SOURCE_BIN_NAME("matchmaking_ds"), NULL, 0)) {
|
||||
char path[PLATFORM_MAX_PATH];
|
||||
|
||||
ke::path::Format(path, sizeof(path),
|
||||
"%s/bin/" MATCHMAKINGDS_NAME,
|
||||
g_SMAPI->GetBaseDir());
|
||||
|
||||
if (ke::RefPtr<ke::SharedLib> mmlib = ke::SharedLib::Open(path, NULL, 0)) {
|
||||
this->matchmakingDSFactory =
|
||||
mmlib->get<decltype(sCoreProviderImpl.matchmakingDSFactory)>("CreateInterface");
|
||||
}
|
||||
@ -660,7 +668,7 @@ bool CoreProviderImpl::LoadBridge(char *error, size_t maxlength)
|
||||
/* Now it's time to load the logic binary */
|
||||
g_SMAPI->PathFormat(file,
|
||||
sizeof(file),
|
||||
"%s/bin/" PLATFORM_ARCH_FOLDER "sourcemod.logic." PLATFORM_LIB_EXT,
|
||||
"%s/bin/sourcemod.logic." PLATFORM_LIB_EXT,
|
||||
g_SourceMod.GetSourceModPath());
|
||||
|
||||
char myerror[255];
|
||||
@ -673,7 +681,7 @@ bool CoreProviderImpl::LoadBridge(char *error, size_t maxlength)
|
||||
LogicLoadFunction llf = logic_->get<decltype(llf)>("logic_load");
|
||||
if (!llf) {
|
||||
logic_ = nullptr;
|
||||
ke::SafeStrcpy(error, maxlength, "could not find logic_load function");
|
||||
ke::SafeSprintf(error, maxlength, "could not find logic_load function");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -682,7 +690,7 @@ bool CoreProviderImpl::LoadBridge(char *error, size_t maxlength)
|
||||
|
||||
logic_init_ = llf(SM_LOGIC_MAGIC);
|
||||
if (!logic_init_) {
|
||||
ke::SafeStrcpy(error, maxlength, "component version mismatch");
|
||||
ke::SafeSprintf(error, maxlength, "component version mismatch");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -712,8 +712,7 @@ static cell_t sm_RegServerCmd(IPluginContext *pContext, const cell_t *params)
|
||||
return pContext->ThrowNativeError("Invalid function id (%X)", params[2]);
|
||||
}
|
||||
|
||||
IPlugin *pPlugin = scripts->FindPluginByContext(pContext->GetContext());
|
||||
if (!g_ConCmds.AddServerCommand(pFunction, name, help, params[4], pPlugin))
|
||||
if (!g_ConCmds.AddServerCommand(pFunction, name, help, params[4]))
|
||||
{
|
||||
return pContext->ThrowNativeError("Command \"%s\" could not be created. A convar with the same name already exists.", name);
|
||||
}
|
||||
@ -743,7 +742,7 @@ static cell_t sm_RegConsoleCmd(IPluginContext *pContext, const cell_t *params)
|
||||
|
||||
IPlugin *pPlugin = scripts->FindPluginByContext(pContext->GetContext());
|
||||
const char *group = pPlugin->GetFilename();
|
||||
if (!g_ConCmds.AddAdminCommand(pFunction, name, group, 0, help, params[4], pPlugin))
|
||||
if (!g_ConCmds.AddAdminCommand(pFunction, name, group, 0, help, params[4]))
|
||||
{
|
||||
return pContext->ThrowNativeError("Command \"%s\" could not be created. A convar with the same name already exists.", name);
|
||||
}
|
||||
@ -770,9 +769,9 @@ static cell_t sm_RegAdminCmd(IPluginContext *pContext, const cell_t *params)
|
||||
pContext->LocalToString(params[5], (char **)&group);
|
||||
pFunction = pContext->GetFunctionById(params[2]);
|
||||
|
||||
IPlugin *pPlugin = scripts->FindPluginByContext(pContext->GetContext());
|
||||
if (group[0] == '\0')
|
||||
{
|
||||
IPlugin *pPlugin = scripts->FindPluginByContext(pContext->GetContext());
|
||||
group = pPlugin->GetFilename();
|
||||
}
|
||||
|
||||
@ -781,7 +780,7 @@ static cell_t sm_RegAdminCmd(IPluginContext *pContext, const cell_t *params)
|
||||
return pContext->ThrowNativeError("Invalid function id (%X)", params[2]);
|
||||
}
|
||||
|
||||
if (!g_ConCmds.AddAdminCommand(pFunction, name, group, flags, help, cmdflags, pPlugin))
|
||||
if (!g_ConCmds.AddAdminCommand(pFunction, name, group, flags, help, cmdflags))
|
||||
{
|
||||
return pContext->ThrowNativeError("Command \"%s\" could not be created. A convar with the same name already exists.", name);
|
||||
}
|
||||
@ -1318,141 +1317,6 @@ static cell_t FakeClientCommandKeyValues(IPluginContext *pContext, const cell_t
|
||||
#endif
|
||||
}
|
||||
|
||||
static cell_t sm_CommandIterator(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
GlobCmdIter *iter = new GlobCmdIter;
|
||||
iter->started = false;
|
||||
|
||||
Handle_t hndl = handlesys->CreateHandle(hCmdIterType, iter, pContext->GetIdentity(), g_pCoreIdent, NULL);
|
||||
if (hndl == BAD_HANDLE)
|
||||
{
|
||||
delete iter;
|
||||
}
|
||||
|
||||
return hndl;
|
||||
}
|
||||
|
||||
static cell_t sm_CommandIteratorNext(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
GlobCmdIter *iter;
|
||||
HandleError err;
|
||||
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
|
||||
|
||||
if ((err = handlesys->ReadHandle(params[1], hCmdIterType, &sec, (void **)&iter))
|
||||
!= HandleError_None)
|
||||
{
|
||||
return pContext->ThrowNativeError("Invalid CommandIterator Handle %x", params[1]);
|
||||
}
|
||||
|
||||
const List<ConCmdInfo *> &cmds = g_ConCmds.GetCommandList();
|
||||
|
||||
if (!iter->started)
|
||||
{
|
||||
iter->iter = cmds.begin();
|
||||
iter->started = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
iter->iter++;
|
||||
}
|
||||
|
||||
// iterate further, skip non-sourcemod cmds
|
||||
while (iter->iter != cmds.end() && !(*(iter->iter))->sourceMod)
|
||||
{
|
||||
iter->iter++;
|
||||
}
|
||||
|
||||
return iter->iter != cmds.end();
|
||||
}
|
||||
|
||||
static cell_t sm_CommandIteratorFlags(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
GlobCmdIter *iter;
|
||||
HandleError err;
|
||||
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
|
||||
|
||||
if ((err = handlesys->ReadHandle(params[1], hCmdIterType, &sec, (void **)&iter))
|
||||
!= HandleError_None)
|
||||
{
|
||||
return pContext->ThrowNativeError("Invalid CommandIterator Handle %x", params[1]);
|
||||
}
|
||||
const List<ConCmdInfo *> &cmds = g_ConCmds.GetCommandList();
|
||||
if (!iter->started || iter->iter == cmds.end())
|
||||
{
|
||||
return pContext->ThrowNativeError("Invalid CommandIterator position");
|
||||
}
|
||||
|
||||
ConCmdInfo *pInfo = (*(iter->iter));
|
||||
return pInfo->eflags;
|
||||
}
|
||||
|
||||
static cell_t sm_CommandIteratorGetDesc(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
GlobCmdIter *iter;
|
||||
HandleError err;
|
||||
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
|
||||
|
||||
if ((err = handlesys->ReadHandle(params[1], hCmdIterType, &sec, (void **)&iter))
|
||||
!= HandleError_None)
|
||||
{
|
||||
return pContext->ThrowNativeError("Invalid CommandIterator Handle %x", params[1]);
|
||||
}
|
||||
const List<ConCmdInfo *> &cmds = g_ConCmds.GetCommandList();
|
||||
if (!iter->started || iter->iter == cmds.end())
|
||||
{
|
||||
return pContext->ThrowNativeError("Invalid CommandIterator position");
|
||||
}
|
||||
|
||||
ConCmdInfo *pInfo = (*(iter->iter));
|
||||
pContext->StringToLocalUTF8(params[2], params[3], pInfo->pCmd->GetHelpText(), NULL);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell_t sm_CommandIteratorGetName(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
GlobCmdIter *iter;
|
||||
HandleError err;
|
||||
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
|
||||
|
||||
if ((err = handlesys->ReadHandle(params[1], hCmdIterType, &sec, (void **)&iter))
|
||||
!= HandleError_None)
|
||||
{
|
||||
return pContext->ThrowNativeError("Invalid CommandIterator Handle %x", params[1]);
|
||||
}
|
||||
const List<ConCmdInfo *> &cmds = g_ConCmds.GetCommandList();
|
||||
if (!iter->started || iter->iter == cmds.end())
|
||||
{
|
||||
return pContext->ThrowNativeError("Invalid CommandIterator position");
|
||||
}
|
||||
|
||||
ConCmdInfo *pInfo = (*(iter->iter));
|
||||
pContext->StringToLocalUTF8(params[2], params[3], pInfo->pCmd->GetName(), NULL);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell_t sm_CommandIteratorPlugin(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
GlobCmdIter *iter;
|
||||
HandleError err;
|
||||
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
|
||||
|
||||
if ((err = handlesys->ReadHandle(params[1], hCmdIterType, &sec, (void **)&iter))
|
||||
!= HandleError_None)
|
||||
{
|
||||
return pContext->ThrowNativeError("Invalid CommandIterator Handle %x", params[1]);
|
||||
}
|
||||
const List<ConCmdInfo *> &cmds = g_ConCmds.GetCommandList();
|
||||
if (!iter->started || iter->iter == cmds.end())
|
||||
{
|
||||
return pContext->ThrowNativeError("Invalid CommandIterator position");
|
||||
}
|
||||
|
||||
ConCmdInfo *pInfo = (*(iter->iter));
|
||||
return pInfo->pPlugin->GetMyHandle();
|
||||
}
|
||||
|
||||
REGISTER_NATIVES(consoleNatives)
|
||||
{
|
||||
{"CreateConVar", sm_CreateConVar},
|
||||
@ -1519,12 +1383,5 @@ REGISTER_NATIVES(consoleNatives)
|
||||
{"ConVar.AddChangeHook", sm_HookConVarChange},
|
||||
{"ConVar.RemoveChangeHook", sm_UnhookConVarChange},
|
||||
|
||||
{"CommandIterator.CommandIterator", sm_CommandIterator},
|
||||
{"CommandIterator.Next", sm_CommandIteratorNext},
|
||||
{"CommandIterator.GetDescription", sm_CommandIteratorGetDesc},
|
||||
{"CommandIterator.GetName", sm_CommandIteratorGetName},
|
||||
{"CommandIterator.Flags.get", sm_CommandIteratorFlags},
|
||||
{"CommandIterator.Plugin.get", sm_CommandIteratorPlugin},
|
||||
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
@ -2595,7 +2595,7 @@ static cell_t GetEntityFlags(IPluginContext *pContext, const cell_t *params)
|
||||
|
||||
for (int32_t i = 0; i < 32; i++)
|
||||
{
|
||||
int32_t flag = (1U<<i);
|
||||
int32_t flag = (1<<i);
|
||||
if ((actual_flags & flag) == flag)
|
||||
{
|
||||
sm_flags |= SDKEntFlagToSMEntFlag(flag);
|
||||
@ -2641,7 +2641,7 @@ static cell_t SetEntityFlags(IPluginContext *pContext, const cell_t *params)
|
||||
|
||||
for (int32_t i = 0; i < 32; i++)
|
||||
{
|
||||
int32_t flag = (1U<<i);
|
||||
int32_t flag = (1<<i);
|
||||
if ((sm_flags & flag) == flag)
|
||||
{
|
||||
actual_flags |= SMEntFlagToSDKEntFlag(flag);
|
||||
@ -2660,12 +2660,7 @@ static cell_t GetEntityAddress(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
|
||||
}
|
||||
|
||||
#ifdef PLATFORM_X86
|
||||
return reinterpret_cast<cell_t>(pEntity);
|
||||
#else
|
||||
return g_SourceMod.ToPseudoAddress(pEntity);
|
||||
#endif
|
||||
}
|
||||
|
||||
REGISTER_NATIVES(entityNatives)
|
||||
|
@ -438,22 +438,6 @@ static cell_t sm_SetEventBroadcast(IPluginContext *pContext, const cell_t *param
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell_t sm_GetEventBroadcast(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||
HandleError err;
|
||||
EventInfo *pInfo;
|
||||
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
|
||||
|
||||
if ((err=handlesys->ReadHandle(hndl, g_EventManager.GetHandleType(), &sec, (void **)&pInfo))
|
||||
!= HandleError_None)
|
||||
{
|
||||
return pContext->ThrowNativeError("Invalid game event handle %x (error %d)", hndl, err);
|
||||
}
|
||||
|
||||
return pInfo->bDontBroadcast;
|
||||
}
|
||||
|
||||
REGISTER_NATIVES(gameEventNatives)
|
||||
{
|
||||
{"HookEvent", sm_HookEvent},
|
||||
@ -487,7 +471,6 @@ REGISTER_NATIVES(gameEventNatives)
|
||||
{"Event.SetFloat", sm_SetEventFloat},
|
||||
{"Event.SetString", sm_SetEventString},
|
||||
{"Event.BroadcastDisabled.set", sm_SetEventBroadcast},
|
||||
{"Event.BroadcastDisabled.get", sm_GetEventBroadcast},
|
||||
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
@ -1104,7 +1104,7 @@ static cell_t smn_KvGetSectionSymbol(IPluginContext *pCtx, const cell_t *params)
|
||||
static cell_t KeyValues_Import(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
// This version takes (dest, src). The original is (src, dest).
|
||||
const cell_t new_params[3] = {
|
||||
cell_t new_params[3] = {
|
||||
2,
|
||||
params[2],
|
||||
params[1],
|
||||
|
@ -82,38 +82,6 @@ static cell_t smn_PbReadInt(IPluginContext *pCtx, const cell_t *params)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static cell_t smn_PbReadInt64(IPluginContext *pCtx, const cell_t *params)
|
||||
{
|
||||
GET_MSG_FROM_HANDLE_OR_ERR();
|
||||
GET_FIELD_NAME_OR_ERR();
|
||||
|
||||
cell_t *ret;
|
||||
pCtx->LocalToPhysAddr(params[3], &ret);
|
||||
int64 temp;
|
||||
((cell_t *)&temp)[0] = ret[0];
|
||||
((cell_t *)&temp)[1] = ret[1];
|
||||
|
||||
if (params[4] < 0)
|
||||
{
|
||||
if (!msg->GetInt64OrUnsigned(strField, &temp))
|
||||
{
|
||||
return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!msg->GetRepeatedInt64OrUnsigned(strField, params[4], &temp))
|
||||
{
|
||||
return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, params[4], msg->GetProtobufMessage()->GetTypeName().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
ret[0] = ((cell_t *)&temp)[0];
|
||||
ret[1] = ((cell_t *)&temp)[1];
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell_t smn_PbReadFloat(IPluginContext *pCtx, const cell_t *params)
|
||||
{
|
||||
GET_MSG_FROM_HANDLE_OR_ERR();
|
||||
@ -336,14 +304,6 @@ static cell_t smn_PbGetRepeatedFieldCount(IPluginContext *pCtx, const cell_t *pa
|
||||
return cnt;
|
||||
}
|
||||
|
||||
static cell_t smn_PbHasField(IPluginContext *pCtx, const cell_t *params)
|
||||
{
|
||||
GET_MSG_FROM_HANDLE_OR_ERR();
|
||||
GET_FIELD_NAME_OR_ERR();
|
||||
|
||||
return msg->HasField(strField) ? 1 : 0;
|
||||
}
|
||||
|
||||
static cell_t smn_PbSetInt(IPluginContext *pCtx, const cell_t *params)
|
||||
{
|
||||
GET_MSG_FROM_HANDLE_OR_ERR();
|
||||
@ -368,35 +328,6 @@ static cell_t smn_PbSetInt(IPluginContext *pCtx, const cell_t *params)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell_t smn_PbSetInt64(IPluginContext *pCtx, const cell_t *params)
|
||||
{
|
||||
GET_MSG_FROM_HANDLE_OR_ERR();
|
||||
GET_FIELD_NAME_OR_ERR();
|
||||
|
||||
cell_t *value;
|
||||
pCtx->LocalToPhysAddr(params[3], &value);
|
||||
int64 temp;
|
||||
((cell_t *)&temp)[0] = value[0];
|
||||
((cell_t *)&temp)[1] = value[1];
|
||||
|
||||
if (params[4] < 0)
|
||||
{
|
||||
if (!msg->SetInt64OrUnsigned(strField, temp))
|
||||
{
|
||||
return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!msg->SetRepeatedInt64OrUnsigned(strField, params[4], temp))
|
||||
{
|
||||
return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, params[4], msg->GetProtobufMessage()->GetTypeName().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell_t smn_PbSetFloat(IPluginContext *pCtx, const cell_t *params)
|
||||
{
|
||||
GET_MSG_FROM_HANDLE_OR_ERR();
|
||||
@ -614,25 +545,6 @@ static cell_t smn_PbAddInt(IPluginContext *pCtx, const cell_t *params)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell_t smn_PbAddInt64(IPluginContext *pCtx, const cell_t *params)
|
||||
{
|
||||
GET_MSG_FROM_HANDLE_OR_ERR();
|
||||
GET_FIELD_NAME_OR_ERR();
|
||||
|
||||
cell_t *value;
|
||||
pCtx->LocalToPhysAddr(params[3], &value);
|
||||
int64 temp;
|
||||
((cell_t *)&temp)[0] = value[0];
|
||||
((cell_t *)&temp)[1] = value[1];
|
||||
|
||||
if (!msg->AddInt64OrUnsigned(strField, temp))
|
||||
{
|
||||
return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell_t smn_PbAddFloat(IPluginContext *pCtx, const cell_t *params)
|
||||
{
|
||||
GET_MSG_FROM_HANDLE_OR_ERR();
|
||||
@ -858,7 +770,6 @@ REGISTER_NATIVES(protobufnatives)
|
||||
|
||||
// Transitional syntax.
|
||||
{"Protobuf.ReadInt", smn_PbReadInt},
|
||||
{"Protobuf.ReadInt64", smn_PbReadInt64},
|
||||
{"Protobuf.ReadFloat", smn_PbReadFloat},
|
||||
{"Protobuf.ReadBool", smn_PbReadBool},
|
||||
{"Protobuf.ReadString", smn_PbReadString},
|
||||
@ -867,9 +778,7 @@ REGISTER_NATIVES(protobufnatives)
|
||||
{"Protobuf.ReadVector", smn_PbReadVector},
|
||||
{"Protobuf.ReadVector2D", smn_PbReadVector2D},
|
||||
{"Protobuf.GetRepeatedFieldCount", smn_PbGetRepeatedFieldCount},
|
||||
{"Protobuf.HasField", smn_PbHasField},
|
||||
{"Protobuf.SetInt", smn_PbSetInt},
|
||||
{"Protobuf.SetInt64", smn_PbSetInt64},
|
||||
{"Protobuf.SetFloat", smn_PbSetFloat},
|
||||
{"Protobuf.SetBool", smn_PbSetBool},
|
||||
{"Protobuf.SetString", smn_PbSetString},
|
||||
@ -878,7 +787,6 @@ REGISTER_NATIVES(protobufnatives)
|
||||
{"Protobuf.SetVector", smn_PbSetVector},
|
||||
{"Protobuf.SetVector2D", smn_PbSetVector2D},
|
||||
{"Protobuf.AddInt", smn_PbAddInt},
|
||||
{"Protobuf.AddInt64", smn_PbAddInt64},
|
||||
{"Protobuf.AddFloat", smn_PbAddFloat},
|
||||
{"Protobuf.AddBool", smn_PbAddBool},
|
||||
{"Protobuf.AddString", smn_PbAddString},
|
||||
|
@ -110,7 +110,7 @@ bool SourceMod_Core::Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen
|
||||
{
|
||||
if (error)
|
||||
{
|
||||
ke::SafeSprintf(error, maxlen, "Unable to find interface %s", MMIFACE_PLMANAGER);
|
||||
snprintf(error, maxlen, "Unable to find interface %s", MMIFACE_PLMANAGER);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -107,7 +107,7 @@ ConfigResult SourceModBase::OnSourceModConfigChanged(const char *key,
|
||||
{
|
||||
if (source == ConfigSource_Console)
|
||||
{
|
||||
ke::SafeStrcpy(error, maxlength, "Cannot be set at runtime");
|
||||
ke::SafeSprintf(error, maxlength, "Cannot be set at runtime");
|
||||
return ConfigResult_Reject;
|
||||
}
|
||||
|
||||
@ -185,7 +185,7 @@ bool SourceModBase::InitializeSourceMod(char *error, size_t maxlength, bool late
|
||||
/* Attempt to load the JIT! */
|
||||
char file[PLATFORM_MAX_PATH];
|
||||
char myerror[255];
|
||||
g_SMAPI->PathFormat(file, sizeof(file), "%s/bin/" PLATFORM_ARCH_FOLDER "sourcepawn.jit.x86.%s",
|
||||
g_SMAPI->PathFormat(file, sizeof(file), "%s/bin/sourcepawn.jit.x86.%s",
|
||||
GetSourceModPath(),
|
||||
PLATFORM_LIB_EXT
|
||||
);
|
||||
@ -195,7 +195,7 @@ bool SourceModBase::InitializeSourceMod(char *error, size_t maxlength, bool late
|
||||
{
|
||||
if (error && maxlength)
|
||||
{
|
||||
ke::SafeSprintf(error, maxlength, "%s (failed to load bin/" PLATFORM_ARCH_FOLDER "sourcepawn.jit.x86.%s)",
|
||||
ke::SafeSprintf(error, maxlength, "%s (failed to load bin/sourcepawn.jit.x86.%s)",
|
||||
myerror,
|
||||
PLATFORM_LIB_EXT);
|
||||
}
|
||||
@ -207,7 +207,7 @@ bool SourceModBase::InitializeSourceMod(char *error, size_t maxlength, bool late
|
||||
|
||||
if (!factoryFn) {
|
||||
if (error && maxlength)
|
||||
ke::SafeStrcpy(error, maxlength, "SourcePawn library is out of date");
|
||||
snprintf(error, maxlength, "SourcePawn library is out of date");
|
||||
ShutdownJIT();
|
||||
return false;
|
||||
}
|
||||
@ -215,7 +215,7 @@ bool SourceModBase::InitializeSourceMod(char *error, size_t maxlength, bool late
|
||||
ISourcePawnFactory *factory = factoryFn(SOURCEPAWN_API_VERSION);
|
||||
if (!factory) {
|
||||
if (error && maxlength)
|
||||
ke::SafeStrcpy(error, maxlength, "SourcePawn library is out of date");
|
||||
snprintf(error, maxlength, "SourcePawn library is out of date");
|
||||
ShutdownJIT();
|
||||
return false;
|
||||
}
|
||||
@ -223,7 +223,7 @@ bool SourceModBase::InitializeSourceMod(char *error, size_t maxlength, bool late
|
||||
g_pPawnEnv = factory->NewEnvironment();
|
||||
if (!g_pPawnEnv) {
|
||||
if (error && maxlength)
|
||||
ke::SafeStrcpy(error, maxlength, "Could not create a SourcePawn environment!");
|
||||
snprintf(error, maxlength, "Could not create a SourcePawn environment!");
|
||||
ShutdownJIT();
|
||||
return false;
|
||||
}
|
||||
@ -617,14 +617,14 @@ unsigned int SourceModBase::GetGlobalTarget() const
|
||||
return m_target;
|
||||
}
|
||||
|
||||
void *SourceModBase::CreateDataPack()
|
||||
IDataPack *SourceModBase::CreateDataPack()
|
||||
{
|
||||
return nullptr;
|
||||
return logicore.CreateDataPack();
|
||||
}
|
||||
|
||||
void SourceModBase::FreeDataPack(void *pack)
|
||||
void SourceModBase::FreeDataPack(IDataPack *pack)
|
||||
{
|
||||
return;
|
||||
logicore.FreeDataPack(pack);
|
||||
}
|
||||
|
||||
Handle_t SourceModBase::GetDataPackHandleType(bool readonly)
|
||||
@ -745,16 +745,6 @@ bool SourceModBase::IsMapRunning()
|
||||
return g_OnMapStarted;
|
||||
}
|
||||
|
||||
void *SourceModBase::FromPseudoAddress(uint32_t pseudoAddr)
|
||||
{
|
||||
return logicore.FromPseudoAddress(pseudoAddr);
|
||||
}
|
||||
|
||||
uint32_t SourceModBase::ToPseudoAddress(void *addr)
|
||||
{
|
||||
return logicore.ToPseudoAddress(addr);
|
||||
}
|
||||
|
||||
class ConVarRegistrar :
|
||||
public IConCommandBaseAccessor,
|
||||
public SMGlobalClass
|
||||
|
@ -113,8 +113,8 @@ public: // ISourceMod
|
||||
void LogMessage(IExtension *pExt, const char *format, ...);
|
||||
void LogError(IExtension *pExt, const char *format, ...);
|
||||
size_t FormatString(char *buffer, size_t maxlength, IPluginContext *pContext, const cell_t *params, unsigned int param);
|
||||
void *CreateDataPack();
|
||||
void FreeDataPack(void *pack);
|
||||
IDataPack *CreateDataPack();
|
||||
void FreeDataPack(IDataPack *pack);
|
||||
HandleType_t GetDataPackHandleType(bool readonly=false);
|
||||
KeyValues *ReadKeyValuesHandle(Handle_t hndl, HandleError *err=NULL, bool root=false);
|
||||
const char *GetGameFolderName() const;
|
||||
@ -135,8 +135,6 @@ public: // ISourceMod
|
||||
int GetPluginId();
|
||||
int GetShApiVersion();
|
||||
bool IsMapRunning();
|
||||
void *FromPseudoAddress(uint32_t pseudoAddr);
|
||||
uint32_t ToPseudoAddress(void *addr);
|
||||
private:
|
||||
void ShutdownServices();
|
||||
private:
|
||||
|
@ -1,30 +1,27 @@
|
||||
# vim: set sts=2 ts=8 sw=2 tw=99 et ft=python:
|
||||
import os
|
||||
|
||||
for arch in SM.archs:
|
||||
binary = SM.ExtLibrary(builder, 'bintools.ext', arch)
|
||||
binary.compiler.defines += ['HOOKING_ENABLED']
|
||||
binary.compiler.cxxincludes += [
|
||||
binary = SM.ExtLibrary(builder, 'bintools.ext')
|
||||
binary.compiler.defines += ['HOOKING_ENABLED']
|
||||
binary.compiler.cxxincludes += [
|
||||
os.path.join(SM.mms_root, 'core', 'sourcehook'),
|
||||
os.path.join(builder.sourcePath, 'public', 'jit'),
|
||||
os.path.join(builder.sourcePath, 'public', 'jit', 'x86'),
|
||||
]
|
||||
if binary.compiler.family == 'gcc' or binary.compiler.family == 'clang':
|
||||
]
|
||||
if binary.compiler.family == 'gcc' or binary.compiler.family == 'clang':
|
||||
binary.compiler.cxxflags += ['-fno-rtti']
|
||||
elif binary.compiler.family == 'msvc':
|
||||
elif binary.compiler.family == 'msvc':
|
||||
binary.compiler.cxxflags += ['/GR-']
|
||||
|
||||
binary.sources += [
|
||||
binary.sources += [
|
||||
'extension.cpp',
|
||||
'CallMaker.cpp',
|
||||
'CallWrapper.cpp',
|
||||
'HookWrapper.cpp',
|
||||
'jit_call.cpp',
|
||||
'jit_hook.cpp',
|
||||
'../../public/smsdk_ext.cpp'
|
||||
]
|
||||
]
|
||||
|
||||
if arch == 'x64':
|
||||
binary.sources += ['jit_call_x64.cpp']
|
||||
else:
|
||||
binary.sources += ['jit_call.cpp']
|
||||
|
||||
SM.extensions += [builder.Add(binary)]
|
||||
SM.extensions += [builder.Add(binary)]
|
||||
|
||||
|
@ -82,8 +82,7 @@ ICallWrapper *CallMaker::CreateCall(void *address,
|
||||
CallConvention cv,
|
||||
const PassInfo *retInfo,
|
||||
const PassInfo paramInfo[],
|
||||
unsigned int numParams,
|
||||
unsigned int fnFlags)
|
||||
unsigned int numParams)
|
||||
{
|
||||
SourceHook::CProtoInfoBuilder protoInfo(GetSHCallConvention(cv));
|
||||
|
||||
@ -104,11 +103,7 @@ ICallWrapper *CallMaker::CreateCall(void *address,
|
||||
NULL, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
#if defined PLATFORM_X64
|
||||
return g_CallMaker2.CreateCall(address, &(*protoInfo), retInfo, paramInfo, fnFlags);
|
||||
#else
|
||||
return g_CallMaker2.CreateCall(address, &(*protoInfo));
|
||||
#endif
|
||||
}
|
||||
|
||||
ICallWrapper *CallMaker::CreateVCall(unsigned int vtblIdx,
|
||||
@ -116,8 +111,7 @@ ICallWrapper *CallMaker::CreateVCall(unsigned int vtblIdx,
|
||||
unsigned int thisOffs,
|
||||
const PassInfo *retInfo,
|
||||
const PassInfo paramInfo[],
|
||||
unsigned int numParams,
|
||||
unsigned int fnFlags)
|
||||
unsigned int numParams)
|
||||
{
|
||||
SourceHook::MemFuncInfo info;
|
||||
info.isVirtual = true;
|
||||
@ -144,16 +138,12 @@ ICallWrapper *CallMaker::CreateVCall(unsigned int vtblIdx,
|
||||
NULL, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
#if defined PLATFORM_X64
|
||||
return g_CallMaker2.CreateVirtualCall(&(*protoInfo), &info, retInfo, paramInfo, fnFlags);
|
||||
#else
|
||||
|
||||
return g_CallMaker2.CreateVirtualCall(&(*protoInfo), &info);
|
||||
#endif
|
||||
}
|
||||
|
||||
ICallWrapper *CallMaker2::CreateCall(void *address, const SourceHook::ProtoInfo *protoInfo)
|
||||
{
|
||||
#ifdef PLATFORM_X86
|
||||
CallWrapper *pWrapper = new CallWrapper(protoInfo);
|
||||
pWrapper->SetCalleeAddr(address);
|
||||
|
||||
@ -161,15 +151,11 @@ ICallWrapper *CallMaker2::CreateCall(void *address, const SourceHook::ProtoInfo
|
||||
pWrapper->SetCodeBaseAddr(addr);
|
||||
|
||||
return pWrapper;
|
||||
#else
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
ICallWrapper *CallMaker2::CreateVirtualCall(const SourceHook::ProtoInfo *protoInfo,
|
||||
const SourceHook::MemFuncInfo *info)
|
||||
{
|
||||
#ifdef PLATFORM_X86
|
||||
CallWrapper *pWrapper = new CallWrapper(protoInfo);
|
||||
pWrapper->SetMemFuncInfo(info);
|
||||
|
||||
@ -177,48 +163,9 @@ ICallWrapper *CallMaker2::CreateVirtualCall(const SourceHook::ProtoInfo *protoIn
|
||||
pWrapper->SetCodeBaseAddr(addr);
|
||||
|
||||
return pWrapper;
|
||||
#else
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
ICallWrapper *CallMaker2::CreateCall(void *address, const SourceHook::ProtoInfo *protoInfo,
|
||||
const PassInfo *retInfo, const PassInfo paramInfo[],
|
||||
unsigned int fnFlags)
|
||||
{
|
||||
#ifdef PLATFORM_X64
|
||||
CallWrapper *pWrapper = new CallWrapper(protoInfo, retInfo, paramInfo, fnFlags);
|
||||
pWrapper->SetCalleeAddr(address);
|
||||
|
||||
void *addr = JIT_CallCompile(pWrapper, FuncAddr_Direct);
|
||||
pWrapper->SetCodeBaseAddr(addr);
|
||||
|
||||
return pWrapper;
|
||||
#else
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
ICallWrapper *CallMaker2::CreateVirtualCall(const SourceHook::ProtoInfo *protoInfo,
|
||||
const SourceHook::MemFuncInfo *info,
|
||||
const PassInfo *retInfo,
|
||||
const PassInfo paramInfo[],
|
||||
unsigned int fnFlags)
|
||||
{
|
||||
#ifdef PLATFORM_X64
|
||||
CallWrapper *pWrapper = new CallWrapper(protoInfo, retInfo, paramInfo, fnFlags);
|
||||
pWrapper->SetMemFuncInfo(info);
|
||||
|
||||
void *addr = JIT_CallCompile(pWrapper, FuncAddr_VTable);
|
||||
pWrapper->SetCodeBaseAddr(addr);
|
||||
|
||||
return pWrapper;
|
||||
#else
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if 0
|
||||
#if defined HOOKING_ENABLED
|
||||
IHookWrapper *CallMaker2::CreateVirtualHook(SourceHook::ISourceHook *pSH,
|
||||
const SourceHook::ProtoInfo *protoInfo,
|
||||
const SourceHook::MemFuncInfo *info,
|
||||
|
@ -34,6 +34,7 @@
|
||||
|
||||
|
||||
#include "CallWrapper.h"
|
||||
#include "HookWrapper.h"
|
||||
|
||||
using namespace SourceMod;
|
||||
|
||||
@ -44,30 +45,26 @@ public: //IBinTools
|
||||
CallConvention cv,
|
||||
const PassInfo *retInfo,
|
||||
const PassInfo paramInfo[],
|
||||
unsigned int numParams,
|
||||
unsigned int fnFlags);
|
||||
unsigned int numParams);
|
||||
ICallWrapper *CreateVCall(unsigned int vtblIdx,
|
||||
unsigned int vtblOffs,
|
||||
unsigned int thisOffs,
|
||||
const PassInfo *retInfo,
|
||||
const PassInfo paramInfo[],
|
||||
unsigned int numParams,
|
||||
unsigned int fnFlags);
|
||||
unsigned int numParams);
|
||||
};
|
||||
|
||||
class CallMaker2
|
||||
#if defined HOOKING_ENABLED
|
||||
: public IBinTools2
|
||||
#endif
|
||||
{
|
||||
public: //IBinTools2
|
||||
virtual ICallWrapper *CreateCall(void *address,
|
||||
const SourceHook::ProtoInfo *protoInfo);
|
||||
virtual ICallWrapper *CreateVirtualCall(const SourceHook::ProtoInfo *protoInfo,
|
||||
const SourceHook::MemFuncInfo *info);
|
||||
ICallWrapper *CreateCall(void *address, const SourceHook::ProtoInfo *protoInfo,
|
||||
const PassInfo *retInfo, const PassInfo paramInfo[], unsigned int fnFlags);
|
||||
ICallWrapper *CreateVirtualCall(const SourceHook::ProtoInfo *protoInfo,
|
||||
const SourceHook::MemFuncInfo *info, const PassInfo *retInfo,
|
||||
const PassInfo paramInfo[], unsigned int fnFlags);
|
||||
#if 0
|
||||
#if defined HOOKING_ENABLED
|
||||
virtual IHookWrapper *CreateVirtualHook(SourceHook::ISourceHook *pSH,
|
||||
const SourceHook::ProtoInfo *protoInfo,
|
||||
const SourceHook::MemFuncInfo *info,
|
||||
|
@ -33,7 +33,7 @@
|
||||
#include "CallWrapper.h"
|
||||
#include "CallMaker.h"
|
||||
|
||||
CallWrapper::CallWrapper(const SourceHook::ProtoInfo *protoInfo) : m_FnFlags(0)
|
||||
CallWrapper::CallWrapper(const SourceHook::ProtoInfo *protoInfo)
|
||||
{
|
||||
m_AddrCodeBase = NULL;
|
||||
m_AddrCallee = NULL;
|
||||
@ -77,22 +77,6 @@ CallWrapper::CallWrapper(const SourceHook::ProtoInfo *protoInfo) : m_FnFlags(0)
|
||||
}
|
||||
}
|
||||
|
||||
CallWrapper::CallWrapper(const SourceHook::ProtoInfo *protoInfo, const PassInfo *retInfo,
|
||||
const PassInfo paramInfo[], unsigned int fnFlags) : CallWrapper(protoInfo)
|
||||
{
|
||||
m_RetParam->fields = retInfo->fields;
|
||||
m_RetParam->numFields = retInfo->numFields;
|
||||
|
||||
unsigned int argnum = protoInfo->numOfParams;
|
||||
for (unsigned int i = 0; i < argnum; i++)
|
||||
{
|
||||
m_Params[i].info.fields = paramInfo[i].fields;
|
||||
m_Params[i].info.numFields = paramInfo[i].numFields;
|
||||
}
|
||||
|
||||
m_FnFlags = fnFlags;
|
||||
}
|
||||
|
||||
CallWrapper::~CallWrapper()
|
||||
{
|
||||
delete [] m_Params;
|
||||
@ -200,8 +184,3 @@ unsigned int CallWrapper::GetParamOffset(unsigned int num)
|
||||
|
||||
return m_Params[num].offset;
|
||||
}
|
||||
|
||||
unsigned int CallWrapper::GetFunctionFlags()
|
||||
{
|
||||
return m_FnFlags;
|
||||
}
|
||||
|
@ -47,8 +47,6 @@ class CallWrapper : public ICallWrapper
|
||||
{
|
||||
public:
|
||||
CallWrapper(const SourceHook::ProtoInfo *protoInfo);
|
||||
CallWrapper(const SourceHook::ProtoInfo *protoInfo, const PassInfo *retInfo,
|
||||
const PassInfo paramInfo[], unsigned int fnFlags);
|
||||
~CallWrapper();
|
||||
public: //ICallWrapper
|
||||
CallConvention GetCallConvention();
|
||||
@ -61,7 +59,6 @@ public: //ICallWrapper
|
||||
SourceHook::ProtoInfo::CallConvention GetSHCallConvention();
|
||||
const SourceHook::PassInfo *GetSHParamInfo(unsigned int num);
|
||||
unsigned int GetParamOffset(unsigned int num);
|
||||
unsigned int GetFunctionFlags();
|
||||
public:
|
||||
void SetCalleeAddr(void *addr);
|
||||
void SetCodeBaseAddr(void *addr);
|
||||
@ -77,7 +74,6 @@ private:
|
||||
void *m_AddrCallee;
|
||||
void *m_AddrCodeBase;
|
||||
SourceHook::MemFuncInfo m_FuncInfo;
|
||||
unsigned int m_FnFlags;
|
||||
};
|
||||
|
||||
#endif //_INCLUDE_SOURCEMOD_CALLWRAPPER_H_
|
||||
|
@ -50,6 +50,12 @@ bool BinTools::SDK_OnLoad(char *error, size_t maxlength, bool late)
|
||||
g_SPEngine = g_pSM->GetScriptingEngine();
|
||||
g_pShareSys->AddInterface(myself, &g_CallMaker);
|
||||
|
||||
/* IBinTools2 is only compatible with SH v5 */
|
||||
if (g_pSM->GetShApiVersion() >= 5)
|
||||
{
|
||||
g_pShareSys->AddInterface(myself, &g_CallMaker2);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -34,12 +34,11 @@
|
||||
|
||||
#include <jit_helpers.h>
|
||||
#include <x86_macros.h>
|
||||
#include <sm_platform.h>
|
||||
#include "CallWrapper.h"
|
||||
#include "HookWrapper.h"
|
||||
|
||||
void *JIT_CallCompile(CallWrapper *pWrapper, FuncAddrMethod method);
|
||||
|
||||
#if 0
|
||||
#if defined HOOKING_ENABLED
|
||||
void *JIT_HookCompile(HookWrapper *pWrapper);
|
||||
void JIT_FreeHook(void *addr);
|
||||
#endif
|
||||
|
@ -214,7 +214,7 @@ inline void Write_Push_Params(JitWriter *jit,
|
||||
IA32_Push_Reg(jit, kREG_EBX);
|
||||
|
||||
//push <pWrapper>
|
||||
IA32_Push_Imm32(jit, (jit_int32_t)(intptr_t)pWrapper);
|
||||
IA32_Push_Imm32(jit, (jit_int32_t)pWrapper);
|
||||
}
|
||||
|
||||
inline void Write_Call_Handler(JitWriter *jit, void *addr)
|
||||
|
@ -1,656 +0,0 @@
|
||||
/**
|
||||
* vim: set ts=4 :
|
||||
* =============================================================================
|
||||
* SourceMod BinTools Extension
|
||||
* Copyright (C) 2004-2017 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* 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 <http://www.sourcemod.net/license.php>.
|
||||
*/
|
||||
|
||||
#include <jit_helpers.h>
|
||||
#include <x86_macros.h>
|
||||
|
||||
// 64-bit registers
|
||||
const jit_uint8_t kREG_RAX = kREG_EAX;
|
||||
const jit_uint8_t kREG_RCX = kREG_ECX;
|
||||
const jit_uint8_t kREG_RDX = kREG_EDX;
|
||||
const jit_uint8_t kREG_RBX = kREG_EBX;
|
||||
const jit_uint8_t kREG_RSP = kREG_ESP;
|
||||
const jit_uint8_t kREG_RBP = kREG_EBP;
|
||||
const jit_uint8_t kREG_RSI = kREG_ESI;
|
||||
const jit_uint8_t kREG_RDI = kREG_EDI;
|
||||
const jit_uint8_t kREG_R8 = 8;
|
||||
const jit_uint8_t kREG_R9 = 9;
|
||||
const jit_uint8_t kREG_R10 = 10;
|
||||
const jit_uint8_t kREG_R11 = 11;
|
||||
const jit_uint8_t kREG_R12 = 12;
|
||||
const jit_uint8_t kREG_R13 = 13;
|
||||
const jit_uint8_t kREG_R14 = 14;
|
||||
const jit_uint8_t kREG_R15 = 15;
|
||||
|
||||
const jit_uint8_t kREG_XMM0 = 0;
|
||||
const jit_uint8_t kREG_XMM1 = 1;
|
||||
const jit_uint8_t kREG_XMM2 = 2;
|
||||
const jit_uint8_t kREG_XMM3 = 3;
|
||||
const jit_uint8_t kREG_XMM4 = 4;
|
||||
const jit_uint8_t kREG_XMM5 = 5;
|
||||
const jit_uint8_t kREG_XMM6 = 6;
|
||||
const jit_uint8_t kREG_XMM7 = 7;
|
||||
const jit_uint8_t kREG_XMM8 = 8;
|
||||
const jit_uint8_t kREG_XMM9 = 9;
|
||||
const jit_uint8_t kREG_XMM10 = 10;
|
||||
const jit_uint8_t kREG_XMM11 = 11;
|
||||
const jit_uint8_t kREG_XMM12 = 12;
|
||||
const jit_uint8_t kREG_XMM13 = 13;
|
||||
const jit_uint8_t kREG_XMM14 = 14;
|
||||
const jit_uint8_t kREG_XMM15 = 15;
|
||||
|
||||
#define X64_REX_PREFIX 0x40
|
||||
|
||||
#define IA32_MOV_REG8_IMM8 0xB0
|
||||
|
||||
inline jit_uint8_t x64_rex(bool w, jit_uint8_t r, jit_uint8_t x, jit_uint8_t b)
|
||||
{
|
||||
return (X64_REX_PREFIX | ((jit_uint8_t)w << 3) | ((r>>3) << 2) | ((x>>3) << 1) | (b >> 3));
|
||||
}
|
||||
|
||||
inline void X64_Push_Reg(JitWriter *jit, jit_uint8_t reg)
|
||||
{
|
||||
if (reg >= kREG_R8)
|
||||
jit->write_ubyte(x64_rex(false, 0, 0, reg));
|
||||
IA32_Push_Reg(jit, reg & 7);
|
||||
}
|
||||
|
||||
inline void X64_Mov_Reg_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode)
|
||||
{
|
||||
jit->write_ubyte(x64_rex(true, dest, 0, src));
|
||||
IA32_Mov_Reg_Rm(jit, dest & 7, src & 7, mode);
|
||||
}
|
||||
|
||||
inline void X64_Mov_Reg_Rm_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp)
|
||||
{
|
||||
jit->write_ubyte(x64_rex(true, dest, 0, src));
|
||||
IA32_Mov_Reg_Rm_Disp8(jit, dest & 7, src & 7, disp);
|
||||
}
|
||||
|
||||
inline void X64_Mov_Reg_Rm_Disp32(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int32_t disp)
|
||||
{
|
||||
jit->write_ubyte(x64_rex(true, dest, 0, src));
|
||||
IA32_Mov_Reg_Rm_Disp32(jit, dest & 7, src & 7, disp);
|
||||
}
|
||||
|
||||
inline void X64_Mov_Reg32_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode)
|
||||
{
|
||||
if (src>= kREG_R8 || dest >= kREG_R8)
|
||||
jit->write_ubyte(x64_rex(false, dest, 0, src));
|
||||
IA32_Mov_Reg_Rm(jit, dest & 7, src & 7, mode);
|
||||
}
|
||||
|
||||
inline void X64_Mov_Reg32_Rm_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp)
|
||||
{
|
||||
if (src>= kREG_R8 || dest >= kREG_R8)
|
||||
jit->write_ubyte(x64_rex(false, dest, 0, src));
|
||||
IA32_Mov_Reg_Rm_Disp8(jit, dest & 7, src & 7, disp);
|
||||
}
|
||||
|
||||
inline void X64_Mov_Reg32_Rm_Disp32(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int32_t disp)
|
||||
{
|
||||
if (src>= kREG_R8 || dest >= kREG_R8)
|
||||
jit->write_ubyte(x64_rex(false, dest, 0, src));
|
||||
IA32_Mov_Reg_Rm_Disp32(jit, dest & 7, src & 7, disp);
|
||||
}
|
||||
|
||||
inline void X64_And_Rm_Imm8(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode, jit_int8_t value)
|
||||
{
|
||||
jit->write_ubyte(x64_rex(true, 0, 0, reg));
|
||||
IA32_And_Rm_Imm8(jit, reg & 7, mode, value);
|
||||
}
|
||||
|
||||
inline void X64_Sub_Rm_Imm8(JitWriter *jit, jit_uint8_t reg, jit_int8_t val, jit_uint8_t mode)
|
||||
{
|
||||
jit->write_ubyte(x64_rex(true, 5, 0, reg));
|
||||
IA32_Sub_Rm_Imm8(jit, reg & 7, val, mode);
|
||||
}
|
||||
|
||||
inline void X64_Sub_Rm_Imm32(JitWriter *jit, jit_uint8_t reg, jit_int32_t val, jit_uint8_t mode)
|
||||
{
|
||||
jit->write_ubyte(x64_rex(true, 5, 0, reg));
|
||||
IA32_Sub_Rm_Imm32(jit, reg & 7, val, mode);
|
||||
}
|
||||
|
||||
inline void X64_Pop_Reg(JitWriter *jit, jit_uint8_t reg)
|
||||
{
|
||||
if (reg >= kREG_R8)
|
||||
jit->write_ubyte(x64_rex(false, 0, 0, reg));
|
||||
IA32_Pop_Reg(jit, reg & 7);
|
||||
}
|
||||
|
||||
inline void X64_Return(JitWriter *jit)
|
||||
{
|
||||
IA32_Return(jit);
|
||||
}
|
||||
|
||||
inline void X64_Movzx_Reg64_Rm8_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp)
|
||||
{
|
||||
jit->write_ubyte(x64_rex(true, dest, 0, src));
|
||||
IA32_Movzx_Reg32_Rm8_Disp8(jit, dest & 7, src & 7, disp);
|
||||
}
|
||||
|
||||
inline void X64_Movzx_Reg64_Rm8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode)
|
||||
{
|
||||
jit->write_ubyte(x64_rex(true, dest, 0, src));
|
||||
IA32_Movzx_Reg32_Rm8(jit, dest & 7, src & 7, mode);
|
||||
}
|
||||
|
||||
inline void X64_Movzx_Reg64_Rm8_Disp32(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int32_t disp)
|
||||
{
|
||||
jit->write_ubyte(x64_rex(true, dest, 0, src));
|
||||
IA32_Movzx_Reg32_Rm8_Disp32(jit, dest & 7, src & 7, disp);
|
||||
}
|
||||
|
||||
inline void X64_Mov_RmRSP_Reg(JitWriter *jit, jit_uint8_t src)
|
||||
{
|
||||
jit->write_ubyte(x64_rex(true, kREG_RSP, 0, src));
|
||||
jit->write_ubyte(IA32_MOV_RM_REG);
|
||||
jit->write_ubyte(ia32_modrm(MOD_MEM_REG, src & 7, kREG_RSP));
|
||||
jit->write_ubyte(ia32_sib(NOSCALE, kREG_NOIDX, kREG_RSP));
|
||||
}
|
||||
|
||||
inline void X64_Mov_RmRSP_Disp8_Reg(JitWriter *jit, jit_uint8_t src, jit_int8_t disp)
|
||||
{
|
||||
jit->write_ubyte(x64_rex(true, src, 0, kREG_RSP));
|
||||
jit->write_ubyte(IA32_MOV_RM_REG);
|
||||
jit->write_ubyte(ia32_modrm(MOD_DISP8, src & 7, kREG_RSP));
|
||||
jit->write_ubyte(ia32_sib(NOSCALE, kREG_NOIDX, kREG_RSP));
|
||||
jit->write_byte(disp);
|
||||
}
|
||||
|
||||
inline void X64_Mov_RmRSP_Disp32_Reg(JitWriter *jit, jit_uint8_t src, jit_int8_t disp)
|
||||
{
|
||||
jit->write_ubyte(x64_rex(true, src, 0, kREG_RSP));
|
||||
jit->write_ubyte(IA32_MOV_RM_REG);
|
||||
jit->write_ubyte(ia32_modrm(MOD_DISP32, src & 7, kREG_RSP));
|
||||
jit->write_ubyte(ia32_sib(NOSCALE, kREG_NOIDX, kREG_RSP));
|
||||
jit->write_byte(disp);
|
||||
}
|
||||
|
||||
inline void X64_Movzx_Reg64_Rm16(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode)
|
||||
{
|
||||
jit->write_ubyte(x64_rex(true, dest, 0, src));
|
||||
IA32_Movzx_Reg32_Rm16(jit, dest & 7, src & 7, mode);
|
||||
}
|
||||
|
||||
inline void X64_Movzx_Reg64_Rm16_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp)
|
||||
{
|
||||
jit->write_ubyte(x64_rex(true, dest, 0, src));
|
||||
IA32_Movzx_Reg32_Rm16_Disp8(jit, dest & 7, src & 7, disp);
|
||||
}
|
||||
|
||||
inline void X64_Movzx_Reg64_Rm16_Disp32(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int32_t disp)
|
||||
{
|
||||
jit->write_ubyte(x64_rex(true, dest, 0, src));
|
||||
IA32_Movzx_Reg32_Rm16_Disp32(jit, dest & 7, src & 7, disp);
|
||||
}
|
||||
|
||||
inline void X64_Lea_DispRegImm8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src_base, jit_int8_t val)
|
||||
{
|
||||
jit->write_ubyte(x64_rex(true, dest, 0, src_base));
|
||||
IA32_Lea_DispRegImm8(jit, dest & 7, src_base & 7, val);
|
||||
}
|
||||
|
||||
inline void X64_Lea_DispRegImm32(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src_base, jit_int32_t val)
|
||||
{
|
||||
jit->write_ubyte(x64_rex(true, dest, 0, src_base));
|
||||
IA32_Lea_DispRegImm32(jit, dest & 7, src_base & 7, val);
|
||||
}
|
||||
|
||||
inline void X64_Add_Rm_Imm8(JitWriter *jit, jit_uint8_t reg, jit_int8_t value, jit_uint8_t mode)
|
||||
{
|
||||
jit->write_ubyte(x64_rex(true, 0, 0, reg));
|
||||
IA32_Add_Rm_Imm8(jit, reg & 7, value, mode);
|
||||
}
|
||||
|
||||
inline void X64_Add_Rm_Imm32(JitWriter *jit, jit_uint8_t reg, jit_int32_t value, jit_uint8_t mode)
|
||||
{
|
||||
jit->write_ubyte(x64_rex(true, 0, 0, reg));
|
||||
IA32_Add_Rm_Imm32(jit, reg & 7, value, mode);
|
||||
}
|
||||
|
||||
inline void X64_Movaps_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src)
|
||||
{
|
||||
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
|
||||
jit->write_ubyte(x64_rex(false, dest, 0, src));
|
||||
jit->write_ubyte(0x0F);
|
||||
jit->write_ubyte(0x28);
|
||||
jit->write_ubyte(ia32_modrm(MOD_MEM_REG, dest & 7, src & 7));
|
||||
}
|
||||
|
||||
inline void X64_Movups_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src)
|
||||
{
|
||||
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
|
||||
jit->write_ubyte(x64_rex(false, dest, 0, src));
|
||||
jit->write_ubyte(0x0F);
|
||||
jit->write_ubyte(0x10);
|
||||
jit->write_ubyte(ia32_modrm(MOD_MEM_REG, dest & 7, src & 7));
|
||||
}
|
||||
|
||||
inline void X64_Movaps_Rm_Reg(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src)
|
||||
{
|
||||
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
|
||||
jit->write_ubyte(x64_rex(false, src, 0, dest));
|
||||
jit->write_ubyte(0x0F);
|
||||
jit->write_ubyte(0x29);
|
||||
jit->write_ubyte(ia32_modrm(MOD_MEM_REG, src & 7, dest & 7));
|
||||
jit->write_ubyte(ia32_sib(NOSCALE, kREG_NOIDX, dest & 7));
|
||||
}
|
||||
|
||||
inline void X64_Movapd_Rm_Reg(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src)
|
||||
{
|
||||
jit->write_ubyte(0x66);
|
||||
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
|
||||
jit->write_ubyte(x64_rex(false, src, 0, dest));
|
||||
jit->write_ubyte(0x0F);
|
||||
jit->write_ubyte(0x29);
|
||||
jit->write_ubyte(ia32_modrm(MOD_MEM_REG, src & 7, dest & 7));
|
||||
jit->write_ubyte(ia32_sib(NOSCALE, kREG_NOIDX, dest & 7));
|
||||
}
|
||||
|
||||
inline void X64_Movups_Rm_Reg(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src)
|
||||
{
|
||||
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
|
||||
jit->write_ubyte(x64_rex(false, src, 0, dest));
|
||||
jit->write_ubyte(0x0F);
|
||||
jit->write_ubyte(0x11);
|
||||
jit->write_ubyte(ia32_modrm(MOD_MEM_REG, src & 7, dest & 7));
|
||||
}
|
||||
|
||||
inline void X64_Movupd_Rm_Reg(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src)
|
||||
{
|
||||
jit->write_ubyte(0x66);
|
||||
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
|
||||
jit->write_ubyte(x64_rex(false, src, 0, dest));
|
||||
jit->write_ubyte(0x0F);
|
||||
jit->write_ubyte(0x11);
|
||||
jit->write_ubyte(ia32_modrm(MOD_MEM_REG, src & 7, dest & 7));
|
||||
}
|
||||
|
||||
inline void X64_Movupd_Rm_Disp8_Reg(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp)
|
||||
{
|
||||
jit->write_ubyte(0x66);
|
||||
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
|
||||
jit->write_ubyte(x64_rex(false, src, 0, dest));
|
||||
jit->write_ubyte(0x0F);
|
||||
jit->write_ubyte(0x11);
|
||||
jit->write_ubyte(ia32_modrm(MOD_DISP8, src & 7, dest & 7));
|
||||
jit->write_byte(disp);
|
||||
}
|
||||
|
||||
inline void X64_Movaps_Rm_Disp8_Reg(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp)
|
||||
{
|
||||
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
|
||||
jit->write_ubyte(x64_rex(false, src, 0, dest));
|
||||
jit->write_ubyte(0x0F);
|
||||
jit->write_ubyte(0x29);
|
||||
jit->write_ubyte(ia32_modrm(MOD_DISP8, src & 7, dest & 7));
|
||||
jit->write_byte(disp);
|
||||
}
|
||||
|
||||
inline void X64_Movups_Rm_Disp8_Reg(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp)
|
||||
{
|
||||
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
|
||||
jit->write_ubyte(x64_rex(false, src, 0, dest));
|
||||
jit->write_ubyte(0x0F);
|
||||
jit->write_ubyte(0x11);
|
||||
jit->write_ubyte(ia32_modrm(MOD_DISP8, src & 7, dest & 7));
|
||||
jit->write_byte(disp);
|
||||
}
|
||||
|
||||
inline void X64_Movaps_Rm_Disp32_Reg(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int32_t disp)
|
||||
{
|
||||
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
|
||||
jit->write_ubyte(x64_rex(false, src, 0, dest));
|
||||
jit->write_ubyte(0x0F);
|
||||
jit->write_ubyte(0x29);
|
||||
jit->write_ubyte(ia32_modrm(MOD_DISP32, src & 7, dest & 7));
|
||||
jit->write_byte(disp);
|
||||
}
|
||||
|
||||
inline void X64_Movups_Rm_Disp32_Reg(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int32_t disp)
|
||||
{
|
||||
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
|
||||
jit->write_ubyte(x64_rex(false, src, 0, dest));
|
||||
jit->write_ubyte(0x0F);
|
||||
jit->write_ubyte(0x11);
|
||||
jit->write_ubyte(ia32_modrm(MOD_DISP32, src & 7, dest & 7));
|
||||
jit->write_byte(disp);
|
||||
}
|
||||
|
||||
inline void X64_Movlps_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src)
|
||||
{
|
||||
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
|
||||
jit->write_ubyte(x64_rex(false, dest, 0, src));
|
||||
jit->write_ubyte(0x0F);
|
||||
jit->write_ubyte(0x12);
|
||||
jit->write_ubyte(ia32_modrm(MOD_MEM_REG, dest & 7, src & 7));
|
||||
}
|
||||
|
||||
inline void X64_Movhps_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src)
|
||||
{
|
||||
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
|
||||
jit->write_ubyte(x64_rex(false, dest, 0, src));
|
||||
jit->write_ubyte(0x0F);
|
||||
jit->write_ubyte(0x16);
|
||||
jit->write_ubyte(ia32_modrm(MOD_MEM_REG, dest & 7, src & 7));
|
||||
}
|
||||
|
||||
inline void X64_Movaps_Rm_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp)
|
||||
{
|
||||
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
|
||||
jit->write_ubyte(x64_rex(false, dest, 0, src));
|
||||
jit->write_ubyte(0x0F);
|
||||
jit->write_ubyte(0x28);
|
||||
jit->write_ubyte(ia32_modrm(MOD_DISP8, dest & 7, src & 7));
|
||||
jit->write_byte(disp);
|
||||
}
|
||||
|
||||
inline void X64_Movups_Rm_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp)
|
||||
{
|
||||
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
|
||||
jit->write_ubyte(x64_rex(false, dest, 0, src));
|
||||
jit->write_ubyte(0x0F);
|
||||
jit->write_ubyte(0x10);
|
||||
jit->write_ubyte(ia32_modrm(MOD_DISP8, dest & 7, src & 7));
|
||||
jit->write_byte(disp);
|
||||
}
|
||||
|
||||
inline void X64_Movlps_Rm_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp)
|
||||
{
|
||||
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
|
||||
jit->write_ubyte(x64_rex(false, dest, 0, src));
|
||||
jit->write_ubyte(0x0F);
|
||||
jit->write_ubyte(0x12);
|
||||
jit->write_ubyte(ia32_modrm(MOD_DISP8, dest & 7, src & 7));
|
||||
jit->write_byte(disp);
|
||||
}
|
||||
|
||||
inline void X64_Movhps_Rm_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp)
|
||||
{
|
||||
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
|
||||
jit->write_ubyte(x64_rex(false, dest, 0, src));
|
||||
jit->write_ubyte(0x0F);
|
||||
jit->write_ubyte(0x16);
|
||||
jit->write_ubyte(ia32_modrm(MOD_DISP8, dest & 7, src & 7));
|
||||
jit->write_byte(disp);
|
||||
}
|
||||
|
||||
inline void X64_Movaps_Rm_Disp32(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int32_t disp)
|
||||
{
|
||||
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
|
||||
jit->write_ubyte(x64_rex(false, dest, 0, src));
|
||||
jit->write_ubyte(0x0F);
|
||||
jit->write_ubyte(0x28);
|
||||
jit->write_ubyte(ia32_modrm(MOD_DISP32, dest & 7, src & 7));
|
||||
jit->write_byte(disp);
|
||||
}
|
||||
|
||||
inline void X64_Movups_Rm_Disp32(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int32_t disp)
|
||||
{
|
||||
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
|
||||
jit->write_ubyte(x64_rex(false, dest, 0, src));
|
||||
jit->write_ubyte(0x0F);
|
||||
jit->write_ubyte(0x10);
|
||||
jit->write_ubyte(ia32_modrm(MOD_DISP32, dest & 7, src & 7));
|
||||
jit->write_byte(disp);
|
||||
}
|
||||
|
||||
inline void X64_Movapd_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src)
|
||||
{
|
||||
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
|
||||
jit->write_ubyte(x64_rex(false, dest, 0, src));
|
||||
jit->write_ubyte(0x66);
|
||||
jit->write_ubyte(0x0F);
|
||||
jit->write_ubyte(0x28);
|
||||
jit->write_ubyte(ia32_modrm(MOD_MEM_REG, dest & 7, src & 7));
|
||||
}
|
||||
|
||||
inline void X64_Movupd_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src)
|
||||
{
|
||||
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
|
||||
jit->write_ubyte(x64_rex(false, dest, 0, src));
|
||||
jit->write_ubyte(0x66);
|
||||
jit->write_ubyte(0x0F);
|
||||
jit->write_ubyte(0x10);
|
||||
jit->write_ubyte(ia32_modrm(MOD_MEM_REG, dest & 7, src & 7));
|
||||
}
|
||||
|
||||
inline void X64_Movapd_Rm_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp)
|
||||
{
|
||||
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
|
||||
jit->write_ubyte(x64_rex(false, dest, 0, src));
|
||||
jit->write_ubyte(0x66);
|
||||
jit->write_ubyte(0x0F);
|
||||
jit->write_ubyte(0x28);
|
||||
jit->write_ubyte(ia32_modrm(MOD_DISP8, dest & 7, src & 7));
|
||||
jit->write_byte(disp);
|
||||
}
|
||||
|
||||
inline void X64_Movupd_Rm_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp)
|
||||
{
|
||||
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
|
||||
jit->write_ubyte(x64_rex(false, dest, 0, src));
|
||||
jit->write_ubyte(0x66);
|
||||
jit->write_ubyte(0x0F);
|
||||
jit->write_ubyte(0x10);
|
||||
jit->write_ubyte(ia32_modrm(MOD_DISP8, dest & 7, src & 7));
|
||||
jit->write_byte(disp);
|
||||
}
|
||||
|
||||
inline void X64_Movapd_Rm_Disp32(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int32_t disp)
|
||||
{
|
||||
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
|
||||
jit->write_ubyte(x64_rex(false, dest, 0, src));
|
||||
jit->write_ubyte(0x66);
|
||||
jit->write_ubyte(0x0F);
|
||||
jit->write_ubyte(0x28);
|
||||
jit->write_ubyte(ia32_modrm(MOD_DISP32, dest & 7, src & 7));
|
||||
jit->write_byte(disp);
|
||||
}
|
||||
|
||||
inline void X64_Movupd_Rm_Disp32(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int32_t disp)
|
||||
{
|
||||
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
|
||||
jit->write_ubyte(x64_rex(false, dest, 0, src));
|
||||
jit->write_ubyte(0x66);
|
||||
jit->write_ubyte(0x0F);
|
||||
jit->write_ubyte(0x10);
|
||||
jit->write_ubyte(ia32_modrm(MOD_DISP32, dest & 7, src & 7));
|
||||
jit->write_byte(disp);
|
||||
}
|
||||
|
||||
inline void X64_Cld(JitWriter *jit)
|
||||
{
|
||||
IA32_Cld(jit);
|
||||
}
|
||||
|
||||
inline void X64_Rep(JitWriter *jit)
|
||||
{
|
||||
IA32_Rep(jit);
|
||||
}
|
||||
|
||||
inline void X64_Movsq(JitWriter *jit)
|
||||
{
|
||||
jit->write_ubyte(x64_rex(true, 0, 0, 0));
|
||||
jit->write_ubyte(IA32_MOVSD);
|
||||
}
|
||||
|
||||
inline void X64_Movsb(JitWriter *jit)
|
||||
{
|
||||
jit->write_ubyte(IA32_MOVSB);
|
||||
}
|
||||
|
||||
inline void X64_Lea_Reg_DispRegMultImm8(JitWriter *jit,
|
||||
jit_uint8_t dest,
|
||||
jit_uint8_t src_base,
|
||||
jit_uint8_t src_index,
|
||||
jit_uint8_t scale,
|
||||
jit_int8_t val)
|
||||
{
|
||||
jit->write_ubyte(x64_rex(true, dest, 0, src_index));
|
||||
IA32_Lea_Reg_DispRegMultImm8(jit, dest & 7, src_base, src_index & 7, scale, val);
|
||||
}
|
||||
|
||||
inline void X64_Lea_Reg_DispRegMultImm32(JitWriter *jit,
|
||||
jit_uint8_t dest,
|
||||
jit_uint8_t src_base,
|
||||
jit_uint8_t src_index,
|
||||
jit_uint8_t scale,
|
||||
jit_int32_t val)
|
||||
{
|
||||
jit->write_ubyte(x64_rex(true, dest, 0, src_index));
|
||||
jit->write_ubyte(IA32_LEA_REG_MEM);
|
||||
jit->write_ubyte(ia32_modrm(MOD_DISP32, dest & 7, kREG_SIB));
|
||||
jit->write_ubyte(ia32_sib(scale, src_index & 7, src_base));
|
||||
jit->write_int32(val);
|
||||
}
|
||||
|
||||
inline jitoffs_t X64_Mov_Reg_Imm32(JitWriter *jit, jit_uint8_t dest, jit_int32_t num)
|
||||
{
|
||||
jitoffs_t offs;
|
||||
jit->write_ubyte(x64_rex(true, 0, 0, dest));
|
||||
jit->write_ubyte(0xC7);
|
||||
jit->write_ubyte(ia32_modrm(MOD_REG, 0, dest & 7));
|
||||
offs = jit->get_outputpos();
|
||||
jit->write_int32(num);
|
||||
return offs;
|
||||
}
|
||||
|
||||
inline jitoffs_t X64_Mov_Reg_Imm64(JitWriter *jit, jit_uint8_t dest, jit_int64_t num)
|
||||
{
|
||||
jitoffs_t offs;
|
||||
jit->write_ubyte(x64_rex(true, 0, 0, dest));
|
||||
jit->write_ubyte(IA32_MOV_REG_IMM+(dest & 7));
|
||||
offs = jit->get_outputpos();
|
||||
jit->write_int64(num);
|
||||
return offs;
|
||||
}
|
||||
|
||||
inline void X64_Mov_Rm8_Reg8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode)
|
||||
{
|
||||
if (dest >= kREG_R8 || src > kREG_R8)
|
||||
jit->write_ubyte(x64_rex(false, src, 0, dest));
|
||||
jit->write_ubyte(IA32_MOV_RM8_REG8);
|
||||
if ((dest & 7) == kREG_RBP) // Using rbp/r13 requires a displacement
|
||||
mode = MOD_DISP8;
|
||||
jit->write_ubyte(ia32_modrm(mode, src & 7, dest & 7));
|
||||
if ((dest & 7) == kREG_RSP) // rsp/r12 needs SIB byte
|
||||
jit->write_ubyte(ia32_sib(NOSCALE, kREG_NOIDX, dest & 7));
|
||||
else if ((dest & 7) == kREG_RBP)
|
||||
jit->write_ubyte(0); // Displacement of 0 needed to use rbp/r13
|
||||
}
|
||||
|
||||
inline void X64_Mov_Rm32_Reg32(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode)
|
||||
{
|
||||
if (dest >= kREG_R8 || src > kREG_R8)
|
||||
jit->write_ubyte(x64_rex(false, src, 0, dest));
|
||||
jit->write_ubyte(IA32_MOV_RM_REG);
|
||||
if ((dest & 7) == kREG_RBP) // Using rbp/r13 requires a displacement
|
||||
mode = MOD_DISP8;
|
||||
jit->write_ubyte(ia32_modrm(mode, src & 7, dest & 7));
|
||||
if ((dest & 7) == kREG_RSP) // rsp/r12 needs SIB byte
|
||||
jit->write_ubyte(ia32_sib(NOSCALE, kREG_NOIDX, dest & 7));
|
||||
else if ((dest & 7) == kREG_RBP)
|
||||
jit->write_ubyte(0); // Displacement of 0 needed to use rbp/r13
|
||||
}
|
||||
|
||||
inline void X64_Mov_Rm16_Reg16(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode)
|
||||
{
|
||||
jit->write_ubyte(IA32_16BIT_PREFIX);
|
||||
X64_Mov_Rm32_Reg32(jit, dest, src, mode);
|
||||
}
|
||||
|
||||
|
||||
inline void X64_Mov_Rm_Reg(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode)
|
||||
{
|
||||
jit->write_ubyte(x64_rex(true, src, 0, dest));
|
||||
jit->write_ubyte(IA32_MOV_RM_REG);
|
||||
if ((dest & 7) == kREG_RBP) // Using rbp/r13 requires a displacement
|
||||
mode = MOD_DISP8;
|
||||
jit->write_ubyte(ia32_modrm(mode, src & 7, dest & 7));
|
||||
if ((dest & 7) == kREG_RSP) // rsp/r12 needs SIB byte
|
||||
jit->write_ubyte(ia32_sib(NOSCALE, kREG_NOIDX, dest & 7));
|
||||
else if ((dest & 7) == kREG_RBP)
|
||||
jit->write_ubyte(0); // Displacement of 0 needed to use rbp/r13
|
||||
}
|
||||
|
||||
inline void X64_Mov_Rm_Reg_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp)
|
||||
{
|
||||
jit->write_ubyte(x64_rex(true, src, 0, dest));
|
||||
IA32_Mov_Rm_Reg_Disp8(jit, dest & 7, src & 7, disp);
|
||||
}
|
||||
|
||||
inline jitoffs_t X64_Call_Imm32(JitWriter *jit, jit_int32_t disp)
|
||||
{
|
||||
return IA32_Call_Imm32(jit, disp);
|
||||
}
|
||||
|
||||
inline void X64_Write_Jump32_Abs(JitWriter *jit, jitoffs_t jmp, void *target)
|
||||
{
|
||||
IA32_Write_Jump32_Abs(jit, jmp, target);
|
||||
}
|
||||
|
||||
inline void X64_Call_Reg(JitWriter *jit, jit_uint8_t reg)
|
||||
{
|
||||
if (reg >= kREG_R8)
|
||||
jit->write_ubyte(x64_rex(false, 0, 0, reg));
|
||||
IA32_Call_Reg(jit, reg & 7);
|
||||
}
|
||||
|
||||
inline jitoffs_t X64_Mov_Reg8_Imm8(JitWriter *jit, jit_uint8_t dest, jit_int8_t value)
|
||||
{
|
||||
jitoffs_t offs;
|
||||
if (dest >= kREG_R8)
|
||||
jit->write_ubyte(x64_rex(false, 0, 0, dest));
|
||||
jit->write_ubyte(IA32_MOV_REG8_IMM8+(dest & 7));
|
||||
offs = jit->get_outputpos();
|
||||
jit->write_byte(value);
|
||||
return offs;
|
||||
}
|
||||
|
||||
inline void X64_Movd_Reg32_Xmm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src)
|
||||
{
|
||||
jit->write_ubyte(0x66);
|
||||
if (dest >= kREG_R8 || src >= kREG_XMM8)
|
||||
jit->write_ubyte(x64_rex(false, src, 0, dest));
|
||||
jit->write_ubyte(0x0F);
|
||||
jit->write_ubyte(0x7E);
|
||||
jit->write_ubyte(ia32_modrm(MOD_REG, src & 7, dest & 7));
|
||||
}
|
||||
|
||||
inline void X64_Movq_Reg_Xmm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src)
|
||||
{
|
||||
jit->write_ubyte(0x66);
|
||||
jit->write_ubyte(x64_rex(true, src, 0, dest));
|
||||
jit->write_ubyte(0x0F);
|
||||
jit->write_ubyte(0x7E);
|
||||
jit->write_ubyte(ia32_modrm(MOD_REG, src & 7, dest & 7));
|
||||
}
|
@ -1,24 +1,23 @@
|
||||
# vim: set sts=2 ts=8 sw=2 tw=99 et ft=python:
|
||||
import os
|
||||
|
||||
for arch in SM.archs:
|
||||
binary = SM.ExtLibrary(builder, 'clientprefs.ext', arch)
|
||||
binary.compiler.cxxincludes += [
|
||||
binary = SM.ExtLibrary(builder, 'clientprefs.ext')
|
||||
binary.compiler.cxxincludes += [
|
||||
os.path.join(SM.mms_root, 'core', 'sourcehook'),
|
||||
]
|
||||
if binary.compiler.family == 'gcc' or binary.compiler.family == 'clang':
|
||||
]
|
||||
if binary.compiler.family == 'gcc' or binary.compiler.family == 'clang':
|
||||
binary.compiler.cxxflags += ['-fno-rtti']
|
||||
elif binary.compiler.family == 'msvc':
|
||||
elif binary.compiler.family == 'msvc':
|
||||
binary.compiler.cxxflags += ['/GR-']
|
||||
|
||||
binary.sources += [
|
||||
binary.sources += [
|
||||
'extension.cpp',
|
||||
'cookie.cpp',
|
||||
'menus.cpp',
|
||||
'natives.cpp',
|
||||
'query.cpp',
|
||||
'../../public/smsdk_ext.cpp'
|
||||
]
|
||||
]
|
||||
|
||||
SM.extensions += [builder.Add(binary)]
|
||||
SM.extensions += [builder.Add(binary)]
|
||||
|
||||
|
@ -56,14 +56,20 @@ bool ClientPrefs::SDK_OnLoad(char *error, size_t maxlength, bool late)
|
||||
|
||||
if (DBInfo == NULL)
|
||||
{
|
||||
DBInfo = dbi->FindDatabaseConf("storage-local");
|
||||
DBInfo = dbi->FindDatabaseConf("default");
|
||||
|
||||
if (DBInfo == NULL)
|
||||
{
|
||||
ke::SafeStrcpy(error, maxlength, "Could not find any suitable database configs");
|
||||
return false;
|
||||
DBInfo = dbi->FindDatabaseConf("storage-local");
|
||||
}
|
||||
}
|
||||
|
||||
if (DBInfo == NULL)
|
||||
{
|
||||
snprintf(error, maxlength, "Could not find any suitable database configs");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (DBInfo->driver && DBInfo->driver[0] != '\0')
|
||||
{
|
||||
Driver = dbi->FindOrLoadDriver(DBInfo->driver);
|
||||
@ -75,7 +81,7 @@ bool ClientPrefs::SDK_OnLoad(char *error, size_t maxlength, bool late)
|
||||
|
||||
if (Driver == NULL)
|
||||
{
|
||||
ke::SafeSprintf(error, maxlength, "Could not load DB Driver \"%s\"", DBInfo->driver);
|
||||
snprintf(error, maxlength, "Could not load DB Driver \"%s\"", DBInfo->driver);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -471,58 +471,6 @@ cell_t GetClientCookieTime(IPluginContext *pContext, const cell_t *params)
|
||||
return value;
|
||||
}
|
||||
|
||||
static cell_t Cookie_Set(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
// This version takes (handle, client, value). The original is (client, handle, value).
|
||||
const cell_t new_params[4] = {
|
||||
3,
|
||||
params[2],
|
||||
params[1],
|
||||
params[3]
|
||||
};
|
||||
|
||||
return SetClientPrefCookie(pContext, new_params);
|
||||
}
|
||||
|
||||
static cell_t Cookie_Get(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
// This verson takes (handle, client, buffer, maxlen). The original is (client, handle, buffer, maxlen).
|
||||
const cell_t new_params[5] = {
|
||||
4,
|
||||
params[2],
|
||||
params[1],
|
||||
params[3],
|
||||
params[4]
|
||||
};
|
||||
|
||||
return GetClientPrefCookie(pContext, new_params);
|
||||
}
|
||||
|
||||
static cell_t Cookie_SetByAuthId(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
// This version takes (handle, authid, value). The original is (authid, handle, value).
|
||||
const cell_t new_params[4] = {
|
||||
3,
|
||||
params[2],
|
||||
params[1],
|
||||
params[3]
|
||||
};
|
||||
|
||||
return SetAuthIdCookie(pContext, new_params);
|
||||
}
|
||||
|
||||
static cell_t Cookie_GetClientTime(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
// This version takes (handle, client). The original is (client, handle)
|
||||
const cell_t new_params[3] = {
|
||||
2,
|
||||
params[2],
|
||||
params[1],
|
||||
};
|
||||
|
||||
return GetClientCookieTime(pContext, new_params);
|
||||
}
|
||||
|
||||
sp_nativeinfo_t g_ClientPrefNatives[] =
|
||||
{
|
||||
{"RegClientCookie", RegClientPrefCookie},
|
||||
@ -538,15 +486,5 @@ sp_nativeinfo_t g_ClientPrefNatives[] =
|
||||
{"SetCookieMenuItem", AddSettingsMenuItem},
|
||||
{"SetCookiePrefabMenu", AddSettingsPrefabMenuItem},
|
||||
{"GetClientCookieTime", GetClientCookieTime},
|
||||
|
||||
{"Cookie.Cookie", RegClientPrefCookie},
|
||||
{"Cookie.Find", FindClientPrefCookie},
|
||||
{"Cookie.Set", Cookie_Set},
|
||||
{"Cookie.Get", Cookie_Get},
|
||||
{"Cookie.SetByAuthId", Cookie_SetByAuthId},
|
||||
{"Cookie.SetPrefabMenu", AddSettingsPrefabMenuItem},
|
||||
{"Cookie.GetClientTime", Cookie_GetClientTime},
|
||||
{"Cookie.AccessLevel.get", GetCookieAccess},
|
||||
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
@ -11,24 +11,14 @@ project.sources += [
|
||||
'util_cstrike.cpp',
|
||||
'../../public/smsdk_ext.cpp',
|
||||
'../../public/CDetour/detours.cpp',
|
||||
'../../public/asm/asm.c',
|
||||
'../../public/libudis86/decode.c',
|
||||
'../../public/libudis86/itab.c',
|
||||
'../../public/libudis86/syn-att.c',
|
||||
'../../public/libudis86/syn-intel.c',
|
||||
'../../public/libudis86/syn.c',
|
||||
'../../public/libudis86/udis86.c',
|
||||
'../../public/asm/asm.c'
|
||||
]
|
||||
project.compiler.defines += ['HAVE_STRING_H'];
|
||||
|
||||
for sdk_name in ['css', 'csgo']:
|
||||
if sdk_name not in SM.sdks:
|
||||
continue
|
||||
sdk = SM.sdks[sdk_name]
|
||||
for arch in SM.archs:
|
||||
if not arch in sdk.platformSpec[builder.target.platform]:
|
||||
continue
|
||||
|
||||
SM.HL2Config(project, 'game.cstrike.ext.' + sdk.ext, sdk, arch)
|
||||
SM.HL2Config(project, 'game.cstrike.ext.' + sdk.ext, sdk)
|
||||
|
||||
SM.extensions += builder.Add(project)
|
||||
|
@ -64,7 +64,7 @@ bool CStrike::SDK_OnLoad(char *error, size_t maxlength, bool late)
|
||||
#if SOURCE_ENGINE != SE_CSGO
|
||||
if (strcmp(g_pSM->GetGameFolderName(), "cstrike") != 0)
|
||||
{
|
||||
ke::SafeStrcpy(error, maxlength, "Cannot Load Cstrike Extension on mods other than CS:S and CS:GO");
|
||||
snprintf(error, maxlength, "Cannot Load Cstrike Extension on mods other than CS:S and CS:GO");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
@ -77,7 +77,7 @@ bool CStrike::SDK_OnLoad(char *error, size_t maxlength, bool late)
|
||||
{
|
||||
if (error)
|
||||
{
|
||||
ke::SafeSprintf(error, maxlength, "Could not read sm-cstrike.games: %s", conf_error);
|
||||
snprintf(error, maxlength, "Could not read sm-cstrike.games: %s", conf_error);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -126,7 +126,7 @@ DETOUR_DECL_MEMBER0(DetourWeaponPrice, int)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if SOURCE_ENGINE == SE_CSS
|
||||
#if SOURCE_ENGINE != SE_CSGO
|
||||
DETOUR_DECL_MEMBER2(DetourTerminateRound, void, float, delay, int, reason)
|
||||
{
|
||||
if (g_pIgnoreTerminateDetour)
|
||||
@ -135,7 +135,7 @@ DETOUR_DECL_MEMBER2(DetourTerminateRound, void, float, delay, int, reason)
|
||||
DETOUR_MEMBER_CALL(DetourTerminateRound)(delay, reason);
|
||||
return;
|
||||
}
|
||||
#elif SOURCE_ENGINE == SE_CSGO && !defined(WIN32)
|
||||
#elif !defined(WIN32)
|
||||
DETOUR_DECL_MEMBER4(DetourTerminateRound, void, float, delay, int, reason, int, unknown, int, unknown2)
|
||||
{
|
||||
if (g_pIgnoreTerminateDetour)
|
||||
@ -189,12 +189,12 @@ DETOUR_DECL_MEMBER3(DetourTerminateRound, void, int, reason, int, unknown, int,
|
||||
reason++;
|
||||
#endif
|
||||
|
||||
#if SOURCE_ENGINE == SE_CSS
|
||||
#if SOURCE_ENGINE != SE_CSGO
|
||||
if (result == Pl_Changed)
|
||||
return DETOUR_MEMBER_CALL(DetourTerminateRound)(delay, reason);
|
||||
|
||||
return DETOUR_MEMBER_CALL(DetourTerminateRound)(orgdelay, orgreason);
|
||||
#elif SOURCE_ENGINE == SE_CSGO && !defined(WIN32)
|
||||
#elif !defined(WIN32)
|
||||
if (result == Pl_Changed)
|
||||
return DETOUR_MEMBER_CALL(DetourTerminateRound)(delay, reason, unknown, unknown2);
|
||||
|
||||
|
@ -18,11 +18,7 @@ struct HashItemDef_Node
|
||||
class CHashItemDef
|
||||
{
|
||||
public:
|
||||
#ifdef PLATFORM_X86
|
||||
unsigned char padding[36];
|
||||
#else
|
||||
unsigned char padding[56];
|
||||
#endif
|
||||
HashItemDef_Node *pMem;
|
||||
int nAllocatedCount;
|
||||
int nGrowSize;
|
||||
|
@ -34,7 +34,6 @@
|
||||
#include "forwards.h"
|
||||
#include "util_cstrike.h"
|
||||
#include <server_class.h>
|
||||
#include <sm_argbuffer.h>
|
||||
|
||||
#if SOURCE_ENGINE == SE_CSGO
|
||||
#include "itemdef-hash.h"
|
||||
@ -179,8 +178,12 @@ static cell_t CS_SwitchTeam(IPluginContext *pContext, const cell_t *params)
|
||||
return pContext->ThrowNativeError("Client index %d is not valid", params[1]);
|
||||
}
|
||||
|
||||
ArgBuffer<CBaseEntity*, int> vstk(pEntity, params[2]);
|
||||
unsigned char vstk[sizeof(CBaseEntity *) + sizeof(int)];
|
||||
unsigned char *vptr = vstk;
|
||||
|
||||
*(CBaseEntity **)vptr = pEntity;
|
||||
vptr += sizeof(CBaseEntity *);
|
||||
*(int *)vptr = params[2];
|
||||
pWrapper->Execute(vstk, NULL);
|
||||
#else
|
||||
if (g_pSDKTools == NULL)
|
||||
@ -267,9 +270,17 @@ static cell_t CS_DropWeapon(IPluginContext *pContext, const cell_t *params)
|
||||
if (params[4] == 1 && g_pCSWeaponDropDetoured)
|
||||
g_pIgnoreCSWeaponDropDetour = true;
|
||||
|
||||
ArgBuffer<CBaseEntity*, CBaseEntity*, bool> vstk(pEntity, pWeapon, (params[3]) ? true : false);
|
||||
unsigned char vstk[sizeof(CBaseEntity *) * 2 + sizeof(bool)];
|
||||
unsigned char *vptr = vstk;
|
||||
|
||||
*(CBaseEntity **)vptr = pEntity;
|
||||
vptr += sizeof(CBaseEntity *);
|
||||
*(CBaseEntity **)vptr = pWeapon;
|
||||
vptr += sizeof(CBaseEntity *);
|
||||
*(bool *)vptr = (params[3]) ? true : false;
|
||||
|
||||
pWrapper->Execute(vstk, NULL);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -297,7 +308,7 @@ static cell_t CS_TerminateRound(IPluginContext *pContext, const cell_t *params)
|
||||
reason++;
|
||||
#endif
|
||||
|
||||
#if SOURCE_ENGINE == SE_CSS
|
||||
#if SOURCE_ENGINE != SE_CSGO
|
||||
static ICallWrapper *pWrapper = NULL;
|
||||
|
||||
if (!pWrapper)
|
||||
@ -305,7 +316,7 @@ static cell_t CS_TerminateRound(IPluginContext *pContext, const cell_t *params)
|
||||
REGISTER_NATIVE_ADDR("TerminateRound",
|
||||
PassInfo pass[2]; \
|
||||
pass[0].flags = PASSFLAG_BYVAL; \
|
||||
pass[0].type = PassType_Float; \
|
||||
pass[0].type = PassType_Basic; \
|
||||
pass[0].size = sizeof(float); \
|
||||
pass[1].flags = PASSFLAG_BYVAL; \
|
||||
pass[1].type = PassType_Basic; \
|
||||
@ -316,10 +327,17 @@ static cell_t CS_TerminateRound(IPluginContext *pContext, const cell_t *params)
|
||||
if (params[3] == 1 && g_pTerminateRoundDetoured)
|
||||
g_pIgnoreTerminateDetour = true;
|
||||
|
||||
ArgBuffer<void*, float, int> vstk(gamerules, sp_ctof(params[1]), reason);
|
||||
unsigned char vstk[sizeof(void *) + sizeof(float)+ sizeof(int)];
|
||||
unsigned char *vptr = vstk;
|
||||
|
||||
*(void **)vptr = gamerules;
|
||||
vptr += sizeof(void *);
|
||||
*(float *)vptr = sp_ctof(params[1]);
|
||||
vptr += sizeof(float);
|
||||
*(int*)vptr = reason;
|
||||
|
||||
pWrapper->Execute(vstk, NULL);
|
||||
#elif SOURCE_ENGINE == SE_CSGO && !defined(WIN32)
|
||||
#elif !defined(WIN32)
|
||||
static ICallWrapper *pWrapper = NULL;
|
||||
|
||||
if (!pWrapper)
|
||||
@ -327,7 +345,7 @@ static cell_t CS_TerminateRound(IPluginContext *pContext, const cell_t *params)
|
||||
REGISTER_NATIVE_ADDR("TerminateRound",
|
||||
PassInfo pass[4]; \
|
||||
pass[0].flags = PASSFLAG_BYVAL; \
|
||||
pass[0].type = PassType_Float; \
|
||||
pass[0].type = PassType_Basic; \
|
||||
pass[0].size = sizeof(float); \
|
||||
pass[1].flags = PASSFLAG_BYVAL; \
|
||||
pass[1].type = PassType_Basic; \
|
||||
@ -344,10 +362,21 @@ static cell_t CS_TerminateRound(IPluginContext *pContext, const cell_t *params)
|
||||
if (params[3] == 1 && g_pTerminateRoundDetoured)
|
||||
g_pIgnoreTerminateDetour = true;
|
||||
|
||||
ArgBuffer<void*, float, int, int, int> vstk(gamerules, sp_ctof(params[1]), reason, 0, 0);
|
||||
unsigned char vstk[sizeof(void *) + sizeof(float) + (sizeof(int)*3)];
|
||||
unsigned char *vptr = vstk;
|
||||
|
||||
*(void **)vptr = gamerules;
|
||||
vptr += sizeof(void *);
|
||||
*(float *)vptr = sp_ctof(params[1]);
|
||||
vptr += sizeof(float);
|
||||
*(int*)vptr = reason;
|
||||
vptr += sizeof(int);
|
||||
*(int*)vptr = 0;
|
||||
vptr += sizeof(int);
|
||||
*(int*)vptr = 0;
|
||||
|
||||
pWrapper->Execute(vstk, NULL);
|
||||
#else // CSGO Win32
|
||||
#else
|
||||
static void *addr = NULL;
|
||||
|
||||
if(!addr)
|
||||
@ -486,6 +515,80 @@ static cell_t CS_GetWeaponPrice(IPluginContext *pContext, const cell_t *params)
|
||||
}
|
||||
#endif
|
||||
|
||||
static cell_t CS_GetClientClanTag(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
static void *addr;
|
||||
if (!addr)
|
||||
{
|
||||
if (!g_pGameConf->GetMemSig("SetClanTag", &addr) || !addr)
|
||||
{
|
||||
return pContext->ThrowNativeError("Failed to locate function");
|
||||
}
|
||||
}
|
||||
|
||||
CBaseEntity *pEntity;
|
||||
if (!(pEntity = GetCBaseEntity(params[1], true)))
|
||||
{
|
||||
return pContext->ThrowNativeError("Client index %d is not valid", params[1]);
|
||||
}
|
||||
|
||||
static int tagOffsetOffset = -1;
|
||||
static int tagOffset;
|
||||
|
||||
if (tagOffsetOffset == -1)
|
||||
{
|
||||
if (!g_pGameConf->GetOffset("ClanTagOffset", &tagOffsetOffset))
|
||||
{
|
||||
tagOffsetOffset = -1;
|
||||
return pContext->ThrowNativeError("Unable to find ClanTagOffset gamedata");
|
||||
}
|
||||
|
||||
tagOffset = *(int *)((intptr_t)addr + tagOffsetOffset);
|
||||
}
|
||||
|
||||
size_t len;
|
||||
|
||||
const char *src = (char *)((intptr_t)pEntity + tagOffset);
|
||||
pContext->StringToLocalUTF8(params[2], params[3], src, &len);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static cell_t CS_SetClientClanTag(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
static ICallWrapper *pWrapper = NULL;
|
||||
|
||||
if (!pWrapper)
|
||||
{
|
||||
REGISTER_NATIVE_ADDR("SetClanTag",
|
||||
PassInfo pass[1]; \
|
||||
pass[0].flags = PASSFLAG_BYVAL; \
|
||||
pass[0].type = PassType_Basic; \
|
||||
pass[0].size = sizeof(char *); \
|
||||
pWrapper = g_pBinTools->CreateCall(addr, CallConv_ThisCall, NULL, pass, 1))
|
||||
}
|
||||
|
||||
CBaseEntity *pEntity;
|
||||
if (!(pEntity = GetCBaseEntity(params[1], true)))
|
||||
{
|
||||
return pContext->ThrowNativeError("Client index %d is not valid", params[1]);
|
||||
}
|
||||
|
||||
char *szNewTag;
|
||||
pContext->LocalToString(params[2], &szNewTag);
|
||||
|
||||
unsigned char vstk[sizeof(CBaseEntity *) + sizeof(char *)];
|
||||
unsigned char *vptr = vstk;
|
||||
|
||||
*(CBaseEntity **)vptr = pEntity;
|
||||
vptr += sizeof(CBaseEntity *);
|
||||
*(char **)vptr = szNewTag;
|
||||
|
||||
pWrapper->Execute(vstk, NULL);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell_t CS_AliasToWeaponID(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
#if SOURCE_ENGINE == SE_CSGO
|
||||
@ -729,130 +832,6 @@ static inline cell_t SetPlayerVar(IPluginContext *pContext, const cell_t *params
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline cell_t GetPlayerStringVar(IPluginContext *pContext, const cell_t *params, const char *varName)
|
||||
{
|
||||
CBaseEntity *pPlayer = GetCBaseEntity(params[1], true);
|
||||
if (!pPlayer)
|
||||
{
|
||||
return pContext->ThrowNativeError("Client index %d is not valid", params[1]);
|
||||
}
|
||||
|
||||
char *pVar = GetPlayerVarAddressOrError<char>(varName, pContext, pPlayer);
|
||||
if (pVar)
|
||||
{
|
||||
size_t len;
|
||||
pContext->StringToLocalUTF8(params[2], params[3], pVar, &len);
|
||||
return len;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline cell_t SetPlayerStringVar(IPluginContext *pContext, const cell_t *params, const char *varName)
|
||||
{
|
||||
CBaseEntity *pPlayer = GetCBaseEntity(params[1], true);
|
||||
if (!pPlayer)
|
||||
{
|
||||
return pContext->ThrowNativeError("Client index %d is not valid", params[1]);
|
||||
}
|
||||
|
||||
char szSizeName[128];
|
||||
g_pSM->Format(szSizeName, sizeof(szSizeName), "%sSize", varName);
|
||||
|
||||
int maxlen = 0;
|
||||
if(!g_pGameConf->GetOffset(szSizeName, &maxlen))
|
||||
{
|
||||
return pContext->ThrowNativeError("Failed to locate %s offset in gamedata", szSizeName);
|
||||
}
|
||||
|
||||
char *pVar = GetPlayerVarAddressOrError<char>(varName, pContext, pPlayer);
|
||||
|
||||
if (pVar)
|
||||
{
|
||||
char *newValue;
|
||||
pContext->LocalToString(params[2], &newValue);
|
||||
Q_strncpy(pVar, newValue, maxlen);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell_t CS_GetClientClanTag(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
#if SOURCE_ENGINE == SE_CSGO
|
||||
return GetPlayerStringVar(pContext, params, "ClanTag");
|
||||
#else
|
||||
static void *addr;
|
||||
if (!addr)
|
||||
{
|
||||
if (!g_pGameConf->GetMemSig("SetClanTag", &addr) || !addr)
|
||||
{
|
||||
return pContext->ThrowNativeError("Failed to locate function");
|
||||
}
|
||||
}
|
||||
|
||||
CBaseEntity *pEntity;
|
||||
if (!(pEntity = GetCBaseEntity(params[1], true)))
|
||||
{
|
||||
return pContext->ThrowNativeError("Client index %d is not valid", params[1]);
|
||||
}
|
||||
|
||||
static int tagOffsetOffset = -1;
|
||||
static int tagOffset;
|
||||
|
||||
if (tagOffsetOffset == -1)
|
||||
{
|
||||
if (!g_pGameConf->GetOffset("ClanTagOffset", &tagOffsetOffset))
|
||||
{
|
||||
tagOffsetOffset = -1;
|
||||
return pContext->ThrowNativeError("Unable to find ClanTagOffset gamedata");
|
||||
}
|
||||
|
||||
tagOffset = *(int *)((intptr_t)addr + tagOffsetOffset);
|
||||
}
|
||||
|
||||
size_t len;
|
||||
|
||||
const char *src = (char *)((intptr_t)pEntity + tagOffset);
|
||||
pContext->StringToLocalUTF8(params[2], params[3], src, &len);
|
||||
|
||||
return len;
|
||||
#endif
|
||||
}
|
||||
|
||||
static cell_t CS_SetClientClanTag(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
#if SOURCE_ENGINE == SE_CSGO
|
||||
return SetPlayerStringVar(pContext, params, "ClanTag");
|
||||
#else
|
||||
static ICallWrapper *pWrapper = NULL;
|
||||
|
||||
if (!pWrapper)
|
||||
{
|
||||
REGISTER_NATIVE_ADDR("SetClanTag",
|
||||
PassInfo pass[1]; \
|
||||
pass[0].flags = PASSFLAG_BYVAL; \
|
||||
pass[0].type = PassType_Basic; \
|
||||
pass[0].size = sizeof(char *); \
|
||||
pWrapper = g_pBinTools->CreateCall(addr, CallConv_ThisCall, NULL, pass, 1))
|
||||
}
|
||||
|
||||
CBaseEntity *pEntity;
|
||||
if (!(pEntity = GetCBaseEntity(params[1], true)))
|
||||
{
|
||||
return pContext->ThrowNativeError("Client index %d is not valid", params[1]);
|
||||
}
|
||||
|
||||
char *szNewTag;
|
||||
pContext->LocalToString(params[2], &szNewTag);
|
||||
|
||||
ArgBuffer<CBaseEntity*, char*> vstk(pEntity, szNewTag);
|
||||
|
||||
pWrapper->Execute(vstk, NULL);
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
static cell_t CS_SetMVPCount(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
return SetPlayerVar<int>(pContext, params, "MVPs");
|
||||
|
@ -33,8 +33,6 @@
|
||||
#include "util_cstrike.h"
|
||||
#include "RegNatives.h"
|
||||
#include <iplayerinfo.h>
|
||||
#include <sm_argbuffer.h>
|
||||
|
||||
#if SOURCE_ENGINE == SE_CSGO
|
||||
#include "itemdef-hash.h"
|
||||
|
||||
@ -136,9 +134,16 @@ CEconItemView *GetEconItemView(CBaseEntity *pEntity, int iSlot)
|
||||
if (team != 2 && team != 3)
|
||||
return NULL;
|
||||
|
||||
ArgBuffer<void*, int, int> vstk(reinterpret_cast<void*>(((intptr_t)pEntity + thisPtrOffset)), team, iSlot);
|
||||
CEconItemView *ret;
|
||||
unsigned char vstk[sizeof(void *) + sizeof(int) * 2];
|
||||
unsigned char *vptr = vstk;
|
||||
|
||||
*(void **)vptr = (void *)((intptr_t)pEntity + thisPtrOffset);
|
||||
vptr += sizeof(void *);
|
||||
*(int *)vptr = team;
|
||||
vptr += sizeof(int);
|
||||
*(int *)vptr = iSlot;
|
||||
|
||||
CEconItemView *ret = nullptr;
|
||||
pWrapper->Execute(vstk, &ret);
|
||||
|
||||
return ret;
|
||||
@ -158,9 +163,13 @@ CCSWeaponData *GetCCSWeaponData(CEconItemView *view)
|
||||
pWrapper = g_pBinTools->CreateCall(addr, CallConv_ThisCall, &retpass, NULL, 0))
|
||||
}
|
||||
|
||||
ArgBuffer<CEconItemView*> vstk(view);
|
||||
unsigned char vstk[sizeof(CEconItemView *)];
|
||||
unsigned char *vptr = vstk;
|
||||
|
||||
*(CEconItemView **)vptr = view;
|
||||
|
||||
CCSWeaponData *pWpnData = NULL;
|
||||
|
||||
CCSWeaponData *pWpnData = nullptr;
|
||||
pWrapper->Execute(vstk, &pWpnData);
|
||||
|
||||
return pWpnData;
|
||||
@ -183,9 +192,9 @@ CEconItemSchema *GetItemSchema()
|
||||
void *pSchema = NULL;
|
||||
pWrapper->Execute(NULL, &pSchema);
|
||||
|
||||
//On windows/mac this is actually ItemSystem() + sizeof(void *) is ItemSchema
|
||||
#if defined(PLATFORM_WINDOWS) || defined(PLATFORM_APPLE)
|
||||
return (CEconItemSchema *)((intptr_t)pSchema + sizeof(void *));
|
||||
//In windows this is actually ItemSystem() + 4 is ItemSchema
|
||||
#ifdef WIN32
|
||||
return (CEconItemSchema *)((intptr_t)pSchema + 4);
|
||||
#else
|
||||
return (CEconItemSchema *)pSchema;
|
||||
#endif
|
||||
@ -225,9 +234,14 @@ CEconItemDefinition *GetItemDefintionByName(const char *classname)
|
||||
g_RegNatives.Register(pWrapper);
|
||||
}
|
||||
|
||||
ArgBuffer<void*, const char *> vstk(pSchema, classname);
|
||||
unsigned char vstk[sizeof(void *) + sizeof(const char *)];
|
||||
unsigned char *vptr = vstk;
|
||||
|
||||
CEconItemDefinition *pItemDef = nullptr;
|
||||
*(void **)vptr = pSchema;
|
||||
vptr += sizeof(void *);
|
||||
*(const char **)vptr = classname;
|
||||
|
||||
CEconItemDefinition *pItemDef = NULL;
|
||||
pWrapper->Execute(vstk, &pItemDef);
|
||||
|
||||
return pItemDef;
|
||||
@ -326,7 +340,7 @@ SMCSWeapon GetWeaponIdFromDefIdx(uint16_t iDefIdx)
|
||||
SMCSWeapon_UMP45, SMCSWeapon_XM1014, SMCSWeapon_BIZON, SMCSWeapon_MAG7,
|
||||
SMCSWeapon_NEGEV, SMCSWeapon_SAWEDOFF, SMCSWeapon_TEC9, SMCSWeapon_TASER,
|
||||
SMCSWeapon_HKP2000, SMCSWeapon_MP7, SMCSWeapon_MP9, SMCSWeapon_NOVA,
|
||||
SMCSWeapon_P250, SMCSWeapon_SHIELD, SMCSWeapon_SCAR20, SMCSWeapon_SG556,
|
||||
SMCSWeapon_P250, SMCSWeapon_NONE, SMCSWeapon_SCAR20, SMCSWeapon_SG556,
|
||||
SMCSWeapon_SSG08, SMCSWeapon_KNIFE_GG, SMCSWeapon_KNIFE, SMCSWeapon_FLASHBANG,
|
||||
SMCSWeapon_HEGRENADE, SMCSWeapon_SMOKEGRENADE, SMCSWeapon_MOLOTOV, SMCSWeapon_DECOY,
|
||||
SMCSWeapon_INCGRENADE, SMCSWeapon_C4, SMCSWeapon_KEVLAR, SMCSWeapon_ASSAULTSUIT,
|
||||
@ -343,7 +357,7 @@ ItemDefHashValue *GetHashValueFromWeapon(const char *szWeapon)
|
||||
{
|
||||
char tempWeapon[MAX_WEAPON_NAME_LENGTH];
|
||||
|
||||
ke::SafeStrcpy(tempWeapon, sizeof(tempWeapon), szWeapon);
|
||||
Q_strncpy(tempWeapon, szWeapon, sizeof(tempWeapon));
|
||||
Q_strlower(tempWeapon);
|
||||
|
||||
if (strstr(tempWeapon, "weapon_") == NULL && strstr(tempWeapon, "item_") == NULL)
|
||||
@ -353,7 +367,7 @@ ItemDefHashValue *GetHashValueFromWeapon(const char *szWeapon)
|
||||
for (unsigned int i = 0; i < SM_ARRAYSIZE(szClassPrefixs); i++)
|
||||
{
|
||||
char classname[MAX_WEAPON_NAME_LENGTH];
|
||||
ke::SafeSprintf(classname, sizeof(classname), "%s%s", szClassPrefixs[i], tempWeapon);
|
||||
Q_snprintf(classname, sizeof(classname), "%s%s", szClassPrefixs[i], tempWeapon);
|
||||
|
||||
ClassnameMap::Result res = g_mapClassToDefIdx.find(classname);
|
||||
|
||||
@ -376,6 +390,8 @@ ItemDefHashValue *GetHashValueFromWeapon(const char *szWeapon)
|
||||
#if SOURCE_ENGINE != SE_CSGO
|
||||
void *GetWeaponInfo(int weaponID)
|
||||
{
|
||||
void *info;
|
||||
|
||||
static ICallWrapper *pWrapper = NULL;
|
||||
if (!pWrapper)
|
||||
{
|
||||
@ -391,9 +407,11 @@ void *GetWeaponInfo(int weaponID)
|
||||
pWrapper = g_pBinTools->CreateCall(addr, CallConv_Cdecl, &retpass, pass, 1))
|
||||
}
|
||||
|
||||
ArgBuffer<int> vstk(weaponID);
|
||||
unsigned char vstk[sizeof(int)];
|
||||
unsigned char *vptr = vstk;
|
||||
|
||||
*(int *)vptr = weaponID;
|
||||
|
||||
void *info = nullptr;
|
||||
pWrapper->Execute(vstk, &info);
|
||||
|
||||
return info;
|
||||
@ -417,6 +435,7 @@ const char *GetWeaponNameFromClassname(const char *weapon)
|
||||
const char *GetTranslatedWeaponAlias(const char *weapon)
|
||||
{
|
||||
#if SOURCE_ENGINE != SE_CSGO
|
||||
const char *alias = NULL;
|
||||
|
||||
static ICallWrapper *pWrapper = NULL;
|
||||
|
||||
@ -434,11 +453,12 @@ const char *GetTranslatedWeaponAlias(const char *weapon)
|
||||
pWrapper = g_pBinTools->CreateCall(addr, CallConv_Cdecl, &retpass, pass, 1))
|
||||
}
|
||||
|
||||
ArgBuffer<const char *> vstk(GetWeaponNameFromClassname(weapon));
|
||||
unsigned char vstk[sizeof(const char *)];
|
||||
unsigned char *vptr = vstk;
|
||||
|
||||
*(const char **)vptr = GetWeaponNameFromClassname(weapon);
|
||||
|
||||
const char *alias = nullptr;
|
||||
pWrapper->Execute(vstk, &alias);
|
||||
|
||||
return alias;
|
||||
#else //this should work for both games maybe replace both?
|
||||
static const char *szAliases[] =
|
||||
@ -472,6 +492,8 @@ const char *GetTranslatedWeaponAlias(const char *weapon)
|
||||
int AliasToWeaponID(const char *weapon)
|
||||
{
|
||||
#if SOURCE_ENGINE != SE_CSGO
|
||||
int weaponID = 0;
|
||||
|
||||
static ICallWrapper *pWrapper = NULL;
|
||||
|
||||
if (!pWrapper)
|
||||
@ -488,9 +510,11 @@ int AliasToWeaponID(const char *weapon)
|
||||
pWrapper = g_pBinTools->CreateCall(addr, CallConv_Cdecl, &retpass, pass, 1))
|
||||
}
|
||||
|
||||
ArgBuffer<const char *> vstk(GetWeaponNameFromClassname(weapon));
|
||||
unsigned char vstk[sizeof(const char *)];
|
||||
unsigned char *vptr = vstk;
|
||||
|
||||
*(const char **)vptr = GetWeaponNameFromClassname(weapon);
|
||||
|
||||
int weaponID = 0;
|
||||
pWrapper->Execute(vstk, &weaponID);
|
||||
|
||||
return weaponID;
|
||||
@ -507,8 +531,10 @@ int AliasToWeaponID(const char *weapon)
|
||||
const char *WeaponIDToAlias(int weaponID)
|
||||
{
|
||||
#if SOURCE_ENGINE != SE_CSGO
|
||||
const char *alias = NULL;
|
||||
|
||||
static ICallWrapper *pWrapper = NULL;
|
||||
|
||||
if (!pWrapper)
|
||||
{
|
||||
REGISTER_ADDR("WeaponIDToAlias", 0,
|
||||
@ -523,9 +549,11 @@ const char *WeaponIDToAlias(int weaponID)
|
||||
pWrapper = g_pBinTools->CreateCall(addr, CallConv_Cdecl, &retpass, pass, 1))
|
||||
}
|
||||
|
||||
ArgBuffer<int> vstk(weaponID);
|
||||
unsigned char vstk[sizeof(int)];
|
||||
unsigned char *vptr = vstk;
|
||||
|
||||
*(int *)vptr = weaponID;
|
||||
|
||||
const char *alias = nullptr;
|
||||
pWrapper->Execute(vstk, &alias);
|
||||
|
||||
return alias;
|
||||
|
@ -2,27 +2,27 @@
|
||||
import os
|
||||
|
||||
libcurl = builder.Build('curl-src/lib/AMBuilder')
|
||||
for arch in SM.archs:
|
||||
binary = SM.ExtLibrary(builder, 'webternet.ext', arch)
|
||||
binary.compiler.includes += [
|
||||
|
||||
binary = SM.ExtLibrary(builder, 'webternet.ext')
|
||||
binary.compiler.includes += [
|
||||
os.path.join(builder.sourcePath, 'extensions', 'curl', 'curl-src', 'include')
|
||||
]
|
||||
binary.compiler.defines += ['CURL_STATICLIB']
|
||||
if binary.compiler.family == 'gcc' or binary.compiler.family == 'clang':
|
||||
]
|
||||
binary.compiler.defines += ['CURL_STATICLIB']
|
||||
if binary.compiler.family == 'gcc' or binary.compiler.family == 'clang':
|
||||
binary.compiler.cxxflags += ['-fno-rtti']
|
||||
elif binary.compiler.family == 'msvc':
|
||||
elif binary.compiler.family == 'msvc':
|
||||
binary.compiler.cxxflags += ['/GR-']
|
||||
binary.compiler.postlink += [libcurl[arch].binary]
|
||||
if builder.target.platform == 'linux':
|
||||
binary.compiler.postlink += [libcurl.binary]
|
||||
if builder.target.platform == 'linux':
|
||||
binary.compiler.postlink += ['-lrt']
|
||||
elif builder.target.platform == 'windows':
|
||||
elif builder.target.platform == 'windows':
|
||||
binary.compiler.postlink += ['ws2_32.lib']
|
||||
|
||||
binary.sources += [
|
||||
binary.sources += [
|
||||
'extension.cpp',
|
||||
'curlapi.cpp',
|
||||
'../../public/smsdk_ext.cpp'
|
||||
]
|
||||
]
|
||||
|
||||
SM.extensions += [builder.Add(binary)]
|
||||
SM.extensions += [builder.Add(binary)]
|
||||
|
||||
|
@ -3,33 +3,31 @@ import os, platform
|
||||
|
||||
builder.SetBuildFolder('libcurl')
|
||||
|
||||
rvalue = {}
|
||||
for arch in SM.archs:
|
||||
binary = SM.StaticLibrary(builder, 'curl', arch)
|
||||
binary.compiler.includes += [
|
||||
binary = SM.StaticLibrary(builder, 'curl')
|
||||
binary.compiler.includes += [
|
||||
os.path.join(builder.sourcePath, 'extensions', 'curl', 'curl-src', 'lib'),
|
||||
os.path.join(builder.sourcePath, 'extensions', 'curl', 'curl-src', 'include')
|
||||
]
|
||||
]
|
||||
|
||||
if builder.target.platform == 'mac':
|
||||
if builder.target.platform == 'mac':
|
||||
mac_version, ignore, ignore = platform.mac_ver()
|
||||
mac_tuple = mac_version.split('.')
|
||||
if int(mac_tuple[0]) >= 10 and int(mac_tuple[1]) >= 9:
|
||||
binary.compiler.defines += ['BUILTIN_STRLCAT']
|
||||
elif builder.target.platform == 'windows':
|
||||
elif builder.target.platform == 'windows':
|
||||
binary.compiler.defines += [
|
||||
'BUILDING_LIBCURL',
|
||||
'CURL_STATICLIB',
|
||||
'CURL_DISABLE_LDAP',
|
||||
]
|
||||
elif builder.target.platform == 'linux':
|
||||
elif builder.target.platform == 'linux':
|
||||
binary.compiler.defines += ['_GNU_SOURCE']
|
||||
|
||||
if binary.compiler.family == 'clang':
|
||||
if binary.compiler.family == 'clang':
|
||||
# https://llvm.org/bugs/show_bug.cgi?id=16428
|
||||
binary.compiler.cflags += ['-Wno-attributes']
|
||||
|
||||
binary.sources += [
|
||||
binary.sources += [
|
||||
'base64.c',
|
||||
'connect.c',
|
||||
'content_encoding.c',
|
||||
@ -95,6 +93,6 @@ for arch in SM.archs:
|
||||
'transfer.c',
|
||||
'url.c',
|
||||
'version.c'
|
||||
]
|
||||
rvalue[arch] = builder.Add(binary)
|
||||
]
|
||||
rvalue = builder.Add(binary)
|
||||
|
||||
|
@ -1,20 +1,19 @@
|
||||
# vim: set sts=2 ts=8 sw=2 tw=99 et ft=python:
|
||||
import os
|
||||
|
||||
for arch in SM.archs:
|
||||
binary = SM.ExtLibrary(builder, 'geoip.ext', arch)
|
||||
if binary.compiler.family == 'gcc' or binary.compiler.family == 'clang':
|
||||
binary = SM.ExtLibrary(builder, 'geoip.ext')
|
||||
if binary.compiler.family == 'gcc' or binary.compiler.family == 'clang':
|
||||
binary.compiler.cxxflags += ['-fno-rtti']
|
||||
elif binary.compiler.family == 'msvc':
|
||||
elif binary.compiler.family == 'msvc':
|
||||
binary.compiler.cxxflags += ['/GR-']
|
||||
if builder.target.platform == 'windows':
|
||||
if builder.target.platform == 'windows':
|
||||
binary.compiler.postlink += ['wsock32.lib']
|
||||
|
||||
binary.sources += [
|
||||
binary.sources += [
|
||||
'extension.cpp',
|
||||
'GeoIP.c',
|
||||
'../../public/smsdk_ext.cpp'
|
||||
]
|
||||
]
|
||||
|
||||
SM.extensions += [builder.Add(binary)]
|
||||
SM.extensions += [builder.Add(binary)]
|
||||
|
||||
|
@ -32,7 +32,6 @@
|
||||
#include <sourcemod_version.h>
|
||||
#include "extension.h"
|
||||
#include "GeoIP.h"
|
||||
#include "am-string.h"
|
||||
|
||||
/**
|
||||
* @file extension.cpp
|
||||
@ -52,7 +51,7 @@ bool GeoIP_Extension::SDK_OnLoad(char *error, size_t maxlength, bool late)
|
||||
|
||||
if (!gi)
|
||||
{
|
||||
ke::SafeStrcpy(error, maxlength, "Could not load configs/geoip/GeoIP.dat");
|
||||
snprintf(error, maxlength, "Could not load configs/geoip/GeoIP.dat");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -2,10 +2,9 @@
|
||||
import os
|
||||
|
||||
if SM.mysql_root:
|
||||
for arch in SM.archs:
|
||||
binary = SM.ExtLibrary(builder, 'dbi.mysql.ext', arch)
|
||||
binary = SM.ExtLibrary(builder, 'dbi.mysql.ext')
|
||||
binary.compiler.cxxincludes += [
|
||||
os.path.join(SM.mysql_root[arch], 'include'),
|
||||
os.path.join(SM.mysql_root, 'include'),
|
||||
os.path.join(SM.mms_root, 'core', 'sourcehook')
|
||||
]
|
||||
if binary.compiler.family == 'gcc' or binary.compiler.family == 'clang':
|
||||
@ -15,7 +14,7 @@ if SM.mysql_root:
|
||||
|
||||
if builder.target.platform == 'linux' or builder.target.platform == 'mac':
|
||||
binary.compiler.postlink += [
|
||||
os.path.join(SM.mysql_root[arch], 'lib', 'libmysqlclient_r.a'),
|
||||
os.path.join(SM.mysql_root, 'lib', 'libmysqlclient_r.a'),
|
||||
'-lz',
|
||||
'-lpthread',
|
||||
'-lm',
|
||||
@ -23,9 +22,9 @@ if SM.mysql_root:
|
||||
if builder.target.platform == 'linux':
|
||||
binary.compiler.postlink += ['-lrt']
|
||||
elif builder.target.platform == 'windows':
|
||||
binary.compiler.defines += ['WIN32_LEAN_AND_MEAN']
|
||||
binary.compiler.postlink += [
|
||||
os.path.join(SM.mysql_root[arch], 'lib', 'mysqlclient.lib'),
|
||||
os.path.join(SM.mysql_root, 'lib', 'opt', 'mysqlclient.lib'),
|
||||
os.path.join(SM.mysql_root, 'lib', 'opt', 'zlib.lib'),
|
||||
'wsock32.lib'
|
||||
]
|
||||
|
||||
@ -42,7 +41,6 @@ if SM.mysql_root:
|
||||
if binary.compiler.family == 'msvc' and binary.compiler.version >= 1900:
|
||||
binary.sources += [ 'msvc15hack.c' ]
|
||||
binary.compiler.linkflags += ['legacy_stdio_definitions.lib', 'legacy_stdio_wide_specifiers.lib']
|
||||
binary.compiler.defines += ['HAVE_STRUCT_TIMESPEC']
|
||||
|
||||
SM.extensions += [builder.Add(binary)]
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user