Compare commits

..
Author SHA1 Message Date
David Anderson e47703ee83 version bump
--HG--
branch : sourcemod-1.0.1
extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/branches/sourcemod-1.0.1%402166
2008-05-21 03:48:47 +00:00
Scott Ehlert 0c3cc85f6d Removed GiveNamedItem/GivePlayerItem offset due to crashes
--HG--
branch : sourcemod-1.0.1
extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/branches/sourcemod-1.0.1%402165
2008-05-21 03:39:00 +00:00
David Anderson 467663bff5 merged in bug fixes from trunk
--HG--
branch : sourcemod-1.0.1
extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/branches/sourcemod-1.0.1%402164
2008-05-21 03:31:42 +00:00
Scott Ehlert ac862954f1 Fixed amb1688 - Linux GivePlayerItem/GiveNamedItem offset for Day of Defeat was incorrect
--HG--
branch : sourcemod-1.0.1
extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/branches/sourcemod-1.0.1%402160
2008-05-20 09:44:30 +00:00
Matt Woodrow a12f61d463 Fixed amb1657 - Server should see admin version of sm_who
--HG--
branch : sourcemod-1.0.1
extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/branches/sourcemod-1.0.1%402146
2008-05-14 22:40:03 +00:00
Scott Ehlert 7d372ceedc Fixed up IGameHelpers.h such that it no longer requires HL2SDK headers if a function doesn't need them
--HG--
branch : sourcemod-1.0.1
extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/branches/sourcemod-1.0.1%402143
2008-05-13 08:22:21 +00:00
Scott Ehlert bba7ff1c37 Err, fixed Linux build
--HG--
branch : sourcemod-1.0.1
extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/branches/sourcemod-1.0.1%402138
2008-05-12 02:05:31 +00:00
Scott Ehlert 6f8fad7784 Symbols no longer stripped on Linux for easier debugging
--HG--
branch : sourcemod-1.0.1
extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/branches/sourcemod-1.0.1%402136
2008-05-11 07:49:10 +00:00
Scott Ehlert 22f96dd195 Removed odd debug code, err, in CrazyDebug of all places
--HG--
branch : sourcemod-1.0.1
extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/branches/sourcemod-1.0.1%402130
2008-05-09 08:22:22 +00:00
Scott Ehlert 423ad68a6f CrazyDebug just got crazier!
1) Now works with SrcDS -console + DEP on Windows
2) Updated vcproj files for OB, Episode 1, etc

--HG--
branch : sourcemod-1.0.1
extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/branches/sourcemod-1.0.1%402128
2008-05-09 08:04:06 +00:00
Scott Ehlert f522c531fb Attempted fix for amb1648 - stack corruption when GetClientEyeAngles() is called on Windows
--HG--
branch : sourcemod-1.0.1
extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/branches/sourcemod-1.0.1%402123
2008-05-02 07:47:16 +00:00
Scott Ehlert fe71d6a5ab 1.0.1 build fixes
--HG--
branch : sourcemod-1.0.1
extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/branches/sourcemod-1.0.1%402120
2008-05-01 22:01:23 +00:00
Matt Woodrow 2352b11b18 More bugfixes
--HG--
branch : sourcemod-1.0.1
extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/branches/sourcemod-1.0.1%402118
2008-05-01 04:54:37 +00:00
Matt Woodrow d140bfa8af Merged bug fixes from 1.0.x branch.
--HG--
branch : sourcemod-1.0.1
extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/branches/sourcemod-1.0.1%402117
2008-05-01 04:49:06 +00:00
Scott Ehlert a41c004d1c Merged TF2 vfunc offset update into 1.0.1
--HG--
branch : sourcemod-1.0.1
extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/branches/sourcemod-1.0.1%402116
2008-05-01 02:58:20 +00:00
Matt Woodrow 9009c115a5 Missing ! in sample_ext
--HG--
branch : sourcemod-1.0.1
extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/branches/sourcemod-1.0.1%402113
2008-05-01 02:43:07 +00:00
Matt Woodrow b637ab794b Moved mapchooser tf2 fix into 1.0.1
--HG--
branch : sourcemod-1.0.1
extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/branches/sourcemod-1.0.1%402111
2008-05-01 02:39:19 +00:00
Scott Ehlert 4be098c694 New 1.0.1 branch
--HG--
branch : sourcemod-1.0.1
2008-05-01 01:41:12 +00:00
2326 changed files with 22382 additions and 606537 deletions
-23
View File
@@ -1,23 +0,0 @@
# Binaries
\.dll$
\.exe$
\.so$
# Files generated by Visual Studio
\.aps$
\.ncb$
\.sdf$
\.suo$
\.user$
# Build directories
/CrazyDebug.*
/Debug.*
/Release.*
# Files generated by Mac OS X Finder
(^|/)\.DS_Store$
# Files generated by Windows Explorer
(^|/)[dD]esktop\.ini$
(^|/)[tT]humbs\.db$
-10
View File
@@ -1,10 +0,0 @@
54539fa4e51f98d7841c853c1370dff6ccd3cdf2 sourcemod-1.0.0
e6ef5ecdf8d75740ca2685a709bf321f8873bc3b sourcemod-1.1.0
e877885fac80be71822641f7a9122cebc9812521 sourcemod-1.1.1
b3ffa8a4511c4eadaf533fc790aa6b14f7f0c6ea sourcemod-1.1.2
3a73bbf60f34befa9b66be03fa5974b394bb3411 sourcemod-1.2.0
a71318396392e3c6d0ff31e069a60fbde59e0cea sourcemod-1.3.0
3f33d01fcc28b509bed30f7be07ed215cc000538 sourcemod-1.3.1
a3e8f7a7fdf7f012dd02ad491a2e1ccdad151687 sourcemod-1.3.2
c5062ca8283033cf33f45da6f19e486ca10835ff sourcemod-1.3.3
4d6afc42522c8f416dc45be7af7b145507b00630 sourcemod-1.3.4
-323
View File
@@ -1,323 +0,0 @@
# vim: set ts=2 sw=2 tw=99 noet ft=python:
import os
import sys
from ambuild.command import SymlinkCommand
class SM:
def __init__(self):
self.compiler = Cpp.Compiler()
#Build SDK info
self.sdkInfo = { }
self.sdkInfo['ep1'] = {'sdk': 'HL2SDK', 'ext': '1.ep1', 'def': '1',
'name': 'EPISODEONE'}
self.sdkInfo['ep2'] = {'sdk': 'HL2SDKOB', 'ext': '2.ep2', 'def': '3',
'name': 'ORANGEBOX'}
self.sdkInfo['ep2v'] = {'sdk': 'HL2SDKOBVALVE', 'ext': '2.ep2v', 'def': '4',
'name': 'ORANGEBOXVALVE'}
self.sdkInfo['l4d'] = {'sdk': 'HL2SDKL4D', 'ext': '2.l4d', 'def': '5',
'name': 'LEFT4DEAD'}
self.sdkInfo['l4d2'] = {'sdk': 'HL2SDKL4D2', 'ext': '2.l4d2', 'def': '6',
'name': 'LEFT4DEAD2'}
if AMBuild.target['platform'] == 'windows':
self.sdkInfo['darkm'] = {'sdk': 'HL2SDK-DARKM', 'ext': '2.darkm', 'def': '2',
'name': 'DARKMESSIAH'}
self.sdkInfo['swarm'] = {'sdk': 'HL2SDK-SWARM', 'ext': '2.swarm', 'def': '7',
'name': 'ALIENSWARM'}
if AMBuild.mode == 'config':
#Detect compilers
self.compiler.DetectAll(AMBuild)
#Detect variables
envvars = { 'MMSOURCE18': 'mmsource-1.8',
'HL2SDK': 'hl2sdk',
'HL2SDKOB': 'hl2sdk-ob',
'HL2SDKL4D': 'hl2sdk-l4d',
'HL2SDKOBVALVE': 'hl2sdk-ob-valve',
'HL2SDKL4D2': 'hl2sdk-l4d2',
'MYSQL5': 'mysql-5.0'
}
#Dark Messiah is Windows-only
if AMBuild.target['platform'] == 'windows':
envvars['HL2SDK-DARKM'] = 'hl2sdk-darkm'
envvars['HL2SDK-SWARM'] = 'hl2sdk-swarm'
#Must have a path for each envvar (file a bug if you don't like this)
for i in envvars:
if i in os.environ:
path = os.environ[i]
if not os.path.isdir(path):
raise Exception('Path for {0} was not found: {1}'.format(i, path))
else:
head = os.getcwd()
oldhead = None
while head != None and head != oldhead:
path = os.path.join(head, envvars[i])
if os.path.isdir(path):
break
oldhead = head
head, tail = os.path.split(head)
if head == None or head == oldhead:
raise Exception('Could not find a valid path for {0}'.format(i))
AMBuild.cache.CacheVariable(i, path)
#Set up defines
cxx = self.compiler.cxx
if isinstance(cxx, Cpp.GCC):
self.vendor = 'gcc'
self.compiler.AddToListVar('CDEFINES', 'stricmp=strcasecmp')
self.compiler.AddToListVar('CDEFINES', '_stricmp=strcasecmp')
self.compiler.AddToListVar('CDEFINES', '_snprintf=snprintf')
self.compiler.AddToListVar('CDEFINES', '_vsnprintf=vsnprintf')
self.compiler.AddToListVar('CFLAGS', '-pipe')
self.compiler.AddToListVar('CFLAGS', '-fno-strict-aliasing')
if cxx.majorVersion >= 4:
self.compiler.AddToListVar('CFLAGS', '-fvisibility=hidden')
self.compiler.AddToListVar('CXXFLAGS', '-fvisibility-inlines-hidden')
self.compiler.AddToListVar('CFLAGS', '-Wall')
self.compiler.AddToListVar('CFLAGS', '-Werror')
self.compiler.AddToListVar('CFLAGS', '-Wno-uninitialized')
self.compiler.AddToListVar('CFLAGS', '-Wno-unused')
self.compiler.AddToListVar('CFLAGS', '-Wno-switch')
self.compiler.AddToListVar('CFLAGS', '-mfpmath=sse')
self.compiler.AddToListVar('CFLAGS', '-msse')
self.compiler.AddToListVar('CFLAGS', '-m32')
self.compiler.AddToListVar('CFLAGS', '-static-libgcc')
self.compiler.AddToListVar('CXXFLAGS', '-fno-exceptions')
self.compiler.AddToListVar('CXXFLAGS', '-fno-rtti')
self.compiler.AddToListVar('CXXFLAGS', '-fno-threadsafe-statics')
self.compiler.AddToListVar('CXXFLAGS', '-Wno-non-virtual-dtor')
self.compiler.AddToListVar('CDEFINES', 'HAVE_STDINT_H')
elif isinstance(cxx, Cpp.MSVC):
self.vendor = 'msvc'
if AMBuild.options.debug == '1':
self.compiler.AddToListVar('CFLAGS', '/MTd')
self.compiler.AddToListVar('POSTLINKFLAGS', '/NODEFAULTLIB:libcmt')
else:
self.compiler.AddToListVar('CFLAGS', '/MT')
self.compiler.AddToListVar('CDEFINES', '_CRT_SECURE_NO_DEPRECATE')
self.compiler.AddToListVar('CDEFINES', '_CRT_SECURE_NO_WARNINGS')
self.compiler.AddToListVar('CDEFINES', '_CRT_NONSTDC_NO_DEPRECATE')
self.compiler.AddToListVar('CXXFLAGS', '/EHsc')
self.compiler.AddToListVar('CXXFLAGS', '/GR-')
self.compiler.AddToListVar('CFLAGS', '/W3')
self.compiler.AddToListVar('CFLAGS', '/nologo')
self.compiler.AddToListVar('CFLAGS', '/Zi')
self.compiler.AddToListVar('CXXFLAGS', '/TP')
self.compiler.AddToListVar('POSTLINKFLAGS', '/DEBUG')
self.compiler.AddToListVar('POSTLINKFLAGS', '/MACHINE:X86')
self.compiler.AddToListVar('POSTLINKFLAGS', '/SUBSYSTEM:WINDOWS')
self.compiler.AddToListVar('POSTLINKFLAGS', 'kernel32.lib')
self.compiler.AddToListVar('POSTLINKFLAGS', 'user32.lib')
self.compiler.AddToListVar('POSTLINKFLAGS', 'gdi32.lib')
self.compiler.AddToListVar('POSTLINKFLAGS', 'winspool.lib')
self.compiler.AddToListVar('POSTLINKFLAGS', 'comdlg32.lib')
self.compiler.AddToListVar('POSTLINKFLAGS', 'advapi32.lib')
self.compiler.AddToListVar('POSTLINKFLAGS', 'shell32.lib')
self.compiler.AddToListVar('POSTLINKFLAGS', 'ole32.lib')
self.compiler.AddToListVar('POSTLINKFLAGS', 'oleaut32.lib')
self.compiler.AddToListVar('POSTLINKFLAGS', 'uuid.lib')
self.compiler.AddToListVar('POSTLINKFLAGS', 'odbc32.lib')
self.compiler.AddToListVar('POSTLINKFLAGS', 'odbccp32.lib')
#Optimization
if AMBuild.options.opt == '1':
self.compiler.AddToListVar('CDEFINES', 'NDEBUG')
if self.vendor == 'gcc':
self.compiler.AddToListVar('CFLAGS', '-O3')
elif self.vendor == 'msvc':
self.compiler.AddToListVar('CFLAGS', '/Ox')
self.compiler.AddToListVar('POSTLINKFLAGS', '/OPT:ICF')
self.compiler.AddToListVar('POSTLINKFLAGS', '/OPT:REF')
#Debugging
if AMBuild.options.debug == '1':
self.compiler.AddToListVar('CDEFINES', 'DEBUG')
self.compiler.AddToListVar('CDEFINES', '_DEBUG')
if self.vendor == 'gcc':
self.compiler.AddToListVar('CFLAGS', '-g3')
elif self.vendor == 'msvc':
self.compiler.AddToListVar('CFLAGS', '/Od')
self.compiler.AddToListVar('CFLAGS', '/RTC1')
#Platform-specifics
if AMBuild.target['platform'] == 'linux':
self.compiler.AddToListVar('CDEFINES', '_LINUX')
elif AMBuild.target['platform'] == 'windows':
self.compiler.AddToListVar('CDEFINES', 'WIN32')
self.compiler.AddToListVar('CDEFINES', '_WINDOWS')
#Finish up
self.compiler.AddToListVar('CDEFINES', 'SOURCEMOD_BUILD')
self.compiler.AddToListVar('CDEFINES', 'SM_GENERATED_BUILD')
self.compiler.AddToListVar('CINCLUDES',
os.path.join(AMBuild.outputFolder, 'includes'))
self.compiler.ToConfig(AMBuild, 'compiler')
AMBuild.cache.CacheVariable('vendor', self.vendor)
self.targetMap = { }
AMBuild.cache.CacheVariable('targetMap', self.targetMap)
else:
self.compiler.FromConfig(AMBuild, 'compiler')
self.targetMap = AMBuild.cache['targetMap']
if AMBuild.target['platform'] == 'windows':
self.compiler.AddToListVar('RCINCLUDES', os.path.join(AMBuild.sourceFolder, 'public'))
self.compiler.AddToListVar('RCINCLUDES',
os.path.join(AMBuild.outputFolder, 'includes'))
self.mmsPath = AMBuild.cache['MMSOURCE18']
def DefaultCompiler(self):
return self.compiler.Clone()
def JobMatters(self, jobname):
file = sys._getframe().f_code.co_filename
if AMBuild.mode == 'config':
self.targetMap[jobname] = file
return True
if len(AMBuild.args) == 0:
return True
if not jobname in AMBuild.args:
return False
def DefaultExtCompiler(self, path):
compiler = self.DefaultCompiler()
compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, path))
compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, path, 'sdk'))
compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, 'public'))
compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, 'public', 'extensions'))
compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, 'public', 'sourcepawn'))
return compiler
def AutoVersion(self, folder, binary):
if AMBuild.target['platform'] != 'windows':
return
env = {'RCDEFINES': ['BINARY_NAME="' + binary.binaryFile + '"', 'SM_GENERATED_BUILD']}
binary.AddResourceFile(os.path.join(folder, 'version.rc' ), env)
def PreSetupHL2Job(self, job, builder, sdk):
info = self.sdkInfo[sdk]
sdkPath = AMBuild.cache[info['sdk']]
if AMBuild.target['platform'] == 'linux':
if sdk == 'ep1':
staticLibs = os.path.join(sdkPath, 'linux_sdk')
else:
staticLibs = os.path.join(sdkPath, 'lib', 'linux')
workFolder = os.path.join(AMBuild.outputFolder, job.workFolder)
if sdk == 'ep2v' or sdk == 'l4d2':
for i in ['tier1_i486.a', 'mathlib_i486.a', 'libvstdlib.so', 'libtier0.so']:
link = os.path.join(workFolder, i)
target = os.path.join(staticLibs, i)
try:
os.lstat(link)
except:
job.AddCommand(SymlinkCommand(link, target))
else:
for i in ['tier1_i486.a', 'mathlib_i486.a', 'vstdlib_i486.so', 'tier0_i486.so']:
link = os.path.join(workFolder, i)
target = os.path.join(staticLibs, i)
try:
os.lstat(link)
except:
job.AddCommand(SymlinkCommand(link, target))
elif AMBuild.target['platform'] == 'windows':
libs = ['tier0', 'tier1', 'vstdlib', 'mathlib']
if sdk == 'swarm':
libs.append('interfaces')
for lib in libs:
libPath = os.path.join(sdkPath, 'lib', 'public', lib) + '.lib'
builder.RebuildIfNewer(libPath)
builder['POSTLINKFLAGS'].append(libPath)
def PostSetupHL2Job(self, job, builder, sdk):
if AMBuild.target['platform'] == 'linux':
builder.AddObjectFiles(['tier1_i486.a', 'mathlib_i486.a'])
def DefaultHL2Compiler(self, path, sdk, noLink = False, oldMms = '-legacy'):
compiler = self.DefaultExtCompiler(path)
mms = 'core'
if sdk == 'ep1':
mms += oldMms
compiler['CXXINCLUDES'].append(os.path.join(self.mmsPath, mms))
compiler['CXXINCLUDES'].append(os.path.join(self.mmsPath, mms, 'sourcehook'))
info = self.sdkInfo
compiler['CDEFINES'].extend(['SE_' + info[i]['name'] + '=' + info[i]['def'] for i in info])
if AMBuild.target['platform'] != 'windows':
compiler['CDEFINES'].extend(['SE_DARKMESSIAH=2', 'SE_ALIENSWARM=7'])
paths = [['public'], ['public', 'engine'], ['public', 'mathlib'], ['public', 'vstdlib'],
['public', 'tier0'], ['public', 'tier1']]
if sdk == 'ep1' or sdk == 'darkm':
paths.append(['public', 'dlls'])
paths.append(['game_shared'])
else:
paths.append(['public', 'game', 'server'])
paths.append(['game', 'shared'])
paths.append(['common'])
info = self.sdkInfo[sdk]
sdkPath = AMBuild.cache[info['sdk']]
compiler['CDEFINES'].append('SOURCE_ENGINE=' + info['def'])
if sdk == 'swarm' and AMBuild.target['platform'] == 'windows':
compiler['CDEFINES'].extend(['COMPILER_MSVC', 'COMPILER_MSVC32'])
if sdk == 'ep1':
if AMBuild.target['platform'] == 'linux':
staticLibs = os.path.join(sdkPath, 'linux_sdk')
else:
if AMBuild.target['platform'] == 'linux':
staticLibs = os.path.join(sdkPath, 'lib', 'linux')
for i in paths:
compiler['CXXINCLUDES'].append(os.path.join(sdkPath, *i))
if not noLink:
if AMBuild.target['platform'] == 'linux':
compiler['POSTLINKFLAGS'][0:0] = ['-lm']
if sdk == 'ep2v' or sdk == 'l4d2':
compiler['POSTLINKFLAGS'][0:0] = ['libtier0.so']
compiler['POSTLINKFLAGS'][0:0] = ['libvstdlib.so']
else:
compiler['POSTLINKFLAGS'][0:0] = ['tier0_i486.so']
compiler['POSTLINKFLAGS'][0:0] = ['vstdlib_i486.so']
return compiler
sm = SM()
globals = {
'SM': sm
}
AMBuild.Include(os.path.join('tools', 'buildbot', 'Versioning'), globals)
FileList = [
['loader', 'AMBuilder'],
['core', 'AMBuilder'],
['core', 'logic', 'AMBuilder'],
['extensions', 'bintools', 'AMBuilder'],
['extensions', 'clientprefs', 'AMBuilder'],
['extensions', 'cstrike', 'AMBuilder'],
['extensions', 'curl', 'AMBuilder'],
['extensions', 'geoip', 'AMBuilder'],
['extensions', 'mysql', 'AMBuilder'],
['extensions', 'sdktools', 'AMBuilder'],
['extensions', 'topmenus', 'AMBuilder'],
['extensions', 'updater', 'AMBuilder'],
['extensions', 'sqlite', 'AMBuilder'],
['extensions', 'regex', 'AMBuilder'],
['extensions', 'tf2', 'AMBuilder'],
['sourcepawn', 'jit', 'AMBuilder'],
['sourcepawn', 'compiler', 'AMBuilder'],
['plugins', 'AMBuilder'],
['tools', 'buildbot', 'PackageScript']
]
for parts in FileList:
AMBuild.Include(os.path.join(*parts), globals)
+18 -3
View File
@@ -1,6 +1,21 @@
We now use svn:keywords "Id" on all .c/.cpp/.h/.sp/.inc files. Please make sure your client is configured properly.
CONFIGURE YOUR IDENTITY FOR MERCURIAL! WINDOWS:
IF YOU ARE A DEVELOPER WITH PUSH ACCESS, DO IT NOW KPLZTHX. Open your Application Data folder.
Windows XP/2000: C:\Documents and Settings\<user>\Application Data
Windows Vista: C:\Users\<user>\AppData\Roaming
http://wiki.alliedmods.net/Mercurial_Tutorial#Identity Now go to Subversion. Open the "config" file with a text editor.
LINUX:
Open ~/.subversion/config with your favorite text editor.
Under [miscellany], uncomment this line:
# enable-auto-props = yes
Under [auto-props], add these lines:
*.c = svn:keywords=Id
*.cpp = svn:keywords=Id
*.h = svn:keywords=Id
*.sp = svn:keywords=Id
*.inc = svn:keywords=Id
-458
View File
@@ -1,458 +0,0 @@
SourceMod Changelog
----------------------------
SourceMod 1.3.5 [2010-10-17]
URL: http://wiki.alliedmods.net/SourceMod_1.3.5_Release_Notes
User Changes:
- Updated support for CS:S, Garry's Mod, DoD:S, TF2, HL2DM.
- Added support for Firearms: Source (bug 4537).
- Added support for Fistful of Frags (bug 3883).
- Added support for Alien Swarm (bug 4530).
- Fixed living players hearing dead players if alltalk is disabled while deadtalk is on (bug 4533, thanks Zach Callear).
- Fixed timeleft not getting reset on Game_Commencing in CS:S (bug 4557).
- Fixed PlayerRunCmd being hooked when not used (bug 3990).
- Fixed errors and missing effects caused by missing sprites on L4D2 (bug 4512).
- Fixed 'sm plugins' public command skipping plugins in recommended listing (bug 4501).
- Fixed corruption with large database.cfg files (bug 4286).
Developer Changes:
- Added TF2 object stocks (bug 4536).
- Added TF2_MakeBleed native to TF2 ext (bug 4542).
- Added support for logical entities in Synergy (bug 4534).
- Updated TF2 conditions enum and defines (bug 4526).
- Fixed potential crash with IMemUtils::FindPattern on Linux (bug 4554).
----------------------------
SourceMod 1.3.4 [2010-07-18]
URL: http://wiki.alliedmods.net/SourceMod_1.3.4_Release_Notes
User Changes:
- Support for latest TF update (bug 4506).
- Support for latest L4D2 update (bug 4509).
Developer Changes:
- Added FindFlagChar native (bug 3776).
- Added GetConVarDefault native (bug 4502).
- Added forward for TF's GetHoliday function (bug 4462).
----------------------------
SourceMod 1.3.3 [2010-06-23]
URL: http://wiki.alliedmods.net/SourceMod_1.3.3_Release_Notes
User Changes:
- Added support for CS:S on Orange Box
- Added gamedata for Resistance and Liberation (bug 4418).
- Updated gamedata for SourceForts, Empires, Obsidian Conflict, Zombie Master.
- Fixed memory corruption and leaks with some voice functionality (bug 4415).
- Fixed UI bug in sm_motd (bug 4460).
Developer Changes:
- Added new player condition (TFCond_CritCola, bug 4447).
- Fixed clientprefs deleting cookies twice in rare cases (bug 4412).
- Fixed OnClientConnected forward not firing for bots (bug 4443).
- Fixed sm_dump_datamaps crash (bug 4424).
- Fixed switch case comparisons failing with large numbers (bug 4457).
- Fixed rare crash in output hooks (bug 4422).
- Fixed bug with dynamically sized arrays being sliced (bug 4428).
- Fixed SendConVarValue() on TF2, DOD:S, L4D, and L4D2 (bug 4273).
- Fixed TF2 natives not being marked optional (bug 4389).
----------------------------
SourceMod 1.3.2 [2010-05-02]
URL: http://wiki.alliedmods.net/SourceMod_1.3.2_Release_Notes
User Changes:
- Support for recent TF, DoD, and L4D2 updates (bug 4356, bug 4361, bug 4371, bug 4374, bug 4375).
- Fixed rare crash when replicating cvars to clients (bug 4315).
- Lots of extra game support for Insurgency, ZPS, CSProMod, PVKII, and FortressForever (thanks
Nicholas "psychonic" hastings).
Developer Changes:
- Added TF functions for stunning, conditions, regeneration, and power play (bug 4166, bug 4331).
----------------------------
SourceMod 1.3.1 [2010-02-09]
URL: http://wiki.alliedmods.net/SourceMod_1.3.1_Release_Notes
User Changes:
- Added extended support for CSProMod (bug 4255).
- Fixed client disconnect crash on many third party games (bug 4231).
- Improved support for Battlegrounds 2 (bug 4146).
- Improved support for Insurgency (bug 4180).
- Improved support for Garry's Mod (bug 4230, bug 4268).
- Improved support for Synergy (bug 4235).
- Updated Day of Defeat support for 20010123 update (bug 4262).
- Fixed Webternet extension not loading on Windows 2000 (bug 4234).
Developer Changes:
- Fixed compiler complaints when using |any| tag on array arguments (bug 4274).
- Fixed GetClientCookieTime not being exported (bug 4237).
- Fixed potential crash in entity handling code (bug 4249).
----------------------------
SourceMod 1.3.0 [2010-01-15]
URL: http://wiki.alliedmods.net/SourceMod_1.3.0_Release_Notes
Major Features:
* Left 4 Dead 2 support
* Non-networked entity support
User Changes:
- Added Left 4 Dead 2 support (bug 4075).
- Added much richer voting progress feedback (bug 1997).
- Improved support for various third-party games (Nicholas "psychonic" Hastings).
- Added @spec target (bug 2718).
- Added sm_resetcvar command (bug 3636).
- Added "motd" chat trigger (bug 2694).
- Updated GeoIP to OCT-2009.
- Fixed rare map vote error (bug 3905).
- Fixed small leak in the nominations plugin (bug 4104).
- Fixed last client being excluded from some command effects (bug 3984).
- Fixed crashes in plugin [|un|re]loading (bug 4034, bug 4038, bug 4044, bug 4153).
- Special target "@me" is now filtered for certain statuses properly (bug 4000).
- Improved non-admin to admin chat (bug 3844).
- Removed "auto.*" extension folders (bug 3949).
Developer Changes:
- Added non-networked entity support (bug 2459).
- Added improved random number generator (bug 3831).
- Added GetClientCookieTime native (bug 3736).
- Added AskPluginLoad2 callback (bug 3716).
- Added PlayerRunCmd callback (bug 3289).
- Added PointOutsideWorld native (bug 3906).
- Added API for "blanket" command hooks (bug 4015).
- Added ability to test for SourceMod features (bug 4021).
- Added ability to change broadcast status on hooked events (bug 3886).
- OnClientCommand no longer receives unconnected clients (bug 3732).
- Fixed various bugs in client listening API (bug 3818).
- Fixed crash in BanClient (bug 3912).
- Fixed various crashes in self-removing callbacks (bug 4059).
- Fixed rare HUD text crash on TF (bug 4016).
- Fixed OnConfigsExecuted not running on EP1 games with large configs (bug 3828).
- Fixed entity output hooks not working (bug 3988).
- Gamedata folder matches are now case-insensitive (bug 3913).
- Blocked plugins from hooking "sm" command (bug 4013).
----------------------------
SourceMod 1.2.4 [2009-10-03]
URL: http://wiki.alliedmods.net/SourceMod_1.2.4_Release_Notes
- Updated for L4D changes (bugs 4032, 4033, 4035).
- Updated GeoLite Country database for GeoIP extension.
- Fixed crash when block-loading more than eight plugins (bug 4034).
- Fixed rare crash in hudtext code on TF (bug 4016).
- Fixed crash when reloading a blocked plugin failed (bug 4038).
- Fixed Huntsman not firing critical callback on TF (bug 3927).
- Registering the "sm" command no longer has any effect (bug 4013).
- Fixed translation bug in extension API (bug 4010).
----------------------------
SourceMod 1.2.3 [2009-08-28]
URL: http://wiki.alliedmods.net/SourceMod_1.2.3_Release_Notes
- Fix extension filename lookup. (bug 3975).
----------------------------
SourceMod 1.2.2 [2009-08-28]
URL: http://wiki.alliedmods.net/SourceMod_1.2.2_Release_Notes
- Removed auto folders. (bug 3949).
- Added PointOutsideWorld native to sdktools. (bug 3906).
- Added "motd" chat trigger to basetriggers. (bug 2694).
- Added manual extension reloading command to root console menu. (bug 3934)
- Fixed 'list' type custom menu entries overwriting admin restrictions. (bug 3783).
- Added sm_resetcvar command to basecommands. (bug 3636).
- Updated gamedata for DOD:S. (bug 3948).
- Updated gamedata for TF2. (bug 3948).
- Added new .ep2v build config for valve OB based games. (bug 3948).
- Fixed incorrect escaping in clientprefs SQLite queries. (bug 3904)
- Updated gamedata for Synergy. (bug 3315).
- Upgraded to pcre-7.9 (bug 3923).
- Switched Insurgency chat printing to SayText. (bug 3738).
- Updated gamedata for Insurgency. (bug 3511).
- Updated gamedata for ZM. (bug 3746).
- Updated gamedata for Empires. (bug 3500).
- Updated gamedata for ZPS. (bug 3877).
- Updated gamedata for AoC. (bug 3891).
- Fixed RemovePlayerDisguise signature for TF2. (bug 3892).
----------------------------
SourceMod 1.2.1 [2009-05-31]
URL: http://wiki.alliedmods.net/SourceMod_1.2.1_Release_Notes
- Updated SDKTools for latest Team Fortress update.
- Added L4D handling to GuessSDKVersion() (bug 3842).
- Updated Zombie Panic Source offsets (bug 3632).
- Fixed crash when clientprefs saw disconnect from 64th client (bug 3821).
- Fixed Plugin_Handled acting like a Stop in usermsg hooks (bug 3685).
- Fixed early tv_enable causing crashes (bug 3766).
- Fixed unhook event crash (bug 3814).
- Fixed compiler reading uninitialized strings while processing varargs (bug 3811).
- Fixed compiler choosing whether to emit stradjust.pri on dynamic arrays based on uninitialized memory (bug 3810).
- Fixed Windows L4D CreateFakeClient signature (bug 3792).
- Fixed sm_slap for EP1 games (bug 3768).
- Fixed casting problems in TextParsers breaking TrimString for non-ASCII characters (bug 3800).
- Fixed OnClientConnect rejectmsg handling, improved doc (bug 3690).
- Fixed clientprefs not loading cookies for clients on late load (bug 3735).
- Fixed GetCommandFlags on original engine games (bug 3759).
- Fixed compiler asserting when returning a string literal (bug 3836).
- Fixed compiler erroring when tagging functions for string return (bug 3837).
- Fixed compiler not handling constant chained relational operators correctly (bug 3838).
- Fixed revote bug and inflexibilities in RedrawClientVoteMenu (bug 3834).
- Fixed auto update URL being set too late (bug 3699).
- Disabled nextmap in Synergy and Dystopia (bug 3687, bug 3741).
- Removed unnecessary SSE optimizations from msvc9 project files (bug 3756).
- Removed short-lived tag system (bug 3751).
- Removed the alive check from sm_rename. (bug 3698).
- Switched FortressForever to Valve menus (bug 3819).
----------------------------
SourceMod 1.2.0 [2009-03-05]
URL: http://wiki.alliedmods.net/SourceMod_1.2.0_Release_Notes
Major Features:
* Left 4 Dead Support
* Dark Messiah Support
* New and Improved Updater
Changes:
- Added Left 4 Dead support (bug 3414).
- Added Dark Messiah game support (requires Metamod:Source 1.7.1 or higher).
- Added sm_name command (bug 2150).
- Added extension-level dynamic hooking to bintools (bug 2616).
- Added client validation API to replace passing userids asynchronously.
- Added cURL extension, available to other extensions (bug 3560).
- Added parsing of custom gamedata files (bug 3644).
- Added case insensitivity search to ReplaceString (bug 3639, Fyren).
- Added more detail to certain player-oriented menu titles (bug 2740, Fyren).
- Added sv_tags API (bug 3677).
- Greatly improved admin-sql-prefetch performance for large tables (bug 3354, FLOOR_MASTER).
- Exposed IServer address to extensions (bug 3545).
- New gamedata organization; files are now smaller and per-game (bug 3546).
- Split sound functions into a new plugin, sounds.smx.
- Fixed slap and slay on Insurgency (bug 2560).
- Fixed blank admins being created from invalid admin file lines (bug 3431).
- Fixed basetriggers not working on Insurgency (bug 3497).
- Fixed client preferences missing some clients (bug 3616).
- Improved database fallback mechanism in clientprefs (bug 3564).
- Improved timer handling in funcommands (bug 3498).
- Improved compile.sh to take filenames (bug 3550, jonasfietz).
- sm_kick now shows the kick reason when available.
- Fixed MsgPostHook (ex MsgSentNotify) callbacks not firing on intercept hook (bug 3631).
- Note: SourceMod now adds "sourcemod" to the sv_tags cvar.
----------------------------
SourceMod 1.1.2 [2009-02-26]
URL: http://wiki.alliedmods.net/SourceMod_1.1.2_Release_Notes
Changes:
- Fixed critical hits being permanently disabled (bug 2674)
----------------------------
SourceMod 1.1.1 [2009-02-25]
URL: http://wiki.alliedmods.net/SourceMod_1.1.1_Release_Notes
Changes:
- Added Age of Chivalry support (bug 3366, IceMatrix).
- Added Obsidian Conflict support (bug 2699, The DOO).
- Fixed compatibility issues with latest TF2 update.
- Fixed crash when an event handler fired an event of the same name (bug 3468).
- Fixed rare crash in the event manager on post hooks (bug 3548).
- Fixed formatting error with zero precision floats (bug 3447).
- Fixed various Insurgency offsets (bug 3544).
- Fixed admin menu (topmenu) categories being selectable when not usable (bug 3256).
- Fixed sm_sql_addgroup not working (bug 3578).
- Fixed memory leak when events were hooked as EventHookMode_Post.
- Fixed nextmap trigger showing wrong output with end-of-map voting disabled and sm_trigger_show set to zero (bug 3597, mr.e.unk).
----------------------------
SourceMod 1.1.0 [2008-12-28]
URL: http://wiki.alliedmods.net/SourceMod_1.1.0_Release_Notes
Major features:
* New map management plugins.
* New reserved slot type.
* GameData updates are retrieved remotely
* Client Preferences extension for per-client "cookies"
* New incremental and independent JIT
Changes:
- Added new client preferences extension (API in clientprefs.inc, bug 1925).
- Added new gamedata auto-update functionality (bug 2602).
- Revamped and greatly expanded map management plugins and their functionality (bug 2201).
- Debug mode is now always on; as there is no longer a performance loss, there is no non-debug mode.
- The timeleft trigger can now handle mp_winlimit, mp_fraglimit, and mp_maxrounds (bug 2344).
- Translations can now be in separate files and placed in language-unique folders.
- The leading "STEAM_0:" or "STEAM_1:" in SteamIDs can now be omitted from admin files.
- Added sm_revote command so clients can participate in a vote that fell off their screen (bug 2156).
- Added Core API for creating stack structures (adt_stack.inc, bug 2441).
- Added API for extending mapchooser (mapchooser.inc, bug 2201).
- Added Core API for map transition control and history (nextmap.inc).
- Added TF2 forward for overriding how critical hits are calculated.
- Added SetClientInfo() native for modifying how a server sees a client's setinfo properties.
- Added CreateDirectory() native (bug 3253).
- Added "magic" MaxClients variable to replace slower GetMaxClients() call.
- Added support for three-letter language codes (bug 3526).
- Functions to control client versus client mic listening now work as described (bug 2498).
- Fixed SDKTools not being reloadable, and fixed a related bug in Handle type removal (bug 2753).
- Rewrote internal translation handling. Extensions now have access to an ITranslator API (bug 2535).
- Rewrote internal handling of dependencies (especially relating to native providers) (bug 2466).
- Added user config hooks to IGameConfigManager, for parsing user-defined sections.
- Revamped SourcePawn API. Removed and deprecated many structures and functions accidentally exposed publicly.
- Revamped SourcePawn structure, it is now separable from SourceMod for other projects.
- Renamed basefuncommands.phrases.txt to funcommands.phrases.txt (bug 2485).
- Renamed basefunvotes.phrases.txt to funvotes.phrases.txt (bug 2485).
- Added IDBDriver API call for extensions to handle IDBDriver dependencies properly.
- Usermessage natives now validate clients to prevent crashing.
- Fixed OnConfigsExecuted not working on listen servers.
- Fixed out-of-handle conditions in CreateTimer() causing crashes (bug 3381).
- Fixed accessing invalid Handles causing crashes (bug 3359).
- Fixed memory corruption with MySQL + FetchString (bug 3352).
- Fixed ReadFileString ignoring its fourth parameter (bug 3459).
- Fixed sm_sql_addadmin reading the immunity field as a password (bug 3395).
- Fixed ReadFile sign-extending instead of zero-extending (bug 3449).
----------------------------
SourceMod 1.0.4 [2008-09-14]
Changes:
- Fixed amb1986: Format() with very long strings could crash if the input and output buffers overlapped.
- Fixed amb1938: The compiler ate too many characters in preprocessor macros.
- Fixed amb1935: Topmenu child names were not uncached when a category was deleted.
- Fixed amb1929: Banning via the console threw a runtime error.
- Fixed amb1918: Ban menu should compare userids, not client indexes
- Fixed amb1916: Threaded query delay is now 50ms instead of 500ms.
- Fixed amb1899: Duplicate maps in auto generated maplists.
- Fixed amb1891: Basechat didn't check for blank message in private says.
- Fixed amb1853: Ternary operators with string assignments could chop strings off.
- Fixed amb1815: Custom admin menu wasn't escaping input.
- Fixed amb1808: KickClient() is now delayed to prevent crashes, use KickClientEx for old functionality.
- Fixed amb1802: Possible crash when a client disconnected.
- Fixed amb1801: Improved bot detection, and fixed bots crashing if inside an OrangeBox server.cfg.
- Fixed amb1780: admin-sql-threaded had a debug spew turned on.
- Fixed amb1779: Crash in GetTeamName() on mods that don't support it.
- Fixed amb1763: Function call status is now cleared on a new function call.
- Fixed amb1749: Updated and improved DoD:S SDKTools coverage.
- Fixed team native crashes in SDKTools for mods like Insurgency.
- Fixed various file handle leaks.
----------------------------
SourceMod 1.0.3 [2008-06-21]
Changes:
- Fixed SDKTools compatibility for latest TF2 update.
- Fixed amb1750: OnAutoConfigsBuffered() inserted before "exec server.cfg".
- Fixed a logic bug where OnConfigsExecuted() could be executed before "exec server.cfg" finished.
- Fixed a rare crash in the event manager that manifested on Zombie Panic! Source.
----------------------------
SourceMod 1.0.2 [2008-05-31]
Changes:
- The admin menu is now user-modifiable (the "Dynamic Admin Menu").
- Added a TF2 extension with Team Fortress functions.
- Added a RegEx extension with regular expression functions.
- Added functions to SDKTools for hooking entity outputs.
- Added preliminary support for the DoD:S Orange Box beta.
- Added a forward for map config plugins for preventing race conditions.
- Added a %b format specifier for binary printing.
- Added sm_dump_datamaps command (SDKTools) for enumerating datamap properties.
- Added sm_dump_admcache command for debugging the admin cache.
- Added amb1715 - TraceHull functions to SDKTools (complementing TraceRay).
- Added amb1694 - FindCharInString() function.
- Added amb1685 - GetTickInterval() function.
- Added amb1620 - ActivateEntity() function to SDKTools (for Orange Box particle system).
- Added amb1610 - StripQuotes() function.
- Added amb1558 - Compiler now has __BINARY_PATH__ and __BINARY_FILE__ macros.
- Fixed amb1686 - ReplaceString* with an empty search string crashed; it now throws an error.
- Fixed amb1684 - Blank passwords required an empty but set password.
- Fixed amb1595 - Extension load failures did not show a platform error message.
- Fixed amb1583 - MySQL string fetch from prepared queries returned corrupted data.
- Fixed amb1358 - Timeleft did not reset on TF2 restarts.
- Fixed cases where the JIT was too cautious in space optimizations.
- Fixed TF2/Cstrike extensions being loadable on incompatible games.
- Fixed various documentation inconsistencies and typos.
- Fixed internal bugs with file extension handling.
Notes:
There is a possible compatibility regression from amb1684. SetAdminPassword()
has been modified to remove any set password when given an empty string. Previously,
a blank password ("") would force an admin to use "setinfo" to set an empty password,
but this functionality was deemed unuseful and unintended. Blank passwords now
remove any set password.
----------------------------
SourceMod 1.0.1 [2008-05-20]
Changes:
- Fixed SDKTools compatibility for latest TF2 update.
- Removed GivePlayerItem from TF2 (TF2 update broke functionality).
- Fixed amb1688: GivePlayerItem offset was wrong for DoD:S Linux.
- Fixed amb1657: Server console did not see admin version of sm_who.
- Fixed amb1648: Stack corruption from GetClientEyeAngles() on Windows.
- Fixed amb1646: NetFlow_Both did not work for client network statistics.
- Fixed amb1601: Vote FF menu reading from sv_alltalk cvar instead of mp_friendlyfire.
- Fixed amb1591: Fixed listen server crashes on mods like IOS:S which pre-add more than one bot.
- Fixed amb1586: GetTeamName() could crash the server if called on load.
- Fixed mapchooser's round counting for TF2.
- Fixed a bug where an RTE on plugin load would throw a message referring to the plugin as "-1".
- Symbols are no longer stripped on Linux.
- Minor SourceMod SDK fixes.
Notes:
The extension interface version has been bumped. Any extensions compiled against 1.0.1 will require 1.0.1 or higher to run. Extensions against 1.0.0 will continue to run normally.
-12
View File
@@ -1,12 +0,0 @@
// Custom admin menu commands.
// For more information:
//
// http://wiki.alliedmods.net/Custom_Admin_Menu_%28SourceMod%29
//
// Note: This file must be in Valve KeyValues format (no multiline comments)
//
"Commands"
{
}
-20
View File
@@ -1,20 +0,0 @@
/* Add group options to be added to 'group' or 'groupplayer' type submenus
* The left side is the name that will show in the menu, right is the command that will be fired
*
* For more information: http://wiki.alliedmods.net/Custom_Admin_Menu_%28SourceMod%29
*/
Groups
{
"All" "@all"
"Bots" "@bots"
"Alive" "@alive"
"Dead" "@dead"
"Humans" "@humans"
"Current aim" "@aim"
/* You can enable these if you are using Counter-Strike Source and running the cstrike extension */
// "Terrorists" "@t"
// "Counter-Terrorists" "@ct"
}
+3 -3
View File
@@ -16,7 +16,7 @@
// "@Full Admins" // "@Full Admins"
// //
// You can also specify immunity values. Two examples: // You can also specify immunity values. Two examples:
// "83:abcdefgh" //Immunity is 83, flags are abcdefgh // "83:abcdefg" //Immunity is 83, flags are abcefgh
// "6:@Full Admins" //Immunity is 6, group is "Full Admins" // "6:@Full Admins" //Immunity is 6, group is "Full Admins"
// //
// Immunity values can be any number. An admin cannot target an admin with // Immunity values can be any number. An admin cannot target an admin with
@@ -37,9 +37,9 @@
//////////////////////////////// ////////////////////////////////
// Examples: (do not put // in front of real lines, as // means 'comment') // Examples: (do not put // in front of real lines, as // means 'comment')
// //
// "STEAM_0:1:16" "bce" //generic, kick, unban for this steam ID, no immunity // "STEAM_0:1:16" "bce" //kick, ban, slay for this steam ID, no immunity
// "!127.0.0.1" "99:z" //all permissions for this ip, immunity value is 99 // "!127.0.0.1" "99:z" //all permissions for this ip, immunity value is 99
// "BAILOPAN" "abc" "Gab3n" //name BAILOPAN, password "Gab3n": gets reservation, generic, kick // "BAILOPAN" "abc" "Gab3n" //name BAILOPAN, password "Gab3n": gets reservation, kick, ban
// //
//////////////////////////////// ////////////////////////////////
-1
View File
@@ -1,7 +1,6 @@
//This file unloads all plugins, re-loads a few "safe" ones, and then prevents //This file unloads all plugins, re-loads a few "safe" ones, and then prevents
//any more plugins from being loaded. //any more plugins from being loaded.
sm plugins unload_all sm plugins unload_all
sm plugins load_unlock
sm plugins load basebans.smx sm plugins load basebans.smx
sm plugins load basecommands.smx sm plugins load basecommands.smx
sm plugins load admin-flatfile.smx sm plugins load admin-flatfile.smx
+3 -28
View File
@@ -80,21 +80,21 @@ sm_reserve_type 0
sm_reserved_slots 0 sm_reserved_slots 0
// Specifies whether or not reserved slots will be hidden (subtracted from max // Specifies whether or not reserved slots will be hidden (subtracted from max
// slot count). Valid values are 0 (Visible) or 1 (Hidden). // slot count). Valid values are 0 (visible) or 1 (hidden).
// -- // --
// Requires: reservedslots.smx // Requires: reservedslots.smx
// Default: 0 // Default: 0
sm_hide_slots 0 sm_hide_slots 0
// Specifies whether or not non-admins can send messages to admins using // Specifies whether or not non-admins can send messages to admins using
// say_team @<message>. Valid values are 0 (Disabled) or 1 (Enabled) // say_team @<message>. Valid values are 0 (disabled) or 1 (enabled)
// -- // --
// Requires: basechat.smx // Requires: basechat.smx
// Default: 1 // Default: 1
sm_chat_mode 1 sm_chat_mode 1
// Specifies whether or not "timeleft" will automaticly be triggered every // Specifies whether or not "timeleft" will automaticly be triggered every
// x seconds. Valid values are 0 (Disabled) to 1800 seconds. // x seconds. Valid values are 0 (disabled) to 1800 seconds.
// -- // --
// Requires: basetriggers.smx // Requires: basetriggers.smx
// Default: 0 // Default: 0
@@ -107,28 +107,3 @@ sm_timeleft_interval 0
// Requires: basetriggers.smx // Requires: basetriggers.smx
// Default: 1 // Default: 1
sm_trigger_show 1 sm_trigger_show 1
// Specifies whether or not to display vote progress to clients in the
// "hint" box (near the bottom of the screen in most games).
// Valid values are 0 (Disabled) or 1 (Enabled).
// --
// Default: 0
sm_vote_progress_hintbox 0
// Specifies whether or not to display vote progress to clients in the
// chat area. Valid values are 0 (Disabled) or 1 (Enabled).
// --
// Default: 0
sm_vote_progress_chat 0
// Specifies whether or not to display vote progress in the server console.
// Valid values are 0 (Disabled) or 1 (Enabled).
// --
// Default: 0
sm_vote_progress_console 0
// Specifies whether or not to display vote progress to clients in the
// client console. Valid values are 0 (Disabled) or 1 (Enabled).
// --
// Default: 0
sm_vote_progress_client_console 0
+8 -27
View File
@@ -4,6 +4,14 @@
*/ */
"Core" "Core"
{ {
/**
* Relative path to SourceMod's base directory. This is relative to the game/mod directory.
* Only change this if you have installed SourceMod in a non-default location.
*
* The default value is "addons/sourcemod"
*/
"BasePath" "addons/sourcemod"
/** /**
* This option determines if SourceMod logging is enabled. * This option determines if SourceMod logging is enabled.
* *
@@ -80,31 +88,4 @@
* "off" - Translate using default server's language * "off" - Translate using default server's language
*/ */
"AllowClLanguageVar" "On" "AllowClLanguageVar" "On"
/**
* Enables or Disables SourceMod's automatic gamedata updating.
*
* The default value is "no". A value of "yes" will block the Auto Updater.
*/
"DisableAutoUpdate" "no"
/**
* If set to yes, a successful gamedata update will attempt to restart SourceMod.
* SourceMod is unloaded and reloaded, and the map is changed to the current map.
* Since gamedata updates occur when the server loads, impact should be minimal.
* But to be safe, this option is disabled by default.
*/
"ForceRestartAfterUpdate" "no"
/**
* URL to use for retrieving update information.
* SSL is not yet supported.
*/
"AutoUpdateURL" "http://update.sourcemod.net/update/"
/**
* Whether to show debug spew.
* Currently this will log details about the gamedata updating process.
*/
"DebugSpew" "no"
} }
-11
View File
@@ -18,15 +18,4 @@
"driver" "sqlite" "driver" "sqlite"
"database" "sourcemod-local" "database" "sourcemod-local"
} }
"clientprefs"
{
"driver" "sqlite"
"host" "localhost"
"database" "clientprefs-sqlite"
"user" "root"
"pass" ""
//"timeout" "0"
//"port" "0"
}
} }
Binary file not shown.
+2
View File
@@ -1,4 +1,6 @@
"Languages" "Languages"
{ {
"en" "English" "en" "English"
"es" "Español"
} }
+2 -2
View File
@@ -51,8 +51,8 @@
"target" "default" "target" "default"
} }
/* For the "nominations" plugin */ /* For the "randomcycle" plugin */
"nominations" "rockthevote"
{ {
"target" "default" "target" "default"
} }
+4 -2
View File
@@ -6,13 +6,14 @@
* Available properties for plugins are: * Available properties for plugins are:
* "pause" - Whether or not the plugin should load paused - "yes" or "no" (default) * "pause" - Whether or not the plugin should load paused - "yes" or "no" (default)
* "lifetime" - Lifetime of the plugin. Options: * "lifetime" - Lifetime of the plugin. Options:
* "mapsync" - Plugins should be reloaded on mapchange if changed (default) * "mapsync" - Plugins should be reloaded on mapchange if changed (default)
* "global" - Plugin will never be unloaded or updated * "global" - Plugin will never be unloaded or updated
* "blockload" - Plugin will always be blocked from loading. Implicit (automatic) loads * "blockload" - Plugin will always be blocked from loading. Implicit (automatic) loads
* produce no error, but explicit (manual) loads will show an error message. * produce no error, but explicit (manual) loads will show an error message.
* (Options are one of "yes" or "no") * (Options are one of "yes" or "no")
* *
* You can also have an "Options" section declaring options to pass onto the JIT: * You can also have an "Options" section declaring options to pass onto the JIT:
* "debug" - Whether or not to load the plugin in debug mode
* "profile" - Bit flags for profiling level. Add flags together to reach a value. * "profile" - Bit flags for profiling level. Add flags together to reach a value.
* WARNING: Profiler is _ALPHA_ software! Use it at your own risk for * WARNING: Profiler is _ALPHA_ software! Use it at your own risk for
* development cycles only (not production setups). * development cycles only (not production setups).
@@ -31,6 +32,7 @@
"Options" "Options"
{ {
"debug" "no"
} }
} }
} }
@@ -1,17 +0,0 @@
CREATE TABLE sm_cookies
(
id INTEGER unsigned NOT NULL auto_increment,
name varchar(30) NOT NULL UNIQUE,
description varchar(255),
access INTEGER,
PRIMARY KEY (id)
);
CREATE TABLE sm_cookie_cache
(
player varchar(65) NOT NULL,
cookie_id int(10) NOT NULL,
value varchar(100),
timestamp int NOT NULL,
PRIMARY KEY (player, cookie_id)
);
@@ -1,16 +0,0 @@
CREATE TABLE sm_cookies
(
id INTEGER PRIMARY KEY AUTOINCREMENT,
name varchar(30) NOT NULL UNIQUE,
description varchar(255),
access INTEGER
);
CREATE TABLE sm_cookie_cache
(
player varchar(65) NOT NULL,
cookie_id int(10) NOT NULL,
value varchar(100),
timestamp int,
PRIMARY KEY (player, cookie_id)
);
-10
View File
@@ -1,10 +0,0 @@
# vim: set ts=2 sw=2 tw=99 noet:
import sys
import ambuild.runner as runner
run = runner.Runner()
run.options.add_option('--enable-debug', action='store_const', const='1', dest='debug',
help='Enable debugging symbols')
run.options.add_option('--enable-optimize', action='store_const', const='1', dest='opt',
help='Enable optimization')
run.Configure(sys.path[0])
+1 -1
View File
@@ -2,7 +2,7 @@
* vim: set ts=4 : * vim: set ts=4 :
* ============================================================================= * =============================================================================
* SourceMod * SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
* ============================================================================= * =============================================================================
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under
+1 -1
View File
@@ -2,7 +2,7 @@
* vim: set ts=4 : * vim: set ts=4 :
* ============================================================================= * =============================================================================
* SourceMod * SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
* ============================================================================= * =============================================================================
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under
-90
View File
@@ -1,90 +0,0 @@
# vim: set ts=2 sw=2 tw=99 noet ft=python:
import os
for i in SM.sdkInfo:
sdk = SM.sdkInfo[i]
name = 'sourcemod.' + sdk['ext']
compiler = SM.DefaultHL2Compiler('core', i)
extension = AMBuild.AddJob(name)
binary = Cpp.LibraryBuilder(name, AMBuild, extension, compiler)
SM.PreSetupHL2Job(extension, binary, i)
files = [
'AdminCache.cpp',
'ExtensionSys.cpp',
'MenuStyle_Valve.cpp',
'sm_crc32.cpp',
'logic_bridge.cpp',
'smn_entities.cpp',
'sm_stringutil.cpp',
'ADTFactory.cpp',
'ForwardSys.cpp',
'MenuVoting.cpp',
'sm_memtable.cpp',
'smn_events.cpp',
'smn_menus.cpp',
'sm_trie.cpp',
'CDataPack.cpp',
'frame_hooks.cpp',
'NativeInvoker.cpp',
'smn_admin.cpp',
'smn_fakenatives.cpp',
'smn_nextmap.cpp',
'sourcemm_api.cpp',
'ChatTriggers.cpp',
'GameConfigs.cpp',
'NativeOwner.cpp',
'smn_filesystem.cpp',
'smn_player.cpp',
'sourcemod.cpp',
'concmd_cleaner.cpp',
'HalfLife2.cpp',
'NextMap.cpp',
'smn_profiler.cpp',
'ConCmdManager.cpp',
'HandleSys.cpp',
'PhraseCollection.cpp',
'ConVarManager.cpp',
'LibrarySys.cpp',
'PlayerManager.cpp',
'smn_banning.cpp',
'smn_gameconfigs.cpp',
'smn_string.cpp',
'TimerSys.cpp',
'CoreConfig.cpp',
'Logger.cpp',
'PluginInfoDatabase.cpp',
'smn_bitbuffer.cpp',
'smn_halflife.cpp',
'Translator.cpp',
'MemoryUtils.cpp',
'PluginSys.cpp',
'smn_console.cpp',
'smn_handles.cpp',
'smn_timers.cpp',
'UserMessages.cpp',
'Database.cpp',
'MenuManager.cpp',
'smn_core.cpp',
'smn_hudtext.cpp',
'smn_usermsgs.cpp',
'DebugReporter.cpp',
'MenuStyle_Base.cpp',
'ShareSys.cpp',
'smn_database.cpp',
'smn_keyvalues.cpp',
'smn_vector.cpp',
'EventManager.cpp',
'MenuStyle_Radio.cpp',
'sm_autonatives.cpp',
'smn_datapacks.cpp',
'smn_lang.cpp',
'sm_srvcmds.cpp',
'ConsoleDetours.cpp'
]
binary.AddSourceFiles('core', files)
SM.PostSetupHL2Job(extension, binary, i)
SM.AutoVersion('core', binary)
binary.SendToJob()
+6 -372
View File
@@ -2,7 +2,7 @@
* vim: set ts=4 : * vim: set ts=4 :
* ============================================================================= * =============================================================================
* SourceMod * SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
* ============================================================================= * =============================================================================
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under
@@ -41,14 +41,12 @@
#include "sourcemod.h" #include "sourcemod.h"
#include "sm_stringutil.h" #include "sm_stringutil.h"
#include "sourcemm_api.h" #include "sourcemm_api.h"
#include "sm_srvcmds.h"
#define LEVEL_STATE_NONE 0 #define LEVEL_STATE_NONE 0
#define LEVEL_STATE_LEVELS 1 #define LEVEL_STATE_LEVELS 1
#define LEVEL_STATE_FLAGS 2 #define LEVEL_STATE_FLAGS 2
AdminCache g_Admins; AdminCache g_Admins;
char g_ReverseFlags[26];
AdminFlag g_FlagLetters[26]; AdminFlag g_FlagLetters[26];
bool g_FlagSet[26]; bool g_FlagSet[26];
@@ -162,6 +160,8 @@ private:
c -= (unsigned)'a'; c -= (unsigned)'a';
assert(c >= 0 && c < 26);
if (!g_Admins.FindFlag(key, &g_FlagLetters[c])) if (!g_Admins.FindFlag(key, &g_FlagLetters[c]))
{ {
ParseError(states, "Unrecognized admin level \"%s\"", key); ParseError(states, "Unrecognized admin level \"%s\"", key);
@@ -299,23 +299,8 @@ void AdminCache::OnSourceModAllInitialized()
void AdminCache::OnSourceModLevelChange(const char *mapName) void AdminCache::OnSourceModLevelChange(const char *mapName)
{ {
int i;
AdminFlag flag;
/* For now, we only read these once per level. */ /* For now, we only read these once per level. */
s_FlagReader.LoadLevels(); s_FlagReader.LoadLevels();
for (i = 0; i < 26; i++)
{
if (FindFlag('a' + i, &flag))
{
g_ReverseFlags[flag] = 'a' + i;
}
else
{
g_ReverseFlags[flag] = '?';
}
}
} }
void AdminCache::OnSourceModShutdown() void AdminCache::OnSourceModShutdown()
@@ -449,9 +434,7 @@ AdminId AdminCache::CreateAdmin(const char *name)
assert(pUser->magic == USR_MAGIC_UNSET); assert(pUser->magic == USR_MAGIC_UNSET);
id = m_FreeUserList; id = m_FreeUserList;
m_FreeUserList = pUser->next_user; m_FreeUserList = pUser->next_user;
} } else {
else
{
id = m_pMemory->CreateMem(sizeof(AdminUser), (void **)&pUser); id = m_pMemory->CreateMem(sizeof(AdminUser), (void **)&pUser);
pUser->grp_size = 0; pUser->grp_size = 0;
pUser->grp_table = -1; pUser->grp_table = -1;
@@ -471,28 +454,19 @@ AdminId AdminCache::CreateAdmin(const char *name)
{ {
m_FirstUser = id; m_FirstUser = id;
m_LastUser = id; m_LastUser = id;
} } else {
else
{
AdminUser *pPrev = (AdminUser *)m_pMemory->GetAddress(m_LastUser); AdminUser *pPrev = (AdminUser *)m_pMemory->GetAddress(m_LastUser);
pPrev->next_user = id; pPrev->next_user = id;
pUser->prev_user = m_LastUser; pUser->prev_user = m_LastUser;
m_LastUser = id; m_LastUser = id;
} }
/* Since we always append to the tail, we should invalidate their next */
pUser->next_user = -1;
if (name && name[0] != '\0') if (name && name[0] != '\0')
{ {
int nameidx = m_pStrings->AddString(name); int nameidx = m_pStrings->AddString(name);
pUser = (AdminUser *)m_pMemory->GetAddress(id); pUser = (AdminUser *)m_pMemory->GetAddress(id);
pUser->nameidx = nameidx; pUser->nameidx = nameidx;
} }
else
{
pUser->nameidx = -1;
}
return id; return id;
} }
@@ -1170,11 +1144,6 @@ bool AdminCache::GetMethodIndex(const char *name, unsigned int *_index)
bool AdminCache::BindAdminIdentity(AdminId id, const char *auth, const char *ident) bool AdminCache::BindAdminIdentity(AdminId id, const char *auth, const char *ident)
{ {
if (ident[0] == '\0')
{
return false;
}
AdminUser *pUser = (AdminUser *)m_pMemory->GetAddress(id); AdminUser *pUser = (AdminUser *)m_pMemory->GetAddress(id);
if (!pUser || pUser->magic != USR_MAGIC_SET) if (!pUser || pUser->magic != USR_MAGIC_SET)
{ {
@@ -1187,12 +1156,6 @@ bool AdminCache::BindAdminIdentity(AdminId id, const char *auth, const char *ide
return false; return false;
} }
/* If the id was a steam id strip off the STEAM_*: part */
if (strcmp(auth, "steam") == 0 && strncmp(ident, "STEAM_", 6) == 0)
{
ident += 8;
}
if (sm_trie_retrieve(pTable, ident, NULL)) if (sm_trie_retrieve(pTable, ident, NULL))
{ {
return false; return false;
@@ -1215,12 +1178,6 @@ AdminId AdminCache::FindAdminByIdentity(const char *auth, const char *identity)
return INVALID_ADMIN_ID; return INVALID_ADMIN_ID;
} }
/* If the id was a steam id strip off the STEAM_*: part */
if (strcmp(auth, "steam") == 0 && strncmp(identity, "STEAM_", 6) == 0)
{
identity += 8;
}
void *object; void *object;
if (!sm_trie_retrieve(pTable, identity, &object)) if (!sm_trie_retrieve(pTable, identity, &object))
{ {
@@ -1455,12 +1412,6 @@ void AdminCache::SetAdminPassword(AdminId id, const char *password)
return; return;
} }
if (password[0] == '\0')
{
pUser->password = -1;
return;
}
int i_password = m_pStrings->AddString(password); int i_password = m_pStrings->AddString(password);
pUser = (AdminUser *)m_pMemory->GetAddress(id); pUser = (AdminUser *)m_pMemory->GetAddress(id);
pUser->password = i_password; pUser->password = i_password;
@@ -1636,9 +1587,7 @@ bool AdminCache::CanAdminTarget(AdminId id, AdminId target)
bool AdminCache::FindFlag(char c, AdminFlag *pAdmFlag) bool AdminCache::FindFlag(char c, AdminFlag *pAdmFlag)
{ {
if (c < 'a' if (c < 'a' || c > 'z')
|| c > 'z'
|| !g_FlagSet[(unsigned)c - (unsigned)'a'])
{ {
return false; return false;
} }
@@ -1651,21 +1600,6 @@ bool AdminCache::FindFlag(char c, AdminFlag *pAdmFlag)
return true; return true;
} }
bool AdminCache::FindFlagChar(AdminFlag flag, char *c)
{
if (!g_FlagSet[flag])
{
return false;
}
if (c)
{
*c = g_ReverseFlags[flag];
}
return true;
}
FlagBits AdminCache::ReadFlagString(const char *flags, const char **end) FlagBits AdminCache::ReadFlagString(const char *flags, const char **end)
{ {
FlagBits bits = 0; FlagBits bits = 0;
@@ -1796,303 +1730,3 @@ bool AdminCache::CheckAccess(int client, const char *cmd, FlagBits flags, bool o
return g_ConCmds.CheckCommandAccess(client, cmd, bits) ? 1 : 0; return g_ConCmds.CheckCommandAccess(client, cmd, bits) ? 1 : 0;
} }
void iterator_glob_basic_override(Trie *pTrie, const char *key, void **value, void *data)
{
FILE *fp;
int flags;
char flagstr[64];
fp = (FILE *)data;
flags = (int)*value;
g_Admins.FillFlagString(flags, flagstr, sizeof(flagstr));
fprintf(fp, "\t\"%s\"\t\t\"%s\"\n", key, flagstr);
}
void iterator_glob_grp_override(Trie *pTrie, const char *key, void **value, void *data)
{
FILE *fp;
int flags;
char flagstr[64];
fp = (FILE *)data;
flags = (int)*value;
g_Admins.FillFlagString(flags, flagstr, sizeof(flagstr));
fprintf(fp, "\t\"@%s\"\t\t\"%s\"\n", key, flagstr);
}
void iterator_group_basic_override(Trie *pTrie, const char *key, void **value, void *data)
{
FILE *fp;
int flags;
char flagstr[64];
fp = (FILE *)data;
flags = (int)*value;
g_Admins.FillFlagString(flags, flagstr, sizeof(flagstr));
fprintf(fp, "\t\t\t\"%s\"\t\t\"%s\"\n", key, flagstr);
}
void iterator_group_grp_override(Trie *pTrie, const char *key, void **value, void *data)
{
FILE *fp;
int flags;
char flagstr[64];
fp = (FILE *)data;
flags = (int)*value;
g_Admins.FillFlagString(flags, flagstr, sizeof(flagstr));
fprintf(fp, "\t\t\t\"@%s\"\t\t\"%s\"\n", key, flagstr);
}
void AdminCache::DumpCache(FILE *fp)
{
int *itable;
AdminId aid;
GroupId gid;
char flagstr[64];
unsigned int num;
AdminUser *pAdmin;
AdminGroup *pGroup;
char name_buffer[512];
fprintf(fp, "\"Groups\"\n{\n");
num = 0;
gid = m_FirstGroup;
while (gid != INVALID_GROUP_ID
&& (pGroup = GetGroup(gid)) != NULL)
{
num++;
FillFlagString(pGroup->addflags, flagstr, sizeof(flagstr));
fprintf(fp, "\t/* num = %d, gid = 0x%X */\n", num, gid);
fprintf(fp, "\t\"%s\"\n\t{\n", GetString(pGroup->nameidx));
fprintf(fp, "\t\t\"flags\"\t\t\t\"%s\"\n", flagstr);
fprintf(fp, "\t\t\"immunity\"\t\t\"%d\"\n", pGroup->immunity_level);
if (pGroup->immune_table != -1
&& (itable = (int *)m_pMemory->GetAddress(pGroup->immune_table)) != NULL)
{
AdminGroup *pAltGroup;
const char *gname, *mod;
for (int i = 1; i <= itable[0]; i++)
{
if ((pAltGroup = GetGroup(itable[i])) == NULL)
{
/* Assume the rest of the table is corrupt */
break;
}
gname = GetString(pAltGroup->nameidx);
if (atoi(gname) != 0)
{
mod = "@";
}
else
{
mod = "";
}
fprintf(fp, "\t\t\"immunity\"\t\t\"%s%s\"\n", mod, gname);
}
}
fprintf(fp, "\n\t\t\"Overrides\"\n\t\t{\n");
if (pGroup->pCmdGrpTable != NULL)
{
sm_trie_bad_iterator(pGroup->pCmdGrpTable,
name_buffer,
sizeof(name_buffer),
iterator_group_grp_override,
fp);
}
if (pGroup->pCmdTable != NULL)
{
sm_trie_bad_iterator(pGroup->pCmdTable,
name_buffer,
sizeof(name_buffer),
iterator_group_basic_override,
fp);
}
fprintf(fp, "\t\t}\n");
fprintf(fp, "\t}\n");
if ((gid = pGroup->next_grp) != INVALID_GROUP_ID)
{
fprintf(fp, "\n");
}
}
fprintf(fp, "}\n\n");
fprintf(fp, "\"Admins\"\n{\n");
num = 0;
aid = m_FirstUser;
while (aid != INVALID_ADMIN_ID
&& (pAdmin = GetUser(aid)) != NULL)
{
num++;
FillFlagString(pAdmin->flags, flagstr, sizeof(flagstr));
fprintf(fp, "\t/* num = %d, aid = 0x%X, serialno = 0x%X*/\n", num, aid, pAdmin->serialchange);
if (pAdmin->nameidx != -1)
{
fprintf(fp, "\t\"%s\"\n\t{\n", GetString(pAdmin->nameidx));
}
else
{
fprintf(fp, "\t\"\"\n\t{\n");
}
if (pAdmin->auth.identidx != -1)
{
fprintf(fp, "\t\t\"auth\"\t\t\t\"%s\"\n", GetMethodName(pAdmin->auth.index));
fprintf(fp, "\t\t\"identity\"\t\t\"%s\"\n", GetString(pAdmin->auth.identidx));
}
if (pAdmin->password != -1)
{
fprintf(fp, "\t\t\"password\"\t\t\"%s\"\n", GetString(pAdmin->password));
}
fprintf(fp, "\t\t\"flags\"\t\t\t\"%s\"\n", flagstr);
fprintf(fp, "\t\t\"immunity\"\t\t\"%d\"\n", pAdmin->immunity_level);
if (pAdmin->grp_count != 0
&& pAdmin->grp_table != -1
&& (itable = (int *)m_pMemory->GetAddress(pAdmin->grp_table)) != NULL)
{
unsigned int i;
for (i = 0; i < pAdmin->grp_count; i++)
{
if ((pGroup = GetGroup(itable[i])) == NULL)
{
/* Assume the rest of the table is corrupt */
break;
}
fprintf(fp, "\t\t\"group\"\t\t\t\"%s\"\n", GetString(pGroup->nameidx));
}
}
fprintf(fp, "\t}\n");
if ((aid = pAdmin->next_user) != INVALID_ADMIN_ID)
{
fprintf(fp, "\n");
}
}
fprintf(fp, "}\n\n");
fprintf(fp, "\"Overrides\"\n{\n");
if (m_pCmdGrpOverrides != NULL)
{
sm_trie_bad_iterator(m_pCmdGrpOverrides,
name_buffer,
sizeof(name_buffer),
iterator_glob_grp_override,
fp);
}
if (m_pCmdOverrides != NULL)
{
sm_trie_bad_iterator(m_pCmdOverrides,
name_buffer,
sizeof(name_buffer),
iterator_glob_basic_override,
fp);
}
fprintf(fp, "}\n");
}
AdminGroup *AdminCache::GetGroup(GroupId gid)
{
AdminGroup *pGroup;
pGroup = (AdminGroup *)m_pMemory->GetAddress(gid);
if (!pGroup || pGroup->magic != GRP_MAGIC_SET)
{
return NULL;
}
return pGroup;
}
AdminUser *AdminCache::GetUser(AdminId aid)
{
AdminUser *pAdmin;
pAdmin = (AdminUser *)m_pMemory->GetAddress(aid);
if (!pAdmin || pAdmin->magic != USR_MAGIC_SET)
{
return NULL;
}
return pAdmin;
}
const char *AdminCache::GetMethodName(unsigned int index)
{
List<AuthMethod>::iterator iter;
for (iter=m_AuthMethods.begin();
iter!=m_AuthMethods.end();
iter++)
{
if (index-- == 0)
{
return (*iter).name.c_str();
}
}
return NULL;
}
const char *AdminCache::GetString(int idx)
{
return m_pStrings->GetString(idx);
}
size_t AdminCache::FillFlagString(FlagBits bits, char *buffer, size_t maxlen)
{
size_t pos;
unsigned int i, num_flags;
AdminFlag flags[AdminFlags_TOTAL];
num_flags = FlagBitsToArray(bits, flags, AdminFlags_TOTAL);
pos = 0;
for (i = 0; pos < maxlen && i < num_flags; i++)
{
if (FindFlagChar(flags[i], &buffer[pos]))
{
pos++;
}
}
buffer[pos] = '\0';
return pos;
}
CON_COMMAND(sm_dump_admcache, "Dumps the admin cache for debugging")
{
FILE *fp;
char buffer[PLATFORM_MAX_PATH];
g_SourceMod.BuildPath(Path_SM, buffer, sizeof(buffer), "data/admin_cache_dump.txt");
if ((fp = fopen(buffer, "wt")) == NULL)
{
g_RootMenu.ConsolePrint("Could not open file for writing: %s", buffer);
return;
}
g_Admins.DumpCache(fp);
g_RootMenu.ConsolePrint("Admin cache dumped to: %s", buffer);
fclose(fp);
}
+1 -8
View File
@@ -2,7 +2,7 @@
* vim: set ts=4 : * vim: set ts=4 :
* ============================================================================= * =============================================================================
* SourceMod * SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
* ============================================================================= * =============================================================================
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under
@@ -153,7 +153,6 @@ public: //IAdminSystem
bool FindFlag(const char *str, AdminFlag *pFlag); bool FindFlag(const char *str, AdminFlag *pFlag);
bool FindFlag(char c, AdminFlag *pAdmFlag); bool FindFlag(char c, AdminFlag *pAdmFlag);
FlagBits ReadFlagString(const char *flags, const char **end); FlagBits ReadFlagString(const char *flags, const char **end);
size_t FillFlagString(FlagBits bits, char *buffer, size_t maxlen);
unsigned int GetAdminSerialChange(AdminId id); unsigned int GetAdminSerialChange(AdminId id);
bool CanAdminUseCommand(int client, const char *cmd); bool CanAdminUseCommand(int client, const char *cmd);
const char *GetGroupName(GroupId gid); const char *GetGroupName(GroupId gid);
@@ -165,13 +164,8 @@ public: //IAdminSystem
const char *cmd, const char *cmd,
FlagBits flags, FlagBits flags,
bool override_only); bool override_only);
bool FindFlagChar(AdminFlag flag, char *c);
public: public:
bool IsValidAdmin(AdminId id); bool IsValidAdmin(AdminId id);
void DumpCache(FILE *fp);
AdminGroup *GetGroup(GroupId gid);
AdminUser *GetUser(AdminId id);
const char *GetString(int idx);
private: private:
void _UnsetCommandOverride(const char *cmd); void _UnsetCommandOverride(const char *cmd);
void _UnsetCommandGroupOverride(const char *group); void _UnsetCommandGroupOverride(const char *group);
@@ -180,7 +174,6 @@ private:
void DumpCommandOverrideCache(OverrideType type); void DumpCommandOverrideCache(OverrideType type);
Trie *GetMethodByIndex(unsigned int index); Trie *GetMethodByIndex(unsigned int index);
bool GetMethodIndex(const char *name, unsigned int *_index); bool GetMethodIndex(const char *name, unsigned int *_index);
const char *GetMethodName(unsigned int index);
void NameFlag(const char *str, AdminFlag flag); void NameFlag(const char *str, AdminFlag flag);
public: public:
BaseStringTable *m_pStrings; BaseStringTable *m_pStrings;
+2 -2
View File
@@ -2,7 +2,7 @@
* vim: set ts=4 : * vim: set ts=4 :
* ============================================================================= * =============================================================================
* SourceMod * SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
* ============================================================================= * =============================================================================
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under
@@ -29,7 +29,7 @@
* Version: $Id$ * Version: $Id$
*/ */
#include <stdlib.h> #include <malloc.h>
#include <string.h> #include <string.h>
#include "CDataPack.h" #include "CDataPack.h"
+1 -1
View File
@@ -2,7 +2,7 @@
* vim: set ts=4 : * vim: set ts=4 :
* ============================================================================= * =============================================================================
* SourceMod * SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
* ============================================================================= * =============================================================================
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under
+3 -19
View File
@@ -2,7 +2,7 @@
* vim: set ts=4 : * vim: set ts=4 :
* ============================================================================= * =============================================================================
* SourceMod * SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
* ============================================================================= * =============================================================================
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under
@@ -29,10 +29,7 @@
* Version: $Id$ * Version: $Id$
*/ */
#ifndef _INCLUDE_SOURCEMOD_CELLARRAY_H_ #include <malloc.h>
#define _INCLUDE_SOURCEMOD_CELLARRAY_H_
#include <stdlib.h>
#include <string.h> #include <string.h>
extern HandleType_t htCellArray; extern HandleType_t htCellArray;
@@ -43,17 +40,14 @@ public:
CellArray(size_t blocksize) : m_Data(NULL), m_BlockSize(blocksize), m_AllocSize(0), m_Size(0) CellArray(size_t blocksize) : m_Data(NULL), m_BlockSize(blocksize), m_AllocSize(0), m_Size(0)
{ {
} }
~CellArray() ~CellArray()
{ {
free(m_Data); free(m_Data);
} }
size_t size() const size_t size() const
{ {
return m_Size; return m_Size;
} }
cell_t *push() cell_t *push()
{ {
if (!GrowIfNeeded(1)) if (!GrowIfNeeded(1))
@@ -64,22 +58,18 @@ public:
m_Size++; m_Size++;
return arr; return arr;
} }
cell_t *at(size_t b) const cell_t *at(size_t b) const
{ {
return &m_Data[b * m_BlockSize]; return &m_Data[b * m_BlockSize];
} }
size_t blocksize() const size_t blocksize() const
{ {
return m_BlockSize; return m_BlockSize;
} }
void clear() void clear()
{ {
m_Size = 0; m_Size = 0;
} }
bool swap(size_t item1, size_t item2) bool swap(size_t item1, size_t item2)
{ {
/* Make sure there is extra space available */ /* Make sure there is extra space available */
@@ -100,7 +90,6 @@ public:
return true; return true;
} }
void remove(size_t index) void remove(size_t index)
{ {
/* If we're at the end, take the easy way out */ /* If we're at the end, take the easy way out */
@@ -118,7 +107,6 @@ public:
m_Size--; m_Size--;
} }
cell_t *insert_at(size_t index) cell_t *insert_at(size_t index)
{ {
/* Make sure it'll fit */ /* Make sure it'll fit */
@@ -136,7 +124,6 @@ public:
return src; return src;
} }
bool resize(size_t count) bool resize(size_t count)
{ {
if (count <= m_Size) if (count <= m_Size)
@@ -145,7 +132,7 @@ public:
return true; return true;
} }
if (!GrowIfNeeded(count - m_Size)) if(!GrowIfNeeded(count - m_Size))
{ {
return false; return false;
} }
@@ -207,6 +194,3 @@ private:
size_t m_AllocSize; size_t m_AllocSize;
size_t m_Size; size_t m_Size;
}; };
#endif /* _INCLUDE_SOURCEMOD_CELLARRAY_H_ */
+1 -1
View File
@@ -2,7 +2,7 @@
* vim: set ts=4 : * vim: set ts=4 :
* ============================================================================= * =============================================================================
* SourceMod * SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
* ============================================================================= * =============================================================================
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under
+44 -16
View File
@@ -2,7 +2,7 @@
* vim: set ts=4 : * vim: set ts=4 :
* ============================================================================= * =============================================================================
* SourceMod * SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
* ============================================================================= * =============================================================================
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under
@@ -41,7 +41,7 @@
* While the OB build only runs on MM:S 1.6.0+ (SH 5+), the older one * While the OB build only runs on MM:S 1.6.0+ (SH 5+), the older one
* can technically be compiled against any MM:S version after 1.4.2. * can technically be compiled against any MM:S version after 1.4.2.
*/ */
#if SOURCE_ENGINE >= SE_ORANGEBOX #if defined ORANGEBOX_BUILD
extern bool __SourceHook_FHRemoveConCommandDispatch(void *, bool, class fastdelegate::FastDelegate1<const CCommand &, void>); extern bool __SourceHook_FHRemoveConCommandDispatch(void *, bool, class fastdelegate::FastDelegate1<const CCommand &, void>);
extern int __SourceHook_FHAddConCommandDispatch(void *, ISourceHook::AddHookMode, bool, class fastdelegate::FastDelegate1<const CCommand &, void>); extern int __SourceHook_FHAddConCommandDispatch(void *, ISourceHook::AddHookMode, bool, class fastdelegate::FastDelegate1<const CCommand &, void>);
#else #else
@@ -53,10 +53,11 @@ extern int __SourceHook_FHAddConCommandDispatch(void *, bool, class fastdelegate
#elif SH_IMPL_VERSION == 3 #elif SH_IMPL_VERSION == 3
extern bool __SourceHook_FHAddConCommandDispatch(void *, bool, class fastdelegate::FastDelegate0<void>); extern bool __SourceHook_FHAddConCommandDispatch(void *, bool, class fastdelegate::FastDelegate0<void>);
#endif //SH_IMPL_VERSION #endif //SH_IMPL_VERSION
#endif //SE_ORANGEBOX #endif //ORANGEBOX_BUILD
ChatTriggers g_ChatTriggers; ChatTriggers g_ChatTriggers;
bool g_bSupressSilentFails = false; bool g_bSupressSilentFails = false;
CPhraseFile *g_pFloodPhrases = NULL;
ChatTriggers::ChatTriggers() : m_pSayCmd(NULL), m_bWillProcessInPost(false), ChatTriggers::ChatTriggers() : m_pSayCmd(NULL), m_bWillProcessInPost(false),
m_bTriggerWasSilent(false), m_ReplyTo(SM_REPLY_CONSOLE) m_bTriggerWasSilent(false), m_ReplyTo(SM_REPLY_CONSOLE)
@@ -113,13 +114,39 @@ void ChatTriggers::OnSourceModAllInitialized()
void ChatTriggers::OnSourceModAllInitialized_Post() void ChatTriggers::OnSourceModAllInitialized_Post()
{ {
g_pCorePhrases->AddPhraseFile("antiflood.phrases"); unsigned int file_id;
file_id = g_Translator.FindOrAddPhraseFile("antiflood.phrases.txt");
g_pFloodPhrases = g_Translator.GetFileByIndex(file_id);
} }
void ChatTriggers::OnSourceModGameInitialized() void ChatTriggers::OnSourceModGameInitialized()
{ {
m_pSayCmd = FindCommand("say"); unsigned int total = 2;
m_pSayTeamCmd = FindCommand("say_team"); ConCommandBase *pCmd = icvar->GetCommands();
const char *name;
while (pCmd)
{
if (pCmd->IsCommand())
{
name = pCmd->GetName();
if (!m_pSayCmd && strcmp(name, "say") == 0)
{
m_pSayCmd = (ConCommand *)pCmd;
if (--total == 0)
{
break;
}
} else if (!m_pSayTeamCmd && strcmp(name, "say_team") == 0) {
m_pSayTeamCmd = (ConCommand *)pCmd;
if (--total == 0)
{
break;
}
}
}
pCmd = const_cast<ConCommandBase *>(pCmd->GetNext());
}
if (m_pSayCmd) if (m_pSayCmd)
{ {
@@ -150,7 +177,7 @@ void ChatTriggers::OnSourceModShutdown()
g_Forwards.ReleaseForward(m_pDidFloodBlock); g_Forwards.ReleaseForward(m_pDidFloodBlock);
} }
#if SOURCE_ENGINE >= SE_ORANGEBOX #if defined ORANGEBOX_BUILD
void ChatTriggers::OnSayCommand_Pre(const CCommand &command) void ChatTriggers::OnSayCommand_Pre(const CCommand &command)
{ {
#else #else
@@ -189,14 +216,15 @@ void ChatTriggers::OnSayCommand_Pre()
{ {
char buffer[128]; char buffer[128];
if (!CoreTranslate( /* :TODO: log an error? */
buffer, if (g_Translator.CoreTransEx(g_pFloodPhrases,
client,
buffer,
sizeof(buffer), sizeof(buffer),
"%T",
2,
NULL,
"Flooding the server", "Flooding the server",
&client)) NULL,
NULL)
!= Trans_Okay)
{ {
UTIL_Format(buffer, sizeof(buffer), "You are flooding the server!"); UTIL_Format(buffer, sizeof(buffer), "You are flooding the server!");
} }
@@ -244,7 +272,7 @@ void ChatTriggers::OnSayCommand_Pre()
/** /**
* Test if this is actually a command! * Test if this is actually a command!
*/ */
if (!PreProcessTrigger(PEntityOfEntIndex(client), args, is_quoted)) if (!PreProcessTrigger(engine->PEntityOfEntIndex(client), args, is_quoted))
{ {
CPlayer *pPlayer; CPlayer *pPlayer;
if (is_silent if (is_silent
@@ -276,7 +304,7 @@ void ChatTriggers::OnSayCommand_Pre()
RETURN_META(MRES_IGNORED); RETURN_META(MRES_IGNORED);
} }
#if SOURCE_ENGINE >= SE_ORANGEBOX #if defined ORANGEBOX_BUILD
void ChatTriggers::OnSayCommand_Post(const CCommand &command) void ChatTriggers::OnSayCommand_Post(const CCommand &command)
#else #else
void ChatTriggers::OnSayCommand_Post() void ChatTriggers::OnSayCommand_Post()
@@ -292,7 +320,7 @@ void ChatTriggers::OnSayCommand_Post()
/* Execute the cached command */ /* Execute the cached command */
int client = g_ConCmds.GetCommandClient(); int client = g_ConCmds.GetCommandClient();
unsigned int old = SetReplyTo(SM_REPLY_CHAT); unsigned int old = SetReplyTo(SM_REPLY_CHAT);
serverpluginhelpers->ClientCommand(PEntityOfEntIndex(client), m_ToExecute); serverpluginhelpers->ClientCommand(engine->PEntityOfEntIndex(client), m_ToExecute);
SetReplyTo(old); SetReplyTo(old);
} }
} }
+2 -2
View File
@@ -2,7 +2,7 @@
* vim: set ts=4 : * vim: set ts=4 :
* ============================================================================= * =============================================================================
* SourceMod * SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
* ============================================================================= * =============================================================================
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under
@@ -54,7 +54,7 @@ public: //SMGlobalClass
char *error, char *error,
size_t maxlength); size_t maxlength);
private: //ConCommand private: //ConCommand
#if SOURCE_ENGINE >= SE_ORANGEBOX #if defined ORANGEBOX_BUILD
void OnSayCommand_Pre(const CCommand &command); void OnSayCommand_Pre(const CCommand &command);
void OnSayCommand_Post(const CCommand &command); void OnSayCommand_Post(const CCommand &command);
#else #else
+56 -86
View File
@@ -40,7 +40,7 @@
ConCmdManager g_ConCmds; ConCmdManager g_ConCmds;
#if SOURCE_ENGINE >= SE_ORANGEBOX #if defined ORANGEBOX_BUILD
SH_DECL_HOOK1_void(ConCommand, Dispatch, SH_NOATTRIB, false, const CCommand &); SH_DECL_HOOK1_void(ConCommand, Dispatch, SH_NOATTRIB, false, const CCommand &);
#else #else
SH_DECL_HOOK0_void(ConCommand, Dispatch, SH_NOATTRIB, false); SH_DECL_HOOK0_void(ConCommand, Dispatch, SH_NOATTRIB, false);
@@ -205,7 +205,7 @@ void ConCmdManager::OnPluginDestroyed(IPlugin *plugin)
delete pList; delete pList;
} }
} }
#if SOURCE_ENGINE >= SE_ORANGEBOX #if defined ORANGEBOX_BUILD
void CommandCallback(const CCommand &command) void CommandCallback(const CCommand &command)
{ {
#else #else
@@ -229,67 +229,46 @@ void ConCmdManager::SetCommandClient(int client)
ResultType ConCmdManager::DispatchClientCommand(int client, const char *cmd, int args, ResultType type) ResultType ConCmdManager::DispatchClientCommand(int client, const char *cmd, int args, ResultType type)
{ {
ConCmdInfo *pInfo; ConCmdInfo *pInfo;
if (sm_trie_retrieve(m_pCmds, cmd, (void **)&pInfo))
if (!sm_trie_retrieve(m_pCmds, cmd, (void **)&pInfo))
{ {
List<ConCmdInfo *>::iterator iter; cell_t result = type;
cell_t tempres = result;
pInfo = NULL; List<CmdHook *>::iterator iter;
iter = m_CmdList.begin(); CmdHook *pHook;
while (iter != m_CmdList.end()) for (iter=pInfo->conhooks.begin();
iter!=pInfo->conhooks.end();
iter++)
{ {
if (strcasecmp((*iter)->pCmd->GetName(), cmd) == 0) pHook = (*iter);
if (!pHook->pf->IsRunnable())
{ {
pInfo = (*iter); continue;
break; }
if (pHook->pAdmin && !CheckAccess(client, cmd, pHook->pAdmin))
{
if (result < Pl_Handled)
{
result = Pl_Handled;
}
continue;
}
pHook->pf->PushCell(client);
pHook->pf->PushCell(args);
if (pHook->pf->Execute(&tempres) == SP_ERROR_NONE)
{
if (tempres > result)
{
result = tempres;
}
if (result == Pl_Stop)
{
break;
}
} }
iter++;
}
if (pInfo == NULL)
{
return type;
} }
type = (ResultType)result;
} }
cell_t result = type;
cell_t tempres = result;
List<CmdHook *>::iterator iter;
CmdHook *pHook;
for (iter=pInfo->conhooks.begin();
iter!=pInfo->conhooks.end();
iter++)
{
pHook = (*iter);
if (!pHook->pf->IsRunnable())
{
continue;
}
if (pHook->pAdmin && !CheckAccess(client, cmd, pHook->pAdmin))
{
if (result < Pl_Handled)
{
result = Pl_Handled;
}
continue;
}
pHook->pf->PushCell(client);
pHook->pf->PushCell(args);
if (pHook->pf->Execute(&tempres) == SP_ERROR_NONE)
{
if (tempres > result)
{
result = tempres;
}
if (result == Pl_Stop)
{
break;
}
}
}
type = (ResultType)result;
return type; return type;
} }
@@ -317,32 +296,7 @@ void ConCmdManager::InternalDispatch(const CCommand &command)
ConCmdInfo *pInfo; ConCmdInfo *pInfo;
if (!sm_trie_retrieve(m_pCmds, cmd, (void **)&pInfo)) if (!sm_trie_retrieve(m_pCmds, cmd, (void **)&pInfo))
{ {
/* Unfortunately, we now have to do a slow lookup because Valve made client commands return;
* case-insensitive. We can't even use our sortedness.
*/
if (client == 0 && !engine->IsDedicatedServer())
{
return;
}
List<ConCmdInfo *>::iterator iter;
pInfo = NULL;
iter = m_CmdList.begin();
while (iter != m_CmdList.end())
{
if (strcasecmp((*iter)->pCmd->GetName(), cmd) == 0)
{
pInfo = (*iter);
break;
}
iter++;
}
if (pInfo == NULL)
{
return;
}
} }
/* This is a hack to prevent say triggers from firing on messages that were /* This is a hack to prevent say triggers from firing on messages that were
@@ -432,7 +386,6 @@ void ConCmdManager::InternalDispatch(const CCommand &command)
pHook->pf->PushCell(client); pHook->pf->PushCell(client);
pHook->pf->PushCell(args); pHook->pf->PushCell(args);
if (pHook->pf->Execute(&tempres) == SP_ERROR_NONE) if (pHook->pf->Execute(&tempres) == SP_ERROR_NONE)
{ {
if (tempres > result) if (tempres > result)
@@ -536,11 +489,12 @@ bool ConCmdManager::CheckAccess(int client, const char *cmd, AdminCmdInfo *pAdmi
return true; return true;
} }
edict_t *pEdict = PEntityOfEntIndex(client); edict_t *pEdict = engine->PEntityOfEntIndex(client);
/* If we got here, the command failed... */ /* If we got here, the command failed... */
char buffer[128]; char buffer[128];
if (!CoreTranslate(buffer, sizeof(buffer), "%T", 2, NULL, "No Access", &client)) if (g_Translator.CoreTrans(client, buffer, sizeof(buffer), "No Access", NULL, NULL)
!= Trans_Okay)
{ {
UTIL_Format(buffer, sizeof(buffer), "You do not have access to this command"); UTIL_Format(buffer, sizeof(buffer), "You do not have access to this command");
} }
@@ -918,7 +872,23 @@ ConCmdInfo *ConCmdManager::AddOrFindCommand(const char *name, const char *descri
{ {
pInfo = new ConCmdInfo(); pInfo = new ConCmdInfo();
/* Find the commandopan */ /* Find the commandopan */
ConCommand *pCmd = FindCommand(name); ConCommandBase *pBase = icvar->GetCommands();
ConCommand *pCmd = NULL;
while (pBase)
{
if (strcmp(pBase->GetName(), name) == 0)
{
/* Don't want to return convar with same name */
if (!pBase->IsCommand())
{
return NULL;
}
pCmd = (ConCommand *)pBase;
break;
}
pBase = const_cast<ConCommandBase *>(pBase->GetNext());
}
if (!pCmd) if (!pCmd)
{ {
+2 -3
View File
@@ -2,7 +2,7 @@
* vim: set ts=4 : * vim: set ts=4 :
* ============================================================================= * =============================================================================
* SourceMod * SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
* ============================================================================= * =============================================================================
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under
@@ -98,7 +98,7 @@ class ConCmdManager :
public IPluginsListener, public IPluginsListener,
public IConCommandTracker public IConCommandTracker
{ {
#if SOURCE_ENGINE >= SE_ORANGEBOX #if defined ORANGEBOX_BUILD
friend void CommandCallback(const CCommand &command); friend void CommandCallback(const CCommand &command);
#else #else
friend void CommandCallback(); friend void CommandCallback();
@@ -159,4 +159,3 @@ private:
extern ConCmdManager g_ConCmds; extern ConCmdManager g_ConCmds;
#endif // _INCLUDE_SOURCEMOD_CONCMDMANAGER_H_ #endif // _INCLUDE_SOURCEMOD_CONCMDMANAGER_H_
-89
View File
@@ -1,89 +0,0 @@
/**
* vim: set ts=4 sw=4 tw=99 noet :
* =============================================================================
* SourceMod
* Copyright (C) 2004-2010 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_SOURCEMOD_CON_COMMAND_BASE_ITERATOR_H_
#define _INCLUDE_SOURCEMOD_CON_COMMAND_BASE_ITERATOR_H_
#if SOURCE_ENGINE >= SE_LEFT4DEAD
class ConCommandBaseIterator
{
public:
inline ConCommandBaseIterator() : iter(icvar)
{
iter.SetFirst();
}
inline bool IsValid()
{
return iter.IsValid();
}
inline void Next()
{
iter.Next();
}
inline ConCommandBase *Get()
{
return iter.Get();
}
private:
ICvar::Iterator iter;
};
#else
class ConCommandBaseIterator
{
public:
inline ConCommandBaseIterator()
{
iter = icvar->GetCommands();
}
inline bool IsValid()
{
return iter != NULL;
}
inline void Next()
{
iter = const_cast<ConCommandBase *>(iter->GetNext());
}
inline ConCommandBase *Get()
{
return iter;
}
private:
ConCommandBase *iter;
};
#endif
#endif /* _INCLUDE_SOURCEMOD_CON_COMMAND_BASE_ITERATOR_H_ */
+24 -77
View File
@@ -1,8 +1,8 @@
/** /**
* vim: set ts=4 sw=4 tw=99 noet : * vim: set ts=4 :
* ============================================================================= * =============================================================================
* SourceMod * SourceMod
* Copyright (C) 2004-2009 AlliedModders LLC. All rights reserved. * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
* ============================================================================= * =============================================================================
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under
@@ -25,6 +25,8 @@
* this exception to all derivative works. AlliedModders LLC defines further * this exception to all derivative works. AlliedModders LLC defines further
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
* or <http://www.sourcemod.net/license.php>. * or <http://www.sourcemod.net/license.php>.
*
* Version: $Id$
*/ */
#include "ConVarManager.h" #include "ConVarManager.h"
@@ -39,59 +41,23 @@
ConVarManager g_ConVarManager; ConVarManager g_ConVarManager;
#if SOURCE_ENGINE <= SE_DARKMESSIAH #if !defined ORANGEBOX_BUILD
#define CallGlobalChangeCallbacks CallGlobalChangeCallback #define CallGlobalChangeCallbacks CallGlobalChangeCallback
#endif #endif
#if SOURCE_ENGINE >= SE_ORANGEBOX #if defined ORANGEBOX_BUILD
SH_DECL_HOOK3_void(ICvar, CallGlobalChangeCallbacks, SH_NOATTRIB, false, ConVar *, const char *, float); SH_DECL_HOOK3_void(ICvar, CallGlobalChangeCallbacks, SH_NOATTRIB, false, ConVar *, const char *, float);
#else #else
SH_DECL_HOOK2_void(ICvar, CallGlobalChangeCallbacks, SH_NOATTRIB, false, ConVar *, const char *); SH_DECL_HOOK2_void(ICvar, CallGlobalChangeCallbacks, SH_NOATTRIB, false, ConVar *, const char *);
#endif #endif
#if SOURCE_ENGINE != SE_DARKMESSIAH
SH_DECL_HOOK5_void(IServerGameDLL, OnQueryCvarValueFinished, SH_NOATTRIB, 0, QueryCvarCookie_t, edict_t *, EQueryCvarValueStatus, const char *, const char *); SH_DECL_HOOK5_void(IServerGameDLL, OnQueryCvarValueFinished, SH_NOATTRIB, 0, QueryCvarCookie_t, edict_t *, EQueryCvarValueStatus, const char *, const char *);
SH_DECL_HOOK5_void(IServerPluginCallbacks, OnQueryCvarValueFinished, SH_NOATTRIB, 0, QueryCvarCookie_t, edict_t *, EQueryCvarValueStatus, const char *, const char *); SH_DECL_HOOK5_void(IServerPluginCallbacks, OnQueryCvarValueFinished, SH_NOATTRIB, 0, QueryCvarCookie_t, edict_t *, EQueryCvarValueStatus, const char *, const char *);
#endif
const ParamType CONVARCHANGE_PARAMS[] = {Param_Cell, Param_String, Param_String}; const ParamType CONVARCHANGE_PARAMS[] = {Param_Cell, Param_String, Param_String};
typedef List<const ConVar *> ConVarList; typedef List<const ConVar *> ConVarList;
KTrie<ConVarInfo *> convar_cache; KTrie<ConVarInfo *> convar_cache;
class ConVarReentrancyGuard
{
ConVar *cvar;
ConVarReentrancyGuard *up;
public:
static ConVarReentrancyGuard *chain;
ConVarReentrancyGuard(ConVar *cvar)
: cvar(cvar), up(chain)
{
chain = this;
}
~ConVarReentrancyGuard()
{
assert(chain == this);
chain = up;
}
static bool IsCvarInChain(ConVar *cvar)
{
ConVarReentrancyGuard *guard = chain;
while (guard != NULL)
{
if (guard->cvar == cvar)
return true;
guard = guard->up;
}
return false;
}
};
ConVarReentrancyGuard *ConVarReentrancyGuard::chain = NULL;
ConVarManager::ConVarManager() : m_ConVarType(0), m_bIsDLLQueryHooked(false), m_bIsVSPQueryHooked(false) ConVarManager::ConVarManager() : m_ConVarType(0), m_bIsDLLQueryHooked(false), m_bIsVSPQueryHooked(false)
{ {
} }
@@ -118,7 +84,7 @@ void ConVarManager::OnSourceModAllInitialized()
/** /**
* Episode 2 has this function by default, but the older versions do not. * Episode 2 has this function by default, but the older versions do not.
*/ */
#if SOURCE_ENGINE == SE_EPISODEONE #if !defined ORANGEBOX_BUILD
if (g_SMAPI->GetGameDLLVersion() >= 6) if (g_SMAPI->GetGameDLLVersion() >= 6)
{ {
SH_ADD_HOOK_MEMFUNC(IServerGameDLL, OnQueryCvarValueFinished, gamedll, this, &ConVarManager::OnQueryCvarValueFinished, false); SH_ADD_HOOK_MEMFUNC(IServerGameDLL, OnQueryCvarValueFinished, gamedll, this, &ConVarManager::OnQueryCvarValueFinished, false);
@@ -128,8 +94,6 @@ void ConVarManager::OnSourceModAllInitialized()
SH_ADD_HOOK_STATICFUNC(ICvar, CallGlobalChangeCallbacks, icvar, OnConVarChanged, false); SH_ADD_HOOK_STATICFUNC(ICvar, CallGlobalChangeCallbacks, icvar, OnConVarChanged, false);
g_PluginSys.AddPluginsListener(this);
/* Add the 'convars' option to the 'sm' console command */ /* Add the 'convars' option to the 'sm' console command */
g_RootMenu.AddRootConsoleCommand("cvars", "View convars created by a plugin", this); g_RootMenu.AddRootConsoleCommand("cvars", "View convars created by a plugin", this);
} }
@@ -177,7 +141,6 @@ void ConVarManager::OnSourceModShutdown()
} }
convar_cache.clear(); convar_cache.clear();
#if SOURCE_ENGINE != SE_DARKMESSIAH
/* Unhook things */ /* Unhook things */
if (m_bIsDLLQueryHooked) if (m_bIsDLLQueryHooked)
{ {
@@ -189,15 +152,12 @@ void ConVarManager::OnSourceModShutdown()
SH_REMOVE_HOOK_MEMFUNC(IServerPluginCallbacks, OnQueryCvarValueFinished, vsp_interface, this, &ConVarManager::OnQueryCvarValueFinished, false); SH_REMOVE_HOOK_MEMFUNC(IServerPluginCallbacks, OnQueryCvarValueFinished, vsp_interface, this, &ConVarManager::OnQueryCvarValueFinished, false);
m_bIsVSPQueryHooked = false; m_bIsVSPQueryHooked = false;
} }
#endif
SH_REMOVE_HOOK_STATICFUNC(ICvar, CallGlobalChangeCallbacks, icvar, OnConVarChanged, false); SH_REMOVE_HOOK_STATICFUNC(ICvar, CallGlobalChangeCallbacks, icvar, OnConVarChanged, false);
/* Remove the 'convars' option from the 'sm' console command */ /* Remove the 'convars' option from the 'sm' console command */
g_RootMenu.RemoveRootConsoleCommand("cvars", this); g_RootMenu.RemoveRootConsoleCommand("cvars", this);
g_PluginSys.RemovePluginsListener(this);
/* Remove the 'ConVar' handle type */ /* Remove the 'ConVar' handle type */
g_HandleSys.RemoveType(m_ConVarType, g_pCoreIdent); g_HandleSys.RemoveType(m_ConVarType, g_pCoreIdent);
} }
@@ -216,7 +176,7 @@ void ConVarManager::OnSourceModVSPReceived()
} }
/* For later MM:S versions, use the updated API, since it's cleaner. */ /* For later MM:S versions, use the updated API, since it's cleaner. */
#if defined METAMOD_PLAPI_VERSION || PLAPI_VERSION >= 11 #if defined METAMOD_PLAPI_VERSION
int engine = g_SMAPI->GetSourceEngineBuild(); int engine = g_SMAPI->GetSourceEngineBuild();
if (engine == SOURCE_ENGINE_ORIGINAL || vsp_version < 2) if (engine == SOURCE_ENGINE_ORIGINAL || vsp_version < 2)
{ {
@@ -229,10 +189,8 @@ void ConVarManager::OnSourceModVSPReceived()
} }
#endif #endif
#if SOURCE_ENGINE != SE_DARKMESSIAH
SH_ADD_HOOK_MEMFUNC(IServerPluginCallbacks, OnQueryCvarValueFinished, vsp_interface, this, &ConVarManager::OnQueryCvarValueFinished, false); SH_ADD_HOOK_MEMFUNC(IServerPluginCallbacks, OnQueryCvarValueFinished, vsp_interface, this, &ConVarManager::OnQueryCvarValueFinished, false);
m_bIsVSPQueryHooked = true; m_bIsVSPQueryHooked = true;
#endif
} }
bool convar_cache_lookup(const char *name, ConVarInfo **pVar) bool convar_cache_lookup(const char *name, ConVarInfo **pVar)
@@ -288,23 +246,12 @@ void ConVarManager::OnUnlinkConCommandBase(ConCommandBase *pBase, const char *na
void ConVarManager::OnPluginUnloaded(IPlugin *plugin) void ConVarManager::OnPluginUnloaded(IPlugin *plugin)
{ {
ConVarList *pConVarList; ConVarList *pConVarList;
List<ConVarQuery>::iterator iter;
/* If plugin has a convar list, free its memory */ /* If plugin has a convar list, free its memory */
if (plugin->GetProperty("ConVarList", (void **)&pConVarList, true)) if (plugin->GetProperty("ConVarList", (void **)&pConVarList, true))
{ {
delete pConVarList; delete pConVarList;
} }
/* Remove convar queries for this plugin that haven't returned results yet */
for (iter = m_ConVarQueries.begin(); iter != m_ConVarQueries.end(); iter++)
{
ConVarQuery &query = (*iter);
if (query.pCallback->GetParentRuntime() == plugin->GetRuntime())
{
m_ConVarQueries.erase(iter);
}
}
} }
void ConVarManager::OnHandleDestroy(HandleType_t type, void *object) void ConVarManager::OnHandleDestroy(HandleType_t type, void *object)
@@ -362,7 +309,7 @@ void ConVarManager::OnRootConsoleCommand(const char *cmdname, const CCommand &co
} }
/* Display usage of subcommand */ /* Display usage of subcommand */
g_RootMenu.ConsolePrint("[SM] Usage: sm cvars <plugin #>"); g_RootMenu.ConsolePrint("[SM] Usage: sm convars <plugin #>");
} }
Handle_t ConVarManager::CreateConVar(IPluginContext *pContext, const char *name, const char *defaultVal, const char *description, int flags, bool hasMin, float min, bool hasMax, float max) Handle_t ConVarManager::CreateConVar(IPluginContext *pContext, const char *name, const char *defaultVal, const char *description, int flags, bool hasMin, float min, bool hasMax, float max)
@@ -412,10 +359,17 @@ Handle_t ConVarManager::CreateConVar(IPluginContext *pContext, const char *name,
} }
} }
/* Prevent creating a convar that has the same name as a console command */ /* To prevent creating a convar that has the same name as a console command... ugh */
if (FindCommand(name)) ConCommandBase *pBase = icvar->GetCommands();
while (pBase)
{ {
return BAD_HANDLE; if (pBase->IsCommand() && strcmp(pBase->GetName(), name) == 0)
{
return BAD_HANDLE;
}
pBase = const_cast<ConCommandBase *>(pBase->GetNext());
} }
/* Create and initialize ConVarInfo structure */ /* Create and initialize ConVarInfo structure */
@@ -570,8 +524,7 @@ void ConVarManager::UnhookConVarChange(ConVar *pConVar, IPluginFunction *pFuncti
} }
/* If the forward now has 0 functions in it... */ /* If the forward now has 0 functions in it... */
if (pForward->GetFunctionCount() == 0 && if (pForward->GetFunctionCount() == 0)
!ConVarReentrancyGuard::IsCvarInChain(pConVar))
{ {
/* Free this forward */ /* Free this forward */
g_Forwards.ReleaseForward(pForward); g_Forwards.ReleaseForward(pForward);
@@ -582,9 +535,8 @@ void ConVarManager::UnhookConVarChange(ConVar *pConVar, IPluginFunction *pFuncti
QueryCvarCookie_t ConVarManager::QueryClientConVar(edict_t *pPlayer, const char *name, IPluginFunction *pCallback, Handle_t hndl) QueryCvarCookie_t ConVarManager::QueryClientConVar(edict_t *pPlayer, const char *name, IPluginFunction *pCallback, Handle_t hndl)
{ {
QueryCvarCookie_t cookie = 0; QueryCvarCookie_t cookie;
#if SOURCE_ENGINE != SE_DARKMESSIAH
/* Call StartQueryCvarValue() in either the IVEngineServer or IServerPluginHelpers depending on situation */ /* Call StartQueryCvarValue() in either the IVEngineServer or IServerPluginHelpers depending on situation */
if (m_bIsDLLQueryHooked) if (m_bIsDLLQueryHooked)
{ {
@@ -601,7 +553,6 @@ QueryCvarCookie_t ConVarManager::QueryClientConVar(edict_t *pPlayer, const char
ConVarQuery query = {cookie, pCallback, hndl}; ConVarQuery query = {cookie, pCallback, hndl};
m_ConVarQueries.push_back(query); m_ConVarQueries.push_back(query);
#endif
return cookie; return cookie;
} }
@@ -644,7 +595,7 @@ void ConVarManager::AddConVarToPluginList(IPluginContext *pContext, const ConVar
} }
} }
#if SOURCE_ENGINE >= SE_ORANGEBOX #if defined ORANGEBOX_BUILD
void ConVarManager::OnConVarChanged(ConVar *pConVar, const char *oldValue, float flOldValue) void ConVarManager::OnConVarChanged(ConVar *pConVar, const char *oldValue, float flOldValue)
#else #else
void ConVarManager::OnConVarChanged(ConVar *pConVar, const char *oldValue) void ConVarManager::OnConVarChanged(ConVar *pConVar, const char *oldValue)
@@ -672,7 +623,7 @@ void ConVarManager::OnConVarChanged(ConVar *pConVar, const char *oldValue)
i != pInfo->changeListeners.end(); i != pInfo->changeListeners.end();
i++) i++)
{ {
#if SOURCE_ENGINE >= SE_ORANGEBOX #if defined ORANGEBOX_BUILD
(*i)->OnConVarChanged(pConVar, oldValue, flOldValue); (*i)->OnConVarChanged(pConVar, oldValue, flOldValue);
#else #else
(*i)->OnConVarChanged(pConVar, oldValue, atof(oldValue)); (*i)->OnConVarChanged(pConVar, oldValue, atof(oldValue));
@@ -682,8 +633,6 @@ void ConVarManager::OnConVarChanged(ConVar *pConVar, const char *oldValue)
if (pForward != NULL) if (pForward != NULL)
{ {
ConVarReentrancyGuard guard(pConVar);
/* Now call forwards in plugins that have hooked this */ /* Now call forwards in plugins that have hooked this */
pForward->PushCell(pInfo->handle); pForward->PushCell(pInfo->handle);
pForward->PushString(oldValue); pForward->PushString(oldValue);
@@ -697,7 +646,6 @@ bool ConVarManager::IsQueryingSupported()
return (m_bIsDLLQueryHooked || m_bIsVSPQueryHooked); return (m_bIsDLLQueryHooked || m_bIsVSPQueryHooked);
} }
#if SOURCE_ENGINE != SE_DARKMESSIAH
void ConVarManager::OnQueryCvarValueFinished(QueryCvarCookie_t cookie, edict_t *pPlayer, EQueryCvarValueStatus result, const char *cvarName, const char *cvarValue) void ConVarManager::OnQueryCvarValueFinished(QueryCvarCookie_t cookie, edict_t *pPlayer, EQueryCvarValueStatus result, const char *cvarName, const char *cvarValue)
{ {
IPluginFunction *pCallback = NULL; IPluginFunction *pCallback = NULL;
@@ -720,7 +668,7 @@ void ConVarManager::OnQueryCvarValueFinished(QueryCvarCookie_t cookie, edict_t *
cell_t ret; cell_t ret;
pCallback->PushCell(cookie); pCallback->PushCell(cookie);
pCallback->PushCell(IndexOfEdict(pPlayer)); pCallback->PushCell(engine->IndexOfEdict(pPlayer));
pCallback->PushCell(result); pCallback->PushCell(result);
pCallback->PushString(cvarName); pCallback->PushString(cvarName);
@@ -739,7 +687,6 @@ void ConVarManager::OnQueryCvarValueFinished(QueryCvarCookie_t cookie, edict_t *
m_ConVarQueries.erase(iter); m_ConVarQueries.erase(iter);
} }
} }
#endif
HandleError ConVarManager::ReadConVarHandle(Handle_t hndl, ConVar **pVar) HandleError ConVarManager::ReadConVarHandle(Handle_t hndl, ConVar **pVar)
{ {
+2 -9
View File
@@ -2,7 +2,7 @@
* vim: set ts=4 : * vim: set ts=4 :
* ============================================================================= * =============================================================================
* SourceMod * SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
* ============================================================================= * =============================================================================
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under
@@ -42,11 +42,6 @@
#include <compat_wrappers.h> #include <compat_wrappers.h>
#include "concmd_cleaner.h" #include "concmd_cleaner.h"
#if SOURCE_ENGINE == SE_DARKMESSIAH
class EQueryCvarValueStatus;
typedef int QueryCvarCookie_t;
#endif
using namespace SourceHook; using namespace SourceHook;
class IConVarChangeListener class IConVarChangeListener
@@ -145,7 +140,7 @@ private:
/** /**
* Static callback that Valve's ConVar object executes when the convar's value changes. * Static callback that Valve's ConVar object executes when the convar's value changes.
*/ */
#if SOURCE_ENGINE >= SE_ORANGEBOX #if defined ORANGEBOX_BUILD
static void OnConVarChanged(ConVar *pConVar, const char *oldValue, float flOldValue); static void OnConVarChanged(ConVar *pConVar, const char *oldValue, float flOldValue);
#else #else
static void OnConVarChanged(ConVar *pConVar, const char *oldValue); static void OnConVarChanged(ConVar *pConVar, const char *oldValue);
@@ -154,10 +149,8 @@ private:
/** /**
* Callback for when StartQueryCvarValue() has finished. * Callback for when StartQueryCvarValue() has finished.
*/ */
#if SOURCE_ENGINE != SE_DARKMESSIAH
void OnQueryCvarValueFinished(QueryCvarCookie_t cookie, edict_t *pPlayer, EQueryCvarValueStatus result, void OnQueryCvarValueFinished(QueryCvarCookie_t cookie, edict_t *pPlayer, EQueryCvarValueStatus result,
const char *cvarName, const char *cvarValue); const char *cvarName, const char *cvarValue);
#endif
private: private:
HandleType_t m_ConVarType; HandleType_t m_ConVarType;
List<ConVarInfo *> m_ConVars; List<ConVarInfo *> m_ConVars;
-742
View File
@@ -1,742 +0,0 @@
/**
* vim: set ts=4 sw=4 tw=99 noet :
* =============================================================================
* SourceMod
* Copyright (C) 2004-2009 AlliedModders LLC. All rights reserved.
* =============================================================================
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, version 3.0, as published by the
* Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <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$
*/
/**
* On SourceHook v4.3 or lower, there are no DVP hooks. Very sad, right?
* Only do this on newer versions. For the older code, we'll do an incredibly
* hacky detour.
*
* The idea of the "non-hacky" (yeah... no) code is that every unique
* ConCommand vtable gets its own DVP hook. We watch for unloading and
* loading commands to remove stale hooks from SH.
*/
#include "sourcemod.h"
#include "sourcemm_api.h"
#include "Logger.h"
#include "compat_wrappers.h"
#include "ConsoleDetours.h"
#include "GameConfigs.h"
#include "sm_stringutil.h"
#include "ConCmdManager.h"
#include "HalfLife2.h"
#include "ConCommandBaseIterator.h"
#include "ShareSys.h"
#if defined PLATFORM_LINUX
# include <dlfcn.h>
# include <sys/mman.h>
# include <stdint.h>
# include <unistd.h>
#endif
#if SH_IMPL_VERSION >= 5
# if SOURCE_ENGINE >= SE_ORANGEBOX
SH_DECL_EXTERN1_void(ConCommand, Dispatch, SH_NOATTRIB, false, const CCommand &);
# else
SH_DECL_EXTERN0_void(ConCommand, Dispatch, SH_NOATTRIB, false);
# endif
#else
# if SH_IMPL_VERSION >= 4
extern int __SourceHook_FHVPAddConCommandDispatch(void *,bool,class fastdelegate::FastDelegate0<void>,bool);
extern int __SourceHook_FHAddConCommandDispatch(void *, bool, class fastdelegate::FastDelegate0<void>);
# else
extern bool __SourceHook_FHAddConCommandDispatch(void *, bool, class fastdelegate::FastDelegate0<void>);
# endif
extern bool __SourceHook_FHRemoveConCommandDispatch(void *, bool, class fastdelegate::FastDelegate0<void>);
#endif
#if SH_IMPL_VERSION >= 4
class GenericCommandHooker : public IConCommandLinkListener
{
struct HackInfo
{
void **vtable;
int hook;
unsigned int refcount;
};
CVector<HackInfo> vtables;
bool enabled;
SourceHook::MemFuncInfo dispatch;
inline void **GetVirtualTable(ConCommandBase *pBase)
{
return *reinterpret_cast<void***>(reinterpret_cast<char*>(pBase) +
dispatch.thisptroffs +
dispatch.vtbloffs);
}
inline bool FindVtable(void **ptr, size_t& index)
{
for (size_t i = 0; i < vtables.size(); i++)
{
if (vtables[i].vtable == ptr)
{
index = i;
return true;
}
}
return false;
}
void MakeHookable(ConCommandBase *pBase)
{
if (!pBase->IsCommand())
return;
ConCommand *cmd = (ConCommand*)pBase;
void **vtable = GetVirtualTable(cmd);
size_t index;
if (!FindVtable(vtable, index))
{
HackInfo hack;
hack.vtable = vtable;
hack.hook = SH_ADD_VPHOOK(ConCommand, Dispatch, cmd, SH_MEMBER(this, &GenericCommandHooker::Dispatch), false);
hack.refcount = 1;
vtables.push_back(hack);
}
else
{
vtables[index].refcount++;
}
}
# if SOURCE_ENGINE >= SE_ORANGEBOX
void Dispatch(const CCommand& args)
# else
void Dispatch()
# endif
{
cell_t res = ConsoleDetours::Dispatch(META_IFACEPTR(ConCommand)
# if SOURCE_ENGINE >= SE_ORANGEBOX
, args
# endif
);
if (res >= Pl_Handled)
RETURN_META(MRES_SUPERCEDE);
}
void ReparseCommandList()
{
for (size_t i = 0; i < vtables.size(); i++)
vtables[i].refcount = 0;
for (ConCommandBaseIterator iter; iter.IsValid(); iter.Next())
MakeHookable(iter.Get());
CVector<HackInfo>::iterator iter = vtables.begin();
while (iter != vtables.end())
{
if ((*iter).refcount)
{
iter++;
continue;
}
/* Damn it. This event happens AFTER the plugin has unloaded!
* There's two options. Remove the hook now and hope SH's memory
* protection will prevent a crash. Otherwise, we can wait until
* the server shuts down and more likely crash then.
*
* This situation only arises if:
* 1) Someone has used AddCommandFilter()
* 2) ... on a Dark Messiah server (mm:s new api)
* 3) ... and another MM:S plugin that uses ConCommands has unloaded.
*
* Even though the impact is really small, we'll wait until the
* server shuts down, so normal operation isn't interrupted.
*
* See bug 4018.
*/
iter = vtables.erase(iter);
}
}
void UnhookCommand(ConCommandBase *pBase)
{
if (!pBase->IsCommand())
return;
ConCommand *cmd = (ConCommand*)pBase;
void **vtable = GetVirtualTable(cmd);
size_t index;
if (!FindVtable(vtable, index))
{
g_Logger.LogError("Console detour tried to unhook command \"%s\" but it wasn't found", pBase->GetName());
return;
}
assert(vtables[index].refcount > 0);
vtables[index].refcount--;
if (vtables[index].refcount == 0)
{
SH_REMOVE_HOOK_ID(vtables[index].hook);
vtables.erase(vtables.iterAt(index));
}
}
public:
GenericCommandHooker() : enabled(false)
{
}
bool Enable()
{
SourceHook::GetFuncInfo(&ConCommand::Dispatch, dispatch);
if (dispatch.thisptroffs < 0)
{
g_Logger.LogError("Command filter could not determine ConCommand layout");
return false;
}
for (ConCommandBaseIterator iter; iter.IsValid(); iter.Next())
MakeHookable(iter.Get());
if (!vtables.size())
{
g_Logger.LogError("Command filter could not find any cvars!");
return false;
}
enabled = true;
return true;
}
void Disable()
{
for (size_t i = 0; i < vtables.size(); i++)
SH_REMOVE_HOOK_ID(vtables[i].hook);
vtables.clear();
}
virtual void OnLinkConCommand(ConCommandBase *pBase)
{
if (!enabled)
return;
MakeHookable(pBase);
}
virtual void OnUnlinkConCommand(ConCommandBase *pBase)
{
if (!enabled)
return;
if (pBase == NULL)
ReparseCommandList();
else
UnhookCommand(pBase);
}
};
/**
* END DVP HOOK VERSION
*/
#else /* SH_IMPL_VERSION >= 4 */
/**
* BEGIN ENGINE DETOUR VERSION
*/
# include <jit/jit_helpers.h>
# include <jit/x86/x86_macros.h>
class GenericCommandHooker
{
struct Patch
{
Patch() : applied(false)
{
}
bool applied;
void *base;
unsigned char search[16];
size_t search_len;
size_t offset;
size_t saveat;
int regparam;
void *detour;
};
Patch ces;
Patch cgc;
public:
static void DelayedActivation(void *inparam)
{
GenericCommandHooker *cdtrs = reinterpret_cast<GenericCommandHooker*>(inparam);
/* Safe to re-enter because the frame queue is lock+swapped. */
if ((!cdtrs->ces.applied || !cdtrs->cgc.applied) &&
g_HL2.PeekCommandStack() != NULL)
{
g_SourceMod.AddFrameAction(GenericCommandHooker::DelayedActivation, cdtrs);
return;
}
if (!cdtrs->ces.applied)
cdtrs->ApplyPatch(&cdtrs->ces);
if (!cdtrs->cgc.applied)
cdtrs->ApplyPatch(&cdtrs->cgc);
}
bool Enable()
{
const char *platform = NULL;
# if defined(PLATFORM_WINDOWS)
platform = "Windows";
# else
void *addrInBase = (void *)g_SMAPI->GetEngineFactory(false);
Dl_info info;
if (!dladdr(addrInBase, &info))
{
g_Logger.LogError("Command filter could not find engine name");
return false;
}
if (strstr(info.dli_fname, "engine_i486"))
{
platform = "Linux_486";
}
else if (strstr(info.dli_fname, "engine_i686"))
{
platform = "Linux_686";
}
else if (strstr(info.dli_fname, "engine_amd"))
{
platform = "Linux_AMD";
}
else
{
g_Logger.LogError("Command filter could not determine engine (%s)", info.dli_fname);
return false;
}
# endif
if (!PrepPatch("Cmd_ExecuteString", "CES", platform, &ces))
return false;
if (!PrepPatch("CGameClient::ExecuteString", "CGC", platform, &cgc))
return false;
if (g_HL2.PeekCommandStack() != NULL)
{
g_SourceMod.AddFrameAction(GenericCommandHooker::DelayedActivation, this);
return true;
}
ApplyPatch(&ces);
ApplyPatch(&cgc);
return true;
}
void Disable()
{
UndoPatch(&ces);
UndoPatch(&cgc);
}
private:
# if !defined PLATFORM_WINDOWS
# define PAGE_READWRITE PROT_READ|PROT_WRITE
# define PAGE_EXECUTE_READ PROT_READ|PROT_EXEC
static inline uintptr_t AddrToPage(uintptr_t address)
{
return (address & ~(uintptr_t(sysconf(_SC_PAGE_SIZE) - 1)));
}
# endif
void Protect(void *addr, size_t length, int prot)
{
# if defined PLATFORM_WINDOWS
DWORD ignore;
VirtualProtect(addr, length, prot, &ignore);
# else
uintptr_t startPage = AddrToPage(uintptr_t(addr));
length += (uintptr_t(addr) - startPage);
mprotect((void*)startPage, length, prot);
# endif
}
void UndoPatch(Patch *patch)
{
if (!patch->applied || patch->detour == NULL)
return;
g_pSourcePawn->FreePageMemory(patch->detour);
unsigned char *source = (unsigned char *)patch->base + patch->offset;
Protect(source, patch->search_len, PAGE_READWRITE);
for (size_t i = 0; i < patch->search_len; i++)
source[i] = patch->search[i];
Protect(source, patch->search_len, PAGE_EXECUTE_READ);
}
void ApplyPatch(Patch *patch)
{
assert(!patch->applied);
size_t length = 0;
void *callback = (void*)&ConsoleDetours::Dispatch;
/* Bogus assignment to make compiler is doing the right thing. */
patch->detour = callback;
/* Assemgle the detour. */
JitWriter writer;
writer.outbase = NULL;
writer.outptr = NULL;
do
{
/* Need a specific register, or value on stack? */
if (patch->regparam != -1)
IA32_Push_Reg(&writer, patch->regparam);
/* Call real function. */
IA32_Write_Jump32_Abs(&writer, IA32_Call_Imm32(&writer, 0), callback);
/* Restore stack. */
if (patch->regparam != -1)
IA32_Pop_Reg(&writer, patch->regparam);
/* Copy any saved bytes */
if (patch->saveat)
{
for (size_t i = patch->saveat; i < patch->search_len; i++)
{
writer.write_ubyte(patch->search[i]);
}
}
/* Jump back to the caller. */
unsigned char *target = (unsigned char *)patch->base + patch->offset + patch->search_len;
IA32_Jump_Imm32_Abs(&writer, target);
/* Assemble, if we can. */
if (writer.outbase == NULL)
{
length = writer.outptr - writer.outbase;
patch->detour = g_pSourcePawn->AllocatePageMemory(length);
if (patch->detour == NULL)
{
g_Logger.LogError("Ran out of memory!");
return;
}
g_pSourcePawn->SetReadWrite(patch->detour);
writer.outbase = (jitcode_t)patch->detour;
writer.outptr = writer.outbase;
}
else
{
break;
}
} while (true);
g_pSourcePawn->SetReadExecute(patch->detour);
unsigned char *source = (unsigned char *)patch->base + patch->offset;
Protect(source, 6, PAGE_READWRITE);
source[0] = 0xFF;
source[1] = 0x25;
*(void **)&source[2] = &patch->detour;
Protect(source, 6, PAGE_EXECUTE_READ);
patch->applied = true;
}
bool PrepPatch(const char *signature, const char *name, const char *platform, Patch *patch)
{
/* Get the base address of the function. */
if (!g_pGameConf->GetMemSig(signature, &patch->base) || patch->base == NULL)
{
g_Logger.LogError("Command filter could not find signature: %s", signature);
return false;
}
const char *value;
char keyname[255];
/* Get the verification bytes that will be written over. */
UTIL_Format(keyname, sizeof(keyname), "%s_Patch_%s", name, platform);
if ((value = g_pGameConf->GetKeyValue(keyname)) == NULL)
{
g_Logger.LogError("Command filter could not find key: %s", keyname);
return false;
}
patch->search_len = UTIL_DecodeHexString(patch->search, sizeof(patch->search), value);
if (patch->search_len < 6)
{
g_Logger.LogError("Error decoding %s value, or not long enough", keyname);
return false;
}
/* Get the offset into the function. */
UTIL_Format(keyname, sizeof(keyname), "%s_Offset_%s", name, platform);
if ((value = g_pGameConf->GetKeyValue(keyname)) == NULL)
{
g_Logger.LogError("Command filter could not find key: %s", keyname);
return false;
}
patch->offset = atoi(value);
if (patch->offset > 20000)
{
g_Logger.LogError("Command filter %s value is bogus", keyname);
return false;
}
/* Get the number of bytes to save from what was written over. */
patch->saveat = 0;
UTIL_Format(keyname, sizeof(keyname), "%s_Save_%s", name, platform);
if ((value = g_pGameConf->GetKeyValue(keyname)) != NULL)
{
patch->saveat = atoi(value);
if (patch->saveat >= patch->search_len)
{
g_Logger.LogError("Command filter %s value is too large", keyname);
return false;
}
}
/* Get register for parameter, if any. */
patch->regparam = -1;
UTIL_Format(keyname, sizeof(keyname), "%s_Reg_%s", name, platform);
if ((value = g_pGameConf->GetKeyValue(keyname)) != NULL)
{
patch->regparam = atoi(value);
}
/* Everything loaded from gamedata, make sure the patch will succeed. */
unsigned char *address = (unsigned char *)patch->base + patch->offset;
for (size_t i = 0; i < patch->search_len; i++)
{
if (address[i] != patch->search[i])
{
g_Logger.LogError("Command filter %s has changed (byte %x is not %x sub-offset %d)",
name, address[i], patch->search[i], i);
return false;
}
}
return true;
}
};
static bool dummy_hook_set = false;
void DummyHook()
{
if (dummy_hook_set)
{
dummy_hook_set = false;
RETURN_META(MRES_SUPERCEDE);
}
}
#endif
/**
* BEGIN THE ACTUALLY GENERIC CODE.
*/
#define FEATURECAP_COMMANDLISTENER "command listener"
static GenericCommandHooker s_GenericHooker;
ConsoleDetours g_ConsoleDetours;
ConsoleDetours::ConsoleDetours() : status(FeatureStatus_Unknown)
{
}
void ConsoleDetours::OnSourceModAllInitialized()
{
m_pForward = g_Forwards.CreateForwardEx("OnAnyCommand", ET_Hook, 3, NULL, Param_Cell,
Param_String, Param_Cell);
g_ShareSys.AddCapabilityProvider(NULL, this, FEATURECAP_COMMANDLISTENER);
}
void ConsoleDetours::OnSourceModShutdown()
{
List<Listener*>::iterator iter = m_Listeners.begin();
while (iter != m_Listeners.end())
{
Listener *listener = (*iter);
g_Forwards.ReleaseForward(listener->forward);
delete listener;
iter = m_Listeners.erase(iter);
}
g_Forwards.ReleaseForward(m_pForward);
s_GenericHooker.Disable();
}
FeatureStatus ConsoleDetours::GetFeatureStatus(FeatureType type, const char *name)
{
return GetStatus();
}
FeatureStatus ConsoleDetours::GetStatus()
{
if (status == FeatureStatus_Unknown)
{
status = s_GenericHooker.Enable() ? FeatureStatus_Available : FeatureStatus_Unavailable;
}
return status;
}
bool ConsoleDetours::AddListener(IPluginFunction *fun, const char *command)
{
if (GetStatus() != FeatureStatus_Available)
return false;
if (command == NULL)
{
m_pForward->AddFunction(fun);
}
else
{
const char *str = UTIL_ToLowerCase(command);
Listener *listener;
Listener **plistener = m_CmdLookup.retrieve(str);
if (plistener == NULL)
{
listener = new Listener;
listener->forward = g_Forwards.CreateForwardEx(NULL, ET_Hook, 3, NULL, Param_Cell,
Param_String, Param_Cell);
m_CmdLookup.insert(str, listener);
}
else
{
listener = *plistener;
}
listener->forward->AddFunction(fun);
delete [] str;
}
return true;
}
bool ConsoleDetours::RemoveListener(IPluginFunction *fun, const char *command)
{
if (command == NULL)
{
return m_pForward->RemoveFunction(fun);
}
else
{
const char *str = UTIL_ToLowerCase(command);
Listener *listener;
Listener **plistener = m_CmdLookup.retrieve(str);
delete [] str;
if (plistener == NULL)
return false;
listener = *plistener;
return listener->forward->RemoveFunction(fun);
}
}
cell_t ConsoleDetours::InternalDispatch(int client, const CCommand& args)
{
char name[255];
const char *realname = args.Arg(0);
size_t len = strlen(realname);
for (size_t i = 0; i < len; i++)
{
if (realname[i] >= 'A' && realname[i] <= 'Z')
name[i] = tolower(realname[i]);
else
name[i] = realname[i];
}
name[len] = '\0';
cell_t result = Pl_Continue;
m_pForward->PushCell(client);
m_pForward->PushString(name);
m_pForward->PushCell(args.ArgC() - 1);
m_pForward->Execute(&result, NULL);
/* Don't let plugins block this. */
if (strcmp(name, "sm") == 0)
result = Pl_Continue;
if (result >= Pl_Stop)
return result;
Listener **plistener = m_CmdLookup.retrieve(name);
if (plistener == NULL)
return result;
Listener *listener = *plistener;
if (listener->forward->GetFunctionCount() == 0)
return result;
cell_t result2 = Pl_Continue;
listener->forward->PushCell(client);
listener->forward->PushString(name);
listener->forward->PushCell(args.ArgC() - 1);
listener->forward->Execute(&result2, NULL);
if (result2 > result)
result = result2;
/* "sm" should not have flown through the above. */
assert(strcmp(name, "sm") != 0 || result == Pl_Continue);
return result;
}
#if SOURCE_ENGINE >= SE_ORANGEBOX
cell_t ConsoleDetours::Dispatch(ConCommand *pBase, const CCommand& args)
{
#else
cell_t ConsoleDetours::Dispatch(ConCommand *pBase)
{
CCommand args;
#endif
g_HL2.PushCommandStack(&args);
cell_t res = g_ConsoleDetours.InternalDispatch(g_ConCmds.GetCommandClient(), args);
g_HL2.PopCommandStack();
#if SH_IMPL_VERSION < 4
if (res >= Pl_Handled)
{
/* See bug 4020 - we can't optimize this because looking at the vtable
* is probably more expensive, since there's no SH_GET_ORIG_VFNPTR_ENTRY.
*/
SH_ADD_HOOK_STATICFUNC(ConCommand, Dispatch, pBase, DummyHook, false);
dummy_hook_set = true;
pBase->Dispatch();
SH_REMOVE_HOOK_STATICFUNC(ConCommand, Dispatch, pBase, DummyHook, false);
}
else
{
/* Make sure the command gets invoked. See bug 4019 on making this better. */
pBase->Dispatch();
}
#endif
return res;
}
-83
View File
@@ -1,83 +0,0 @@
/**
* vim: set ts=4 sw=4 tw=99 noet :
* =============================================================================
* SourceMod
* Copyright (C) 2004-2009 AlliedModders LLC. All rights reserved.
* =============================================================================
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, version 3.0, as published by the
* Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <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_SOURCEMOD_CONSOLE_DETOURS_H_
#define _INCLUDE_SOURCEMOD_CONSOLE_DETOURS_H_
#include "sm_globals.h"
#include "sourcemm_api.h"
#include "ForwardSys.h"
#include <sm_trie_tpl.h>
class ConsoleDetours :
public SMGlobalClass,
public IFeatureProvider
{
friend class PlayerManager;
friend class GenericCommandHooker;
struct Listener
{
IChangeableForward *forward;
};
public:
ConsoleDetours();
public: //SMGlobalClass
void OnSourceModAllInitialized();
void OnSourceModShutdown();
public: //IFeatureProvider
FeatureStatus GetFeatureStatus(FeatureType type, const char *name);
public:
bool AddListener(IPluginFunction *fun, const char *command);
bool RemoveListener(IPluginFunction *fun, const char *command);
private:
cell_t InternalDispatch(int client, const CCommand& args);
#if SOURCE_ENGINE >= SE_ORANGEBOX
static cell_t Dispatch(ConCommand *pBase, const CCommand& args);
#else
static cell_t Dispatch(ConCommand *pBase);
#endif
public:
FeatureStatus GetStatus();
bool IsEnabled()
{
return status == FeatureStatus_Available;
}
private:
FeatureStatus status;
IChangeableForward *m_pForward;
KTrie<Listener*> m_CmdLookup;
List<Listener*> m_Listeners;
};
extern ConsoleDetours g_ConsoleDetours;
#endif /* _INCLUDE_SOURCEMOD_CONSOLE_DETOURS_H_ */
+12 -160
View File
@@ -2,7 +2,7 @@
* vim: set ts=4 : * vim: set ts=4 :
* ============================================================================= * =============================================================================
* SourceMod * SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
* ============================================================================= * =============================================================================
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under
@@ -34,97 +34,29 @@
#include "sourcemod.h" #include "sourcemod.h"
#include "sourcemm_api.h" #include "sourcemm_api.h"
#include "sm_srvcmds.h" #include "sm_srvcmds.h"
#include <sourcemod_version.h> #include "sm_version.h"
#include "sm_stringutil.h" #include "sm_stringutil.h"
#include "LibrarySys.h" #include "LibrarySys.h"
#include "Logger.h" #include "Logger.h"
#include "PluginSys.h" #include "PluginSys.h"
#include "ForwardSys.h" #include "ForwardSys.h"
#include "frame_hooks.h"
#ifdef PLATFORM_WINDOWS #ifdef PLATFORM_WINDOWS
ConVar sm_corecfgfile("sm_corecfgfile", "addons\\sourcemod\\configs\\core.cfg", 0, "SourceMod core configuration file"); ConVar sm_corecfgfile("sm_corecfgfile", "addons\\sourcemod\\configs\\core.cfg", 0, "SourceMod core configuration file");
#elif defined PLATFORM_LINUX || defined PLATFORM_APPLE #elif defined PLATFORM_LINUX
ConVar sm_corecfgfile("sm_corecfgfile", "addons/sourcemod/configs/core.cfg", 0, "SourceMod core configuration file"); ConVar sm_corecfgfile("sm_corecfgfile", "addons/sourcemod/configs/core.cfg", 0, "SourceMod core configuration file");
#endif #endif
IForward *g_pOnServerCfg = NULL; IForward *g_pOnServerCfg = NULL;
IForward *g_pOnConfigsExecuted = NULL; IForward *g_pOnConfigsExecuted = NULL;
IForward *g_pOnAutoConfigsBuffered = NULL;
CoreConfig g_CoreConfig; CoreConfig g_CoreConfig;
bool g_bConfigsExecd = false; bool g_bConfigsExecd = false;
bool g_bServerExecd = false;
bool g_bGotServerStart = false;
bool g_bGotTrigger = false;
ConCommand *g_pExecPtr = NULL;
ConVar *g_ServerCfgFile = NULL;
void CheckAndFinalizeConfigs();
#if SOURCE_ENGINE >= SE_ORANGEBOX
SH_DECL_EXTERN1_void(ConCommand, Dispatch, SH_NOATTRIB, false, const CCommand &);
void Hook_ExecDispatchPre(const CCommand &cmd)
#elif SOURCE_ENGINE == SE_DARKMESSIAH
SH_DECL_EXTERN0_void(ConCommand, Dispatch, SH_NOATTRIB, false);
void Hook_ExecDispatchPre()
#else
# if SH_IMPL_VERSION >= 4
extern int __SourceHook_FHAddConCommandDispatch(void *,bool,class fastdelegate::FastDelegate0<void>);
# else
extern bool __SourceHook_FHAddConCommandDispatch(void *,bool,class fastdelegate::FastDelegate0<void>);
# endif
extern bool __SourceHook_FHRemoveConCommandDispatch(void *,bool,class fastdelegate::FastDelegate0<void>);
void Hook_ExecDispatchPre()
#endif
{
#if SOURCE_ENGINE <= SE_DARKMESSIAH
CCommand cmd;
#endif
const char *arg = cmd.Arg(1);
if (!g_bServerExecd && arg != NULL && strcmp(arg, g_ServerCfgFile->GetString()) == 0)
{
g_bGotTrigger = true;
}
}
#if SOURCE_ENGINE >= SE_ORANGEBOX
void Hook_ExecDispatchPost(const CCommand &cmd)
#else
void Hook_ExecDispatchPost()
#endif
{
if (g_bGotTrigger)
{
g_bGotTrigger = false;
g_bServerExecd = true;
CheckAndFinalizeConfigs();
}
}
void CheckAndFinalizeConfigs()
{
if ((g_bServerExecd || g_ServerCfgFile == NULL) && g_bGotServerStart)
{
g_PendingInternalPush = true;
}
}
void CoreConfig::OnSourceModAllInitialized() void CoreConfig::OnSourceModAllInitialized()
{ {
g_RootMenu.AddRootConsoleCommand("config", "Set core configuration options", this); g_RootMenu.AddRootConsoleCommand("config", "Set core configuration options", this);
g_pOnServerCfg = g_Forwards.CreateForward("OnServerCfg", ET_Ignore, 0, NULL); g_pOnServerCfg = g_Forwards.CreateForward("OnServerCfg", ET_Ignore, 0, NULL);
g_pOnConfigsExecuted = g_Forwards.CreateForward("OnConfigsExecuted", ET_Ignore, 0, NULL); g_pOnConfigsExecuted = g_Forwards.CreateForward("OnConfigsExecuted", ET_Ignore, 0, NULL);
g_pOnAutoConfigsBuffered = g_Forwards.CreateForward("OnAutoConfigsBuffered", ET_Ignore, 0, NULL);
}
CoreConfig::CoreConfig() : m_Strings(512)
{
}
CoreConfig::~CoreConfig()
{
} }
void CoreConfig::OnSourceModShutdown() void CoreConfig::OnSourceModShutdown()
@@ -132,51 +64,11 @@ void CoreConfig::OnSourceModShutdown()
g_RootMenu.RemoveRootConsoleCommand("config", this); g_RootMenu.RemoveRootConsoleCommand("config", this);
g_Forwards.ReleaseForward(g_pOnServerCfg); g_Forwards.ReleaseForward(g_pOnServerCfg);
g_Forwards.ReleaseForward(g_pOnConfigsExecuted); g_Forwards.ReleaseForward(g_pOnConfigsExecuted);
g_Forwards.ReleaseForward(g_pOnAutoConfigsBuffered);
if (g_pExecPtr != NULL)
{
SH_REMOVE_HOOK_STATICFUNC(ConCommand, Dispatch, g_pExecPtr, Hook_ExecDispatchPre, false);
SH_REMOVE_HOOK_STATICFUNC(ConCommand, Dispatch, g_pExecPtr, Hook_ExecDispatchPost, true);
g_pExecPtr = NULL;
}
} }
void CoreConfig::OnSourceModLevelChange(const char *mapName) void CoreConfig::OnSourceModLevelChange(const char *mapName)
{ {
static bool already_checked = false;
if (!already_checked)
{
if (engine->IsDedicatedServer())
{
g_ServerCfgFile = icvar->FindVar("servercfgfile");
}
else
{
g_ServerCfgFile = icvar->FindVar("lservercfgfile");
}
if (g_ServerCfgFile != NULL)
{
g_pExecPtr = FindCommand("exec");
if (g_pExecPtr != NULL)
{
SH_ADD_HOOK_STATICFUNC(ConCommand, Dispatch, g_pExecPtr, Hook_ExecDispatchPre, false);
SH_ADD_HOOK_STATICFUNC(ConCommand, Dispatch, g_pExecPtr, Hook_ExecDispatchPost, true);
}
else
{
g_ServerCfgFile = NULL;
}
}
already_checked = true;
}
g_bConfigsExecd = false; g_bConfigsExecd = false;
g_bServerExecd = false;
g_bGotServerStart = false;
g_bGotTrigger = false;
} }
void CoreConfig::OnRootConsoleCommand(const char *cmdname, const CCommand &command) void CoreConfig::OnRootConsoleCommand(const char *cmdname, const CCommand &command)
@@ -214,32 +106,14 @@ void CoreConfig::Initialize()
/* Try to get command line value of core config convar */ /* Try to get command line value of core config convar */
const char *corecfg = icvar->GetCommandLineValue("sm_corecfgfile"); const char *corecfg = icvar->GetCommandLineValue("sm_corecfgfile");
/* If sm_corecfgfile is on the command line, use that /* If sm_corecfgfile not specified on command line, use default value */
* If sm_corecfgfile isn't there, check sm_basepath on the command line and build the path off that if (!corecfg)
* If sm_basepath isn't there, just use the default path for the cfg
*/
if (corecfg)
{ {
g_LibSys.PathFormat(filePath, sizeof(filePath), "%s/%s", g_SourceMod.GetGamePath(), corecfg); corecfg = sm_corecfgfile.GetDefault();
}
else
{
const char *basepath = icvar->GetCommandLineValue("sm_basepath");
/* Format path to config file */
if (basepath)
{
g_LibSys.PathFormat(filePath, sizeof(filePath), "%s/%s/%s", g_SourceMod.GetGamePath(), basepath, "configs/core.cfg");
}
else
{
g_LibSys.PathFormat(filePath, sizeof(filePath), "%s/%s", g_SourceMod.GetGamePath(), sm_corecfgfile.GetDefault());
}
} }
/* Reset cached key values */ /* Format path to config file */
m_KeyValues.clear(); g_LibSys.PathFormat(filePath, sizeof(filePath), "%s/%s", g_SourceMod.GetGamePath(), corecfg);
m_Strings.Reset();
/* Parse config file */ /* Parse config file */
if ((err=textparsers->ParseFile_SMC(filePath, this, NULL)) != SMCError_Okay) if ((err=textparsers->ParseFile_SMC(filePath, this, NULL)) != SMCError_Okay)
@@ -279,21 +153,9 @@ ConfigResult CoreConfig::SetConfigOption(const char *option, const char *value,
pBase = pBase->m_pGlobalClassNext; pBase = pBase->m_pGlobalClassNext;
} }
m_KeyValues.replace(option, m_Strings.AddString(value));
return ConfigResult_Ignore; return ConfigResult_Ignore;
} }
const char *CoreConfig::GetCoreConfigValue(const char *key)
{
int *pKey = m_KeyValues.retrieve(key);
if (pKey == NULL)
{
return NULL;
}
return m_Strings.GetString(*pKey);
}
bool SM_AreConfigsExecuted() bool SM_AreConfigsExecuted()
{ {
return g_bConfigsExecd; return g_bConfigsExecd;
@@ -303,7 +165,7 @@ inline bool IsPathSepChar(char c)
{ {
#if defined PLATFORM_WINDOWS #if defined PLATFORM_WINDOWS
return (c == '\\' || c == '/'); return (c == '\\' || c == '/');
#elif defined PLATFORM_LINUX || defined PLATFORM_POSIX #elif defined PLATFORM_LINUX
return (c == '/'); return (c == '/');
#endif #endif
} }
@@ -395,7 +257,7 @@ bool SM_ExecuteConfig(CPlugin *pl, AutoConfig *cfg, bool can_create)
FILE *fp = fopen(file, "wt"); FILE *fp = fopen(file, "wt");
if (fp) if (fp)
{ {
fprintf(fp, "// This file was auto-generated by SourceMod (v%s)\n", SM_FULL_VERSION); fprintf(fp, "// This file was auto-generated by SourceMod (v%s)\n", SVN_FULL_VERSION);
fprintf(fp, "// ConVars for plugin \"%s\"\n", pl->GetFilename()); fprintf(fp, "// ConVars for plugin \"%s\"\n", pl->GetFilename());
fprintf(fp, "\n\n"); fprintf(fp, "\n\n");
@@ -520,7 +382,7 @@ void SM_ExecuteForPlugin(IPluginContext *ctx)
void SM_ExecuteAllConfigs() void SM_ExecuteAllConfigs()
{ {
if (g_bGotServerStart) if (g_bConfigsExecd)
{ {
return; return;
} }
@@ -541,8 +403,7 @@ void SM_ExecuteAllConfigs()
} }
iter->Release(); iter->Release();
g_bGotServerStart = true; engine->ServerCommand("sm internal 1\n");
CheckAndFinalizeConfigs();
} }
void SM_ConfigsExecuted_Global() void SM_ConfigsExecuted_Global()
@@ -557,12 +418,3 @@ void SM_ConfigsExecuted_Global()
g_pOnServerCfg->Execute(NULL); g_pOnServerCfg->Execute(NULL);
g_pOnConfigsExecuted->Execute(NULL); g_pOnConfigsExecuted->Execute(NULL);
} }
void SM_InternalCmdTrigger()
{
/* Order is important here. We need to buffer things before we send the command out. */
g_pOnAutoConfigsBuffered->Execute(NULL);
engine->ServerCommand("sm internal 1\n");
g_PendingInternalPush = false;
}
+1 -11
View File
@@ -2,7 +2,7 @@
* vim: set ts=4 : * vim: set ts=4 :
* ============================================================================= * =============================================================================
* SourceMod * SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
* ============================================================================= * =============================================================================
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under
@@ -35,8 +35,6 @@
#include "sm_globals.h" #include "sm_globals.h"
#include <ITextParsers.h> #include <ITextParsers.h>
#include <IRootConsoleMenu.h> #include <IRootConsoleMenu.h>
#include <sm_trie_tpl.h>
#include "sm_memtable.h"
using namespace SourceMod; using namespace SourceMod;
@@ -45,9 +43,6 @@ class CoreConfig :
public ITextListener_SMC, public ITextListener_SMC,
public IRootConsoleCommand public IRootConsoleCommand
{ {
public:
CoreConfig();
~CoreConfig();
public: // SMGlobalClass public: // SMGlobalClass
void OnSourceModAllInitialized(); void OnSourceModAllInitialized();
void OnSourceModShutdown(); void OnSourceModShutdown();
@@ -61,15 +56,11 @@ public:
* Initializes CoreConfig by reading from core.cfg file * Initializes CoreConfig by reading from core.cfg file
*/ */
void Initialize(); void Initialize();
const char *GetCoreConfigValue(const char *key);
private: private:
/** /**
* Sets configuration option by notifying SourceMod components that rely on core.cfg * Sets configuration option by notifying SourceMod components that rely on core.cfg
*/ */
ConfigResult SetConfigOption(const char *option, const char *value, ConfigSource, char *Error, size_t maxlength); ConfigResult SetConfigOption(const char *option, const char *value, ConfigSource, char *Error, size_t maxlength);
private:
BaseStringTable m_Strings;
KTrie<int> m_KeyValues;
}; };
extern bool SM_AreConfigsExecuted(); extern bool SM_AreConfigsExecuted();
@@ -77,7 +68,6 @@ extern void SM_ExecuteAllConfigs();
extern void SM_ExecuteForPlugin(IPluginContext *ctx); extern void SM_ExecuteForPlugin(IPluginContext *ctx);
extern void SM_ConfigsExecuted_Global(); extern void SM_ConfigsExecuted_Global();
extern void SM_ConfigsExecuted_Plugin(unsigned int serial); extern void SM_ConfigsExecuted_Plugin(unsigned int serial);
extern void SM_InternalCmdTrigger();
extern CoreConfig g_CoreConfig; extern CoreConfig g_CoreConfig;
+2
View File
@@ -168,7 +168,9 @@ public:
} }
else if (strcasecmp(me32.szModule, "steam.dll") == 0) else if (strcasecmp(me32.szModule, "steam.dll") == 0)
{ {
/* Steam.dll is loaded by engine.dll, so we can exit the loop here */
steam = me32.modBaseAddr; steam = me32.modBaseAddr;
break;
} }
} while (Module32Next(hModuleList, &me32)); } while (Module32Next(hModuleList, &me32));
+33 -48
View File
@@ -2,7 +2,7 @@
* vim: set ts=4 : * vim: set ts=4 :
* ============================================================================= * =============================================================================
* SourceMod * SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
* ============================================================================= * =============================================================================
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under
@@ -37,7 +37,7 @@
#include "Logger.h" #include "Logger.h"
#include "ExtensionSys.h" #include "ExtensionSys.h"
#include <stdlib.h> #include <stdlib.h>
#include <IThreader.h> #include "ThreadSupport.h"
#define DBPARSE_LEVEL_NONE 0 #define DBPARSE_LEVEL_NONE 0
#define DBPARSE_LEVEL_MAIN 1 #define DBPARSE_LEVEL_MAIN 1
@@ -47,7 +47,7 @@ DBManager g_DBMan;
static bool s_OneTimeThreaderErrorMsg = false; static bool s_OneTimeThreaderErrorMsg = false;
DBManager::DBManager() DBManager::DBManager()
: m_ParseLevel(0), m_ParseState(0), m_pDefault(NULL) : m_StrTab(512), m_ParseLevel(0), m_ParseState(0), m_pDefault(NULL)
{ {
} }
@@ -104,7 +104,6 @@ void DBManager::OnSourceModShutdown()
m_pQueueLock->DestroyThis(); m_pQueueLock->DestroyThis();
g_HandleSys.RemoveType(m_DatabaseType, g_pCoreIdent); g_HandleSys.RemoveType(m_DatabaseType, g_pCoreIdent);
g_HandleSys.RemoveType(m_DriverType, g_pCoreIdent); g_HandleSys.RemoveType(m_DriverType, g_pCoreIdent);
ClearConfigs();
} }
unsigned int DBManager::GetInterfaceVersion() unsigned int DBManager::GetInterfaceVersion()
@@ -134,20 +133,13 @@ void DBManager::OnHandleDestroy(HandleType_t type, void *object)
void DBManager::ReadSMC_ParseStart() void DBManager::ReadSMC_ParseStart()
{ {
ClearConfigs(); m_confs.clear();
m_ParseLevel = 0; m_ParseLevel = 0;
m_ParseState = DBPARSE_LEVEL_NONE; m_ParseState = DBPARSE_LEVEL_NONE;
m_StrTab.Reset();
m_DefDriver.clear(); 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; ConfDbInfo s_CurInfo;
SMCResult DBManager::ReadSMC_NewSection(const SMCStates *states, const char *name) SMCResult DBManager::ReadSMC_NewSection(const SMCStates *states, const char *name)
{ {
@@ -167,7 +159,7 @@ SMCResult DBManager::ReadSMC_NewSection(const SMCStates *states, const char *nam
} }
} else if (m_ParseState == DBPARSE_LEVEL_MAIN) { } else if (m_ParseState == DBPARSE_LEVEL_MAIN) {
s_CurInfo = ConfDbInfo(); s_CurInfo = ConfDbInfo();
s_CurInfo.name = name; s_CurInfo.name = m_StrTab.AddString(name);
m_ParseState = DBPARSE_LEVEL_DATABASE; m_ParseState = DBPARSE_LEVEL_DATABASE;
} else if (m_ParseState == DBPARSE_LEVEL_DATABASE) { } else if (m_ParseState == DBPARSE_LEVEL_DATABASE) {
m_ParseLevel++; m_ParseLevel++;
@@ -194,16 +186,16 @@ SMCResult DBManager::ReadSMC_KeyValue(const SMCStates *states, const char *key,
{ {
if (strcmp(value, "default") != 0) if (strcmp(value, "default") != 0)
{ {
s_CurInfo.driver = value; s_CurInfo.driver = m_StrTab.AddString(value);
} }
} else if (strcmp(key, "database") == 0) { } else if (strcmp(key, "database") == 0) {
s_CurInfo.database = value; s_CurInfo.database = m_StrTab.AddString(value);
} else if (strcmp(key, "host") == 0) { } else if (strcmp(key, "host") == 0) {
s_CurInfo.host = value; s_CurInfo.host = m_StrTab.AddString(value);
} else if (strcmp(key, "user") == 0) { } else if (strcmp(key, "user") == 0) {
s_CurInfo.user = value; s_CurInfo.user = m_StrTab.AddString(value);
} else if (strcmp(key, "pass") == 0) { } else if (strcmp(key, "pass") == 0) {
s_CurInfo.pass = value; s_CurInfo.pass = m_StrTab.AddString(value);
} else if (strcmp(key, "timeout") == 0) { } else if (strcmp(key, "timeout") == 0) {
s_CurInfo.info.maxTimeout = atoi(value); s_CurInfo.info.maxTimeout = atoi(value);
} else if (strcmp(key, "port") == 0) { } else if (strcmp(key, "port") == 0) {
@@ -214,6 +206,13 @@ SMCResult DBManager::ReadSMC_KeyValue(const SMCStates *states, const char *key,
return SMCResult_Continue; return SMCResult_Continue;
} }
#define ASSIGN_VAR(var) \
if (s_CurInfo.var == -1) { \
s_CurInfo.info.var = ""; \
} else { \
s_CurInfo.info.var = m_StrTab.GetString(s_CurInfo.var); \
}
SMCResult DBManager::ReadSMC_LeavingSection(const SMCStates *states) SMCResult DBManager::ReadSMC_LeavingSection(const SMCStates *states)
{ {
if (m_ParseLevel) if (m_ParseLevel)
@@ -224,26 +223,17 @@ SMCResult DBManager::ReadSMC_LeavingSection(const SMCStates *states)
if (m_ParseState == DBPARSE_LEVEL_DATABASE) if (m_ParseState == DBPARSE_LEVEL_DATABASE)
{ {
ConfDbInfo *cdb = new ConfDbInfo(); /* Set all of the info members to either a blank string
* or the string pointer from the string table.
cdb->name = s_CurInfo.name; */
cdb->driver = s_CurInfo.driver; ASSIGN_VAR(driver);
cdb->host = s_CurInfo.host; ASSIGN_VAR(database);
cdb->user = s_CurInfo.user; ASSIGN_VAR(host);
cdb->pass = s_CurInfo.pass; ASSIGN_VAR(user);
cdb->database = s_CurInfo.database; ASSIGN_VAR(pass);
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.. */ /* Save it.. */
m_confs.push_back(cdb); m_confs.push_back(s_CurInfo);
/* Go up one level */ /* Go up one level */
m_ParseState = DBPARSE_LEVEL_MAIN; m_ParseState = DBPARSE_LEVEL_MAIN;
@@ -254,6 +244,7 @@ SMCResult DBManager::ReadSMC_LeavingSection(const SMCStates *states)
return SMCResult_Continue; return SMCResult_Continue;
} }
#undef ASSIGN_VAR
void DBManager::ReadSMC_ParseEnd(bool halted, bool failed) void DBManager::ReadSMC_ParseEnd(bool halted, bool failed)
{ {
@@ -342,10 +333,10 @@ void DBManager::RemoveDriver(IDBDriver *pDriver)
} }
/* Make sure NOTHING references this! */ /* Make sure NOTHING references this! */
List<ConfDbInfo *>::iterator iter; List<ConfDbInfo>::iterator iter;
for (iter=m_confs.begin(); iter!=m_confs.end(); iter++) for (iter=m_confs.begin(); iter!=m_confs.end(); iter++)
{ {
ConfDbInfo &db = *(*iter); ConfDbInfo &db = (*iter);
if (db.realDriver == pDriver) if (db.realDriver == pDriver)
{ {
db.realDriver = NULL; db.realDriver = NULL;
@@ -457,12 +448,12 @@ const DatabaseInfo *DBManager::FindDatabaseConf(const char *name)
ConfDbInfo *DBManager::GetDatabaseConf(const char *name) ConfDbInfo *DBManager::GetDatabaseConf(const char *name)
{ {
List<ConfDbInfo *>::iterator iter; List<ConfDbInfo>::iterator iter;
for (iter=m_confs.begin(); iter!=m_confs.end(); iter++) for (iter=m_confs.begin(); iter!=m_confs.end(); iter++)
{ {
ConfDbInfo &conf = *(*iter); ConfDbInfo &conf = (*iter);
if (conf.name == name) if (strcmp(m_StrTab.GetString(conf.name), name) == 0)
{ {
return &conf; return &conf;
} }
@@ -726,9 +717,3 @@ const char *DBManager::GetDefaultDriverName()
{ {
return m_DefDriver.c_str(); return m_DefDriver.c_str();
} }
void DBManager::AddDependency(IExtension *myself, IDBDriver *driver)
{
g_Extensions.AddRawDependency(myself, driver->GetIdentity(), driver);
}
+11 -11
View File
@@ -2,7 +2,7 @@
* vim: set ts=4 : * vim: set ts=4 :
* ============================================================================= * =============================================================================
* SourceMod * SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
* ============================================================================= * =============================================================================
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under
@@ -47,15 +47,16 @@ using namespace SourceHook;
struct ConfDbInfo struct ConfDbInfo
{ {
ConfDbInfo() : realDriver(NULL) ConfDbInfo() : name(-1), driver(-1), host(-1), user(-1), pass(-1),
database(-1), realDriver(NULL)
{ {
} }
String name; int name;
String driver; int driver;
String host; int host;
String user; int user;
String pass; int pass;
String database; int database;
IDBDriver *realDriver; IDBDriver *realDriver;
DatabaseInfo info; DatabaseInfo info;
}; };
@@ -91,7 +92,6 @@ public: //IDBManager
Handle_t CreateHandle(DBHandleType type, void *ptr, IdentityToken_t *pToken); Handle_t CreateHandle(DBHandleType type, void *ptr, IdentityToken_t *pToken);
HandleError ReadHandle(Handle_t hndl, DBHandleType type, void **ptr); HandleError ReadHandle(Handle_t hndl, DBHandleType type, void **ptr);
HandleError ReleaseHandle(Handle_t hndl, DBHandleType type, IdentityToken_t *token); HandleError ReleaseHandle(Handle_t hndl, DBHandleType type, IdentityToken_t *token);
void AddDependency(IExtension *myself, IDBDriver *driver);
public: //ITextListener_SMC public: //ITextListener_SMC
void ReadSMC_ParseStart(); void ReadSMC_ParseStart();
SMCResult ReadSMC_NewSection(const SMCStates *states, const char *name); SMCResult ReadSMC_NewSection(const SMCStates *states, const char *name);
@@ -120,7 +120,6 @@ public:
return m_DatabaseType; return m_DatabaseType;
} }
private: private:
void ClearConfigs();
void KillWorkerThread(); void KillWorkerThread();
private: private:
CVector<IDBDriver *> m_drivers; CVector<IDBDriver *> m_drivers;
@@ -134,10 +133,11 @@ private:
IMutex *m_pQueueLock; /* Queue safety lock */ IMutex *m_pQueueLock; /* Queue safety lock */
IMutex *m_pThinkLock; /* Think-queue lock */ IMutex *m_pThinkLock; /* Think-queue lock */
List<ConfDbInfo *> m_confs; List<ConfDbInfo> m_confs;
HandleType_t m_DriverType; HandleType_t m_DriverType;
HandleType_t m_DatabaseType; HandleType_t m_DatabaseType;
String m_DefDriver; String m_DefDriver;
BaseStringTable m_StrTab;
char m_Filename[PLATFORM_MAX_PATH]; char m_Filename[PLATFORM_MAX_PATH];
unsigned int m_ParseLevel; unsigned int m_ParseLevel;
unsigned int m_ParseState; unsigned int m_ParseState;
+9 -16
View File
@@ -36,23 +36,16 @@
DebugReport g_DbgReporter; DebugReport g_DbgReporter;
/* I'm really lazy. This should probably be exported to ISourcePawnEngine someday,
* but we need to make sure the JIT will deal with the version bump.
*/
extern const char *GetSourcePawnErrorMessage(int error);
void DebugReport::OnSourceModAllInitialized() void DebugReport::OnSourceModAllInitialized()
{ {
g_pSourcePawn->SetDebugListener(this); g_pSourcePawn->SetDebugListener(this);
} }
void DebugReport::OnDebugSpew(const char *msg, ...)
{
va_list ap;
char buffer[512];
va_start(ap, msg);
UTIL_FormatArgs(buffer, sizeof(buffer), msg, ap);
va_end(ap);
g_Logger.LogMessage("[SM] %s", buffer);
}
void DebugReport::GenerateError(IPluginContext *ctx, cell_t func_idx, int err, const char *message, ...) void DebugReport::GenerateError(IPluginContext *ctx, cell_t func_idx, int err, const char *message, ...)
{ {
va_list ap; va_list ap;
@@ -63,7 +56,7 @@ void DebugReport::GenerateError(IPluginContext *ctx, cell_t func_idx, int err, c
va_end(ap); va_end(ap);
const char *plname = g_PluginSys.FindPluginByContext(ctx->GetContext())->GetFilename(); const char *plname = g_PluginSys.FindPluginByContext(ctx->GetContext())->GetFilename();
const char *error = g_pSourcePawn2->GetErrorString(err); const char *error = GetSourcePawnErrorMessage(err);
if (error) if (error)
{ {
@@ -80,7 +73,7 @@ void DebugReport::GenerateError(IPluginContext *ctx, cell_t func_idx, int err, c
{ {
func_idx >>= 1; func_idx >>= 1;
sp_public_t *function; sp_public_t *function;
if (ctx->GetRuntime()->GetPublicByIndex(func_idx, &function) == SP_ERROR_NONE) if (ctx->GetPublicByIndex(func_idx, &function) == SP_ERROR_NONE)
{ {
g_Logger.LogError("[SM] Unable to call function \"%s\" due to above error(s).", function->name); g_Logger.LogError("[SM] Unable to call function \"%s\" due to above error(s).", function->name);
} }
@@ -98,7 +91,7 @@ void DebugReport::GenerateCodeError(IPluginContext *pContext, uint32_t code_addr
va_end(ap); va_end(ap);
const char *plname = g_PluginSys.FindPluginByContext(pContext->GetContext())->GetFilename(); const char *plname = g_PluginSys.FindPluginByContext(pContext->GetContext())->GetFilename();
const char *error = g_pSourcePawn2->GetErrorString(err); const char *error = GetSourcePawnErrorMessage(err);
if (error) if (error)
{ {
@@ -110,7 +103,7 @@ void DebugReport::GenerateCodeError(IPluginContext *pContext, uint32_t code_addr
g_Logger.LogError("[SM] %s", buffer); g_Logger.LogError("[SM] %s", buffer);
IPluginDebugInfo *pDebug; IPluginDebugInfo *pDebug;
if ((pDebug = pContext->GetRuntime()->GetDebugInfo()) == NULL) if ((pDebug = pContext->GetDebugInfo()) == NULL)
{ {
g_Logger.LogError("[SM] Debug mode is not enabled for \"%s\"", plname); g_Logger.LogError("[SM] Debug mode is not enabled for \"%s\"", plname);
g_Logger.LogError("[SM] To enable debug mode, edit plugin_settings.cfg, or type: sm plugins debug %d on", g_Logger.LogError("[SM] To enable debug mode, edit plugin_settings.cfg, or type: sm plugins debug %d on",
+1 -3
View File
@@ -2,7 +2,7 @@
* vim: set ts=4 : * vim: set ts=4 :
* ============================================================================= * =============================================================================
* SourceMod * SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
* ============================================================================= * =============================================================================
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under
@@ -43,8 +43,6 @@ public: // SMGlobalClass
void OnSourceModAllInitialized(); void OnSourceModAllInitialized();
public: // IDebugListener public: // IDebugListener
void OnContextExecuteError(IPluginContext *ctx, IContextTrace *error); void OnContextExecuteError(IPluginContext *ctx, IContextTrace *error);
void OnDebugSpew(const char *msg, ...);
public:
void GenerateError(IPluginContext *ctx, cell_t func_idx, int err, const char *message, ...); void GenerateError(IPluginContext *ctx, cell_t func_idx, int err, const char *message, ...);
void GenerateCodeError(IPluginContext *ctx, uint32_t code_addr, int err, const char *message, ...); void GenerateCodeError(IPluginContext *ctx, uint32_t code_addr, int err, const char *message, ...);
private: private:
+22 -89
View File
@@ -1,8 +1,8 @@
/** /**
* vim: set ts=4 sw=4 tw=99 noet : * vim: set ts=4 :
* ============================================================================= * =============================================================================
* SourceMod * SourceMod
* Copyright (C) 2004-2010 AlliedModders LLC. All rights reserved. * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
* ============================================================================= * =============================================================================
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under
@@ -42,20 +42,6 @@ SH_DECL_HOOK2(IGameEventManager2, FireEvent, SH_NOATTRIB, 0, bool, IGameEvent *,
const ParamType GAMEEVENT_PARAMS[] = {Param_Cell, Param_String, Param_Cell}; const ParamType GAMEEVENT_PARAMS[] = {Param_Cell, Param_String, Param_Cell};
typedef List<EventHook *> EventHookList; typedef List<EventHook *> EventHookList;
class EventForwardFilter : public IForwardFilter
{
EventInfo *pEventInfo;
public:
EventForwardFilter(EventInfo *pEventInfo) : pEventInfo(pEventInfo)
{
}
void Preprocess(IPluginFunction *fun, FwdParamInfo *params)
{
params[2].val = pEventInfo->bDontBroadcast ? 1 : 0;
}
};
EventManager::EventManager() : m_EventType(0) EventManager::EventManager() : m_EventType(0)
{ {
/* Create an event lookup trie */ /* Create an event lookup trie */
@@ -161,13 +147,6 @@ void EventManager::FireGameEvent(IGameEvent *pEvent)
Just need to add ourselves as a listener to make our hook on IGameEventManager2::FireEvent work */ Just need to add ourselves as a listener to make our hook on IGameEventManager2::FireEvent work */
} }
#if SOURCE_ENGINE >= SE_LEFT4DEAD
int EventManager::GetEventDebugID()
{
return EVENT_DEBUG_ID_INIT;
}
#endif
EventHookError EventManager::HookEvent(const char *name, IPluginFunction *pFunction, EventHookMode mode) EventHookError EventManager::HookEvent(const char *name, IPluginFunction *pFunction, EventHookMode mode)
{ {
EventHook *pHook; EventHook *pHook;
@@ -214,9 +193,6 @@ EventHookError EventManager::HookEvent(const char *name, IPluginFunction *pFunct
pHook->pPostHook->AddFunction(pFunction); pHook->pPostHook->AddFunction(pFunction);
} }
/* Cache the name for post hooks */
pHook->name = sm_strdup(name);
/* Increase reference count */ /* Increase reference count */
pHook->refCount++; pHook->refCount++;
@@ -320,9 +296,6 @@ EventHookError EventManager::UnhookEvent(const char *name, IPluginFunction *pFun
/* Delete entry in trie */ /* Delete entry in trie */
sm_trie_delete(m_EventHooks, name); sm_trie_delete(m_EventHooks, name);
/* Free the cached name */
delete pHook->name;
/* And finally free structure memory */ /* And finally free structure memory */
delete pHook; delete pHook;
} }
@@ -348,7 +321,6 @@ EventInfo *EventManager::CreateEvent(IPluginContext *pContext, const char *name,
pInfo->pEvent = pEvent; pInfo->pEvent = pEvent;
pInfo->pOwner = pContext->GetIdentity(); pInfo->pOwner = pContext->GetIdentity();
pInfo->bDontBroadcast = false;
return pInfo; return pInfo;
} }
@@ -387,49 +359,33 @@ bool EventManager::OnFireEvent(IGameEvent *pEvent, bool bDontBroadcast)
IChangeableForward *pForward; IChangeableForward *pForward;
const char *name; const char *name;
cell_t res = Pl_Continue; cell_t res = Pl_Continue;
bool broadcast = bDontBroadcast;
/* The engine accepts NULL without crashing, so to prevent a crash in SM we ignore these */
if (!pEvent)
{
RETURN_META_VALUE(MRES_IGNORED, false);
}
name = pEvent->GetName();
/* Get the event name, we're going to need this for passing to post hooks */
name = pEvent->GetName();
m_EventNames.push(name);
if (sm_trie_retrieve(m_EventHooks, name, reinterpret_cast<void **>(&pHook))) if (sm_trie_retrieve(m_EventHooks, name, reinterpret_cast<void **>(&pHook)))
{ {
/* Push the event onto the event stack. The reference count is increased to make sure
* the structure is not garbage collected in between now and the post hook.
*/
pHook->refCount++;
m_EventStack.push(pHook);
pForward = pHook->pPreHook; pForward = pHook->pPreHook;
if (pForward) if (pForward)
{ {
EventInfo info(pEvent, NULL); EventInfo info = { pEvent, NULL };
HandleSecurity sec(NULL, g_pCoreIdent);
Handle_t hndl = g_HandleSys.CreateHandle(m_EventType, &info, NULL, g_pCoreIdent, NULL); Handle_t hndl = g_HandleSys.CreateHandle(m_EventType, &info, NULL, g_pCoreIdent, NULL);
info.bDontBroadcast = bDontBroadcast;
EventForwardFilter filter(&info);
pForward->PushCell(hndl); pForward->PushCell(hndl);
pForward->PushString(name); pForward->PushString(name);
pForward->PushCell(bDontBroadcast); pForward->PushCell(bDontBroadcast);
pForward->Execute(&res, &filter); pForward->Execute(&res, NULL);
broadcast = info.bDontBroadcast;
HandleSecurity sec(NULL, g_pCoreIdent);
g_HandleSys.FreeHandle(hndl, &sec); g_HandleSys.FreeHandle(hndl, &sec);
} }
if (pHook->postCopy) if (pHook->postCopy)
{ {
m_EventCopies.push(gameevents->DuplicateEvent(pEvent)); pHook->pEventCopy = gameevents->DuplicateEvent(pEvent);
} }
if (res) if (res)
@@ -438,13 +394,6 @@ bool EventManager::OnFireEvent(IGameEvent *pEvent, bool bDontBroadcast)
RETURN_META_VALUE(MRES_SUPERCEDE, false); RETURN_META_VALUE(MRES_SUPERCEDE, false);
} }
} }
else
{
m_EventStack.push(NULL);
}
if (broadcast != bDontBroadcast)
RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, true, &IGameEventManager2::FireEvent, (pEvent, broadcast));
RETURN_META_VALUE(MRES_IGNORED, true); RETURN_META_VALUE(MRES_IGNORED, true);
} }
@@ -452,30 +401,24 @@ bool EventManager::OnFireEvent(IGameEvent *pEvent, bool bDontBroadcast)
/* IGameEventManager2::FireEvent post hook */ /* IGameEventManager2::FireEvent post hook */
bool EventManager::OnFireEvent_Post(IGameEvent *pEvent, bool bDontBroadcast) bool EventManager::OnFireEvent_Post(IGameEvent *pEvent, bool bDontBroadcast)
{ {
IGameEvent *pEventCopy = NULL;
EventHook *pHook; EventHook *pHook;
EventInfo info;
IChangeableForward *pForward; IChangeableForward *pForward;
const char *name;
Handle_t hndl = 0; Handle_t hndl = 0;
/* The engine accepts NULL without crashing, so to prevent a crash in SM we ignore these */ name = m_EventNames.front();
if (!pEvent)
{
RETURN_META_VALUE(MRES_IGNORED, false);
}
pHook = m_EventStack.front(); if (sm_trie_retrieve(m_EventHooks, name, reinterpret_cast<void **>(&pHook)))
if (pHook != NULL)
{ {
pForward = pHook->pPostHook; pForward = pHook->pPostHook;
if (pForward) if (pForward)
{ {
EventInfo info = { pHook->pEventCopy, NULL };
if (pHook->postCopy) if (pHook->postCopy)
{ {
info.bDontBroadcast = bDontBroadcast;
info.pEvent = m_EventCopies.front();
info.pOwner = NULL;
hndl = g_HandleSys.CreateHandle(m_EventType, &info, NULL, g_pCoreIdent, NULL); hndl = g_HandleSys.CreateHandle(m_EventType, &info, NULL, g_pCoreIdent, NULL);
pForward->PushCell(hndl); pForward->PushCell(hndl);
@@ -483,7 +426,7 @@ bool EventManager::OnFireEvent_Post(IGameEvent *pEvent, bool bDontBroadcast)
pForward->PushCell(BAD_HANDLE); pForward->PushCell(BAD_HANDLE);
} }
pForward->PushString(pHook->name); pForward->PushString(name);
pForward->PushCell(bDontBroadcast); pForward->PushCell(bDontBroadcast);
pForward->Execute(NULL); pForward->Execute(NULL);
@@ -494,23 +437,13 @@ bool EventManager::OnFireEvent_Post(IGameEvent *pEvent, bool bDontBroadcast)
g_HandleSys.FreeHandle(hndl, &sec); g_HandleSys.FreeHandle(hndl, &sec);
/* Free event structure */ /* Free event structure */
gameevents->FreeEvent(info.pEvent); gameevents->FreeEvent(pEventCopy);
m_EventCopies.pop(); pHook->pEventCopy = NULL;
} }
} }
/* Decrement reference count, check if a delayed delete is needed */
if (--pHook->refCount == 0)
{
assert(pHook->pPostHook == NULL);
assert(pHook->pPreHook == NULL);
sm_trie_delete(m_EventHooks, pHook->name);
delete pHook->name;
delete pHook;
}
} }
m_EventStack.pop(); m_EventNames.pop();
RETURN_META_VALUE(MRES_IGNORED, true); RETURN_META_VALUE(MRES_IGNORED, true);
} }
+4 -14
View File
@@ -2,7 +2,7 @@
* vim: set ts=4 : * vim: set ts=4 :
* ============================================================================= * =============================================================================
* SourceMod * SourceMod
* Copyright (C) 2004-2010 AlliedModders LLC. All rights reserved. * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
* ============================================================================= * =============================================================================
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under
@@ -45,15 +45,8 @@ using namespace SourceHook;
struct EventInfo struct EventInfo
{ {
EventInfo()
{
}
EventInfo(IGameEvent *ev, IdentityToken_t *owner) : pEvent(ev), pOwner(owner)
{
}
IGameEvent *pEvent; IGameEvent *pEvent;
IdentityToken_t *pOwner; IdentityToken_t *pOwner;
bool bDontBroadcast;
}; };
struct EventHook struct EventHook
@@ -63,13 +56,14 @@ struct EventHook
pPreHook = NULL; pPreHook = NULL;
pPostHook = NULL; pPostHook = NULL;
postCopy = false; postCopy = false;
pEventCopy = NULL;
refCount = 0; refCount = 0;
} }
IChangeableForward *pPreHook; IChangeableForward *pPreHook;
IChangeableForward *pPostHook; IChangeableForward *pPostHook;
bool postCopy; bool postCopy;
IGameEvent *pEventCopy;
unsigned int refCount; unsigned int refCount;
char *name;
}; };
enum EventHookMode enum EventHookMode
@@ -105,9 +99,6 @@ public: // IPluginsListener
void OnPluginUnloaded(IPlugin *plugin); void OnPluginUnloaded(IPlugin *plugin);
public: // IGameEventListener2 public: // IGameEventListener2
void FireGameEvent(IGameEvent *pEvent); void FireGameEvent(IGameEvent *pEvent);
#if SOURCE_ENGINE >= SE_LEFT4DEAD
int GetEventDebugID();
#endif
public: public:
/** /**
* Get the 'GameEvent' handle type ID. * Get the 'GameEvent' handle type ID.
@@ -129,8 +120,7 @@ private:
HandleType_t m_EventType; HandleType_t m_EventType;
Trie *m_EventHooks; Trie *m_EventHooks;
CStack<EventInfo *> m_FreeEvents; CStack<EventInfo *> m_FreeEvents;
CStack<EventHook *> m_EventStack; CStack<const char *> m_EventNames;
CStack<IGameEvent *> m_EventCopies;
}; };
extern EventManager g_EventManager; extern EventManager g_EventManager;
+76 -404
View File
@@ -1,8 +1,8 @@
/** /**
* vim: set ts=4 sw=4 tw=99 noet : * vim: set ts=4 :
* ============================================================================= * =============================================================================
* SourceMod * SourceMod
* Copyright (C) 2004-2009 AlliedModders LLC. All rights reserved. * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
* ============================================================================= * =============================================================================
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under
@@ -25,6 +25,8 @@
* this exception to all derivative works. AlliedModders LLC defines further * this exception to all derivative works. AlliedModders LLC defines further
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
* or <http://www.sourcemod.net/license.php>. * or <http://www.sourcemod.net/license.php>.
*
* Version: $Id$
*/ */
#include <string.h> #include <string.h>
@@ -47,9 +49,9 @@
GameConfigManager g_GameConfigs; GameConfigManager g_GameConfigs;
IGameConfig *g_pGameConf = NULL; IGameConfig *g_pGameConf = NULL;
static char g_Game[256]; char g_Game[256];
static char g_GameDesc[256] = {'!', '\0'}; char g_GameDesc[256] = {'!', '\0'};
static char g_GameName[256] = {'$', '\0'}; char g_GameName[256] = {'$', '\0'};
#define PSTATE_NONE 0 #define PSTATE_NONE 0
#define PSTATE_GAMES 1 #define PSTATE_GAMES 1
@@ -62,7 +64,6 @@ static char g_GameName[256] = {'$', '\0'};
#define PSTATE_GAMEDEFS_SIGNATURES_SIG 8 #define PSTATE_GAMEDEFS_SIGNATURES_SIG 8
#define PSTATE_GAMEDEFS_CRC 9 #define PSTATE_GAMEDEFS_CRC 9
#define PSTATE_GAMEDEFS_CRC_BINARY 10 #define PSTATE_GAMEDEFS_CRC_BINARY 10
#define PSTATE_GAMEDEFS_CUSTOM 11
#if defined PLATFORM_WINDOWS #if defined PLATFORM_WINDOWS
#define PLATFORM_NAME "windows" #define PLATFORM_NAME "windows"
@@ -70,9 +71,6 @@ static char g_GameName[256] = {'$', '\0'};
#elif defined PLATFORM_LINUX #elif defined PLATFORM_LINUX
#define PLATFORM_NAME "linux" #define PLATFORM_NAME "linux"
#define PLATFORM_SERVER_BINARY "server_i486.so" #define PLATFORM_SERVER_BINARY "server_i486.so"
#elif defined PLATFORM_APPLE
#define PLATFORM_NAME "undef"
#define PLATFORM_SERVER_BINARY "undef.dylib"
#endif #endif
struct TempSigInfo struct TempSigInfo
@@ -88,58 +86,15 @@ struct TempSigInfo
unsigned int s_ServerBinCRC; unsigned int s_ServerBinCRC;
bool s_ServerBinCRC_Ok = false; bool s_ServerBinCRC_Ok = false;
static bool DoesGameMatch(const char *value)
{
#if defined PLATFORM_WINDOWS
if (strcasecmp(value, g_Game) == 0 ||
#else
if (strcmp(value, g_Game) == 0 ||
#endif
strcmp(value, g_GameDesc) == 0 ||
strcmp(value, g_GameName) == 0)
{
return true;
}
return false;
}
static bool DoesEngineMatch(const char *value)
{
#if SOURCE_ENGINE == SE_EPISODEONE
if (strcmp(value, "original") == 0)
#elif SOURCE_ENGINE == SE_DARKMESSIAH
if (strcmp(value, "darkmessiah") == 0)
#elif SOURCE_ENGINE == SE_ORANGEBOX
if (strcmp(value, "orangebox") == 0)
#elif SOURCE_ENGINE == SE_ORANGEBOXVALVE
if (strcmp(value, "orangebox_valve") == 0)
#elif SOURCE_ENGINE == SE_LEFT4DEAD
if (strcmp(value, "left4dead") == 0)
#elif SOURCE_ENGINE == SE_LEFT4DEAD2
if (strcmp(value, "left4dead2") == 0)
#elif SOURCE_ENGINE == SE_ALIENSWARM
if (strcmp(value, "alienswarm") == 0)
#else
#error "Unknown engine type"
#endif
{
return true;
}
return false;
}
CGameConfig::CGameConfig(const char *file) CGameConfig::CGameConfig(const char *file)
{ {
strncopy(m_File, file, sizeof(m_File)); m_pFile = sm_strdup(file);
m_pOffsets = sm_trie_create(); m_pOffsets = sm_trie_create();
m_pProps = sm_trie_create(); m_pProps = sm_trie_create();
m_pKeys = sm_trie_create(); m_pKeys = sm_trie_create();
m_pSigs = sm_trie_create(); m_pSigs = sm_trie_create();
m_pStrings = new BaseStringTable(512); m_pStrings = new BaseStringTable(512);
m_RefCount = 0; m_RefCount = 0;
m_CustomLevel = 0;
m_CustomHandler = NULL;
} }
CGameConfig::~CGameConfig() CGameConfig::~CGameConfig()
@@ -148,6 +103,7 @@ CGameConfig::~CGameConfig()
sm_trie_destroy(m_pProps); sm_trie_destroy(m_pProps);
sm_trie_destroy(m_pKeys); sm_trie_destroy(m_pKeys);
sm_trie_destroy(m_pSigs); sm_trie_destroy(m_pSigs);
delete [] m_pFile;
delete m_pStrings; delete m_pStrings;
} }
@@ -173,9 +129,11 @@ SMCResult CGameConfig::ReadSMC_NewSection(const SMCStates *states, const char *n
} }
case PSTATE_GAMES: case PSTATE_GAMES:
{ {
if (strcmp(name, "*") == 0 || if ((strcmp(name, "*") == 0)
strcmp(name, "#default") == 0 || || (strcmp(name, "#default") == 0)
DoesGameMatch(name)) || (strcasecmp(name, g_Game) == 0)
|| (strcasecmp(name, g_GameDesc) == 0)
|| (strcasecmp(name, g_GameName) == 0))
{ {
bShouldBeReadingDefault = true; bShouldBeReadingDefault = true;
m_ParseState = PSTATE_GAMEDEFS; m_ParseState = PSTATE_GAMEDEFS;
@@ -195,15 +153,12 @@ SMCResult CGameConfig::ReadSMC_NewSection(const SMCStates *states, const char *n
{ {
m_ParseState = PSTATE_GAMEDEFS_KEYS; m_ParseState = PSTATE_GAMEDEFS_KEYS;
} }
else if ((strcmp(name, "#supported") == 0) && (strcmp(m_Game, "#default") == 0)) else if ((strcmp(name, "#supported") == 0)
&& (strcmp(m_Game, "#default") == 0))
{ {
m_ParseState = PSTATE_GAMEDEFS_SUPPORTED; m_ParseState = PSTATE_GAMEDEFS_SUPPORTED;
/* Ignore this section unless we get a game. */ /* Ignore this section unless we get a game. */
bShouldBeReadingDefault = false; bShouldBeReadingDefault = false;
had_game = false;
matched_game = false;
had_engine = false;
matched_engine = false;
} }
else if (strcmp(name, "Signatures") == 0) else if (strcmp(name, "Signatures") == 0)
{ {
@@ -216,17 +171,6 @@ SMCResult CGameConfig::ReadSMC_NewSection(const SMCStates *states, const char *n
} }
else else
{ {
ITextListener_SMC **pListen = g_GameConfigs.m_customHandlers.retrieve(name);
if (pListen != NULL)
{
m_CustomLevel = 0;
m_ParseState = PSTATE_GAMEDEFS_CUSTOM;
m_CustomHandler = *pListen;
m_CustomHandler->ReadSMC_ParseStart();
break;
}
m_IgnoreLevel++; m_IgnoreLevel++;
} }
break; break;
@@ -276,25 +220,18 @@ SMCResult CGameConfig::ReadSMC_NewSection(const SMCStates *states, const char *n
s_ServerBinCRC = UTIL_CRC32(buffer, size); s_ServerBinCRC = UTIL_CRC32(buffer, size);
free(buffer); free(buffer);
s_ServerBinCRC_Ok = true; s_ServerBinCRC_Ok = true;
fclose(fp);
} }
} }
if (error[0] != '\0') if (error[0] != '\0')
{ {
m_IgnoreLevel = 1; m_IgnoreLevel = 1;
g_Logger.LogError("[SM] Error while parsing CRC section for \"%s\" (%s):", m_Game, m_CurFile); g_Logger.LogError("[SM] Error while parsing CRC section for \"%s\" (%s):", m_Game, m_pFile);
g_Logger.LogError("[SM] %s", error); g_Logger.LogError("[SM] %s", error);
} else { } else {
m_ParseState = PSTATE_GAMEDEFS_CRC_BINARY; m_ParseState = PSTATE_GAMEDEFS_CRC_BINARY;
} }
break; break;
} }
case PSTATE_GAMEDEFS_CUSTOM:
{
m_CustomLevel++;
return m_CustomHandler->ReadSMC_NewSection(states, name);
break;
}
/* No sub-sections allowed: /* No sub-sections allowed:
case PSTATE_GAMEDEFS_OFFSETS_OFFSET: case PSTATE_GAMEDEFS_OFFSETS_OFFSET:
case PSTATE_GAMEDEFS_KEYS: case PSTATE_GAMEDEFS_KEYS:
@@ -335,29 +272,13 @@ SMCResult CGameConfig::ReadSMC_KeyValue(const SMCStates *states, const char *key
int id = m_pStrings->AddString(value); int id = m_pStrings->AddString(value);
sm_trie_replace(m_pKeys, key, (void *)id); sm_trie_replace(m_pKeys, key, (void *)id);
} else if (m_ParseState == PSTATE_GAMEDEFS_SUPPORTED) { } else if (m_ParseState == PSTATE_GAMEDEFS_SUPPORTED) {
if (strcmp(key, "game") == 0) if (strcmp(key, "game") == 0
&& (strcasecmp(value, g_Game) == 0
|| strcasecmp(value, g_GameDesc) == 0
|| strcasecmp(value, g_GameName) == 0)
)
{ {
had_game = true; bShouldBeReadingDefault = true;
if (DoesGameMatch(value))
{
matched_game = true;
}
if ((!had_engine && matched_game) || (matched_engine && matched_game))
{
bShouldBeReadingDefault = true;
}
}
else if (strcmp(key, "engine") == 0)
{
had_engine = true;
if (DoesEngineMatch(value))
{
matched_engine = true;
}
if ((!had_game && matched_engine) || (matched_game && matched_engine))
{
bShouldBeReadingDefault = true;
}
} }
} else if (m_ParseState == PSTATE_GAMEDEFS_SIGNATURES_SIG) { } else if (m_ParseState == PSTATE_GAMEDEFS_SIGNATURES_SIG) {
if (strcmp(key, PLATFORM_NAME) == 0) if (strcmp(key, PLATFORM_NAME) == 0)
@@ -378,8 +299,6 @@ SMCResult CGameConfig::ReadSMC_KeyValue(const SMCStates *states, const char *key
bShouldBeReadingDefault = true; bShouldBeReadingDefault = true;
} }
} }
} else if (m_ParseState == PSTATE_GAMEDEFS_CUSTOM) {
return m_CustomHandler->ReadSMC_KeyValue(states, key, value);
} }
return SMCResult_Continue; return SMCResult_Continue;
@@ -393,13 +312,6 @@ SMCResult CGameConfig::ReadSMC_LeavingSection(const SMCStates *states)
return SMCResult_Continue; return SMCResult_Continue;
} }
if (m_CustomLevel)
{
m_CustomLevel--;
m_CustomHandler->ReadSMC_LeavingSection(states);
return SMCResult_Continue;
}
switch (m_ParseState) switch (m_ParseState)
{ {
case PSTATE_GAMES: case PSTATE_GAMES:
@@ -412,12 +324,6 @@ SMCResult CGameConfig::ReadSMC_LeavingSection(const SMCStates *states)
m_ParseState = PSTATE_GAMES; m_ParseState = PSTATE_GAMES;
break; break;
} }
case PSTATE_GAMEDEFS_CUSTOM:
{
m_ParseState = PSTATE_GAMEDEFS;
m_CustomHandler->ReadSMC_ParseEnd(false, false);
break;
}
case PSTATE_GAMEDEFS_KEYS: case PSTATE_GAMEDEFS_KEYS:
case PSTATE_GAMEDEFS_OFFSETS: case PSTATE_GAMEDEFS_OFFSETS:
{ {
@@ -444,7 +350,7 @@ SMCResult CGameConfig::ReadSMC_LeavingSection(const SMCStates *states)
g_Logger.LogError("[SM] Unable to find property %s.%s (file \"%s\") (mod \"%s\")", g_Logger.LogError("[SM] Unable to find property %s.%s (file \"%s\") (mod \"%s\")",
m_Class, m_Class,
m_Prop, m_Prop,
m_CurFile, m_pFile,
m_Game); m_Game);
} }
} }
@@ -494,7 +400,7 @@ SMCResult CGameConfig::ReadSMC_LeavingSection(const SMCStates *states)
{ {
g_Logger.LogError("[SM] Unrecognized library \"%s\" (gameconf \"%s\")", g_Logger.LogError("[SM] Unrecognized library \"%s\" (gameconf \"%s\")",
s_TempSig.library, s_TempSig.library,
m_CurFile); m_pFile);
} else { } else {
#if defined PLATFORM_LINUX #if defined PLATFORM_LINUX
if (s_TempSig.sig[0] == '@') if (s_TempSig.sig[0] == '@')
@@ -506,21 +412,17 @@ SMCResult CGameConfig::ReadSMC_LeavingSection(const SMCStates *states)
void *handle = dlopen(info.dli_fname, RTLD_NOW); void *handle = dlopen(info.dli_fname, RTLD_NOW);
if (handle) if (handle)
{ {
#if (SOURCE_ENGINE == SE_ORANGEBOXVALVE) || (SOURCE_ENGINE == SE_LEFT4DEAD2)
final_addr = g_MemUtils.ResolveSymbol(handle, &s_TempSig.sig[1]);
#else
final_addr = dlsym(handle, &s_TempSig.sig[1]); final_addr = dlsym(handle, &s_TempSig.sig[1]);
#endif
dlclose(handle); dlclose(handle);
} else { } else {
g_Logger.LogError("[SM] Unable to load library \"%s\" (gameconf \"%s\")", g_Logger.LogError("[SM] Unable to load library \"%s\" (gameconf \"%s\")",
s_TempSig.library, s_TempSig.library,
m_File); m_pFile);
} }
} else { } else {
g_Logger.LogError("[SM] Unable to find library \"%s\" in memory (gameconf \"%s\")", g_Logger.LogError("[SM] Unable to find library \"%s\" in memory (gameconf \"%s\")",
s_TempSig.library, s_TempSig.library,
m_File); m_pFile);
} }
} }
if (final_addr) if (final_addr)
@@ -529,18 +431,45 @@ SMCResult CGameConfig::ReadSMC_LeavingSection(const SMCStates *states)
} }
#endif #endif
/* First, preprocess the signature */ /* First, preprocess the signature */
unsigned char real_sig[511]; char real_sig[511];
size_t real_bytes; size_t real_bytes;
size_t length; size_t length;
real_bytes = 0; real_bytes = 0;
length = strlen(s_TempSig.sig); length = strlen(s_TempSig.sig);
real_bytes = UTIL_DecodeHexString(real_sig, sizeof(real_sig), s_TempSig.sig); for (size_t i=0; i<length; i++)
{
if (real_bytes >= sizeof(real_sig))
{
break;
}
real_sig[real_bytes++] = s_TempSig.sig[i];
if (s_TempSig.sig[i] == '\\'
&& s_TempSig.sig[i+1] == 'x')
{
if (i + 3 >= length)
{
continue;
}
/* Get the hex part */
char s_byte[3];
int r_byte;
s_byte[0] = s_TempSig.sig[i+2];
s_byte[1] = s_TempSig.sig[i+3];
s_byte[2] = '\0';
/* Read it as an integer */
sscanf(s_byte, "%x", &r_byte);
/* Save the value */
real_sig[real_bytes-1] = r_byte;
/* Adjust index */
i += 3;
}
}
if (real_bytes >= 1) if (real_bytes >= 1)
{ {
final_addr = g_MemUtils.FindPattern(addrInBase, (char*)real_sig, real_bytes); final_addr = g_MemUtils.FindPattern(addrInBase, real_sig, real_bytes);
} }
} }
@@ -557,258 +486,42 @@ skip_find:
return SMCResult_Continue; return SMCResult_Continue;
} }
#define MSTATE_NONE 0
#define MSTATE_MAIN 1
#define MSTATE_FILE 2
class MasterReader : public ITextListener_SMC
{
public:
virtual void ReadSMC_ParseStart()
{
state = MSTATE_NONE;
ignoreLevel = 0;
}
virtual SMCResult ReadSMC_NewSection(const SMCStates *states, const char *name)
{
if (ignoreLevel)
{
return SMCResult_Continue;
}
if (state == MSTATE_NONE)
{
if (strcmp(name, "Game Master") == 0)
{
state = MSTATE_MAIN;
}
else
{
ignoreLevel++;
}
}
else if (state == MSTATE_MAIN)
{
strncopy(cur_file, name, sizeof(cur_file));
had_engine = false;
matched_engine = false;
had_game = false;
matched_game = false;
state = MSTATE_FILE;
}
else if (state == MSTATE_FILE)
{
ignoreLevel++;
}
return SMCResult_Continue;
}
virtual SMCResult ReadSMC_KeyValue(const SMCStates *states, const char *key, const char *value)
{
if (ignoreLevel || state != MSTATE_FILE)
{
return SMCResult_Continue;
}
if (strcmp(key, "engine") == 0)
{
had_engine = true;
if (DoesEngineMatch(value))
{
matched_engine = true;
}
}
else if (strcmp(key, "game") == 0)
{
had_game = true;
if (DoesGameMatch(value))
{
matched_game = true;
}
}
return SMCResult_Continue;
}
virtual SMCResult ReadSMC_LeavingSection(const SMCStates *states)
{
if (ignoreLevel)
{
ignoreLevel--;
return SMCResult_Continue;
}
if (state == MSTATE_FILE)
{
/* The four success conditions:
* 1. Needed nothing.
* 2. Needed game only.
* 3. Needed engine only.
* 4. Needed both engine and game.
* Final result is minimized via k-map.
*/
#if 0
if ((!had_engine && !had_game) ||
(!had_engine && (had_game && matched_game)) ||
(!had_game && (had_engine && matched_engine)) ||
((had_game && had_engine) && (matched_game && matched_engine)))
#endif
if ((!had_engine && !had_game) ||
(!had_engine && matched_game) ||
(!had_game && matched_engine) ||
(matched_engine && matched_game))
{
fileList->push_back(cur_file);
}
state = MSTATE_MAIN;
}
else if (state == MSTATE_MAIN)
{
state = MSTATE_NONE;
}
return SMCResult_Continue;
}
public:
List<String> *fileList;
unsigned int state;
unsigned int ignoreLevel;
char cur_file[PLATFORM_MAX_PATH];
bool had_engine;
bool matched_engine;
bool had_game;
bool matched_game;
};
static MasterReader master_reader;
bool CGameConfig::Reparse(char *error, size_t maxlength) bool CGameConfig::Reparse(char *error, size_t maxlength)
{ {
SMCError err;
SMCStates state = {0, 0};
char path[PLATFORM_MAX_PATH];
g_SourceMod.BuildPath(Path_SM, path, sizeof(path), "gamedata/%s.txt", m_pFile);
/* Backwards compatibility */
if (!g_LibSys.PathExists(path))
{
g_SourceMod.BuildPath(Path_SM, path, sizeof(path), "configs/gamedata/%s.txt", m_pFile);
}
/* Initialize parse states */
m_IgnoreLevel = 0;
bShouldBeReadingDefault = true;
m_ParseState = PSTATE_NONE;
/* Reset cached data */ /* Reset cached data */
m_pStrings->Reset(); m_pStrings->Reset();
sm_trie_clear(m_pOffsets); sm_trie_clear(m_pOffsets);
sm_trie_clear(m_pProps); sm_trie_clear(m_pProps);
sm_trie_clear(m_pKeys); sm_trie_clear(m_pKeys);
char path[PLATFORM_MAX_PATH]; if ((err=textparsers->ParseSMCFile(path, this, &state, error, maxlength))
/* See if we can use the extended gamedata format. */
g_SourceMod.BuildPath(Path_SM, path, sizeof(path), "gamedata/%s/master.games.txt", m_File);
if (!g_LibSys.PathExists(path))
{
/* Nope, use the old mechanism. */
UTIL_Format(path, sizeof(path), "%s.txt", m_File);
return EnterFile(path, error, maxlength);
}
/* Otherwise, it's time to parse the master. */
SMCError err;
SMCStates state = {0, 0};
List<String> fileList;
master_reader.fileList = &fileList;
err = textparsers->ParseSMCFile(path, &master_reader, &state, error, maxlength);
if (err != SMCError_Okay)
{
const char *msg = textparsers->GetSMCErrorString(err);
g_Logger.LogError("[SM] Error parsing master gameconf file \"%s\":", path);
g_Logger.LogError("[SM] Error %d on line %d, col %d: %s",
err,
state.line,
state.col,
msg ? msg : "Unknown error");
return false;
}
/* Go through each file we found and parse it. */
List<String>::iterator iter;
for (iter = fileList.begin(); iter != fileList.end(); iter++)
{
UTIL_Format(path, sizeof(path), "%s/%s", m_File, (*iter).c_str());
if (!EnterFile(path, error, maxlength))
{
return false;
}
}
/* Parse the contents of the 'custom' directory */
g_SourceMod.BuildPath(Path_SM, path, sizeof(path), "gamedata/%s/custom", m_File);
IDirectory *customDir = g_LibSys.OpenDirectory(path);
if (!customDir)
{
return true;
}
while (customDir->MoreFiles())
{
if (!customDir->IsEntryFile())
{
customDir->NextEntry();
continue;
}
const char *curFile = customDir->GetEntryName();
/* Only allow .txt files */
int len = strlen(curFile);
if (len > 4 && strcmp(&curFile[len-4], ".txt") != 0)
{
customDir->NextEntry();
continue;
}
UTIL_Format(path, sizeof(path), "%s/custom/%s", m_File, curFile);
if (!EnterFile(path, error, maxlength))
{
g_LibSys.CloseDirectory(customDir);
return false;
}
customDir->NextEntry();
}
g_LibSys.CloseDirectory(customDir);
return true;
}
bool CGameConfig::EnterFile(const char *file, char *error, size_t maxlength)
{
SMCError err;
SMCStates state = {0, 0};
g_SourceMod.BuildPath(Path_SM, m_CurFile, sizeof(m_CurFile), "gamedata/%s", file);
/* Initialize parse states */
m_IgnoreLevel = 0;
bShouldBeReadingDefault = true;
m_ParseState = PSTATE_NONE;
if ((err=textparsers->ParseSMCFile(m_CurFile, this, &state, error, maxlength))
!= SMCError_Okay) != SMCError_Okay)
{ {
const char *msg; const char *msg;
msg = textparsers->GetSMCErrorString(err); msg = textparsers->GetSMCErrorString(err);
g_Logger.LogError("[SM] Error parsing gameconfig file \"%s\":", m_CurFile); g_Logger.LogError("[SM] Error parsing gameconfig file \"%s\":", path);
g_Logger.LogError("[SM] Error %d on line %d, col %d: %s", g_Logger.LogError("[SM] Error %d on line %d, col %d: %s",
err, err,
state.line, state.line,
state.col, state.col,
msg ? msg : "Unknown error"); msg ? msg : "Unknown error");
if (m_ParseState == PSTATE_GAMEDEFS_CUSTOM)
{
//error occurred while parsing a custom section
m_CustomHandler->ReadSMC_ParseEnd(true, true);
m_CustomHandler = NULL;
m_CustomLevel = 0;
}
return false; return false;
} }
@@ -885,7 +598,7 @@ void GameConfigManager::OnSourceModStartup(bool late)
strncopy(g_GameDesc + 1, SERVER_CALL(GetGameDescription)(), sizeof(g_GameDesc) - 1); strncopy(g_GameDesc + 1, SERVER_CALL(GetGameDescription)(), sizeof(g_GameDesc) - 1);
KeyValues *pGameInfo = new KeyValues("GameInfo"); KeyValues *pGameInfo = new KeyValues("GameInfo");
if (g_HL2.KVLoadFromFile(pGameInfo, basefilesystem, "gameinfo.txt")) if (pGameInfo->LoadFromFile(basefilesystem, "gameinfo.txt"))
{ {
const char *str; const char *str;
if ((str = pGameInfo->GetString("game", NULL)) != NULL) if ((str = pGameInfo->GetString("game", NULL)) != NULL)
@@ -917,15 +630,6 @@ void GameConfigManager::OnSourceModAllShutdown()
bool GameConfigManager::LoadGameConfigFile(const char *file, IGameConfig **_pConfig, char *error, size_t maxlength) bool GameConfigManager::LoadGameConfigFile(const char *file, IGameConfig **_pConfig, char *error, size_t maxlength)
{ {
#if 0
/* A crash was detected during last load - We block the gamedata loading so it hopefully won't happen again */
if (g_blockGameDataLoad)
{
UTIL_Format(error, maxlength, "GameData loaded blocked due to detected crash");
return false;
}
#endif
CGameConfig *pConfig; CGameConfig *pConfig;
if (sm_trie_retrieve(m_pLookup, file, (void **)&pConfig)) if (sm_trie_retrieve(m_pLookup, file, (void **)&pConfig))
@@ -960,7 +664,7 @@ void GameConfigManager::CloseGameConfigFile(IGameConfig *cfg)
if (pConfig->DecRefCount() == 0) if (pConfig->DecRefCount() == 0)
{ {
sm_trie_delete(m_pLookup, pConfig->m_File); sm_trie_delete(m_pLookup, pConfig->m_pFile);
delete pConfig; delete pConfig;
} }
} }
@@ -980,35 +684,3 @@ IGameConfig *GameConfigManager::ReadHandle(Handle_t hndl, IdentityToken_t *ident
return conf; return conf;
} }
void GameConfigManager::AddUserConfigHook(const char *sectionname, ITextListener_SMC *listener)
{
m_customHandlers.insert(sectionname, listener);
}
void GameConfigManager::RemoveUserConfigHook(const char *sectionname, ITextListener_SMC *listener)
{
ITextListener_SMC **pListener = m_customHandlers.retrieve(sectionname);
if (pListener == NULL)
{
return;
}
if (*pListener != listener)
{
return;
}
m_customHandlers.remove(sectionname);
return;
}
void GameConfigManager::AcquireLock()
{
}
void GameConfigManager::ReleaseLock()
{
}
+2 -19
View File
@@ -2,7 +2,7 @@
* vim: set ts=4 : * vim: set ts=4 :
* ============================================================================= * =============================================================================
* SourceMod * SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
* ============================================================================= * =============================================================================
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under
@@ -38,7 +38,6 @@
#include "sm_trie.h" #include "sm_trie.h"
#include "sm_globals.h" #include "sm_globals.h"
#include "sm_memtable.h" #include "sm_memtable.h"
#include "sm_trie_tpl.h"
using namespace SourceMod; using namespace SourceMod;
using namespace SourceHook; using namespace SourceHook;
@@ -55,7 +54,6 @@ public:
~CGameConfig(); ~CGameConfig();
public: public:
bool Reparse(char *error, size_t maxlength); bool Reparse(char *error, size_t maxlength);
bool EnterFile(const char *file, char *error, size_t maxlength);
public: //ITextListener_SMC public: //ITextListener_SMC
SMCResult ReadSMC_NewSection(const SMCStates *states, const char *name); SMCResult ReadSMC_NewSection(const SMCStates *states, const char *name);
SMCResult ReadSMC_KeyValue(const SMCStates *states, const char *key, const char *value); SMCResult ReadSMC_KeyValue(const SMCStates *states, const char *key, const char *value);
@@ -70,8 +68,7 @@ public:
unsigned int DecRefCount(); unsigned int DecRefCount();
private: private:
BaseStringTable *m_pStrings; BaseStringTable *m_pStrings;
char m_File[PLATFORM_MAX_PATH]; char *m_pFile;
char m_CurFile[PLATFORM_MAX_PATH];
Trie *m_pOffsets; Trie *m_pOffsets;
Trie *m_pProps; Trie *m_pProps;
Trie *m_pKeys; Trie *m_pKeys;
@@ -85,14 +82,6 @@ private:
char m_offset[64]; char m_offset[64];
char m_Game[256]; char m_Game[256];
bool bShouldBeReadingDefault; bool bShouldBeReadingDefault;
bool had_game;
bool matched_game;
bool had_engine;
bool matched_engine;
/* Custom Sections */
unsigned int m_CustomLevel;
ITextListener_SMC *m_CustomHandler;
}; };
class GameConfigManager : class GameConfigManager :
@@ -108,10 +97,6 @@ public: //IGameConfigManager
IGameConfig *ReadHandle(Handle_t hndl, IGameConfig *ReadHandle(Handle_t hndl,
IdentityToken_t *ident, IdentityToken_t *ident,
HandleError *err); HandleError *err);
void AddUserConfigHook(const char *sectionname, ITextListener_SMC *listener);
void RemoveUserConfigHook(const char *sectionname, ITextListener_SMC *listener);
void AcquireLock();
void ReleaseLock();
public: //SMGlobalClass public: //SMGlobalClass
void OnSourceModStartup(bool late); void OnSourceModStartup(bool late);
void OnSourceModAllInitialized(); void OnSourceModAllInitialized();
@@ -119,8 +104,6 @@ public: //SMGlobalClass
private: private:
List<CGameConfig *> m_cfgs; List<CGameConfig *> m_cfgs;
Trie *m_pLookup; Trie *m_pLookup;
public:
KTrie<ITextListener_SMC *> m_customHandlers;
}; };
extern GameConfigManager g_GameConfigs; extern GameConfigManager g_GameConfigs;
+7 -421
View File
@@ -2,7 +2,7 @@
* vim: set ts=4 : * vim: set ts=4 :
* ============================================================================= * =============================================================================
* SourceMod * SourceMod
* Copyright (C) 2004-2010 AlliedModders LLC. All rights reserved. * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
* ============================================================================= * =============================================================================
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under
@@ -37,14 +37,10 @@
#include "sm_stringutil.h" #include "sm_stringutil.h"
#include "GameConfigs.h" #include "GameConfigs.h"
#include <compat_wrappers.h> #include <compat_wrappers.h>
#include <Logger.h>
CHalfLife2 g_HL2; CHalfLife2 g_HL2;
ConVar *sv_lan = NULL; ConVar *sv_lan = NULL;
static void *g_EntList = NULL;
static int entInfoOffset = -1;
namespace SourceHook namespace SourceHook
{ {
template<> template<>
@@ -92,20 +88,13 @@ CHalfLife2::~CHalfLife2()
m_Maps.clear(); m_Maps.clear();
} }
#if SOURCE_ENGINE != SE_DARKMESSIAH
CSharedEdictChangeInfo *g_pSharedChangeInfo = NULL; CSharedEdictChangeInfo *g_pSharedChangeInfo = NULL;
#endif
#if !defined METAMOD_PLAPI_VERSION || PLAPI_VERSION < 11
bool is_original_engine = false; bool is_original_engine = false;
#endif
void CHalfLife2::OnSourceModStartup(bool late) void CHalfLife2::OnSourceModStartup(bool late)
{ {
#if SOURCE_ENGINE != SE_DARKMESSIAH
/* The Ship currently is the only known game to use an older version of the engine */ /* The Ship currently is the only known game to use an older version of the engine */
#if defined METAMOD_PLAPI_VERSION || PLAPI_VERSION >= 11 #if defined METAMOD_PLAPI_VERSION
if (g_SMAPI->GetSourceEngineBuild() == SOURCE_ENGINE_ORIGINAL) if (g_SMAPI->GetSourceEngineBuild() == SOURCE_ENGINE_ORIGINAL)
#else #else
if (strcasecmp(g_SourceMod.GetGameFolderName(), "ship") == 0) if (strcasecmp(g_SourceMod.GetGameFolderName(), "ship") == 0)
@@ -117,76 +106,29 @@ void CHalfLife2::OnSourceModStartup(bool late)
{ {
g_pSharedChangeInfo = engine->GetSharedEdictChangeInfo(); g_pSharedChangeInfo = engine->GetSharedEdictChangeInfo();
} }
#endif
} }
void CHalfLife2::OnSourceModAllInitialized() void CHalfLife2::OnSourceModAllInitialized()
{ {
m_MsgTextMsg = g_UserMsgs.GetMessageIndex("TextMsg"); m_MsgTextMsg = g_UserMsgs.GetMessageIndex("TextMsg");
m_HinTextMsg = g_UserMsgs.GetMessageIndex("HintText"); m_HinTextMsg = g_UserMsgs.GetMessageIndex("HintText");
m_SayTextMsg = g_UserMsgs.GetMessageIndex("SayText");
m_VGUIMenu = g_UserMsgs.GetMessageIndex("VGUIMenu"); m_VGUIMenu = g_UserMsgs.GetMessageIndex("VGUIMenu");
g_ShareSys.AddInterface(NULL, this); g_ShareSys.AddInterface(NULL, this);
FindInSendTable("CTFPlayer", "m_nDisguiseClass");
} }
void CHalfLife2::OnSourceModAllInitialized_Post() #if !defined METAMOD_PLAPI_VERSION
{
char *addr = NULL;
#ifdef PLATFORM_WINDOWS
int offset;
/* gEntList and/or g_pEntityList */
if (!g_pGameConf->GetMemSig("LevelShutdown", (void **)&addr))
{
g_Logger.LogError("Logical Entities not supported by this mod (LevelShutdown) - Reverting to networkable entities only");
return;
}
if (!addr)
{
g_Logger.LogError("Failed lookup of LevelShutdown - Reverting to networkable entities only");
return;
}
if (!g_pGameConf->GetOffset("gEntList", &offset))
{
g_Logger.LogError("Logical Entities not supported by this mod (gEntList) - Reverting to networkable entities only");
return;
}
g_EntList = *reinterpret_cast<void **>(addr + offset);
#elif defined PLATFORM_LINUX
/* gEntList and/or g_pEntityList */
if (!g_pGameConf->GetMemSig("gEntList", (void **)&addr))
{
g_Logger.LogError("Logical Entities not supported by this mod (gEntList) - Reverting to networkable entities only");
return;
}
if (!addr)
{
g_Logger.LogError("Failed lookup of gEntList - Reverting to networkable entities only");
return;
}
g_EntList = reinterpret_cast<void *>(addr);
#endif
if (!g_pGameConf->GetOffset("EntInfo", &entInfoOffset))
{
g_Logger.LogError("Logical Entities not supported by this mod (EntInfo) - Reverting to networkable entities only");
return;
}
}
#if !defined METAMOD_PLAPI_VERSION || PLAPI_VERSION < 11
bool CHalfLife2::IsOriginalEngine() bool CHalfLife2::IsOriginalEngine()
{ {
return is_original_engine; return is_original_engine;
} }
#endif #endif
#if SOURCE_ENGINE != SE_DARKMESSIAH
IChangeInfoAccessor *CBaseEdict::GetChangeAccessor() IChangeInfoAccessor *CBaseEdict::GetChangeAccessor()
{ {
return engine->GetChangeAccessor( (const edict_t *)this ); return engine->GetChangeAccessor( (const edict_t *)this );
} }
#endif
bool UTIL_FindInSendTable(SendTable *pTable, bool UTIL_FindInSendTable(SendTable *pTable,
const char *name, const char *name,
@@ -356,7 +298,6 @@ typedescription_t *CHalfLife2::FindInDataMap(datamap_t *pMap, const char *offset
void CHalfLife2::SetEdictStateChanged(edict_t *pEdict, unsigned short offset) void CHalfLife2::SetEdictStateChanged(edict_t *pEdict, unsigned short offset)
{ {
#if SOURCE_ENGINE != SE_DARKMESSIAH
if (g_pSharedChangeInfo != NULL) if (g_pSharedChangeInfo != NULL)
{ {
if (offset) if (offset)
@@ -369,7 +310,6 @@ void CHalfLife2::SetEdictStateChanged(edict_t *pEdict, unsigned short offset)
} }
} }
else else
#endif
{ {
pEdict->m_fStateFlags |= FL_EDICT_CHANGED; pEdict->m_fStateFlags |= FL_EDICT_CHANGED;
} }
@@ -380,31 +320,6 @@ bool CHalfLife2::TextMsg(int client, int dest, const char *msg)
bf_write *pBitBuf = NULL; bf_write *pBitBuf = NULL;
cell_t players[] = {client}; cell_t players[] = {client};
if (dest == HUD_PRINTTALK)
{
const char *chat_saytext = g_pGameConf->GetKeyValue("ChatSayText");
/* Use SayText user message instead */
if (chat_saytext != NULL && strcmp(chat_saytext, "yes") == 0)
{
char buffer[192];
UTIL_Format(buffer, sizeof(buffer), "%s\1\n", msg);
if ((pBitBuf = g_UserMsgs.StartMessage(m_SayTextMsg, players, 1, USERMSG_RELIABLE)) == NULL)
{
return false;
}
pBitBuf->WriteByte(0);
pBitBuf->WriteString(buffer);
pBitBuf->WriteByte(1);
g_UserMsgs.EndMessage();
return true;
}
}
if ((pBitBuf = g_UserMsgs.StartMessage(m_MsgTextMsg, players, 1, USERMSG_RELIABLE)) == NULL) if ((pBitBuf = g_UserMsgs.StartMessage(m_MsgTextMsg, players, 1, USERMSG_RELIABLE)) == NULL)
{ {
return false; return false;
@@ -412,7 +327,6 @@ bool CHalfLife2::TextMsg(int client, int dest, const char *msg)
pBitBuf->WriteByte(dest); pBitBuf->WriteByte(dest);
pBitBuf->WriteString(msg); pBitBuf->WriteString(msg);
g_UserMsgs.EndMessage(); g_UserMsgs.EndMessage();
return true; return true;
@@ -439,26 +353,6 @@ bool CHalfLife2::HintTextMsg(int client, const char *msg)
return true; return true;
} }
bool CHalfLife2::HintTextMsg(cell_t *players, int count, const char *msg)
{
bf_write *pBitBuf = NULL;
if ((pBitBuf = g_UserMsgs.StartMessage(m_HinTextMsg, players, count, USERMSG_RELIABLE)) == NULL)
{
return false;
}
const char *pre_byte = g_pGameConf->GetKeyValue("HintTextPreByte");
if (pre_byte != NULL && strcmp(pre_byte, "yes") == 0)
{
pBitBuf->WriteByte(1);
}
pBitBuf->WriteString(msg);
g_UserMsgs.EndMessage();
return true;
}
bool CHalfLife2::ShowVGUIMenu(int client, const char *name, KeyValues *data, bool show) bool CHalfLife2::ShowVGUIMenu(int client, const char *name, KeyValues *data, bool show)
{ {
bf_write *pBitBuf = NULL; bf_write *pBitBuf = NULL;
@@ -543,53 +437,12 @@ bool CHalfLife2::IsLANServer()
return (sv_lan->GetInt() != 0); return (sv_lan->GetInt() != 0);
} }
bool CHalfLife2::KVLoadFromFile(KeyValues *kv, IBaseFileSystem *filesystem, const char *resourceName, const char *pathID)
{
#if defined METAMOD_PLAPI_VERSION || PLAPI_VERSION >= 11
if (g_SMAPI->GetSourceEngineBuild() == SOURCE_ENGINE_ORIGINAL)
#else
if (strcasecmp(g_SourceMod.GetGameFolderName(), "ship") == 0)
#endif
{
Assert(filesystem);
#ifdef _MSC_VER
Assert(_heapchk() == _HEAPOK);
#endif
FileHandle_t f = filesystem->Open(resourceName, "rb", pathID);
if (!f)
return false;
// load file into a null-terminated buffer
int fileSize = filesystem->Size(f);
char *buffer = (char *)MemAllocScratch(fileSize + 1);
Assert(buffer);
filesystem->Read(buffer, fileSize, f); // read into local buffer
buffer[fileSize] = 0; // null terminate file as EOF
filesystem->Close( f ); // close file after reading
bool retOK = kv->LoadFromBuffer( resourceName, buffer, filesystem );
MemFreeScratch();
return retOK;
}
else
{
return kv->LoadFromFile(filesystem, resourceName, pathID);
}
}
void CHalfLife2::PushCommandStack(const CCommand *cmd) void CHalfLife2::PushCommandStack(const CCommand *cmd)
{ {
CachedCommandInfo info; CachedCommandInfo info;
info.args = cmd; info.args = cmd;
#if SOURCE_ENGINE <= SE_DARKMESSIAH #if !defined ORANGEBOX_BUILD
strncopy(info.cmd, cmd->Arg(0), sizeof(info.cmd)); strncopy(info.cmd, cmd->Arg(0), sizeof(info.cmd));
#endif #endif
@@ -613,276 +466,9 @@ void CHalfLife2::PopCommandStack()
const char *CHalfLife2::CurrentCommandName() const char *CHalfLife2::CurrentCommandName()
{ {
#if SOURCE_ENGINE >= SE_ORANGEBOX #if defined ORANGEBOX_BUILD
return m_CommandStack.front().args->Arg(0); return m_CommandStack.front().args->Arg(0);
#else #else
return m_CommandStack.front().cmd; return m_CommandStack.front().cmd;
#endif #endif
} }
void CHalfLife2::AddDelayedKick(int client, int userid, const char *msg)
{
DelayedKickInfo kick;
kick.client = client;
kick.userid = userid;
UTIL_Format(kick.buffer, sizeof(kick.buffer), "%s", msg);
m_DelayedKicks.push(kick);
}
void CHalfLife2::ProcessDelayedKicks()
{
while (!m_DelayedKicks.empty())
{
DelayedKickInfo info = m_DelayedKicks.first();
m_DelayedKicks.pop();
CPlayer *player = g_Players.GetPlayerByIndex(info.client);
if (player == NULL || player->GetUserId() != info.userid)
{
continue;
}
player->Kick(info.buffer);
}
}
edict_t *CHalfLife2::EdictOfIndex(int index)
{
return ::PEntityOfEntIndex(index);
}
int CHalfLife2::IndexOfEdict(edict_t *pEnt)
{
return ::IndexOfEdict(pEnt);
}
edict_t *CHalfLife2::GetHandleEntity(CBaseHandle &hndl)
{
if (!hndl.IsValid())
{
return NULL;
}
int index = hndl.GetEntryIndex();
edict_t *pStoredEdict;
CBaseEntity *pStoredEntity;
if (!IndexToAThings(index, &pStoredEntity, &pStoredEdict))
{
return NULL;
}
if (pStoredEdict == NULL || pStoredEntity == NULL)
{
return NULL;
}
IServerEntity *pSE = pStoredEdict->GetIServerEntity();
if (pSE == NULL)
{
return NULL;
}
if (pSE->GetRefEHandle() != hndl)
{
return NULL;
}
return pStoredEdict;
}
void CHalfLife2::SetHandleEntity(CBaseHandle &hndl, edict_t *pEnt)
{
IServerEntity *pEntOther = pEnt->GetIServerEntity();
if (pEntOther == NULL)
{
return;
}
hndl.Set(pEntOther);
}
const char *CHalfLife2::GetCurrentMap()
{
return STRING(gpGlobals->mapname);
}
void CHalfLife2::ServerCommand(const char *buffer)
{
engine->ServerCommand(buffer);
}
cell_t CHalfLife2::EntityToReference(CBaseEntity *pEntity)
{
IServerUnknown *pUnknown = (IServerUnknown *)pEntity;
CBaseHandle hndl = pUnknown->GetRefEHandle();
return (hndl.ToInt() | (1<<31));
}
CBaseEntity *CHalfLife2::ReferenceToEntity(cell_t entRef)
{
CEntInfo *pInfo = NULL;
if (entRef & (1<<31))
{
/* Proper ent reference */
int hndlValue = entRef & ~(1<<31);
CBaseHandle hndl(hndlValue);
pInfo = LookupEntity(hndl.GetEntryIndex());
if (pInfo->m_SerialNumber != hndl.GetSerialNumber())
{
return NULL;
}
}
else
{
/* Old style index only */
pInfo = LookupEntity(entRef);
}
if (!pInfo)
{
return NULL;
}
IServerUnknown *pUnk = static_cast<IServerUnknown *>(pInfo->m_pEntity);
if (pUnk)
{
return pUnk->GetBaseEntity();
}
return NULL;
}
/**
* Retrieves the CEntInfo pointer from g_EntList for a given entity index
*/
CEntInfo *CHalfLife2::LookupEntity(int entIndex)
{
if (!g_EntList || entInfoOffset == -1)
{
/* Attempt to use engine interface instead */
static CEntInfo tempInfo;
tempInfo.m_pNext = NULL;
tempInfo.m_pPrev = NULL;
edict_t *pEdict = PEntityOfEntIndex(entIndex);
if (!pEdict)
{
return NULL;
}
IServerUnknown *pUnk = pEdict->GetUnknown();
if (!pUnk)
{
return NULL;
}
tempInfo.m_pEntity = pUnk;
tempInfo.m_SerialNumber = pUnk->GetRefEHandle().GetSerialNumber();
return &tempInfo;
}
CEntInfo *pArray = (CEntInfo *)(((unsigned char *)g_EntList) + entInfoOffset);
return &pArray[entIndex];
}
/**
SERIAL_MASK = 0x7fff (15 bits)
#define MAX_EDICT_BITS 11
#define NUM_ENT_ENTRY_BITS (MAX_EDICT_BITS + 1)
m_Index = iEntry | (iSerialNumber << NUM_ENT_ENTRY_BITS);
Top 5 bits of a handle are unused.
Bit 31 - Our 'reference' flag indicator
*/
cell_t CHalfLife2::IndexToReference(int entIndex)
{
CBaseEntity *pEnt = ReferenceToEntity(entIndex);
if (!pEnt)
{
return INVALID_EHANDLE_INDEX;
}
return EntityToReference(pEnt);
}
int CHalfLife2::ReferenceToIndex(cell_t entRef)
{
if ((unsigned)entRef == INVALID_EHANDLE_INDEX)
{
return INVALID_EHANDLE_INDEX;
}
if (entRef & (1<<31))
{
/* Proper ent reference */
int hndlValue = entRef & ~(1<<31);
CBaseHandle hndl(hndlValue);
CEntInfo *pInfo = LookupEntity(hndl.GetEntryIndex());
if (pInfo->m_SerialNumber != hndl.GetSerialNumber())
{
return INVALID_EHANDLE_INDEX;
}
return hndl.GetEntryIndex();
}
return entRef;
}
cell_t CHalfLife2::EntityToBCompatRef(CBaseEntity *pEntity)
{
if (pEntity == NULL)
{
return INVALID_EHANDLE_INDEX;
}
IServerUnknown *pUnknown = (IServerUnknown *)pEntity;
CBaseHandle hndl = pUnknown->GetRefEHandle();
if (hndl.GetEntryIndex() >= MAX_EDICTS)
{
return (hndl.ToInt() | (1<<31));
}
else
{
return hndl.GetEntryIndex();
}
}
cell_t CHalfLife2::ReferenceToBCompatRef(cell_t entRef)
{
if ((unsigned)entRef == INVALID_EHANDLE_INDEX)
{
return INVALID_EHANDLE_INDEX;
}
int hndlValue = entRef & ~(1<<31);
CBaseHandle hndl(hndlValue);
if (hndl.GetEntryIndex() < MAX_EDICTS)
{
return hndl.GetEntryIndex();
}
return entRef;
}
void *CHalfLife2::GetGlobalEntityList()
{
return g_EntList;
}
+3 -43
View File
@@ -2,7 +2,7 @@
* vim: set ts=4 : * vim: set ts=4 :
* ============================================================================= * =============================================================================
* SourceMod * SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
* ============================================================================= * =============================================================================
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under
@@ -43,7 +43,6 @@
#include <KeyValues.h> #include <KeyValues.h>
#include <server_class.h> #include <server_class.h>
#include <datamap.h> #include <datamap.h>
#include <ihandleentity.h>
class CCommand; class CCommand;
@@ -75,27 +74,11 @@ struct DelayedFakeCliCmd
struct CachedCommandInfo struct CachedCommandInfo
{ {
const CCommand *args; const CCommand *args;
#if SOURCE_ENGINE <= SE_DARKMESSIAH #if !defined ORANGEBOX_BUILD
char cmd[300]; char cmd[300];
#endif #endif
}; };
struct DelayedKickInfo
{
int userid;
int client;
char buffer[384];
};
class CEntInfo
{
public:
IHandleEntity *m_pEntity;
int m_SerialNumber;
CEntInfo *m_pPrev;
CEntInfo *m_pNext;
};
class CHalfLife2 : class CHalfLife2 :
public SMGlobalClass, public SMGlobalClass,
public IGameHelpers public IGameHelpers
@@ -106,7 +89,6 @@ public:
public: public:
void OnSourceModStartup(bool late); void OnSourceModStartup(bool late);
void OnSourceModAllInitialized(); void OnSourceModAllInitialized();
void OnSourceModAllInitialized_Post();
/*void OnSourceModAllShutdown();*/ /*void OnSourceModAllShutdown();*/
public: //IGameHelpers public: //IGameHelpers
SendProp *FindInSendTable(const char *classname, const char *offset); SendProp *FindInSendTable(const char *classname, const char *offset);
@@ -117,24 +99,8 @@ public: //IGameHelpers
void SetEdictStateChanged(edict_t *pEdict, unsigned short offset); void SetEdictStateChanged(edict_t *pEdict, unsigned short offset);
bool TextMsg(int client, int dest, const char *msg); bool TextMsg(int client, int dest, const char *msg);
bool HintTextMsg(int client, const char *msg); bool HintTextMsg(int client, const char *msg);
bool HintTextMsg(cell_t *players, int count, const char *msg);
bool ShowVGUIMenu(int client, const char *name, KeyValues *data, bool show); bool ShowVGUIMenu(int client, const char *name, KeyValues *data, bool show);
bool IsLANServer(); bool IsLANServer();
bool KVLoadFromFile(KeyValues *kv, IBaseFileSystem *filesystem, const char *resourceName, const char *pathID = NULL);
edict_t *EdictOfIndex(int index);
int IndexOfEdict(edict_t *pEnt);
edict_t *GetHandleEntity(CBaseHandle &hndl);
void SetHandleEntity(CBaseHandle &hndl, edict_t *pEnt);
const char *GetCurrentMap();
void ServerCommand(const char *buffer);
CBaseEntity *ReferenceToEntity(cell_t entRef);
cell_t EntityToReference(CBaseEntity *pEntity);
cell_t IndexToReference(int entIndex);
int ReferenceToIndex(cell_t entRef);
cell_t ReferenceToBCompatRef(cell_t entRef);
CEntInfo *LookupEntity(int entIndex);
cell_t EntityToBCompatRef(CBaseEntity *pEntity);
void *GetGlobalEntityList();
public: public:
void AddToFakeCliCmdQueue(int client, int userid, const char *cmd); void AddToFakeCliCmdQueue(int client, int userid, const char *cmd);
void ProcessFakeCliCmdQueue(); void ProcessFakeCliCmdQueue();
@@ -143,9 +109,7 @@ public:
void PopCommandStack(); void PopCommandStack();
const CCommand *PeekCommandStack(); const CCommand *PeekCommandStack();
const char *CurrentCommandName(); const char *CurrentCommandName();
void AddDelayedKick(int client, int userid, const char *msg); #if !defined METAMOD_PLAPI_VERSION
void ProcessDelayedKicks();
#if !defined METAMOD_PLAPI_VERSION || PLAPI_VERSION < 11
bool IsOriginalEngine(); bool IsOriginalEngine();
#endif #endif
private: private:
@@ -156,16 +120,12 @@ private:
THash<datamap_t *, DataMapTrie> m_Maps; THash<datamap_t *, DataMapTrie> m_Maps;
int m_MsgTextMsg; int m_MsgTextMsg;
int m_HinTextMsg; int m_HinTextMsg;
int m_SayTextMsg;
int m_VGUIMenu; int m_VGUIMenu;
Queue<DelayedFakeCliCmd *> m_CmdQueue; Queue<DelayedFakeCliCmd *> m_CmdQueue;
CStack<DelayedFakeCliCmd *> m_FreeCmds; CStack<DelayedFakeCliCmd *> m_FreeCmds;
CStack<CachedCommandInfo> m_CommandStack; CStack<CachedCommandInfo> m_CommandStack;
Queue<DelayedKickInfo> m_DelayedKicks;
}; };
extern CHalfLife2 g_HL2; extern CHalfLife2 g_HL2;
bool IndexToAThings(cell_t, CBaseEntity **pEntData, edict_t **pEdictData);
#endif //_INCLUDE_SOURCEMOD_CHALFLIFE2_H_ #endif //_INCLUDE_SOURCEMOD_CHALFLIFE2_H_
+9 -47
View File
@@ -1,8 +1,8 @@
/** /**
* vim: set ts=4 sw=4 : * vim: set ts=4 :
* ============================================================================= * =============================================================================
* SourceMod * SourceMod
* Copyright (C) 2004-2009 AlliedModders LLC. All rights reserved. * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
* ============================================================================= * =============================================================================
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under
@@ -34,9 +34,9 @@
#include "sourcemm_api.h" #include "sourcemm_api.h"
#include "sm_stringutil.h" #include "sm_stringutil.h"
#include "Logger.h" #include "Logger.h"
#include "LibrarySys.h" #include "systems/LibrarySys.h"
#include "TimerSys.h" #include "TimerSys.h"
#include <sourcemod_version.h> #include "sm_version.h"
Logger g_Logger; Logger g_Logger;
@@ -149,7 +149,7 @@ void Logger::_NewMapFile()
} else { } else {
char date[32]; char date[32];
strftime(date, sizeof(date), "%m/%d/%Y - %H:%M:%S", curtime); 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, SM_FULL_VERSION); 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, SVN_FULL_VERSION);
fclose(fp); fclose(fp);
} }
} }
@@ -245,19 +245,6 @@ void Logger::LogToOpenFile(FILE *fp, const char *msg, ...)
va_end(ap); va_end(ap);
} }
void Logger::LogToFileOnly(FILE *fp, const char *msg, ...)
{
if (!m_Active)
{
return;
}
va_list ap;
va_start(ap, msg);
LogToFileOnlyEx(fp, msg, ap);
va_end(ap);
}
void Logger::LogToOpenFileEx(FILE *fp, const char *msg, va_list ap) void Logger::LogToOpenFileEx(FILE *fp, const char *msg, va_list ap)
{ {
if (!m_Active) if (!m_Active)
@@ -278,26 +265,6 @@ void Logger::LogToOpenFileEx(FILE *fp, const char *msg, va_list ap)
g_SMAPI->ConPrintf("L %s: %s\n", date, buffer); g_SMAPI->ConPrintf("L %s: %s\n", date, buffer);
} }
void Logger::LogToFileOnlyEx(FILE *fp, const char *msg, va_list ap)
{
if (!m_Active)
{
return;
}
char buffer[3072];
UTIL_FormatArgs(buffer, sizeof(buffer), msg, ap);
char date[32];
time_t t;
GetAdjustedTime(&t);
tm *curtime = localtime(&t);
strftime(date, sizeof(date), "%m/%d/%Y - %H:%M:%S", curtime);
fprintf(fp, "L %s: %s\n", date, buffer);
fflush(fp);
}
void Logger::LogMessage(const char *vafmt, ...) void Logger::LogMessage(const char *vafmt, ...)
{ {
if (!m_Active) if (!m_Active)
@@ -356,7 +323,7 @@ void Logger::LogMessage(const char *vafmt, ...)
char date[32]; char date[32];
m_DailyPrintHdr = false; m_DailyPrintHdr = false;
strftime(date, sizeof(date), "%m/%d/%Y - %H:%M:%S", curtime); 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, SM_FULL_VERSION); 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, SVN_FULL_VERSION);
} }
va_list ap; va_list ap;
va_start(ap, vafmt); va_start(ap, vafmt);
@@ -378,14 +345,6 @@ print_error:
} }
void Logger::LogError(const char *vafmt, ...) void Logger::LogError(const char *vafmt, ...)
{
va_list ap;
va_start(ap, vafmt);
LogErrorEx(vafmt, ap);
va_end(ap);
}
void Logger::LogErrorEx(const char *vafmt, va_list ap)
{ {
if (!m_Active) if (!m_Active)
{ {
@@ -416,7 +375,10 @@ void Logger::LogErrorEx(const char *vafmt, va_list ap)
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); 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; m_ErrMapStart = true;
} }
va_list ap;
va_start(ap, vafmt);
LogToOpenFileEx(fp, vafmt, ap); LogToOpenFileEx(fp, vafmt, ap);
va_end(ap);
fclose(fp); fclose(fp);
} }
else else
+1 -5
View File
@@ -2,7 +2,7 @@
* vim: set ts=4 : * vim: set ts=4 :
* ============================================================================= * =============================================================================
* SourceMod * SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
* ============================================================================= * =============================================================================
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under
@@ -75,13 +75,9 @@ public:
void DisableLogging(); void DisableLogging();
void LogMessage(const char *msg, ...); void LogMessage(const char *msg, ...);
void LogError(const char *msg, ...); void LogError(const char *msg, ...);
void LogErrorEx(const char *msg, va_list ap);
void LogFatal(const char *msg, ...); void LogFatal(const char *msg, ...);
void LogToOpenFile(FILE *fp, const char *msg, ...); void LogToOpenFile(FILE *fp, const char *msg, ...);
void LogToOpenFileEx(FILE *fp, const char *msg, va_list ap); void LogToOpenFileEx(FILE *fp, const char *msg, va_list ap);
/* 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); void MapChange(const char *mapname);
const char *GetLogFileName(LogType type) const; const char *GetLogFileName(LogType type) const;
LoggingMode GetLoggingMode() const; LoggingMode GetLoggingMode() const;
+81 -129
View File
@@ -1,181 +1,133 @@
# (C)2004-2008 SourceMod Development Team #(C)2004-2008 Metamod:Source Development Team
# Makefile written by David "BAILOPAN" Anderson # Makefile written by David "BAILOPAN" Anderson
SMSDK = .. #Local paths
SRCDS_BASE = ~/srcds
HL2SDK_ORIG = ../../hl2sdk HL2SDK_ORIG = ../../hl2sdk
HL2SDK_OB = ../../hl2sdk-ob HL2SDK_OB = ../../hl2sdk-ob
HL2SDK_OB_VALVE = ../../hl2sdk-ob-valve SOURCEMM14 = ../../sourcemm-1.4
HL2SDK_L4D = ../../hl2sdk-l4d SOURCEMM16 = ../../sourcemm-1.6
HL2SDK_L4D2 = ../../hl2sdk-l4d2 SRCDS_BASE = ~/srcds
MMSOURCE17 = ../../mmsource-central SMSDK = ..
#Project options
OPT_FLAGS = -O3 -funroll-loops -pipe -fno-strict-aliasing
GCC4_FLAGS = -fvisibility=hidden
GCC4_CPP_FLAGS = -fvisibility-inlines-hidden
DEBUG_FLAGS = -g -ggdb3
CPP = gcc-4.1
#####################################
### EDIT BELOW FOR OTHER PROJECTS ###
#####################################
OBJECTS = AdminCache.cpp CDataPack.cpp ConCmdManager.cpp ConVarManager.cpp CoreConfig.cpp \ OBJECTS = AdminCache.cpp CDataPack.cpp ConCmdManager.cpp ConVarManager.cpp CoreConfig.cpp \
Database.cpp DebugReporter.cpp EventManager.cpp GameConfigs.cpp HalfLife2.cpp Logger.cpp \ Database.cpp DebugReporter.cpp EventManager.cpp GameConfigs.cpp HalfLife2.cpp Logger.cpp \
MemoryUtils.cpp PlayerManager.cpp TimerSys.cpp Translator.cpp UserMessages.cpp \ MemoryUtils.cpp PlayerManager.cpp TextParsers.cpp TimerSys.cpp Translator.cpp UserMessages.cpp \
sm_autonatives.cpp sm_memtable.cpp sm_srvcmds.cpp sm_stringutil.cpp sm_trie.cpp \ sm_autonatives.cpp sm_memtable.cpp sm_srvcmds.cpp sm_stringutil.cpp sm_trie.cpp \
sourcemm_api.cpp sourcemod.cpp MenuStyle_Base.cpp MenuStyle_Valve.cpp MenuManager.cpp \ sourcemm_api.cpp sourcemod.cpp MenuStyle_Base.cpp MenuStyle_Valve.cpp MenuManager.cpp \
MenuStyle_Radio.cpp ChatTriggers.cpp ADTFactory.cpp MenuVoting.cpp sm_crc32.cpp \ MenuStyle_Radio.cpp ChatTriggers.cpp ADTFactory.cpp MenuVoting.cpp sm_crc32.cpp \
frame_hooks.cpp concmd_cleaner.cpp PhraseCollection.cpp NextMap.cpp \ frame_hooks.cpp concmd_cleaner.cpp Profiler.cpp
NativeOwner.cpp logic_bridge.cpp ConsoleDetours.cpp
OBJECTS += smn_admin.cpp smn_bitbuffer.cpp smn_console.cpp smn_core.cpp \ OBJECTS += smn_admin.cpp smn_bitbuffer.cpp smn_console.cpp smn_core.cpp \
smn_datapacks.cpp smn_entities.cpp smn_events.cpp smn_fakenatives.cpp \ smn_datapacks.cpp smn_entities.cpp smn_events.cpp smn_fakenatives.cpp \
smn_filesystem.cpp smn_gameconfigs.cpp smn_halflife.cpp \ smn_filesystem.cpp smn_float.cpp smn_functions.cpp smn_gameconfigs.cpp smn_halflife.cpp \
smn_handles.cpp smn_keyvalues.cpp smn_banning.cpp \ smn_handles.cpp smn_keyvalues.cpp smn_banning.cpp smn_maplists.cpp \
smn_lang.cpp smn_player.cpp smn_string.cpp smn_timers.cpp \ smn_lang.cpp smn_player.cpp smn_string.cpp smn_sorting.cpp smn_textparse.cpp smn_timers.cpp \
smn_usermsgs.cpp smn_menus.cpp smn_database.cpp smn_vector.cpp \ smn_usermsgs.cpp smn_menus.cpp smn_database.cpp smn_vector.cpp smn_adt_array.cpp \
smn_hudtext.cpp smn_nextmap.cpp smn_adt_trie.cpp smn_hudtext.cpp
OBJECTS += ExtensionSys.cpp \ OBJECTS += systems/ExtensionSys.cpp systems/ForwardSys.cpp systems/HandleSys.cpp \
ForwardSys.cpp \ systems/LibrarySys.cpp systems/PluginInfoDatabase.cpp systems/PluginSys.cpp \
HandleSys.cpp \ systems/ShareSys.cpp vm/sp_vm_basecontext.cpp vm/sp_vm_function.cpp
LibrarySys.cpp \ OBJECTS += thread/ThreadWorker.cpp thread/BaseWorker.cpp thread/PosixThreads.cpp ThreadSupport.cpp
PluginInfoDatabase.cpp \ OBJECTS_C = zlib/adler32.c zlib/compress.c zlib/crc32.c zlib/deflate.c zlib/gzio.c \
PluginSys.cpp \ zlib/infback.c zlib/inffast.c zlib/inflate.c zlib/inftrees.c zlib/trees.c \
ShareSys.cpp \ zlib/uncompr.c zlib/zutil.c
NativeInvoker.cpp OBJECTS_SM16 = vm/sp_vm_engine.cpp
##############################################
### CONFIGURE ANY OTHER FLAGS/OPTIONS HERE ###
##############################################
C_OPT_FLAGS = -DNDEBUG -O3 -funroll-loops -pipe -fno-strict-aliasing
C_DEBUG_FLAGS = -D_DEBUG -DDEBUG -g -ggdb3
C_GCC4_FLAGS = -fvisibility=hidden
CPP_GCC4_FLAGS = -fvisibility-inlines-hidden
CPP = gcc
override ENGSET = false
ifeq "$(ENGINE)" "original" ifeq "$(ENGINE)" "original"
HL2SDK = $(HL2SDK_ORIG) HL2SDK = $(HL2SDK_ORIG)
HL2PUB = $(HL2SDK)/public HL2PUB = $(HL2SDK_ORIG)/public
HL2LIB = $(HL2SDK)/linux_sdk HL2LIB = $(HL2SDK)/linux_sdk
CFLAGS += -DSOURCE_ENGINE=1 METAMOD = $(SOURCEMM14)
METAMOD = $(MMSOURCE17)/core-legacy INCLUDE += -I$(HL2PUB)/dlls
INCLUDE += -I$(HL2SDK)/public/dlls
SRCDS = $(SRCDS_BASE) SRCDS = $(SRCDS_BASE)
BINARY = sourcemod.1.ep1.so BINARY = sourcemod.1.ep1.so
override ENGSET = true
endif endif
ifeq "$(ENGINE)" "orangebox" ifeq "$(ENGINE)" "orangebox"
HL2SDK = $(HL2SDK_OB) HL2SDK = $(HL2SDK_OB)
HL2PUB = $(HL2SDK)/public HL2PUB = $(HL2SDK_OB)/public
HL2LIB = $(HL2SDK)/lib/linux HL2LIB = $(HL2SDK)/linux_sdk
CFLAGS += -DSOURCE_ENGINE=3 CFLAGS += -DORANGEBOX_BUILD
METAMOD = $(MMSOURCE17)/core METAMOD = $(SOURCEMM16)
INCLUDE += -I$(HL2SDK)/public/game/server INCLUDE += -I$(HL2PUB)/game/server
SRCDS = $(SRCDS_BASE)/orangebox SRCDS = $(SRCDS_BASE)/orangebox
BINARY = sourcemod.2.ep2.so BINARY = sourcemod.2.ep2.so
override ENGSET = true
endif endif
ifeq "$(ENGINE)" "orangeboxvalve" ifeq "$(BINARY)" ""
HL2SDK = $(HL2SDK_OB_VALVE) echo "You must supply ENGINE=orangebox or ENGINE=original"
HL2PUB = $(HL2SDK)/public false
HL2LIB = $(HL2SDK)/lib/linux
CFLAGS += -DSOURCE_ENGINE=4
METAMOD = $(MMSOURCE17)/core
INCLUDE += -I$(HL2SDK)/public/game/server -I$(HL2SDK)/common
SRCDS = $(SRCDS_BASE)/orangebox
BINARY = sourcemod.2.ep2v.so
override ENGSET = true
endif
ifeq "$(ENGINE)" "left4dead"
HL2SDK = $(HL2SDK_L4D)
HL2PUB = $(HL2SDK)/public
HL2LIB = $(HL2SDK)/lib/linux
CFLAGS += -DSOURCE_ENGINE=5
METAMOD = $(MMSOURCE17)/core
INCLUDE += -I$(HL2SDK)/public/game/server
SRCDS = $(SRCDS_BASE)/l4d
BINARY = sourcemod.2.l4d.so
override ENGSET = true
endif
ifeq "$(ENGINE)" "left4dead2"
HL2SDK = $(HL2SDK_L4D2)
HL2PUB = $(HL2SDK)/public
HL2LIB = $(HL2SDK)/lib/linux
CFLAGS += -DSOURCE_ENGINE=6
METAMOD = $(MMSOURCE17)/core
INCLUDE += -I$(HL2SDK)/public/game/server
SRCDS = $(SRCDS_BASE)/left4dead2
BINARY = sourcemod.2.l4d2.so
override ENGSET = true
endif endif
CFLAGS += -DSE_EPISODEONE=1 -DSE_DARKMESSIAH=2 -DSE_ORANGEBOX=3 -DSE_ORANGEBOXVALVE=4 -DSE_LEFT4DEAD=5 -DSE_LEFT4DEAD2=6
ifeq "$(ENGINE)" "left4dead2"
LINK += $(HL2LIB)/tier1_i486.a $(HL2LIB)/mathlib_i486.a libvstdlib.so \
libtier0.so -static-libgcc
else
LINK += $(HL2LIB)/tier1_i486.a $(HL2LIB)/mathlib_i486.a vstdlib_i486.so \ LINK += $(HL2LIB)/tier1_i486.a $(HL2LIB)/mathlib_i486.a vstdlib_i486.so \
tier0_i486.so -static-libgcc tier0_i486.so -lpthread -static-libgcc
endif
INCLUDE += -I. -I.. -I$(HL2PUB) -I$(HL2PUB)/engine -I$(HL2PUB)/mathlib -I$(HL2PUB)/vstdlib \
-I$(HL2PUB)/tier0 -I$(HL2PUB)/tier1 -I$(METAMOD) -I$(METAMOD)/sourcehook \
-I$(SMSDK)/public -I$(SMSDK)/public/sourcepawn
CFLAGS += -D_LINUX -Dstricmp=strcasecmp -D_stricmp=strcasecmp -D_strnicmp=strncasecmp -Dstrnicmp=strncasecmp \ INCLUDE_SMSDK = -I$(SMSDK)/public -I$(SMSDK)/public/sourcepawn -I$(SMSDK)/public/extensions
-D_snprintf=snprintf -D_vsnprintf=vsnprintf -D_alloca=alloca -Dstrcmpi=strcasecmp -Wall -Werror \
-Wno-uninitialized -mfpmath=sse -msse -DSOURCEMOD_BUILD -DHAVE_STDINT_H -DSM_DEFAULT_THREADER -m32
CPPFLAGS += -Wno-non-virtual-dtor -fno-exceptions -fno-rtti
################################################ INCLUDE += -I. -I.. -I$(HL2PUB) -I$(HL2PUB)/dlls -I$(HL2PUB)/engine -I$(HL2PUB)/tier0 -I$(HL2PUB)/tier1 \
### DO NOT EDIT BELOW HERE FOR MOST PROJECTS ### -I$(HL2PUB)/vstdlib -I$(HL2SDK)/tier1 -I$(METAMOD) -I$(METAMOD)/sourcehook -I$(METAMOD)/sourcemm \
################################################ -I$(HL2PUB)/mathlib -Isystems $(INCLUDE_SMSDK)
SM16_INCLUDE = -I. -I.. -I$(SOURCEMM16)/sourcehook $(INCLUDE_SMSDK)
ifeq "$(DEBUG)" "true" ifeq "$(DEBUG)" "true"
BIN_DIR = Debug.$(ENGINE) BIN_DIR = Debug.$(ENGINE)
CFLAGS += $(C_DEBUG_FLAGS) CFLAGS += $(DEBUG_FLAGS)
else else
BIN_DIR = Release.$(ENGINE) BIN_DIR = Release.$(ENGINE)
CFLAGS += $(C_OPT_FLAGS) CFLAGS += $(OPT_FLAGS)
endif endif
GCC_VERSION := $(shell $(CPP) -dumpversion >&1 | cut -b1) GCC_VERSION := $(shell $(CPP) -dumpversion >&1 | cut -b1)
CFLAGS += -D_LINUX -DNDEBUG -Dstricmp=strcasecmp -D_stricmp=strcasecmp -D_strnicmp=strncasecmp \
-Dstrnicmp=strncasecmp -D_snprintf=snprintf -D_vsnprintf=vsnprintf -D_alloca=alloca \
-Dstrcmpi=strcasecmp -Wall -Wno-uninitialized -Werror -mfpmath=sse -msse \
-DSOURCEMOD_BUILD -DSM_DEFAULT_THREADER -m32
CPPFLAGS = -Wno-non-virtual-dtor -fno-exceptions -fno-rtti
ifeq "$(GCC_VERSION)" "4" ifeq "$(GCC_VERSION)" "4"
CFLAGS += $(C_GCC4_FLAGS) CFLAGS += $(GCC4_FLAGS)
CPPFLAGS += $(CPP_GCC4_FLAGS) CPPFLAGS += $(GCC4_CPP_FLAGS)
endif endif
OBJ_LINUX := $(OBJECTS:%.cpp=$(BIN_DIR)/%.o) OBJ_LINUX := $(OBJECTS:%.cpp=$(BIN_DIR)/%.ox)
OBJ_LINUX := $(OBJ_LINUX:%.c=$(BIN_DIR)/%.o) OBJ_LINUX_C := $(OBJECTS_C:%.c=$(BIN_DIR)/%.oc)
OBJ_LINUX_SM16 := $(OBJECTS_SM16:%.cpp=$(BIN_DIR)/%.ok)
$(BIN_DIR)/%.o: %.cpp $(BIN_DIR)/%.ox: %.cpp
$(CPP) $(INCLUDE) $(CFLAGS) $(CPPFLAGS) -o $@ -c $< $(CPP) $(INCLUDE) $(CFLAGS) $(CPPFLAGS) -o $@ -c $<
$(BIN_DIR)/%.o: %.c $(BIN_DIR)/%.oc: %.c
$(CPP) $(INCLUDE) $(CFLAGS) -o $@ -c $< $(CPP) $(INCLUDE) $(CFLAGS) -o $@ -c $<
all: check $(BIN_DIR)/%.ok: %.cpp
mkdir -p $(BIN_DIR) $(CPP) $(SM16_INCLUDE) $(CFLAGS) $(CPPFLAGS) -o $@ -c $<
ifeq "$(ENGINE)" "left4dead2"
ln -sf $(SRCDS)/bin/libvstdlib.so libvstdlib.so; all:
ln -sf $(SRCDS)/bin/libtier0.so libtier0.so; mkdir -p $(BIN_DIR)/systems
else mkdir -p $(BIN_DIR)/vm
ln -sf $(SRCDS)/bin/vstdlib_i486.so vstdlib_i486.so; mkdir -p $(BIN_DIR)/zlib
ln -sf $(SRCDS)/bin/tier0_i486.so tier0_i486.so; mkdir -p $(BIN_DIR)/thread
endif ln -sf $(SRCDS)/bin/vstdlib_i486.so vstdlib_i486.so
ln -sf $(SRCDS)/bin/tier0_i486.so tier0_i486.so
$(MAKE) -f Makefile sourcemod $(MAKE) -f Makefile sourcemod
check: sourcemod: $(OBJ_LINUX) $(OBJ_LINUX_C) $(OBJ_LINUX_SM16)
if [ "$(ENGSET)" = "false" ]; then \ $(CPP) $(OBJ_LINUX) $(OBJ_LINUX_C) $(OBJ_LINUX_SM16) $(LINK) -m32 -shared -ldl -lm -o$(BIN_DIR)/$(BINARY)
echo "You must supply ENGINE=left4dead or ENGINE=orangebox or ENGINE=original"; \
exit 1; \
fi
sourcemod: check $(OBJ_LINUX)
$(CPP) $(INCLUDE) $(OBJ_LINUX) $(LINK) -m32 -shared -ldl -lm -o$(BIN_DIR)/$(BINARY)
debug:
$(MAKE) -f Makefile all DEBUG=true
default: all default: all
clean: check clean:
rm -rf $(BIN_DIR)/*.o rm -rf $(BIN_DIR)/*.ox
rm -rf $(BIN_DIR)/systems/*.ox
rm -rf $(BIN_DIR)/zlib/*.oc
rm -rf $(BIN_DIR)/vm/*.ox
rm -rf $(BIN_DIR)/thread/*.ox
rm -rf $(BIN_DIR)/$(BINARY) rm -rf $(BIN_DIR)/$(BINARY)
+9 -173
View File
@@ -1,8 +1,8 @@
/** /**
* vim: set ts=4 sw=4 tw=99 noet : * vim: set ts=4 :
* ============================================================================= * =============================================================================
* SourceMod * SourceMod
* Copyright (C) 2004-2010 AlliedModders LLC. All rights reserved. * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
* ============================================================================= * =============================================================================
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under
@@ -25,17 +25,15 @@
* this exception to all derivative works. AlliedModders LLC defines further * this exception to all derivative works. AlliedModders LLC defines further
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
* or <http://www.sourcemod.net/license.php>. * or <http://www.sourcemod.net/license.php>.
*
* Version: $Id$
*/ */
#include "MemoryUtils.h" #include "MemoryUtils.h"
#include "ShareSys.h" #include "ShareSys.h"
#ifdef PLATFORM_LINUX #ifdef PLATFORM_LINUX
#include <fcntl.h> #include <string.h>
#include <link.h> #include <elf.h>
#include <sys/mman.h>
#define PAGE_SIZE 4096
#define PAGE_ALIGN_UP(x) ((x + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))
#endif #endif
MemoryUtils g_MemUtils; MemoryUtils g_MemUtils;
@@ -58,17 +56,6 @@ MemoryUtils::MemoryUtils()
} }
#endif #endif
MemoryUtils::~MemoryUtils()
{
#ifdef PLATFORM_LINUX
for (size_t i = 0; i < m_SymTables.size(); i++)
{
delete m_SymTables[i];
}
m_SymTables.clear();
#endif
}
void MemoryUtils::OnSourceModAllInitialized() void MemoryUtils::OnSourceModAllInitialized()
{ {
g_ShareSys.AddInterface(NULL, this); g_ShareSys.AddInterface(NULL, this);
@@ -111,149 +98,6 @@ void *MemoryUtils::FindPattern(const void *libPtr, const char *pattern, size_t l
return NULL; return NULL;
} }
void *MemoryUtils::ResolveSymbol(void *handle, const char *symbol)
{
#ifdef PLATFORM_WINDOWS
return GetProcAddress((HMODULE)handle, symbol);
#elif defined PLATFORM_LINUX
struct link_map *dlmap;
struct stat dlstat;
int dlfile;
uintptr_t map_base;
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;
LibSymbolTable *libtable;
SymbolTable *table;
Symbol *symbol_entry;
dlmap = (struct link_map *)handle;
symtab_hdr = NULL;
strtab_hdr = NULL;
table = NULL;
/* See if we already have a symbol table for this library */
for (size_t i = 0; i < m_SymTables.size(); i++)
{
libtable = m_SymTables[i];
if (libtable->lib_base == dlmap->l_addr)
{
table = &libtable->table;
break;
}
}
/* If we don't have a symbol table for this library, then create one */
if (table == NULL)
{
libtable = new LibSymbolTable();
libtable->table.Initialize();
libtable->lib_base = dlmap->l_addr;
libtable->last_pos = 0;
table = &libtable->table;
m_SymTables.push_back(libtable);
}
/* See if the symbol is already cached in our table */
symbol_entry = table->FindSymbol(symbol, strlen(symbol));
if (symbol_entry != NULL)
{
return symbol_entry->address;
}
/* If symbol isn't in our table, then we have open the actual library */
dlfile = open(dlmap->l_name, O_RDONLY);
if (dlfile == -1 || fstat(dlfile, &dlstat) == -1)
{
close(dlfile);
return NULL;
}
/* Map library file into memory */
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)
{
close(dlfile);
return NULL;
}
close(dlfile);
if (file_hdr->e_shoff == 0 || file_hdr->e_shstrndx == SHN_UNDEF)
{
munmap(file_hdr, dlstat.st_size);
return NULL;
}
sections = (Elf32_Shdr *)(map_base + file_hdr->e_shoff);
section_count = file_hdr->e_shnum;
/* Get ELF section header string table */
shstrtab_hdr = &sections[file_hdr->e_shstrndx];
shstrtab = (const char *)(map_base + shstrtab_hdr->sh_offset);
/* Iterate sections while looking for ELF symbol table and string table */
for (uint16_t i = 0; i < section_count; i++)
{
Elf32_Shdr &hdr = sections[i];
const char *section_name = shstrtab + hdr.sh_name;
if (strcmp(section_name, ".symtab") == 0)
{
symtab_hdr = &hdr;
}
else if (strcmp(section_name, ".strtab") == 0)
{
strtab_hdr = &hdr;
}
}
/* Uh oh, we don't have a symbol table or a string table */
if (symtab_hdr == NULL || strtab_hdr == NULL)
{
munmap(file_hdr, dlstat.st_size);
return NULL;
}
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++)
{
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;
/* Skip symbols that are undefined or do not refer to functions or objects */
if (sym.st_shndx == SHN_UNDEF || (sym_type != STT_FUNC && sym_type != STT_OBJECT))
{
continue;
}
/* Caching symbols as we go along */
cur_sym = table->InternSymbol(sym_name, strlen(sym_name), (void *)(dlmap->l_addr + sym.st_value));
if (strcmp(symbol, sym_name) == 0)
{
symbol_entry = cur_sym;
libtable->last_pos = ++i;
break;
}
}
munmap(file_hdr, dlstat.st_size);
return symbol_entry ? symbol_entry->address : NULL;
#endif
}
bool MemoryUtils::GetLibraryInfo(const void *libPtr, DynLibInfo &lib) bool MemoryUtils::GetLibraryInfo(const void *libPtr, DynLibInfo &lib)
{ {
unsigned long baseAddr; unsigned long baseAddr;
@@ -357,22 +201,14 @@ bool MemoryUtils::GetLibraryInfo(const void *libPtr, DynLibInfo &lib)
phdrCount = file->e_phnum; phdrCount = file->e_phnum;
phdr = reinterpret_cast<Elf32_Phdr *>(baseAddr + file->e_phoff); phdr = reinterpret_cast<Elf32_Phdr *>(baseAddr + file->e_phoff);
/* Add up the memory sizes of segments marked as PT_LOAD as those are the only ones that should be in memory */
for (uint16_t i = 0; i < phdrCount; i++) for (uint16_t i = 0; i < phdrCount; i++)
{ {
Elf32_Phdr &hdr = phdr[i]; Elf32_Phdr &hdr = phdr[i];
/* We only really care about the segment with executable code */ if (hdr.p_type == PT_LOAD)
if (hdr.p_type == PT_LOAD && hdr.p_flags == (PF_X|PF_R))
{ {
/* From glibc, elf/dl-load.c: lib.memorySize += hdr.p_memsz;
* c->mapend = ((ph->p_vaddr + ph->p_filesz + GLRO(dl_pagesize) - 1)
* & ~(GLRO(dl_pagesize) - 1));
*
* In glibc, the segment file size is aligned up to the nearest page size and
* added to the virtual address of the segment. We just want the size here.
*/
lib.memorySize = PAGE_ALIGN_UP(hdr.p_filesz);
break;
} }
} }
+5 -27
View File
@@ -1,8 +1,8 @@
/** /**
* vim: set ts=4 sw=4 tw=99 noet : * vim: set ts=4 :
* ============================================================================= * =============================================================================
* SourceMod * SourceMod
* Copyright (C) 2004-2000 AlliedModders LLC. All rights reserved. * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
* ============================================================================= * =============================================================================
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under
@@ -25,6 +25,8 @@
* this exception to all derivative works. AlliedModders LLC defines further * this exception to all derivative works. AlliedModders LLC defines further
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
* or <http://www.sourcemod.net/license.php>. * or <http://www.sourcemod.net/license.php>.
*
* Version: $Id$
*/ */
#ifndef _INCLUDE_SOURCEMOD_MEMORYUTILS_H_ #ifndef _INCLUDE_SOURCEMOD_MEMORYUTILS_H_
@@ -32,12 +34,6 @@
#include <IMemoryUtils.h> #include <IMemoryUtils.h>
#include "sm_globals.h" #include "sm_globals.h"
#ifdef PLATFORM_LINUX
#include <sh_vector.h>
#include "sm_symtable.h"
using namespace SourceHook;
#endif
using namespace SourceMod; using namespace SourceMod;
@@ -47,34 +43,16 @@ struct DynLibInfo
size_t memorySize; size_t memorySize;
}; };
#ifdef PLATFORM_LINUX
typedef uint32_t Elf32_Addr;
struct LibSymbolTable
{
SymbolTable table;
Elf32_Addr lib_base;
uint32_t last_pos;
};
#endif
class MemoryUtils : class MemoryUtils :
public IMemoryUtils, public IMemoryUtils,
public SMGlobalClass public SMGlobalClass
{ {
public:
~MemoryUtils();
public: // SMGlobalClass public: // SMGlobalClass
void OnSourceModAllInitialized(); void OnSourceModAllInitialized();
public: // IMemoryUtils public: // IMemoryUtils
void *FindPattern(const void *libPtr, const char *pattern, size_t len); void *FindPattern(const void *libPtr, const char *pattern, size_t len);
void *ResolveSymbol(void *handle, const char *symbol);
public:
bool GetLibraryInfo(const void *libPtr, DynLibInfo &lib);
#ifdef PLATFORM_LINUX
private: private:
CVector<LibSymbolTable *> m_SymTables; bool GetLibraryInfo(const void *libPtr, DynLibInfo &lib);
#endif
}; };
extern MemoryUtils g_MemUtils; extern MemoryUtils g_MemUtils;
+5 -34
View File
@@ -2,7 +2,7 @@
* vim: set ts=4 : * vim: set ts=4 :
* ============================================================================= * =============================================================================
* SourceMod * SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
* ============================================================================= * =============================================================================
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under
@@ -41,7 +41,6 @@
#include "ShareSys.h" #include "ShareSys.h"
#include "HandleSys.h" #include "HandleSys.h"
#include "sourcemm_api.h" #include "sourcemm_api.h"
#include "Translator.h"
MenuManager g_Menus; MenuManager g_Menus;
VoteMenuHandler s_VoteHandler; VoteMenuHandler s_VoteHandler;
@@ -586,20 +585,14 @@ skip_search:
{ {
if (exitBackButton) if (exitBackButton)
{ {
if (!CoreTranslate(text, sizeof(text), "%T", 2, NULL, "Back", &client)) CorePlayerTranslate(client, text, sizeof(text), "Back", NULL);
{
UTIL_Format(text, sizeof(text), "Back");
}
dr.style = ITEMDRAW_CONTROL; dr.style = ITEMDRAW_CONTROL;
position = panel->DrawItem(dr); position = panel->DrawItem(dr);
slots[position].type = ItemSel_ExitBack; slots[position].type = ItemSel_ExitBack;
} }
else else
{ {
if (!CoreTranslate(text, sizeof(text), "%T", 2, NULL, "Previous", &client)) CorePlayerTranslate(client, text, sizeof(text), "Previous", NULL);
{
UTIL_Format(text, sizeof(text), "Previous");
}
dr.style = (displayPrev ? 0 : ITEMDRAW_DISABLED)|ITEMDRAW_CONTROL; dr.style = (displayPrev ? 0 : ITEMDRAW_DISABLED)|ITEMDRAW_CONTROL;
position = panel->DrawItem(dr); position = panel->DrawItem(dr);
slots[position].type = ItemSel_Back; slots[position].type = ItemSel_Back;
@@ -617,10 +610,7 @@ skip_search:
/* NEXT */ /* NEXT */
if (displayNext || canDrawDisabled) if (displayNext || canDrawDisabled)
{ {
if (!CoreTranslate(text, sizeof(text), "%T", 2, NULL, "Next", &client)) CorePlayerTranslate(client, text, sizeof(text), "Next", NULL);
{
UTIL_Format(text, sizeof(text), "Next");
}
dr.style = (displayNext ? 0 : ITEMDRAW_DISABLED)|ITEMDRAW_CONTROL; dr.style = (displayNext ? 0 : ITEMDRAW_DISABLED)|ITEMDRAW_CONTROL;
position = panel->DrawItem(dr); position = panel->DrawItem(dr);
slots[position].type = ItemSel_Next; slots[position].type = ItemSel_Next;
@@ -648,10 +638,7 @@ skip_search:
/* EXIT */ /* EXIT */
if (exitButton) if (exitButton)
{ {
if (!CoreTranslate(text, sizeof(text), "%T", 2, NULL, "Exit", &client)) CorePlayerTranslate(client, text, sizeof(text), "Exit", NULL);
{
UTIL_Format(text, sizeof(text), "Exit");
}
dr.style = ITEMDRAW_CONTROL; dr.style = ITEMDRAW_CONTROL;
position = panel->DrawItem(dr); position = panel->DrawItem(dr);
slots[position].type = ItemSel_Exit; slots[position].type = ItemSel_Exit;
@@ -790,19 +777,3 @@ unsigned int MenuManager::GetRemainingVoteDelay()
{ {
return s_VoteHandler.GetRemainingVoteDelay(); return s_VoteHandler.GetRemainingVoteDelay();
} }
bool MenuManager::IsClientInVotePool(int client)
{
return s_VoteHandler.IsClientInVotePool(client);
}
bool MenuManager::RedrawClientVoteMenu(int client)
{
return RedrawClientVoteMenu2(client, true);
}
bool MenuManager::RedrawClientVoteMenu2(int client, bool revote)
{
return s_VoteHandler.RedrawToClient(client, revote);
}
+1 -4
View File
@@ -2,7 +2,7 @@
* vim: set ts=4 : * vim: set ts=4 :
* ============================================================================= * =============================================================================
* SourceMod * SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
* ============================================================================= * =============================================================================
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under
@@ -89,9 +89,6 @@ public:
bool IsVoteInProgress(); bool IsVoteInProgress();
void CancelVoting(); void CancelVoting();
unsigned int GetRemainingVoteDelay(); unsigned int GetRemainingVoteDelay();
bool IsClientInVotePool(int client);
bool RedrawClientVoteMenu(int client);
bool RedrawClientVoteMenu2(int client, bool revote);
public: //IHandleTypeDispatch public: //IHandleTypeDispatch
void OnHandleDestroy(HandleType_t type, void *object); void OnHandleDestroy(HandleType_t type, void *object);
bool GetHandleApproxSize(HandleType_t type, void *object, unsigned int *pSize); bool GetHandleApproxSize(HandleType_t type, void *object, unsigned int *pSize);
+2 -2
View File
@@ -2,7 +2,7 @@
* vim: set ts=4 : * vim: set ts=4 :
* ============================================================================= * =============================================================================
* SourceMod * SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
* ============================================================================= * =============================================================================
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under
@@ -314,7 +314,7 @@ void BaseMenuStyle::ClientPressedKey(int client, unsigned int key_press)
if (sound != NULL) if (sound != NULL)
{ {
edict_t *pEdict = PEntityOfEntIndex(client); edict_t *pEdict = engine->PEntityOfEntIndex(client);
if (pEdict) if (pEdict)
{ {
ICollideable *pCollideable = pEdict->GetCollideable(); ICollideable *pCollideable = pEdict->GetCollideable();
+1 -1
View File
@@ -2,7 +2,7 @@
* vim: set ts=4 : * vim: set ts=4 :
* ============================================================================= * =============================================================================
* SourceMod * SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
* ============================================================================= * =============================================================================
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under
+1 -1
View File
@@ -2,7 +2,7 @@
* vim: set ts=4 : * vim: set ts=4 :
* ============================================================================= * =============================================================================
* SourceMod * SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
* ============================================================================= * =============================================================================
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under
+1 -1
View File
@@ -2,7 +2,7 @@
* vim: set ts=4 : * vim: set ts=4 :
* ============================================================================= * =============================================================================
* SourceMod * SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
* ============================================================================= * =============================================================================
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under
+3 -3
View File
@@ -2,7 +2,7 @@
* vim: set ts=4 : * vim: set ts=4 :
* ============================================================================= * =============================================================================
* SourceMod * SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
* ============================================================================= * =============================================================================
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under
@@ -88,7 +88,7 @@ void ValveMenuStyle::HookCreateMessage(edict_t *pEdict,
return; return;
} }
int client = IndexOfEdict(pEdict); int client = engine->IndexOfEdict(pEdict);
if (client < 1 || client > 256) if (client < 1 || client > 256)
{ {
return; return;
@@ -325,7 +325,7 @@ void CValveMenuDisplay::SendRawDisplay(int client, int priority, unsigned int ti
m_pKv->SetInt("time", time ? time : 200); m_pKv->SetInt("time", time ? time : 200);
SH_CALL(g_pSPHCC, &IServerPluginHelpers::CreateMessage)( SH_CALL(g_pSPHCC, &IServerPluginHelpers::CreateMessage)(
PEntityOfEntIndex(client), engine->PEntityOfEntIndex(client),
DIALOG_MENU, DIALOG_MENU,
m_pKv, m_pKv,
vsp_interface); vsp_interface);
+1 -1
View File
@@ -2,7 +2,7 @@
* vim: set ts=4 : * vim: set ts=4 :
* ============================================================================= * =============================================================================
* SourceMod * SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
* ============================================================================= * =============================================================================
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under
+17 -300
View File
@@ -1,8 +1,8 @@
/** /**
* vim: set ts=4 sw=4 : * vim: set ts=4 :
* ============================================================================= * =============================================================================
* SourceMod * SourceMod
* Copyright (C) 2004-2009 AlliedModders LLC. All rights reserved. * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
* ============================================================================= * =============================================================================
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under
@@ -34,56 +34,10 @@
#include "MenuVoting.h" #include "MenuVoting.h"
#include "PlayerManager.h" #include "PlayerManager.h"
#include "sourcemm_api.h" #include "sourcemm_api.h"
#include <sourcemod.h>
#include <Logger.h>
#include <HalfLife2.h>
#include <mathlib.h>
#include <const.h>
#include <Translator.h>
float g_next_vote = 0.0f; float g_next_vote = 0.0f;
#define VOTE_NOT_VOTING -2 #if defined ORANGEBOX_BUILD
#define VOTE_PENDING -1
ConVar sm_vote_hintbox("sm_vote_progress_hintbox",
"0",
0,
"Show current vote progress in a hint box",
true,
0.0,
true,
1.0);
ConVar sm_vote_chat("sm_vote_progress_chat",
"0",
0,
"Show current vote progress as chat messages",
true,
0.0,
true,
1.0);
ConVar sm_vote_console("sm_vote_progress_console",
"0",
0,
"Show current vote progress as console messages",
true,
0.0,
true,
1.0);
ConVar sm_vote_client_console("sm_vote_progress_client_console",
"0",
0,
"Show current vote progress as console messages to clients",
true,
0.0,
true,
1.0);
#if SOURCE_ENGINE >= SE_ORANGEBOX
void OnVoteDelayChange(IConVar *cvar, const char *value, float flOldValue); void OnVoteDelayChange(IConVar *cvar, const char *value, float flOldValue);
#else #else
void OnVoteDelayChange(ConVar *cvar, const char *value); void OnVoteDelayChange(ConVar *cvar, const char *value);
@@ -98,7 +52,7 @@ ConVar sm_vote_delay("sm_vote_delay",
0.0, 0.0,
OnVoteDelayChange); OnVoteDelayChange);
#if SOURCE_ENGINE >= SE_ORANGEBOX #if defined ORANGEBOX_BUILD
void OnVoteDelayChange(IConVar *cvar, const char *value, float flOldValue) void OnVoteDelayChange(IConVar *cvar, const char *value, float flOldValue)
#else #else
void OnVoteDelayChange(ConVar *cvar, const char *value) void OnVoteDelayChange(ConVar *cvar, const char *value)
@@ -159,19 +113,14 @@ void VoteMenuHandler::OnClientDisconnected(int client)
return; return;
} }
/* Wipe out their vote if they had one. We have to make sure the the the /* Wipe out their vote if they had one */
* newly connected client is not allowed to vote.
*/
int item; int item;
if ((item = m_ClientVotes[client]) >= VOTE_PENDING) if ((item = m_ClientVotes[client]) >= 0)
{ {
if (item >= 0) assert((unsigned)item < m_Items);
{ assert(m_Votes[item] > 0);
assert((unsigned)item < m_Items); m_Votes[item]--;
assert(m_Votes[item] > 0); m_ClientVotes[client] = -1;
m_Votes[item]--;
}
m_ClientVotes[client] = VOTE_NOT_VOTING;
} }
} }
@@ -180,28 +129,18 @@ bool VoteMenuHandler::IsVoteInProgress()
return (m_pCurMenu != NULL); return (m_pCurMenu != NULL);
} }
bool VoteMenuHandler::StartVote(IBaseMenu *menu, bool VoteMenuHandler::StartVote(IBaseMenu *menu, unsigned int num_clients, int clients[], unsigned int max_time, unsigned int flags/* =0 */)
unsigned int num_clients,
int clients[],
unsigned int max_time,
unsigned int flags/* =0 */)
{ {
if (!InitializeVoting(menu, menu->GetHandler(), max_time, flags)) if (!InitializeVoting(menu, menu->GetHandler(), max_time, flags))
{ {
return false; return false;
} }
/* Note: we can use game time and not universal time because
* if we're voting then players are in-game.
*/
float fVoteDelay = sm_vote_delay.GetFloat(); float fVoteDelay = sm_vote_delay.GetFloat();
if (fVoteDelay < 1.0) if (fVoteDelay < 1.0)
{ {
g_next_vote = 0.0; g_next_vote = 0.0;
} } else {
else
{
/* This little trick breaks for infinite votes! /* This little trick breaks for infinite votes!
* However, we just ignore that since those 1) shouldn't exist and * However, we just ignore that since those 1) shouldn't exist and
* 2) people must be checking IsVoteInProgress() beforehand anyway. * 2) people must be checking IsVoteInProgress() beforehand anyway.
@@ -209,15 +148,8 @@ bool VoteMenuHandler::StartVote(IBaseMenu *menu,
g_next_vote = gpGlobals->curtime + fVoteDelay + (float)max_time; g_next_vote = gpGlobals->curtime + fVoteDelay + (float)max_time;
} }
m_fStartTime = gpGlobals->curtime;
m_nMenuTime = max_time;
for (unsigned int i=0; i<num_clients; i++) for (unsigned int i=0; i<num_clients; i++)
{ {
if (clients[i] < 1 || clients[i] > 256)
{
continue;
}
menu->Display(clients[i], max_time, this); menu->Display(clients[i], max_time, this);
} }
@@ -226,72 +158,6 @@ bool VoteMenuHandler::StartVote(IBaseMenu *menu,
return true; return true;
} }
bool VoteMenuHandler::IsClientInVotePool(int client)
{
if (client < 1
|| client > g_Players.MaxClients()
|| m_pCurMenu == NULL)
{
return false;
}
return (m_ClientVotes[client] > VOTE_NOT_VOTING);
}
bool VoteMenuHandler::GetClientVoteChoice(int client, unsigned int *pItem)
{
if (!IsClientInVotePool(client)
|| m_ClientVotes[client] == VOTE_PENDING)
{
return false;
}
*pItem = m_ClientVotes[client];
return true;
}
bool VoteMenuHandler::RedrawToClient(int client, bool revotes)
{
unsigned int time_limit;
if (!IsClientInVotePool(client))
{
return false;
}
if (m_ClientVotes[client] >= 0)
{
if ((m_VoteFlags & VOTEFLAG_NO_REVOTES) == VOTEFLAG_NO_REVOTES || !revotes)
{
return false;
}
assert((unsigned)m_ClientVotes[client] < m_Items);
assert(m_Votes[m_ClientVotes[client]] > 0);
m_Votes[m_ClientVotes[client]]--;
m_ClientVotes[client] = VOTE_PENDING;
m_Revoting[client] = true;
m_NumVotes--;
}
if (m_nMenuTime == MENU_TIME_FOREVER)
{
time_limit = m_nMenuTime;
}
else
{
time_limit = (int)((float)m_nMenuTime - (gpGlobals->curtime - m_fStartTime));
/* Make sure this doesn't round to zero */
if (time_limit == MENU_TIME_FOREVER)
{
time_limit = 1;
}
}
return m_pCurMenu->Display(client, time_limit, this);
}
bool VoteMenuHandler::InitializeVoting(IBaseMenu *menu, bool VoteMenuHandler::InitializeVoting(IBaseMenu *menu,
IMenuHandler *handler, IMenuHandler *handler,
unsigned int time, unsigned int time,
@@ -307,8 +173,7 @@ bool VoteMenuHandler::InitializeVoting(IBaseMenu *menu,
/* Mark all clients as not voting */ /* Mark all clients as not voting */
for (int i=1; i<=gpGlobals->maxClients; i++) for (int i=1; i<=gpGlobals->maxClients; i++)
{ {
m_ClientVotes[i] = VOTE_NOT_VOTING; m_ClientVotes[i] = -2;
m_Revoting[i] = false;
} }
m_Items = menu->GetItemCount(); m_Items = menu->GetItemCount();
@@ -322,9 +187,7 @@ bool VoteMenuHandler::InitializeVoting(IBaseMenu *menu,
m_Votes[i] = 0; m_Votes[i] = 0;
} }
m_Votes.resize(m_Items, 0); m_Votes.resize(m_Items, 0);
} } else {
else
{
for (unsigned int i=0; i<m_Items; i++) for (unsigned int i=0; i<m_Items; i++)
{ {
m_Votes[i] = 0; m_Votes[i] = 0;
@@ -352,8 +215,6 @@ void VoteMenuHandler::StartVoting()
m_pHandler->OnMenuVoteStart(m_pCurMenu); m_pHandler->OnMenuVoteStart(m_pCurMenu);
m_displayTimer = g_Timers.CreateTimer(this, 1.0, NULL, TIMER_FLAG_REPEAT|TIMER_FLAG_NO_MAPCHANGE);
/* By now we know how many clients were set. /* By now we know how many clients were set.
* If there are none, we should end IMMEDIATELY. * If there are none, we should end IMMEDIATELY.
*/ */
@@ -361,8 +222,6 @@ void VoteMenuHandler::StartVoting()
{ {
EndVoting(); EndVoting();
} }
m_TotalClients = m_Clients;
} }
void VoteMenuHandler::DecrementPlayerCount() void VoteMenuHandler::DecrementPlayerCount()
@@ -393,17 +252,10 @@ void VoteMenuHandler::EndVoting()
if (fVoteDelay < 1.0) if (fVoteDelay < 1.0)
{ {
g_next_vote = 0.0; g_next_vote = 0.0;
} } else {
else
{
g_next_vote = gpGlobals->curtime + fVoteDelay; g_next_vote = gpGlobals->curtime + fVoteDelay;
} }
if (m_displayTimer)
{
g_Timers.KillTimer(m_displayTimer);
}
if (m_bCancelled) if (m_bCancelled)
{ {
/* If we were cancelled, don't bother tabulating anything. /* If we were cancelled, don't bother tabulating anything.
@@ -450,7 +302,7 @@ void VoteMenuHandler::EndVoting()
/* Build the client list */ /* Build the client list */
for (int i=1; i<=gpGlobals->maxClients; i++) for (int i=1; i<=gpGlobals->maxClients; i++)
{ {
if (m_ClientVotes[i] >= VOTE_PENDING) if (m_ClientVotes[i] >= -1)
{ {
client_vote[vote.num_clients].client = i; client_vote[vote.num_clients].client = i;
client_vote[vote.num_clients].item = m_ClientVotes[i]; client_vote[vote.num_clients].item = m_ClientVotes[i];
@@ -494,7 +346,7 @@ void VoteMenuHandler::OnMenuCancel(IBaseMenu *menu, int client, MenuCancelReason
void VoteMenuHandler::OnMenuDisplay(IBaseMenu *menu, int client, IMenuPanel *display) void VoteMenuHandler::OnMenuDisplay(IBaseMenu *menu, int client, IMenuPanel *display)
{ {
m_ClientVotes[client] = VOTE_PENDING; m_ClientVotes[client] = -1;
m_pHandler->OnMenuDisplay(menu, client, display); m_pHandler->OnMenuDisplay(menu, client, display);
} }
@@ -516,55 +368,6 @@ void VoteMenuHandler::OnMenuSelect(IBaseMenu *menu, int client, unsigned int ite
m_ClientVotes[client] = item; m_ClientVotes[client] = item;
m_Votes[item]++; m_Votes[item]++;
m_NumVotes++; m_NumVotes++;
if (sm_vote_chat.GetBool() || sm_vote_console.GetBool())
{
static char buffer[1024];
ItemDrawInfo dr;
menu->GetItemInfo(item, &dr);
if (sm_vote_console.GetBool())
{
int target = SOURCEMOD_SERVER_LANGUAGE;
CoreTranslate(buffer, sizeof(buffer), "[SM] %T", 4, NULL, "Voted For", &target, g_Players.GetPlayerByIndex(client)->GetName(), dr.display);
Engine_LogPrintWrapper(buffer);
}
if (sm_vote_chat.GetBool() || sm_vote_client_console.GetBool())
{
int maxclients = g_Players.GetMaxClients();
for (int i=1; i<=maxclients; i++)
{
CPlayer *pPlayer = g_Players.GetPlayerByIndex(i);
assert(pPlayer);
if (pPlayer->IsInGame())
{
if (m_Revoting[client])
{
CoreTranslate(buffer, sizeof(buffer), "[SM] %T", 4, NULL, "Changed Vote", &i, g_Players.GetPlayerByIndex(client)->GetName(), dr.display);
}
else
{
CoreTranslate(buffer, sizeof(buffer), "[SM] %T", 4, NULL, "Voted For", &i, g_Players.GetPlayerByIndex(client)->GetName(), dr.display);
}
if (sm_vote_chat.GetBool())
{
g_HL2.TextMsg(i, HUD_PRINTTALK, buffer);
}
if (sm_vote_client_console.GetBool())
{
engine->ClientPrintf(pPlayer->GetEdict(), buffer);
}
}
}
}
}
BuildVoteLeaders();
DrawHintProgress();
} }
m_pHandler->OnMenuSelect(menu, client, item); m_pHandler->OnMenuSelect(menu, client, item);
@@ -587,9 +390,6 @@ void VoteMenuHandler::InternalReset()
m_NumVotes = 0; m_NumVotes = 0;
m_bCancelled = false; m_bCancelled = false;
m_pHandler = NULL; m_pHandler = NULL;
m_leaderList[0] = '\0';
m_displayTimer = NULL;
m_TotalClients = 0;
} }
void VoteMenuHandler::CancelVoting() void VoteMenuHandler::CancelVoting()
@@ -611,86 +411,3 @@ bool VoteMenuHandler::IsCancelling()
{ {
return m_bCancelled; return m_bCancelled;
} }
void VoteMenuHandler::DrawHintProgress()
{
if (!sm_vote_hintbox.GetBool())
{
return;
}
static char buffer[1024];
float timeRemaining = (m_fStartTime + m_nMenuTime) - gpGlobals->curtime;
if (timeRemaining < 0)
{
timeRemaining = 0.0;
}
int iTimeRemaining = RoundFloatToInt(timeRemaining);
int maxclients = g_Players.GetMaxClients();
for (int i=1; i<=maxclients; i++)
{
if (g_Players.GetPlayerByIndex(i)->IsInGame())
{
CoreTranslate(buffer, sizeof(buffer), "%T%s", 6, NULL, "Vote Count", &i, &m_NumVotes, &m_TotalClients, &iTimeRemaining, &m_leaderList);
g_HL2.HintTextMsg(i, buffer);
}
}
}
void VoteMenuHandler::BuildVoteLeaders()
{
if (m_NumVotes == 0 || !sm_vote_hintbox.GetBool())
{
return;
}
menu_vote_result_t vote;
menu_vote_result_t::menu_item_vote_t item_vote[256];
memset(&vote, 0, sizeof(vote));
/* Build the item list */
for (unsigned int i=0; i<m_Items; i++)
{
if (m_Votes[i] > 0)
{
item_vote[vote.num_items].count = m_Votes[i];
item_vote[vote.num_items].item = i;
vote.num_votes += m_Votes[i];
vote.num_items++;
}
}
vote.item_list = item_vote;
assert(vote.num_votes);
/* Sort the item list descending */
qsort(item_vote,
vote.num_items,
sizeof(menu_vote_result_t::menu_item_vote_t),
SortVoteItems);
/* Take the top 3 (if applicable) and draw them */
int len = 0;
for (unsigned int i=0; i<vote.num_items && i<3; i++)
{
int curItem = vote.item_list[i].item;
ItemDrawInfo dr;
m_pCurMenu->GetItemInfo(curItem, &dr);
len += g_SourceMod.Format(m_leaderList + len, sizeof(m_leaderList) - len, "\n%i. %s: (%i)", i+1, dr.display, vote.item_list[i].count);
}
}
SourceMod::ResultType VoteMenuHandler::OnTimer(ITimer *pTimer, void *pData)
{
DrawHintProgress();
return Pl_Continue;
}
void VoteMenuHandler::OnTimerEnd(ITimer *pTimer, void *pData)
{
m_displayTimer = NULL;
}
+2 -19
View File
@@ -2,7 +2,7 @@
* vim: set ts=4 : * vim: set ts=4 :
* ============================================================================= * =============================================================================
* SourceMod * SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
* ============================================================================= * =============================================================================
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under
@@ -36,7 +36,6 @@
#include <IPlayerHelpers.h> #include <IPlayerHelpers.h>
#include <sh_vector.h> #include <sh_vector.h>
#include "sm_globals.h" #include "sm_globals.h"
#include <TimerSys.h>
using namespace SourceHook; using namespace SourceHook;
using namespace SourceMod; using namespace SourceMod;
@@ -44,8 +43,7 @@ using namespace SourceMod;
class VoteMenuHandler : class VoteMenuHandler :
public IMenuHandler, public IMenuHandler,
public SMGlobalClass, public SMGlobalClass,
public IClientListener, public IClientListener
public ITimedEvent
{ {
public: //SMGlobalClass public: //SMGlobalClass
void OnSourceModAllInitialized(); void OnSourceModAllInitialized();
@@ -63,9 +61,6 @@ public: //IMenuHandler
void OnMenuEnd(IBaseMenu *menu, MenuEndReason reason); void OnMenuEnd(IBaseMenu *menu, MenuEndReason reason);
void OnMenuDrawItem(IBaseMenu *menu, int client, unsigned int item, unsigned int &style); void OnMenuDrawItem(IBaseMenu *menu, int client, unsigned int item, unsigned int &style);
unsigned int OnMenuDisplayItem(IBaseMenu *menu, int client, IMenuPanel *panel, unsigned int item, const ItemDrawInfo &dr); unsigned int OnMenuDisplayItem(IBaseMenu *menu, int client, IMenuPanel *panel, unsigned int item, const ItemDrawInfo &dr);
public: //ITimedEvent
ResultType OnTimer(ITimer *pTimer, void *pData);
void OnTimerEnd(ITimer *pTimer, void *pData);
public: public:
bool StartVote(IBaseMenu *menu, bool StartVote(IBaseMenu *menu,
unsigned int num_clients, unsigned int num_clients,
@@ -77,9 +72,6 @@ public:
IBaseMenu *GetCurrentMenu(); IBaseMenu *GetCurrentMenu();
bool IsCancelling(); bool IsCancelling();
unsigned int GetRemainingVoteDelay(); unsigned int GetRemainingVoteDelay();
bool IsClientInVotePool(int client);
bool GetClientVoteChoice(int client, unsigned int *pItem);
bool RedrawToClient(int client, bool revote);
private: private:
void Reset(IMenuHandler *mh); void Reset(IMenuHandler *mh);
void DecrementPlayerCount(); void DecrementPlayerCount();
@@ -90,12 +82,9 @@ private:
unsigned int time, unsigned int time,
unsigned int flags); unsigned int flags);
void StartVoting(); void StartVoting();
void DrawHintProgress();
void BuildVoteLeaders();
private: private:
IMenuHandler *m_pHandler; IMenuHandler *m_pHandler;
unsigned int m_Clients; unsigned int m_Clients;
unsigned int m_TotalClients;
unsigned int m_Items; unsigned int m_Items;
CVector<unsigned int> m_Votes; CVector<unsigned int> m_Votes;
IBaseMenu *m_pCurMenu; IBaseMenu *m_pCurMenu;
@@ -104,13 +93,7 @@ private:
unsigned int m_NumVotes; unsigned int m_NumVotes;
unsigned int m_VoteTime; unsigned int m_VoteTime;
unsigned int m_VoteFlags; unsigned int m_VoteFlags;
float m_fStartTime;
unsigned int m_nMenuTime;
int m_ClientVotes[256+1]; int m_ClientVotes[256+1];
bool m_Revoting[256+1];
char m_leaderList[1024];
ITimer *m_displayTimer;
}; };
#endif //_INCLUDE_SOURCEMOD_MENUVOTING_H_ #endif //_INCLUDE_SOURCEMOD_MENUVOTING_H_
-379
View File
@@ -1,379 +0,0 @@
/**
* vim: set ts=4 :
* =============================================================================
* SourcePawn
* Copyright (C) 2004-2009 AlliedModders LLC. All rights reserved.
* =============================================================================
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, version 3.0, as published by the
* Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <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 "NativeInvoker.h"
#include "ShareSys.h"
NativeInterface g_NInvoke;
NativeInvoker::NativeInvoker()
{
}
NativeInvoker::~NativeInvoker()
{
}
const char *NativeInterface::GetInterfaceName()
{
return SMINTERFACE_NINVOKE_NAME;
}
unsigned int NativeInterface::GetInterfaceVersion()
{
return SMINTERFACE_NINVOKE_VERSION;
}
void NativeInterface::OnSourceModAllInitialized()
{
g_ShareSys.AddInterface(NULL, &g_NInvoke);
}
IPluginRuntime *NativeInterface::CreateRuntime(const char *name, size_t bytes)
{
return g_pSourcePawn2->CreateEmptyRuntime(name, bytes);
}
INativeInvoker *NativeInterface::CreateInvoker()
{
return new NativeInvoker();
}
bool NativeInvoker::Start(IPluginContext *pContext, const char *name)
{
NativeEntry *entry;
entry = g_ShareSys.FindNative(name);
if (entry == NULL)
{
return false;
}
native = NULL;
if (entry->replacement.owner != NULL)
{
native = entry->replacement.func;
}
else if (entry->owner != NULL)
{
native = entry->func;
}
if (native == NULL)
{
return false;
}
this->pContext = pContext;
m_curparam = 0;
m_errorstate = SP_ERROR_NONE;
return true;
}
cell_t NativeInvoker::PushCell(cell_t cell)
{
if (m_curparam >= SP_MAX_EXEC_PARAMS)
{
return SetError(SP_ERROR_PARAMS_MAX);
}
m_info[m_curparam].marked = false;
m_params[m_curparam] = cell;
m_curparam++;
return SP_ERROR_NONE;
}
int NativeInvoker::PushCellByRef(cell_t *cell, int flags)
{
return PushArray(cell, 1, flags);
}
int NativeInvoker::PushFloat(float number)
{
cell_t val = *(cell_t *)&number;
return PushCell(val);
}
int NativeInvoker::PushFloatByRef(float *number, int flags)
{
return PushCellByRef((cell_t *)number, flags);
}
int NativeInvoker::PushArray(cell_t *inarray, unsigned int cells, int copyback)
{
if (m_curparam >= SP_MAX_EXEC_PARAMS)
{
return SetError(SP_ERROR_PARAMS_MAX);
}
ParamInfo *info = &m_info[m_curparam];
info->flags = inarray ? copyback : 0;
info->marked = true;
info->size = cells;
info->str.is_sz = false;
info->orig_addr = inarray;
m_curparam++;
return SP_ERROR_NONE;
}
int NativeInvoker::PushString(const char *string)
{
return _PushString(string, SM_PARAM_STRING_COPY, 0, strlen(string)+1);
}
int NativeInvoker::PushStringEx(char *buffer, size_t length, int sz_flags, int cp_flags)
{
return _PushString(buffer, sz_flags, cp_flags, length);
}
int NativeInvoker::_PushString(const char *string, int sz_flags, int cp_flags, size_t len)
{
if (m_curparam >= SP_MAX_EXEC_PARAMS)
{
return SetError(SP_ERROR_PARAMS_MAX);
}
ParamInfo *info = &m_info[m_curparam];
info->marked = true;
info->orig_addr = (cell_t *)string;
info->flags = cp_flags;
info->size = len;
info->str.sz_flags = sz_flags;
info->str.is_sz = true;
m_curparam++;
return SP_ERROR_NONE;
}
void NativeInvoker::Cancel()
{
if (pContext == NULL)
{
return;
}
m_errorstate = SP_ERROR_NONE;
m_curparam = 0;
pContext = NULL;
native = NULL;
}
int NativeInvoker::SetError(int err)
{
m_errorstate = err;
return err;
}
int NativeInvoker::Invoke(cell_t *result)
{
int err = SP_ERROR_NONE;
if (pContext == NULL)
{
return SP_ERROR_INVALID_NATIVE;
}
if (m_errorstate != SP_ERROR_NONE)
{
err = m_errorstate;
Cancel();
return err;
}
cell_t tresult;
if (result == NULL)
{
result = &tresult;
}
//This is for re-entrancy!
IPluginContext *ctx = pContext;
cell_t _temp_params[SP_MAX_EXEC_PARAMS + 1];
cell_t *temp_params = &_temp_params[1];
ParamInfo temp_info[SP_MAX_EXEC_PARAMS];
unsigned int numparams = m_curparam;
unsigned int i;
bool docopies = true;
if (numparams)
{
//Save the info locally, then reset it for re-entrant calls.
memcpy(temp_info, m_info, numparams * sizeof(ParamInfo));
}
m_curparam = 0;
pContext = NULL;
/* Initialize 0th parameter */
_temp_params[0] = numparams;
/* Browse the parameters and build arrays */
for (i = 0; i < numparams; i++)
{
/* Is this marked as an array? */
if (temp_info[i].marked)
{
if (!temp_info[i].str.is_sz)
{
/* Allocate a normal/generic array */
if ((err = ctx->HeapAlloc(temp_info[i].size,
&temp_info[i].local_addr,
&temp_info[i].phys_addr))
!= SP_ERROR_NONE)
{
break;
}
if (temp_info[i].orig_addr)
{
memcpy(temp_info[i].phys_addr, temp_info[i].orig_addr, sizeof(cell_t) * temp_info[i].size);
}
}
else
{
/* Calculate cells required for the string */
size_t cells = (temp_info[i].size + sizeof(cell_t) - 1) / sizeof(cell_t);
/* Allocate the buffer */
if ((err = ctx->HeapAlloc(cells,
&temp_info[i].local_addr,
&temp_info[i].phys_addr))
!= SP_ERROR_NONE)
{
break;
}
/* Copy original string if necessary */
if ((temp_info[i].str.sz_flags & SM_PARAM_STRING_COPY) && (temp_info[i].orig_addr != NULL))
{
/* Cut off UTF-8 properly */
if (temp_info[i].str.sz_flags & SM_PARAM_STRING_UTF8)
{
if ((err = ctx->StringToLocalUTF8(temp_info[i].local_addr,
temp_info[i].size,
(const char *)temp_info[i].orig_addr,
NULL))
!= SP_ERROR_NONE)
{
break;
}
}
/* Copy a binary blob */
else if (temp_info[i].str.sz_flags & SM_PARAM_STRING_BINARY)
{
memmove(temp_info[i].phys_addr, temp_info[i].orig_addr, temp_info[i].size);
}
/* Copy ASCII characters */
else
{
if ((err = ctx->StringToLocal(temp_info[i].local_addr,
temp_info[i].size,
(const char *)temp_info[i].orig_addr))
!= SP_ERROR_NONE)
{
break;
}
}
}
} /* End array/string calculation */
/* Update the pushed parameter with the byref local address */
temp_params[i] = temp_info[i].local_addr;
}
else
{
/* Just copy the value normally */
temp_params[i] = m_params[i];
}
}
/* Make the call if we can */
if (err == SP_ERROR_NONE)
{
*result = native(ctx, _temp_params);
if (ctx->GetLastNativeError() != SP_ERROR_NONE)
{
docopies = false;
ctx->ClearLastNativeError();
}
}
else
{
docopies = false;
}
/* i should be equal to the last valid parameter + 1 */
while (i--)
{
if (!temp_info[i].marked)
{
continue;
}
if (docopies && (temp_info[i].flags & SM_PARAM_COPYBACK))
{
if (temp_info[i].orig_addr)
{
if (temp_info[i].str.is_sz)
{
memcpy(temp_info[i].orig_addr, temp_info[i].phys_addr, temp_info[i].size);
}
else
{
if (temp_info[i].size == 1)
{
*temp_info[i].orig_addr = *(temp_info[i].phys_addr);
}
else
{
memcpy(temp_info[i].orig_addr,
temp_info[i].phys_addr,
temp_info[i].size * sizeof(cell_t));
}
}
}
}
if ((err = ctx->HeapPop(temp_info[i].local_addr)) != SP_ERROR_NONE)
{
return err;
}
}
return err;
}
-98
View File
@@ -1,98 +0,0 @@
/**
* vim: set ts=4 :
* =============================================================================
* SourceMod
* Copyright (C) 2004-2009 AlliedModders LLC. All rights reserved.
* =============================================================================
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, version 3.0, as published by the
* Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <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_SOURCEMOD_NATIVE_INVOKER_H_
#define _INCLUDE_SOURCEMOD_NATIVE_INVOKER_H_
#include "sm_globals.h"
#include <INativeInvoker.h>
struct ParamInfo
{
int flags; /* Copy-back flags */
bool marked; /* Whether this is marked as being used */
cell_t local_addr; /* Local address to free */
cell_t *phys_addr; /* Physical address of our copy */
cell_t *orig_addr; /* Original address to copy back to */
ucell_t size; /* Size of array in bytes */
struct
{
bool is_sz; /* is a string */
int sz_flags; /* has sz flags */
} str;
};
class NativeInvoker : public INativeInvoker
{
public:
NativeInvoker();
~NativeInvoker();
public: /* ICallable */
int PushCell(cell_t cell);
int PushCellByRef(cell_t *cell, int flags=SM_PARAM_COPYBACK);
int PushFloat(float number);
int PushFloatByRef(float *number, int flags=SM_PARAM_COPYBACK);
int PushArray(cell_t *inarray, unsigned int cells, int flags=0);
int PushString(const char *string);
int PushStringEx(char *buffer, size_t length, int sz_flags, int cp_flags);
void Cancel();
public: /* INativeInvoker */
bool Start(IPluginContext *pContext, const char *name);
int Invoke(cell_t *result);
private:
int _PushString(const char *string, int sz_flags, int cp_flags, size_t len);
int SetError(int err);
private:
IPluginContext *pContext;
SPVM_NATIVE_FUNC native;
cell_t m_params[SP_MAX_EXEC_PARAMS];
ParamInfo m_info[SP_MAX_EXEC_PARAMS];
unsigned int m_curparam;
int m_errorstate;
};
class NativeInterface :
public INativeInterface,
public SMGlobalClass
{
public: /* SMGlobalClass */
void OnSourceModAllInitialized();
public: /* SMInterface */
unsigned int GetInterfaceVersion();
const char *GetInterfaceName();
public: /* INativeInvoker */
IPluginRuntime *CreateRuntime(const char *name, size_t bytes);
INativeInvoker *CreateInvoker();
};
extern NativeInterface g_NInvoke;
#endif /* _INCLUDE_SOURCEMOD_NATIVE_INVOKER_H_ */
-144
View File
@@ -1,144 +0,0 @@
#include "NativeOwner.h"
#include "ShareSys.h"
#include "PluginSys.h"
CNativeOwner::CNativeOwner() : m_nMarkSerial(0)
{
}
void CNativeOwner::SetMarkSerial(unsigned int serial)
{
m_nMarkSerial = serial;
}
unsigned int CNativeOwner::GetMarkSerial()
{
return m_nMarkSerial;
}
void CNativeOwner::AddDependent(CPlugin *pPlugin)
{
m_Dependents.push_back(pPlugin);
}
void CNativeOwner::AddWeakRef(const WeakNative & ref)
{
m_WeakRefs.push_back(ref);
}
void CNativeOwner::AddNatives(const sp_nativeinfo_t *natives)
{
NativeEntry *pEntry;
for (unsigned int i = 0; natives[i].func != NULL && natives[i].name != NULL; i++)
{
if ((pEntry = g_ShareSys.AddNativeToCache(this, &natives[i])) == NULL)
{
continue;
}
m_Natives.push_back(pEntry);
}
}
void CNativeOwner::PropogateMarkSerial(unsigned int serial)
{
CNativeOwner *pOwner;
List<CPlugin *>::iterator iter;
for (iter = m_Dependents.begin();
iter != m_Dependents.end();
iter++)
{
pOwner = (*iter);
pOwner->SetMarkSerial(serial);
}
}
void CNativeOwner::UnbindWeakRef(const WeakNative & ref)
{
sp_native_t *native;
IPluginContext *pContext;
pContext = ref.pl->GetBaseContext();
if ((pContext->GetNativeByIndex(ref.idx, &native)) == SP_ERROR_NONE)
{
/* If there is no reference, the native must be unbound */
if (ref.entry == NULL)
{
native->status = SP_NATIVE_UNBOUND;
native->pfn = NULL;
}
/* If we've cached a reference, it's a core native we can
* rebind back to its original (this was a replacement).
*/
else
{
native->pfn = ref.entry->func;
}
}
}
void CNativeOwner::DropEverything()
{
NativeEntry *pEntry;
List<WeakNative>::iterator iter;
List<NativeEntry *>::iterator ntv_iter;
/* Unbind and remove all weak references to us */
iter = m_WeakRefs.begin();
while (iter != m_WeakRefs.end())
{
UnbindWeakRef((*iter));
iter = m_WeakRefs.erase(iter);
}
/* Unmark our replacement natives */
ntv_iter = m_ReplacedNatives.begin();
while (ntv_iter != m_ReplacedNatives.end())
{
pEntry = (*ntv_iter);
pEntry->replacement.func = NULL;
pEntry->replacement.owner = NULL;
ntv_iter = m_ReplacedNatives.erase(ntv_iter);
}
/* Strip all of our natives from the cache */
ntv_iter = m_Natives.begin();
while (ntv_iter != m_Natives.end())
{
g_ShareSys.ClearNativeFromCache(this, (*ntv_iter)->name);
ntv_iter = m_Natives.erase(ntv_iter);
}
}
void CNativeOwner::DropWeakRefsTo(CPlugin *pPlugin)
{
List<WeakNative>::iterator iter;
iter = m_WeakRefs.begin();
while (iter != m_WeakRefs.end())
{
WeakNative & ref = (*iter);
if (ref.pl == pPlugin)
{
iter = m_WeakRefs.erase(iter);
}
else
{
iter++;
}
}
}
void CNativeOwner::DropRefsTo(CPlugin *pPlugin)
{
m_Dependents.remove(pPlugin);
DropWeakRefsTo(pPlugin);
}
void CNativeOwner::AddReplacedNative(NativeEntry *pEntry)
{
m_ReplacedNatives.push_back(pEntry);
}
-59
View File
@@ -1,59 +0,0 @@
#ifndef _INCLUDE_SOURCEMOD_NATIVE_OWNER_H_
#define _INCLUDE_SOURCEMOD_NATIVE_OWNER_H_
#include <sp_vm_types.h>
#include <sh_list.h>
class CPlugin;
struct NativeEntry;
struct WeakNative
{
WeakNative(CPlugin *plugin, uint32_t index) :
pl(plugin), idx(index), entry(NULL)
{
pl = plugin;
idx = index;
}
WeakNative(CPlugin *plugin, uint32_t index, NativeEntry *pEntry) :
pl(plugin), idx(index), entry(pEntry)
{
pl = plugin;
idx = index;
}
CPlugin *pl;
uint32_t idx;
NativeEntry *entry;
};
using namespace SourceHook;
class CNativeOwner
{
public:
CNativeOwner();
public:
virtual void DropEverything();
public:
void AddNatives(const sp_nativeinfo_t *info);
public:
void SetMarkSerial(unsigned int serial);
unsigned int GetMarkSerial();
void PropogateMarkSerial(unsigned int serial);
public:
void AddDependent(CPlugin *pPlugin);
void AddWeakRef(const WeakNative & ref);
void DropRefsTo(CPlugin *pPlugin);
void AddReplacedNative(NativeEntry *pEntry);
private:
void DropWeakRefsTo(CPlugin *pPlugin);
void UnbindWeakRef(const WeakNative & ref);
protected:
List<CPlugin *> m_Dependents;
unsigned int m_nMarkSerial;
List<WeakNative> m_WeakRefs;
List<NativeEntry *> m_Natives;
List<NativeEntry *> m_ReplacedNatives;
};
#endif //_INCLUDE_SOURCEMOD_NATIVE_OWNER_H_
-226
View File
@@ -1,226 +0,0 @@
/**
* vim: set ts=4 :
* =============================================================================
* SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
* =============================================================================
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, version 3.0, as published by the
* Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <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 "NextMap.h"
#include "Logger.h"
#include "sourcemm_api.h"
#include "sm_stringutil.h"
#include "sourcehook.h"
#include "sm_srvcmds.h"
NextMapManager g_NextMap;
#if SOURCE_ENGINE != SE_DARKMESSIAH
SH_DECL_HOOK2_void(IVEngineServer, ChangeLevel, SH_NOATTRIB, 0, const char *, const char *);
#else
SH_DECL_HOOK4_void(IVEngineServer, ChangeLevel, SH_NOATTRIB, 0, const char *, const char *, const char *, bool);
#endif
#if SOURCE_ENGINE >= SE_ORANGEBOX
SH_DECL_EXTERN1_void(ConCommand, Dispatch, SH_NOATTRIB, false, const CCommand &);
#elif SOURCE_ENGINE == SE_DARKMESSIAH
SH_DECL_EXTERN0_void(ConCommand, Dispatch, SH_NOATTRIB, false);
#else
# if SH_IMPL_VERSION >= 4
extern int __SourceHook_FHAddConCommandDispatch(void *,bool,class fastdelegate::FastDelegate0<void>);
# else
extern bool __SourceHook_FHAddConCommandDispatch(void *,bool,class fastdelegate::FastDelegate0<void>);
#endif
extern bool __SourceHook_FHRemoveConCommandDispatch(void *,bool,class fastdelegate::FastDelegate0<void>);
#endif
ConCommand *changeLevelCmd = NULL;
ConVar sm_nextmap("sm_nextmap", "", FCVAR_NOTIFY);
bool g_forcedChange = false;
void NextMapManager::OnSourceModAllInitialized_Post()
{
#if SOURCE_ENGINE >= SE_ORANGEBOX
SH_ADD_HOOK(IVEngineServer, ChangeLevel, engine, SH_MEMBER(this, &NextMapManager::HookChangeLevel), false);
#else
SH_ADD_HOOK_MEMFUNC(IVEngineServer, ChangeLevel, engine, this, &NextMapManager::HookChangeLevel, false);
#endif
ConCommand *pCmd = FindCommand("changelevel");
if (pCmd != NULL)
{
SH_ADD_HOOK_STATICFUNC(ConCommand, Dispatch, pCmd, CmdChangeLevelCallback, false);
changeLevelCmd = pCmd;
}
}
void NextMapManager::OnSourceModShutdown()
{
#if SOURCE_ENGINE >= SE_ORANGEBOX
SH_REMOVE_HOOK(IVEngineServer, ChangeLevel, engine, SH_MEMBER(this, &NextMapManager::HookChangeLevel), false);
#else
SH_REMOVE_HOOK_MEMFUNC(IVEngineServer, ChangeLevel, engine, this, &NextMapManager::HookChangeLevel, false);
#endif
if (changeLevelCmd != NULL)
{
SH_REMOVE_HOOK_STATICFUNC(ConCommand, Dispatch, changeLevelCmd, CmdChangeLevelCallback, false);
}
SourceHook::List<MapChangeData *>::iterator iter;
iter = m_mapHistory.begin();
while (iter != m_mapHistory.end())
{
delete (MapChangeData *)*iter;
iter = m_mapHistory.erase(iter);
}
}
const char *NextMapManager::GetNextMap()
{
return sm_nextmap.GetString();
}
bool NextMapManager::SetNextMap(const char *map)
{
if (!engine->IsMapValid(map))
{
return false;
}
sm_nextmap.SetValue(map);
return true;
}
#if SOURCE_ENGINE != SE_DARKMESSIAH
void NextMapManager::HookChangeLevel(const char *map, const char *unknown)
#else
void NextMapManager::HookChangeLevel(const char *map, const char *unknown, const char *video, bool bLongLoading)
#endif
{
if (g_forcedChange)
{
g_Logger.LogMessage("[SM] Changed map to \"%s\"", map);
RETURN_META(MRES_IGNORED);
}
const char *newmap = sm_nextmap.GetString();
if (newmap[0] == 0 || !engine->IsMapValid(newmap))
{
RETURN_META(MRES_IGNORED);
}
g_Logger.LogMessage("[SM] Changed map to \"%s\"", newmap);
UTIL_Format(m_tempChangeInfo.m_mapName, sizeof(m_tempChangeInfo.m_mapName), newmap);
UTIL_Format(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));
#else
RETURN_META_NEWPARAMS(MRES_IGNORED, &IVEngineServer::ChangeLevel, (newmap, unknown, video, bLongLoading));
#endif
}
void NextMapManager::OnSourceModLevelChange( const char *mapName )
{
/* Skip the first 'mapchange' when the server starts up */
if (m_tempChangeInfo.startTime != 0)
{
if (strcmp(mapName, m_tempChangeInfo.m_mapName) == 0)
{
/* The map change was as we expected */
m_mapHistory.push_back(new MapChangeData(lastMap, m_tempChangeInfo.m_changeReason, m_tempChangeInfo.startTime));
}
else
{
/* Something intercepted the mapchange */
char newReason[255];
UTIL_Format(newReason, sizeof(newReason), "%s (Map overridden)", m_tempChangeInfo.m_changeReason);
m_mapHistory.push_back(new MapChangeData(lastMap, newReason, m_tempChangeInfo.startTime));
}
/* TODO: Should this be customizable? */
if (m_mapHistory.size() > 20)
{
SourceHook::List<MapChangeData *>::iterator iter;
iter = m_mapHistory.begin();
delete (MapChangeData *)*iter;
m_mapHistory.erase(iter);
}
}
m_tempChangeInfo.m_mapName[0] ='\0';
m_tempChangeInfo.m_changeReason[0] = '\0';
m_tempChangeInfo.startTime = time(NULL);
UTIL_Format(lastMap, sizeof(lastMap), mapName);
}
void NextMapManager::ForceChangeLevel( const char *mapName, const char* changeReason )
{
/* Store the mapname and reason */
UTIL_Format(m_tempChangeInfo.m_mapName, sizeof(m_tempChangeInfo.m_mapName), mapName);
UTIL_Format(m_tempChangeInfo.m_changeReason, sizeof(m_tempChangeInfo.m_changeReason), changeReason);
/* Change level and skip our hook */
g_forcedChange = true;
engine->ChangeLevel(mapName, NULL);
g_forcedChange = false;
}
NextMapManager::NextMapManager()
{
m_tempChangeInfo = MapChangeData();
m_mapHistory = SourceHook::List<MapChangeData *>();
}
#if SOURCE_ENGINE >= SE_ORANGEBOX
void CmdChangeLevelCallback(const CCommand &command)
{
#else
void CmdChangeLevelCallback()
{
CCommand command;
#endif
if (command.ArgC() < 2)
{
return;
}
if (g_NextMap.m_tempChangeInfo.m_mapName[0] == '\0')
{
UTIL_Format(g_NextMap.m_tempChangeInfo.m_mapName, sizeof(g_NextMap.m_tempChangeInfo.m_mapName), command.Arg(1));
UTIL_Format(g_NextMap.m_tempChangeInfo.m_changeReason, sizeof(g_NextMap.m_tempChangeInfo.m_changeReason), "changelevel Command");
}
}
-103
View File
@@ -1,103 +0,0 @@
/**
* vim: set ts=4 :
* =============================================================================
* SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
* =============================================================================
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, version 3.0, as published by the
* Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <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_SOURCEMOD_NEXTMAP_H_
#define _INCLUDE_SOURCEMOD_NEXTMAP_H_
#include "sm_globals.h"
#include "eiface.h"
#include "sh_list.h"
#include "sm_stringutil.h"
struct MapChangeData
{
MapChangeData(const char *mapName, const char *changeReason, time_t time)
{
UTIL_Format(m_mapName, sizeof(m_mapName), mapName);
UTIL_Format(m_changeReason, sizeof(m_changeReason), changeReason);
startTime = time;
}
MapChangeData()
{
m_mapName[0] = '\0';
m_changeReason[0] = '\0';
startTime = 0;
}
char m_mapName[32];
char m_changeReason[100];
time_t startTime;
};
#if SOURCE_ENGINE >= SE_ORANGEBOX
void CmdChangeLevelCallback(const CCommand &command);
#else
void CmdChangeLevelCallback();
#endif
class NextMapManager : public SMGlobalClass
{
public:
NextMapManager();
#if SOURCE_ENGINE >= SE_ORANGEBOX
friend void CmdChangeLevelCallback(const CCommand &command);
#else
friend void CmdChangeLevelCallback();
#endif
void OnSourceModAllInitialized_Post();
void OnSourceModShutdown();
void OnSourceModLevelChange(const char *mapName);
const char *GetNextMap();
bool SetNextMap(const char *map);
void ForceChangeLevel(const char *mapName, const char* changeReason);
#if SOURCE_ENGINE != SE_DARKMESSIAH
void HookChangeLevel(const char *map, const char *unknown);
#else
void HookChangeLevel(const char *map, const char *unknown, const char *video, bool bLongLoading);
#endif
public:
SourceHook::List<MapChangeData *> m_mapHistory;
private:
MapChangeData m_tempChangeInfo;
char lastMap[32];
};
extern NextMapManager g_NextMap;
#endif //_INCLUDE_SOURCEMOD_NEXTMAP_H_
-131
View File
@@ -1,131 +0,0 @@
/**
* vim: set ts=4 :
* =============================================================================
* SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
* =============================================================================
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, version 3.0, as published by the
* Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <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 "PhraseCollection.h"
#include "Translator.h"
#include "sm_stringutil.h"
CPhraseCollection::CPhraseCollection()
{
}
CPhraseCollection::~CPhraseCollection()
{
}
void CPhraseCollection::Destroy()
{
delete this;
}
IPhraseFile *CPhraseCollection::AddPhraseFile(const char *filename)
{
size_t i;
unsigned int fid;
IPhraseFile *pFile;
char full_name[PLATFORM_MAX_PATH];
/* No compat shim here. The user should have read the doc. */
UTIL_Format(full_name, sizeof(full_name), "%s.txt", filename);
fid = g_Translator.FindOrAddPhraseFile(full_name);
pFile = g_Translator.GetFileByIndex(fid);
for (i = 0; i < m_Files.size(); i++)
{
if (m_Files[i] == pFile)
{
return pFile;
}
}
m_Files.push_back(pFile);
return pFile;
}
unsigned int CPhraseCollection::GetFileCount()
{
return (unsigned int)m_Files.size();
}
IPhraseFile *CPhraseCollection::GetFile(unsigned int file)
{
if (file >= m_Files.size())
{
return NULL;
}
return m_Files[file];
}
TransError CPhraseCollection::FindTranslation(const char *key, unsigned int langid, Translation *pTrans)
{
size_t i;
for (i = 0; i < m_Files.size(); i++)
{
if (m_Files[i]->GetTranslation(key, langid, pTrans) == Trans_Okay)
{
return Trans_Okay;
}
}
return Trans_BadPhrase;
}
bool CPhraseCollection::FormatString(char *buffer,
size_t maxlength,
const char *format,
void **params,
unsigned int numparams,
size_t *pOutLength,
const char **pFailPhrase)
{
unsigned int arg;
arg = 0;
if (!gnprintf(buffer, maxlength, format, this, params, numparams, arg, pOutLength, pFailPhrase))
{
return false;
}
if (arg != numparams)
{
if (pFailPhrase != NULL)
{
*pFailPhrase = NULL;
}
return false;
}
return true;
}
-65
View File
@@ -1,65 +0,0 @@
/**
* vim: set ts=4 :
* =============================================================================
* SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
* =============================================================================
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, version 3.0, as published by the
* Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <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_SOURCEMOD_PHRASECOLLECTION_H_
#define _INCLUDE_SOURCEMOD_PHRASECOLLECTION_H_
#include <string.h>
#include <sh_vector.h>
#include <ITranslator.h>
using namespace SourceHook;
using namespace SourceMod;
class CPhraseCollection : public IPhraseCollection
{
public:
CPhraseCollection();
~CPhraseCollection();
public:
IPhraseFile *AddPhraseFile(const char *filename);
unsigned int GetFileCount();
IPhraseFile *GetFile(unsigned int file);
void Destroy();
TransError FindTranslation(const char *key, unsigned int langid, Translation *pTrans);
bool FormatString(
char *buffer,
size_t maxlength,
const char *format,
void **params,
unsigned int numparams,
size_t *pOutLength,
const char **pFailPhrase);
private:
CVector<IPhraseFile *> m_Files;
};
#endif //_INCLUDE_SOURCEMOD_PHRASECOLLECTION_H_
+91 -363
View File
@@ -1,8 +1,8 @@
/** /**
* vim: set ts=4 sw=4 tw=99 noet : * vim: set ts=4 :
* ============================================================================= * =============================================================================
* SourceMod * SourceMod
* Copyright (C) 2004-2009 AlliedModders LLC. All rights reserved. * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
* ============================================================================= * =============================================================================
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under
@@ -46,16 +46,13 @@
#include <inetchannel.h> #include <inetchannel.h>
#include <iclient.h> #include <iclient.h>
#include "GameConfigs.h" #include "GameConfigs.h"
#include "ExtensionSys.h" #include "systems/ExtensionSys.h"
#include <sourcemod_version.h>
#include "ConsoleDetours.h"
PlayerManager g_Players; PlayerManager g_Players;
bool g_OnMapStarted = false; bool g_OnMapStarted = false;
IForward *PreAdminCheck = NULL; IForward *PreAdminCheck = NULL;
IForward *PostAdminCheck = NULL; IForward *PostAdminCheck = NULL;
IForward *PostAdminFilter = NULL; IForward *PostAdminFilter = NULL;
IForward *OnClientConnected = NULL;
const unsigned int *g_NumPlayersToAuth = NULL; const unsigned int *g_NumPlayersToAuth = NULL;
int lifestate_offset = -1; int lifestate_offset = -1;
List<ICommandTargetProcessor *> target_processors; List<ICommandTargetProcessor *> target_processors;
@@ -63,7 +60,7 @@ List<ICommandTargetProcessor *> target_processors;
SH_DECL_HOOK5(IServerGameClients, ClientConnect, SH_NOATTRIB, 0, bool, edict_t *, const char *, const char *, char *, int); 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 *); SH_DECL_HOOK2_void(IServerGameClients, ClientPutInServer, SH_NOATTRIB, 0, edict_t *, const char *);
SH_DECL_HOOK1_void(IServerGameClients, ClientDisconnect, SH_NOATTRIB, 0, edict_t *); SH_DECL_HOOK1_void(IServerGameClients, ClientDisconnect, SH_NOATTRIB, 0, edict_t *);
#if SOURCE_ENGINE >= SE_ORANGEBOX #if defined ORANGEBOX_BUILD
SH_DECL_HOOK2_void(IServerGameClients, ClientCommand, SH_NOATTRIB, 0, edict_t *, const CCommand &); SH_DECL_HOOK2_void(IServerGameClients, ClientCommand, SH_NOATTRIB, 0, edict_t *, const CCommand &);
#else #else
SH_DECL_HOOK1_void(IServerGameClients, ClientCommand, SH_NOATTRIB, 0, edict_t *); SH_DECL_HOOK1_void(IServerGameClients, ClientCommand, SH_NOATTRIB, 0, edict_t *);
@@ -71,23 +68,6 @@ SH_DECL_HOOK1_void(IServerGameClients, ClientCommand, SH_NOATTRIB, 0, edict_t *)
SH_DECL_HOOK1_void(IServerGameClients, ClientSettingsChanged, SH_NOATTRIB, 0, edict_t *); SH_DECL_HOOK1_void(IServerGameClients, ClientSettingsChanged, SH_NOATTRIB, 0, edict_t *);
SH_DECL_HOOK3_void(IServerGameDLL, ServerActivate, SH_NOATTRIB, 0, edict_t *, int, int); SH_DECL_HOOK3_void(IServerGameDLL, ServerActivate, SH_NOATTRIB, 0, edict_t *, int, int);
#if SOURCE_ENGINE >= SE_ORANGEBOX
SH_DECL_EXTERN1_void(ConCommand, Dispatch, SH_NOATTRIB, false, const CCommand &);
#elif SOURCE_ENGINE == SE_DARKMESSIAH
SH_DECL_EXTERN0_void(ConCommand, Dispatch, SH_NOATTRIB, false);
#else
# if SH_IMPL_VERSION >= 4
extern int __SourceHook_FHAddConCommandDispatch(void *,bool,class fastdelegate::FastDelegate0<void>);
# else
extern bool __SourceHook_FHAddConCommandDispatch(void *,bool,class fastdelegate::FastDelegate0<void>);
# endif
extern bool __SourceHook_FHRemoveConCommandDispatch(void *,bool,class fastdelegate::FastDelegate0<void>);
#endif
ConCommand *maxplayersCmd = NULL;
unsigned int g_PlayerSerialCount = 0;
class KickPlayerTimer : public ITimedEvent class KickPlayerTimer : public ITimedEvent
{ {
public: public:
@@ -141,7 +121,7 @@ void PlayerManager::OnSourceModAllInitialized()
ParamType p1[] = {Param_Cell, Param_String, Param_Cell}; ParamType p1[] = {Param_Cell, Param_String, Param_Cell};
ParamType p2[] = {Param_Cell}; ParamType p2[] = {Param_Cell};
m_clconnect = g_Forwards.CreateForward("OnClientConnect", ET_LowEvent, 3, p1); m_clconnect = g_Forwards.CreateForward("OnClientConnect", ET_Event, 3, p1);
m_clputinserver = g_Forwards.CreateForward("OnClientPutInServer", ET_Ignore, 1, p2); m_clputinserver = g_Forwards.CreateForward("OnClientPutInServer", ET_Ignore, 1, p2);
m_cldisconnect = g_Forwards.CreateForward("OnClientDisconnect", ET_Ignore, 1, p2); m_cldisconnect = g_Forwards.CreateForward("OnClientDisconnect", ET_Ignore, 1, p2);
m_cldisconnect_post = g_Forwards.CreateForward("OnClientDisconnect_Post", ET_Ignore, 1, p2); m_cldisconnect_post = g_Forwards.CreateForward("OnClientDisconnect_Post", ET_Ignore, 1, p2);
@@ -150,23 +130,12 @@ void PlayerManager::OnSourceModAllInitialized()
m_clauth = g_Forwards.CreateForward("OnClientAuthorized", ET_Ignore, 2, NULL, Param_Cell, Param_String); m_clauth = g_Forwards.CreateForward("OnClientAuthorized", ET_Ignore, 2, NULL, Param_Cell, Param_String);
m_onActivate = g_Forwards.CreateForward("OnServerLoad", ET_Ignore, 0, NULL); m_onActivate = g_Forwards.CreateForward("OnServerLoad", ET_Ignore, 0, NULL);
m_onActivate2 = g_Forwards.CreateForward("OnMapStart", ET_Ignore, 0, NULL); m_onActivate2 = g_Forwards.CreateForward("OnMapStart", ET_Ignore, 0, NULL);
OnClientConnected = g_Forwards.CreateForward("OnClientConnected", ET_Ignore, 1, p2);
PreAdminCheck = g_Forwards.CreateForward("OnClientPreAdminCheck", ET_Event, 1, p1); PreAdminCheck = g_Forwards.CreateForward("OnClientPreAdminCheck", ET_Event, 1, p1);
PostAdminCheck = g_Forwards.CreateForward("OnClientPostAdminCheck", ET_Ignore, 1, p1); PostAdminCheck = g_Forwards.CreateForward("OnClientPostAdminCheck", ET_Ignore, 1, p1);
PostAdminFilter = g_Forwards.CreateForward("OnClientPostAdminFilter", ET_Ignore, 1, p1); PostAdminFilter = g_Forwards.CreateForward("OnClientPostAdminFilter", ET_Ignore, 1, p1);
m_bIsListenServer = !engine->IsDedicatedServer(); m_bIsListenServer = !engine->IsDedicatedServer();
m_ListenClient = 0; m_ListenClient = 0;
g_ConVarManager.AddConVarChangeListener("tv_enable", this);
ConCommand *pCmd = FindCommand("maxplayers");
if (pCmd != NULL)
{
SH_ADD_HOOK_STATICFUNC(ConCommand, Dispatch, pCmd, CmdMaxplayersCallback, true);
maxplayersCmd = pCmd;
}
} }
void PlayerManager::OnSourceModShutdown() void PlayerManager::OnSourceModShutdown()
@@ -189,20 +158,12 @@ void PlayerManager::OnSourceModShutdown()
g_Forwards.ReleaseForward(m_clauth); g_Forwards.ReleaseForward(m_clauth);
g_Forwards.ReleaseForward(m_onActivate); g_Forwards.ReleaseForward(m_onActivate);
g_Forwards.ReleaseForward(m_onActivate2); g_Forwards.ReleaseForward(m_onActivate2);
g_Forwards.ReleaseForward(OnClientConnected);
g_Forwards.ReleaseForward(PreAdminCheck); g_Forwards.ReleaseForward(PreAdminCheck);
g_Forwards.ReleaseForward(PostAdminCheck); g_Forwards.ReleaseForward(PostAdminCheck);
g_Forwards.ReleaseForward(PostAdminFilter); g_Forwards.ReleaseForward(PostAdminFilter);
delete [] m_Players; delete [] m_Players;
g_ConVarManager.RemoveConVarChangeListener("tv_enable", this);
if (maxplayersCmd != NULL)
{
SH_REMOVE_HOOK_STATICFUNC(ConCommand, Dispatch, maxplayersCmd, CmdMaxplayersCallback, true);
}
} }
ConfigResult PlayerManager::OnSourceModConfigChanged(const char *key, ConfigResult PlayerManager::OnSourceModConfigChanged(const char *key,
@@ -240,15 +201,13 @@ void PlayerManager::OnServerActivate(edict_t *pEdictList, int edictCount, int cl
/* Initialize all players */ /* Initialize all players */
m_maxClients = clientMax; m_maxClients = clientMax;
m_PlayerCount = 0; m_PlayerCount = 0;
m_Players = new CPlayer[ABSOLUTE_PLAYER_LIMIT + 1]; m_Players = new CPlayer[m_maxClients + 1];
m_AuthQueue = new unsigned int[ABSOLUTE_PLAYER_LIMIT + 1]; m_AuthQueue = new unsigned int[m_maxClients + 1];
m_FirstPass = true; m_FirstPass = true;
memset(m_AuthQueue, 0, sizeof(unsigned int) * (ABSOLUTE_PLAYER_LIMIT + 1)); memset(m_AuthQueue, 0, sizeof(unsigned int) * (m_maxClients + 1));
g_NumPlayersToAuth = &m_AuthQueue[0]; g_NumPlayersToAuth = &m_AuthQueue[0];
g_PluginSys.SyncMaxClients(clientMax);
} }
g_Extensions.CallOnCoreMapStart(pEdictList, edictCount, clientMax); g_Extensions.CallOnCoreMapStart(pEdictList, edictCount, clientMax);
m_onActivate->Execute(NULL); m_onActivate->Execute(NULL);
@@ -265,13 +224,6 @@ void PlayerManager::OnServerActivate(edict_t *pEdictList, int edictCount, int cl
g_OnMapStarted = true; g_OnMapStarted = true;
SMGlobalClass *cls = SMGlobalClass::head;
while (cls)
{
cls->OnSourceModLevelActivated();
cls = cls->m_pGlobalClassNext;
}
SM_ExecuteAllConfigs(); SM_ExecuteAllConfigs();
} }
@@ -335,7 +287,7 @@ void PlayerManager::RunAuthChecks()
unsigned int removed = 0; unsigned int removed = 0;
for (unsigned int i=1; i<=m_AuthQueue[0]; i++) for (unsigned int i=1; i<=m_AuthQueue[0]; i++)
{ {
pPlayer = &m_Players[m_AuthQueue[i]]; pPlayer = GetPlayerByIndex(m_AuthQueue[i]);
authstr = engine->GetPlayerNetworkIDString(pPlayer->m_pEdict); authstr = engine->GetPlayerNetworkIDString(pPlayer->m_pEdict);
if (authstr && authstr[0] != '\0' if (authstr && authstr[0] != '\0'
&& (strcmp(authstr, "STEAM_ID_PENDING") != 0)) && (strcmp(authstr, "STEAM_ID_PENDING") != 0))
@@ -408,8 +360,7 @@ void PlayerManager::RunAuthChecks()
bool PlayerManager::OnClientConnect(edict_t *pEntity, const char *pszName, const char *pszAddress, char *reject, int maxrejectlen) bool PlayerManager::OnClientConnect(edict_t *pEntity, const char *pszName, const char *pszAddress, char *reject, int maxrejectlen)
{ {
int client = IndexOfEdict(pEntity); int client = engine->IndexOfEdict(pEntity);
CPlayer *pPlayer = &m_Players[client];
List<IClientListener *>::iterator iter; List<IClientListener *>::iterator iter;
IClientListener *pListener = NULL; IClientListener *pListener = NULL;
@@ -424,37 +375,34 @@ bool PlayerManager::OnClientConnect(edict_t *pEntity, const char *pszName, const
cell_t res = 1; cell_t res = 1;
pPlayer->Initialize(pszName, pszAddress, pEntity); m_Players[client].Initialize(pszName, pszAddress, pEntity);
m_clconnect->PushCell(client); m_clconnect->PushCell(client);
m_clconnect->PushStringEx(reject, maxrejectlen, SM_PARAM_STRING_UTF8 | SM_PARAM_STRING_COPY, SM_PARAM_COPYBACK); m_clconnect->PushStringEx(reject, maxrejectlen, SM_PARAM_STRING_UTF8, SM_PARAM_COPYBACK);
m_clconnect->PushCell(maxrejectlen); m_clconnect->PushCell(maxrejectlen);
m_clconnect->Execute(&res); m_clconnect->Execute(&res, NULL);
if (res) if (res)
{ {
if (!pPlayer->IsAuthorized()) if (!m_Players[client].IsAuthorized())
{ {
m_AuthQueue[++m_AuthQueue[0]] = client; m_AuthQueue[++m_AuthQueue[0]] = client;
} }
m_UserIdLookUp[engine->GetPlayerUserId(pEntity)] = client;
} }
else else
{ {
if (!pPlayer->IsFakeClient()) RETURN_META_VALUE(MRES_SUPERCEDE, false);
{
RETURN_META_VALUE(MRES_SUPERCEDE, false);
}
} }
m_UserIdLookUp[engine->GetPlayerUserId(pEntity)] = client;
return true; return true;
} }
bool PlayerManager::OnClientConnect_Post(edict_t *pEntity, const char *pszName, const char *pszAddress, char *reject, int maxrejectlen) bool PlayerManager::OnClientConnect_Post(edict_t *pEntity, const char *pszName, const char *pszAddress, char *reject, int maxrejectlen)
{ {
int client = IndexOfEdict(pEntity); int client = engine->IndexOfEdict(pEntity);
bool orig_value = META_RESULT_ORIG_RET(bool); bool orig_value = META_RESULT_ORIG_RET(bool);
CPlayer *pPlayer = &m_Players[client]; CPlayer *pPlayer = GetPlayerByIndex(client);
if (orig_value) if (orig_value)
{ {
@@ -466,24 +414,16 @@ bool PlayerManager::OnClientConnect_Post(edict_t *pEntity, const char *pszName,
pListener->OnClientConnected(client); pListener->OnClientConnected(client);
if (!pPlayer->IsConnected()) if (!pPlayer->IsConnected())
{ {
return true; break;
} }
} }
if (!pPlayer->IsFakeClient()
&& m_bIsListenServer
&& strncmp(pszAddress, "127.0.0.1", 9) == 0)
{
m_ListenClient = client;
}
cell_t res;
OnClientConnected->PushCell(client);
OnClientConnected->Execute(&res, NULL);
} }
else
if (!pPlayer->IsFakeClient()
&& m_bIsListenServer
&& strncmp(pszAddress, "127.0.0.1", 9) == 0)
{ {
InvalidatePlayer(pPlayer); m_ListenClient = client;
} }
return true; return true;
@@ -492,9 +432,9 @@ bool PlayerManager::OnClientConnect_Post(edict_t *pEntity, const char *pszName,
void PlayerManager::OnClientPutInServer(edict_t *pEntity, const char *playername) void PlayerManager::OnClientPutInServer(edict_t *pEntity, const char *playername)
{ {
cell_t res; cell_t res;
int client = IndexOfEdict(pEntity); int client = engine->IndexOfEdict(pEntity);
CPlayer *pPlayer = &m_Players[client];
CPlayer *pPlayer = GetPlayerByIndex(client);
/* If they're not connected, they're a bot */ /* If they're not connected, they're a bot */
if (!pPlayer->IsConnected()) if (!pPlayer->IsConnected())
{ {
@@ -502,7 +442,6 @@ void PlayerManager::OnClientPutInServer(edict_t *pEntity, const char *playername
char error[255]; char error[255];
const char *authid = engine->GetPlayerNetworkIDString(pEntity); const char *authid = engine->GetPlayerNetworkIDString(pEntity);
pPlayer->Authorize(authid); pPlayer->Authorize(authid);
pPlayer->m_bFakeClient = true;
if (!OnClientConnect(pEntity, playername, "127.0.0.1", error, sizeof(error))) if (!OnClientConnect(pEntity, playername, "127.0.0.1", error, sizeof(error)))
{ {
/* :TODO: kick the bot if it's rejected */ /* :TODO: kick the bot if it's rejected */
@@ -520,11 +459,6 @@ void PlayerManager::OnClientPutInServer(edict_t *pEntity, const char *playername
return; return;
} }
} }
cell_t res;
OnClientConnected->PushCell(client);
OnClientConnected->Execute(&res, NULL);
/* Now do authorization */ /* Now do authorization */
for (iter=m_hooks.begin(); iter!=m_hooks.end(); iter++) for (iter=m_hooks.begin(); iter!=m_hooks.end(); iter++)
{ {
@@ -559,7 +493,7 @@ void PlayerManager::OnClientPutInServer(edict_t *pEntity, const char *playername
} }
} }
pPlayer->Connect(); m_Players[client].Connect();
m_PlayerCount++; m_PlayerCount++;
List<IClientListener *>::iterator iter; List<IClientListener *>::iterator iter;
@@ -573,9 +507,9 @@ void PlayerManager::OnClientPutInServer(edict_t *pEntity, const char *playername
m_clputinserver->PushCell(client); m_clputinserver->PushCell(client);
m_clputinserver->Execute(&res, NULL); m_clputinserver->Execute(&res, NULL);
if (pPlayer->IsAuthorized()) if (m_Players[client].IsAuthorized())
{ {
pPlayer->DoPostConnectAuthorization(); m_Players[client].DoPostConnectAuthorization();
} }
} }
@@ -595,10 +529,9 @@ void PlayerManager::OnSourceModLevelEnd()
void PlayerManager::OnClientDisconnect(edict_t *pEntity) void PlayerManager::OnClientDisconnect(edict_t *pEntity)
{ {
cell_t res; cell_t res;
int client = IndexOfEdict(pEntity); int client = engine->IndexOfEdict(pEntity);
CPlayer *pPlayer = &m_Players[client];
if (pPlayer->IsConnected()) if (m_Players[client].IsConnected())
{ {
m_cldisconnect->PushCell(client); m_cldisconnect->PushCell(client);
m_cldisconnect->Execute(&res, NULL); m_cldisconnect->Execute(&res, NULL);
@@ -609,7 +542,7 @@ void PlayerManager::OnClientDisconnect(edict_t *pEntity)
return; return;
} }
if (pPlayer->WasCountedAsInGame()) if (m_Players[client].WasCountedAsInGame())
{ {
m_PlayerCount--; m_PlayerCount--;
} }
@@ -622,8 +555,29 @@ void PlayerManager::OnClientDisconnect(edict_t *pEntity)
pListener->OnClientDisconnecting(client); pListener->OnClientDisconnecting(client);
} }
InvalidatePlayer(pPlayer); /**
* Remove client from auth queue if necessary
*/
if (!m_Players[client].IsAuthorized())
{
for (unsigned int i=1; i<=m_AuthQueue[0]; i++)
{
if (m_AuthQueue[i] == (unsigned)client)
{
/* Move everything ahead of us back by one */
for (unsigned int j=i+1; j<=m_AuthQueue[0]; j++)
{
m_AuthQueue[j-1] = m_AuthQueue[j];
}
/* Remove us and break */
m_AuthQueue[0]--;
break;
}
}
}
m_Players[client].Disconnect();
m_UserIdLookUp[engine->GetPlayerUserId(pEntity)] = 0;
if (m_ListenClient == client) if (m_ListenClient == client)
{ {
m_ListenClient = 0; m_ListenClient = 0;
@@ -633,7 +587,7 @@ void PlayerManager::OnClientDisconnect(edict_t *pEntity)
void PlayerManager::OnClientDisconnect_Post(edict_t *pEntity) void PlayerManager::OnClientDisconnect_Post(edict_t *pEntity)
{ {
cell_t res; cell_t res;
int client = IndexOfEdict(pEntity); int client = engine->IndexOfEdict(pEntity);
m_cldisconnect_post->PushCell(client); m_cldisconnect_post->PushCell(client);
m_cldisconnect_post->Execute(&res, NULL); m_cldisconnect_post->Execute(&res, NULL);
@@ -647,28 +601,7 @@ void PlayerManager::OnClientDisconnect_Post(edict_t *pEntity)
} }
} }
void ClientConsolePrint(edict_t *e, const char *fmt, ...) #if defined ORANGEBOX_BUILD
{
char buffer[512];
va_list ap;
va_start(ap, fmt);
size_t len = vsnprintf(buffer, sizeof(buffer), fmt, ap);
va_end(ap);
if (len >= sizeof(buffer) - 1)
{
buffer[sizeof(buffer) - 2] = '\n';
buffer[sizeof(buffer) - 1] = '\0';
} else {
buffer[len++] = '\n';
buffer[len] = '\0';
}
engine->ClientPrintf(e, buffer);
}
#if SOURCE_ENGINE >= SE_ORANGEBOX
void PlayerManager::OnClientCommand(edict_t *pEntity, const CCommand &args) void PlayerManager::OnClientCommand(edict_t *pEntity, const CCommand &args)
{ {
#else #else
@@ -676,48 +609,15 @@ void PlayerManager::OnClientCommand(edict_t *pEntity)
{ {
CCommand args; CCommand args;
#endif #endif
int client = IndexOfEdict(pEntity); int client = engine->IndexOfEdict(pEntity);
cell_t res = Pl_Continue; cell_t res = Pl_Continue;
CPlayer *pPlayer = &m_Players[client];
if (!pPlayer->IsConnected()) CPlayer *pPlayer = GetPlayerByIndex(client);
if (!pPlayer || !pPlayer->IsConnected())
{ {
return; return;
} }
if (strcmp(args.Arg(0), "sm") == 0)
{
if (args.ArgC() > 1 && strcmp(args.Arg(1), "plugins") == 0)
{
g_PluginSys.ListPluginsToClient(pPlayer, args);
RETURN_META(MRES_SUPERCEDE);
}
else if (args.ArgC() > 1 && strcmp(args.Arg(1), "credits") == 0)
{
ClientConsolePrint(pEntity,
"SourceMod would not be possible without:");
ClientConsolePrint(pEntity,
" David \"BAILOPAN\" Anderson, Borja \"faluco\" Ferrer");
ClientConsolePrint(pEntity,
" Scott \"DS\" Ehlert, Matt \"pRED\" Woodrow");
ClientConsolePrint(pEntity,
" Michael \"ferret\" McKoy, Pavol \"PM OnoTo\" Marko");
ClientConsolePrint(pEntity,
"SourceMod is open source under the GNU General Public License.");
RETURN_META(MRES_SUPERCEDE);
}
ClientConsolePrint(pEntity,
"SourceMod %s, by AlliedModders LLC", SM_FULL_VERSION);
ClientConsolePrint(pEntity,
"To see running plugins, type \"sm plugins\"");
ClientConsolePrint(pEntity,
"To see credits, type \"sm credits\"");
ClientConsolePrint(pEntity,
"Visit http://www.sourcemod.net/");
RETURN_META(MRES_SUPERCEDE);
}
g_HL2.PushCommandStack(&args); g_HL2.PushCommandStack(&args);
int argcount = args.ArgC() - 1; int argcount = args.ArgC() - 1;
@@ -735,27 +635,10 @@ void PlayerManager::OnClientCommand(edict_t *pEntity)
} }
} }
if (g_ConsoleDetours.IsEnabled())
{
cell_t res2 = g_ConsoleDetours.InternalDispatch(client, args);
if (res2 >= Pl_Stop)
{
g_HL2.PopCommandStack();
RETURN_META(MRES_SUPERCEDE);
}
else if (res2 > res)
{
res = res2;
}
}
cell_t res2 = Pl_Continue; cell_t res2 = Pl_Continue;
if (pPlayer->IsInGame()) m_clcommand->PushCell(client);
{ m_clcommand->PushCell(argcount);
m_clcommand->PushCell(client); m_clcommand->Execute(&res2, NULL);
m_clcommand->PushCell(argcount);
m_clcommand->Execute(&res2, NULL);
}
if (res2 > res) if (res2 > res)
{ {
@@ -781,58 +664,52 @@ void PlayerManager::OnClientCommand(edict_t *pEntity)
void PlayerManager::OnClientSettingsChanged(edict_t *pEntity) void PlayerManager::OnClientSettingsChanged(edict_t *pEntity)
{ {
cell_t res; cell_t res;
int client = IndexOfEdict(pEntity); int client = engine->IndexOfEdict(pEntity);
CPlayer *pPlayer = &m_Players[client];
if (!pPlayer->IsConnected()) if (!m_Players[client].IsConnected())
{ {
return; return;
} }
m_clinfochanged->PushCell(client); m_clinfochanged->PushCell(engine->IndexOfEdict(pEntity));
m_clinfochanged->Execute(&res, NULL); m_clinfochanged->Execute(&res, NULL);
if (pPlayer->IsFakeClient()) IPlayerInfo *info = m_Players[client].GetPlayerInfo();
{
return;
}
IPlayerInfo *info = pPlayer->GetPlayerInfo();
const char *new_name = info ? info->GetName() : engine->GetClientConVarValue(client, "name"); const char *new_name = info ? info->GetName() : engine->GetClientConVarValue(client, "name");
const char *old_name = pPlayer->m_Name.c_str(); const char *old_name = m_Players[client].m_Name.c_str();
if (strcmp(old_name, new_name) != 0) if (strcmp(old_name, new_name) != 0)
{ {
AdminId id = g_Admins.FindAdminByIdentity("name", new_name); AdminId id = g_Admins.FindAdminByIdentity("name", new_name);
if (id != INVALID_ADMIN_ID && pPlayer->GetAdminId() != id) if (id != INVALID_ADMIN_ID && m_Players[client].GetAdminId() != id)
{ {
if (!CheckSetAdminName(client, pPlayer, id)) if (!CheckSetAdminName(client, &m_Players[client], id))
{ {
pPlayer->Kick("Your name is reserved by SourceMod; set your password to use it."); m_Players[client].Kick("Your name is reserved by SourceMod; set your password to use it.");
RETURN_META(MRES_IGNORED); RETURN_META(MRES_IGNORED);
} }
} else if ((id = g_Admins.FindAdminByIdentity("name", old_name)) != INVALID_ADMIN_ID) { } else if ((id = g_Admins.FindAdminByIdentity("name", old_name)) != INVALID_ADMIN_ID) {
if (id == pPlayer->GetAdminId()) if (id == m_Players[client].GetAdminId())
{ {
/* This player is changing their name; force them to drop admin privileges! */ /* This player is changing their name; force them to drop admin privileges! */
pPlayer->SetAdminId(INVALID_ADMIN_ID, false); m_Players[client].SetAdminId(INVALID_ADMIN_ID, false);
} }
} }
pPlayer->SetName(new_name); m_Players[client].SetName(new_name);
} }
if (m_PassInfoVar.size() > 0) if (m_PassInfoVar.size() > 0)
{ {
/* Try for a password change */ /* Try for a password change */
const char *old_pass = pPlayer->m_LastPassword.c_str(); const char *old_pass = m_Players[client].m_LastPassword.c_str();
const char *new_pass = engine->GetClientConVarValue(client, m_PassInfoVar.c_str()); const char *new_pass = engine->GetClientConVarValue(client, m_PassInfoVar.c_str());
if (strcmp(old_pass, new_pass) != 0) if (strcmp(old_pass, new_pass) != 0)
{ {
pPlayer->m_LastPassword.assign(new_pass); m_Players[client].m_LastPassword.assign(new_pass);
if (pPlayer->IsInGame() && pPlayer->IsAuthorized()) if (m_Players[client].IsInGame() && m_Players[client].IsAuthorized())
{ {
/* If there is already an admin id assigned, this will just bail out. */ /* If there is already an admin id assigned, this will just bail out. */
pPlayer->DoBasicAdminChecks(); m_Players[client].DoBasicAdminChecks();
} }
} }
} }
@@ -914,7 +791,7 @@ void PlayerManager::RemoveClientListener(IClientListener *listener)
IGamePlayer *PlayerManager::GetGamePlayer(edict_t *pEdict) IGamePlayer *PlayerManager::GetGamePlayer(edict_t *pEdict)
{ {
int index = IndexOfEdict(pEdict); int index = engine->IndexOfEdict(pEdict);
return GetGamePlayer(index); return GetGamePlayer(index);
} }
@@ -983,33 +860,6 @@ void PlayerManager::UnregisterCommandTargetProcessor(ICommandTargetProcessor *pH
target_processors.remove(pHandler); target_processors.remove(pHandler);
} }
void PlayerManager::InvalidatePlayer(CPlayer *pPlayer)
{
/**
* Remove client from auth queue if necessary
*/
if (!pPlayer->IsAuthorized())
{
for (unsigned int i=1; i<=m_AuthQueue[0]; i++)
{
if (m_AuthQueue[i] == (unsigned)pPlayer->m_iIndex)
{
/* Move everything ahead of us back by one */
for (unsigned int j=i+1; j<=m_AuthQueue[0]; j++)
{
m_AuthQueue[j-1] = m_AuthQueue[j];
}
/* Remove us and break */
m_AuthQueue[0]--;
break;
}
}
}
m_UserIdLookUp[engine->GetPlayerUserId(pPlayer->m_pEdict)] = 0;
pPlayer->Disconnect();
}
int PlayerManager::InternalFilterCommandTarget(CPlayer *pAdmin, CPlayer *pTarget, int flags) int PlayerManager::InternalFilterCommandTarget(CPlayer *pAdmin, CPlayer *pTarget, int flags)
{ {
if ((flags & COMMAND_FILTER_CONNECTED) == COMMAND_FILTER_CONNECTED if ((flags & COMMAND_FILTER_CONNECTED) == COMMAND_FILTER_CONNECTED
@@ -1180,18 +1030,10 @@ void PlayerManager::ProcessCommandTarget(cmd_target_info_t *info)
if (strcmp(info->pattern, "@me") == 0 && info->admin != 0) if (strcmp(info->pattern, "@me") == 0 && info->admin != 0)
{ {
info->reason = FilterCommandTarget(pAdmin, pAdmin, info->flags); info->targets[0] = info->admin;
if (info->reason == COMMAND_TARGET_VALID) info->num_targets = 1;
{ strncopy(info->target_name, pAdmin->GetName(), info->target_name_maxlength);
info->targets[0] = info->admin; info->target_name_style = COMMAND_TARGETNAME_RAW;
info->num_targets = 1;
strncopy(info->target_name, pAdmin->GetName(), info->target_name_maxlength);
info->target_name_style = COMMAND_TARGETNAME_RAW;
}
else
{
info->num_targets = 0;
}
return; return;
} }
@@ -1343,95 +1185,6 @@ void PlayerManager::ProcessCommandTarget(cmd_target_info_t *info)
} }
} }
void PlayerManager::OnConVarChanged( ConVar *pConVar, const char *oldValue, float flOldValue )
{
if (pConVar->GetBool() && !atoi(oldValue))
{
MaxPlayersChanged(gpGlobals->maxClients + 1);
}
else
{
MaxPlayersChanged();
}
}
void PlayerManager::OnSourceModMaxPlayersChanged( int newvalue )
{
m_maxClients = newvalue;
}
void PlayerManager::MaxPlayersChanged( int newvalue /*= -1*/ )
{
if (!m_FirstPass)
{
return;
}
if (newvalue == -1)
{
newvalue = gpGlobals->maxClients;
}
if (newvalue == MaxClients())
{
return;
}
/* Notify the rest of core */
SMGlobalClass *pBase = SMGlobalClass::head;
while (pBase)
{
pBase->OnSourceModMaxPlayersChanged(newvalue);
pBase = pBase->m_pGlobalClassNext;
}
/* Notify Extensions */
List<IClientListener *>::iterator iter;
IClientListener *pListener = NULL;
for (iter=m_hooks.begin(); iter!=m_hooks.end(); iter++)
{
pListener = (*iter);
if (pListener->GetClientListenerVersion() >= 8)
{
pListener->OnMaxPlayersChanged(newvalue);
}
}
}
int PlayerManager::GetClientFromSerial(unsigned int serial)
{
serial_t s;
s.value = serial;
int client = s.bits.index;
IGamePlayer *pPlayer = GetGamePlayer(client);
if (!pPlayer)
{
return 0;
}
if (serial == pPlayer->GetSerial())
{
return client;
}
return 0;
}
#if SOURCE_ENGINE >= SE_ORANGEBOX
void CmdMaxplayersCallback(const CCommand &command)
{
#else
void CmdMaxplayersCallback()
{
#endif
g_Players.MaxPlayersChanged();
}
/******************* /*******************
*** PLAYER CODE *** *** PLAYER CODE ***
*******************/ *******************/
@@ -1446,11 +1199,9 @@ CPlayer::CPlayer()
m_TempAdmin = false; m_TempAdmin = false;
m_Info = NULL; m_Info = NULL;
m_bAdminCheckSignalled = false; m_bAdminCheckSignalled = false;
m_UserId = -1;
m_bIsInKickQueue = false; m_bIsInKickQueue = false;
m_LastPassword.clear(); m_LastPassword.clear();
m_LangId = SOURCEMOD_LANGUAGE_ENGLISH; m_LangId = LANGUAGE_ENGLISH;
m_bFakeClient = false;
} }
void CPlayer::Initialize(const char *name, const char *ip, edict_t *pEntity) void CPlayer::Initialize(const char *name, const char *ip, edict_t *pEntity)
@@ -1459,12 +1210,9 @@ void CPlayer::Initialize(const char *name, const char *ip, edict_t *pEntity)
m_Name.assign(name); m_Name.assign(name);
m_Ip.assign(ip); m_Ip.assign(ip);
m_pEdict = pEntity; m_pEdict = pEntity;
m_iIndex = IndexOfEdict(pEntity); m_iIndex = engine->IndexOfEdict(pEntity);
m_LangId = g_Translator.GetServerLanguage(); m_LangId = g_Translator.GetServerLanguage();
m_Serial.bits.index = m_iIndex;
m_Serial.bits.serial = g_PlayerSerialCount++;
char ip2[24], *ptr; char ip2[24], *ptr;
strncopy(ip2, ip, sizeof(ip2)); strncopy(ip2, ip, sizeof(ip2));
if ((ptr = strchr(ip2, ':')) != NULL) if ((ptr = strchr(ip2, ':')) != NULL)
@@ -1484,7 +1232,7 @@ void CPlayer::Connect()
m_IsInGame = true; m_IsInGame = true;
const char *var = g_Players.GetPassInfoVar(); const char *var = g_Players.GetPassInfoVar();
int client = IndexOfEdict(m_pEdict); int client = engine->IndexOfEdict(m_pEdict);
if (var[0] != '\0') if (var[0] != '\0')
{ {
const char *pass = engine->GetClientConVarValue(client, var); const char *pass = engine->GetClientConVarValue(client, var);
@@ -1521,7 +1269,6 @@ void CPlayer::Disconnect()
m_bAdminCheckSignalled = false; m_bAdminCheckSignalled = false;
m_UserId = -1; m_UserId = -1;
m_bIsInKickQueue = false; m_bIsInKickQueue = false;
m_bFakeClient = false;
} }
void CPlayer::SetName(const char *name) void CPlayer::SetName(const char *name)
@@ -1586,7 +1333,7 @@ IPlayerInfo *CPlayer::GetPlayerInfo()
bool CPlayer::IsFakeClient() bool CPlayer::IsFakeClient()
{ {
return m_bFakeClient; return (strcmp(m_AuthID.c_str(), "BOT") == 0);
} }
void CPlayer::SetAdminId(AdminId id, bool temporary) void CPlayer::SetAdminId(AdminId id, bool temporary)
@@ -1624,22 +1371,8 @@ void CPlayer::Kick(const char *str)
{ {
MarkAsBeingKicked(); MarkAsBeingKicked();
INetChannel *pNetChan = static_cast<INetChannel *>(engine->GetPlayerNetInfo(m_iIndex)); INetChannel *pNetChan = static_cast<INetChannel *>(engine->GetPlayerNetInfo(m_iIndex));
if (pNetChan == NULL) IClient *pClient = static_cast<IClient *>(pNetChan->GetMsgHandler());
{ pClient->Disconnect("%s", str);
/* What does this even mean? Hell if I know. */
int userid = GetUserId();
if (userid > 0)
{
char buffer[255];
UTIL_Format(buffer, sizeof(buffer), "kickid %d %s\n", userid, str);
engine->ServerCommand(buffer);
}
}
else
{
IClient *pClient = static_cast<IClient *>(pNetChan->GetMsgHandler());
pClient->Disconnect("%s", str);
}
} }
void CPlayer::Authorize_Post() void CPlayer::Authorize_Post()
@@ -1745,7 +1478,7 @@ void CPlayer::DoBasicAdminChecks()
/* First check the name */ /* First check the name */
AdminId id; AdminId id;
int client = IndexOfEdict(m_pEdict); int client = engine->IndexOfEdict(m_pEdict);
if ((id = g_Admins.FindAdminByIdentity("name", GetName())) != INVALID_ADMIN_ID) if ((id = g_Admins.FindAdminByIdentity("name", GetName())) != INVALID_ADMIN_ID)
{ {
@@ -1766,7 +1499,7 @@ void CPlayer::DoBasicAdminChecks()
} }
} }
/* Check steam id */ /* Check IP address */
if ((id = g_Admins.FindAdminByIdentity("steam", m_AuthID.c_str())) != INVALID_ADMIN_ID) if ((id = g_Admins.FindAdminByIdentity("steam", m_AuthID.c_str())) != INVALID_ADMIN_ID)
{ {
if (g_Players.CheckSetAdmin(client, this, id)) if (g_Players.CheckSetAdmin(client, this, id))
@@ -1842,8 +1575,3 @@ int CPlayer::GetLifeState()
return PLAYER_LIFE_DEAD; return PLAYER_LIFE_DEAD;
} }
} }
unsigned int CPlayer::GetSerial()
{
return m_Serial.value;
}
+4 -33
View File
@@ -2,7 +2,7 @@
* vim: set ts=4 : * vim: set ts=4 :
* ============================================================================= * =============================================================================
* SourceMod * SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
* ============================================================================= * =============================================================================
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under
@@ -41,7 +41,6 @@
#include <sh_string.h> #include <sh_string.h>
#include <sh_list.h> #include <sh_list.h>
#include <sh_vector.h> #include <sh_vector.h>
#include "ConVarManager.h"
using namespace SourceHook; using namespace SourceHook;
@@ -51,16 +50,6 @@ using namespace SourceHook;
#define MIN_API_FOR_ADMINCALLS 7 #define MIN_API_FOR_ADMINCALLS 7
union serial_t
{
uint32_t value;
struct
{
uint8_t index;
uint32_t serial : 24;
} bits;
};
class CPlayer : public IGamePlayer class CPlayer : public IGamePlayer
{ {
friend class PlayerManager; friend class PlayerManager;
@@ -79,15 +68,14 @@ public:
void SetAdminId(AdminId id, bool temporary); void SetAdminId(AdminId id, bool temporary);
AdminId GetAdminId(); AdminId GetAdminId();
void Kick(const char *str); void Kick(const char *str);
bool IsInKickQueue();
IPlayerInfo *GetPlayerInfo(); IPlayerInfo *GetPlayerInfo();
unsigned int GetLanguageId(); unsigned int GetLanguageId();
int GetUserId(); int GetUserId();
bool RunAdminCacheChecks(); bool RunAdminCacheChecks();
void NotifyPostAdminChecks(); void NotifyPostAdminChecks();
unsigned int GetSerial();
public: public:
void DoBasicAdminChecks(); void DoBasicAdminChecks();
bool IsInKickQueue();
void MarkAsBeingKicked(); void MarkAsBeingKicked();
int GetLifeState(); int GetLifeState();
private: private:
@@ -117,14 +105,11 @@ private:
int m_iIndex; int m_iIndex;
unsigned int m_LangId; unsigned int m_LangId;
int m_UserId; int m_UserId;
bool m_bFakeClient;
serial_t m_Serial;
}; };
class PlayerManager : class PlayerManager :
public SMGlobalClass, public SMGlobalClass,
public IPlayerManager, public IPlayerManager
public IConVarChangeListener
{ {
friend class CPlayer; friend class CPlayer;
public: public:
@@ -135,7 +120,6 @@ public: //SMGlobalClass
void OnSourceModShutdown(); void OnSourceModShutdown();
void OnSourceModLevelEnd(); void OnSourceModLevelEnd();
ConfigResult OnSourceModConfigChanged(const char *key, const char *value, ConfigSource source, char *error, size_t maxlength); ConfigResult OnSourceModConfigChanged(const char *key, const char *value, ConfigSource source, char *error, size_t maxlength);
void OnSourceModMaxPlayersChanged(int newvalue);
public: public:
CPlayer *GetPlayerByIndex(int client) const; CPlayer *GetPlayerByIndex(int client) const;
void RunAuthChecks(); void RunAuthChecks();
@@ -147,7 +131,7 @@ public:
void OnClientPutInServer(edict_t *pEntity, char const *playername); void OnClientPutInServer(edict_t *pEntity, char const *playername);
void OnClientDisconnect(edict_t *pEntity); void OnClientDisconnect(edict_t *pEntity);
void OnClientDisconnect_Post(edict_t *pEntity); void OnClientDisconnect_Post(edict_t *pEntity);
#if SOURCE_ENGINE >= SE_ORANGEBOX #if defined ORANGEBOX_BUILD
void OnClientCommand(edict_t *pEntity, const CCommand &args); void OnClientCommand(edict_t *pEntity, const CCommand &args);
#else #else
void OnClientCommand(edict_t *pEntity); void OnClientCommand(edict_t *pEntity);
@@ -168,9 +152,6 @@ public: //IPlayerManager
void RegisterCommandTargetProcessor(ICommandTargetProcessor *pHandler); void RegisterCommandTargetProcessor(ICommandTargetProcessor *pHandler);
void UnregisterCommandTargetProcessor(ICommandTargetProcessor *pHandler); void UnregisterCommandTargetProcessor(ICommandTargetProcessor *pHandler);
void ProcessCommandTarget(cmd_target_info_t *info); void ProcessCommandTarget(cmd_target_info_t *info);
int GetClientFromSerial(unsigned int serial);
public: // IConVarChangeListener
void OnConVarChanged(ConVar *pConVar, const char *oldValue, float flOldValue);
public: public:
inline int MaxClients() inline int MaxClients()
{ {
@@ -190,10 +171,8 @@ public:
void RecheckAnyAdmins(); void RecheckAnyAdmins();
unsigned int GetReplyTo(); unsigned int GetReplyTo();
unsigned int SetReplyTo(unsigned int reply); unsigned int SetReplyTo(unsigned int reply);
void MaxPlayersChanged(int newvalue = -1);
private: private:
void OnServerActivate(edict_t *pEdictList, int edictCount, int clientMax); void OnServerActivate(edict_t *pEdictList, int edictCount, int clientMax);
void InvalidatePlayer(CPlayer *pPlayer);
private: private:
List<IClientListener *> m_hooks; List<IClientListener *> m_hooks;
IForward *m_clconnect; IForward *m_clconnect;
@@ -217,14 +196,6 @@ private:
int m_ListenClient; int m_ListenClient;
}; };
#if SOURCE_ENGINE >= SE_ORANGEBOX
void CmdMaxplayersCallback(const CCommand &command);
#else
void CmdMaxplayersCallback();
#endif
extern void ClientConsolePrint(edict_t *e, const char *fmt, ...);
extern PlayerManager g_Players; extern PlayerManager g_Players;
extern bool g_OnMapStarted; extern bool g_OnMapStarted;
extern const unsigned int *g_NumPlayersToAuth; extern const unsigned int *g_NumPlayersToAuth;
+22 -21
View File
@@ -2,7 +2,7 @@
* vim: set ts=4 : * vim: set ts=4 :
* ============================================================================= * =============================================================================
* SourceMod * SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
* ============================================================================= * =============================================================================
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under
@@ -30,12 +30,13 @@
*/ */
#include "Profiler.h" #include "Profiler.h"
#include <ISourceMod.h> #include "PluginSys.h"
#include "sm_stringutil.h"
#include "Logger.h"
#if defined PLATFORM_POSIX #if defined PLATFORM_POSIX
#include <sys/time.h> #include <sys/time.h>
#include <time.h> #include <time.h>
#endif #endif
#include <IPluginSys.h>
ProfileEngine g_Profiler; ProfileEngine g_Profiler;
IProfiler *sm_profiler = &g_Profiler; IProfiler *sm_profiler = &g_Profiler;
@@ -313,28 +314,28 @@ void ProfileEngine::Clear()
void ProfileEngine::OnSourceModAllInitialized() void ProfileEngine::OnSourceModAllInitialized()
{ {
rootmenu->AddRootConsoleCommand2("profiler", "Profiler commands", this); g_RootMenu.AddRootConsoleCommand("profiler", "Profiler commands", this);
} }
void ProfileEngine::OnSourceModShutdown() void ProfileEngine::OnSourceModShutdown()
{ {
rootmenu->RemoveRootConsoleCommand("profiler", this); g_RootMenu.RemoveRootConsoleCommand("profiler", this);
} }
void ProfileEngine::OnRootConsoleCommand2(const char *cmdname, const ICommandArgs *command) void ProfileEngine::OnRootConsoleCommand(const char *cmdname, const CCommand &command)
{ {
if (command->ArgC() >= 3) if (command.ArgC() >= 3)
{ {
if (strcmp(command->Arg(2), "flush") == 0) if (strcmp(command.Arg(2), "flush") == 0)
{ {
FILE *fp; FILE *fp;
char path[256]; char path[256];
g_pSM->BuildPath(Path_SM, path, sizeof(path), "logs/profile_%d.xml", (int)time(NULL)); g_SourceMod.BuildPath(Path_SM, path, sizeof(path), "logs/profile_%d.xml", (int)time(NULL));
if ((fp = fopen(path, "wt")) == NULL) if ((fp = fopen(path, "wt")) == NULL)
{ {
rootmenu->ConsolePrint("Failed, could not open file for writing: %s", path); g_RootMenu.ConsolePrint("Failed, could not open file for writing: %s", path);
return; return;
} }
@@ -342,14 +343,14 @@ void ProfileEngine::OnRootConsoleCommand2(const char *cmdname, const ICommandArg
fclose(fp); fclose(fp);
rootmenu->ConsolePrint("Profiler report generated as: %s\n", path); g_RootMenu.ConsolePrint("Profiler report generated as: %s\n", path);
return; return;
} }
} }
rootmenu->ConsolePrint("Profiler commands:"); g_RootMenu.ConsolePrint("Profiler commands:");
rootmenu->DrawGenericOption("flush", "Flushes statistics to disk and starts over"); g_RootMenu.DrawGenericOption("flush", "Flushes statistics to disk and starts over");
} }
bool ProfileEngine::GenerateReport(FILE *fp) bool ProfileEngine::GenerateReport(FILE *fp)
@@ -386,9 +387,9 @@ void ProfileEngine::WriteReport(FILE *fp, ProfileReport *report, const char *nam
{ {
ar = report->GetReport(i); ar = report->GetReport(i);
smcore.strncopy(new_name, ar->atom_name, sizeof(new_name)); strncopy(new_name, ar->atom_name, sizeof(new_name));
smcore.ReplaceAll(new_name, sizeof(new_name), "<", "&lt;", true); UTIL_ReplaceAll(new_name, sizeof(new_name), "<", "&lt;");
smcore.ReplaceAll(new_name, sizeof(new_name), ">", "&gt;", true); UTIL_ReplaceAll(new_name, sizeof(new_name), ">", "&gt;");
fprintf(fp, " <item name=\"%s\" numcalls=\"%d\" mintime=\"%f\" maxtime=\"%f\" totaltime=\"%f\"/>\n", fprintf(fp, " <item name=\"%s\" numcalls=\"%d\" mintime=\"%f\" maxtime=\"%f\" totaltime=\"%f\"/>\n",
new_name, new_name,
@@ -437,20 +438,20 @@ void ProfileReport::SaveAtom(const prof_atom_t &atom)
if (atom.atom_type == SP_PROF_NATIVES) if (atom.atom_type == SP_PROF_NATIVES)
{ {
smcore.strncopy(full_name, atom.name, sizeof(full_name)); strncopy(full_name, atom.name, sizeof(full_name));
} }
else else
{ {
IPlugin *pl; CPlugin *pl;
const char *file; const char *file;
file = "unknown"; file = "unknown";
if ((pl = pluginsys->FindPluginByContext(atom.ctx)) != NULL) if ((pl = g_PluginSys.GetPluginByCtx(atom.ctx)) != NULL)
{ {
file = pl->GetFilename(); file = pl->GetFilename();
} }
smcore.Format(full_name, sizeof(full_name), "%s!%s", file, atom.name); UTIL_Format(full_name, sizeof(full_name), "%s!%s", file, atom.name);
} }
atom_time = CalcAtomTime(atom); atom_time = CalcAtomTime(atom);
@@ -459,7 +460,7 @@ void ProfileReport::SaveAtom(const prof_atom_t &atom)
{ {
report = new prof_atom_report_t; report = new prof_atom_report_t;
smcore.strncopy(report->atom_name, full_name, sizeof(report->atom_name)); strncopy(report->atom_name, full_name, sizeof(report->atom_name));
report->max_time = atom_time; report->max_time = atom_time;
report->min_time = atom_time; report->min_time = atom_time;
report->num_calls = 1; report->num_calls = 1;
+5 -5
View File
@@ -2,7 +2,7 @@
* vim: set ts=4 : * vim: set ts=4 :
* ============================================================================= * =============================================================================
* SourceMod * SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
* ============================================================================= * =============================================================================
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under
@@ -38,8 +38,8 @@
#include <sh_vector.h> #include <sh_vector.h>
#include <sh_stack.h> #include <sh_stack.h>
#include <stdio.h> #include <stdio.h>
#include "common_logic.h" #include "sm_globals.h"
#include <IRootConsoleMenu.h> #include "sm_srvcmds.h"
using namespace SourcePawn; using namespace SourcePawn;
using namespace SourceHook; using namespace SourceHook;
@@ -103,7 +103,7 @@ public: //SMGlobalClass
void OnSourceModAllInitialized(); void OnSourceModAllInitialized();
void OnSourceModShutdown(); void OnSourceModShutdown();
public: //IRootConsoleCommand public: //IRootConsoleCommand
void OnRootConsoleCommand2(const char *cmdname, const ICommandArgs *command); void OnRootConsoleCommand(const char *cmdname, const CCommand &command);
public: //IProfiler public: //IProfiler
void OnNativeBegin(IPluginContext *pContext, sp_native_t *native); void OnNativeBegin(IPluginContext *pContext, sp_native_t *native);
void OnNativeEnd() ; void OnNativeEnd() ;
@@ -126,6 +126,6 @@ private:
prof_point_t m_ProfStart; prof_point_t m_ProfStart;
}; };
extern IProfiler *sm_profiler; extern ProfileEngine g_Profiler;
#endif //_INCLUDE_SOURCEMOD_PLUGIN_PROFILER_H_ #endif //_INCLUDE_SOURCEMOD_PLUGIN_PROFILER_H_
-611
View File
@@ -1,611 +0,0 @@
/**
* vim: set ts=4 :
* =============================================================================
* SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
* =============================================================================
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, version 3.0, as published by the
* Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <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 "ShareSys.h"
#include "HandleSys.h"
#include "ExtensionSys.h"
#include "LibrarySys.h"
#include "PluginSys.h"
#include "sm_stringutil.h"
ShareSystem g_ShareSys;
static unsigned int g_mark_serial = 0;
ShareSystem::ShareSystem()
{
m_IdentRoot.ident = 0;
m_TypeRoot = 0;
m_IfaceType = 0;
m_CoreType = 0;
}
IdentityToken_t *ShareSystem::CreateCoreIdentity()
{
if (!m_CoreType)
{
m_CoreType = CreateIdentType("CORE");
}
return CreateIdentity(m_CoreType, this);
}
void ShareSystem::Initialize()
{
TypeAccess sec;
g_HandleSys.InitAccessDefaults(&sec, NULL);
sec.ident = GetIdentRoot();
m_TypeRoot = g_HandleSys.CreateType("Identity", this, 0, &sec, NULL, NULL, NULL);
m_IfaceType = g_HandleSys.CreateType("Interface", this, 0, NULL, NULL, GetIdentRoot(), NULL);
/* Initialize our static identity handle */
m_IdentRoot.ident = g_HandleSys.CreateHandle(m_TypeRoot, NULL, NULL, GetIdentRoot(), NULL);
/* Add the Handle System and others... they are too innocent and pure to do it themselves */
AddInterface(NULL, &g_HandleSys);
AddInterface(NULL, &g_LibSys);
}
void ShareSystem::OnSourceModShutdown()
{
if (m_CoreType)
{
g_HandleSys.RemoveType(m_CoreType, GetIdentRoot());
}
g_HandleSys.RemoveType(m_IfaceType, GetIdentRoot());
g_HandleSys.RemoveType(m_TypeRoot, GetIdentRoot());
}
IdentityType_t ShareSystem::FindIdentType(const char *name)
{
HandleType_t type;
if (g_HandleSys.FindHandleType(name, &type))
{
if (g_HandleSys.TypeCheck(type, m_TypeRoot))
{
return type;
}
}
return 0;
}
IdentityType_t ShareSystem::CreateIdentType(const char *name)
{
if (!m_TypeRoot)
{
return 0;
}
return g_HandleSys.CreateType(name, this, m_TypeRoot, NULL, NULL, GetIdentRoot(), NULL);
}
void ShareSystem::OnHandleDestroy(HandleType_t type, void *object)
{
/* THIS WILL NEVER BE CALLED FOR ANYTHING WITH THE IDENTITY TYPE */
}
IdentityToken_t *ShareSystem::CreateIdentity(IdentityType_t type, void *ptr)
{
if (!m_TypeRoot)
{
return 0;
}
/* :TODO: Cache? */
IdentityToken_t *pToken = new IdentityToken_t;
HandleSecurity sec;
sec.pOwner = sec.pIdentity = GetIdentRoot();
pToken->ident = g_HandleSys.CreateHandleInt(type, NULL, &sec, NULL, NULL, true);
pToken->ptr = ptr;
pToken->type = type;
return pToken;
}
bool ShareSystem::AddInterface(IExtension *myself, SMInterface *iface)
{
if (!iface)
{
return false;
}
IfaceInfo info;
info.owner = myself;
info.iface = iface;
m_Interfaces.push_back(info);
return true;
}
bool ShareSystem::RequestInterface(const char *iface_name,
unsigned int iface_vers,
IExtension *myself,
SMInterface **pIface)
{
/* See if the interface exists */
List<IfaceInfo>::iterator iter;
SMInterface *iface;
IExtension *iface_owner;
bool found = false;
for (iter=m_Interfaces.begin(); iter!=m_Interfaces.end(); iter++)
{
IfaceInfo &info = (*iter);
iface = info.iface;
if (strcmp(iface->GetInterfaceName(), iface_name) == 0)
{
if (iface->GetInterfaceVersion() == iface_vers
|| iface->IsVersionCompatible(iface_vers))
{
iface_owner = info.owner;
found = true;
break;
}
}
}
if (!found)
{
return false;
}
/* Add a dependency node */
if (iface_owner)
{
IfaceInfo info;
info.iface = iface;
info.owner = iface_owner;
g_Extensions.BindDependency(myself, &info);
}
if (pIface)
{
*pIface = iface;
}
return true;
}
void ShareSystem::AddNatives(IExtension *myself, const sp_nativeinfo_t *natives)
{
CNativeOwner *pOwner;
pOwner = g_Extensions.GetNativeOwner(myself);
pOwner->AddNatives(natives);
}
void ShareSystem::DestroyIdentity(IdentityToken_t *identity)
{
HandleSecurity sec;
sec.pOwner = GetIdentRoot();
sec.pIdentity = GetIdentRoot();
g_HandleSys.FreeHandle(identity->ident, &sec);
delete identity;
}
void ShareSystem::DestroyIdentType(IdentityType_t type)
{
g_HandleSys.RemoveType(type, GetIdentRoot());
}
void ShareSystem::RemoveInterfaces(IExtension *pExtension)
{
List<IfaceInfo>::iterator iter = m_Interfaces.begin();
while (iter != m_Interfaces.end())
{
if ((*iter).owner == pExtension)
{
iter = m_Interfaces.erase(iter);
}
else
{
iter++;
}
}
}
void ShareSystem::AddDependency(IExtension *myself, const char *filename, bool require, bool autoload)
{
g_Extensions.AddDependency(myself, filename, require, autoload);
}
void ShareSystem::RegisterLibrary(IExtension *myself, const char *name)
{
g_Extensions.AddLibrary(myself, name);
}
void ShareSystem::OverrideNatives(IExtension *myself, const sp_nativeinfo_t *natives)
{
unsigned int i;
NativeEntry *pEntry;
CNativeOwner *pOwner;
pOwner = g_Extensions.GetNativeOwner(myself);
for (i = 0; natives[i].func != NULL && natives[i].name != NULL; i++)
{
if ((pEntry = FindNative(natives[i].name)) == NULL)
{
continue;
}
if (pEntry->owner != g_pCoreNatives)
{
continue;
}
if (pEntry->replacement.owner != NULL)
{
continue;
}
/* Now it's safe to add the override */
pEntry->replacement.func = natives[i].func;
pEntry->replacement.owner = pOwner;
pOwner->AddReplacedNative(pEntry);
}
}
NativeEntry *ShareSystem::FindNative(const char *name)
{
NativeEntry **ppEntry;
if ((ppEntry = m_NtvCache.retrieve(name)) == NULL)
{
return NULL;
}
return *ppEntry;
}
void ShareSystem::BindNativesToPlugin(CPlugin *pPlugin, bool bCoreOnly)
{
NativeEntry *pEntry;
sp_native_t *native;
uint32_t i, native_count;
IPluginContext *pContext;
pContext = pPlugin->GetBaseContext();
/* Generate a new serial ID, mark our dependencies with it. */
g_mark_serial++;
pPlugin->PropogateMarkSerial(g_mark_serial);
native_count = pContext->GetNativesNum();
for (i = 0; i < native_count; i++)
{
if (pContext->GetNativeByIndex(i, &native) != SP_ERROR_NONE)
{
continue;
}
/* If we're bound, check if there is a replacement available.
* If not, this native is totally finalized.
*/
if (native->status == SP_NATIVE_BOUND)
{
pEntry = (NativeEntry *)native->user;
assert(pEntry != NULL);
if (pEntry->replacement.owner == NULL
|| (pEntry->replacement.owner != NULL
&& pEntry->replacement.func == native->pfn))
{
continue;
}
}
/* Otherwise, the native must be in our cache. */
else if ((pEntry = FindNative(native->name)) == NULL)
{
continue;
}
if (bCoreOnly && pEntry->owner != g_pCoreNatives)
{
continue;
}
BindNativeToPlugin(pPlugin, native, i, pEntry);
}
}
void ShareSystem::BindNativeToPlugin(CPlugin *pPlugin, NativeEntry *pEntry)
{
uint32_t i;
sp_native_t *native;
IPluginContext *pContext;
pContext = pPlugin->GetBaseContext();
if (pContext->FindNativeByName(pEntry->name, &i) != SP_ERROR_NONE)
{
return;
}
if (pContext->GetNativeByIndex(i, &native) != SP_ERROR_NONE)
{
return;
}
if (native->status == SP_NATIVE_BOUND)
{
return;
}
BindNativeToPlugin(pPlugin, native, i, pEntry);
}
void ShareSystem::BindNativeToPlugin(CPlugin *pPlugin,
sp_native_t *native,
uint32_t index,
NativeEntry *pEntry)
{
/* Mark as bound... we do the rest next. */
native->status = SP_NATIVE_BOUND;
native->user = pEntry;
/* See if a replacement is available. */
if (pEntry->replacement.owner != NULL)
{
/* Perform a replacement bind. */
native->pfn = pEntry->replacement.func;
pEntry->replacement.owner->AddWeakRef(WeakNative(pPlugin, index, pEntry));
}
else
{
/* Perform a normal bind. */
native->pfn = pEntry->func;
/* We don't bother with dependency crap if the owner is Core. */
if (pEntry->owner != g_pCoreNatives)
{
/* The native is optional, this is a special case */
if ((native->flags & SP_NTVFLAG_OPTIONAL) == SP_NTVFLAG_OPTIONAL)
{
/* Only add if there is a valid owner. */
if (pEntry->owner != NULL)
{
pEntry->owner->AddWeakRef(WeakNative(pPlugin, index));
}
else
{
native->status = SP_NATIVE_UNBOUND;
}
}
/* Otherwise, we're a strong dependent and not a weak one */
else
{
/* See if this has already been marked as a dependent.
* If it has, it means this relationship has already occurred,
* and there is no reason to do it again.
*/
if (pEntry->owner != pPlugin
&& pEntry->owner->GetMarkSerial() != g_mark_serial)
{
/* This has not been marked as a dependency yet */
//pPlugin->AddDependency(pEntry->owner);
pEntry->owner->AddDependent(pPlugin);
pEntry->owner->SetMarkSerial(g_mark_serial);
}
}
}
}
}
NativeEntry *ShareSystem::AddNativeToCache(CNativeOwner *pOwner, const sp_nativeinfo_t *ntv)
{
NativeEntry *pEntry;
if ((pEntry = FindNative(ntv->name)) == NULL)
{
pEntry = new NativeEntry;
pEntry->owner = pOwner;
pEntry->name = ntv->name;
pEntry->func = ntv->func;
pEntry->replacement.func = NULL;
pEntry->replacement.owner = NULL;
pEntry->fake = NULL;
m_NtvCache.insert(ntv->name, pEntry);
return pEntry;
}
if (pEntry->owner != NULL)
{
return NULL;
}
pEntry->owner = pOwner;
pEntry->func = ntv->func;
pEntry->name = ntv->name;
return pEntry;
}
void ShareSystem::ClearNativeFromCache(CNativeOwner *pOwner, const char *name)
{
NativeEntry *pEntry;
if ((pEntry = FindNative(name)) == NULL)
{
return;
}
if (pEntry->owner != pOwner)
{
return;
}
if (pEntry->fake != NULL)
{
g_pSourcePawn2->DestroyFakeNative(pEntry->func);
delete pEntry->fake;
pEntry->fake = NULL;
}
pEntry->func = NULL;
pEntry->name = NULL;
pEntry->owner = NULL;
pEntry->replacement.func = NULL;
pEntry->replacement.owner = NULL;
}
NativeEntry *ShareSystem::AddFakeNative(IPluginFunction *pFunc, const char *name, SPVM_FAKENATIVE_FUNC func)
{
FakeNative *pFake;
NativeEntry *pEntry;
SPVM_NATIVE_FUNC gate;
if ((pEntry = FindNative(name)) != NULL && pEntry->owner != NULL)
{
return NULL;
}
pFake = new FakeNative;
if ((gate = g_pSourcePawn2->CreateFakeNative(func, pFake)) == NULL)
{
delete pFake;
return NULL;
}
if (pEntry == NULL)
{
pEntry = new NativeEntry;
m_NtvCache.insert(name, pEntry);
}
pFake->call = pFunc;
pFake->ctx = pFunc->GetParentContext();
strncopy(pFake->name, name, sizeof(pFake->name));
pEntry->fake = pFake;
pEntry->func = gate;
pEntry->name = pFake->name;
pEntry->owner = g_PluginSys.GetPluginByCtx(pFake->ctx->GetContext());
pEntry->replacement.func = NULL;
pEntry->replacement.owner = NULL;
return pEntry;
}
void ShareSystem::AddCapabilityProvider(IExtension *myself, IFeatureProvider *provider,
const char *name)
{
if (m_caps.retrieve(name) != NULL)
return;
Capability cap;
cap.ext = myself;
cap.provider = provider;
m_caps.insert(name, cap);
}
void ShareSystem::DropCapabilityProvider(IExtension *myself, IFeatureProvider *provider,
const char *name)
{
Capability *pCap = m_caps.retrieve(name);
if (pCap == NULL)
return;
if (pCap->ext != myself || pCap->provider != provider)
return;
m_caps.remove(name);
}
FeatureStatus ShareSystem::TestFeature(IPluginRuntime *pRuntime, FeatureType feature,
const char *name)
{
switch (feature)
{
case FeatureType_Native:
return TestNative(pRuntime, name);
case FeatureType_Capability:
return TestCap(name);
default:
break;
}
return FeatureStatus_Unknown;
}
FeatureStatus ShareSystem::TestNative(IPluginRuntime *pRuntime, const char *name)
{
uint32_t index;
if (pRuntime->FindNativeByName(name, &index) == SP_ERROR_NONE)
{
sp_native_t *native;
if (pRuntime->GetNativeByIndex(index, &native) == SP_ERROR_NONE)
{
if (native->status == SP_NATIVE_BOUND)
return FeatureStatus_Available;
else
return FeatureStatus_Unknown;
}
}
NativeEntry *entry = FindNative(name);
if (entry == NULL)
return FeatureStatus_Unknown;
if ((entry->replacement.owner != NULL || entry->owner != NULL) &&
(entry->replacement.func != NULL || entry->func != NULL))
{
return FeatureStatus_Available;
}
else
{
return FeatureStatus_Unavailable;
}
}
FeatureStatus ShareSystem::TestCap(const char *name)
{
Capability *cap = m_caps.retrieve(name);
if (cap == NULL)
return FeatureStatus_Unknown;
return cap->provider->GetFeatureStatus(FeatureType_Capability, name);
}
@@ -2,7 +2,7 @@
* vim: set ts=4 : * vim: set ts=4 :
* ============================================================================= * =============================================================================
* SourceMod * SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
* ============================================================================= * =============================================================================
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under
@@ -36,9 +36,9 @@
#include <stdlib.h> #include <stdlib.h>
#include <assert.h> #include <assert.h>
#include "TextParsers.h" #include "TextParsers.h"
//#include "ShareSys.h" #include "ShareSys.h"
//#include "sm_stringutil.h" #include "sm_stringutil.h"
//#include "LibrarySys.h" #include "LibrarySys.h"
TextParsers g_TextParser; TextParsers g_TextParser;
ITextParsers *textparsers = &g_TextParser; ITextParsers *textparsers = &g_TextParser;
@@ -69,6 +69,11 @@ TextParsers::TextParsers()
g_ws_chartable[(unsigned)' '] = 1; g_ws_chartable[(unsigned)' '] = 1;
} }
void TextParsers::OnSourceModAllInitialized()
{
g_ShareSys.AddInterface(NULL, this);
}
unsigned int TextParsers::GetUTF8CharBytes(const char *stream) unsigned int TextParsers::GetUTF8CharBytes(const char *stream)
{ {
return _GetUTF8CharBytes(stream); return _GetUTF8CharBytes(stream);
@@ -169,7 +174,7 @@ SMCError TextParsers::ParseSMCFile(const char *file,
states->line = 0; states->line = 0;
states->col = 0; states->col = 0;
} }
//g_LibSys.GetPlatformError(error, sizeof(error)); g_LibSys.GetPlatformError(error, sizeof(error));
UTIL_Format(buffer, maxsize, "File could not be opened: %s", error); UTIL_Format(buffer, maxsize, "File could not be opened: %s", error);
return SMCError_StreamOpen; return SMCError_StreamOpen;
} }
@@ -2,7 +2,7 @@
* vim: set ts=4 : * vim: set ts=4 :
* ============================================================================= * =============================================================================
* SourceMod * SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
* ============================================================================= * =============================================================================
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under
@@ -32,8 +32,8 @@
#ifndef _INCLUDE_SOURCEMOD_TEXTPARSERS_H_ #ifndef _INCLUDE_SOURCEMOD_TEXTPARSERS_H_
#define _INCLUDE_SOURCEMOD_TEXTPARSERS_H_ #define _INCLUDE_SOURCEMOD_TEXTPARSERS_H_
#include "ITextParsers.h" #include <ITextParsers.h>
#include "main.h" #include "sm_globals.h"
using namespace SourceMod; using namespace SourceMod;
@@ -46,10 +46,14 @@ using namespace SourceMod;
*/ */
typedef bool (*STREAMREADER)(void *, char *, size_t, unsigned int *); typedef bool (*STREAMREADER)(void *, char *, size_t, unsigned int *);
class TextParsers : public ITextParsers class TextParsers :
public ITextParsers,
public SMGlobalClass
{ {
public: public:
TextParsers(); TextParsers();
public: //SMGlobalClass
void OnSourceModAllInitialized();
public: public:
bool ParseFile_INI(const char *file, bool ParseFile_INI(const char *file,
ITextListener_INI *ini_listener, ITextListener_INI *ini_listener,
@@ -1,8 +1,8 @@
/** /**
* vim: set ts=4 sw=4 : * vim: set ts=4 :
* ============================================================================= * =============================================================================
* SourceMod * SourceMod
* Copyright (C) 2004-2009 AlliedModders LLC. All rights reserved. * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
* ============================================================================= * =============================================================================
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under
@@ -28,9 +28,10 @@
* *
* Version: $Id$ * Version: $Id$
*/ */
#include <sm_platform.h>
#include "ThreadSupport.h" #include "ThreadSupport.h"
#include "common_logic.h" #include "sm_globals.h"
#include "ShareSys.h"
#if defined PLATFORM_POSIX #if defined PLATFORM_POSIX
#include "thread/PosixThreads.h" #include "thread/PosixThreads.h"
@@ -46,7 +47,6 @@ class RegThreadStuff : public SMGlobalClass
public: public:
void OnSourceModAllInitialized() void OnSourceModAllInitialized()
{ {
sharesys->AddInterface(NULL, g_pThreader); g_ShareSys.AddInterface(NULL, g_pThreader);
} }
} s_RegThreadStuff; } s_RegThreadStuff;
@@ -2,7 +2,7 @@
* vim: set ts=4 : * vim: set ts=4 :
* ============================================================================= * =============================================================================
* SourceMod * SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
* ============================================================================= * =============================================================================
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under
+1 -1
View File
@@ -2,7 +2,7 @@
* vim: set ts=4 : * vim: set ts=4 :
* ============================================================================= * =============================================================================
* SourceMod * SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
* ============================================================================= * =============================================================================
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under
+1 -1
View File
@@ -2,7 +2,7 @@
* vim: set ts=4 : * vim: set ts=4 :
* ============================================================================= * =============================================================================
* SourceMod * SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
* ============================================================================= * =============================================================================
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under
+91 -179
View File
@@ -2,7 +2,7 @@
* vim: set ts=4 : * vim: set ts=4 :
* ============================================================================= * =============================================================================
* SourceMod * SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
* ============================================================================= * =============================================================================
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under
@@ -38,11 +38,9 @@
#include "sm_stringutil.h" #include "sm_stringutil.h"
#include "sourcemod.h" #include "sourcemod.h"
#include "PlayerManager.h" #include "PlayerManager.h"
#include "PhraseCollection.h"
#include "ShareSys.h"
Translator g_Translator; Translator g_Translator;
IPhraseCollection *g_pCorePhrases = NULL; CPhraseFile *g_pCorePhrases = NULL;
unsigned int g_pCorePhraseID = 0; unsigned int g_pCorePhraseID = 0;
struct trans_t struct trans_t
@@ -103,7 +101,7 @@ void CPhraseFile::ParseWarning(const char *message, ...)
m_FileLogged = true; m_FileLogged = true;
} }
g_Logger.LogError("[SM] %s", buffer); g_Logger.LogError("[SM] %s", message);
} }
void CPhraseFile::ReparseFile() void CPhraseFile::ReparseFile()
@@ -152,45 +150,6 @@ void CPhraseFile::ReparseFile()
g_Logger.LogError("[SM] Fatal error encountered parsing translation file \"%s\"", m_File.c_str()); g_Logger.LogError("[SM] Fatal error encountered parsing translation file \"%s\"", m_File.c_str());
g_Logger.LogError("[SM] Error (line %d, column %d): %s", states.line, states.col, msg); g_Logger.LogError("[SM] Error (line %d, column %d): %s", states.line, states.col, msg);
} }
const char *code;
for (unsigned int i = 1; i < m_LangCount; i++)
{
if (!m_pTranslator->GetLanguageInfo(i, &code, NULL))
{
continue;
}
g_SourceMod.BuildPath(Path_SM,
path,
PLATFORM_MAX_PATH,
"translations/%s/%s",
code,
m_File.c_str());
/* Speculatively load these. */
if (!g_LibSys.PathExists(path))
{
continue;
}
if ((err=textparsers->ParseFile_SMC(path, this, &states)) != SMCError_Okay)
{
const char *msg = textparsers->GetSMCErrorString(err);
if (!msg)
{
msg = m_ParseError.c_str();
}
g_Logger.LogError("[SM] Fatal error encountered parsing translation file \"%s/%s\"",
code,
m_File.c_str());
g_Logger.LogError("[SM] Error (line %d, column %d): %s",
states.line,
states.col,
msg);
}
}
} }
void CPhraseFile::ReadSMC_ParseStart() void CPhraseFile::ReadSMC_ParseStart()
@@ -217,21 +176,21 @@ SMCResult CPhraseFile::ReadSMC_NewSection(const SMCStates *states, const char *n
m_ParseState = PPS_InPhrase; m_ParseState = PPS_InPhrase;
recognized = true; recognized = true;
void *value; phrase_t *pPhrase;
if (sm_trie_retrieve(m_pPhraseLookup, name, &value)) m_CurPhrase = m_pMemory->CreateMem(sizeof(phrase_t), (void **)&pPhrase);
{
m_CurPhrase = reinterpret_cast<int>(value);
}
else
{
phrase_t *pPhrase;
m_CurPhrase = m_pMemory->CreateMem(sizeof(phrase_t), (void **)&pPhrase);
sm_trie_insert(m_pPhraseLookup, name, reinterpret_cast<void *>(m_CurPhrase));
/* Create the reverse lookup */
if (!sm_trie_insert(m_pPhraseLookup, name, reinterpret_cast<void *>(m_CurPhrase)))
{
ParseWarning("Skipping duplicate phrase \"%s\" on line %d.", name, states->line);
/* :IDEA: prevent memory waste by seeking backwards in memtable? */
m_CurPhrase = -1;
}
else
{
/* Initialize new phrase */ /* Initialize new phrase */
trans_t *pTrans; trans_t *pTrans;
pPhrase->fmt_count = 0; pPhrase->fmt_count = 0;
pPhrase->fmt_list = -1; pPhrase->fmt_list = -1;
@@ -241,14 +200,13 @@ SMCResult CPhraseFile::ReadSMC_NewSection(const SMCStates *states, const char *n
pPhrase->translations = 0; pPhrase->translations = 0;
pPhrase->fmt_bytes = 0; pPhrase->fmt_bytes = 0;
for (unsigned int i=0; i<m_LangCount; i++) for (unsigned int i=0; i<m_LangCount; i++)
{ {
pTrans[i].stridx = -1; pTrans[i].stridx = -1;
} }
m_LastPhraseString.assign(name);
} }
m_LastPhraseString.assign(name);
} }
else if (m_ParseState == PPS_InPhrase) else if (m_ParseState == PPS_InPhrase)
{ {
@@ -273,12 +231,15 @@ SMCResult CPhraseFile::ReadSMC_KeyValue(const SMCStates *states, const char *key
} }
phrase_t *pPhrase = (phrase_t *)m_pMemory->GetAddress(m_CurPhrase); phrase_t *pPhrase = (phrase_t *)m_pMemory->GetAddress(m_CurPhrase);
/* Duplicate format keys get silently ignored. */ if (key[0] == '#' && strcmp(key, "#format") == 0)
if (key[0] == '#'
&& strcmp(key, "#format") == 0
&& pPhrase->fmt_list == -1)
{ {
if (pPhrase->fmt_list != -1)
{
ParseWarning("Ignoring duplicated #format property on line %d", states->line);
return SMCResult_Continue;
}
if (pPhrase->translations > 0) if (pPhrase->translations > 0)
{ {
ParseWarning("#format property should come before translations on line %d, ignoring", states->line); ParseWarning("#format property should come before translations on line %d, ignoring", states->line);
@@ -487,7 +448,7 @@ SMCResult CPhraseFile::ReadSMC_KeyValue(const SMCStates *states, const char *key
else else
{ {
size_t len = strlen(key); size_t len = strlen(key);
if (len < 2 || len > 3) if (len != 2)
{ {
ParseWarning("Ignoring translation to invalid language \"%s\" on line %d.", key, states->line); ParseWarning("Ignoring translation to invalid language \"%s\" on line %d.", key, states->line);
return SMCResult_Continue; return SMCResult_Continue;
@@ -702,7 +663,7 @@ const char *CPhraseFile::GetFilename()
** MAIN TRANSLATOR CODE ** ** MAIN TRANSLATOR CODE **
**************************/ **************************/
Translator::Translator() : m_ServerLang(SOURCEMOD_LANGUAGE_ENGLISH) Translator::Translator() : m_ServerLang(LANGUAGE_ENGLISH)
{ {
m_pStringTab = new BaseStringTable(2048); m_pStringTab = new BaseStringTable(2048);
m_pLCodeLookup = sm_trie_create(); m_pLCodeLookup = sm_trie_create();
@@ -766,15 +727,11 @@ void Translator::OnSourceModAllInitialized()
{ {
AddLanguage("en", "English"); AddLanguage("en", "English");
g_pCorePhrases = CreatePhraseCollection(); unsigned int id;
g_pCorePhrases->AddPhraseFile("core.phrases");
g_ShareSys.AddInterface(NULL, this); id = FindOrAddPhraseFile("core.phrases.txt");
} g_pCorePhraseID = id;
g_pCorePhrases = GetFileByIndex(id);
void Translator::OnSourceModShutdown()
{
g_pCorePhrases->Destroy();
} }
bool Translator::GetLanguageByCode(const char *code, unsigned int *index) bool Translator::GetLanguageByCode(const char *code, unsigned int *index)
@@ -885,7 +842,7 @@ void Translator::RebuildLanguageDatabase(const char *lang_header_file)
g_Logger.LogError("Server language was set to bad language \"%s\" -- reverting to English", m_InitialLang); g_Logger.LogError("Server language was set to bad language \"%s\" -- reverting to English", m_InitialLang);
strncopy(m_InitialLang, "en", sizeof(m_InitialLang)); strncopy(m_InitialLang, "en", sizeof(m_InitialLang));
m_ServerLang = SOURCEMOD_LANGUAGE_ENGLISH; m_ServerLang = LANGUAGE_ENGLISH;
} }
m_ServerLang = reinterpret_cast<unsigned int>(serverLang); m_ServerLang = reinterpret_cast<unsigned int>(serverLang);
@@ -936,7 +893,7 @@ SMCResult Translator::ReadSMC_KeyValue(const SMCStates *states, const char *key,
{ {
size_t len = strlen(key); size_t len = strlen(key);
if (len < 2 || len > 3) if (len != 2)
{ {
g_Logger.LogError("[SM] Warning encountered parsing languages.cfg file."); g_Logger.LogError("[SM] Warning encountered parsing languages.cfg file.");
g_Logger.LogError("[SM] Invalid language code \"%s\" is being ignored.", key); g_Logger.LogError("[SM] Invalid language code \"%s\" is being ignored.", key);
@@ -957,7 +914,9 @@ bool Translator::AddLanguage(const char *langcode, const char *description)
Language *pLanguage = new Language; Language *pLanguage = new Language;
unsigned int idx = m_Languages.size(); unsigned int idx = m_Languages.size();
UTIL_Format(pLanguage->m_code2, sizeof(pLanguage->m_code2), "%s", langcode); pLanguage->m_code2[0] = langcode[0];
pLanguage->m_code2[1] = langcode[1];
pLanguage->m_code2[2] = langcode[2];
pLanguage->m_FullName = m_pStringTab->AddString(description); pLanguage->m_FullName = m_pStringTab->AddString(description);
sm_trie_insert(m_pLCodeLookup, langcode, reinterpret_cast<void *>(idx)); sm_trie_insert(m_pLCodeLookup, langcode, reinterpret_cast<void *>(idx));
@@ -977,6 +936,61 @@ CPhraseFile *Translator::GetFileByIndex(unsigned int index)
return m_Files[index]; return m_Files[index];
} }
size_t Translator::Translate(char *buffer, size_t maxlength, void **params, const Translation *pTrans)
{
void *new_params[MAX_TRANSLATE_PARAMS];
/* Rewrite the parameter order */
for (unsigned int i=0; i<pTrans->fmt_count; i++)
{
new_params[i] = params[pTrans->fmt_order[i]];
}
return gnprintf(buffer, maxlength, pTrans->szPhrase, new_params);
}
TransError Translator::CoreTransEx(CPhraseFile *pFile,
int client,
char *buffer,
size_t maxlength,
const char *phrase,
void **params,
size_t *outlen)
{
Translation trans;
TransError err;
/* Using server lang temporarily until client lang stuff is implemented */
if ((err = pFile->GetTranslation(phrase, m_ServerLang, &trans)) != Trans_Okay)
{
return err;
}
size_t len = Translate(buffer, maxlength, params, &trans);
if (outlen)
{
*outlen = len;
}
return Trans_Okay;
}
TransError Translator::CoreTrans(int client,
char *buffer,
size_t maxlength,
const char *phrase,
void **params,
size_t *outlen)
{
if (!g_pCorePhrases)
{
return Trans_BadPhraseFile;
}
return CoreTransEx(g_pCorePhrases, client, buffer, maxlength, phrase, params, outlen);
}
unsigned int Translator::GetServerLanguage() unsigned int Translator::GetServerLanguage()
{ {
return m_ServerLang; return m_ServerLang;
@@ -1007,105 +1021,3 @@ bool Translator::GetLanguageInfo(unsigned int number, const char **code, const c
return true; return true;
} }
const char *Translator::GetInterfaceName()
{
return SMINTERFACE_TRANSLATOR_NAME;
}
unsigned int Translator::GetInterfaceVersion()
{
return SMINTERFACE_TRANSLATOR_VERSION;
}
IPhraseCollection *Translator::CreatePhraseCollection()
{
return new CPhraseCollection();
}
int Translator::SetGlobalTarget(int index)
{
return g_SourceMod.SetGlobalTarget(index);
}
int Translator::GetGlobalTarget() const
{
return g_SourceMod.GetGlobalTarget();
}
bool CoreTranslate(char *buffer,
size_t maxlength,
const char *format,
unsigned int numparams,
size_t *pOutLength,
...)
{
va_list ap;
unsigned int i;
const char *fail_phrase;
void *params[MAX_TRANSLATE_PARAMS];
if (numparams > MAX_TRANSLATE_PARAMS)
{
assert(false);
return false;
}
va_start(ap, pOutLength);
for (i = 0; i < numparams; i++)
{
params[i] = va_arg(ap, void *);
}
va_end(ap);
if (!g_pCorePhrases->FormatString(buffer,
maxlength,
format,
params,
numparams,
pOutLength,
&fail_phrase))
{
if (fail_phrase != NULL)
{
g_Logger.LogError("[SM] Could not find core phrase: %s", fail_phrase);
}
else
{
g_Logger.LogError("[SM] Unknown fatal error while translating a core phrase.");
}
return false;
}
return true;
}
bool Translator::FormatString(char *buffer,
size_t maxlength,
const char *format,
IPhraseCollection *pPhrases,
void **params,
unsigned int numparams,
size_t *pOutLength,
const char **pFailPhrase)
{
unsigned int arg;
arg = 0;
if (!gnprintf(buffer, maxlength, format, pPhrases, params, numparams, arg, pOutLength, pFailPhrase))
{
return false;
}
if (arg != numparams)
{
if (pFailPhrase != NULL)
{
*pFailPhrase = NULL;
}
return false;
}
return true;
}
+38 -40
View File
@@ -2,7 +2,7 @@
* vim: set ts=4 : * vim: set ts=4 :
* ============================================================================= * =============================================================================
* SourceMod * SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
* ============================================================================= * =============================================================================
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under
@@ -38,7 +38,6 @@
#include "sm_globals.h" #include "sm_globals.h"
#include "sm_memtable.h" #include "sm_memtable.h"
#include "ITextParsers.h" #include "ITextParsers.h"
#include <ITranslator.h>
#define MAX_TRANSLATE_PARAMS 32 #define MAX_TRANSLATE_PARAMS 32
#define CORELANG_ENGLISH 0 #define CORELANG_ENGLISH 0
@@ -57,13 +56,29 @@ enum PhraseParseState
struct Language struct Language
{ {
char m_code2[4]; char m_code2[3];
int m_FullName; int m_FullName;
}; };
class CPhraseFile : struct Translation
public ITextListener_SMC, {
public IPhraseFile const char *szPhrase; /**< Translated phrase. */
unsigned int fmt_count; /**< Number of format parameters. */
int *fmt_order; /**< Format phrase order. */
};
#define LANGUAGE_ENGLISH 0
enum TransError
{
Trans_Okay = 0,
Trans_BadLanguage = 1,
Trans_BadPhrase = 2,
Trans_BadPhraseLanguage = 3,
Trans_BadPhraseFile = 4,
};
class CPhraseFile : public ITextListener_SMC
{ {
public: public:
CPhraseFile(Translator *pTranslator, const char *file); CPhraseFile(Translator *pTranslator, const char *file);
@@ -97,8 +112,7 @@ private:
class Translator : class Translator :
public ITextListener_SMC, public ITextListener_SMC,
public SMGlobalClass, public SMGlobalClass
public ITranslator
{ {
public: public:
Translator(); Translator();
@@ -111,7 +125,6 @@ public: // SMGlobalClass
size_t maxlength); size_t maxlength);
void OnSourceModAllInitialized(); void OnSourceModAllInitialized();
void OnSourceModLevelChange(const char *mapName); void OnSourceModLevelChange(const char *mapName);
void OnSourceModShutdown();
public: // ITextListener_SMC public: // ITextListener_SMC
void ReadSMC_ParseStart(); void ReadSMC_ParseStart();
SMCResult ReadSMC_NewSection(const SMCStates *states, const char *name); SMCResult ReadSMC_NewSection(const SMCStates *states, const char *name);
@@ -125,30 +138,23 @@ public:
bool GetLanguageInfo(unsigned int number, const char **code, const char **name); bool GetLanguageInfo(unsigned int number, const char **code, const char **name);
bool GetLanguageByCode(const char *code, unsigned int *index); bool GetLanguageByCode(const char *code, unsigned int *index);
bool GetLanguageByName(const char *name, unsigned int *index); bool GetLanguageByName(const char *name, unsigned int *index);
size_t Translate(char *buffer, size_t maxlength, void **params, const Translation *pTrans);
CPhraseFile *GetFileByIndex(unsigned int index); CPhraseFile *GetFileByIndex(unsigned int index);
public: //ITranslator TransError CoreTransEx(CPhraseFile *pFile,
unsigned int GetServerLanguage(); int client,
unsigned int GetClientLanguage(int client);
const char *GetInterfaceName();
unsigned int GetInterfaceVersion();
IPhraseCollection *CreatePhraseCollection();
int SetGlobalTarget(int index);
int GetGlobalTarget() const;
size_t FormatString(
char *buffer, char *buffer,
size_t maxlength, size_t maxlength,
SourcePawn::IPluginContext *pContext, const char *phrase,
const cell_t *params, void **params,
unsigned int param); size_t *outlen=NULL);
bool FormatString( TransError CoreTrans(int client,
char *buffer, char *buffer,
size_t maxlength, size_t maxlength,
const char *format, const char *phrase,
IPhraseCollection *pPhrases, void **params,
void **params, size_t *outlen=NULL);
unsigned int numparams, unsigned int GetServerLanguage();
size_t *pOutLength, unsigned int GetClientLanguage(int client);
const char **pFailPhrase);
private: private:
bool AddLanguage(const char *langcode, const char *description); bool AddLanguage(const char *langcode, const char *description);
private: private:
@@ -159,18 +165,10 @@ private:
bool m_InLanguageSection; bool m_InLanguageSection;
String m_CustomError; String m_CustomError;
unsigned int m_ServerLang; unsigned int m_ServerLang;
char m_InitialLang[4]; char m_InitialLang[3];
}; };
/* Nice little wrapper to handle error logging and whatnot */ extern CPhraseFile *g_pCorePhrases;
bool CoreTranslate(char *buffer,
size_t maxlength,
const char *format,
unsigned int numparams,
size_t *pOutLength,
...);
extern IPhraseCollection *g_pCorePhrases;
extern unsigned int g_pCorePhraseID; extern unsigned int g_pCorePhraseID;
extern Translator g_Translator; extern Translator g_Translator;
+14 -73
View File
@@ -2,7 +2,7 @@
* vim: set ts=4 : * vim: set ts=4 :
* ============================================================================= * =============================================================================
* SourceMod * SourceMod
* Copyright (C) 2004-2010 AlliedModders LLC. All rights reserved. * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
* ============================================================================= * =============================================================================
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under
@@ -34,11 +34,7 @@
UserMessages g_UserMsgs; UserMessages g_UserMsgs;
#if SOURCE_ENGINE >= SE_LEFT4DEAD
SH_DECL_HOOK3(IVEngineServer, UserMessageBegin, SH_NOATTRIB, 0, bf_write *, IRecipientFilter *, int, const char *);
#else
SH_DECL_HOOK2(IVEngineServer, UserMessageBegin, SH_NOATTRIB, 0, bf_write *, IRecipientFilter *, int); SH_DECL_HOOK2(IVEngineServer, UserMessageBegin, SH_NOATTRIB, 0, bf_write *, IRecipientFilter *, int);
#endif
SH_DECL_HOOK0_void(IVEngineServer, MessageEnd, SH_NOATTRIB, 0); SH_DECL_HOOK0_void(IVEngineServer, MessageEnd, SH_NOATTRIB, 0);
UserMessages::UserMessages() : m_InterceptBuffer(m_pBase, 2500) UserMessages::UserMessages() : m_InterceptBuffer(m_pBase, 2500)
@@ -168,17 +164,9 @@ bf_write *UserMessages::StartMessage(int msg_id, const cell_t players[], unsigne
if (m_CurFlags & USERMSG_BLOCKHOOKS) if (m_CurFlags & USERMSG_BLOCKHOOKS)
{ {
#if SOURCE_ENGINE >= SE_LEFT4DEAD
buffer = ENGINE_CALL(UserMessageBegin)(static_cast<IRecipientFilter *>(&m_CellRecFilter), msg_id, g_SMAPI->GetUserMessage(msg_id));
#else
buffer = ENGINE_CALL(UserMessageBegin)(static_cast<IRecipientFilter *>(&m_CellRecFilter), msg_id); buffer = ENGINE_CALL(UserMessageBegin)(static_cast<IRecipientFilter *>(&m_CellRecFilter), msg_id);
#endif
} else { } else {
#if SOURCE_ENGINE >= SE_LEFT4DEAD
buffer = engine->UserMessageBegin(static_cast<IRecipientFilter *>(&m_CellRecFilter), msg_id, g_SMAPI->GetUserMessage(msg_id));
#else
buffer = engine->UserMessageBegin(static_cast<IRecipientFilter *>(&m_CellRecFilter), msg_id); buffer = engine->UserMessageBegin(static_cast<IRecipientFilter *>(&m_CellRecFilter), msg_id);
#endif
} }
return buffer; return buffer;
@@ -205,31 +193,7 @@ bool UserMessages::EndMessage()
return true; return true;
} }
bool UserMessages::HookUserMessage2(int msg_id,
IUserMessageListener *pListener,
bool intercept)
{
return InternalHook(msg_id, pListener, intercept, true);
}
bool UserMessages::UnhookUserMessage2(int msg_id,
IUserMessageListener *pListener,
bool intercept)
{
return InternalUnhook(msg_id, pListener, intercept, true);
}
bool UserMessages::HookUserMessage(int msg_id, IUserMessageListener *pListener, bool intercept) bool UserMessages::HookUserMessage(int msg_id, IUserMessageListener *pListener, bool intercept)
{
return InternalHook(msg_id, pListener, intercept, false);
}
bool UserMessages::UnhookUserMessage(int msg_id, IUserMessageListener *pListener, bool intercept)
{
return InternalUnhook(msg_id, pListener, intercept, false);
}
bool UserMessages::InternalHook(int msg_id, IUserMessageListener *pListener, bool intercept, bool isNew)
{ {
if (msg_id < 0 || msg_id >= 255) if (msg_id < 0 || msg_id >= 255)
{ {
@@ -248,7 +212,6 @@ bool UserMessages::InternalHook(int msg_id, IUserMessageListener *pListener, boo
pInfo->Callback = pListener; pInfo->Callback = pListener;
pInfo->IsHooked = false; pInfo->IsHooked = false;
pInfo->KillMe = false; pInfo->KillMe = false;
pInfo->IsNew = isNew;
if (!m_HookCount++) if (!m_HookCount++)
{ {
@@ -268,8 +231,8 @@ bool UserMessages::InternalHook(int msg_id, IUserMessageListener *pListener, boo
return true; return true;
} }
bool UserMessages::InternalUnhook(int msg_id, IUserMessageListener *pListener, bool intercept, bool isNew) bool UserMessages::UnhookUserMessage(int msg_id, IUserMessageListener *pListener, bool intercept)
{ {
MsgList *pList; MsgList *pList;
MsgIter iter; MsgIter iter;
ListenerInfo *pInfo; ListenerInfo *pInfo;
@@ -284,7 +247,7 @@ bool UserMessages::InternalUnhook(int msg_id, IUserMessageListener *pListener, b
for (iter=pList->begin(); iter!=pList->end(); iter++) for (iter=pList->begin(); iter!=pList->end(); iter++)
{ {
pInfo = (*iter); pInfo = (*iter);
if (pInfo->Callback == pListener && pInfo->IsNew == isNew) if (pInfo->Callback == pListener)
{ {
if (pInfo->IsHooked) if (pInfo->IsHooked)
{ {
@@ -316,11 +279,7 @@ void UserMessages::_DecRefCounter()
} }
} }
#if SOURCE_ENGINE >= SE_LEFT4DEAD
bf_write *UserMessages::OnStartMessage_Pre(IRecipientFilter *filter, int msg_type, const char *msg_name)
#else
bf_write *UserMessages::OnStartMessage_Pre(IRecipientFilter *filter, int msg_type) bf_write *UserMessages::OnStartMessage_Pre(IRecipientFilter *filter, int msg_type)
#endif
{ {
bool is_intercept_empty = m_msgIntercepts[msg_type].empty(); bool is_intercept_empty = m_msgIntercepts[msg_type].empty();
bool is_hook_empty = m_msgHooks[msg_type].empty(); bool is_hook_empty = m_msgHooks[msg_type].empty();
@@ -346,11 +305,7 @@ bf_write *UserMessages::OnStartMessage_Pre(IRecipientFilter *filter, int msg_typ
RETURN_META_VALUE(MRES_IGNORED, NULL); RETURN_META_VALUE(MRES_IGNORED, NULL);
} }
#if SOURCE_ENGINE >= SE_LEFT4DEAD
bf_write *UserMessages::OnStartMessage_Post(IRecipientFilter *filter, int msg_type, const char *msg_name)
#else
bf_write *UserMessages::OnStartMessage_Post(IRecipientFilter *filter, int msg_type) bf_write *UserMessages::OnStartMessage_Post(IRecipientFilter *filter, int msg_type)
#endif
{ {
if (!m_InHook) if (!m_InHook)
{ {
@@ -364,7 +319,7 @@ bf_write *UserMessages::OnStartMessage_Post(IRecipientFilter *filter, int msg_ty
void UserMessages::OnMessageEnd_Post() void UserMessages::OnMessageEnd_Post()
{ {
if (!m_InHook) if (!m_InHook || m_BlockEndPost)
{ {
RETURN_META(MRES_IGNORED); RETURN_META(MRES_IGNORED);
} }
@@ -373,22 +328,12 @@ void UserMessages::OnMessageEnd_Post()
MsgIter iter; MsgIter iter;
ListenerInfo *pInfo; ListenerInfo *pInfo;
m_InHook = false;
pList = &m_msgIntercepts[m_CurId]; pList = &m_msgIntercepts[m_CurId];
for (iter=pList->begin(); iter!=pList->end(); ) for (iter=pList->begin(); iter!=pList->end(); )
{ {
pInfo = (*iter); pInfo = (*iter);
if (m_BlockEndPost && !pInfo->IsNew)
{
continue;
}
pInfo->IsHooked = true; pInfo->IsHooked = true;
pInfo->Callback->OnUserMessageSent(m_CurId); pInfo->Callback->OnUserMessageSent(m_CurId);
if (pInfo->IsNew)
{
pInfo->Callback->OnPostUserMessage(m_CurId, !m_BlockEndPost);
}
if (pInfo->KillMe) if (pInfo->KillMe)
{ {
@@ -402,20 +347,14 @@ void UserMessages::OnMessageEnd_Post()
iter++; iter++;
} }
m_InHook = false;
pList = &m_msgHooks[m_CurId]; pList = &m_msgHooks[m_CurId];
for (iter=pList->begin(); iter!=pList->end(); ) for (iter=pList->begin(); iter!=pList->end(); )
{ {
pInfo = (*iter); pInfo = (*iter);
if (m_BlockEndPost && !pInfo->IsNew)
{
continue;
}
pInfo->IsHooked = true; pInfo->IsHooked = true;
pInfo->Callback->OnUserMessageSent(m_CurId); pInfo->Callback->OnUserMessageSent(m_CurId);
if (pInfo->IsNew)
{
pInfo->Callback->OnPostUserMessage(m_CurId, !m_BlockEndPost);
}
if (pInfo->KillMe) if (pInfo->KillMe)
{ {
@@ -496,15 +435,16 @@ void UserMessages::OnMessageEnd_Pre()
iter++; iter++;
} }
if (!handled && intercepted) if (handled)
{
goto supercede;
}
if (intercepted)
{ {
bf_write *engine_bfw; bf_write *engine_bfw;
#if SOURCE_ENGINE >= SE_LEFT4DEAD
engine_bfw = ENGINE_CALL(UserMessageBegin)(m_CurRecFilter, m_CurId, g_SMAPI->GetUserMessage(m_CurId));
#else
engine_bfw = ENGINE_CALL(UserMessageBegin)(m_CurRecFilter, m_CurId); engine_bfw = ENGINE_CALL(UserMessageBegin)(m_CurRecFilter, m_CurId);
#endif
m_ReadBuffer.StartReading(m_InterceptBuffer.GetBasePointer(), m_InterceptBuffer.GetNumBytesWritten()); m_ReadBuffer.StartReading(m_InterceptBuffer.GetBasePointer(), m_InterceptBuffer.GetNumBytesWritten());
engine_bfw->WriteBitsFromBuffer(&m_ReadBuffer, m_InterceptBuffer.GetNumBitsWritten()); engine_bfw->WriteBitsFromBuffer(&m_ReadBuffer, m_InterceptBuffer.GetNumBitsWritten());
ENGINE_CALL(MessageEnd)(); ENGINE_CALL(MessageEnd)();
@@ -531,6 +471,7 @@ void UserMessages::OnMessageEnd_Pre()
RETURN_META((intercepted) ? MRES_SUPERCEDE : MRES_IGNORED); RETURN_META((intercepted) ? MRES_SUPERCEDE : MRES_IGNORED);
supercede: supercede:
m_InHook = false;
m_BlockEndPost = true; m_BlockEndPost = true;
RETURN_META(MRES_SUPERCEDE); RETURN_META(MRES_SUPERCEDE);
} }
+1 -15
View File
@@ -2,7 +2,7 @@
* vim: set ts=4 : * vim: set ts=4 :
* ============================================================================= * =============================================================================
* SourceMod * SourceMod
* Copyright (C) 2004-2010 AlliedModders LLC. All rights reserved. * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
* ============================================================================= * =============================================================================
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under
@@ -48,7 +48,6 @@ struct ListenerInfo
IUserMessageListener *Callback; IUserMessageListener *Callback;
bool IsHooked; bool IsHooked;
bool KillMe; bool KillMe;
bool IsNew;
}; };
typedef List<ListenerInfo *> MsgList; typedef List<ListenerInfo *> MsgList;
@@ -72,25 +71,12 @@ public: //IUserMessages
bool UnhookUserMessage(int msg_id, IUserMessageListener *pListener, bool intercept=false); bool UnhookUserMessage(int msg_id, IUserMessageListener *pListener, bool intercept=false);
bf_write *StartMessage(int msg_id, const cell_t players[], unsigned int playersNum, int flags); bf_write *StartMessage(int msg_id, const cell_t players[], unsigned int playersNum, int flags);
bool EndMessage(); bool EndMessage();
bool HookUserMessage2(int msg_id,
IUserMessageListener *pListener,
bool intercept=false);
bool UnhookUserMessage2(int msg_id,
IUserMessageListener *pListener,
bool intercept=false);
public: public:
#if SOURCE_ENGINE >= SE_LEFT4DEAD
bf_write *OnStartMessage_Pre(IRecipientFilter *filter, int msg_type, const char *msg_name);
bf_write *OnStartMessage_Post(IRecipientFilter *filter, int msg_type, const char *msg_name);
#else
bf_write *OnStartMessage_Pre(IRecipientFilter *filter, int msg_type); bf_write *OnStartMessage_Pre(IRecipientFilter *filter, int msg_type);
bf_write *OnStartMessage_Post(IRecipientFilter *filter, int msg_type); bf_write *OnStartMessage_Post(IRecipientFilter *filter, int msg_type);
#endif
void OnMessageEnd_Pre(); void OnMessageEnd_Pre();
void OnMessageEnd_Post(); void OnMessageEnd_Post();
private: private:
bool InternalHook(int msg_id, IUserMessageListener *pListener, bool intercept, bool isNew);
bool InternalUnhook(int msg_id, IUserMessageListener *pListener, bool intercept, bool isNew);
void _DecRefCounter(); void _DecRefCounter();
private: private:
List<ListenerInfo *> m_msgHooks[255]; List<ListenerInfo *> m_msgHooks[255];
+21 -35
View File
@@ -2,7 +2,7 @@
* vim: set ts=4 : * vim: set ts=4 :
* ============================================================================= * =============================================================================
* SourceMod * SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
* ============================================================================= * =============================================================================
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under
@@ -35,13 +35,9 @@
#include "concmd_cleaner.h" #include "concmd_cleaner.h"
#include "sm_stringutil.h" #include "sm_stringutil.h"
#include "sourcemm_api.h" #include "sourcemm_api.h"
#include "compat_wrappers.h"
#if SOURCE_ENGINE >= SE_ORANGEBOX #if defined ORANGEBOX_BUILD
SH_DECL_HOOK1_void(ICvar, UnregisterConCommand, SH_NOATTRIB, 0, ConCommandBase *); SH_DECL_HOOK1_void(ICvar, UnregisterConCommand, SH_NOATTRIB, 0, ConCommandBase *);
SH_DECL_HOOK1_void(ICvar, RegisterConCommand, SH_NOATTRIB, 0, ConCommandBase *);
#else
SH_DECL_HOOK1_void(ICvar, RegisterConCommandBase, SH_NOATTRIB, 0, ConCommandBase *);
#endif #endif
using namespace SourceHook; using namespace SourceHook;
@@ -54,55 +50,29 @@ struct ConCommandInfo
}; };
List<ConCommandInfo *> tracked_bases; List<ConCommandInfo *> tracked_bases;
IConCommandLinkListener *IConCommandLinkListener::head = NULL;
ConCommandBase *FindConCommandBase(const char *name); ConCommandBase *FindConCommandBase(const char *name);
class ConCommandCleaner : public SMGlobalClass class ConCommandCleaner : public SMGlobalClass
{ {
public: public:
#if defined ORANGEBOX_BUILD
void OnSourceModAllInitialized() void OnSourceModAllInitialized()
{ {
#if SOURCE_ENGINE >= SE_ORANGEBOX
SH_ADD_HOOK_MEMFUNC(ICvar, UnregisterConCommand, icvar, this, &ConCommandCleaner::UnlinkConCommandBase, false); SH_ADD_HOOK_MEMFUNC(ICvar, UnregisterConCommand, icvar, this, &ConCommandCleaner::UnlinkConCommandBase, false);
SH_ADD_HOOK_MEMFUNC(ICvar, RegisterConCommand, icvar, this, &ConCommandCleaner::LinkConCommandBase, false);
#else
SH_ADD_HOOK_MEMFUNC(ICvar, RegisterConCommandBase, icvar, this, &ConCommandCleaner::LinkConCommandBase, false);
#endif
} }
void OnSourceModShutdown() void OnSourceModShutdown()
{ {
#if SOURCE_ENGINE >= SE_ORANGEBOX
SH_REMOVE_HOOK_MEMFUNC(ICvar, UnregisterConCommand, icvar, this, &ConCommandCleaner::UnlinkConCommandBase, false); SH_REMOVE_HOOK_MEMFUNC(ICvar, UnregisterConCommand, icvar, this, &ConCommandCleaner::UnlinkConCommandBase, false);
SH_REMOVE_HOOK_MEMFUNC(ICvar, RegisterConCommand, icvar, this, &ConCommandCleaner::LinkConCommandBase, false); }
#else
SH_REMOVE_HOOK_MEMFUNC(ICvar, RegisterConCommandBase, icvar, this, &ConCommandCleaner::LinkConCommandBase, false);
#endif #endif
}
void LinkConCommandBase(ConCommandBase *pBase)
{
IConCommandLinkListener *listener = IConCommandLinkListener::head;
while (listener)
{
listener->OnLinkConCommand(pBase);
listener = listener->next;
}
}
void UnlinkConCommandBase(ConCommandBase *pBase) void UnlinkConCommandBase(ConCommandBase *pBase)
{ {
ConCommandInfo *pInfo; ConCommandInfo *pInfo;
List<ConCommandInfo *>::iterator iter = tracked_bases.begin(); List<ConCommandInfo *>::iterator iter = tracked_bases.begin();
IConCommandLinkListener *listener = IConCommandLinkListener::head;
while (listener)
{
listener->OnUnlinkConCommand(pBase);
listener = listener->next;
}
if (pBase) if (pBase)
{ {
while (iter != tracked_bases.end()) while (iter != tracked_bases.end())
@@ -125,7 +95,7 @@ public:
while (iter != tracked_bases.end()) while (iter != tracked_bases.end())
{ {
/* This is just god-awful! */ /* This is just god-awful! */
if (FindCommandBase((*iter)->name) != (*iter)->pBase) if (FindConCommandBase((*iter)->name) != (*iter)->pBase)
{ {
pInfo = (*iter); pInfo = (*iter);
iter = tracked_bases.erase(iter); iter = tracked_bases.erase(iter);
@@ -173,6 +143,22 @@ public:
} }
} s_ConCmdTracker; } s_ConCmdTracker;
ConCommandBase *FindConCommandBase(const char *name)
{
const ConCommandBase *pBase = icvar->GetCommands();
while (pBase != NULL)
{
if (strcmp(pBase->GetName(), name) == 0)
{
return const_cast<ConCommandBase *>(pBase);
}
pBase = pBase->GetNext();
}
return NULL;
}
void TrackConCommandBase(ConCommandBase *pBase, IConCommandTracker *me) void TrackConCommandBase(ConCommandBase *pBase, IConCommandTracker *me)
{ {
s_ConCmdTracker.AddTarget(pBase, me); s_ConCmdTracker.AddTarget(pBase, me);
+2 -23
View File
@@ -2,7 +2,7 @@
* vim: set ts=4 : * vim: set ts=4 :
* ============================================================================= * =============================================================================
* SourceMod * SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
* ============================================================================= * =============================================================================
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under
@@ -38,30 +38,9 @@ public:
virtual void OnUnlinkConCommandBase(ConCommandBase *pBase, const char *name, bool is_read_safe) = 0; virtual void OnUnlinkConCommandBase(ConCommandBase *pBase, const char *name, bool is_read_safe) = 0;
}; };
ConCommandBase *FindConCommandBase(const char *name);
void TrackConCommandBase(ConCommandBase *pBase, IConCommandTracker *me); void TrackConCommandBase(ConCommandBase *pBase, IConCommandTracker *me);
void UntrackConCommandBase(ConCommandBase *pBase, IConCommandTracker *me); void UntrackConCommandBase(ConCommandBase *pBase, IConCommandTracker *me);
void Global_OnUnlinkConCommandBase(ConCommandBase *pBase); void Global_OnUnlinkConCommandBase(ConCommandBase *pBase);
class IConCommandLinkListener
{
friend class ConCommandCleaner;
static IConCommandLinkListener *head;
IConCommandLinkListener *next;
public:
IConCommandLinkListener()
{
next = head;
head = this;
}
virtual void OnLinkConCommand(ConCommandBase *pBase)
{
}
virtual void OnUnlinkConCommand(ConCommandBase *pBase)
{
}
};
#endif //_INCLUDE_CONCMD_TRACKER_H_ #endif //_INCLUDE_CONCMD_TRACKER_H_
-718
View File
@@ -1,718 +0,0 @@
//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
// $Workfile: $
// $Date: $
//
//-----------------------------------------------------------------------------
// $NoKeywords: $
//===========================================================================//
#ifndef CONVAR_H
#define CONVAR_H
#if _WIN32
#pragma once
#endif
#include "tier0/dbg.h"
#include "tier1/iconvar.h"
#include "tier1/utlvector.h"
#include "tier1/utlstring.h"
#include "icvar.h"
#ifdef _WIN32
#define FORCEINLINE_CVAR FORCEINLINE
#elif _LINUX
#define FORCEINLINE_CVAR inline
#else
#error "implement me"
#endif
//-----------------------------------------------------------------------------
// Forward declarations
//-----------------------------------------------------------------------------
class ConVar;
class CCommand;
class ConCommand;
class ConCommandBase;
struct characterset_t;
//-----------------------------------------------------------------------------
// Any executable that wants to use ConVars need to implement one of
// these to hook up access to console variables.
//-----------------------------------------------------------------------------
class IConCommandBaseAccessor
{
public:
// Flags is a combination of FCVAR flags in cvar.h.
// hOut is filled in with a handle to the variable.
virtual bool RegisterConCommandBase( ConCommandBase *pVar ) = 0;
};
//-----------------------------------------------------------------------------
// Helper method for console development
//-----------------------------------------------------------------------------
#if defined( _X360 ) && !defined( _RETAIL )
void ConVar_PublishToVXConsole();
#endif
//-----------------------------------------------------------------------------
// Called when a ConCommand needs to execute
//-----------------------------------------------------------------------------
typedef void ( *FnCommandCallbackV1_t )( void );
typedef void ( *FnCommandCallback_t )( const CCommand &command );
#define COMMAND_COMPLETION_MAXITEMS 64
#define COMMAND_COMPLETION_ITEM_LENGTH 64
//-----------------------------------------------------------------------------
// Returns 0 to COMMAND_COMPLETION_MAXITEMS worth of completion strings
//-----------------------------------------------------------------------------
typedef int ( *FnCommandCompletionCallback )( const char *partial, char commands[ COMMAND_COMPLETION_MAXITEMS ][ COMMAND_COMPLETION_ITEM_LENGTH ] );
//-----------------------------------------------------------------------------
// Interface version
//-----------------------------------------------------------------------------
class ICommandCallback
{
public:
virtual void CommandCallback( const CCommand &command ) = 0;
};
class ICommandCompletionCallback
{
public:
virtual int CommandCompletionCallback( const char *pPartial, CUtlVector< CUtlString > &commands ) = 0;
};
//-----------------------------------------------------------------------------
// Purpose: The base console invoked command/cvar interface
//-----------------------------------------------------------------------------
class ConCommandBase
{
friend class CCvar;
friend class ConVar;
friend class ConCommand;
friend void ConVar_Register( int nCVarFlag, IConCommandBaseAccessor *pAccessor );
friend void ConVar_PublishToVXConsole();
// FIXME: Remove when ConVar changes are done
friend class CDefaultCvar;
public:
ConCommandBase( void );
ConCommandBase( const char *pName, const char *pHelpString = 0,
int flags = 0 );
virtual ~ConCommandBase( void );
virtual bool IsCommand( void ) const;
// Check flag
virtual bool IsFlagSet( int flag ) const;
// Set flag
virtual void AddFlags( int flags );
// Remove flag
virtual void RemoveFlags( int flags );
// Get flags
virtual int GetFlags( void ) const;
// Return name of cvar
virtual const char *GetName( void ) const;
// Return help text for cvar
virtual const char *GetHelpText( void ) const;
// Deal with next pointer
const ConCommandBase *GetNext( void ) const;
ConCommandBase *GetNext( void );
inline void SetNext(ConCommandBase *pBase)
{
m_pNext = pBase;
}
virtual bool IsRegistered( void ) const;
// Returns the DLL identifier
virtual CVarDLLIdentifier_t GetDLLIdentifier() const;
protected:
virtual void Create( const char *pName, const char *pHelpString = 0,
int flags = 0 );
// Used internally by OneTimeInit to initialize/shutdown
virtual void Init();
void Shutdown();
// Internal copy routine ( uses new operator from correct module )
char *CopyString( const char *from );
private:
// Next ConVar in chain
// Prior to register, it points to the next convar in the DLL.
// Once registered, though, m_pNext is reset to point to the next
// convar in the global list
ConCommandBase *m_pNext;
// Has the cvar been added to the global list?
bool m_bRegistered;
// Static data
const char *m_pszName;
const char *m_pszHelpString;
// ConVar flags
int m_nFlags;
protected:
// ConVars add themselves to this list for the executable.
// Then ConVar_Register runs through all the console variables
// and registers them into a global list stored in vstdlib.dll
static ConCommandBase *s_pConCommandBases;
// ConVars in this executable use this 'global' to access values.
static IConCommandBaseAccessor *s_pAccessor;
public:
inline void SetFlags(int flags)
{
m_nFlags = flags;
}
};
//-----------------------------------------------------------------------------
// Command tokenizer
//-----------------------------------------------------------------------------
class CCommand
{
public:
CCommand();
CCommand( int nArgC, const char **ppArgV );
bool Tokenize( const char *pCommand, characterset_t *pBreakSet = NULL );
void Reset();
int ArgC() const;
const char **ArgV() const;
const char *ArgS() const; // All args that occur after the 0th arg, in string form
const char *GetCommandString() const; // The entire command in string form, including the 0th arg
const char *operator[]( int nIndex ) const; // Gets at arguments
const char *Arg( int nIndex ) const; // Gets at arguments
// Helper functions to parse arguments to commands.
const char* FindArg( const char *pName ) const;
int FindArgInt( const char *pName, int nDefaultVal ) const;
static int MaxCommandLength();
static characterset_t* DefaultBreakSet();
private:
enum
{
COMMAND_MAX_ARGC = 64,
COMMAND_MAX_LENGTH = 512,
};
int m_nArgc;
int m_nArgv0Size;
char m_pArgSBuffer[ COMMAND_MAX_LENGTH ];
char m_pArgvBuffer[ COMMAND_MAX_LENGTH ];
const char* m_ppArgv[ COMMAND_MAX_ARGC ];
};
inline int CCommand::MaxCommandLength()
{
return COMMAND_MAX_LENGTH - 1;
}
inline int CCommand::ArgC() const
{
return m_nArgc;
}
inline const char **CCommand::ArgV() const
{
return m_nArgc ? (const char**)m_ppArgv : NULL;
}
inline const char *CCommand::ArgS() const
{
return m_nArgv0Size ? &m_pArgSBuffer[m_nArgv0Size] : "";
}
inline const char *CCommand::GetCommandString() const
{
return m_nArgc ? m_pArgSBuffer : "";
}
inline const char *CCommand::Arg( int nIndex ) const
{
// FIXME: Many command handlers appear to not be particularly careful
// about checking for valid argc range. For now, we're going to
// do the extra check and return an empty string if it's out of range
if ( nIndex < 0 || nIndex >= m_nArgc )
return "";
return m_ppArgv[nIndex];
}
inline const char *CCommand::operator[]( int nIndex ) const
{
return Arg( nIndex );
}
//-----------------------------------------------------------------------------
// Purpose: The console invoked command
//-----------------------------------------------------------------------------
class ConCommand : public ConCommandBase
{
friend class CCvar;
public:
typedef ConCommandBase BaseClass;
ConCommand( const char *pName, FnCommandCallbackV1_t callback,
const char *pHelpString = 0, int flags = 0, FnCommandCompletionCallback completionFunc = 0 );
ConCommand( const char *pName, FnCommandCallback_t callback,
const char *pHelpString = 0, int flags = 0, FnCommandCompletionCallback completionFunc = 0 );
ConCommand( const char *pName, ICommandCallback *pCallback,
const char *pHelpString = 0, int flags = 0, ICommandCompletionCallback *pCommandCompletionCallback = 0 );
virtual ~ConCommand( void );
virtual bool IsCommand( void ) const;
virtual int AutoCompleteSuggest( const char *partial, CUtlVector< CUtlString > &commands );
virtual bool CanAutoComplete( void );
// Invoke the function
virtual void Dispatch( const CCommand &command );
private:
// NOTE: To maintain backward compat, we have to be very careful:
// All public virtual methods must appear in the same order always
// since engine code will be calling into this code, which *does not match*
// in the mod code; it's using slightly different, but compatible versions
// of this class. Also: Be very careful about adding new fields to this class.
// Those fields will not exist in the version of this class that is instanced
// in mod code.
// Call this function when executing the command
union
{
FnCommandCallbackV1_t m_fnCommandCallbackV1;
FnCommandCallback_t m_fnCommandCallback;
ICommandCallback *m_pCommandCallback;
};
union
{
FnCommandCompletionCallback m_fnCompletionCallback;
ICommandCompletionCallback *m_pCommandCompletionCallback;
};
bool m_bHasCompletionCallback : 1;
bool m_bUsingNewCommandCallback : 1;
bool m_bUsingCommandCallbackInterface : 1;
public:
inline FnCommandCallback_t GetCallback() const
{
return m_fnCommandCallback;
}
};
//-----------------------------------------------------------------------------
// Purpose: A console variable
//-----------------------------------------------------------------------------
class ConVar : public ConCommandBase, public IConVar
{
friend class CCvar;
friend class ConVarRef;
public:
typedef ConCommandBase BaseClass;
ConVar( const char *pName, const char *pDefaultValue, int flags = 0);
ConVar( const char *pName, const char *pDefaultValue, int flags,
const char *pHelpString );
ConVar( const char *pName, const char *pDefaultValue, int flags,
const char *pHelpString, bool bMin, float fMin, bool bMax, float fMax );
ConVar( const char *pName, const char *pDefaultValue, int flags,
const char *pHelpString, FnChangeCallback_t callback );
ConVar( const char *pName, const char *pDefaultValue, int flags,
const char *pHelpString, bool bMin, float fMin, bool bMax, float fMax,
FnChangeCallback_t callback );
virtual ~ConVar( void );
virtual bool IsCommand( void ) const;
virtual bool IsFlagSet( int flag ) const;
virtual void AddFlags( int flags );
virtual int GetFlags( void ) const;
virtual const char *GetName( void ) const;
virtual const char* GetHelpText( void ) const;
virtual bool IsRegistered( void ) const;
// Install a change callback (there shouldn't already be one....)
void InstallChangeCallback( FnChangeCallback_t callback );
// Retrieve value
FORCEINLINE_CVAR float GetFloat( void ) const;
FORCEINLINE_CVAR int GetInt( void ) const;
FORCEINLINE_CVAR bool GetBool() const { return !!GetInt(); }
FORCEINLINE_CVAR char const *GetString( void ) const;
// Used internally by OneTimeInit to initialize.
virtual void Init();
virtual const char *GetBaseName( void ) const;
virtual int GetSplitScreenPlayerSlot ( void ) const;
// Any function that allocates/frees memory needs to be virtual or else you'll have crashes
// from alloc/free across dll/exe boundaries.
// These just call into the IConCommandBaseAccessor to check flags and set the var (which ends up calling InternalSetValue).
virtual void SetValue( const char *value );
virtual void SetValue( float value );
virtual void SetValue( int value );
#if SOURCE_ENGINE >= SE_LEFT4DEAD2
virtual void SetValue( Color value );
#endif
// Reset to default value
void Revert( void );
// True if it has a min/max setting
bool GetMin( float& minVal ) const;
bool GetMax( float& maxVal ) const;
const char *GetDefault( void ) const;
private:
// Called by CCvar when the value of a var is changing.
virtual void InternalSetValue(const char *value);
// For CVARs marked FCVAR_NEVER_AS_STRING
virtual void InternalSetFloatValue( float fNewValue );
virtual void InternalSetIntValue( int nValue );
#if SOURCE_ENGINE >= SE_LEFT4DEAD2
virtual void InternalSetColorValue( Color value );
#endif
virtual bool ClampValue( float& value );
virtual void ChangeStringValue( const char *tempVal, float flOldValue );
virtual void Create( const char *pName, const char *pDefaultValue, int flags = 0,
const char *pHelpString = 0, bool bMin = false, float fMin = 0.0,
bool bMax = false, float fMax = false, FnChangeCallback_t callback = 0 );
private:
// This either points to "this" or it points to the original declaration of a ConVar.
// This allows ConVars to exist in separate modules, and they all use the first one to be declared.
// m_pParent->m_pParent must equal m_pParent (ie: m_pParent must be the root, or original, ConVar).
ConVar *m_pParent;
// Static data
const char *m_pszDefaultValue;
// Value
// Dynamically allocated
char *m_pszString;
int m_StringLength;
// Values
float m_fValue;
int m_nValue;
// Min/Max values
bool m_bHasMin;
float m_fMinVal;
bool m_bHasMax;
float m_fMaxVal;
// Call this function when ConVar changes
FnChangeCallback_t m_fnChangeCallback;
public:
inline FnChangeCallback_t GetCallback() const
{
return m_fnChangeCallback;
}
inline void SetMin(bool set, float min=0.0)
{
m_bHasMin = set;
m_fMinVal = min;
}
inline void SetMax(bool set, float max=0.0)
{
m_bHasMax = set;
m_fMaxVal = max;
}
};
//-----------------------------------------------------------------------------
// Purpose: Return ConVar value as a float
// Output : float
//-----------------------------------------------------------------------------
FORCEINLINE_CVAR float ConVar::GetFloat( void ) const
{
return m_pParent->m_fValue;
}
//-----------------------------------------------------------------------------
// Purpose: Return ConVar value as an int
// Output : int
//-----------------------------------------------------------------------------
FORCEINLINE_CVAR int ConVar::GetInt( void ) const
{
return m_pParent->m_nValue;
}
//-----------------------------------------------------------------------------
// Purpose: Return ConVar value as a string, return "" for bogus string pointer, etc.
// Output : const char *
//-----------------------------------------------------------------------------
FORCEINLINE_CVAR const char *ConVar::GetString( void ) const
{
if ( m_nFlags & FCVAR_NEVER_AS_STRING )
return "FCVAR_NEVER_AS_STRING";
return ( m_pParent->m_pszString ) ? m_pParent->m_pszString : "";
}
//-----------------------------------------------------------------------------
// Used to read/write convars that already exist (replaces the FindVar method)
//-----------------------------------------------------------------------------
class ConVarRef
{
public:
ConVarRef( const char *pName );
ConVarRef( const char *pName, bool bIgnoreMissing );
ConVarRef( IConVar *pConVar );
void Init( const char *pName, bool bIgnoreMissing );
bool IsValid() const;
bool IsFlagSet( int nFlags ) const;
IConVar *GetLinkedConVar();
// Get/Set value
float GetFloat( void ) const;
int GetInt( void ) const;
bool GetBool() const { return !!GetInt(); }
const char *GetString( void ) const;
void SetValue( const char *pValue );
void SetValue( float flValue );
void SetValue( int nValue );
void SetValue( bool bValue );
const char *GetName() const;
const char *GetDefault() const;
private:
// High-speed method to read convar data
IConVar *m_pConVar;
ConVar *m_pConVarState;
};
//-----------------------------------------------------------------------------
// Did we find an existing convar of that name?
//-----------------------------------------------------------------------------
FORCEINLINE_CVAR bool ConVarRef::IsFlagSet( int nFlags ) const
{
return ( m_pConVar->IsFlagSet( nFlags ) != 0 );
}
FORCEINLINE_CVAR IConVar *ConVarRef::GetLinkedConVar()
{
return m_pConVar;
}
FORCEINLINE_CVAR const char *ConVarRef::GetName() const
{
return m_pConVar->GetName();
}
//-----------------------------------------------------------------------------
// Purpose: Return ConVar value as a float
//-----------------------------------------------------------------------------
FORCEINLINE_CVAR float ConVarRef::GetFloat( void ) const
{
return m_pConVarState->m_fValue;
}
//-----------------------------------------------------------------------------
// Purpose: Return ConVar value as an int
//-----------------------------------------------------------------------------
FORCEINLINE_CVAR int ConVarRef::GetInt( void ) const
{
return m_pConVarState->m_nValue;
}
//-----------------------------------------------------------------------------
// Purpose: Return ConVar value as a string, return "" for bogus string pointer, etc.
//-----------------------------------------------------------------------------
FORCEINLINE_CVAR const char *ConVarRef::GetString( void ) const
{
Assert( !IsFlagSet( FCVAR_NEVER_AS_STRING ) );
return m_pConVarState->m_pszString;
}
FORCEINLINE_CVAR void ConVarRef::SetValue( const char *pValue )
{
m_pConVar->SetValue( pValue );
}
FORCEINLINE_CVAR void ConVarRef::SetValue( float flValue )
{
m_pConVar->SetValue( flValue );
}
FORCEINLINE_CVAR void ConVarRef::SetValue( int nValue )
{
m_pConVar->SetValue( nValue );
}
FORCEINLINE_CVAR void ConVarRef::SetValue( bool bValue )
{
m_pConVar->SetValue( bValue ? 1 : 0 );
}
FORCEINLINE_CVAR const char *ConVarRef::GetDefault() const
{
return m_pConVarState->m_pszDefaultValue;
}
//-----------------------------------------------------------------------------
// Called by the framework to register ConCommands with the ICVar
//-----------------------------------------------------------------------------
void ConVar_Register( int nCVarFlag = 0, IConCommandBaseAccessor *pAccessor = NULL );
void ConVar_Unregister( );
//-----------------------------------------------------------------------------
// Utility methods
//-----------------------------------------------------------------------------
void ConVar_PrintFlags( const ConCommandBase *var );
void ConVar_PrintDescription( const ConCommandBase *pVar );
//-----------------------------------------------------------------------------
// Purpose: Utility class to quickly allow ConCommands to call member methods
//-----------------------------------------------------------------------------
#ifdef _MSC_VER
#pragma warning (disable : 4355 )
#endif
template< class T >
class CConCommandMemberAccessor : public ConCommand, public ICommandCallback, public ICommandCompletionCallback
{
typedef ConCommand BaseClass;
typedef void ( T::*FnMemberCommandCallback_t )( const CCommand &command );
typedef int ( T::*FnMemberCommandCompletionCallback_t )( const char *pPartial, CUtlVector< CUtlString > &commands );
public:
CConCommandMemberAccessor( T* pOwner, const char *pName, FnMemberCommandCallback_t callback, const char *pHelpString = 0,
int flags = 0, FnMemberCommandCompletionCallback_t completionFunc = 0 ) :
BaseClass( pName, this, pHelpString, flags, ( completionFunc != 0 ) ? this : NULL )
{
m_pOwner = pOwner;
m_Func = callback;
m_CompletionFunc = completionFunc;
}
~CConCommandMemberAccessor()
{
Shutdown();
}
void SetOwner( T* pOwner )
{
m_pOwner = pOwner;
}
virtual void CommandCallback( const CCommand &command )
{
Assert( m_pOwner && m_Func );
(m_pOwner->*m_Func)( command );
}
virtual int CommandCompletionCallback( const char *pPartial, CUtlVector< CUtlString > &commands )
{
Assert( m_pOwner && m_CompletionFunc );
return (m_pOwner->*m_CompletionFunc)( pPartial, commands );
}
private:
T* m_pOwner;
FnMemberCommandCallback_t m_Func;
FnMemberCommandCompletionCallback_t m_CompletionFunc;
};
#ifdef _MSC_VER
#pragma warning ( default : 4355 )
#endif
//-----------------------------------------------------------------------------
// Purpose: Utility macros to quicky generate a simple console command
//-----------------------------------------------------------------------------
#define CON_COMMAND( name, description ) \
static void name( const CCommand &args ); \
static ConCommand name##_command( #name, name, description ); \
static void name( const CCommand &args )
#define CON_COMMAND_F( name, description, flags ) \
static void name( const CCommand &args ); \
static ConCommand name##_command( #name, name, description, flags ); \
static void name( const CCommand &args )
#define CON_COMMAND_F_COMPLETION( name, description, flags, completion ) \
static void name( const CCommand &args ); \
static ConCommand name##_command( #name, name, description, flags, completion ); \
static void name( const CCommand &args )
#define CON_COMMAND_EXTERN( name, _funcname, description ) \
void _funcname( const CCommand &args ); \
static ConCommand name##_command( #name, _funcname, description ); \
void _funcname( const CCommand &args )
#define CON_COMMAND_EXTERN_F( name, _funcname, description, flags ) \
void _funcname( const CCommand &args ); \
static ConCommand name##_command( #name, _funcname, description, flags ); \
void _funcname( const CCommand &args )
#define CON_COMMAND_MEMBER_F( _thisclass, name, _funcname, description, flags ) \
void _funcname( const CCommand &args ); \
friend class CCommandMemberInitializer_##_funcname; \
class CCommandMemberInitializer_##_funcname \
{ \
public: \
CCommandMemberInitializer_##_funcname() : m_ConCommandAccessor( NULL, name, &_thisclass::_funcname, description, flags ) \
{ \
m_ConCommandAccessor.SetOwner( GET_OUTER( _thisclass, m_##_funcname##_register ) ); \
} \
private: \
CConCommandMemberAccessor< _thisclass > m_ConCommandAccessor; \
}; \
\
CCommandMemberInitializer_##_funcname m_##_funcname##_register; \
#endif // CONVAR_H
File diff suppressed because it is too large Load Diff
+3 -63
View File
@@ -2,7 +2,7 @@
* vim: set ts=4 : * vim: set ts=4 :
* ============================================================================= * =============================================================================
* SourceMod * SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
* ============================================================================= * =============================================================================
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under
@@ -35,75 +35,15 @@
#include "MenuStyle_Valve.h" #include "MenuStyle_Valve.h"
#include "MenuStyle_Radio.h" #include "MenuStyle_Radio.h"
#include "PlayerManager.h" #include "PlayerManager.h"
#include "CoreConfig.h"
#include <sm_queue.h>
#include <IThreader.h>
static IMutex *frame_mutex; float g_LastMenuTime = 0.0f;
static Queue<FrameAction> *frame_queue; float g_LastAuthCheck = 0.0f;
static Queue<FrameAction> *frame_actions;
static float g_LastMenuTime = 0.0f;
static float g_LastAuthCheck = 0.0f;
bool g_PendingInternalPush = false;
class FrameActionInit : public SMGlobalClass
{
public:
void OnSourceModAllInitialized()
{
frame_queue = new Queue<FrameAction>();
frame_actions = new Queue<FrameAction>();
frame_mutex = g_pThreader->MakeMutex();
}
void OnSourceModShutdown()
{
delete frame_queue;
delete frame_actions;
frame_mutex->DestroyThis();
}
} s_FrameActionInit;
void AddFrameAction(const FrameAction & action)
{
frame_mutex->Lock();
frame_queue->push(action);
frame_mutex->Unlock();
}
void RunFrameHooks(bool simulating) void RunFrameHooks(bool simulating)
{ {
/* It's okay if this check races. */
if (frame_queue->size())
{
Queue<FrameAction> *temp;
/* Very quick lock to move queue/actions back and forth */
frame_mutex->Lock();
temp = frame_queue;
frame_queue = frame_actions;
frame_actions = temp;
frame_mutex->Unlock();
/* The server will now be adding to the other queue, so we can process events. */
while (!frame_actions->empty())
{
FrameAction &item = frame_actions->first();
frame_actions->pop();
item.action(item.data);
}
}
/* Frame based hooks */ /* Frame based hooks */
g_DBMan.RunFrame(); g_DBMan.RunFrame();
g_HL2.ProcessFakeCliCmdQueue(); g_HL2.ProcessFakeCliCmdQueue();
g_HL2.ProcessDelayedKicks();
if (g_PendingInternalPush)
{
SM_InternalCmdTrigger();
}
g_SourceMod.ProcessGameFrameHooks(simulating); g_SourceMod.ProcessGameFrameHooks(simulating);
float curtime = *g_pUniversalTime; float curtime = *g_pUniversalTime;
+1 -17
View File
@@ -2,7 +2,7 @@
* vim: set ts=4 : * vim: set ts=4 :
* ============================================================================= * =============================================================================
* SourceMod * SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
* ============================================================================= * =============================================================================
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under
@@ -32,22 +32,6 @@
#ifndef _INCLUDE_SOURCEMOD_FRAME_HOOKS_H_ #ifndef _INCLUDE_SOURCEMOD_FRAME_HOOKS_H_
#define _INCLUDE_SOURCEMOD_FRAME_HOOKS_H_ #define _INCLUDE_SOURCEMOD_FRAME_HOOKS_H_
#include <ISourceMod.h>
using namespace SourceMod;
struct FrameAction
{
FrameAction(FRAMEACTION a, void *d) : data(d), action(a)
{
}
void *data;
FRAMEACTION action;
};
extern bool g_PendingInternalPush;
void AddFrameAction(const FrameAction & action);
void RunFrameHooks(bool simulating); void RunFrameHooks(bool simulating);
#endif //_INCLUDE_SOURCEMOD_FRAME_HOOKS_H_ #endif //_INCLUDE_SOURCEMOD_FRAME_HOOKS_H_
-41
View File
@@ -1,41 +0,0 @@
# vim: set ts=2 sw=2 tw=99 noet ft=python:
import os
compiler = SM.DefaultCompiler()
base = AMBuild.sourceFolder
compiler['CXXINCLUDES'].append(os.path.join(SM.mmsPath, 'core', 'sourcehook'))
compiler['CXXINCLUDES'].append(os.path.join(base, 'core', 'logic'))
compiler['CXXINCLUDES'].append(os.path.join(base, 'public'))
compiler['CXXINCLUDES'].append(os.path.join(base, 'public', 'sourcepawn'))
compiler['CDEFINES'].append('SM_DEFAULT_THREADER')
compiler['CDEFINES'].append('SM_LOGIC')
if AMBuild.target['platform'] == 'linux':
compiler['POSTLINKFLAGS'].append('-lpthread')
extension = AMBuild.AddJob('sourcemod.logic')
binary = Cpp.LibraryBuilder('sourcemod.logic', AMBuild, extension, compiler)
files = [
'common_logic.cpp',
'smn_adt_array.cpp',
'smn_sorting.cpp',
'smn_maplists.cpp',
'smn_adt_stack.cpp',
'thread/ThreadWorker.cpp',
'thread/BaseWorker.cpp',
'ThreadSupport.cpp',
'smn_float.cpp',
'TextParsers.cpp',
'smn_textparse.cpp',
'smn_adt_trie.cpp',
'Profiler.cpp',
'smn_functions.cpp'
]
if AMBuild.target['platform'] == 'windows':
files.append('thread/WinThreads.cpp')
else:
files.append('thread/PosixThreads.cpp')
binary.AddSourceFiles('core/logic', files)
SM.AutoVersion('core/logic', binary)
binary.SendToJob()
-92
View File
@@ -1,92 +0,0 @@
# (C)2004-2008 SourceMod Development Team
# Makefile written by David "BAILOPAN" Anderson
SMSDK = ../..
MMSOURCE17 = ../../../mmsource-1.7
#####################################
### EDIT BELOW FOR OTHER PROJECTS ###
#####################################
BINARY = sourcemod.logic.so
OBJECTS = \
common_logic.cpp \
smn_adt_array.cpp \
smn_sorting.cpp \
smn_maplists.cpp \
smn_adt_stack.cpp \
thread/ThreadWorker.cpp \
thread/BaseWorker.cpp \
thread/PosixThreads.cpp \
ThreadSupport.cpp \
smn_float.cpp \
TextParsers.cpp \
smn_textparse.cpp \
smn_adt_trie.cpp \
Profiler.cpp \
smn_functions.cpp
##############################################
### CONFIGURE ANY OTHER FLAGS/OPTIONS HERE ###
##############################################
C_OPT_FLAGS = -DNDEBUG -O3 -funroll-loops -pipe -fno-strict-aliasing
C_DEBUG_FLAGS = -D_DEBUG -DDEBUG -g -ggdb3
C_GCC4_FLAGS = -fvisibility=hidden
CPP_GCC4_FLAGS = -fvisibility-inlines-hidden
CPP = gcc
LINK += -lpthread -static-libgcc
INCLUDE += -I. -I$(MMSOURCE17)/core/sourcehook -I$(SMSDK)/public -I$(SMSDK)/public/sourcepawn
CFLAGS += -D_LINUX -Dstricmp=strcasecmp -D_stricmp=strcasecmp -D_strnicmp=strncasecmp -Dstrnicmp=strncasecmp \
-D_snprintf=snprintf -D_vsnprintf=vsnprintf -D_alloca=alloca -Dstrcmpi=strcasecmp -Wall -Werror \
-Wno-uninitialized -mfpmath=sse -msse -DSOURCEMOD_BUILD -DHAVE_STDINT_H -DSM_DEFAULT_THREADER -m32 \
-DSM_LOGIC
CPPFLAGS += -Wno-non-virtual-dtor -fno-exceptions -fno-rtti
################################################
### DO NOT EDIT BELOW HERE FOR MOST PROJECTS ###
################################################
ifeq "$(DEBUG)" "true"
BIN_DIR = Debug
CFLAGS += $(C_DEBUG_FLAGS)
else
BIN_DIR = Release
CFLAGS += $(C_OPT_FLAGS)
endif
GCC_VERSION := $(shell $(CPP) -dumpversion >&1 | cut -b1)
ifeq "$(GCC_VERSION)" "4"
CFLAGS += $(C_GCC4_FLAGS)
CPPFLAGS += $(CPP_GCC4_FLAGS)
endif
OBJ_LINUX := $(OBJECTS:%.cpp=$(BIN_DIR)/%.o)
OBJ_LINUX := $(OBJ_LINUX:%.c=$(BIN_DIR)/%.o)
$(BIN_DIR)/%.o: %.cpp
$(CPP) $(INCLUDE) $(CFLAGS) $(CPPFLAGS) -o $@ -c $<
$(BIN_DIR)/%.o: %.c
$(CPP) $(INCLUDE) $(CFLAGS) -o $@ -c $<
all:
mkdir -p $(BIN_DIR)/thread
$(MAKE) -f Makefile sourcemod
sourcemod: $(OBJ_LINUX)
$(CPP) $(INCLUDE) $(OBJ_LINUX) $(LINK) -m32 -shared -ldl -lm -o $(BIN_DIR)/$(BINARY)
debug:
$(MAKE) -f Makefile all DEBUG=true
default: all
clean:
rm -rf $(BIN_DIR)/*.o
rm -rf $(BIN_DIR)/thread/*.o
rm -rf $(BIN_DIR)/$(BINARY)
-399
View File
@@ -1,399 +0,0 @@
// MersenneTwister.h
// Mersenne Twister random number generator -- a C++ class MTRand
// Based on code by Makoto Matsumoto, Takuji Nishimura, and Shawn Cokus
// Richard J. Wagner v1.0 15 May 2003 [email protected]
// The Mersenne Twister is an algorithm for generating random numbers. It
// was designed with consideration of the flaws in various other generators.
// The period, 2^19937-1, and the order of equidistribution, 623 dimensions,
// are far greater. The generator is also fast; it avoids multiplication and
// division, and it benefits from caches and pipelines. For more information
// see the inventors' web page at http://www.math.keio.ac.jp/~matumoto/emt.html
// Reference
// M. Matsumoto and T. Nishimura, "Mersenne Twister: A 623-Dimensionally
// Equidistributed Uniform Pseudo-Random Number Generator", ACM Transactions on
// Modeling and Computer Simulation, Vol. 8, No. 1, January 1998, pp 3-30.
// Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
// Copyright (C) 2000 - 2003, Richard J. Wagner
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. The names of its contributors may not be used to endorse or promote
// products derived from this software without specific prior written
// permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// The original code included the following notice:
//
// When you use this, send an email to: [email protected]
// with an appropriate reference to your work.
//
// It would be nice to CC: [email protected] and [email protected]
// when you write.
#ifndef MERSENNETWISTER_H
#define MERSENNETWISTER_H
// Not thread safe (unless auto-initialization is avoided and each thread has
// its own MTRand object)
#include <limits.h>
#include <stdio.h>
#include <time.h>
#include <math.h>
class MTRand {
// Data
public:
typedef unsigned long uint32; // unsigned integer type, at least 32 bits
enum { N = 624 }; // length of state vector
enum { SAVE = N + 1 }; // length of array for save()
protected:
enum { M = 397 }; // period parameter
uint32 state[N]; // internal state
uint32 *pNext; // next value to get from state
int left; // number of values left before reload needed
//Methods
public:
MTRand( const uint32& oneSeed ); // initialize with a simple uint32
MTRand( uint32 *const bigSeed, uint32 const seedLength = N ); // or an array
MTRand(); // auto-initialize with /dev/urandom or time() and clock()
// Do NOT use for CRYPTOGRAPHY without securely hashing several returned
// values together, otherwise the generator state can be learned after
// reading 624 consecutive values.
// Access to 32-bit random numbers
double rand(); // real number in [0,1]
double rand( const double& n ); // real number in [0,n]
double randExc(); // real number in [0,1)
double randExc( const double& n ); // real number in [0,n)
double randDblExc(); // real number in (0,1)
double randDblExc( const double& n ); // real number in (0,n)
uint32 randInt(); // integer in [0,2^32-1]
uint32 randInt( const uint32& n ); // integer in [0,n] for n < 2^32
double operator()() { return rand(); } // same as rand()
// Access to 53-bit random numbers (capacity of IEEE double precision)
double rand53(); // real number in [0,1)
// Access to nonuniform random number distributions
double randNorm( const double& mean = 0.0, const double& variance = 0.0 );
// Re-seeding functions with same behavior as initializers
void seed( const uint32 oneSeed );
void seed( uint32 *const bigSeed, const uint32 seedLength = N );
void seed();
// Saving and loading generator state
void save( uint32* saveArray ) const; // to array of size SAVE
void load( uint32 *const loadArray ); // from such array
protected:
void initialize( const uint32 oneSeed );
void reload();
uint32 hiBit( const uint32& u ) const { return u & 0x80000000UL; }
uint32 loBit( const uint32& u ) const { return u & 0x00000001UL; }
uint32 loBits( const uint32& u ) const { return u & 0x7fffffffUL; }
uint32 mixBits( const uint32& u, const uint32& v ) const
{ return hiBit(u) | loBits(v); }
uint32 twist( const uint32& m, const uint32& s0, const uint32& s1 ) const
{ return m ^ (mixBits(s0,s1)>>1) ^ (-loBit(s1) & 0x9908b0dfUL); }
static uint32 hash( time_t t, clock_t c );
};
inline MTRand::MTRand( const uint32& oneSeed )
{ seed(oneSeed); }
inline MTRand::MTRand( uint32 *const bigSeed, const uint32 seedLength )
{ seed(bigSeed,seedLength); }
inline MTRand::MTRand()
{ seed(); }
inline double MTRand::rand()
{ return double(randInt()) * (1.0/4294967295.0); }
inline double MTRand::rand( const double& n )
{ return rand() * n; }
inline double MTRand::randExc()
{ return double(randInt()) * (1.0/4294967296.0); }
inline double MTRand::randExc( const double& n )
{ return randExc() * n; }
inline double MTRand::randDblExc()
{ return ( double(randInt()) + 0.5 ) * (1.0/4294967296.0); }
inline double MTRand::randDblExc( const double& n )
{ return randDblExc() * n; }
inline double MTRand::rand53()
{
uint32 a = randInt() >> 5, b = randInt() >> 6;
return ( a * 67108864.0 + b ) * (1.0/9007199254740992.0); // by Isaku Wada
}
inline double MTRand::randNorm( const double& mean, const double& variance )
{
// Return a real number from a normal (Gaussian) distribution with given
// mean and variance by Box-Muller method
double r = sqrt( -2.0 * log( 1.0-randDblExc()) ) * variance;
double phi = 2.0 * 3.14159265358979323846264338328 * randExc();
return mean + r * cos(phi);
}
inline MTRand::uint32 MTRand::randInt()
{
// Pull a 32-bit integer from the generator state
// Every other access function simply transforms the numbers extracted here
if( left == 0 ) reload();
--left;
register uint32 s1;
s1 = *pNext++;
s1 ^= (s1 >> 11);
s1 ^= (s1 << 7) & 0x9d2c5680UL;
s1 ^= (s1 << 15) & 0xefc60000UL;
return ( s1 ^ (s1 >> 18) );
}
inline MTRand::uint32 MTRand::randInt( const uint32& n )
{
// Find which bits are used in n
// Optimized by Magnus Jonsson ([email protected])
uint32 used = n;
used |= used >> 1;
used |= used >> 2;
used |= used >> 4;
used |= used >> 8;
used |= used >> 16;
// Draw numbers until one is found in [0,n]
uint32 i;
do
i = randInt() & used; // toss unused bits to shorten search
while( i > n );
return i;
}
inline void MTRand::seed( const uint32 oneSeed )
{
// Seed the generator with a simple uint32
initialize(oneSeed);
reload();
}
inline void MTRand::seed( uint32 *const bigSeed, const uint32 seedLength )
{
// Seed the generator with an array of uint32's
// There are 2^19937-1 possible initial states. This function allows
// all of those to be accessed by providing at least 19937 bits (with a
// default seed length of N = 624 uint32's). Any bits above the lower 32
// in each element are discarded.
// Just call seed() if you want to get array from /dev/urandom
initialize(19650218UL);
register int i = 1;
register uint32 j = 0;
register int k = ( N > seedLength ? N : seedLength );
for( ; k; --k )
{
state[i] =
state[i] ^ ( (state[i-1] ^ (state[i-1] >> 30)) * 1664525UL );
state[i] += ( bigSeed[j] & 0xffffffffUL ) + j;
state[i] &= 0xffffffffUL;
++i; ++j;
if( i >= N ) { state[0] = state[N-1]; i = 1; }
if( j >= seedLength ) j = 0;
}
for( k = N - 1; k; --k )
{
state[i] =
state[i] ^ ( (state[i-1] ^ (state[i-1] >> 30)) * 1566083941UL );
state[i] -= i;
state[i] &= 0xffffffffUL;
++i;
if( i >= N ) { state[0] = state[N-1]; i = 1; }
}
state[0] = 0x80000000UL; // MSB is 1, assuring non-zero initial array
reload();
}
inline void MTRand::seed()
{
// Seed the generator with an array from /dev/urandom if available
// Otherwise use a hash of time() and clock() values
// First try getting an array from /dev/urandom
FILE* urandom = fopen( "/dev/urandom", "rb" );
if( urandom )
{
uint32 bigSeed[N];
register uint32 *s = bigSeed;
register int i = N;
register bool success = true;
while( success && i-- )
success = fread( s++, sizeof(uint32), 1, urandom );
fclose(urandom);
if( success ) { seed( bigSeed, N ); return; }
}
// Was not successful, so use time() and clock() instead
seed( hash( time(NULL), clock() ) );
}
inline void MTRand::initialize( const uint32 seed )
{
// Initialize generator state with seed
// See Knuth TAOCP Vol 2, 3rd Ed, p.106 for multiplier.
// In previous versions, most significant bits (MSBs) of the seed affect
// only MSBs of the state array. Modified 9 Jan 2002 by Makoto Matsumoto.
register uint32 *s = state;
register uint32 *r = state;
register int i = 1;
*s++ = seed & 0xffffffffUL;
for( ; i < N; ++i )
{
*s++ = ( 1812433253UL * ( *r ^ (*r >> 30) ) + i ) & 0xffffffffUL;
r++;
}
}
inline void MTRand::reload()
{
// Generate N new values in state
// Made clearer and faster by Matthew Bellew ([email protected])
register uint32 *p = state;
register int i;
for( i = N - M; i--; ++p )
*p = twist( p[M], p[0], p[1] );
for( i = M; --i; ++p )
*p = twist( p[M-N], p[0], p[1] );
*p = twist( p[M-N], p[0], state[0] );
left = N, pNext = state;
}
inline MTRand::uint32 MTRand::hash( time_t t, clock_t c )
{
// Get a uint32 from t and c
// Better than uint32(x) in case x is floating point in [0,1]
// Based on code by Lawrence Kirby ([email protected])
static uint32 differ = 0; // guarantee time-based seeds will change
uint32 h1 = 0;
unsigned char *p = (unsigned char *) &t;
for( size_t i = 0; i < sizeof(t); ++i )
{
h1 *= UCHAR_MAX + 2U;
h1 += p[i];
}
uint32 h2 = 0;
p = (unsigned char *) &c;
for( size_t j = 0; j < sizeof(c); ++j )
{
h2 *= UCHAR_MAX + 2U;
h2 += p[j];
}
return ( h1 + differ++ ) ^ h2;
}
inline void MTRand::save( uint32* saveArray ) const
{
register uint32 *sa = saveArray;
register const uint32 *s = state;
register int i = N;
for( ; i--; *sa++ = *s++ ) {}
*sa = left;
}
inline void MTRand::load( uint32 *const loadArray )
{
register uint32 *s = state;
register uint32 *la = loadArray;
register int i = N;
for( ; i--; *s++ = *la++ ) {}
left = *la;
pNext = &state[N-left];
}
#endif // MERSENNETWISTER_H
// Change log:
//
// v0.1 - First release on 15 May 2000
// - Based on code by Makoto Matsumoto, Takuji Nishimura, and Shawn Cokus
// - Translated from C to C++
// - Made completely ANSI compliant
// - Designed convenient interface for initialization, seeding, and
// obtaining numbers in default or user-defined ranges
// - Added automatic seeding from /dev/urandom or time() and clock()
// - Provided functions for saving and loading generator state
//
// v0.2 - Fixed bug which reloaded generator one step too late
//
// v0.3 - Switched to clearer, faster reload() code from Matthew Bellew
//
// v0.4 - Removed trailing newline in saved generator format to be consistent
// with output format of built-in types
//
// v0.5 - Improved portability by replacing static const int's with enum's and
// clarifying return values in seed(); suggested by Eric Heimburg
// - Removed MAXINT constant; use 0xffffffffUL instead
//
// v0.6 - Eliminated seed overflow when uint32 is larger than 32 bits
// - Changed integer [0,n] generator to give better uniformity
//
// v0.7 - Fixed operator precedence ambiguity in reload()
// - Added access for real numbers in (0,1) and (0,n)
//
// v0.8 - Included time.h header to properly support time_t and clock_t
//
// v1.0 - Revised seeding to match 26 Jan 2002 update of Nishimura and Matsumoto
// - Allowed for seeding with arrays of any length
// - Added access for real numbers in [0,1) with 53-bit resolution
// - Added access for real numbers from normal (Gaussian) distributions
// - Increased overall speed by optimizing twist()
// - Doubled speed of integer [0,n] generation
// - Fixed out-of-range number generation on 64-bit machines
// - Improved portability by substituting literal constants for long enum's
// - Changed license from GNU LGPL to BSD
File diff suppressed because it is too large Load Diff
-95
View File
@@ -1,95 +0,0 @@
/**
* vim: set ts=4 :
* =============================================================================
* SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
* =============================================================================
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, version 3.0, as published by the
* Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <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_SOURCEMOD_TEXTPARSERS_H_
#define _INCLUDE_SOURCEMOD_TEXTPARSERS_H_
#include <ITextParsers.h>
#include "common_logic.h"
using namespace SourceMod;
/**
* @param void * IN: Stream pointer
* @param char * IN/OUT: Stream buffer
* @param size_t IN: Maximum size of buffer
* @param unsigned int * OUT: Number of bytes read (0 = end of stream)
* @return True on success, false on failure
*/
typedef bool (*STREAMREADER)(void *, char *, size_t, unsigned int *);
class TextParsers :
public ITextParsers,
public SMGlobalClass
{
public:
TextParsers();
public: //SMGlobalClass
void OnSourceModAllInitialized();
public:
bool ParseFile_INI(const char *file,
ITextListener_INI *ini_listener,
unsigned int *line,
unsigned int *col);
SMCError ParseFile_SMC(const char *file,
ITextListener_SMC *smc_listener,
SMCStates *states);
SMCError ParseSMCFile(const char *file,
ITextListener_SMC *smc_listener,
SMCStates *states,
char *buffer,
size_t maxsize);
SMCError ParseSMCStream(const char *stream,
size_t length,
ITextListener_SMC *smc_listener,
SMCStates *states,
char *buffer,
size_t maxsize);
unsigned int GetUTF8CharBytes(const char *stream);
const char *GetSMCErrorString(SMCError err);
bool IsWhitespace(const char *stream);
private:
SMCError ParseStream_SMC(void *stream,
STREAMREADER srdr,
ITextListener_SMC *smc,
SMCStates *states);
};
extern TextParsers g_TextParser;
#endif //_INCLUDE_SOURCEMOD_TEXTPARSERS_H_

Some files were not shown because too many files have changed in this diff Show More