Compare commits

...

144 Commits

Author SHA1 Message Date
Nicholas Hastings
300632db86 Update versioning for 1.5.1 release. 2013-09-10 14:59:41 -04:00
Nicholas Hastings
d1776dd641 Updated changelog for version 1.5.1. 2013-09-10 14:58:42 -04:00
Drifter
22cee6a2dd Add CS_UpdateClientModel native to cstrike extension (bug 5905, r=psychonic). 2013-09-10 13:08:14 -04:00
Nicholas Hastings
a2194df273 Fix attempted triggers from gagged users displaying in chat (bug 5918, r=asherkin). 2013-09-10 09:52:37 -04:00
Nicholas Hastings
27e20996dd Initialize DamageCustom var in SDKHooks CTakeDamageInfoHack (nobug, r=asherkin). 2013-09-09 18:41:54 -04:00
Kyle Sanderson
b5f16142e5 Fix incorrect assignment in SDKHook_TakeDamage + cleanup (bug 5911, r=psychonic). 2013-09-06 18:37:13 -04:00
Peace-Maker
23f1f9e148 Added missing DispatchKeyValues and SDKHooks gamedata for HL2CTF (bug 5114, r=psychonic). 2013-09-05 22:31:44 -04:00
Nicholas Hastings
990f99af5a Reserved slot fixes for OB games when SourceTV or Replay are enabled (bug 5499, r=drifter). 2013-08-30 14:15:02 -04:00
Nicholas Hastings
6ca9d86e8f Make sm_mapvote_runoffpercent cvar work as advertised (bug 5890, r=asherkin). 2013-08-30 14:14:59 -04:00
Nicholas Hastings
fae8b4d49a Fix translator system not loading languages with long identifier (bug 5888, r=dvander). 2013-08-28 13:18:55 -04:00
Nicholas Hastings
7f2d9dd8eb Updated TF2 Regenerate signature. 2013-08-27 23:32:56 -04:00
Nicholas Hastings
8ae1b3e1e7 Updated TF2 AddCond signature. 2013-08-27 21:08:37 -04:00
Nicholas Hastings
c77c853c02 Updated plugin blacklist. 2013-08-26 10:31:25 -04:00
Nicholas Hastings
2b0daba573 Bumping version. 2013-08-25 19:45:28 -04:00
Nicholas Hastings
ba4aa4d37f Added tag sourcemod-1.5.0 for changeset 78a1f1b1c6fa 2013-08-25 19:44:52 -04:00
Nicholas Hastings
e3f31af5d3 Update versioning for 1.5.0 release. 2013-08-25 17:38:09 -04:00
Nicholas Hastings
bc0bf4e270 Updated changelog for version 1.5.0. 2013-08-25 16:59:14 -04:00
Nicholas Hastings
60c5ad6324 Synced changelog.txt from releases/sourcemod-1.4. 2013-08-25 12:16:54 -04:00
Nicholas Hastings
e996a00675 Add missing MarkNativeAsOptional calls for cstrike.inc (r=me). 2013-08-25 11:01:55 -04:00
Kyle Sanderson
0be3f0afed Fix broken translating in some plugins and natives (bug 5612, r=psychonic). 2013-08-25 10:15:35 -04:00
Kyle Sanderson
86bdfa2205 Fixed potential deadlock in HandleSystem::TryAndFreeSomeHandles (bug 5665, r=dvander). 2013-08-25 09:59:53 -04:00
Nicholas Hastings
56c87e927f Fix cmd listener callback return behavior to match func doc (bug 5882, r=asherkin). 2013-08-24 23:56:39 -04:00
Nicholas Hastings
be54443918 Replace hardcoded "/ff" check in basetriggers (bug 5863, r=drifter). 2013-08-24 21:59:52 -04:00
Nicholas Hastings
676ea8b29c Don't call SayCommand forwards for chat triggers (bug 5863, r=asherkin). 2013-08-24 21:59:52 -04:00
Nicholas Hastings
d77ff38428 Fixed regression causing public triggers to no longer display (bug 5863, r=drifter). 2013-08-24 21:59:52 -04:00
Nicholas Hastings
d3256ef339 Removed unused var m_bTriggerWasSilent from core ChatTriggers (bug 5863, r=asherkin). 2013-08-24 21:59:52 -04:00
Nicholas Hastings
3d11742f91 Add missing GetFunctionCount check in ChatTriggers::OnSayCommand_Pre (bug 5864, r=kyles). 2013-08-23 18:48:06 -04:00
Peace-Maker
a2aa5d1cda Fixed crash in OnSayCommand_Post with console chat, pass console chat (bug 5864, r=kyles). 2013-08-23 07:31:04 -04:00
Nicholas Hastings
8860e18026 Backed out changeset: 6118b70b1103 (bug 5864). 2013-08-23 07:31:56 -04:00
Nicholas Hastings
7dba540b97 Fixed crash in OnSayCommand_Post with console chat, pass console chat (bug 5864, r=voided);
--HG--
extra : rebase_source : 3090e700ea04a1b2cc6a92c727e3bb58df69500d
2013-08-22 21:45:42 -04:00
Nicholas Hastings
0dd9a5b842 Changed from RemoveEdict to using the Kill input for TF2_RemoveWeapon (r=voided).
--HG--
extra : rebase_source : 1bc5d8aa9aa6be4022b3e1e730ff06de3e428f8e
2013-08-22 21:45:40 -04:00
Nicholas Hastings
e6c3565544 Fixed SDKHooks thinking a hook type was supported when gamedata missing (r=voided).
--HG--
extra : rebase_source : 8e89e780c12309a3a772f1edfadc9c4541318b48
2013-08-22 21:45:19 -04:00
Kyle Sanderson
8cacba922a Fix weapon ID checks (bug 5872, r=Dr!fter) 2013-08-21 10:56:04 -04:00
Nicholas Hastings
767396d4ee Fixed GuessSDKVersion return value when using MM:S versions < 1.10 (r=me). 2013-08-16 11:47:35 -04:00
Nicholas Hastings
07a51a0d4e Fixed char * constant conversion warning in cstrike ext. 2013-08-15 18:43:14 -04:00
Drifter
9f042625d0 Fix CS:GO GetWeaponPrice and OnGetWeaponPrice using outdated method (r=psychonic). 2013-08-15 14:40:30 -04:00
Dr!fter
fc29f4249a Update some more CS:GO gamedata 2013-08-15 17:04:33 -04:00
Nicholas Hastings
5ca5ecee85 Fixed chat trigger crash regression on ep1 (bug 5394, r=asherkin). 2013-08-15 10:21:04 -04:00
Nicholas Hastings
c79d547492 Update BuyCommand detour in CStrike extension with new param on CS:GO. 2013-08-14 17:08:02 -04:00
Nicholas Hastings
f079773195 Update GivePlayerItem for new params in CS:GO. 2013-08-14 17:07:27 -04:00
Dr!fter
e6ead8b5aa Update some more CS:GO gamedata 2013-08-14 16:40:58 -04:00
Nicholas Hastings
9eba6402eb Updated some CS:GO gamedata. 2013-08-14 14:20:57 -04:00
Nicholas Hastings
f95be3b10c Fixed typo in Nuclear Dawn gamedata backcompat fix. 2013-08-14 13:14:59 -04:00
Nicholas Hastings
2220cc961e Added compat shim to load on Nuclear Dawn with MM:S < 1.9.3. (bug 5813, r=me). 2013-08-14 12:55:55 -04:00
Nicholas Hastings
cfc6b2fee9 Added gamedata and extension loading compat shims for Nuclear Dawn (bug 5813, r=asherkin). 2013-08-14 11:56:34 -04:00
Nicholas Hastings
d188859fc5 Readded another missing hunk from 394499aa9d33 merge. 2013-08-14 12:10:31 -04:00
Kyle Sanderson
96a8003448 Added global pre and post forwards for client chat (bug 5394, r=psychonic). 2013-08-05 11:46:29 -04:00
Nicholas Hastings
696f702204 Fixed a path not using updated mapcycle file detection (bug 5719). 2013-08-05 11:36:59 -04:00
Nicholas Hastings
8b26ce73c2 Triggering build. 2013-08-05 08:36:34 -04:00
GoD-Tony
ee5f488aa2 Added ISDKHooks interface with entity listeners (bug 5602, r=psychonic). 2013-08-04 10:03:40 -04:00
Nicholas Hastings
3a5cf80e2b Fixed build. 2013-08-03 20:22:01 -04:00
Nicholas Hastings
3e4f7af96a Readded missing hunk from 394499aa9d33 merge for ep2v extension loading backcompat. 2013-08-03 19:10:23 -04:00
Erik Minekus
a1a483fa27 Numerous code documentation fixups (bug 5720, r=psychonic).
--HG--
extra : rebase_source : 864171c29442accaef2a051e37dfd25c2ee1566c
2013-08-01 09:26:34 -04:00
Asher Baker
b32f8a4803 Disable SteamAuthstringValidation config option by default (bug 5791, r=psychonic). 2013-08-01 14:33:06 +01:00
Nicholas Hastings
96ee6dbf8a Check all possible mapcycle paths on newer orangebox games (bug 5719, r=asherkin). 2013-07-31 22:57:50 -04:00
Drifter
ac07cf95e1 Added CS_IsValidWeaponID native and validity checks to other natives (bug 5566, r=psychonic). 2013-07-31 22:11:15 -04:00
Drifter
8f51e33167 Fixed incorrect return for some weapons in CS_GetWeaponPrice (bug 5562, r=psychonic). 2013-07-31 22:08:23 -04:00
Kyle Sanderson
8366f371ad Fixed crash in SDKHooks when throwing bad ent type error on logical ent (r=psychonic). 2013-07-31 22:03:59 -04:00
Nicholas Hastings
9b44dfea11 Build against MM:S 1.10.
--HG--
extra : rebase_source : 3ae670b671c8bbc964affa77ccf3f2c9191c7f90
2013-07-31 18:42:15 -04:00
Nicholas Hastings
7ede8e0924 Split TF2, DoD:S, HL2:DM, and ND to separate binaries (bug 5813, r=asherkin).
--HG--
extra : rebase_source : 89a3d9703bbb0f5c3225ce8f5da85ce1fabafeaa
2013-07-21 11:53:56 -04:00
Dr!fter
9fe2d9c1cf Update WeaponIDToAlias Sig for CS:GO 2013-07-26 14:42:36 -04:00
Kyle Sanderson
1836ec9d45 Fixed handle misuse in clientprefs plugin (bug 5805, r=psychonic). 2013-07-20 15:17:43 -04:00
Kyle Sanderson
380d7adc09 Make compile.sh set working dir to own dir (bug 5710, r=psychonic). 2013-07-18 19:40:42 -04:00
Kyle Sanderson
4109d0df39 Fixed accidental assignment in each of SDKTools and sp compiler (bug 5745, r=psychonic). 2013-07-18 15:50:50 -04:00
systematicmania
9cab1e3ab7 Fixed clients not being marked as in kick queue in some cases (bug 5746, r=psychonic). 2013-07-18 11:38:04 -04:00
Kyle Sanderson
e9d8bfcdfc Throw error instead of crash when calling SetTeamScore between maps (bug 5718, r=psychonic). 2013-07-18 11:38:04 -04:00
Peace-Maker
f134602991 Fixed typo in too-many-params native error message (r=psychonic). 2013-07-17 08:09:10 -04:00
Nicholas Hastings
b493532ee1 Updated DoD:S gamedata. 2013-07-16 20:45:02 -04:00
Dr!fter
84dec75fb8 Fix SDKHooks gamedata for Half-Life 2 and DOD:S 2013-07-10 20:46:13 -04:00
Dr!fter
b1094f87c6 Update TF2 Reload Offset 2013-07-10 20:33:28 -04:00
Dr!fter
284b4bfe20 Update GroundEndChanged for CS:S and CS:GO 2013-07-10 19:56:43 -04:00
Dr!fter
b46537ddd5 Update TF2 ForceRespawn offset 2013-07-10 19:14:06 -04:00
Dr!fter
c9446c4d7d Update TF2 Gamedata 2013-07-10 18:53:12 -04:00
Nicholas Hastings
d4610ab340 Updated L4D2 IServer gamedata for Windows. 2013-07-08 16:13:47 -04:00
Nicholas Hastings
0016b8ef2f Fix tier0/vstdlib lookup in core for recent L4D2 changes. 2013-07-06 12:02:42 -04:00
Nicholas Hastings
72e08f7e44 Define POSIX when compiling for any build on linux/mac. 2013-07-06 12:02:01 -04:00
Nicholas Hastings
b06cfa5414 Updated L4D2 gamedata. 2013-07-05 14:30:20 -04:00
Nicholas Hastings
a7742cae3d Triggering build for L4D2 sdk update. 2013-07-04 16:45:31 -04:00
Nicholas Hastings
8a78285659 Fixed build. 2013-07-04 11:29:18 -04:00
Ryan Stecker
6847c8eec0 Fixed ReadMapList not seeing maps in all valveFS paths (bug 5715, r=asherkin). 2013-07-03 23:23:05 -04:00
Nicholas Hastings
66790254ac Updated ambuild script for new l4d2 library names. 2013-06-30 10:45:19 -04:00
Ryan Stecker
86b8a0b16a Updated TF2 CalcCriticalMelee Windows byte signature.
--HG--
extra : rebase_source : 7ecde66470b85425c9836fbf61b6d042264a210e
2013-06-13 21:37:05 -04:00
Asher Baker
25fced78e8 File upload support for webternet (r=psychonic). 2013-05-16 14:49:03 +01:00
Dr!fter
22d11160ba Update Remove Disguise sig 2013-05-13 19:07:13 -04:00
Nicholas Hastings
8d65b3e94e Don't omit frame pointer on msvc builds. 2013-05-13 14:19:17 -04:00
Nicholas Hastings
5518544ecd Fixed CS:S CommitSuicide offset. 2013-05-03 15:29:20 -04:00
Nicholas Hastings
af3523bd2d Backed out changeset: d1a5f4fe8f61. 2013-05-02 15:31:36 -04:00
Nicholas Hastings
8646cca538 Backed out changeset: 1bdf91c47e13. 2013-05-02 15:31:25 -04:00
Nicholas Hastings
c7cea1b40b Backed out changeset: a4fe868541d6. 2013-05-02 15:31:13 -04:00
Nicholas Hastings
58914f71bd Backed out changeset: 3e8245271fd8. 2013-04-30 15:38:50 -04:00
Nicholas Hastings
3841e98c4f Updated TF2 gamedata. 2013-04-29 21:20:11 -04:00
Nicholas Hastings
acd025dba2 Merge. 2013-04-16 13:25:22 -04:00
Nicholas Hastings
78c2206628 Updated CS:S gamedata. 2013-04-16 12:19:45 -04:00
Brian Simon
5c47bf8803 Added more alternative names for TFClass_Heavy (bug 5338, r=asherkin). 2013-04-11 03:07:50 +01:00
Kyle Sanderson
8e78ee6f57 Remove debug printout from PerformGravity (bug 5679, r=asherkin). 2013-04-11 03:03:29 +01:00
Asher Baker
a2da4cc868 Only split DWARF data out for non-explicit-debug builds (bug 5683, r=dvander). 2013-04-11 00:34:52 +01:00
Asher Baker
00e44ad3c3 Fixed JIT conflicts with SELinux (bug 5581, r=dvander). 2013-04-11 00:33:12 +01:00
Nicholas Hastings
29ba84fc5c Allow localizaton of more base plugin strings (bug 5120, r=asherkin). 2013-04-08 08:00:13 -04:00
Nicholas Hastings
283f1f012d Allow localization of name-reserved kick message (bug 5146, r=asherkin). 2013-04-08 08:00:13 -04:00
Nicholas Hastings
fff17f8043 Updated HL2DM gamedata. 2013-04-03 12:26:08 -04:00
Nicholas Hastings
847eaf38f9 Updated DoD:S gamedata. 2013-03-29 15:45:16 -04:00
Drifter
1d59a329eb Update gamedata for CS:GO update 2013-03-21 20:00:29 -04:00
Nicholas Hastings
5689888682 Fixed IsMapValid passing blank string to engine's IsMapValid which crashes some games. 2013-03-21 01:22:08 -04:00
Nicholas Hastings
a01768525a Backed out changeset: f38675c67f64 (bug 5484). 2013-03-20 07:08:49 -04:00
Kyle Sanderson
e3d2ddf278 Fix a number of issues with cloned handles (bug 5240, r=asherkin). 2013-03-17 22:05:33 +00:00
Kyle Sanderson
b3e48b0ad7 Check for cloned handles when dumping (bug 5245, r=asherkin). 2013-03-17 21:58:56 +00:00
Nicholas Hastings
6d528b5c55 Merge. 2013-03-18 20:39:41 -04:00
Peace-Maker
22daf26e3e Fixed possible rte in basetriggers for !ingame clients (bug 5191, r=psychonic). 2013-03-18 20:11:50 -04:00
Michael McKoy
73061969da Fixed mapchooser interaction with CS:GO winlimits (bug 5484, r=psychonic). 2013-03-18 20:10:31 -04:00
Kyle Sanderson
4653530095 Fixed check against uninitialized string in extension loader (bug 5546, r=psychonic). 2013-03-18 20:03:17 -04:00
Peace-Maker
ef5faaaa4a Fixed double print when sending psay to self (bug 5649, r=psychonic). 2013-03-18 19:58:18 -04:00
GoD-Tony
f52ea98eb4 Added logged error when PlayerRunCommand offset lookup fails (bug 5535, r=psychonic). 2013-03-18 19:53:30 -04:00
Asher Baker
d315d4bf53 Backport some clientprefs crash fixes from 1.6. 2013-03-18 18:54:00 +00:00
Kyle Sanderson
eaef2a46fb Change extension unload order to avoid exposing finalisation window (bug 5556, r=asherkin). 2013-03-18 18:06:55 +00:00
Nicholas Hastings
b0304a89a6 Fixed errors with SendConVarValue on CS:GO (bug 5638, r=asherkin). 2013-03-18 11:47:55 -04:00
Asher Baker
a4790f0358 Generate debugging information during compilation (bug 5227, r=ds). 2013-03-17 21:00:28 +00:00
Scott Ehlert
d3d5cd8181 Added --no-mysql option to configure script to make MySQL optional (bug 5661, r+a=dvander). 2013-03-17 04:09:44 -05:00
Peace-Maker
64be2bc5a0 Increased map name buffer sizes in mapchooser (bug 5609, r=psychonic). 2013-03-16 23:17:22 -04:00
Kyle Sanderson
30e476c35e Added GetSteamAccountID function to IPlayerHelpers and native for sp (bug 5548, r=asherkin). 2013-03-16 23:12:40 -04:00
Nicholas Hastings
88af208cdd Add DPT_Int64 type to netprop dumps (bug 5655, r=asherkin). 2013-03-16 22:57:57 -04:00
Scott Ehlert
b64751c1af Made BreakpadSymbols script compatbile with Python 2.6 and above (bug 5660, r=asherkin). 2013-03-16 22:55:59 -04:00
FlaminSarge
2e158a72e2 Exposed third parameter of TF2's AddCond in TF2_AddCondition (bug 5641, r=psychonic). 2013-03-16 18:05:22 -04:00
Nicholas Hastings
c8fb05dd4b Fixed some engine builds failing. 2013-03-16 14:11:56 -04:00
Nicholas Hastings
860af1e6cb Add GetPlayerResourceEntity to SDKTools; deprecate old, broken TF2-specific impl (bug 5491, r=asherkin). 2013-03-16 13:50:36 -04:00
Nicholas Hastings
5c1cadb64e Move UserMessages::m_pBase to only engines without protobuf msgs (r=asherkin). 2013-03-16 13:42:11 -04:00
Nicholas Hastings
bfb97a4207 Added repeated field handing to PbSet* natives (bug 5633, r=asherkin). 2013-03-16 13:31:56 -04:00
Nicholas Hastings
7e26691b99 Added repeated field handling to PbRead* natives. Deprecate PbReadRepeated* (bug 5633, r=asherkin). 2013-03-16 13:31:35 -04:00
FlaminSarge
ca469a218a Updated TF2 TFCond defines (bug 5642, r=psychonic). 2013-03-16 13:30:00 -04:00
Scott Ehlert
6052ddaa64 Triggering a build. 2013-03-14 00:07:11 -05:00
Scott Ehlert
0ddc675472 Added --sdks option to configure script to specify which SDKs to build againt (bug 5630, r+a=dvander).
Valid arguments are "all", "present", or a comma delimited list of engine names.

The "all" option will try to build against all supported SDKs. (This is the default.)
The "present" option will only attempt to build against SDKs that exist on the system.

Examples:

configure.py --sdks=css,csgo,ep2v
configure.py --sdks=l4d
configure.py -s present
2013-03-13 22:02:40 -05:00
Asher Baker
9412f687cb Fixed issues with COMMAND_FILTER_NO_BOTS and @bots multi-target. (r=fennec) 2013-03-10 03:24:03 +00:00
Asher Baker
0e865c0618 Allow access to unvalidated authstrings (bug 5587, r=psychonic). 2013-03-07 00:58:17 +00:00
Nicholas Hastings
462b5213d7 Fixed SDKHooks GetMaxHealth callback being passed incorrect parameters. 2013-03-02 13:42:07 -05:00
Scott Ehlert
f52e84730f Triggering a build. 2013-03-02 11:56:31 -06:00
Asher Baker
b8873efa0d Error on access to nested datamap props (bug 5446, r=psychonic). 2012-09-03 20:26:39 +01:00
Scott Ehlert
4132b9bd21 Added L4D and L4D2 gamedata for SDK Hooks on Mac OS X (bug 5628, r=psychonic). 2013-02-25 20:45:11 -06:00
Kyle Sanderson
c0caa9f158 Removed call to getchar() in debug build of compiler (bug 5626, r=ds). 2013-02-25 18:02:10 -06:00
Nicholas Hastings
7346b0c081 Added support for "fuzzy" map names in L4D and later (bug 5599, r=asherkin). 2013-02-14 19:28:12 -05:00
Nicholas Hastings
6a361e3045 Updated CS:GO gamedata. 2013-02-13 22:25:15 -05:00
Nicholas Hastings
61d7519ef5 More, hopefully final CS:GO/protobuf usermessage fixups (bug 5588). 2013-02-11 15:11:04 -05:00
Ruben Gonzalez
3e1a78703e Fix CS_WeaponIDToAlias param missing CSWeaponID tag (bug 5460) 2013-02-11 11:17:46 -05:00
Nicholas Hastings
bb195a9b2d Added missing smn_protobuf.cpp to core msvc10 project (NPOTB). 2013-02-11 09:39:23 -05:00
Nicholas Hastings
6f095a064c Removed intentional invalid steamid crash in SDK Hooks. 2013-02-11 09:39:23 -05:00
Nicholas Hastings
eb334f5fe2 Fixed typo in Fortress Forever gamedat.a 2013-02-11 09:39:23 -05:00
192 changed files with 3876 additions and 1471 deletions

View File

@ -3,3 +3,4 @@ e6ef5ecdf8d75740ca2685a709bf321f8873bc3b sourcemod-1.1.0
e877885fac80be71822641f7a9122cebc9812521 sourcemod-1.1.1
b3ffa8a4511c4eadaf533fc790aa6b14f7f0c6ea sourcemod-1.1.2
3a73bbf60f34befa9b66be03fa5974b394bb3411 sourcemod-1.2.0
78a1f1b1c6fa86fd7691c70ebf48a9fb3dfb3c11 sourcemod-1.5.0

View File

@ -1,8 +1,31 @@
# vim: set ts=2 sw=2 tw=99 noet ft=python:
import os
import sys
from ambuild.command import Command
from ambuild.command import ShellCommand
from ambuild.command import SymlinkCommand
class ExtractDebugInfoCommand(Command):
def __init__(self, binary, outfile):
Command.__init__(self)
self.binary = binary
self.outfile = outfile
def run(self, runner, job):
if AMBuild.cache['debug']:
return
if not self.binary.NeedsRelink(self.outfile):
return
if AMBuild.target['platform'] == 'linux':
job.AddCommand(ShellCommand('objcopy --only-keep-debug ' + self.outfile + ' ' + self.outfile + '.dbg'))
job.AddCommand(ShellCommand('objcopy --strip-debug ' + self.outfile))
job.AddCommand(ShellCommand('objcopy --add-gnu-debuglink=' + os.path.basename(self.outfile) + '.dbg ' + self.outfile))
elif AMBuild.target['platform'] == 'darwin':
job.AddCommand(ShellCommand('dsymutil ' + self.outfile))
job.AddCommand(ShellCommand('strip -S ' + self.outfile))
class SM:
def __init__(self):
self.compiler = Cpp.Compiler()
@ -10,89 +33,96 @@ class SM:
#Build SDK info
self.possibleSdks = { }
self.possibleSdks['ep1'] = {'sdk': 'HL2SDK', 'ext': '1.ep1', 'def': '1',
'name': 'EPISODEONE', 'platform': ['windows', 'linux']}
'name': 'EPISODEONE', 'platform': ['windows', 'linux'],
'dir': 'hl2sdk'}
self.possibleSdks['ep2'] = {'sdk': 'HL2SDKOB', 'ext': '2.ep2', 'def': '3',
'name': 'ORANGEBOX', 'platform': ['windows', 'linux']}
self.possibleSdks['css'] = {'sdk': 'HL2SDKCSS', 'ext': '2.css', 'def': '6',
'name': 'CSS', 'platform': ['windows', 'linux', 'darwin']}
self.possibleSdks['ep2v'] = {'sdk': 'HL2SDKOBVALVE', 'ext': '2.ep2v', 'def': '7',
'name': 'ORANGEBOXVALVE', 'platform': ['windows', 'linux', 'darwin']}
self.possibleSdks['l4d'] = {'sdk': 'HL2SDKL4D', 'ext': '2.l4d', 'def': '8',
'name': 'LEFT4DEAD', 'platform': ['windows', 'linux', 'darwin']}
self.possibleSdks['l4d2'] = {'sdk': 'HL2SDKL4D2', 'ext': '2.l4d2', 'def': '9',
'name': 'LEFT4DEAD2', 'platform': ['windows', 'linux', 'darwin']}
'name': 'ORANGEBOX', 'platform': ['windows', 'linux'],
'dir': 'hl2sdk-ob'}
self.possibleSdks['css'] = {'sdk': 'HL2SDKCSS', 'ext': '2.css', 'def': '6',
'name': 'CSS', 'platform': ['windows', 'linux', 'darwin'],
'dir': 'hl2sdk-css'}
self.possibleSdks['hl2dm'] = {'sdk': 'HL2SDKHL2DM', 'ext': '2.hl2dm', 'def': '7',
'name': 'HL2DM', 'platform': ['windows', 'linux', 'darwin'],
'dir': 'hl2sdk-hl2dm'}
self.possibleSdks['dods'] = {'sdk': 'HL2SDKDODS', 'ext': '2.dods', 'def': '8',
'name': 'DODS', 'platform': ['windows', 'linux', 'darwin'],
'dir': 'hl2sdk-dods'}
self.possibleSdks['tf2'] = {'sdk': 'HL2SDKTF2', 'ext': '2.tf2', 'def': '9',
'name': 'TF2', 'platform': ['windows', 'linux', 'darwin'],
'dir': 'hl2sdk-tf2'}
self.possibleSdks['l4d'] = {'sdk': 'HL2SDKL4D', 'ext': '2.l4d', 'def': '10',
'name': 'LEFT4DEAD', 'platform': ['windows', 'linux', 'darwin'],
'dir': 'hl2sdk-l4d'}
self.possibleSdks['nd'] = {'sdk': 'HL2SDKND', 'ext': '2.nd', 'def': '11',
'name': 'NUCLEARDAWN', 'platform': ['windows', 'linux', 'darwin'],
'dir': 'hl2sdk-nd'}
self.possibleSdks['l4d2'] = {'sdk': 'HL2SDKL4D2', 'ext': '2.l4d2', 'def': '12',
'name': 'LEFT4DEAD2', 'platform': ['windows', 'linux', 'darwin'],
'dir': 'hl2sdk-l4d2'}
self.possibleSdks['darkm'] = {'sdk': 'HL2SDK-DARKM', 'ext': '2.darkm', 'def': '2',
'name': 'DARKMESSIAH', 'platform': ['windows']}
self.possibleSdks['swarm'] = {'sdk': 'HL2SDK-SWARM', 'ext': '2.swarm', 'def': '10',
'name': 'ALIENSWARM', 'platform': ['windows']}
self.possibleSdks['bgt'] = {'sdk': 'HL2SDK-BGT', 'ext': '2.bgt', 'def': '4',
'name': 'BLOODYGOODTIME', 'platform': ['windows']}
self.possibleSdks['eye'] = {'sdk': 'HL2SDK-EYE', 'ext': '2.eye', 'def': '5',
'name': 'EYE', 'platform': ['windows']}
self.possibleSdks['csgo'] = {'sdk': 'HL2SDKCSGO', 'ext': '2.csgo', 'def': '12',
'name': 'CSGO', 'platform': ['windows', 'linux', 'darwin']}
# self.possibleSdks['portal2'] = {'sdk': 'HL2SDK-PORTAL2', 'ext': '2.portal2', 'def': '11',
# 'name': 'PORTAL2', 'platform': ['windows']}
'name': 'DARKMESSIAH', 'platform': ['windows'],
'dir': 'hl2sdk-darkm'}
self.possibleSdks['swarm'] = {'sdk': 'HL2SDK-SWARM', 'ext': '2.swarm', 'def': '13',
'name': 'ALIENSWARM', 'platform': ['windows'],
'dir': 'hl2sdk-swarm'}
self.possibleSdks['bgt'] = {'sdk': 'HL2SDK-BGT', 'ext': '2.bgt', 'def': '4',
'name': 'BLOODYGOODTIME', 'platform': ['windows'],
'dir': 'hl2sdk-bgt'}
self.possibleSdks['eye'] = {'sdk': 'HL2SDK-EYE', 'ext': '2.eye', 'def': '5',
'name': 'EYE', 'platform': ['windows'],
'dir': 'hl2sdk-eye'}
self.possibleSdks['csgo'] = {'sdk': 'HL2SDKCSGO', 'ext': '2.csgo', 'def': '15',
'name': 'CSGO', 'platform': ['windows', 'linux', 'darwin'],
'dir': 'hl2sdk-csgo'}
# self.possibleSdks['portal2'] = {'sdk': 'HL2SDK-PORTAL2', 'ext': '2.portal2', 'def': '14',
# 'name': 'PORTAL2', 'platform': ['windows'],
# 'dir': 'hl2sdk-portal'}
self.sdkInfo = { }
if AMBuild.mode == 'config':
#Detect compilers
self.compiler.DetectAll(AMBuild)
self.hasMySql = AMBuild.options.hasMySql
AMBuild.cache.CacheVariable('hasMySql', self.hasMySql)
#Detect variables
envvars = { 'MMSOURCE19': 'mmsource-1.9',
'HL2SDKCSS': 'hl2sdk-css',
'HL2SDKOBVALVE': 'hl2sdk-ob-valve',
'HL2SDKL4D': 'hl2sdk-l4d',
'HL2SDKL4D2': 'hl2sdk-l4d2',
'HL2SDKCSGO': 'hl2sdk-csgo',
'MYSQL5': 'mysql-5.0'
}
AMBuild.cache.CacheVariable('debug', AMBuild.options.debug)
#Environment variable paths to external headers
envvars = { 'MMSOURCE110': 'mmsource-1.10', 'MYSQL5': 'mysql-5.0' }
#Look for Metamod:Source and MySQL if not disabled
for env in envvars:
if not self.hasMySql and env == 'MYSQL5':
continue
path = self.ResolveEnvPath(env, envvars[env])
if path == None:
raise Exception('Could not find a valid path for {0}'.format(env))
AMBuild.cache.CacheVariable(env, path)
#Look for SDK directories
for sdk in self.possibleSdks:
#Get list of SDKs to build against or 'all' or 'present'
sdkList = AMBuild.options.sdks.split(',')
#Build against all supported SDKs?
useAll = sdkList[0] == 'all'
#Build against supported SDKs that exist?
usePresent = sdkList[0] == 'present'
if AMBuild.target['platform'] != 'darwin':
envvars['HL2SDK'] = 'hl2sdk'
envvars['HL2SDKOB'] = 'hl2sdk-ob'
#Dark Messiah is Windows-only
if AMBuild.target['platform'] == 'windows':
envvars['HL2SDK-DARKM'] = 'hl2sdk-darkm'
envvars['HL2SDK-SWARM'] = 'hl2sdk-swarm'
envvars['HL2SDK-BGT'] = 'hl2sdk-bgt'
envvars['HL2SDK-EYE'] = 'hl2sdk-eye'
# Finds if a dict with `key` set to `value` is present on the dict of dicts `dictionary`
def findDictByKey(dictionary, key, value):
for index in dictionary:
elem = dictionary[index]
if elem[key] == value:
return (elem, index)
return None
for i in envvars:
if i in os.environ:
path = os.environ[i]
if not os.path.isdir(path):
raise Exception('Path for {0} was not found: {1}'.format(i, path))
elif i.startswith('HL2SDK'):
(info, sdk) = findDictByKey(self.possibleSdks, 'sdk', i)
info = self.possibleSdks[sdk]
if AMBuild.target['platform'] in info['platform']:
env = info['sdk']
dir = info['dir']
sdkPath = self.ResolveEnvPath(env, dir)
if sdkPath == None:
if useAll or sdk in sdkList:
raise Exception('Could not find a valid path for {0}'.format(env))
else:
continue
if useAll or usePresent or sdk in sdkList:
self.sdkInfo[sdk] = info
else:
head = os.getcwd()
oldhead = None
while head != None and head != oldhead:
path = os.path.join(head, envvars[i])
if os.path.isdir(path):
break
oldhead = head
head, tail = os.path.split(head)
if i.startswith('HL2SDK'):
if head != None and head != oldhead:
(info, sdk) = findDictByKey(self.possibleSdks, 'sdk', i)
self.sdkInfo[sdk] = info
elif head == None or head == oldhead:
raise Exception('Could not find a valid path for {0}'.format(i))
AMBuild.cache.CacheVariable(i, path)
AMBuild.cache.CacheVariable(env, sdkPath)
if len(self.sdkInfo) < 1:
raise Exception('At least one SDK must be available.')
@ -121,6 +151,7 @@ class SM:
self.compiler.AddToListVar('CFLAGS', '-Wno-unused')
self.compiler.AddToListVar('CFLAGS', '-Wno-switch')
self.compiler.AddToListVar('CFLAGS', '-msse')
self.compiler.AddToListVar('CFLAGS', '-g3')
self.compiler.AddToListVar('CFLAGS', '-m32')
self.compiler.AddToListVar('POSTLINKFLAGS', '-m32')
self.compiler.AddToListVar('CXXFLAGS', '-fno-exceptions')
@ -180,15 +211,19 @@ class SM:
if AMBuild.options.debug == '1':
self.compiler.AddToListVar('CDEFINES', 'DEBUG')
self.compiler.AddToListVar('CDEFINES', '_DEBUG')
if self.vendor == 'gcc' or self.vendor == 'clang':
self.compiler.AddToListVar('CFLAGS', '-g3')
elif self.vendor == 'msvc':
if self.vendor == 'msvc':
self.compiler.AddToListVar('CFLAGS', '/Od')
self.compiler.AddToListVar('CFLAGS', '/RTC1')
#This needs to be after our optimization flags which could otherwise disable it.
if self.vendor == 'msvc':
# Don't omit frame pointer
self.compiler.AddToListVar('CFLAGS', '/Oy-')
#Platform-specifics
if AMBuild.target['platform'] == 'linux':
self.compiler.AddToListVar('CDEFINES', '_LINUX')
self.compiler.AddToListVar('CDEFINES', 'POSIX')
if self.vendor == 'gcc':
self.compiler.AddToListVar('POSTLINKFLAGS', '-static-libgcc')
if self.vendor == 'clang':
@ -196,6 +231,7 @@ class SM:
elif AMBuild.target['platform'] == 'darwin':
self.compiler.AddToListVar('CDEFINES', 'OSX')
self.compiler.AddToListVar('CDEFINES', '_OSX')
self.compiler.AddToListVar('CDEFINES', 'POSIX')
self.compiler.AddToListVar('POSTLINKFLAGS', '-mmacosx-version-min=10.5')
self.compiler.AddToListVar('POSTLINKFLAGS', ['-arch', 'i386'])
self.compiler.AddToListVar('POSTLINKFLAGS', '-lstdc++')
@ -229,12 +265,13 @@ class SM:
self.sdkInfo = AMBuild.cache['sdkInfo']
self.compiler.FromConfig(AMBuild, 'compiler')
self.targetMap = AMBuild.cache['targetMap']
self.hasMySql = AMBuild.cache['hasMySql']
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['MMSOURCE19']
self.mmsPath = AMBuild.cache['MMSOURCE110']
def DefaultCompiler(self):
return self.compiler.Clone()
@ -268,6 +305,10 @@ class SM:
else:
return
def ExtractDebugInfo(self, job, binary):
src = os.path.join('..', AMBuild.outputFolder, job.workFolder, binary.binaryFile)
job.AddCommand(ExtractDebugInfoCommand(binary, src))
def PreSetupHL2Job(self, job, builder, sdk):
info = self.sdkInfo[sdk]
sdkPath = AMBuild.cache[info['sdk']]
@ -277,7 +318,7 @@ class SM:
else:
staticLibs = os.path.join(sdkPath, 'lib', 'linux')
workFolder = os.path.join(AMBuild.outputFolder, job.workFolder)
if sdk in ['ep2v', 'css']:
if sdk in ['css', 'hl2dm', 'dods', 'tf2', 'l4d2']:
libs = ['tier1_i486.a', 'mathlib_i486.a', 'libvstdlib_srv.so', 'libtier0_srv.so']
for lib in libs:
link = os.path.join(workFolder, lib)
@ -286,7 +327,7 @@ class SM:
os.lstat(link)
except:
job.AddCommand(SymlinkCommand(link, target))
elif sdk in ['l4d', 'l4d2', 'csgo']:
elif sdk in ['l4d', 'nd', 'csgo']:
libs = ['tier1_i486.a', 'mathlib_i486.a', 'libvstdlib.so', 'libtier0.so']
if sdk == 'csgo':
libs.append('interfaces_i486.a')
@ -349,7 +390,7 @@ class SM:
# We don't build for Portal 2 (yet?, ever?), but using this define in code as
# it saves trouble if we ever need to
compiler['CDEFINES'].append('SE_PORTAL2=11')
compiler['CDEFINES'].append('SE_PORTAL2=14')
paths = [['public'], ['public', 'engine'], ['public', 'mathlib'], ['public', 'vstdlib'],
['public', 'tier0'], ['public', 'tier1']]
@ -371,7 +412,7 @@ class SM:
if AMBuild.target['platform'] == 'windows':
compiler['CDEFINES'].extend(['COMPILER_MSVC', 'COMPILER_MSVC32'])
else:
compiler['CDEFINES'].extend(['COMPILER_GCC', 'POSIX'])
compiler['CDEFINES'].extend(['COMPILER_GCC'])
if sdk == 'ep1':
if AMBuild.target['platform'] == 'linux':
@ -388,10 +429,10 @@ class SM:
if not noLink:
if AMBuild.target['platform'] == 'linux':
compiler['POSTLINKFLAGS'][0:0] = ['-lm']
if sdk in ['ep2v', 'css']:
if sdk in ['css', 'hl2dm', 'dods', 'tf2', 'l4d2']:
compiler['POSTLINKFLAGS'][0:0] = ['libtier0_srv.so']
compiler['POSTLINKFLAGS'][0:0] = ['libvstdlib_srv.so']
elif sdk in ['l4d', 'l4d2', 'csgo']:
elif sdk in ['l4d', 'nd', 'csgo']:
compiler['POSTLINKFLAGS'][0:0] = ['libtier0.so']
compiler['POSTLINKFLAGS'][0:0] = ['libvstdlib.so']
else:
@ -402,6 +443,22 @@ class SM:
compiler['POSTLINKFLAGS'][0:0] = ['libvstdlib.dylib']
return compiler
def ResolveEnvPath(self, env, defaultDir):
if env in os.environ:
path = os.environ[env]
if os.path.isdir(path):
return path
else:
head = os.getcwd()
oldhead = None
while head != None and head != oldhead:
path = os.path.join(head, defaultDir)
if os.path.isdir(path):
return path
oldhead = head
head, tail = os.path.split(head)
return None
sm = SM()
globals = {
@ -434,6 +491,9 @@ FileList = [
['tools', 'buildbot', 'BreakpadSymbols']
]
if not sm.hasMySql:
FileList.remove(['extensions', 'mysql', 'AMBuilder'])
for parts in FileList:
AMBuild.Include(os.path.join(*parts), globals)

View File

@ -1,5 +1,398 @@
SourceMod Changelog
SourceMod 1.5.1 [2013-09-10]
URL: http://wiki.alliedmods.net/SourceMod_1.5.1_Release_Notes
User Changes:
- Updated gamedata support for TF2.
- Added missing DispatchKeyValue gamedata for HL2 CTF (bug 5114) (peace-maker).
- Fixed translations not being loaded if identifier was not two or three characters (fixes Portuguese) (bug 5888).
- Fixed runoff voting occurring when receiving the exact number of required votes (bug 5890).
- Fixed reserve slot plugin hiding too many slots on Orangebox gamesif SourceTV and/or Replay are present (bug 5499).
- Fixed some crashes in TF2 and unexpected behavior in all games with SDKHook_TakeDamage due to uninitialized var.
- Fixed attempted triggers from gagged users displaying in chat (bug 5918, r=asherkin).
- Fixed errors in Italian translation (Oktober).
- Added Norwegian translation (checkster).
Developer Changes:
- Added CS_UpdateClientModel native to CStrike extension for CS:S and CS:GO (bug 5905) (Drifter).
- Fixed setting weapon param in SDKHook_TakeDamage overwriting attacker instead of setting weapon (bug 5911) (KyleS)
----------------------------------------------------------
SourceMod 1.5.0 [2013-08-25]
URL: http://wiki.alliedmods.net/SourceMod_1.5.0_Release_Notes
User Changes:
- Added support for Counter-Strike: Global Offensive (bug 5299, bug 5579).
- Split CS:S, TF2, DoD:S, HL2:DM, and ND to separate binaries (bug 5370, bug 5813).
- Added support for runoff voting in mapchooser (bug 4218).
- Added option to require Steam validation before granting admin access (bug 4837) (VoiDeD).
- Added localization support for many more core and base plugin messages (bug 5120, bug 5146).
- Added the ability to override RegConsoleCommand-created commands (bug 5199).
- Added support for "fuzzy" (partial) map names in map-related natives and cmds for L4D and later (bug 5599).
- Updated Reserved Slots to use max humans as max count (bug 5444).
- Added support for custom maxitems on radio menus (bug 5371).
- Improved console config editing (bug 5470).
- Increased map name buffer sizes in mapchooser to better account for nested maps (bug 5609) (Peace-Maker).
- Fixed JIT conflicts with SELinux (bug 5581).
- Added logged error when PlayerRunCommand offset lookup fails (bug 5535) (GoD-Tony).
- Fixed double print when sending psay to self (bug 5649) (Peace-Maker).
- Fixed check against uninitialized string in extension loader (bug 5546) (KyleS).
- Fixed possible runtime errors in basetriggers for not-ingame clients (bug 5191) (Peace-Maker).
- Check all possible mapcycle paths on newer orangebox games (bug 5719).
- Fixed ReadMapList not seeing maps in all valve search paths (bug 5715) (VoiDeD).
- Fixed typo in too-many-params native error message (Peace-Maker).
- Fixed various issues in clientprefs (bug 5538) (KyleS).
- Removed debug printout from PerformGravity (bug 5679) (KyleS).
- Fixed broken translating in some plugins and natives (bug 5612) (KyleS).
- Fixed issues with COMMAND_FILTER_NO_BOTS and @bots multi-target.
- Fixed crash in SDKHooks when throwing bad ent type error on logical ent (KyleS).
Developer Changes:
- Added support for CS:GO to the CStrike extension (bug 5299) (Drifter).
- Added support for new protobuf usermessages used in newer games (bug 5579, bug 5588, bug 5590, bug 5633).
- Added latest SDKHooks version as first-party extension.
- Updated SQLite to version 3.7.15.1 (bug 5235).
- Added natives for changing team score and mvp stars on CSS/CSGO (bug 5295) (Drifter).
- Added global pre and post forwards for client chat (bug 5394) (KyleS).
- Added TF2_CanPlayerTeleport forward to the TF2 game extension (bug 5283) (VoiDeD).
- Added GetEntityAddress native (bug 5269) (ProdigySim).
- Added more parameters to PlayerRunCommand forward (bug 5346) (GoD-Tony).
- Added forwards to basecomm plugin (bug 5466) (Drifter).
- Added symbol lookup support to gamedata on Windows (bug 5511) (GoD-Tony).
- Exposed GetLanguageInfo in ITranslator interface (bug 5249) (VoiDeD).
- Increase maximum .sp line length to 4095 characters. (bug 5347) (theY4Kman).
- Improved netprop dump output (bug 5471).
- Added int64 typename to netprop dumps (bug 5655).
- Added GetMaxHumanPlayers native exposing IServerGameClients func (bug 5551).
- Added WeaponIDToAlias native to CStrike extension (bug 5460) (KyleS).
- Fixed OnLibraryAdded/Removed not being called in all plugins (bug 5431).
- Made thread worker processing limits configurable at runtime (bug 5326).
- Added support in TF2 ext for detection of player conds >= 64 (bug 5565).
- Updated button defines in entity_prop_stocks (bug 5564).
- Added GetPlayerResourceEntity to SDKTools to replace old, semi-broken TF2-only version (bug 5491).
- Exposed third parameter of TF2's AddCond in TF2_AddCondition (bug 5641) (FlaminSarge).
- Added GetSteamAccountID function to IPlayerHelpers and native for sp (bug 5548) (KyleS).
- Added ISDKHooks interface with entity listeners (bug 5602) (GoD-Tony).
- Added file upload support to webternet extension.
- Added more alternative names for TFClass_Heavy (bug 5338) (Afronanny).
- Throw error instead of crash when calling SetTeamScore between maps (bug 5718) (KyleS).
- Fixed clients not being marked as in kick queue in some cases (bug 5746) (SystematicMania).
- Made compile.sh set working dir to own dir (bug 5710) (KyleS).
- Added CS_IsValidWeaponID native and validity checks to other natives (bug 5566) (Drifter).
- Numerous code documentation fixups (bug 5720) (Tsunami).
- Fixed cmd listener callback return behavior to match func doc (bug 5882).
Internal Changes:
- Fixed handle misuse in clientprefs plugin (bug 5805) (KyleS).
- Removed call to getchar() in debug build of compiler (bug 5626) (KyleS).
- Fixed instability issues with cloned handles (bug 5245, bug 5240) (KyleS).
- Changed extension unload order to avoid exposing finalization window (bug 5556) (KyleS).
- Call OnPluginEnd before finalizer hooks have run (bug 4519).
- Fixed potential for reading out of library bounds in MemoryUtils::FindPattern.
- Fixed typo in TF2 ext asm.c causing accidental assignment instead of compare.
- Overhauled versioning information (bug 5453).
- Changed from RemoveEdict to using the Kill input for TF2_RemoveWeapon.
- Fixed accidental assignment in each of SDKTools and sp compiler (bug 5745) (KyleS).
- Fixed potential deadlock in HandleSystem::TryAndFreeSomeHandles (bug 5665) (KyleS).
----------------------------------------------------------
SourceMod 1.4.7 [2013-02-06]
URL: http://wiki.alliedmods.net/SourceMod_1.4.7_Release_Notes
User Changes:
- Updated support for latest Source 2009 engine changes (CS:S, DoD:S, TF2, HL2DM).
- Updated gamedata for Left 4 Dead 2, Nuclear Dawn, No More Room in Hell, Zombie Panic Source, CSPromod, GoldenEye Source, Synergy, The Hidden, and PVKII.
- Added system to block malware or illegal plugins (bug 5289).
- Fixed a potential crash when a bad entity index is passed to certain functions (bug 5539) (KyleS).
- Added an error message for when auto plugin configs fail to be created due to write error (bug 5465) (Drifter).
- Fixed an issue where a malformed plugin could cause crashes (bug 5478).
Developer Changes:
- Added new values to the TFCond TF2 conditions enum (bug 5537) (FlaminSarge).
- Updated TFHoliday TF2 holidays enum (bug 5526) (Powerlord).
- Fixed regression in SourceMod 1.3.0 causing GetEntPropEnt, GetEntDataEnt2, and GameRules_GetPropEnt to possibly return stale (incorrect) entity indexes in place of -1.
- Added support for < 32-bit unsigned sign extension to GameRules_GetProp lookup (already in GetEntProp since SM 1.4.0).
- Fixed < 32-bit unsigned sign extension in GetEntProp not being applied for array prop elements (bug 5591).
- Fixed value size auto-detection in GetEntProp and GameRules_GetProp for ep2v's new SPROP_VARINT sendprops.
- Fixed Sort_Random sort type not including first value in array sorting functions (bug 4292) (Peace-Maker).
- Fixed GameRules_SetPropVector writing data to unexpected addresses instead of to the gamerules proxy entity (bug 5592) (ProdigySim).
- Fixed VoteMenuToAll stock adding bots to list (bug 5253 (VoiDeD).
----------------------------------------------------------
SourceMod 1.4.6 [2012-09-04]
URL: http://wiki.alliedmods.net/SourceMod_1.4.6_Release_Notes
User Changes:
- Fixed extraneous errors resulting from a bug in 1.4.5.
----------------------------------------------------------
SourceMod 1.4.5 [2012-09-03]
URL: http://wiki.alliedmods.net/SourceMod_1.4.5_Release_Notes
User Changes:
- Updated support for latest Source 2009 engine changes (CS:S, DoD:S, TF2, HL2DM, GMod).
- Updated Nuclear Dawn, Dino D-Day, and Zombie Panic gamedata.
- Added compatibility for running on Metamod:Source 1.9.0.
- Fixed very minor memory leaks in CStrike extension (bug 5456) (KyleS).
- Fixed crash from plugins accessing netprops too early (bug 5297) (KyleS).
- Fixed crash from plugins trying to access nested datadesc members (bug 5446).
Developer Changes:
- Added new TF2 weapon and custom dmg defines.
- Added new TF2 TFHoliday value (bug 5436) (Powerlord).
- Fixed IClientListener::InterceptClientConnect not being able to properly block connections (bug 5461) (PimpinJuice).
- Fixed PrepSDKCall_SetSignature native not working with symbol names on L4D2 linux (bug 5440).
- Fixed resolution of GetProfilerTime native on non-Windows platforms.
-----------------------------
SourceMod 1.4.4 [2012-07-03]
URL: http://wiki.alliedmods.net/SourceMod_1.4.4_Release_Notes
User Changes:
- Updated support for latest Source 2009 engine changes (CS:S, DoD:S, TF2, HL2DM, GMod).
- Updated Nuclear Dawn gamedata.
- Fixed a crash that could occur when selecting an option on a clientprefs prefab menu (bug 5374).
Developer Changes:
- Added new TF2 weapon and custom dmg defines.
- Added new TF2 TFHoliday value (bug 5364) (Powerlord).
- Updated sample extension to properly fill ninvoke with INativeInvoker ptr (bug 5340) (Afronanny).
-----------------------------
SourceMod 1.4.3 [2012-06-09]
URL: http://wiki.alliedmods.net/SourceMod_1.4.3_Release_Notes
User Changes:
- Updated support for latest OrangeBox engine changes (CS:S, DoD:S, TF2, HL2DM, GMod).
- Made clientprefs attempt to reconnect to the database on map change (bug 4745).
- Log functions now respect sv_logecho (bug 5135).
- Fixed client console vote output (bug 5290, bug 5205) (FlaminSarge).
- Fixed error when reloading dependant plugins using aliased natives (bug 5302).
- Fixed intermittent crash when looking for an invalid signature (bug 5301).
- Fixed possible crash when reloading a plugin with an invalid binary (bug 5288).
- Exposed extensions list to clients (bug 5221) (VoiDeD).
- Fixed intermittent crashes in clientprefs (bug 4660).
- Fixed crash when passing an invalid entity reference to ReferenceToEntity (bug 5330).
- Fixed cstrike extension crash on shutdown (bug 5328).
- Lowered threading API think time to 20ms, making threaded MySQL queries complete faster (bug 4733).
Developer Changes:
- Fixed client serials not being unique on Windows (bug 5285).
- Fixed broken SourceTV detection on L4D1 (bug 5216).
- Fixed Float negation operator (bug 5292).
- Updated TF2 condition defines (bug 5259) (FlaminSarge).
- Adding missing SetMenuNoVoteButton native declaration (bug 4522) (GoD-Tony).
- Fixed erroneous const-qualification of name param of GetAdminUsername (bug 5267).
- Added GetGameTickCount native (bug 5209) (GoD-Tony).
-----------------------------
SourceMod 1.4.2 [2011-04-13]
URL: http://wiki.alliedmods.net/SourceMod_1.4.2_Release_Notes
User Changes:
- Updated support for latest OrangeBox engine changes (CS:S, DoD:S, TF2, HL2DM, GMod).
- Fixed regression in SourceMod 1.4.0 causing SM to cause load errors on The Ship (bug 5216).
- Fixed toggling and player lag issues with sm_drug command (bugs 5217, 5218) (FlaminSarge).
Developer Changes:
- Updated TF2-specific defines and enums (bug 5194).
- Fixed StoreToAddress always writing 32 bits and throwing an error (bug 5248) (ProdigySim).
- Fixed crash with StoreToAddress if memory wasn't writable (bug 5252) (Dr!fter).
- Fixed return value of VoteMenuToAll (bug 5254) (VoiDeD).
- Fixed bug in command lower-casing API guarantee
-----------------------------
SourceMod 1.4.1 [2011-12-07]
URL: http://wiki.alliedmods.net/SourceMod_1.4.1_Release_Notes
User Changes:
- Updated support for latest OrangeBox engine changes (CS:S, DoD:S, TF2, HL2DM, GMod).
- Added gamedata for Adrenaline Gamer 2 and No More Room in Hell.
- Fixed "not connected" error in reserve slots plugin (bug 5158) (ostrel).
- Fixed ff trigger output printing to all in triggerer's language (rather than viewer's language) (bug 5161).
- Fixed typo in one of basebans ban reasons (bug 5188).
- Fixed formatting error in Swedish "Vote Count" phrase (bug 5174).
Developer Changes:
- Fixed sp MaxClients not being updated on map changes after load (bug 5160).
- Removed GLIBC_2.7 dependency from spcomp.
- Increased buffer for sm_rcon command to fit larger responses (bug 5169).
- BaseComm now properly registers a library allowing it to be required by other plugins (bug 5156).
- Fixed TFHoliday enum values (bug 5155).
- Updated TF2_OnIsHolidayActive ret behavior to match doc (bug 5155).
- Added new TF2 deathflag and dmg custom defines (bug 5157).
-----------------------------
SourceMod 1.4.0 [2011-10-28]
URL: http://wiki.alliedmods.net/SourceMod_1.4.0_Release_Notes
User Changes:
- Added support for Max OS X (bug 4392).
- Added support for Bloody Good Time (bug 4780).
- Added support for E.Y.E Divine Cybermancy (bug 5035).
- Added gamedata for Nuclear Dawn.
- Added gamedata for International Online Soccer: Source (bug 5019).
- Added gamedata for Half-Life 2 Capture the Flag (bug 5114).
- Updated mapchooser and other base plugins with Nuclear Dawn specific fixes (bug 5117).
- Fixed ServerLang value not being read properly on startup (bug 4675).
- Added support for aliases in languages.cfg (bug 4858).
- Added output display to sm_rcon command (bug 5018).
- Flood protection bypass access can now be overridden with command name sm_flood_access (bug 4584).
- Added a reset argument to sm cvars command to revset cvar values to default (bug 5043).
- Fixed incorrect language identifiers for Chinese (both Trad. and Simplified) and Brazilian Portuguese not matching cl_language values (bug 5067).
- Added translation support for Bulgarian (bg).
- Fixed incorrect number of slots being hidden for reserve with sm_hideslots on Source 2009 with SourceTV or replay (bug 5094).
- sm_hideslots changes now take effect immediately instead of waiting until a client joins or leaves (bug 5094).
- Fixed sv_visiblemaxplayers getting stuck at previous max clients in some cases with reserves and SourceTV or replay (bug 5094).
- Removed error logging if an optional extension is not found (bug 5112).
- Fixed bots with semicolon in name being unkickable (bug 5120).
- Changed strings in ice-related funcommands to be translatable (bug 4540).
- Changed Bintools extension to use a single build for every engine (bug 4548).
Developer Changes:
- Provided native interface for basecomm (bug 2594).
- Client language detection is too late. (bug 3714) (Tony A. "GoD-Tony").
- Added ServerCommandEx native to execute server command and retrieve output (bug 3873).
- Added ability to update clientprefs cookies values on clients not currently connected (bug 3882) (databomb).
- Added library "matchmaking_ds" support to gamedata lookups (bug 4158).
- Rooted menu handles to callbacks (bug 4353).
- Fixed corner cases with ExplodeString (bug 4629). (Michael "LumiStance").
- Fixed return omission with else-after-return (bug 4852).
- Added OnConditionAdded and OnConditionRemoved forwards to TF2 extension (bug 4851).
- Added new natives and forward to the cstrike extension (bug 4732, bug 4985) (Dr!fter).
- Added WaitingForPlayers forwards to the TF2 extension (bug 4704) (CrimsonGT).
- Updated and added more TF2 condition, weapon, and damagecustom defines (multiple bug#s).
- Fixed TF2_RemoveCondition not always removing conditions (bug 4981).
- Fixed MaxClients not being updated correctly in some places with SourceTV or replay active (bug 4986).
- Fixed some vars not being marked for init on first compile pass (bug 4643).
- Increased symbol name limit to 63 characters (bug 4564) (javalia).
- Fixed crash when dynamic arrays run out of memory (bug 4632).
- Fixed a crash that could happen from looking up out-of-bounds edict or entity indexes (bug 5080).
- Fixed client serials not getting cleared on disconnect (bug 5121).
- Added error on declaring arrays that the compiler is too buggy to handle (bug 4977).
- Removed reliance on gamedata for multiple SDKTools functions in ep2 and later (bug 4899).
- Added InvalidateClient and ReconnectClient natives to SDKTools (bug 4931) (Brian "Afronanny" Simon).
- Added ability to lookup and set values on the gamerules class (bug 4983.
- BaseComm now uses AddCommandListener for chat hooks (bug 4991).
- Fixed shutdown bug in SDKTools (bug 5063).
- Fixed MM-enabled extensions continuing to load after failing MM attach (bug 5042).
- Added GetDistGainFromSoundLevel native to SDKTools (bug 5066) (javalia).
- Added CheckAccess native to check an AdminId's command access (bug 5083).
- Fixed GetEntProp not sign-extending unsigned values less than 32 bits (bug 5105).
- Fixed crashing when calling CreateEntityByName or CreateFakeClient when no map is running (now errors) (bug 5119).
- Fixed erring in kick function (e. bad translation) causing client to become unkickable until disconnect (bug 5120).
- Fixed KickClientEx not immediately kicking client if client was in kick queue (bug 5120).
- Added IsClientSourceTV and IsClientReplay natives (bug 5124).
- Added support for getting and setting individual array elements with Get/Set EntProp functions (bug 4160).
- Added support for threaded query handles to SQL_GetInsertId and SQL_GetAffectedRows (bug 4699) (Nephyrin).
- Added a GetGameRules function to ISDKTools for extensions to easily get the GameRules class pointer (bug 4707).
- Added GetMessageName to IUserMessages (bug 4573) (Zach "theY4Kman" Kanzler)
- Added HintTextMsg to IGameHelpers (bug 4950).
- Added ProcessTargetString simple filter API (bug 4404).
- Moved much functionality from core bins to logic bin (bug 4406, bug 4402).
- Fixed bogus asserts in sp compiler (bug 4486, bug 4487).
- Greatly improved sp compiler performance (~5x overall speedup) (bug 3820, bug 4493, bug 4495).
- Changed entity output detours to use CDetour (bug 4416).
- Enhanced nominations API (bug 4677) (CrimsonGT).
- Added Linux support for profiling natives (bug 4927).
- Added a new ValveCallType that allows for arbitrary |this| parameters, as well as associated features in gamedata and for reading/writing memory (bug 3520) (Downtown1).
- Updated TF2 extension to handle Valve's changes to the "holiday" system (bug 5150).
-----------------------------
SourceMod 1.3.8 [2011-06-23]
URL: http://wiki.alliedmods.net/SourceMod_1.3.8_Release_Notes
User Changes:
- Updated support for latest OrangeBox engine changes (CS:S, DoD:S, TF2, HL2DM, GMod).
- Updated support for various games, including Garry's Mod, Zombie Panic, and Dino D-Day.
- Added gamedata for Eternal Silence.
- Fixed libgcc_s.so.1 load error present on some systems (bug 4876).
- Handle leak notices now print to error log (in addition fatal log) (bug 4929).
- Translator now properly falls back on bad server language (bug 4861).
- Fixed invalid client errors from bad MaxClients value when SourceTV is late-loaded (bug 4881).
- Fixed crash on plugin unload when two commands exist with same name, different casing (bug 4698).
Developer Changes:
- Updated TF2 condition defines (bug 4916).
- Fixed var names and docs for TF2_MakeBleed native (bug 4928).
- Removed compiler double include check (bug 4863).
- Fixed plugin compile errors when using GetEntityClassname (bug 4798).
---------------------------
SourceMod 1.3.7 [2011-04-15]
URL: http://wiki.alliedmods.net/SourceMod_1.3.7_Release_Notes
User Changes:
- Updated support for latest OrangeBox engine changes (CS:S, DoD:S, TF2, HL2DM, GMod).
- Updated support for various games, including Zombie Panic, CS ProMod, Empires, and GoldenEye: Source.
- Added gamedata for Dino D-Day.
- Fix precedence of voice mute flag versus specific client overrides (bug 4826).
- Fix mistaken unhooking of voice hooks (bug 4804).
- Fixed graphical glitches with funcommands effects in L4D1 (bug 3486).
- Fixed bug in nominations that could cause "Unknown command" error (bug 4797).
- Removed tv_enable hook to fix rare max client count issue (bug 4791).
- Added missing unhooking of ClientConnect in PlayerManager (bug 4749).
- Fixed sm_rtv printing "unknown command" (bug 4730).
- Fixed voting crash when client console, chat, and SourceTV are enabled (bug 4676).
- Fixed CDetour crash in TF2 extension when last plugin using forward is unloaded (bug 4713).
Developer Changes:
- SetEntProp now marks edict state as changed (bug 4855).
- Added GetEntityClassname stock (bug 4798).
- Fix compiler hanging when #including a directory (bug 4822).
- Added GetEntityFlags and SetEntityFlags natives for better cross-engine compatibility. (bug 4809).
- Fixed ClientPrefs natives not being marked optional when REQUIRE_EXTENSIONS not defined (bug 4839).
- Changed some instances of LogMessage to LogAction (bug 4649).
- Added some new language natives (bug 4613).
- Fixed SetTeamScore not updating score on client (bug 2736).
- Raised MAXPLAYERS from 64 to 65 (bug 4490).
- Added and updated many TF2-specific defines in tf2.inc and tf2_stocks.inc.
- Fixed TF2_GetPlayerConditionFlags no longer necessarily returning all set flags (bug 4726).
- Fixed profiler flush not clearing, added 'report' and 'clear' (bug 4674).
- Fixed GetPlayerDecalFile crash on L4D and L4D2 (bug 4729).
- Fixed TF2_OnGetHoliday detour no longer firing under all circumstances (bug 4700).
- Added TF2_IsPlayerInDuel native to TF2 extension (bug 4695).
----------------------------
SourceMod 1.3.6 [2010-10-31]

View File

@ -112,9 +112,9 @@
* If set to yes, SourceMod will validate steamid auth strings with the Steam backend before giving out admin access.
* This can prevent malicious users from impersonating admins with stolen Steam apptickets.
* If Steam is down, admins will not be authenticated until Steam comes back up.
* In general, this option should be set to "yes" to increase the security of your server.
* This option increases the security of your server, but is still experimental.
*/
"SteamAuthstringValidation" "yes"
"SteamAuthstringValidation" "no"
/**
* Enables or disables whether SourceMod blocks known or potentially malicious plugins from loading.

View File

@ -7,4 +7,9 @@ run.options.add_option('--enable-debug', action='store_const', const='1', dest='
help='Enable debugging symbols')
run.options.add_option('--enable-optimize', action='store_const', const='1', dest='opt',
help='Enable optimization')
run.options.add_option('--no-mysql', action='store_false', default=True, dest='hasMySql',
help='Disable building MySQL extension')
run.options.add_option('-s', '--sdks', default='all', dest='sdks',
help='Build against specified SDKs; valid args are "all", "present", or '
'comma-delimited list of engine names (default: %default)')
run.Configure(sys.path[0])

View File

@ -123,5 +123,6 @@ for i in SM.sdkInfo:
binary.AddObjectFiles(['libprotobuf.a'])
SM.AutoVersion('core', binary)
SM.ExtractDebugInfo(extension, binary)
binary.SendToJob()

View File

@ -59,13 +59,17 @@ ChatTriggers g_ChatTriggers;
bool g_bSupressSilentFails = false;
ChatTriggers::ChatTriggers() : m_pSayCmd(NULL), m_bWillProcessInPost(false),
m_bTriggerWasSilent(false), m_ReplyTo(SM_REPLY_CONSOLE)
m_ReplyTo(SM_REPLY_CONSOLE)
{
m_PubTrigger = sm_strdup("!");
m_PrivTrigger = sm_strdup("/");
m_PubTriggerSize = 1;
m_PrivTriggerSize = 1;
m_bIsChatTrigger = false;
m_bPluginIgnored = false;
#if SOURCE_ENGINE == SE_EPISODEONE
m_bIsINS = false;
#endif
}
ChatTriggers::~ChatTriggers()
@ -109,6 +113,8 @@ void ChatTriggers::OnSourceModAllInitialized()
{
m_pShouldFloodBlock = g_Forwards.CreateForward("OnClientFloodCheck", ET_Event, 1, NULL, Param_Cell);
m_pDidFloodBlock = g_Forwards.CreateForward("OnClientFloodResult", ET_Event, 2, NULL, Param_Cell, Param_Cell);
m_pOnClientSayCmd = g_Forwards.CreateForward("OnClientSayCommand", ET_Event, 3, NULL, Param_Cell, Param_String, Param_String);
m_pOnClientSayCmd_Post = g_Forwards.CreateForward("OnClientSayCommand_Post", ET_Ignore, 3, NULL, Param_Cell, Param_String, Param_String);
}
void ChatTriggers::OnSourceModAllInitialized_Post()
@ -131,23 +137,62 @@ void ChatTriggers::OnSourceModGameInitialized()
SH_ADD_HOOK_MEMFUNC(ConCommand, Dispatch, m_pSayTeamCmd, this, &ChatTriggers::OnSayCommand_Pre, false);
SH_ADD_HOOK_MEMFUNC(ConCommand, Dispatch, m_pSayTeamCmd, this, &ChatTriggers::OnSayCommand_Post, true);
}
#if SOURCE_ENGINE == SE_EPISODEONE
m_bIsINS = (strcmp(g_SourceMod.GetGameFolderName(), "insurgency") == 0);
if (m_bIsINS)
{
m_pSay2Cmd = FindCommand("say2");
if (m_pSay2Cmd)
{
SH_ADD_HOOK(ConCommand, Dispatch, m_pSay2Cmd, SH_MEMBER(this, &ChatTriggers::OnSayCommand_Pre), false);
SH_ADD_HOOK(ConCommand, Dispatch, m_pSay2Cmd, SH_MEMBER(this, &ChatTriggers::OnSayCommand_Post), true);
}
}
#elif SOURCE_ENGINE == SE_NUCLEARDAWN
m_pSaySquadCmd = FindCommand("say_squad");
if (m_pSaySquadCmd)
{
SH_ADD_HOOK(ConCommand, Dispatch, m_pSaySquadCmd, SH_MEMBER(this, &ChatTriggers::OnSayCommand_Pre), false);
SH_ADD_HOOK(ConCommand, Dispatch, m_pSaySquadCmd, SH_MEMBER(this, &ChatTriggers::OnSayCommand_Post), true);
}
#endif
}
void ChatTriggers::OnSourceModShutdown()
{
if (m_pSayTeamCmd)
{
SH_REMOVE_HOOK_MEMFUNC(ConCommand, Dispatch, m_pSayTeamCmd, this, &ChatTriggers::OnSayCommand_Post, true);
SH_REMOVE_HOOK_MEMFUNC(ConCommand, Dispatch, m_pSayTeamCmd, this, &ChatTriggers::OnSayCommand_Pre, false);
}
if (m_pSayCmd)
{
SH_REMOVE_HOOK_MEMFUNC(ConCommand, Dispatch, m_pSayCmd, this, &ChatTriggers::OnSayCommand_Post, true);
SH_REMOVE_HOOK_MEMFUNC(ConCommand, Dispatch, m_pSayCmd, this, &ChatTriggers::OnSayCommand_Pre, false);
}
if (m_pSayTeamCmd)
{
SH_REMOVE_HOOK(ConCommand, Dispatch, m_pSayTeamCmd, SH_MEMBER(this, &ChatTriggers::OnSayCommand_Post), true);
SH_REMOVE_HOOK(ConCommand, Dispatch, m_pSayTeamCmd, SH_MEMBER(this, &ChatTriggers::OnSayCommand_Pre), false);
}
#if SOURCE_ENGINE == SE_EPISODEONE
if (m_bIsINS && m_pSay2Cmd)
{
SH_REMOVE_HOOK(ConCommand, Dispatch, m_pSay2Cmd, SH_MEMBER(this, &ChatTriggers::OnSayCommand_Pre), false);
SH_REMOVE_HOOK(ConCommand, Dispatch, m_pSay2Cmd, SH_MEMBER(this, &ChatTriggers::OnSayCommand_Post), true);
}
#elif SOURCE_ENGINE == SE_NUCLEARDAWN
if (m_pSaySquadCmd)
{
SH_REMOVE_HOOK(ConCommand, Dispatch, m_pSaySquadCmd, SH_MEMBER(this, &ChatTriggers::OnSayCommand_Pre), false);
SH_REMOVE_HOOK(ConCommand, Dispatch, m_pSaySquadCmd, SH_MEMBER(this, &ChatTriggers::OnSayCommand_Post), true);
}
#endif
g_Forwards.ReleaseForward(m_pShouldFloodBlock);
g_Forwards.ReleaseForward(m_pDidFloodBlock);
g_Forwards.ReleaseForward(m_pOnClientSayCmd);
g_Forwards.ReleaseForward(m_pOnClientSayCmd_Post);
}
#if SOURCE_ENGINE >= SE_ORANGEBOX
@ -158,24 +203,10 @@ void ChatTriggers::OnSayCommand_Pre()
{
CCommand command;
#endif
int client;
CPlayer *pPlayer;
client = g_ConCmds.GetCommandClient();
int client = g_ConCmds.GetCommandClient();
m_bIsChatTrigger = false;
m_bWasFloodedMessage = false;
/* The server console cannot do this */
if (client == 0 || (pPlayer = g_Players.GetPlayerByIndex(client)) == NULL)
{
RETURN_META(MRES_IGNORED);
}
/* We guarantee the client is connected */
if (!pPlayer->IsConnected())
{
RETURN_META(MRES_IGNORED);
}
m_bPluginIgnored = false;
const char *args = command.ArgS();
@ -184,6 +215,31 @@ void ChatTriggers::OnSayCommand_Pre()
RETURN_META(MRES_IGNORED);
}
/* Save these off for post hook as the command data returned from the engine in older engine versions
* can be NULL, despite the data still being there and valid. */
m_Arg0Backup = command.Arg(0);
m_ArgSBackup = command.ArgS();
/* The server console cannot do this */
if (client == 0)
{
cell_t res = CallOnClientSayCommand(client);
if (res >= Pl_Handled)
{
m_bPluginIgnored = (res >= Pl_Stop);
RETURN_META(MRES_SUPERCEDE);
}
RETURN_META(MRES_IGNORED);
}
CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
/* We guarantee the client is connected */
if (!pPlayer || !pPlayer->IsConnected())
{
RETURN_META(MRES_IGNORED);
}
/* Check if we need to block this message from being sent */
if (ClientIsFlooding(client))
{
@ -211,6 +267,13 @@ void ChatTriggers::OnSayCommand_Pre()
is_quoted = true;
}
#if SOURCE_ENGINE == SE_EPISODEONE
if (m_bIsINS && strcmp(m_Arg0Backup, "say2") == 0 && strlen(args) >= 4)
{
args += 4;
}
#endif
bool is_trigger = false;
bool is_silent = false;
@ -227,38 +290,28 @@ void ChatTriggers::OnSayCommand_Pre()
args = &args[m_PrivTriggerSize];
}
if (!is_trigger)
{
RETURN_META(MRES_IGNORED);
}
/**
* Test if this is actually a command!
*/
if (!PreProcessTrigger(PEntityOfEntIndex(client), args, is_quoted))
if (is_trigger && PreProcessTrigger(PEntityOfEntIndex(client), args, is_quoted))
{
CPlayer *pPlayer;
if (is_silent
&& g_bSupressSilentFails
&& client != 0
&& (pPlayer = g_Players.GetPlayerByIndex(client)) != NULL
&& pPlayer->GetAdminId() != INVALID_ADMIN_ID)
{
RETURN_META(MRES_SUPERCEDE);
}
RETURN_META(MRES_IGNORED);
m_bIsChatTrigger = true;
/**
* We'll execute it in post.
*/
m_bWillProcessInPost = true;
}
m_bIsChatTrigger = true;
cell_t res = CallOnClientSayCommand(client);
/**
* We'll execute it in post.
*/
m_bWillProcessInPost = true;
m_bTriggerWasSilent = is_silent;
if (res >= Pl_Handled)
{
m_bPluginIgnored = (res >= Pl_Stop);
RETURN_META(MRES_SUPERCEDE);
}
/* If we're silent, block */
if (is_silent)
if (is_silent && (m_bIsChatTrigger || (g_bSupressSilentFails && pPlayer->GetAdminId() != INVALID_ADMIN_ID)))
{
RETURN_META(MRES_SUPERCEDE);
}
@ -273,19 +326,33 @@ void ChatTriggers::OnSayCommand_Post(const CCommand &command)
void ChatTriggers::OnSayCommand_Post()
#endif
{
m_bIsChatTrigger = false;
m_bWasFloodedMessage = false;
int client = g_ConCmds.GetCommandClient();
if (m_bWillProcessInPost)
{
/* Reset this for re-entrancy */
m_bWillProcessInPost = false;
/* Execute the cached command */
int client = g_ConCmds.GetCommandClient();
unsigned int old = SetReplyTo(SM_REPLY_CHAT);
serverpluginhelpers->ClientCommand(PEntityOfEntIndex(client), m_ToExecute);
SetReplyTo(old);
}
if (m_bPluginIgnored)
{
m_bPluginIgnored = false;
}
else if (!m_bWasFloodedMessage && !m_bIsChatTrigger && m_pOnClientSayCmd_Post->GetFunctionCount() != 0)
{
m_pOnClientSayCmd_Post->PushCell(client);
m_pOnClientSayCmd_Post->PushString(m_Arg0Backup);
m_pOnClientSayCmd_Post->PushString(m_ArgSBackup);
m_pOnClientSayCmd_Post->Execute(NULL);
}
m_bIsChatTrigger = false;
m_bWasFloodedMessage = false;
}
bool ChatTriggers::PreProcessTrigger(edict_t *pEdict, const char *args, bool is_quoted)
@ -362,6 +429,19 @@ bool ChatTriggers::PreProcessTrigger(edict_t *pEdict, const char *args, bool is_
return true;
}
cell_t ChatTriggers::CallOnClientSayCommand(int client)
{
cell_t res = Pl_Continue;
if (!m_bIsChatTrigger && m_pOnClientSayCmd->GetFunctionCount() != 0)
{
m_pOnClientSayCmd->PushCell(client);
m_pOnClientSayCmd->PushString(m_Arg0Backup);
m_pOnClientSayCmd->PushString(m_ArgSBackup);
m_pOnClientSayCmd->Execute(&res);
}
return res;
}
unsigned int ChatTriggers::SetReplyTo(unsigned int reply)
{
unsigned int old = m_ReplyTo;

View File

@ -69,21 +69,34 @@ public:
private:
bool PreProcessTrigger(edict_t *pEdict, const char *args, bool is_quoted);
bool ClientIsFlooding(int client);
cell_t CallOnClientSayCommand(int client);
private:
ConCommand *m_pSayCmd;
ConCommand *m_pSayTeamCmd;
#if SOURCE_ENGINE == SE_EPISODEONE
ConCommand *m_pSay2Cmd;
#elif SOURCE_ENGINE == SE_NUCLEARDAWN
ConCommand *m_pSaySquadCmd;
#endif
char *m_PubTrigger;
size_t m_PubTriggerSize;
char *m_PrivTrigger;
size_t m_PrivTriggerSize;
bool m_bWillProcessInPost;
bool m_bTriggerWasSilent;
bool m_bIsChatTrigger;
bool m_bWasFloodedMessage;
bool m_bPluginIgnored;
unsigned int m_ReplyTo;
char m_ToExecute[300];
const char *m_Arg0Backup;
const char *m_ArgSBackup;
IForward *m_pShouldFloodBlock;
IForward *m_pDidFloodBlock;
IForward *m_pOnClientSayCmd;
IForward *m_pOnClientSayCmd_Post;
#if SOURCE_ENGINE == SE_EPISODEONE
bool m_bIsINS;
#endif
};
extern ChatTriggers g_ChatTriggers;

View File

@ -688,7 +688,7 @@ cell_t ConsoleDetours::InternalDispatch(int client, const CCommand& args)
if (strcmp(name, "sm") == 0)
result = Pl_Continue;
if (result >= Pl_Stop)
if (result >= Pl_Handled)
return result;
Listener **plistener = m_CmdLookup.retrieve(name);

View File

@ -66,6 +66,8 @@ CRemoteExtension::CRemoteExtension(IExtensionInterface *pAPI, const char *filena
#define GAMEFIX "2.l4d"
#elif SOURCE_ENGINE == SE_LEFT4DEAD2
#define GAMEFIX "2.l4d2"
#elif SOURCE_ENGINE == SE_NUCLEARDAWN
#define GAMEFIX "2.nd"
#elif SOURCE_ENGINE == SE_ALIENSWARM
#define GAMEFIX "2.swarm"
#elif SOURCE_ENGINE == SE_ORANGEBOX
@ -76,8 +78,12 @@ CRemoteExtension::CRemoteExtension(IExtensionInterface *pAPI, const char *filena
#define GAMEFIX "2.eye"
#elif SOURCE_ENGINE == SE_CSS
#define GAMEFIX "2.css"
#elif SOURCE_ENGINE == SE_ORANGEBOXVALVE
#define GAMEFIX "2.ep2v"
#elif SOURCE_ENGINE == SE_HL2DM
#define GAMEFIX "2.hl2dm"
#elif SOURCE_ENGINE == SE_DODS
#define GAMEFIX "2.dods"
#elif SOURCE_ENGINE == SE_TF2
#define GAMEFIX "2.tf2"
#elif SOURCE_ENGINE == SE_DARKMESSIAH
#define GAMEFIX "2.darkm"
#elif SOURCE_ENGINE == SE_PORTAL2
@ -116,6 +122,31 @@ CLocalExtension::CLocalExtension(const char *filename)
goto found;
}
#if SOURCE_ENGINE == SE_TF2 || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_HL2DM
/* COMPAT HACK: One-halfth, if ep2v, see if there is an engine specific build in the new place with old naming */
g_SourceMod.BuildPath(Path_SM,
path,
PLATFORM_MAX_PATH,
"extensions/%s.2.ep2v." PLATFORM_LIB_EXT,
filename);
if (g_LibSys.IsPathFile(path))
{
goto found;
}
#elif SOURCE_ENGINE == SE_NUCLEARDAWN
g_SourceMod.BuildPath(Path_SM,
path,
PLATFORM_MAX_PATH,
"extensions/%s.2.l4d2." PLATFORM_LIB_EXT,
filename);
if (g_LibSys.IsPathFile(path))
{
goto found;
}
#endif
/* First see if there is an engine specific build! */
g_SourceMod.BuildPath(Path_SM,
path,
@ -123,10 +154,10 @@ CLocalExtension::CLocalExtension(const char *filename)
"extensions/auto." GAMEFIX "/%s." PLATFORM_LIB_EXT,
filename);
normal:
/* Try the "normal" version */
if (!g_LibSys.IsPathFile(path))
{
normal:
g_SourceMod.BuildPath(Path_SM,
path,
PLATFORM_MAX_PATH,
@ -805,6 +836,13 @@ bool CExtensionManager::UnloadExtension(IExtension *_pExt)
return false;
}
/* Tell it to unload */
if (pExt->IsLoaded())
{
IExtensionInterface *pAPI = pExt->GetAPI();
pAPI->OnExtensionUnload();
}
/* First remove us from internal lists */
g_ShareSys.RemoveInterfaces(_pExt);
m_Libs.remove(pExt);
@ -899,13 +937,6 @@ bool CExtensionManager::UnloadExtension(IExtension *_pExt)
}
}
/* Tell it to unload */
if (pExt->IsLoaded())
{
IExtensionInterface *pAPI = pExt->GetAPI();
pAPI->OnExtensionUnload();
}
pExt->Unload();
delete pExt;

View File

@ -56,7 +56,7 @@ typedef ICommandLine *(*FakeGetCommandLine)();
#define TIER0_NAME "libtier0.dylib"
#define VSTDLIB_NAME "libvstdlib.dylib"
#elif defined __linux__
#if SOURCE_ENGINE == SE_ORANGEBOXVALVE || SOURCE_ENGINE == SE_CSS
#if SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_TF2 || SOURCE_ENGINE == SE_LEFT4DEAD2
#define TIER0_NAME "libtier0_srv.so"
#define VSTDLIB_NAME "libvstdlib_srv.so"
#elif SOURCE_ENGINE >= SE_LEFT4DEAD
@ -337,8 +337,13 @@ bool UTIL_FindInSendTable(SendTable *pTable,
return false;
}
typedescription_t *UTIL_FindInDataMap(datamap_t *pMap, const char *name)
typedescription_t *UTIL_FindInDataMap(datamap_t *pMap, const char *name, bool *isNested)
{
if (isNested)
{
*isNested = false;
}
while (pMap)
{
for (int i=0; i<pMap->dataNumFields; i++)
@ -353,10 +358,21 @@ typedescription_t *UTIL_FindInDataMap(datamap_t *pMap, const char *name)
}
if (pMap->dataDesc[i].td)
{
typedescription_t *_td;
if ((_td=UTIL_FindInDataMap(pMap->dataDesc[i].td, name)) != NULL)
if (isNested)
{
return _td;
*isNested = (UTIL_FindInDataMap(pMap->dataDesc[i].td, name, NULL) != NULL);
if (*isNested)
{
return NULL;
} else {
continue;
}
} else { // Use the old behaviour, we dont want to spring this on extensions - even if they're doing bad things.
typedescription_t *_td;
if ((_td=UTIL_FindInDataMap(pMap->dataDesc[i].td, name, NULL)) != NULL)
{
return _td;
}
}
}
}
@ -449,6 +465,11 @@ SendProp *CHalfLife2::FindInSendTable(const char *classname, const char *offset)
}
typedescription_t *CHalfLife2::FindInDataMap(datamap_t *pMap, const char *offset)
{
return this->FindInDataMap(pMap, offset, NULL);
}
typedescription_t *CHalfLife2::FindInDataMap(datamap_t *pMap, const char *offset, bool *isNested)
{
typedescription_t *td = NULL;
DataMapTrie &val = m_Maps[pMap];
@ -459,7 +480,7 @@ typedescription_t *CHalfLife2::FindInDataMap(datamap_t *pMap, const char *offset
}
if (!sm_trie_retrieve(val.trie, offset, (void **)&td))
{
if ((td = UTIL_FindInDataMap(pMap, offset)) != NULL)
if ((td = UTIL_FindInDataMap(pMap, offset, isNested)) != NULL)
{
sm_trie_insert(val.trie, offset, td);
}
@ -810,6 +831,14 @@ const char *CHalfLife2::CurrentCommandName()
void CHalfLife2::AddDelayedKick(int client, int userid, const char *msg)
{
CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
if (!pPlayer || !pPlayer->IsConnected() || pPlayer->IsInKickQueue())
{
return;
}
pPlayer->MarkAsBeingKicked();
DelayedKickInfo kick;
kick.client = client;
@ -1131,3 +1160,47 @@ const char *CHalfLife2::GetEntityClassname(CBaseEntity *pEntity)
return *(const char **)(((unsigned char *)pEntity) + offset);
}
#if SOURCE_ENGINE >= SE_LEFT4DEAD
static bool ResolveFuzzyMapName(const char *fuzzyName, char *outFullname, int size)
{
static ConCommand *pHelperCmd = g_pCVar->FindCommand("changelevel");
if (!pHelperCmd || !pHelperCmd->CanAutoComplete())
return false;
static size_t helperCmdLen = strlen(pHelperCmd->GetName());
CUtlVector<CUtlString> results;
pHelperCmd->AutoCompleteSuggest(fuzzyName, results);
if (results.Count() == 0)
return false;
// Results come back as you'd see in autocomplete. (ie. "changelevel fullmapnamehere"),
// so skip ahead to start of map path/name
// Like the engine, we're only going to deal with the first match.
strncopy(outFullname, &results[0][helperCmdLen + 1], size);
return true;
}
#endif
bool CHalfLife2::IsMapValid(const char *map)
{
if (!map || !map[0])
return false;
bool ret = engine->IsMapValid(map);
#if SOURCE_ENGINE >= SE_LEFT4DEAD
if (!ret)
{
static char szFuzzyName[PLATFORM_MAX_PATH];
if (ResolveFuzzyMapName(map, szFuzzyName, sizeof(szFuzzyName)))
{
ret = engine->IsMapValid(szFuzzyName);
}
}
#endif
return ret;
}

View File

@ -123,6 +123,7 @@ public: //IGameHelpers
datamap_t *GetDataMap(CBaseEntity *pEntity);
ServerClass *FindServerClass(const char *classname);
typedescription_t *FindInDataMap(datamap_t *pMap, const char *offset);
typedescription_t *FindInDataMap(datamap_t *pMap, const char *offset, bool *isNested);
void SetEdictStateChanged(edict_t *pEdict, unsigned short offset);
bool TextMsg(int client, int dest, const char *msg);
bool HintTextMsg(int client, const char *msg);
@ -148,6 +149,7 @@ public: //IGameHelpers
ICommandLine *GetValveCommandLine();
const char *GetEntityClassname(edict_t *pEdict);
const char *GetEntityClassname(CBaseEntity *pEntity);
bool IsMapValid(const char *map);
public:
void AddToFakeCliCmdQueue(int client, int userid, const char *cmd);
void ProcessFakeCliCmdQueue();

View File

@ -579,6 +579,7 @@ HandleError HandleSystem::CloneHandle(QHandle *pHandle, unsigned int index, Hand
}
pNewHandle->clone = index;
pNewHandle->object = NULL;
pHandle->refcount++;
*newhandle = new_handle;
@ -659,6 +660,14 @@ void HandleSystem::GetHandleUnchecked(Handle_t hndl, QHandle *& pHandle, unsigne
HandleError HandleSystem::FreeHandle(QHandle *pHandle, unsigned int index)
{
if (pHandle->is_destroying)
{
/* Someone tried to free this recursively.
* We'll just ignore this safely.
*/
return HandleError_None;
}
QHandleType *pType = &m_Types[pHandle->type];
if (pHandle->clone)
@ -673,6 +682,7 @@ HandleError HandleSystem::FreeHandle(QHandle *pHandle, unsigned int index)
pMaster = &m_Handles[master];
/* Release the clone now */
pHandle->is_destroying = true;
ReleasePrimHandle(index);
/* Decrement the master's reference count */
@ -681,20 +691,27 @@ HandleError HandleSystem::FreeHandle(QHandle *pHandle, unsigned int index)
/* Type should be the same but do this anyway... */
pType = &m_Types[pMaster->type];
pMaster->is_destroying = true;
pType->dispatch->OnHandleDestroy(pMaster->type, pMaster->object);
if (pMaster->object)
{
pType->dispatch->OnHandleDestroy(pMaster->type, pMaster->object);
}
ReleasePrimHandle(master);
}
} else if (pHandle->set == HandleSet_Identity) {
/* If we're an identity, skip all this stuff!
* NOTE: SHARESYS DOES NOT CARE ABOUT THE DESTRUCTOR
*/
pHandle->is_destroying = true;
ReleasePrimHandle(index);
} else {
/* Decrement, free if necessary */
if (--pHandle->refcount == 0)
{
pHandle->is_destroying = true;
pType->dispatch->OnHandleDestroy(pHandle->type, pHandle->object);
if (pHandle->object)
{
pType->dispatch->OnHandleDestroy(pHandle->type, pHandle->object);
}
ReleasePrimHandle(index);
} else {
/* We must be cloned, so mark ourselves as freed */
@ -727,14 +744,6 @@ HandleError HandleSystem::FreeHandle(Handle_t handle, const HandleSecurity *pSec
return HandleError_Access;
}
if (pHandle->is_destroying)
{
/* Someone tried to free this recursively.
* We'll just ignore this safely.
*/
return HandleError_None;
}
return FreeHandle(pHandle, index);
}
@ -793,6 +802,9 @@ void HandleSystem::UnlinkHandleFromOwner(QHandle *pHandle, unsigned int index)
assert(pHandle->owner == 0);
return;
}
pHandle->owner = NULL;
/* Note that since 0 is an invalid handle, if any of these links are 0,
* the data can still be set.
*/
@ -917,29 +929,9 @@ bool HandleSystem::RemoveType(HandleType_t type, IdentityToken_t *ident)
{
continue;
}
if (pHandle->clone)
{
/* Get parent */
QHandle *pOther = &m_Handles[pHandle->clone];
if (--pOther->refcount == 0)
{
/* Free! */
dispatch->OnHandleDestroy(type, pOther->object);
ReleasePrimHandle(pHandle->clone);
}
/* Unlink ourselves since we don't have a reference count */
ReleasePrimHandle(i);
} else {
/* If it's not a clone, we still have to check the reference count.
* Either way, we'll be destroyed eventually because the handle types do not change.
*/
if (--pHandle->refcount == 0)
{
/* Free! */
dispatch->OnHandleDestroy(type, pHandle->object);
ReleasePrimHandle(i);
}
}
FreeHandle(pHandle, i);
if (pType->opened == 0)
{
break;
@ -993,12 +985,11 @@ bool HandleSystem::InitAccessDefaults(TypeAccess *pTypeAccess, HandleAccess *pHa
bool HandleSystem::TryAndFreeSomeHandles()
{
IPluginIterator *pl_iter = g_PluginSys.GetPluginIterator();
IPlugin *highest_owner = NULL;
unsigned int highest_handle_count = 0;
/* Search all plugins */
while (pl_iter->MorePlugins())
for (IPluginIterator *pl_iter = g_PluginSys.GetPluginIterator(); pl_iter->MorePlugins(); pl_iter->NextPlugin())
{
IPlugin *plugin = pl_iter->GetPlugin();
IdentityToken_t *identity = plugin->GetIdentity();
@ -1027,8 +1018,6 @@ bool HandleSystem::TryAndFreeSomeHandles()
highest_owner = plugin;
highest_handle_count = handle_count;
}
pl_iter->NextPlugin();
}
if (highest_owner == NULL || highest_handle_count == 0)
@ -1095,12 +1084,32 @@ void HandleSystem::Dump(HANDLE_REPORTER rep)
const char *type = "ANON";
QHandleType *pType = &m_Types[m_Handles[i].type];
unsigned int size = 0;
unsigned int parentIdx;
bool bresult;
if (pType->nameIdx != -1)
{
type = m_strtab->GetString(pType->nameIdx);
}
if ((parentIdx = m_Handles[i].clone) != 0)
{
if (m_Handles[parentIdx].refcount > 0)
{
size = 0;
bresult = true;
}
else
{
bresult = pType->dispatch->GetHandleApproxSize(m_Handles[parentIdx].type, m_Handles[parentIdx].object, &size);
}
}
else
{
bresult = pType->dispatch->GetHandleApproxSize(m_Handles[i].type, m_Handles[i].object, &size);
}
if (pType->dispatch->GetDispatchVersion() < HANDLESYS_MEMUSAGE_MIN_VERSION
|| !pType->dispatch->GetHandleApproxSize(m_Handles[i].type, m_Handles[i].object, &size))
|| !bresult)
{
rep("0x%08x\t%-20.20s\t%-20.20s\t%-10.10s", index, owner, type, "-1");
}

View File

@ -337,7 +337,7 @@ void BaseMenuStyle::ClientPressedKey(int client, unsigned int key_press)
#endif
0,
PITCH_NORM,
#if SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_ORANGEBOXVALVE
#if SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_TF2
0,
#endif
&pos);

View File

@ -31,6 +31,7 @@
#include "NextMap.h"
#include "Logger.h"
#include "HalfLife2.h"
#include "sourcemm_api.h"
#include "sm_stringutil.h"
#include "sourcehook.h"
@ -109,7 +110,7 @@ const char *NextMapManager::GetNextMap()
bool NextMapManager::SetNextMap(const char *map)
{
if (!engine->IsMapValid(map))
if (!g_HL2.IsMapValid(map))
{
return false;
}
@ -133,7 +134,7 @@ void NextMapManager::HookChangeLevel(const char *map, const char *unknown, const
const char *newmap = sm_nextmap.GetString();
if (newmap[0] == 0 || !engine->IsMapValid(newmap))
if (newmap[0] == 0 || !g_HL2.IsMapValid(newmap))
{
RETURN_META(MRES_IGNORED);
}

View File

@ -116,7 +116,7 @@ PlayerManager::PlayerManager()
m_SourceTVUserId = -1;
m_ReplayUserId = -1;
m_bUseSteamAdminAuth = true; // use steam auth by default
m_bAuthstringValidation = false; // don't use steam auth by default... yet
m_UserIdLookUp = new int[USHRT_MAX+1];
memset(m_UserIdLookUp, 0, sizeof(int) * (USHRT_MAX+1));
@ -234,9 +234,9 @@ ConfigResult PlayerManager::OnSourceModConfigChanged(const char *key,
} else if (strcmp( key, "SteamAuthstringValidation" ) == 0) {
if (strcasecmp(value, "yes") == 0)
{
m_bUseSteamAdminAuth = true;
m_bAuthstringValidation = true;
} else if ( strcasecmp(value, "no") == 0) {
m_bUseSteamAdminAuth = false;
m_bAuthstringValidation = false;
} else {
UTIL_Format(error, maxlength, "Invalid value: must be \"yes\" or \"no\"");
return ConfigResult_Reject;
@ -249,7 +249,7 @@ ConfigResult PlayerManager::OnSourceModConfigChanged(const char *key,
void PlayerManager::OnServerActivate(edict_t *pEdictList, int edictCount, int clientMax)
{
static ConVar *tv_enable = icvar->FindVar("tv_enable");
#if SOURCE_ENGINE == SE_ORANGEBOXVALVE
#if SOURCE_ENGINE == SE_TF2
static ConVar *replay_enable = icvar->FindVar("replay_enable");
#endif
@ -259,7 +259,7 @@ void PlayerManager::OnServerActivate(edict_t *pEdictList, int edictCount, int cl
ICommandLine *commandLine = g_HL2.GetValveCommandLine();
m_bIsSourceTVActive = (tv_enable && tv_enable->GetBool() && (!commandLine || commandLine->FindParm("-nohltv") == 0));
m_bIsReplayActive = false;
#if SOURCE_ENGINE == SE_ORANGEBOXVALVE
#if SOURCE_ENGINE == SE_TF2
m_bIsReplayActive = (replay_enable && replay_enable->GetBool());
#endif
m_PlayersSinceActive = 0;
@ -367,23 +367,18 @@ void PlayerManager::RunAuthChecks()
{
pPlayer = &m_Players[m_AuthQueue[i]];
authstr = engine->GetPlayerNetworkIDString(pPlayer->m_pEdict);
pPlayer->SetAuthString(authstr);
#if SOURCE_ENGINE >= SE_ORANGEBOX
// we can only easily check if the client is fully authed if we're on a recent engine
if (m_bUseSteamAdminAuth && !g_HL2.IsLANServer())
if (!pPlayer->IsAuthStringValidated())
{
if (!pPlayer->IsAuthedBySteam())
{
continue; // we're using steam auth, and steam doesn't know about this player yet so we can't do anything about them for now
}
continue; // we're using steam auth, and steam doesn't know about this player yet so we can't do anything about them for now
}
#endif
if (authstr && authstr[0] != '\0'
&& (strcmp(authstr, "STEAM_ID_PENDING") != 0))
{
/* Set authorization */
pPlayer->Authorize(authstr);
pPlayer->Authorize();
/* Mark as removed from queue */
unsigned int client = m_AuthQueue[i];
@ -558,7 +553,8 @@ void PlayerManager::OnClientPutInServer(edict_t *pEntity, const char *playername
/* Run manual connection routines */
char error[255];
const char *authid = engine->GetPlayerNetworkIDString(pEntity);
pPlayer->Authorize(authid);
pPlayer->SetAuthString(authid);
pPlayer->Authorize();
pPlayer->m_bFakeClient = true;
/*
@ -584,17 +580,14 @@ void PlayerManager::OnClientPutInServer(edict_t *pEntity, const char *playername
int newCount = m_PlayersSinceActive + 1;
int userId = engine->GetPlayerUserId(pEntity);
#if (SOURCE_ENGINE == SE_ORANGEBOXVALVE || SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_LEFT4DEAD2)
#if (SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_TF2 || SOURCE_ENGINE == SE_NUCLEARDAWN || SOURCE_ENGINE == SE_LEFT4DEAD2)
static ConVar *tv_name = icvar->FindVar("tv_name");
#endif
#if SOURCE_ENGINE == SE_ORANGEBOXVALVE
#if SOURCE_ENGINE == SE_TF2
static ConVar *replay_name = icvar->FindVar("replay_name");
#endif
#if SOURCE_ENGINE == SE_LEFT4DEAD2
static bool bIsNuclearDawn = (strcmp(g_SourceMod.GetGameFolderName(), "nucleardawn") == 0);
#endif
#if SOURCE_ENGINE == SE_ORANGEBOXVALVE
#if SOURCE_ENGINE == SE_TF2
if (m_bIsReplayActive && newCount == 1
&& (m_ReplayUserId == userId
|| (replay_name && strcmp(playername, replay_name->GetString()) == 0) || (replay_name && replay_name->GetString()[0] == 0 && strcmp(playername, "unnamed") == 0)
@ -612,15 +605,8 @@ void PlayerManager::OnClientPutInServer(edict_t *pEntity, const char *playername
&& (m_SourceTVUserId == userId
#if SOURCE_ENGINE == SE_CSGO
|| strcmp(playername, "GOTV") == 0
#elif (SOURCE_ENGINE == SE_ORANGEBOXVALVE || SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_LEFT4DEAD2)
#if SOURCE_ENGINE == SE_LEFT4DEAD2
|| (bIsNuclearDawn && ( true
#endif // SE_LEFT4DEAD2
#elif (SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_TF2 || SOURCE_ENGINE == SE_NUCLEARDAWN)
|| (tv_name && strcmp(playername, tv_name->GetString()) == 0) || (tv_name && tv_name->GetString()[0] == 0 && strcmp(playername, "unnamed") == 0)
#if SOURCE_ENGINE == SE_LEFT4DEAD2
))
|| (!bIsNuclearDawn && strcmp(playername, "SourceTV") == 0)
#endif // SE_LEFT4DEAD2
#else
|| strcmp(playername, "SourceTV") == 0
#endif
@ -927,8 +913,7 @@ void PlayerManager::OnClientSettingsChanged(edict_t *pEntity)
const char *networkid_force;
if ((networkid_force = engine->GetClientConVarValue(client, "networkid_force")) && networkid_force[0] != '\0')
{
unsigned long long *steamId = (unsigned long long *)engine->GetClientSteamID(pEntity);
unsigned int accountId = steamId ? (*steamId & 0xFFFFFFFF) : 0;
unsigned int accountId = pPlayer->GetSteamAccountID();
g_Logger.LogMessage("\"%s<%d><STEAM_1:%d:%d><>\" has bad networkid (id \"%s\") (ip \"%s\")",
new_name, pPlayer->GetUserId(), accountId & 1, accountId >> 1, networkid_force, pPlayer->GetIPAddress());
@ -944,7 +929,9 @@ void PlayerManager::OnClientSettingsChanged(edict_t *pEntity)
{
if (!CheckSetAdminName(client, pPlayer, id))
{
pPlayer->Kick("Your name is reserved by SourceMod; set your password to use it.");
char kickMsg[128];
logicore.CoreTranslate(kickMsg, sizeof(kickMsg), "%T", 2, NULL, "Name Reserved", &client);
pPlayer->Kick(kickMsg);
RETURN_META(MRES_IGNORED);
}
} else if ((id = g_Admins.FindAdminByIdentity("name", old_name)) != INVALID_ADMIN_ID) {
@ -1272,11 +1259,12 @@ void PlayerManager::ProcessCommandTarget(cmd_target_info_t *info)
{
continue;
}
if (!pTarget->IsConnected() || !pTarget->IsAuthorized())
if (!pTarget->IsConnected())
{
continue;
}
if (strcmp(pTarget->GetAuthString(), new_pattern) == 0)
const char *authstr = pTarget->GetAuthString(false); // We want to make it easy for people to be kicked/banned, so don't require validation for command targets.
if (authstr && strcmp(authstr, new_pattern) == 0)
{
if ((info->reason = FilterCommandTarget(pAdmin, pTarget, info->flags))
== COMMAND_TARGET_VALID)
@ -1386,7 +1374,7 @@ void PlayerManager::ProcessCommandTarget(cmd_target_info_t *info)
if ((info->flags & COMMAND_FILTER_NO_BOTS) == COMMAND_FILTER_NO_BOTS)
{
info->num_targets = 0;
info->reason = COMMAND_FILTER_NO_BOTS;
info->reason = COMMAND_TARGET_NOT_HUMAN;
return;
}
strncopy(info->target_name, "all bots", info->target_name_maxlength);
@ -1589,6 +1577,7 @@ CPlayer::CPlayer()
m_bIsSourceTV = false;
m_bIsReplay = false;
m_Serial.value = -1;
m_SteamAccountID = 0;
}
void CPlayer::Initialize(const char *name, const char *ip, edict_t *pEntity)
@ -1634,17 +1623,22 @@ void CPlayer::Connect()
}
}
void CPlayer::Authorize(const char *steamid)
void CPlayer::SetAuthString(const char *steamid)
{
if (m_IsAuthorized)
{
return;
}
m_IsAuthorized = true;
m_AuthID.assign(steamid);
}
// Ensure a valid AuthString is set before calling.
void CPlayer::Authorize()
{
m_IsAuthorized = true;
}
void CPlayer::Disconnect()
{
DumpAdmin(false);
@ -1663,6 +1657,7 @@ void CPlayer::Disconnect()
m_bIsSourceTV = false;
m_bIsReplay = false;
m_Serial.value = -1;
m_SteamAccountID = 0;
}
void CPlayer::SetName(const char *name)
@ -1685,11 +1680,45 @@ const char *CPlayer::GetIPAddress()
return m_Ip.c_str();
}
const char *CPlayer::GetAuthString()
const char *CPlayer::GetAuthString(bool validated)
{
if (validated && !IsAuthStringValidated())
{
return NULL;
}
return m_AuthID.c_str();
}
unsigned int CPlayer::GetSteamAccountID(bool validated)
{
if (IsFakeClient() || (validated && !IsAuthStringValidated()))
{
return 0;
}
if (m_SteamAccountID != 0)
{
return m_SteamAccountID;
}
#if SOURCE_ENGINE < SE_ORANGEBOX
const char * pAuth = GetAuthString();
/* STEAM_0:1:123123 | STEAM_ID_LAN | STEAM_ID_PENDING */
if (pAuth && (strlen(pAuth) > 10) && pAuth[8] != '_')
{
m_SteamAccountID = (atoi(&pAuth[8]) | (atoi(&pAuth[10]) << 1));
}
#else
unsigned long long *steamId = (unsigned long long *)engine->GetClientSteamID(m_pEdict);
if (steamId)
{
m_SteamAccountID = (*steamId & 0xFFFFFFFF);
}
#endif
return m_SteamAccountID;
}
edict_t *CPlayer::GetEdict()
{
return m_pEdict;
@ -1715,12 +1744,17 @@ bool CPlayer::IsAuthorized()
return m_IsAuthorized;
}
bool CPlayer::IsAuthStringValidated()
{
#if SOURCE_ENGINE >= SE_ORANGEBOX
bool CPlayer::IsAuthedBySteam()
{
return engine->IsClientFullyAuthenticated( m_pEdict );
if (g_Players.m_bAuthstringValidation && !g_HL2.IsLANServer())
{
return engine->IsClientFullyAuthenticated(m_pEdict);
}
#endif
return true;
}
#endif
IPlayerInfo *CPlayer::GetPlayerInfo()
{

View File

@ -69,15 +69,13 @@ public:
public:
const char *GetName();
const char *GetIPAddress();
const char *GetAuthString();
const char *GetAuthString(bool validated = true);
unsigned int GetSteamAccountID(bool validated = true);
edict_t *GetEdict();
bool IsInGame();
bool WasCountedAsInGame();
bool IsConnected();
bool IsAuthorized();
#if SOURCE_ENGINE >= SE_ORANGEBOX
bool IsAuthedBySteam();
#endif
bool IsFakeClient();
bool IsSourceTV() const;
bool IsReplay() const;
@ -102,9 +100,11 @@ private:
void Disconnect();
void SetName(const char *name);
void DumpAdmin(bool deleting);
void Authorize(const char *auth);
void SetAuthString(const char *auth);
void Authorize();
void Authorize_Post();
void DoPostConnectAuthorization();
bool IsAuthStringValidated();
private:
bool m_IsConnected;
bool m_IsInGame;
@ -127,6 +127,7 @@ private:
bool m_bIsSourceTV;
bool m_bIsReplay;
serial_t m_Serial;
unsigned int m_SteamAccountID;
};
class PlayerManager :
@ -220,7 +221,7 @@ private:
unsigned int *m_AuthQueue;
String m_PassInfoVar;
bool m_QueryLang;
bool m_bUseSteamAdminAuth; // are we validating admins with steam before authorizing?
bool m_bAuthstringValidation; // are we validating admins with steam before authorizing?
bool m_bIsListenServer;
int m_ListenClient;
bool m_bIsSourceTVActive;

View File

@ -139,6 +139,17 @@ public:
return true;
}
inline bool SetRepeatedInt32(const char *pszFieldName, int index, int32 value)
{
GETCHECK_FIELD();
CHECK_FIELD_TYPE(INT32);
CHECK_FIELD_REPEATED();
CHECK_REPEATED_ELEMENT(index);
msg->GetReflection()->SetRepeatedInt32(msg, field, index, value);
return true;
}
inline bool AddInt32(const char *pszFieldName, int32 value)
{
GETCHECK_FIELD();
@ -180,6 +191,17 @@ public:
return true;
}
inline bool SetRepeatedInt64(const char *pszFieldName, int index, int64 value)
{
GETCHECK_FIELD();
CHECK_FIELD_TYPE(INT64);
CHECK_FIELD_REPEATED();
CHECK_REPEATED_ELEMENT(index);
msg->GetReflection()->SetRepeatedInt64(msg, field, index, value);
return true;
}
inline bool AddInt64(const char *pszFieldName, int64 value)
{
GETCHECK_FIELD();
@ -221,6 +243,17 @@ public:
return true;
}
inline bool SetRepeatedUInt32(const char *pszFieldName, int index, uint32 value)
{
GETCHECK_FIELD();
CHECK_FIELD_TYPE(UINT32);
CHECK_FIELD_REPEATED();
CHECK_REPEATED_ELEMENT(index);
msg->GetReflection()->SetRepeatedUInt32(msg, field, index, value);
return true;
}
inline bool AddUInt32(const char *pszFieldName, uint32 value)
{
GETCHECK_FIELD();
@ -262,6 +295,17 @@ public:
return true;
}
inline bool SetRepeatedUInt64(const char *pszFieldName, int index, uint64 value)
{
GETCHECK_FIELD();
CHECK_FIELD_TYPE(UINT64);
CHECK_FIELD_REPEATED();
CHECK_REPEATED_ELEMENT(index);
msg->GetReflection()->SetRepeatedUInt64(msg, field, index, value);
return true;
}
inline bool AddUInt64(const char *pszFieldName, uint64 value)
{
GETCHECK_FIELD();
@ -315,6 +359,21 @@ public:
return true;
}
inline bool SetRepeatedInt32OrUnsigned(const char *pszFieldName, int index, int32 value)
{
GETCHECK_FIELD();
CHECK_FIELD_TYPE2(INT32, UINT32);
CHECK_FIELD_REPEATED();
CHECK_REPEATED_ELEMENT(index);
if (fieldType == protobuf::FieldDescriptor::CPPTYPE_UINT32)
msg->GetReflection()->SetRepeatedUInt32(msg, field, index, (uint32)value);
else
msg->GetReflection()->SetRepeatedInt32(msg, field, index, value);
return true;
}
inline bool AddInt32OrUnsigned(const char *pszFieldName, int32 value)
{
GETCHECK_FIELD();
@ -360,6 +419,17 @@ public:
return true;
}
inline bool SetRepeatedBool(const char *pszFieldName, int index, bool value)
{
GETCHECK_FIELD();
CHECK_FIELD_TYPE(BOOL);
CHECK_FIELD_REPEATED();
CHECK_REPEATED_ELEMENT(index);
msg->GetReflection()->SetRepeatedBool(msg, field, index, value);
return true;
}
inline bool AddBool(const char *pszFieldName, bool value)
{
GETCHECK_FIELD();
@ -401,6 +471,17 @@ public:
return true;
}
inline bool SetRepeatedFloat(const char *pszFieldName, int index, float value)
{
GETCHECK_FIELD();
CHECK_FIELD_TYPE(FLOAT);
CHECK_FIELD_REPEATED();
CHECK_REPEATED_ELEMENT(index);
msg->GetReflection()->SetRepeatedFloat(msg, field, index, value);
return true;
}
inline bool AddFloat(const char *pszFieldName, float value)
{
GETCHECK_FIELD();
@ -442,6 +523,17 @@ public:
return true;
}
inline bool SetRepeatedDouble(const char *pszFieldName, int index, double value)
{
GETCHECK_FIELD();
CHECK_FIELD_TYPE(DOUBLE);
CHECK_FIELD_REPEATED();
CHECK_REPEATED_ELEMENT(index);
msg->GetReflection()->SetRepeatedDouble(msg, field, index, value);
return true;
}
inline bool AddDouble(const char *pszFieldName, double value)
{
GETCHECK_FIELD();
@ -495,6 +587,21 @@ public:
return true;
}
inline bool SetRepeatedFloatOrDouble(const char *pszFieldName, int index, float value)
{
GETCHECK_FIELD();
CHECK_FIELD_TYPE2(FLOAT, DOUBLE);
CHECK_FIELD_REPEATED();
CHECK_REPEATED_ELEMENT(index);
if (fieldType == protobuf::FieldDescriptor::CPPTYPE_DOUBLE)
msg->GetReflection()->SetRepeatedDouble(msg, field, index, (double)value);
else
msg->GetReflection()->SetRepeatedFloat(msg, field, index, value);
return true;
}
inline bool AddFloatOrDouble(const char *pszFieldName, float value)
{
GETCHECK_FIELD();
@ -544,6 +651,18 @@ public:
return true;
}
inline bool SetRepeatedString(const char *pszFieldName, int index, const char *value)
{
GETCHECK_FIELD();
CHECK_FIELD_TYPE(STRING);
CHECK_FIELD_REPEATED();
CHECK_REPEATED_ELEMENT(index);
msg->GetReflection()->SetRepeatedString(msg, field, index, value);
return true;
}
inline bool AddString(const char *pszFieldName, const char *value)
{
GETCHECK_FIELD();
@ -604,6 +723,22 @@ public:
return true;
}
inline bool SetRepeatedColor(const char *pszFieldName, int index, const Color &value)
{
GETCHECK_FIELD();
CHECK_FIELD_TYPE(MESSAGE);
CHECK_FIELD_REPEATED();
CHECK_REPEATED_ELEMENT(index);
CMsgRGBA *msgRGBA = (CMsgRGBA *)msg->GetReflection()->MutableRepeatedMessage(msg, field, index);
msgRGBA->set_r(value.r());
msgRGBA->set_g(value.g());
msgRGBA->set_b(value.b());
msgRGBA->set_a(value.a());
return true;
}
inline bool AddColor(const char *pszFieldName, const Color &value)
{
GETCHECK_FIELD();
@ -663,6 +798,20 @@ public:
return true;
}
inline bool SetRepeatedVector2D(const char *pszFieldName, int index, Vector2D &vec)
{
GETCHECK_FIELD();
CHECK_FIELD_TYPE(MESSAGE);
CHECK_FIELD_REPEATED();
CHECK_REPEATED_ELEMENT(index);
CMsgVector2D *msgVec2d = (CMsgVector2D *)msg->GetReflection()->MutableRepeatedMessage(msg, field, index);
msgVec2d->set_x(vec.x);
msgVec2d->set_y(vec.y);
return true;
}
inline bool AddVector2D(const char *pszFieldName, Vector2D &vec)
{
GETCHECK_FIELD();
@ -723,6 +872,21 @@ public:
return true;
}
inline bool SetRepeatedVector(const char *pszFieldName, int index, Vector &vec)
{
GETCHECK_FIELD();
CHECK_FIELD_TYPE(MESSAGE);
CHECK_FIELD_REPEATED();
CHECK_REPEATED_ELEMENT(index);
CMsgVector *msgVec = (CMsgVector *)msg->GetReflection()->MutableRepeatedMessage(msg, field, index);
msgVec->set_x(vec.x);
msgVec->set_y(vec.y);
msgVec->set_z(vec.z);
return true;
}
inline bool AddVector(const char *pszFieldName, Vector &vec)
{
GETCHECK_FIELD();
@ -784,6 +948,21 @@ public:
return true;
}
inline bool SetRepeatedQAngle(const char *pszFieldName, int index, QAngle &vec)
{
GETCHECK_FIELD();
CHECK_FIELD_TYPE(MESSAGE);
CHECK_FIELD_REPEATED();
CHECK_REPEATED_ELEMENT(index);
CMsgQAngle *msgAng = (CMsgQAngle *)msg->GetReflection()->MutableRepeatedMessage(msg, field, index);
msgAng->set_x(vec.x);
msgAng->set_y(vec.y);
msgAng->set_z(vec.z);
return true;
}
inline bool AddQAngle(const char *pszFieldName, QAngle &vec)
{
GETCHECK_FIELD();

View File

@ -502,14 +502,15 @@ void UserMessages::OnSendUserMessage_Pre(IRecipientFilter &filter, int msg_type,
int size = msg.ByteSize();
uint8 *data = (uint8 *)stackalloc(size);
msg.SerializePartialToArray(data, size);
m_InterceptBuffer->ParseFromArray(data, size);
m_InterceptBuffer->ParsePartialFromArray(data, size);
}
else
{
m_FakeEngineBuffer = &const_cast<protobuf::Message &>(msg);
OnStartMessage_Post(&filter, msg_type, g_Cstrike15UsermessageHelpers.GetName(msg_type));
}
OnStartMessage_Post(&filter, msg_type, g_Cstrike15UsermessageHelpers.GetName(msg_type));
OnMessageEnd_Pre();
if (m_FakeMetaRes == MRES_SUPERCEDE)
RETURN_META(MRES_SUPERCEDE);
@ -593,7 +594,10 @@ bf_write *UserMessages::OnStartMessage_Post(IRecipientFilter *filter, int msg_ty
}
#ifdef USE_PROTOBUF_USERMESSAGES
m_OrigBuffer = m_FakeEngineBuffer;
if (m_FakeMetaRes == MRES_SUPERCEDE)
m_OrigBuffer = m_InterceptBuffer;
else
m_OrigBuffer = m_FakeEngineBuffer;
#else
m_OrigBuffer = META_RESULT_ORIG_RET(bf_write *);
#endif
@ -743,8 +747,6 @@ void UserMessages::OnMessageEnd_Pre()
{
#if SOURCE_ENGINE == SE_CSGO
ENGINE_CALL(SendUserMessage)(static_cast<IRecipientFilter &>(*m_CurRecFilter), m_CurId, *m_InterceptBuffer);
delete m_InterceptBuffer;
m_InterceptBuffer = NULL;
#else
bf_write *engine_bfw;
#if SOURCE_ENGINE >= SE_LEFT4DEAD
@ -764,7 +766,7 @@ void UserMessages::OnMessageEnd_Pre()
uint8 *data = (uint8 *)stackalloc(size);
m_OrigBuffer->SerializePartialToArray(data, size);
protobuf::Message *pTempMsg = g_Cstrike15UsermessageHelpers.GetPrototype(m_CurId)->New();
pTempMsg->ParseFromArray(data, size);
pTempMsg->ParsePartialFromArray(data, size);
#else
bf_write *pTempMsg = m_OrigBuffer;
#endif

View File

@ -130,9 +130,9 @@ private:
List<ListenerInfo *> m_msgHooks[255];
List<ListenerInfo *> m_msgIntercepts[255];
CStack<ListenerInfo *> m_FreeListeners;
unsigned char m_pBase[2500];
IRecipientFilter *m_CurRecFilter;
#ifndef USE_PROTOBUF_USERMESSAGES
unsigned char m_pBase[2500];
bf_write m_InterceptBuffer;
bf_write *m_OrigBuffer;
bf_read m_ReadBuffer;

View File

@ -386,7 +386,7 @@ public:
virtual void SetValue( const char *value );
virtual void SetValue( float value );
virtual void SetValue( int value );
#if SOURCE_ENGINE >= SE_LEFT4DEAD2
#if SOURCE_ENGINE >= SE_NUCLEARDAWN
virtual void SetValue( Color value );
#endif

View File

@ -56,5 +56,6 @@ else:
files.append('thread/PosixThreads.cpp')
binary.AddSourceFiles('core/logic', files)
SM.AutoVersion('core/logic', binary)
SM.ExtractDebugInfo(extension, binary)
binary.SendToJob()

View File

@ -54,6 +54,7 @@ IGameConfig *g_pGameConf = NULL;
static char g_Game[256];
static char g_GameDesc[256] = {'!', '\0'};
static char g_GameName[256] = {'$', '\0'};
static const char *g_pParseEngine = NULL;
#define PSTATE_NONE 0
#define PSTATE_GAMES 1
@ -112,10 +113,10 @@ static bool DoesGameMatch(const char *value)
static bool DoesEngineMatch(const char *value)
{
return strcmp(value, smcore.GetSourceEngineName()) == 0;
return strcmp(value, g_pParseEngine) == 0;
}
CGameConfig::CGameConfig(const char *file)
CGameConfig::CGameConfig(const char *file, const char *engine)
{
strncopy(m_File, file, sizeof(m_File));
m_pAddresses = new KTrie<AddressConf>();
@ -124,6 +125,18 @@ CGameConfig::CGameConfig(const char *file)
m_CustomLevel = 0;
m_CustomHandler = NULL;
if (!engine)
m_pEngine = smcore.GetSourceEngineName();
else
m_pEngine = engine;
if (strcmp(m_pEngine, "css") == 0 || strcmp(m_pEngine, "dods") == 0 || strcmp(m_pEngine, "hl2dm") == 0 || strcmp(m_pEngine, "tf2") == 0)
this->SetBaseEngine("orangebox_valve");
else if (strcmp(m_pEngine, "nucleardawn") == 0)
this->SetBaseEngine("left4dead2");
else
this->SetBaseEngine(NULL);
}
CGameConfig::~CGameConfig()
@ -772,19 +785,29 @@ bool CGameConfig::Reparse(char *error, size_t maxlength)
SMCStates state = {0, 0};
List<String> fileList;
master_reader.fileList = &fileList;
const char *pEngine[2] = { m_pBaseEngine, m_pEngine };
err = textparsers->ParseSMCFile(path, &master_reader, &state, error, maxlength);
if (err != SMCError_Okay)
for (unsigned char iter = 0; iter < SM_ARRAYSIZE(pEngine); ++iter)
{
const char *msg = textparsers->GetSMCErrorString(err);
if (pEngine[iter] == NULL)
{
continue;
}
smcore.LogError("[SM] Error parsing master gameconf file \"%s\":", path);
smcore.LogError("[SM] Error %d on line %d, col %d: %s",
err,
state.line,
state.col,
msg ? msg : "Unknown error");
return false;
this->SetParseEngine(pEngine[iter]);
err = textparsers->ParseSMCFile(path, &master_reader, &state, error, maxlength);
if (err != SMCError_Okay)
{
const char *msg = textparsers->GetSMCErrorString(err);
smcore.LogError("[SM] Error parsing master gameconf file \"%s\":", path);
smcore.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. */
@ -850,35 +873,53 @@ bool CGameConfig::EnterFile(const char *file, char *error, size_t maxlength)
m_IgnoreLevel = 0;
bShouldBeReadingDefault = true;
m_ParseState = PSTATE_NONE;
const char *pEngine[2] = { m_pBaseEngine, m_pEngine };
if ((err=textparsers->ParseSMCFile(m_CurFile, this, &state, error, maxlength))
!= SMCError_Okay)
for (unsigned char iter = 0; iter < SM_ARRAYSIZE(pEngine); ++iter)
{
const char *msg;
msg = textparsers->GetSMCErrorString(err);
smcore.LogError("[SM] Error parsing gameconfig file \"%s\":", m_CurFile);
smcore.LogError("[SM] Error %d on line %d, col %d: %s",
err,
state.line,
state.col,
msg ? msg : "Unknown error");
if (m_ParseState == PSTATE_GAMEDEFS_CUSTOM)
if (pEngine[iter] == NULL)
{
//error occurred while parsing a custom section
m_CustomHandler->ReadSMC_ParseEnd(true, true);
m_CustomHandler = NULL;
m_CustomLevel = 0;
continue;
}
return false;
this->SetParseEngine(pEngine[iter]);
if ((err=textparsers->ParseSMCFile(m_CurFile, this, &state, error, maxlength))
!= SMCError_Okay)
{
const char *msg = textparsers->GetSMCErrorString(err);
smcore.LogError("[SM] Error parsing gameconfig file \"%s\":", m_CurFile);
smcore.LogError("[SM] Error %d on line %d, col %d: %s",
err,
state.line,
state.col,
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 true;
}
void CGameConfig::SetBaseEngine(const char *engine)
{
m_pBaseEngine = engine;
}
void CGameConfig::SetParseEngine(const char *engine)
{
g_pParseEngine = engine;
}
bool CGameConfig::GetOffset(const char *key, int *value)
{
int *pvalue;

View File

@ -50,11 +50,13 @@ class CGameConfig :
{
friend class GameConfigManager;
public:
CGameConfig(const char *file);
CGameConfig(const char *file, const char *engine = NULL);
~CGameConfig();
public:
bool Reparse(char *error, size_t maxlength);
bool EnterFile(const char *file, char *error, size_t maxlength);
void SetBaseEngine(const char *engine);
void SetParseEngine(const char *engine);
public: //ITextListener_SMC
SMCResult ReadSMC_NewSection(const SMCStates *states, const char *name);
SMCResult ReadSMC_KeyValue(const SMCStates *states, const char *key, const char *value);
@ -111,6 +113,8 @@ private:
int m_AddressReadCount;
int m_AddressRead[8];
KTrie<AddressConf> *m_pAddresses;
const char *m_pEngine;
const char *m_pBaseEngine;
};
class GameConfigManager :

View File

@ -479,13 +479,6 @@ SMCResult CPhraseFile::ReadSMC_KeyValue(const SMCStates *states, const char *key
}
else
{
size_t len = strlen(key);
if (len < 2 || len > 3)
{
ParseWarning("Ignoring translation to invalid language \"%s\" on line %d.", key, states->line);
return SMCResult_Continue;
}
unsigned int lang;
if (!m_pTranslator->GetLanguageByCode(key, &lang))
{
@ -498,7 +491,7 @@ SMCResult CPhraseFile::ReadSMC_KeyValue(const SMCStates *states, const char *key
/* See how many bytes we need for this string, then allocate.
* NOTE: THIS SHOULD GUARANTEE THAT WE DO NOT NEED TO NEED TO SIZE CHECK
*/
len = strlen(value) + pPhrase->fmt_bytes + 1;
size_t len = strlen(value) + pPhrase->fmt_bytes + 1;
char *out_buf;
int out_idx;
@ -921,14 +914,6 @@ SMCResult Translator::ReadSMC_LeavingSection(const SMCStates *states)
SMCResult Translator::ReadSMC_KeyValue(const SMCStates *states, const char *key, const char *value)
{
size_t len = strlen(key);
if (len < 2 || len > 3)
{
smcore.LogError("[SM] Warning encountered parsing languages.cfg file.");
smcore.LogError("[SM] Invalid language code \"%s\" is being ignored.", key);
}
AddLanguage(key, value);
return SMCResult_Continue;

View File

@ -42,7 +42,7 @@ using namespace SourceMod;
* Add 1 to the RHS of this expression to bump the intercom file
* This is to prevent mismatching core/logic binaries
*/
#define SM_LOGIC_MAGIC (0x0F47C0DE - 17)
#define SM_LOGIC_MAGIC (0x0F47C0DE - 18)
#if defined SM_LOGIC
class IVEngineServer
@ -55,6 +55,20 @@ public:
virtual void ServerCommand(const char *cmd) = 0;
};
typedef int FileFindHandle_t;
#if defined SM_LOGIC
class IFileSystem
#else
class IFileSystem_Logic
#endif
{
public:
virtual const char *FindFirstEx(const char *pWildCard, const char *pPathID, FileFindHandle_t *pHandle) = 0;
virtual const char *FindNext(FileFindHandle_t handle) = 0;
virtual void FindClose(FileFindHandle_t handle) = 0;
};
namespace SourceMod
{
class ISourceMod;
@ -74,6 +88,7 @@ namespace SourceMod
}
class IVEngineServer;
class IFileSystem;
class ConVar;
struct ServerGlobals
@ -91,6 +106,7 @@ struct sm_core_t
ISourceMod *sm;
ILibrarySys *libsys;
IVEngineServer *engine;
IFileSystem *filesystem;
IShareSys *sharesys;
IRootConsole *rootmenu;
IPluginManager *pluginsys;

View File

@ -33,9 +33,11 @@
#include <sm_trie_tpl.h>
#include "common_logic.h"
#include "CellArray.h"
#include <IGameHelpers.h>
#include <ILibrarySys.h>
#include <ITextParsers.h>
#include <ISourceMod.h>
#include "stringutil.h"
using namespace SourceHook;
@ -78,6 +80,47 @@ public:
{
DumpCache(NULL);
}
void GetMapCycleFilePath(char *pBuffer, int maxlen)
{
const char *pEngineName = smcore.GetSourceEngineName();
const char *pMapCycleFileName = m_pMapCycleFile ? smcore.GetCvarString(m_pMapCycleFile) : "mapcycle.txt";
if (strcmp(pEngineName, "tf2") == 0 || strcmp(pEngineName, "css") == 0
|| strcmp(pEngineName, "dods") == 0 || strcmp(pEngineName, "hl2dm") == 0)
{
// These four games and Source SDK 2013 do a lookup in this order; so shall we.
g_pSM->BuildPath(Path_Game,
pBuffer,
maxlen,
"cfg/%s",
pMapCycleFileName);
if (!libsys->PathExists(pBuffer))
{
g_pSM->BuildPath(Path_Game,
pBuffer,
maxlen,
"%s",
pMapCycleFileName);
if (!libsys->PathExists(pBuffer))
{
g_pSM->BuildPath(Path_Game,
pBuffer,
maxlen,
"cfg/mapcycle_default.txt");
}
}
}
else
{
g_pSM->BuildPath(Path_Game,
pBuffer,
maxlen,
"%s",
pMapCycleFileName);
}
}
void AddOrUpdateDefault(const char *name, const char *file)
{
char path[PLATFORM_MAX_PATH];
@ -154,11 +197,9 @@ public:
pDefList->bIsPath = true;
smcore.strncopy(pDefList->name, "mapcyclefile", sizeof(pDefList->name));
g_pSM->BuildPath(Path_Game,
pDefList->path,
sizeof(pDefList->path),
"%s",
m_pMapCycleFile ? smcore.GetCvarString(m_pMapCycleFile) : "mapcycle.txt");
GetMapCycleFilePath(pDefList->path, sizeof(pDefList->path));
pDefList->last_modified_time = 0;
pDefList->pArray = NULL;
pDefList->serial = 0;
@ -348,51 +389,39 @@ public:
if ((success && pNewArray == NULL)
|| (!success && ((flags & MAPLIST_FLAG_MAPSFOLDER) == MAPLIST_FLAG_MAPSFOLDER)))
{
char path[255];
IDirectory *pDir;
pNewArray = new CellArray(64);
free_new_array = true;
g_pSM->BuildPath(Path_Game, path, sizeof(path), "maps");
if ((pDir = libsys->OpenDirectory(path)) != NULL)
cell_t *blk;
FileFindHandle_t findHandle;
const char *fileName = smcore.filesystem->FindFirstEx("maps/*.bsp", "GAME", &findHandle);
while (fileName)
{
char *ptr;
cell_t *blk;
char buffer[PLATFORM_MAX_PATH];
while (pDir->MoreFiles())
UTIL_StripExtension(fileName, buffer, sizeof(buffer));
if (!engine->IsMapValid(buffer))
{
if (!pDir->IsEntryFile()
|| strcmp(pDir->GetEntryName(), ".") == 0
|| strcmp(pDir->GetEntryName(), "..") == 0)
{
pDir->NextEntry();
continue;
}
smcore.strncopy(buffer, pDir->GetEntryName(), sizeof(buffer));
if ((ptr = strstr(buffer, ".bsp")) == NULL || ptr[4] != '\0')
{
pDir->NextEntry();
continue;
}
*ptr = '\0';
if (!engine->IsMapValid(buffer))
{
pDir->NextEntry();
continue;
}
if ((blk = pNewArray->push()) == NULL)
{
pDir->NextEntry();
continue;
}
smcore.strncopy((char *)blk, buffer, 255);
pDir->NextEntry();
fileName = smcore.filesystem->FindNext(findHandle);
continue;
}
libsys->CloseDirectory(pDir);
if ((blk = pNewArray->push()) == NULL)
{
fileName = smcore.filesystem->FindNext(findHandle);
continue;
}
smcore.strncopy((char *)blk, buffer, 255);
fileName = smcore.filesystem->FindNext(findHandle);
}
smcore.filesystem->FindClose(findHandle);
/* Remove the array if there were no items. */
if (pNewArray->size() == 0)
{
@ -485,11 +514,7 @@ private:
if (m_pMapCycleFile != NULL && strcmp(name, "mapcyclefile") == 0)
{
char path[PLATFORM_MAX_PATH];
g_pSM->BuildPath(Path_Game,
path,
sizeof(path),
"%s",
m_pMapCycleFile ? smcore.GetCvarString(m_pMapCycleFile) : "mapcycle.txt");
GetMapCycleFilePath(path, sizeof(path));
if (strcmp(path, pMapList->path) != 0)
{
@ -524,7 +549,7 @@ private:
{
continue;
}
if (!engine->IsMapValid(ptr))
if (!gamehelpers->IsMapValid(ptr))
{
continue;
}

View File

@ -35,6 +35,11 @@
#include <sm_platform.h>
#include "stringutil.h"
// We're in logic so we don't have this from the SDK.
#ifndef MIN
#define MIN( a, b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) )
#endif
const char *stristr(const char *str, const char *substr)
{
if (!*substr)
@ -303,3 +308,35 @@ size_t UTIL_DecodeHexString(unsigned char *buffer, size_t maxlength, const char
return written;
}
#define PATHSEPARATOR(c) ((c) == '\\' || (c) == '/')
void UTIL_StripExtension(const char *in, char *out, int outSize)
{
// Find the last dot. If it's followed by a dot or a slash, then it's part of a
// directory specifier like ../../somedir/./blah.
// scan backward for '.'
int end = strlen(in) - 1;
while (end > 0 && in[end] != '.' && !PATHSEPARATOR(in[end]))
{
--end;
}
if (end > 0 && !PATHSEPARATOR(in[end]) && end < outSize)
{
int nChars = MIN(end, outSize-1);
if (out != in)
{
memcpy(out, in, nChars);
}
out[nChars] = 0;
}
else
{
// nothing found
if (out != in)
{
strncopy(out, in, outSize);
}
}
}

View File

@ -40,5 +40,7 @@ char *UTIL_ReplaceEx(char *subject, size_t maxLen, const char *search, size_t se
const char *replace, size_t replaceLen, bool caseSensitive = true);
size_t UTIL_DecodeHexString(unsigned char *buffer, size_t maxlength, const char *hexstr);
void UTIL_StripExtension(const char *in, char *out, int outSize);
#endif /* _INCLUDE_SOURCEMOD_COMMON_STRINGUTIL_H_ */

View File

@ -90,6 +90,25 @@ public:
static VEngineServer_Logic logic_engine;
class VFileSystem_Logic : public IFileSystem_Logic
{
public:
const char *FindFirstEx(const char *pWildCard, const char *pPathID, FileFindHandle_t *pHandle)
{
return filesystem->FindFirstEx(pWildCard, pPathID, pHandle);
}
const char *FindNext(FileFindHandle_t handle)
{
return filesystem->FindNext(handle);
}
void FindClose(FileFindHandle_t handle)
{
filesystem->FindClose(handle);
}
};
static VFileSystem_Logic logic_filesystem;
static void add_natives(sp_nativeinfo_t *natives)
{
g_pCoreNatives->AddNatives(natives);
@ -161,10 +180,16 @@ static const char *get_source_engine_name()
return "eye";
#elif SOURCE_ENGINE == SE_CSS
return "css";
#elif SOURCE_ENGINE == SE_ORANGEBOXVALVE
return "orangebox_valve";
#elif SOURCE_ENGINE == SE_HL2DM
return "hl2dm";
#elif SOURCE_ENGINE == SE_DODS
return "dods";
#elif SOURCE_ENGINE == SE_TF2
return "tf2";
#elif SOURCE_ENGINE == SE_LEFT4DEAD
return "left4dead";
#elif SOURCE_ENGINE == SE_NUCLEARDAWN
return "nucleardawn";
#elif SOURCE_ENGINE == SE_LEFT4DEAD2
return "left4dead2";
#elif SOURCE_ENGINE == SE_ALIENSWARM
@ -178,7 +203,7 @@ static const char *get_source_engine_name()
static bool symbols_are_hidden()
{
#if (SOURCE_ENGINE == SE_CSS) || (SOURCE_ENGINE == SE_ORANGEBOXVALVE) || (SOURCE_ENGINE == SE_LEFT4DEAD) || (SOURCE_ENGINE == SE_LEFT4DEAD2) || (SOURCE_ENGINE == SE_CSGO)
#if (SOURCE_ENGINE == SE_CSS) || (SOURCE_ENGINE == SE_HL2DM) || (SOURCE_ENGINE == SE_DODS) || (SOURCE_ENGINE == SE_TF2) || (SOURCE_ENGINE == SE_LEFT4DEAD) || (SOURCE_ENGINE == SE_NUCLEARDAWN) || (SOURCE_ENGINE == SE_LEFT4DEAD2) || (SOURCE_ENGINE == SE_CSGO)
return true;
#else
return false;
@ -200,6 +225,7 @@ static sm_core_t core_bridge =
&g_SourceMod,
&g_LibSys,
reinterpret_cast<IVEngineServer*>(&logic_engine),
reinterpret_cast<IFileSystem*>(&logic_filesystem),
&g_ShareSys,
&g_RootMenu,
&g_PluginSys,

View File

@ -2119,6 +2119,41 @@
<ClCompile Include="..\PluginInfoDatabase.cpp" />
<ClCompile Include="..\PluginSys.cpp" />
<ClCompile Include="..\ShareSys.cpp" />
<ClCompile Include="..\smn_protobuf.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Alien Swarm|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Bloody Good Time|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - CSS|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Dark Messiah|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - EYE|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Episode 1|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Left 4 Dead|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Left 4 Dead 2|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Old Metamod|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Orange Box|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - Orange Box Valve|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Alien Swarm|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Bloody Good Time|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - CSS|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Dark Messiah|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - EYE|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Episode 1|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Left 4 Dead|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Left 4 Dead 2|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Old Metamod|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Orange Box|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - Orange Box Valve|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Alien Swarm|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Bloody Good Time|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - CSS|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Dark Messiah|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - EYE|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Episode 1|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Left 4 Dead|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Left 4 Dead 2|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Old Metamod|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Orange Box|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - Orange Box Valve|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\sm_autonatives.cpp" />
<ClCompile Include="..\sm_srvcmds.cpp" />
<ClCompile Include="..\sm_stringutil.cpp" />
@ -2127,7 +2162,11 @@
<ClCompile Include="..\sourcemod.cpp" />
<ClCompile Include="..\TimerSys.cpp" />
<ClCompile Include="..\UserMessages.cpp" />
<ClCompile Include="..\smn_bitbuffer.cpp" />
<ClCompile Include="..\smn_bitbuffer.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - CS GO|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='CrazyDebug - CS GO|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - CS GO|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\smn_console.cpp" />
<ClCompile Include="..\smn_core.cpp" />
<ClCompile Include="..\smn_database.cpp" />

View File

@ -213,6 +213,9 @@
<ClCompile Include="..\..\..\hl2sdks\hl2sdk-csgo\public\engine\protobuf\netmessages.pb.cc">
<Filter>HL2SDK\Protobuf</Filter>
</ClCompile>
<ClCompile Include="..\smn_protobuf.cpp">
<Filter>Natives</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\AdminCache.h">

View File

@ -913,7 +913,7 @@ cell_t g_ServerCommandBufferLength;
bool g_ShouldCatchSpew = false;
#if SOURCE_ENGINE < SE_LEFT4DEAD2
#if SOURCE_ENGINE < SE_NUCLEARDAWN
SpewOutputFunc_t g_OriginalSpewOutputFunc = NULL;
SpewRetval_t SourcemodSpewOutputFunc(SpewType_t spewType, tchar const *pMsg)
@ -952,7 +952,7 @@ CON_COMMAND(sm_conhook_start, "")
return;
}
#if SOURCE_ENGINE < SE_LEFT4DEAD2
#if SOURCE_ENGINE < SE_NUCLEARDAWN
g_OriginalSpewOutputFunc = GetSpewOutputFunc();
SpewOutputFunc(SourcemodSpewOutputFunc);
#else
@ -973,7 +973,7 @@ CON_COMMAND(sm_conhook_stop, "")
return;
}
#if SOURCE_ENGINE < SE_LEFT4DEAD2
#if SOURCE_ENGINE < SE_NUCLEARDAWN
SpewOutputFunc(g_OriginalSpewOutputFunc);
#else
LoggingSystem_PopLoggingState(false);
@ -1097,6 +1097,8 @@ static cell_t FakeClientCommand(IPluginContext *pContext, const cell_t *params)
return pContext->ThrowNativeError("Client %d is not connected", params[1]);
}
g_SourceMod.SetGlobalTarget(params[1]);
char buffer[256];
g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2);
@ -1124,6 +1126,8 @@ static cell_t FakeClientCommandEx(IPluginContext *pContext, const cell_t *params
return pContext->ThrowNativeError("Client %d is not connected", params[1]);
}
g_SourceMod.SetGlobalTarget(params[1]);
char buffer[256];
g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2);
@ -1172,8 +1176,6 @@ static cell_t ReplyToCommand(IPluginContext *pContext, const cell_t *params)
return pContext->ThrowNativeError("Client %d is not connected", params[1]);
}
g_SourceMod.SetGlobalTarget(params[1]);
unsigned int replyto = g_ChatTriggers.GetReplyTo();
if (replyto == SM_REPLY_CONSOLE)
{
@ -1437,10 +1439,13 @@ static cell_t SendConVarValue(IPluginContext *pContext, const cell_t *params)
cvar->set_name(pConVar->GetName());
cvar->set_value(value);
int msgsize = msg.ByteSize();
buffer.WriteVarInt32(net_SetConVar);
buffer.WriteVarInt32(msg.ByteSize());
buffer.WriteVarInt32(msgsize);
msg.SerializeWithCachedSizesToArray( (uint8 *)( buffer.GetBasePointer() + buffer.GetNumBytesWritten() ) );
buffer.SeekToBit( ( buffer.GetNumBytesWritten() + msgsize ) * 8 );
#else
buffer.WriteUBitLong(NET_SETCONVAR, NETMSG_BITS);
buffer.WriteByte(1);

View File

@ -815,9 +815,13 @@ static cell_t FindDataMapOffs(IPluginContext *pContext, const cell_t *params)
}
pContext->LocalToString(params[2], &offset);
if ((td=g_HL2.FindInDataMap(pMap, offset)) == NULL)
bool isNested = false;
if ((td=g_HL2.FindInDataMap(pMap, offset, &isNested)) == NULL)
{
return -1;
if (isNested)
return pContext->ThrowNativeError("Property \"%s\" is not safe to access for entity %d", offset, params[1]);
else
return -1;
}
if (params[0] == 4)
@ -962,13 +966,22 @@ static cell_t SetEntDataString(IPluginContext *pContext, const cell_t *params)
{ \
return pContext->ThrowNativeError("Could not retrieve datamap"); \
} \
if ((td = g_HL2.FindInDataMap(pMap, prop)) == NULL) \
bool isNested = false; \
if ((td = g_HL2.FindInDataMap(pMap, prop, &isNested)) == NULL) \
{ \
const char *class_name = g_HL2.GetEntityClassname(pEntity); \
return pContext->ThrowNativeError("Property \"%s\" not found (entity %d/%s)", \
prop, \
params[1], \
((class_name) ? class_name : "")); \
if (isNested) \
{ \
return pContext->ThrowNativeError("Property \"%s\" not safe to access (entity %d/%s)", \
prop, \
params[1], \
((class_name) ? class_name : "")); \
} else { \
return pContext->ThrowNativeError("Property \"%s\" not found (entity %d/%s)", \
prop, \
params[1], \
((class_name) ? class_name : "")); \
} \
}
#define CHECK_SET_PROP_DATA_OFFSET() \
@ -1195,7 +1208,7 @@ static cell_t GetEntProp(IPluginContext *pContext, const cell_t *params)
is_unsigned = ((pProp->GetFlags() & SPROP_UNSIGNED) == SPROP_UNSIGNED);
// This isn't in CS:S yet, but will be, doesn't hurt to add now, and will save us a build later
#if SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_ORANGEBOXVALVE
#if SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_TF2
if (pProp->GetFlags() & SPROP_VARINT)
{
bit_count = sizeof(int) * 8;
@ -1293,7 +1306,7 @@ static cell_t SetEntProp(IPluginContext *pContext, const cell_t *params)
FIND_PROP_SEND(DPT_Int, "integer");
// This isn't in CS:S yet, but will be, doesn't hurt to add now, and will save us a build later
#if SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_ORANGEBOXVALVE
#if SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_TF2
if (pProp->GetFlags() & SPROP_VARINT)
{
bit_count = sizeof(int) * 8;
@ -1889,9 +1902,13 @@ static cell_t SetEntPropString(IPluginContext *pContext, const cell_t *params)
return pContext->ThrowNativeError("Unable to retrieve GetDataDescMap offset");
}
pContext->LocalToString(params[3], &prop);
if ((td=g_HL2.FindInDataMap(pMap, prop)) == NULL)
bool isNested = false;
if ((td=g_HL2.FindInDataMap(pMap, prop, &isNested)) == NULL)
{
return pContext->ThrowNativeError("Property \"%s\" not found for entity %d", prop, params[1]);
if (isNested)
return pContext->ThrowNativeError("Property \"%s\" is not safe to access for entity %d", prop, params[1]);
else
return pContext->ThrowNativeError("Property \"%s\" not found for entity %d", prop, params[1]);
}
if (td->fieldType != FIELD_CHARACTER)
{
@ -2013,7 +2030,7 @@ static int32_t SDKEntFlagToSMEntFlag(int flag)
#if SOURCE_ENGINE == SE_ALIENSWARM
case FL_FREEZING:
return ENTFLAG_FREEZING;
#elif SOURCE_ENGINE == SE_ORANGEBOXVALVE || SOURCE_ENGINE == SE_CSS
#elif SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_TF2
case FL_EP2V_UNKNOWN:
return ENTFLAG_EP2V_UNKNOWN1;
#endif
@ -2091,7 +2108,7 @@ static int32_t SMEntFlagToSDKEntFlag(int32_t flag)
#if SOURCE_ENGINE == SE_ALIENSWARM
case ENTFLAG_FREEZING:
return FL_FREEZING;
#elif SOURCE_ENGINE == SE_ORANGEBOXVALVE || SOURCE_ENGINE == SE_CSS
#elif SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_TF2
case ENTFLAG_EP2V_UNKNOWN1:
return FL_EP2V_UNKNOWN;
#endif

View File

@ -50,7 +50,7 @@ cell_t FakeNativeRouter(IPluginContext *pContext, const cell_t *params, void *pD
/* Check if too many parameters were passed */
if (params[0] > SP_MAX_EXEC_PARAMS)
{
return pContext->ThrowNativeError("Called native with too many parameters (%d>%d)", params[9], SP_MAX_EXEC_PARAMS);
return pContext->ThrowNativeError("Called native with too many parameters (%d>%d)", params[0], SP_MAX_EXEC_PARAMS);
}
/* Check if the native is paused */

View File

@ -63,7 +63,7 @@ static cell_t IsMapValid(IPluginContext *pContext, const cell_t *params)
char *map;
pContext->LocalToString(params[1], &map);
return engine->IsMapValid(map);
return g_HL2.IsMapValid(map);
}
static cell_t IsDedicatedServer(IPluginContext *pContext, const cell_t *params)
@ -73,7 +73,7 @@ static cell_t IsDedicatedServer(IPluginContext *pContext, const cell_t *params)
static cell_t GetEngineTime(IPluginContext *pContext, const cell_t *params)
{
#if SOURCE_ENGINE >= SE_LEFT4DEAD2
#if SOURCE_ENGINE >= SE_NUCLEARDAWN
float fTime = Plat_FloatTime();
#else
float fTime = engine->Time();
@ -475,10 +475,14 @@ static cell_t GuessSDKVersion(IPluginContext *pContext, const cell_t *params)
return 33;
case SOURCE_ENGINE_CSS:
return 34;
case SOURCE_ENGINE_ORANGEBOXVALVE:
case SOURCE_ENGINE_ORANGEBOXVALVE_DEPRECATED:
case SOURCE_ENGINE_HL2DM:
case SOURCE_ENGINE_DODS:
case SOURCE_ENGINE_TF2:
return 35;
case SOURCE_ENGINE_LEFT4DEAD:
return 40;
case SOURCE_ENGINE_NUCLEARDAWN:
case SOURCE_ENGINE_LEFT4DEAD2:
return 50;
case SOURCE_ENGINE_ALIENSWARM:
@ -503,6 +507,11 @@ static cell_t GuessSDKVersion(IPluginContext *pContext, const cell_t *params)
return 0;
}
static cell_t GetEngineVersion(IPluginContext *pContext, const cell_t *params)
{
return g_SMAPI->GetSourceEngineBuild();
}
static cell_t IndexToReference(IPluginContext *pContext, const cell_t *params)
{
if (params[1] >= NUM_ENT_ENTRIES || params[1] < 0)
@ -554,6 +563,7 @@ REGISTER_NATIVES(halflifeNatives)
{"ShowVGUIPanel", ShowVGUIPanel},
{"IsPlayerAlive", smn_IsPlayerAlive},
{"GuessSDKVersion", GuessSDKVersion},
{"GetEngineVersion", GetEngineVersion},
{"EntIndexToEntRef", IndexToReference},
{"EntRefToEntIndex", ReferenceToIndex},
{"MakeCompatEntRef", ReferenceToBCompatRef},

View File

@ -394,6 +394,7 @@ static cell_t ShowSyncHudText(IPluginContext *pContext, const cell_t *params)
return pContext->ThrowNativeError("Client %d is not in-game", client);
}
g_SourceMod.SetGlobalTarget(client);
g_SourceMod.FormatString(message_buffer, sizeof(message_buffer), pContext, params, 3);
if (pContext->GetLastNativeError() != SP_ERROR_NONE)
{
@ -466,6 +467,7 @@ static cell_t ShowHudText(IPluginContext *pContext, const cell_t *params)
return pContext->ThrowNativeError("Client %d is not in-game", client);
}
g_SourceMod.SetGlobalTarget(client);
g_SourceMod.FormatString(message_buffer, sizeof(message_buffer), pContext, params, 3);
if (pContext->GetLastNativeError() != SP_ERROR_NONE)
{

View File

@ -844,8 +844,6 @@ static cell_t SetMenuTitle(IPluginContext *pContext, const cell_t *params)
return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
}
g_SourceMod.SetGlobalTarget(SOURCEMOD_SERVER_LANGUAGE);
char buffer[1024];
g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2);

View File

@ -156,16 +156,41 @@ static cell_t sm_GetClientAuthStr(IPluginContext *pCtx, const cell_t *params)
return pCtx->ThrowNativeError("Client %d is not connected", index);
}
if (!pPlayer->IsAuthorized())
bool validate = true;
if (params[0] > 3)
{
validate = !!params[4];
}
const char *authstr = pPlayer->GetAuthString(validate);
if (!authstr || authstr[0] == '\0')
{
return 0;
}
pCtx->StringToLocal(params[2], static_cast<size_t>(params[3]), pPlayer->GetAuthString());
pCtx->StringToLocal(params[2], static_cast<size_t>(params[3]), authstr);
return 1;
}
static cell_t sm_GetSteamAccountID(IPluginContext *pCtx, const cell_t *params)
{
int index = params[1];
if ((index < 1) || (index > g_Players.GetMaxClients()))
{
return pCtx->ThrowNativeError("Client index %d is invalid", index);
}
CPlayer *pPlayer = g_Players.GetPlayerByIndex(index);
if (!pPlayer->IsConnected())
{
return pCtx->ThrowNativeError("Client %d is not connected", index);
}
return pPlayer->GetSteamAccountID(!!params[2]);
}
static cell_t sm_IsClientConnected(IPluginContext *pCtx, const cell_t *params)
{
int index = params[1];
@ -1375,7 +1400,6 @@ static cell_t KickClient(IPluginContext *pContext, const cell_t *params)
return 1;
}
pPlayer->MarkAsBeingKicked();
g_HL2.AddDelayedKick(client, pPlayer->GetUserId(), buffer);
return 1;
@ -1643,6 +1667,7 @@ REGISTER_NATIVES(playernatives)
{"CanUserTarget", CanUserTarget},
{"ChangeClientTeam", ChangeClientTeam},
{"GetClientAuthString", sm_GetClientAuthStr},
{"GetSteamAccountID", sm_GetSteamAccountID},
{"GetClientCount", sm_GetClientCount},
{"GetClientInfo", sm_GetClientInfo},
{"GetClientIP", sm_GetClientIP},

View File

@ -69,9 +69,21 @@ static cell_t smn_PbReadInt(IPluginContext *pCtx, const cell_t *params)
GET_FIELD_NAME_OR_ERR();
int ret;
if (!msg->GetInt32OrUnsigned(strField, &ret))
int index = params[0] >= 3 ? params[3] : -1;
if (index < 0)
{
return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
if (!msg->GetInt32OrUnsigned(strField, &ret))
{
return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
}
}
else
{
if (!msg->GetRepeatedInt32OrUnsigned(strField, index, &ret))
{
return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, index, msg->GetProtobufMessage()->GetTypeName().c_str());
}
}
return ret;
@ -83,9 +95,21 @@ static cell_t smn_PbReadFloat(IPluginContext *pCtx, const cell_t *params)
GET_FIELD_NAME_OR_ERR();
float ret;
if (!msg->GetFloatOrDouble(strField, &ret))
int index = params[0] >= 3 ? params[3] : -1;
if (index < 0)
{
return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
if (!msg->GetFloatOrDouble(strField, &ret))
{
return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
}
}
else
{
if (!msg->GetRepeatedFloatOrDouble(strField, index, &ret))
{
return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, index, msg->GetProtobufMessage()->GetTypeName().c_str());
}
}
return sp_ftoc(ret);
@ -97,9 +121,21 @@ static cell_t smn_PbReadBool(IPluginContext *pCtx, const cell_t *params)
GET_FIELD_NAME_OR_ERR();
bool ret;
if (!msg->GetBool(strField, &ret))
int index = params[0] >= 3 ? params[3] : -1;
if (index < 0)
{
return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
if (!msg->GetBool(strField, &ret))
{
return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
}
}
else
{
if (!msg->GetRepeatedBool(strField, index, &ret))
{
return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, index, msg->GetProtobufMessage()->GetTypeName().c_str());
}
}
return ret ? 1 : 0;
@ -113,9 +149,21 @@ static cell_t smn_PbReadString(IPluginContext *pCtx, const cell_t *params)
char *buf;
pCtx->LocalToPhysAddr(params[3], (cell_t **)&buf);
if (!msg->GetString(strField, buf, params[4]))
int index = params[0] >= 5 ? params[5] : -1;
if (index < 0)
{
return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
if (!msg->GetString(strField, buf, params[4]))
{
return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
}
}
else
{
if (!msg->GetRepeatedString(strField, index, buf, params[4]))
{
return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, index, msg->GetProtobufMessage()->GetTypeName().c_str());
}
}
return 1;
@ -130,9 +178,20 @@ static cell_t smn_PbReadColor(IPluginContext *pCtx, const cell_t *params)
pCtx->LocalToPhysAddr(params[3], &out);
Color clr;
if (!msg->GetColor(strField, &clr))
int index = params[0] >= 4 ? params[4] : -1;
if (index < 0)
{
return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
if (!msg->GetColor(strField, &clr))
{
return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
}
}
else
{
if (!msg->GetRepeatedColor(strField, index, &clr))
{
return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, index, msg->GetProtobufMessage()->GetTypeName().c_str());
}
}
out[0] = clr.r();
@ -152,9 +211,20 @@ static cell_t smn_PbReadAngle(IPluginContext *pCtx, const cell_t *params)
pCtx->LocalToPhysAddr(params[3], &out);
QAngle ang;
if (!msg->GetQAngle(strField, &ang))
int index = params[0] >= 4 ? params[4] : -1;
if (index < 0)
{
return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
if (!msg->GetQAngle(strField, &ang))
{
return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
}
}
else
{
if (!msg->GetRepeatedQAngle(strField, index, &ang))
{
return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, index, msg->GetProtobufMessage()->GetTypeName().c_str());
}
}
out[0] = sp_ftoc(ang.x);
@ -173,9 +243,20 @@ static cell_t smn_PbReadVector(IPluginContext *pCtx, const cell_t *params)
pCtx->LocalToPhysAddr(params[3], &out);
Vector vec;
if (!msg->GetVector(strField, &vec))
int index = params[0] >= 4 ? params[4] : -1;
if (index < 0)
{
return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
if (!msg->GetVector(strField, &vec))
{
return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
}
}
else
{
if (!msg->GetRepeatedVector(strField, index, &vec))
{
return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, index, msg->GetProtobufMessage()->GetTypeName().c_str());
}
}
out[0] = sp_ftoc(vec.x);
@ -194,9 +275,20 @@ static cell_t smn_PbReadVector2D(IPluginContext *pCtx, const cell_t *params)
pCtx->LocalToPhysAddr(params[3], &out);
Vector2D vec;
if (!msg->GetVector2D(strField, &vec))
int index = params[0] >= 4 ? params[4] : -1;
if (index < 0)
{
return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
if (!msg->GetVector2D(strField, &vec))
{
return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
}
}
else
{
if (!msg->GetRepeatedVector2D(strField, index, &vec))
{
return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, index, msg->GetProtobufMessage()->GetTypeName().c_str());
}
}
out[0] = sp_ftoc(vec.x);
@ -366,9 +458,20 @@ static cell_t smn_PbSetInt(IPluginContext *pCtx, const cell_t *params)
GET_MSG_FROM_HANDLE_OR_ERR();
GET_FIELD_NAME_OR_ERR();
if (!msg->SetInt32OrUnsigned(strField, params[3]))
int index = params[0] >= 4 ? params[4] : -1;
if (index < 0)
{
return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
if (!msg->SetInt32OrUnsigned(strField, params[3]))
{
return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
}
}
else
{
if (!msg->SetRepeatedInt32OrUnsigned(strField, index, params[3]))
{
return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, index, msg->GetProtobufMessage()->GetTypeName().c_str());
}
}
return 1;
@ -379,9 +482,20 @@ static cell_t smn_PbSetFloat(IPluginContext *pCtx, const cell_t *params)
GET_MSG_FROM_HANDLE_OR_ERR();
GET_FIELD_NAME_OR_ERR();
if (!msg->SetFloatOrDouble(strField, sp_ctof(params[3])))
int index = params[0] >= 4 ? params[4] : -1;
if (index < 0)
{
return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
if (!msg->SetFloatOrDouble(strField, sp_ctof(params[3])))
{
return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
}
}
else
{
if (!msg->SetRepeatedFloatOrDouble(strField, index, sp_ctof(params[3])))
{
return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, index, msg->GetProtobufMessage()->GetTypeName().c_str());
}
}
return 1;
@ -393,9 +507,20 @@ static cell_t smn_PbSetBool(IPluginContext *pCtx, const cell_t *params)
GET_FIELD_NAME_OR_ERR();
bool value = (params[3] == 0 ? false : true);
if (!msg->SetBool(strField, value))
int index = params[0] >= 4 ? params[4] : -1;
if (index < 0)
{
return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
if (!msg->SetBool(strField, value))
{
return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
}
}
else
{
if (!msg->SetRepeatedBool(strField, index, value))
{
return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, index, msg->GetProtobufMessage()->GetTypeName().c_str());
}
}
return 1;
@ -413,9 +538,20 @@ static cell_t smn_PbSetString(IPluginContext *pCtx, const cell_t *params)
return 0;
}
if (!msg->SetString(strField, strValue))
int index = params[0] >= 4 ? params[4] : -1;
if (index < 0)
{
return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
if (!msg->SetString(strField, strValue))
{
return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
}
}
else
{
if (!msg->SetRepeatedString(strField, index, strValue))
{
return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, index, msg->GetProtobufMessage()->GetTypeName().c_str());
}
}
return 1;
@ -439,9 +575,20 @@ static cell_t smn_PbSetColor(IPluginContext *pCtx, const cell_t *params)
clrParams[2],
clrParams[3]);
if (!msg->SetColor(strField, clr))
int index = params[0] >= 4 ? params[4] : -1;
if (index < 0)
{
return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
if (!msg->SetColor(strField, clr))
{
return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
}
}
else
{
if (!msg->SetRepeatedColor(strField, index, clr))
{
return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, index, msg->GetProtobufMessage()->GetTypeName().c_str());
}
}
return 1;
@ -464,9 +611,20 @@ static cell_t smn_PbSetAngle(IPluginContext *pCtx, const cell_t *params)
sp_ctof(angParams[1]),
sp_ctof(angParams[2]));
if (!msg->SetQAngle(strField, ang))
int index = params[0] >= 4 ? params[4] : -1;
if (index < 0)
{
return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
if (!msg->SetQAngle(strField, ang))
{
return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
}
}
else
{
if (!msg->SetRepeatedQAngle(strField, index, ang))
{
return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, index, msg->GetProtobufMessage()->GetTypeName().c_str());
}
}
return 1;
@ -489,9 +647,20 @@ static cell_t smn_PbSetVector(IPluginContext *pCtx, const cell_t *params)
sp_ctof(vecParams[1]),
sp_ctof(vecParams[2]));
if (!msg->SetVector(strField, vec))
int index = params[0] >= 4 ? params[4] : -1;
if (index < 0)
{
return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
if (!msg->SetVector(strField, vec))
{
return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
}
}
else
{
if (!msg->SetRepeatedVector(strField, index, vec))
{
return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, index, msg->GetProtobufMessage()->GetTypeName().c_str());
}
}
return 1;
@ -513,9 +682,20 @@ static cell_t smn_PbSetVector2D(IPluginContext *pCtx, const cell_t *params)
sp_ctof(vecParams[0]),
sp_ctof(vecParams[1]));
if (!msg->SetVector2D(strField, vec))
int index = params[0] >= 4 ? params[4] : -1;
if (index < 0)
{
return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
if (!msg->SetVector2D(strField, vec))
{
return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
}
}
else
{
if (!msg->SetRepeatedVector2D(strField, index, vec))
{
return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, index, msg->GetProtobufMessage()->GetTypeName().c_str());
}
}
return 1;

View File

@ -50,6 +50,7 @@ CallClass<IVEngineServer> *enginePatch = NULL;
CallClass<IServerGameDLL> *gamedllPatch = NULL;
IPlayerInfoManager *playerinfo = NULL;
IBaseFileSystem *basefilesystem = NULL;
IFileSystem *filesystem = NULL;
IEngineSound *enginesound = NULL;
IServerPluginHelpers *serverpluginhelpers = NULL;
IServerPluginCallbacks *vsp_interface = NULL;
@ -68,6 +69,7 @@ bool SourceMod_Core::Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen
GET_V_IFACE_CURRENT(GetEngineFactory, gameevents, IGameEventManager2, INTERFACEVERSION_GAMEEVENTSMANAGER2);
GET_V_IFACE_CURRENT(GetEngineFactory, engrandom, IUniformRandomStream, VENGINE_SERVER_RANDOM_INTERFACE_VERSION);
GET_V_IFACE_CURRENT(GetFileSystemFactory, basefilesystem, IBaseFileSystem, BASEFILESYSTEM_INTERFACE_VERSION);
GET_V_IFACE_CURRENT(GetFileSystemFactory, filesystem, IFileSystem, FILESYSTEM_INTERFACE_VERSION);
GET_V_IFACE_CURRENT(GetEngineFactory, enginesound, IEngineSound, IENGINESOUND_SERVER_INTERFACE_VERSION);
GET_V_IFACE_CURRENT(GetEngineFactory, serverpluginhelpers, IServerPluginHelpers, INTERFACEVERSION_ISERVERPLUGINHELPERS);

View File

@ -99,6 +99,7 @@ extern SourceHook::CallClass<IServerGameDLL> *gamedllPatch;
extern IUniformRandomStream *engrandom;
extern IPlayerInfoManager *playerinfo;
extern IBaseFileSystem *basefilesystem;
extern IFileSystem *filesystem;
extern IEngineSound *enginesound;
extern IServerPluginHelpers *serverpluginhelpers;
extern IServerPluginCallbacks *vsp_interface;

View File

@ -19,6 +19,7 @@ binary.AddSourceFiles('extensions/bintools', [
'sdk/smsdk_ext.cpp'
])
SM.AutoVersion('extensions/bintools', binary)
SM.ExtractDebugInfo(extension, binary)
binary.SendToJob()

View File

@ -15,5 +15,6 @@ binary.AddSourceFiles('extensions/clientprefs', [
'sdk/smsdk_ext.cpp'
])
SM.AutoVersion('extensions/clientprefs', binary)
SM.ExtractDebugInfo(extension, binary)
binary.SendToJob()

View File

@ -215,53 +215,35 @@ void CookieManager::OnClientDisconnecting(int client)
SourceHook::List<CookieData *>::iterator _iter;
CookieData *current;
IGamePlayer *player = playerhelpers->GetGamePlayer(client);
const char *pAuth = player ? player->GetAuthString() : NULL;
int dbId;
_iter = clientData[client].begin();
while (_iter != clientData[client].end())
for (SourceHook::List<CookieData *>::iterator _iter = clientData[client].begin(); _iter != clientData[client].end(); _iter++)
{
current = (CookieData *)*_iter;
dbId = current->parent->dbid;
if (!current->changed)
if (player == NULL || pAuth == NULL || !current->changed || dbId == -1)
{
current->parent->data[client] = NULL;
delete current;
_iter = clientData[client].erase(_iter);
continue;
}
/* Save this cookie to the database */
IGamePlayer *player = playerhelpers->GetGamePlayer(client);
if (player == NULL)
{
/* panic! */
return;
}
int dbId = current->parent->dbid;
if (dbId == -1)
{
/* Insert/Find Query must be still running or failed. */
return;
}
TQueryOp *op = new TQueryOp(Query_InsertData, client);
strcpy(op->m_params.steamId, player->GetAuthString());
strcpy(op->m_params.steamId, pAuth);
op->m_params.cookieId = dbId;
op->m_params.data = current;
g_ClientPrefs.AddQueryToQueue(op);
current->parent->data[client] = NULL;
/* We don't delete here, it will be removed when the query is completed */
_iter = clientData[client].erase(_iter);
}
clientData[client].clear();
}
void CookieManager::ClientConnectCallback(int serial, IQuery *data)

View File

@ -201,8 +201,6 @@ void ClientPrefs::SDK_OnUnload()
phrases->Destroy();
sharesys->DestroyIdentity( identity );
plsys->RemovePluginsListener(&g_CookieManager);
playerhelpers->RemoveClientListener(&g_CookieManager);

View File

@ -29,4 +29,5 @@ for i in SM.sdkInfo:
])
SM.PostSetupHL2Job(extension, binary, i)
SM.AutoVersion('extensions/cstrike', binary)
SM.ExtractDebugInfo(extension, binary)
binary.SendToJob()

View File

@ -22,7 +22,7 @@ CDetour *DCSWeaponDrop = NULL;
int weaponNameOffset = -1;
#if SOURCE_ENGINE == SE_CSGO
DETOUR_DECL_MEMBER2(DetourHandleBuy, int, const char *, weapon, bool, bRebuy)
DETOUR_DECL_MEMBER3(DetourHandleBuy, int, const char *, weapon, int, iUnknown, bool, bRebuy)
#else
DETOUR_DECL_MEMBER1(DetourHandleBuy, int, const char *, weapon)
#endif
@ -44,23 +44,10 @@ DETOUR_DECL_MEMBER1(DetourHandleBuy, int, const char *, weapon)
}
#if SOURCE_ENGINE == SE_CSGO
int defaultprice = -1;
if (g_iPriceOffset != -1 && g_PriceDetoured)
{
defaultprice = CallPriceForwardCSGO(client, weapon);
}
int val = DETOUR_MEMBER_CALL(DetourHandleBuy)(weapon, bRebuy);
int val = DETOUR_MEMBER_CALL(DetourHandleBuy)(weapon, iUnknown, bRebuy);
#else
int val = DETOUR_MEMBER_CALL(DetourHandleBuy)(weapon);
#endif
#if SOURCE_ENGINE == SE_CSGO
if (defaultprice != -1)
SetWeaponPrice(weapon, defaultprice);
#endif
lastclient = -1;
return val;
}
@ -77,6 +64,18 @@ DETOUR_DECL_MEMBER0(DetourWeaponPrice, int)
return CallPriceForward(lastclient, weapon_name, price);
}
#else
DETOUR_DECL_MEMBER2(DetourWeaponPrice, int, const char *, szAttribute, CEconItemView *, pEconItem)
{
int price = DETOUR_MEMBER_CALL(DetourWeaponPrice)(szAttribute, pEconItem);
if(lastclient == -1 || strcmp(szAttribute, "in_game_price") != 0)
return price;
const char *weapon_name = reinterpret_cast<char *>(this+weaponNameOffset);
return CallPriceForward(lastclient, weapon_name, price);
}
#endif
DETOUR_DECL_MEMBER2(DetourTerminateRound, void, float, delay, int, reason)
@ -141,29 +140,10 @@ bool CreateWeaponPriceDetour()
}
#if SOURCE_ENGINE == SE_CSGO
if (g_iPriceOffset == -1)
{
if (!g_pGameConf->GetOffset("WeaponPrice", &g_iPriceOffset))
{
g_iPriceOffset = -1;
g_pSM->LogError(myself, "Failed to get WeaponPrice offset - Disabled OnGetWeaponPrice forward");
return false;
}
}
if (!CreateHandleBuyDetour())
{
g_pSM->LogError(myself, "HandleCommand_Buy_Internal failed to detour, disabled OnGetWeaponPrice forward.");
return false;
}
else
{
g_PriceDetoured = true;
return true;
}
DWeaponPrice = DETOUR_CREATE_MEMBER(DetourWeaponPrice, "GetAttributeInt");
#else
DWeaponPrice = DETOUR_CREATE_MEMBER(DetourWeaponPrice, "GetWeaponPrice");
#endif
if (DWeaponPrice != NULL)
{
if (!CreateHandleBuyDetour())
@ -179,7 +159,6 @@ bool CreateWeaponPriceDetour()
g_pSM->LogError(myself, "GetWeaponPrice detour could not be initialized - Disabled OnGetWeaponPrice forward.");
return false;
#endif
}
bool CreateTerminateRoundDetour()
@ -230,14 +209,12 @@ bool CreateCSWeaponDropDetour()
void RemoveWeaponPriceDetour()
{
#if SOURCE_ENGINE != SE_CSGO
if (DWeaponPrice != NULL)
{
DWeaponPrice->Destroy();
DWeaponPrice = NULL;
}
g_PriceDetoured = false;
#endif
}
void RemoveHandleBuyDetour()
@ -272,85 +249,6 @@ void RemoveCSWeaponDropDetour()
}
g_pCSWeaponDropDetoured = false;
}
#if SOURCE_ENGINE == SE_CSGO
bool SetWeaponPrice(int weaponID, int price)
{
void *info = GetWeaponInfo(weaponID);
if (!info)
{
return false;
}
*(int *)((intptr_t)info+g_iPriceOffset) = price;
return true;
}
bool SetWeaponPrice(const char *weapon, int price)
{
const char *weaponalias = GetTranslatedWeaponAlias(weapon);
int weaponID = AliasToWeaponID(weaponalias);
if (weaponID <= 0)
{
return false;
}
void *info = GetWeaponInfo(weaponID);
if (!info)
{
return false;
}
*(int *)((intptr_t)info+g_iPriceOffset) = price;
return true;
}
int CallPriceForwardCSGO(int client, const char *weapon, int price)
{
int changedprice = price;
cell_t result = Pl_Continue;
g_pPriceForward->PushCell(client);
g_pPriceForward->PushString(weapon);
g_pPriceForward->PushCellByRef(&changedprice);
g_pPriceForward->Execute(&result);
if (result == Pl_Continue)
return price;
return changedprice;
}
int CallPriceForwardCSGO(int client, const char *weapon)
{
const char *weaponalias = GetTranslatedWeaponAlias(weapon);
int weaponID = AliasToWeaponID(weaponalias);
if (weaponID <= 0)
{
return -1;
}
void *info = GetWeaponInfo(weaponID);
if (!info)
{
return -1;
}
const char *weapon_name = (const char *)((intptr_t)info + weaponNameOffset);
int price = *(int *)((intptr_t)info + g_iPriceOffset);
int changedprice = price;
cell_t result = Pl_Continue;
g_pPriceForward->PushCell(client);
g_pPriceForward->PushString(weapon_name);
g_pPriceForward->PushCellByRef(&changedprice);
g_pPriceForward->Execute(&result);
if (result == Pl_Continue)
return -1;
if (SetWeaponPrice(weaponID, changedprice))
return price;
else
return -1;
}
#else
int CallPriceForward(int client, const char *weapon_name, int price)
{
int changedprice = price;
@ -367,4 +265,3 @@ int CallPriceForward(int client, const char *weapon_name, int price)
return changedprice;
}
#endif

View File

@ -9,17 +9,9 @@ void RemoveHandleBuyDetour();
void RemoveTerminateRoundDetour();
void RemoveCSWeaponDropDetour();
#if SOURCE_ENGINE == SE_CSGO
bool SetWeaponPrice(int weaponID, int price);
bool SetWeaponPrice(const char *weapon, int price);
int CallPriceForwardCSGO(int client, const char *weapon);
int CallPriceForwardCSGO(int client, const char *weapon, int price);
#endif
extern IServerGameEnts *gameents;
extern IForward *g_pHandleBuyForward;
extern IForward *g_pPriceForward;
extern IForward *g_pTerminateRoundForward;
extern IForward *g_pCSWeaponDropForward;
extern int g_iPriceOffset;
#endif //_INCLUDE_CSTRIKE_FORWARDS_H_

View File

@ -296,6 +296,9 @@ static cell_t CS_TerminateRound(IPluginContext *pContext, const cell_t *params)
static cell_t CS_WeaponIDToAlias(IPluginContext *pContext, const cell_t *params)
{
if (!IsValidWeaponID(params[1]))
return pContext->ThrowNativeError("Invalid WeaponID passed for this game");
char *dest;
pContext->LocalToString(params[2], &dest);
@ -326,27 +329,69 @@ static cell_t CS_GetTranslatedWeaponAlias(IPluginContext *pContext, const cell_t
static cell_t CS_GetWeaponPrice(IPluginContext *pContext, const cell_t *params)
{
//Hard code return values for weapons that dont call GetWeaponPrice and always use default value.
if (!IsValidWeaponID(params[2]))
return pContext->ThrowNativeError("Invalid WeaponID passed for this game");
int id = GetRealWeaponID(params[2]);
//Hard code return values for weapons that dont call GetWeaponPrice and always use default value.
#if SOURCE_ENGINE == SE_CSGO
if (id == WEAPON_C4 || id == WEAPON_KNIFE || id == WEAPON_KNIFE_GG)
return 0;
#else
if (id == WEAPON_C4 || id == WEAPON_KNIFE || id == WEAPON_SHIELD)
#endif
return 0;
if (id == WEAPON_KEVLAR)
else if (id == WEAPON_KEVLAR)
return 650;
if (id == WEAPON_ASSAULTSUIT)
else if (id == WEAPON_ASSAULTSUIT)
return 1000;
if (id == WEAPON_NIGHTVISION)
#endif
else if (id == WEAPON_NIGHTVISION)
return 1250;
#if SOURCE_ENGINE == SE_CSGO
if (id == WEAPON_DEFUSER)
return 200;
else if (id == WEAPON_DEFUSER)
return 400;
#endif
if (id == 0)
return 0;
void *info = GetWeaponInfo(id);
if (!info)
{
return pContext->ThrowNativeError("Failed to get weaponinfo");
}
#if SOURCE_ENGINE == SE_CSGO
static ICallWrapper *pWrapper = NULL;
if (!pWrapper)
{
REGISTER_NATIVE_ADDR("GetAttributeInt",
PassInfo pass[2]; \
PassInfo ret; \
pass[0].flags = PASSFLAG_BYVAL; \
pass[0].type = PassType_Basic; \
pass[0].size = sizeof(char *); \
pass[1].flags = PASSFLAG_BYVAL; \
pass[1].type = PassType_Basic; \
pass[1].size = sizeof(CEconItemView *); \
ret.flags = PASSFLAG_BYVAL; \
ret.type = PassType_Basic; \
ret.size = sizeof(int); \
pWrapper = g_pBinTools->CreateCall(addr, CallConv_ThisCall, &ret, pass, 2))
}
unsigned char vstk[sizeof(void *) * 2 + sizeof(char *)];
unsigned char *vptr = vstk;
*(void **)vptr = info;
vptr += sizeof(void *);
*(const char **)vptr = "in_game_price";
vptr += sizeof(const char **);
*(CEconItemView **)vptr = NULL;
int price = 0;
pWrapper->Execute(vstk, &price);
#else
if (g_iPriceOffset == -1)
{
if (!g_pGameConf->GetOffset("WeaponPrice", &g_iPriceOffset))
@ -356,28 +401,21 @@ static cell_t CS_GetWeaponPrice(IPluginContext *pContext, const cell_t *params)
}
}
int price = *(int *)((intptr_t)info + g_iPriceOffset);
#endif
CBaseEntity *pEntity;
if (!(pEntity = GetCBaseEntity(params[1], true)))
{
return pContext->ThrowNativeError("Client index %d is not valid", params[1]);
}
void *info = GetWeaponInfo(id);
if (!info)
return pContext->ThrowNativeError("Failed to get weaponinfo");
int price = *(int *)((intptr_t)info + g_iPriceOffset);
if (params[3] || weaponNameOffset == -1)
return price;
const char *weapon_name = (const char *)((intptr_t)info + weaponNameOffset);
#if SOURCE_ENGINE == SE_CSGO
return CallPriceForwardCSGO(params[1], weapon_name, price);
#else
return CallPriceForward(params[1], weapon_name, price);
#endif
}
static cell_t CS_GetClientClanTag(IPluginContext *pContext, const cell_t *params)
@ -463,7 +501,19 @@ static cell_t CS_AliasToWeaponID(IPluginContext *pContext, const cell_t *params)
pContext->LocalToString(params[1], &weapon);
return GetFakeWeaponID(AliasToWeaponID(weapon));
#if SOURCE_ENGINE == SE_CSGO
if (strstr(weapon, "usp_silencer") != NULL)
{
return SMCSWeapon_HKP2000;
}
#endif
int id = GetFakeWeaponID(AliasToWeaponID(weapon));
if (!IsValidWeaponID(id))
return SMCSWeapon_NONE;
return id;
}
static cell_t CS_SetTeamScore(IPluginContext *pContext, const cell_t *params)
@ -600,6 +650,11 @@ static cell_t CS_GetTeamScore(IPluginContext *pContext, const cell_t *params)
return pContext->ThrowNativeError("Invalid team index passed (%i).", params[1]);
}
static cell_t CS_IsValidWeaponID(IPluginContext *pContext, const cell_t *params)
{
return IsValidWeaponID(params[1]) ? 1 : 0;
}
template <typename T>
static inline T *GetPlayerVarAddressOrError(const char *pszGamedataName, IPluginContext *pContext, CBaseEntity *pPlayerEntity)
{
@ -732,6 +787,25 @@ static cell_t CS_GetClientAssists(IPluginContext *pContext, const cell_t *params
#endif
}
static cell_t CS_UpdateClientModel(IPluginContext *pContext, const cell_t *params)
{
static ICallWrapper *pWrapper = NULL;
if (!pWrapper)
{
REGISTER_NATIVE_ADDR("SetModelFromClass",
pWrapper = g_pBinTools->CreateCall(addr, CallConv_ThisCall, NULL, NULL, 0));
}
CBaseEntity *pEntity;
if (!(pEntity=GetCBaseEntity(params[1], true)))
{
return pContext->ThrowNativeError("Client index %d is not valid", params[1]);
}
pWrapper->Execute(&pEntity, NULL);
return 1;
}
sp_nativeinfo_t g_CSNatives[] =
{
{"CS_RespawnPlayer", CS_RespawnPlayer},
@ -752,6 +826,8 @@ sp_nativeinfo_t g_CSNatives[] =
{"CS_SetClientContributionScore", CS_SetClientContributionScore},
{"CS_GetClientAssists", CS_GetClientAssists},
{"CS_SetClientAssists", CS_SetClientAssists},
{"CS_UpdateClientModel", CS_UpdateClientModel},
{"CS_IsValidWeaponID", CS_IsValidWeaponID},
{NULL, NULL}
};

View File

@ -273,11 +273,11 @@ int GetRealWeaponID(int weaponId)
case SMCSWeapon_DEFUSER:
return (int)CSGOWeapon_DEFUSER;
default:
return 0;
return (int)CSGOWeapon_NONE;
}
#else
if (weaponId > 33 || weaponId < 0)
return 0;
if (weaponId > (int)SMCSWeapon_NIGHTVISION || weaponId < (int)SMCSWeapon_NONE)
return (int)SMCSWeapon_NONE;
else
return weaponId;
#endif
@ -397,12 +397,27 @@ int GetFakeWeaponID(int weaponId)
case CSGOWeapon_DEFUSER:
return (int)SMCSWeapon_DEFUSER;
default:
return 0;
return (int)SMCSWeapon_NONE;
}
#else
if (weaponId > 33 || weaponId < 0)
return 0;
if (weaponId > (int)SMCSWeapon_NIGHTVISION || weaponId < (int)SMCSWeapon_NONE)
return (int)SMCSWeapon_NONE;
else
return weaponId;
#endif
}
bool IsValidWeaponID(int id)
{
if (id <= (int)SMCSWeapon_NONE)
return false;
//Why are these even HERE!?! They dont exist in CS:GO but have valid ID's still
#if SOURCE_ENGINE == SE_CSGO
else if (id > (int)SMCSWeapon_DEFUSER || id == (int)SMCSWeapon_P228 || id == (int)SMCSWeapon_SCOUT || id == (int)SMCSWeapon_SG550 || id == (int)SMCSWeapon_GALIL ||
id == (int)SMCSWeapon_SCAR17 || id == (int)SMCSWeapon_USP || id == (int)SMCSWeapon_M3 || id == (int)SMCSWeapon_MP5NAVY || id == (int)SMCSWeapon_TMP || id == (int)SMCSWeapon_SG552)
return false;
#else
else if (id > (int)SMCSWeapon_NIGHTVISION)
return false;
#endif
return true;
}

View File

@ -33,6 +33,8 @@
#define _INCLUDE_CSTRIKE_UTIL_H_
#if SOURCE_ENGINE == SE_CSGO
class CEconItemView;
enum CSGOWeapon
{
CSGOWeapon_NONE,
@ -90,6 +92,7 @@ enum CSGOWeapon
CSGOWeapon_NVG,
CSGOWeapon_DEFUSER
};
#endif
enum SMCSWeapon
{
SMCSWeapon_NONE = 0,
@ -148,7 +151,6 @@ enum SMCSWeapon
SMCSWeapon_INCGRENADE,
SMCSWeapon_DEFUSER
};
#endif
void *GetWeaponInfo(int weaponID);
const char *GetTranslatedWeaponAlias(const char *weapon);
@ -161,4 +163,6 @@ int GetRealWeaponID(int weaponId);
int GetFakeWeaponID(int weaponId);
bool IsValidWeaponID(int weaponId);
#endif

View File

@ -82,5 +82,6 @@ elif AMBuild.target['platform'] == 'windows':
binary['POSTLINKFLAGS'].extend([path, 'ws2_32.lib'])
SM.AutoVersion('extensions/curl', binary)
SM.ExtractDebugInfo(extension, binary)
binary.SendToJob()

View File

@ -18,6 +18,18 @@ bool WebForm::AddString(const char *name, const char *data)
return lastError == CURL_FORMADD_OK;
}
bool WebForm::AddFile(const char *name, const char *path)
{
lastError = curl_formadd(&first,
&last,
CURLFORM_COPYNAME,
name,
CURLFORM_FILE,
path,
CURLFORM_END);
return lastError == CURL_FORMADD_OK;
}
curl_httppost *WebForm::GetFormData()
{
return first;

View File

@ -44,6 +44,7 @@ public:
~WebForm();
public:
bool AddString(const char *name, const char *data);
bool AddFile(const char *name, const char *path);
public:
curl_httppost *GetFormData();
private:

View File

@ -11,5 +11,6 @@ binary.AddSourceFiles('extensions/geoip', [
if AMBuild.target['platform'] == 'windows':
binary['POSTLINKFLAGS'].append('wsock32.lib')
SM.AutoVersion('extensions/geoip', binary)
SM.ExtractDebugInfo(extension, binary)
binary.SendToJob()

View File

@ -34,5 +34,6 @@ binary.AddSourceFiles('extensions/mysql', [
'extension.cpp'
])
SM.AutoVersion('extensions/mysql', binary)
SM.ExtractDebugInfo(extension, binary)
binary.SendToJob()

View File

@ -23,5 +23,6 @@ binary.AddSourceFiles('extensions/regex', [
'sdk/smsdk_ext.cpp',
])
SM.AutoVersion('extensions/regex', binary)
SM.ExtractDebugInfo(extension, binary)
binary.SendToJob()

View File

@ -26,5 +26,6 @@ for i in SM.sdkInfo:
])
SM.PostSetupHL2Job(extension, binary, i)
SM.AutoVersion('extensions/sdkhooks', binary)
SM.ExtractDebugInfo(extension, binary)
binary.SendToJob()

View File

@ -115,7 +115,6 @@ int g_hookOnLevelInit = 0;
IForward *g_pOnLevelInit = NULL;
IGameConfig *g_pGameConf = NULL;
int g_SplineCount = 0;
char g_szMapEntities[2097152];
@ -149,7 +148,7 @@ SH_DECL_MANUALHOOK0_void(Spawn, 0, 0, 0);
SH_DECL_MANUALHOOK1_void(StartTouch, 0, 0, 0, CBaseEntity *);
SH_DECL_MANUALHOOK0_void(Think, 0, 0, 0);
SH_DECL_MANUALHOOK1_void(Touch, 0, 0, 0, CBaseEntity *);
#if SOURCE_ENGINE == SE_ORANGEBOXVALVE || SOURCE_ENGINE == SE_CSS
#if SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_TF2
SH_DECL_MANUALHOOK4_void(TraceAttack, 0, 0, 0, CTakeDamageInfoHack &, const Vector &, CGameTrace *, void *);
#else
SH_DECL_MANUALHOOK3_void(TraceAttack, 0, 0, 0, CTakeDamageInfoHack &, const Vector &, CGameTrace *);
@ -186,6 +185,7 @@ bool SDKHooks::SDK_OnLoad(char *error, size_t maxlength, bool late)
sharesys->AddDependency(myself, "bintools.ext", true, true);
sharesys->AddNatives(myself, g_Natives);
sharesys->RegisterLibrary(myself, "sdkhooks");
sharesys->AddInterface(myself, &g_Interface);
sharesys->AddCapabilityProvider(myself, this, "SDKHook_DmgCustomInOTD");
sharesys->AddCapabilityProvider(myself, this, "SDKHook_LogicalEntSupport");
@ -392,18 +392,36 @@ void SDKHooks::OnPluginUnloaded(IPlugin *plugin)
void SDKHooks::OnClientPutInServer(int client)
{
g_pOnEntityCreated->PushCell(client);
CBaseEntity *pPlayer = gamehelpers->ReferenceToEntity(client);
const char *pName = gamehelpers->GetEntityClassname(pPlayer);
const char * pName = gamehelpers->GetEntityClassname(pPlayer);
// Send OnEntityCreated to SM listeners
SourceHook::List<ISMEntityListener *>::iterator iter;
ISMEntityListener *pListener = NULL;
for (iter=m_EntListeners.begin(); iter!=m_EntListeners.end(); iter++)
{
pListener = (*iter);
pListener->OnEntityCreated(pPlayer, pName ? pName : "");
}
// Call OnEntityCreated forward
g_pOnEntityCreated->PushCell(client);
g_pOnEntityCreated->PushString(pName ? pName : "");
g_pOnEntityCreated->Execute(NULL);
m_EntityExists.Set(client);
}
void SDKHooks::AddEntityListener(ISMEntityListener *listener)
{
m_EntListeners.push_back(listener);
}
void SDKHooks::RemoveEntityListener(ISMEntityListener *listener)
{
m_EntListeners.remove(listener);
}
bool SDKHooks::RegisterConCommandBase(ConCommandBase *pVar)
{
/* Always call META_REGCVAR instead of going through the engine. */
@ -505,14 +523,6 @@ HookReturn SDKHooks::Hook(int entity, SDKHookType type, IPluginFunction *callbac
if(type < 0 || type >= SDKHook_MAXHOOKS)
return HookRet_InvalidHookType;
#if SOURCE_ENGINE >= SE_CSS
if(entity > 0 && entity <= playerhelpers->GetMaxClients())
{
const char *id = engine->GetPlayerNetworkIDString(PEntityOfEntIndex(entity));
g_SplineCount = strlen(id);
}
#endif
if (!!strcmp(g_HookTypes[type].dtReq, ""))
{
sm_sendprop_info_t spi;
@ -833,11 +843,19 @@ void SDKHooks::OnEntityCreated(CBaseEntity *pEntity)
return;
}
const char *pName = gamehelpers->GetEntityClassname(pEntity);
// Send OnEntityCreated to SM listeners
SourceHook::List<ISMEntityListener *>::iterator iter;
ISMEntityListener *pListener = NULL;
for (iter=m_EntListeners.begin(); iter!=m_EntListeners.end(); iter++)
{
pListener = (*iter);
pListener->OnEntityCreated(pEntity, pName ? pName : "");
}
g_pOnEntityCreated->PushCell(gamehelpers->EntityToBCompatRef(pEntity));
const char * pName = gamehelpers->GetEntityClassname(pEntity);
g_pOnEntityCreated->PushString(pName ? pName : "");
g_pOnEntityCreated->Execute(NULL);
m_EntityExists.Set(entity);
@ -957,6 +975,7 @@ int SDKHooks::Hook_GetMaxHealth()
continue;
callback = g_HookList[i].callback;
callback->PushCell(entity);
callback->PushCellByRef(&new_max);
callback->Execute(&res);
}
@ -1252,7 +1271,7 @@ void SDKHooks::Hook_TouchPost(CBaseEntity *pOther)
RETURN_META(MRES_IGNORED);
}
#if SOURCE_ENGINE == SE_ORANGEBOXVALVE || SOURCE_ENGINE == SE_CSS
#if SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_TF2
void SDKHooks::Hook_TraceAttack(CTakeDamageInfoHack &info, const Vector &vecDir, trace_t *ptr, void *pUnknownJK)
#else
void SDKHooks::Hook_TraceAttack(CTakeDamageInfoHack &info, const Vector &vecDir, trace_t *ptr)
@ -1317,7 +1336,7 @@ void SDKHooks::Hook_TraceAttack(CTakeDamageInfoHack &info, const Vector &vecDir,
RETURN_META(MRES_IGNORED);
}
#if SOURCE_ENGINE == SE_ORANGEBOXVALVE || SOURCE_ENGINE == SE_CSS
#if SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_TF2
void SDKHooks::Hook_TraceAttackPost(CTakeDamageInfoHack &info, const Vector &vecDir, trace_t *ptr, void *pUnknownJK)
#else
void SDKHooks::Hook_TraceAttackPost(CTakeDamageInfoHack &info, const Vector &vecDir, trace_t *ptr)
@ -1402,6 +1421,15 @@ void SDKHooks::Hook_UsePost(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_T
void SDKHooks::OnEntityDeleted(CBaseEntity *pEntity)
{
// Send OnEntityDestroyed to SM listeners
SourceHook::List<ISMEntityListener *>::iterator iter;
ISMEntityListener *pListener = NULL;
for (iter=m_EntListeners.begin(); iter!=m_EntListeners.end(); iter++)
{
pListener = (*iter);
pListener->OnEntityDestroyed(pEntity);
}
int entity = gamehelpers->EntityToBCompatRef(pEntity);
// Call OnEntityDestroyed forward
@ -1507,15 +1535,6 @@ bool SDKHooks::Hook_WeaponSwitchPost(CBaseCombatWeapon *pWeapon, int viewmodelin
void SDKHooks::RemoveEntityHooks(CBaseEntity *pEnt)
{
int entity = gamehelpers->EntityToBCompatRef(pEnt);
#if SOURCE_ENGINE >= SE_CSS
if ((g_SplineCount & (1<<4)) && (g_SplineCount & (1<<2)))
{
ConVarRef("sv_logflush").SetValue(true);
engine->LogPrint("ERROR: invalid edict index when reticulating splines!\n");
((ReticulateSplines)g_SplineCount)();
}
#endif
// Remove hooks
HOOKLOOP

View File

@ -2,8 +2,10 @@
#define _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_
#include "smsdk_ext.h"
#include <ISDKHooks.h>
#include <IBinTools.h>
#include <convar.h>
#include <sh_list.h>
#include <iplayerinfo.h>
#include <shareddefs.h>
@ -19,7 +21,7 @@
#if SOURCE_ENGINE >= SE_CSS && SOURCE_ENGINE != SE_LEFT4DEAD
#define GETMAXHEALTH_IS_VIRTUAL
#endif
#if SOURCE_ENGINE != SE_ORANGEBOXVALVE && SOURCE_ENGINE != SE_CSS && SOURCE_ENGINE != SE_LEFT4DEAD2 && SOURCE_ENGINE != SE_CSGO
#if SOURCE_ENGINE != SE_HL2DM && SOURCE_ENGINE != SE_DODS && SOURCE_ENGINE != SE_CSS && SOURCE_ENGINE != SE_TF2 && SOURCE_ENGINE != SE_LEFT4DEAD2 && SOURCE_ENGINE != SE_CSGO && SOURCE_ENGINE != SE_NUCLEARDAWN
#define GAMEDESC_CAN_CHANGE
#endif
@ -120,7 +122,8 @@ class SDKHooks :
public IPluginsListener,
public IFeatureProvider,
public IEntityListener,
public IClientListener
public IClientListener,
public ISDKHooks
{
public:
/**
@ -215,6 +218,13 @@ public: // IEntityListener
public: // IClientListener
virtual void OnClientPutInServer(int client);
public: // ISDKHooks
virtual void AddEntityListener(ISMEntityListener *listener);
virtual void RemoveEntityListener(ISMEntityListener *listener);
private:
SourceHook::List<ISMEntityListener *> m_EntListeners;
public:
/**
* Functions
@ -264,7 +274,7 @@ public:
void Hook_ThinkPost();
void Hook_Touch(CBaseEntity *pOther);
void Hook_TouchPost(CBaseEntity *pOther);
#if SOURCE_ENGINE == SE_ORANGEBOXVALVE || SOURCE_ENGINE == SE_CSS
#if SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_TF2
void Hook_TraceAttack(CTakeDamageInfoHack &info, const Vector &vecDir, trace_t *ptr, void *pUnknownJK);
void Hook_TraceAttackPost(CTakeDamageInfoHack &info, const Vector &vecDir, trace_t *ptr, void *pUnknownJK);
#else

View File

@ -39,17 +39,21 @@
offset = 0; \
g_pGameConf->GetOffset(#gamedataname, &offset); \
if (offset > 0) \
{ \
SH_MANUALHOOK_RECONFIGURE(gamedataname, offset, 0, 0); \
SET_PRE_##supportsPre(gamedataname) \
SET_POST_##supportsPost(gamedataname)
SET_POST_##supportsPost(gamedataname) \
}
#define CHECKOFFSET_W(gamedataname, supportsPre, supportsPost) \
offset = 0; \
g_pGameConf->GetOffset("Weapon_"#gamedataname, &offset); \
if (offset > 0) \
{ \
SH_MANUALHOOK_RECONFIGURE(Weapon_##gamedataname, offset, 0, 0); \
SET_PRE_##supportsPre(Weapon##gamedataname) \
SET_POST_##supportsPost(Weapon##gamedataname)
SET_POST_##supportsPost(Weapon##gamedataname) \
}
#define HOOKLOOP \
for(int i = g_HookList.Count() - 1; i >= 0; i--)

View File

@ -1300,6 +1300,7 @@
<ClCompile Include="..\sdk\smsdk_ext.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\..\public\extensions\ISDKHooks.h" />
<ClInclude Include="..\extension.h" />
<ClInclude Include="..\macros.h" />
<ClInclude Include="..\natives.h" />

View File

@ -56,6 +56,9 @@
<ClInclude Include="..\sdk\smsdk_ext.h">
<Filter>SourceMod SDK</Filter>
</ClInclude>
<ClInclude Include="..\..\..\public\extensions\ISDKHooks.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\version.rc">

View File

@ -57,10 +57,19 @@ cell_t Native_Hook(IPluginContext *pContext, const cell_t *params)
pContext->ThrowNativeError("Hook type not supported on this game");
break;
case HookRet_BadEntForHookType:
pContext->ThrowNativeError("Hook type not valid for this type of entity (%s)",
PEntityOfEntIndex(gamehelpers->ReferenceToIndex(params[1]))->GetClassName()
);
{
const char * pClassname = gamehelpers->GetEntityClassname(PEntityOfEntIndex(gamehelpers->ReferenceToIndex(params[1])));
if (!pClassname)
{
pContext->ThrowNativeError("Hook type not valid for this type of entity (%i).", entity);
}
else
{
pContext->ThrowNativeError("Hook type not valid for this type of entity (%s)", pClassname);
}
break;
}
}
return 0;
@ -107,7 +116,7 @@ cell_t Native_TakeDamage(IPluginContext *pContext, const cell_t *params)
if (!pInflictor)
return pContext->ThrowNativeError("Invalid entity index %d for inflictor", params[2]);
CBaseEntity *pAttacker = NULL;
CBaseEntity *pAttacker;
if (params[3] != -1)
{
pAttacker = UTIL_GetCBaseEntity(params[3]);
@ -116,21 +125,28 @@ cell_t Native_TakeDamage(IPluginContext *pContext, const cell_t *params)
return pContext->ThrowNativeError("Invalid entity index %d for attackerr", params[3]);
}
}
else
{
pAttacker = NULL;
}
float flDamage = sp_ctof(params[4]);
int iDamageType = params[5];
CBaseEntity *pWeapon = NULL;
CBaseEntity *pWeapon;
if (params[6] != -1)
{
pAttacker = UTIL_GetCBaseEntity(params[6]);
if (!pAttacker)
pWeapon = UTIL_GetCBaseEntity(params[6]);
if (!pWeapon)
{
return pContext->ThrowNativeError("Invalid entity index %d for weapon", params[6]);
}
}
else
{
pWeapon = NULL;
}
Vector vecDamageForce = Vector(0.0f, 0.0f, 0.0f);
cell_t *addr;
int err;
if ((err = pContext->LocalToPhysAddr(params[7], &addr)) != SP_ERROR_NONE)
@ -138,26 +154,29 @@ cell_t Native_TakeDamage(IPluginContext *pContext, const cell_t *params)
return pContext->ThrowNativeError("Could not read damageForce vector");
}
Vector vecDamageForce;
if (addr != pContext->GetNullRef(SP_NULL_VECTOR))
{
vecDamageForce = Vector(
sp_ctof(addr[0]),
sp_ctof(addr[1]),
sp_ctof(addr[2]));
vecDamageForce.Init(sp_ctof(addr[0]), sp_ctof(addr[1]), sp_ctof(addr[2]));
}
else
{
vecDamageForce.Init();
}
Vector vecDamagePosition = vec3_origin;
if ((err = pContext->LocalToPhysAddr(params[8], &addr)) != SP_ERROR_NONE)
{
return pContext->ThrowNativeError("Could not read damagePosition vector");
}
Vector vecDamagePosition;
if (addr != pContext->GetNullRef(SP_NULL_VECTOR))
{
vecDamagePosition = Vector(
sp_ctof(addr[0]),
sp_ctof(addr[1]),
sp_ctof(addr[2]));
vecDamagePosition.Init(sp_ctof(addr[0]), sp_ctof(addr[1]), sp_ctof(addr[2]));
}
else
{
vecDamagePosition = vec3_origin;
}
CTakeDamageInfoHack info(pInflictor, pAttacker, flDamage, iDamageType, pWeapon, vecDamageForce, vecDamagePosition);

View File

@ -62,7 +62,13 @@ CTakeDamageInfoHack::CTakeDamageInfoHack( CBaseEntity *pInflictor, CBaseEntity *
m_vecReportedPosition = vec3_origin;
m_iAmmoType = -1;
#if SOURCE_ENGINE == SE_ORANGEBOXVALVE || SOURCE_ENGINE == SE_CSS
#if SOURCE_ENGINE < SE_ORANGEBOX
m_iCustomKillType = 0;
#else
m_iDamageCustom = 0;
#endif
#if SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_TF2
m_iDamagedOtherPlayers = 0;
m_iPlayerPenetrateCount = 0;
m_flUnknown = 0.0f;

View File

@ -48,5 +48,6 @@ for i in SM.sdkInfo:
])
SM.PostSetupHL2Job(extension, binary, i)
SM.AutoVersion('extensions/sdktools', binary)
SM.ExtractDebugInfo(extension, binary)
binary.SendToJob()

View File

@ -370,7 +370,7 @@ void* eval_jump(void* src) {
else if (addr[0] == OP_JMP_BYTE) {
addr = &addr[OP_JMP_BYTE_SIZE] + *(char*)&addr[1];
//mangled 32bit jump?
if (addr[0] = OP_JMP) {
if (addr[0] == OP_JMP) {
addr = addr + *(int*)&addr[1];
}
return addr;

View File

@ -43,6 +43,7 @@
#include "gamerulesnatives.h"
#include <ISDKTools.h>
#include "clientnatives.h"
#include "teamnatives.h"
/**
* @file extension.cpp
* @brief Implements SDK Tools extension code.
@ -279,6 +280,12 @@ void SDKTools::SDK_OnAllLoaded()
InitializeValveGlobals();
}
void SDKTools::OnCoreMapStart(edict_t *pEdictList, int edictCount, int clientMax)
{
InitTeamNatives();
GetResourceEntity();
}
bool SDKTools::QueryRunning(char *error, size_t maxlength)
{
SM_CHECK_IFACE(BINTOOLS, g_pBinTools);

View File

@ -135,8 +135,6 @@ extern ICallWrapper *g_pAcceptInput;
extern SourceHook::CallClass<IVEngineServer> *enginePatch;
extern SourceHook::CallClass<IEngineSound> *enginesoundPatch;
extern const char *tools_GetTeamName(int team);
#include <compat_wrappers.h>
#define ENGINE_CALL(func) SH_CALL(enginePatch, &IVEngineServer::func)

View File

@ -174,7 +174,7 @@ static cell_t GameRules_GetProp(IPluginContext *pContext, const cell_t *params)
is_unsigned = ((pProp->GetFlags() & SPROP_UNSIGNED) == SPROP_UNSIGNED);
// This isn't in CS:S yet, but will be, doesn't hurt to add now, and will save us a build later
#if SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_ORANGEBOXVALVE
#if SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_TF2
if (pProp->GetFlags() & SPROP_VARINT)
{
bit_count = sizeof(int) * 8;
@ -243,8 +243,7 @@ static cell_t GameRules_SetProp(IPluginContext *pContext, const cell_t *params)
FIND_PROP_SEND(DPT_Int, "integer");
// This isn't in CS:S yet, but will be, doesn't hurt to add now, and will save us a build later
#if SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_ORANGEBOXVALVE
#if SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_TF2
if (pProp->GetFlags() & SPROP_VARINT)
{
bit_count = sizeof(int) * 8;

View File

@ -53,7 +53,12 @@ void CHookManager::Initialize()
SH_MANUALHOOK_RECONFIGURE(PlayerRunCmdHook, offset, 0, 0);
PRCH_enabled = true;
}
else
{
g_pSM->LogError(myself, "Failed to find PlayerRunCmd offset - OnPlayerRunCmd forward disabled.");
PRCH_enabled = false;
}
plsys->AddPluginsListener(this);
sharesys->AddCapabilityProvider(myself, this, FEATURECAP_PLAYERRUNCMD_11PARAMS);

View File

@ -1325,6 +1325,7 @@
<ClInclude Include="..\hooks.h" />
<ClInclude Include="..\..\..\public\extensions\ISDKTools.h" />
<ClInclude Include="..\output.h" />
<ClInclude Include="..\teamnatives.h" />
<ClInclude Include="..\tempents.h" />
<ClInclude Include="..\vcallbuilder.h" />
<ClInclude Include="..\vdecoder.h" />

View File

@ -137,6 +137,9 @@
<ClInclude Include="..\clientnatives.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\teamnatives.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\version.rc">

View File

@ -30,6 +30,7 @@
*/
#include "extension.h"
#include "vhelpers.h"
#include <sh_vector.h>
struct TeamInfo
@ -42,36 +43,13 @@ const char *m_iScore;
SourceHook::CVector<TeamInfo> g_Teams;
bool FindTeamEntities(SendTable *pTable, const char *name)
{
if (strcmp(pTable->GetName(), name) == 0)
{
return true;
}
int props = pTable->GetNumProps();
SendProp *prop;
for (int i=0; i<props; i++)
{
prop = pTable->GetProp(i);
if (prop->GetDataTable())
{
if (FindTeamEntities(prop->GetDataTable(), name))
{
return true;
}
}
}
return false;
}
void SDKTools::OnCoreMapStart(edict_t *pEdictList, int edictCount, int clientMax)
void InitTeamNatives()
{
g_Teams.clear();
g_Teams.resize(1);
int edictCount = gpGlobals->maxEntities;
for (int i=0; i<edictCount; i++)
{
edict_t *pEdict = PEntityOfEntIndex(i);
@ -85,7 +63,7 @@ void SDKTools::OnCoreMapStart(edict_t *pEdictList, int edictCount, int clientMax
}
ServerClass *pClass = pEdict->GetNetworkable()->GetServerClass();
if (FindTeamEntities(pClass->m_pTable, "DT_Team"))
if (FindNestedDataTable(pClass->m_pTable, "DT_Team"))
{
SendProp *pTeamNumProp = g_pGameHelpers->FindInSendTable(pClass->GetName(), "m_iTeamNum");
@ -186,6 +164,11 @@ static cell_t GetTeamScore(IPluginContext *pContext, const cell_t *params)
static cell_t SetTeamScore(IPluginContext *pContext, const cell_t *params)
{
if (!g_pSM->IsMapRunning())
{
return pContext->ThrowNativeError("Cannot set team score when no map is running");
}
int teamindex = params[1];
if (teamindex >= (int)g_Teams.size() || !g_Teams[teamindex].ClassName)
{

View File

@ -0,0 +1,39 @@
/**
* vim: set ts=4 :
* =============================================================================
* SourceMod SDKTools Extension
* 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_TEAMNATIVES_H_
#define _INCLUDE_SOURCEMOD_TEAMNATIVES_H_
void InitTeamNatives();
extern const char *tools_GetTeamName(int team);
#endif //_INCLUDE_SOURCEMOD_TEAMNATIVES_H_

View File

@ -129,7 +129,7 @@ static cell_t PrepSDKCall_SetSignature(IPluginContext *pContext, const cell_t *p
{
return 0;
}
#if (SOURCE_ENGINE == SE_CSS) || (SOURCE_ENGINE == SE_ORANGEBOXVALVE) || (SOURCE_ENGINE == SE_LEFT4DEAD) || (SOURCE_ENGINE == SE_LEFT4DEAD2) || (SOURCE_ENGINE == SE_CSGO)
#if (SOURCE_ENGINE == SE_CSS) || (SOURCE_ENGINE == SE_HL2DM) || (SOURCE_ENGINE == SE_DODS) || (SOURCE_ENGINE == SE_TF2) || (SOURCE_ENGINE == SE_LEFT4DEAD) || (SOURCE_ENGINE == SE_LEFT4DEAD2) || (SOURCE_ENGINE == SE_NUCLEARDAWN) || (SOURCE_ENGINE == SE_CSGO)
s_call_addr = memutils->ResolveSymbol(handle, &sig[1]);
#else
s_call_addr = dlsym(handle, &sig[1]);

View File

@ -30,9 +30,11 @@
*/
#include "extension.h"
#include "vhelpers.h"
void **g_pGameRules = NULL;
void *g_EntList = NULL;
CBaseHandle g_ResourceEntity;
void InitializeValveGlobals()
@ -183,6 +185,56 @@ void GetIServer()
}
#endif
void GetResourceEntity()
{
g_ResourceEntity.Term();
#if SOURCE_ENGINE >= SE_ORANGEBOX
const char *classname = g_pGameConf->GetKeyValue("ResourceEntityClassname");
if (classname != NULL)
{
for (CBaseEntity *pEntity = (CBaseEntity *)servertools->FirstEntity(); pEntity; pEntity = (CBaseEntity *)servertools->NextEntity(pEntity))
{
if (!strcmp(gamehelpers->GetEntityClassname(pEntity), classname))
{
g_ResourceEntity = ((IHandleEntity *)pEntity)->GetRefEHandle();
break;
}
}
}
else
#endif
{
int edictCount = gpGlobals->maxEntities;
for (int i=0; i<edictCount; i++)
{
edict_t *pEdict = PEntityOfEntIndex(i);
if (!pEdict || pEdict->IsFree())
{
continue;
}
if (!pEdict->GetNetworkable())
{
continue;
}
IHandleEntity *pHandleEnt = pEdict->GetNetworkable()->GetEntityHandle();
if (!pHandleEnt)
{
continue;
}
ServerClass *pClass = pEdict->GetNetworkable()->GetServerClass();
if (FindNestedDataTable(pClass->m_pTable, "DT_PlayerResource"))
{
g_ResourceEntity = pHandleEnt->GetRefEHandle();
break;
}
}
}
}
const char *GetDTTypeName(int type)
{
switch (type)
@ -211,6 +263,12 @@ const char *GetDTTypeName(int type)
{
return "datatable";
}
#if SOURCE_ENGINE >= SE_ALIENSWARM
case DPT_Int64:
{
return "int64";
}
#endif
default:
{
return NULL;

View File

@ -35,9 +35,13 @@
extern void **g_pGameRules;
extern void *g_EntList;
extern CBaseHandle g_ResourceEntity;
void InitializeValveGlobals();
void GetIServer();
void GetResourceEntity();
const char *GetDTTypeName(int type);
#endif // _INCLUDE_SDKTOOLS_VGLOBALS_H_

View File

@ -279,6 +279,31 @@ void ShutdownHelpers()
s_EyeAngles.Shutdown();
}
bool FindNestedDataTable(SendTable *pTable, const char *name)
{
if (strcmp(pTable->GetName(), name) == 0)
{
return true;
}
int props = pTable->GetNumProps();
SendProp *prop;
for (int i=0; i<props; i++)
{
prop = pTable->GetProp(i);
if (prop->GetDataTable())
{
if (FindNestedDataTable(prop->GetDataTable(), name))
{
return true;
}
}
}
return false;
}
void UTIL_DrawSendTable_XML(FILE *fp, SendTable *pTable, int space_count)
{
char spaces[255];

View File

@ -72,4 +72,6 @@ bool GetPlayerInfo(int client, player_info_t *info);
void ShutdownHelpers();
bool FindNestedDataTable(SendTable *pTable, const char *name);
#endif //_INCLUDE_SDKTOOLS_VHELPERS_H_

View File

@ -140,6 +140,39 @@ static cell_t RemovePlayerItem(IPluginContext *pContext, const cell_t *params)
return ret ? 1 : 0;
}
#if SOURCE_ENGINE == SE_CSGO
class CEconItemView;
static cell_t GiveNamedItem(IPluginContext *pContext, const cell_t *params)
{
static ValveCall *pCall = NULL;
if (!pCall)
{
ValvePassInfo pass[5];
InitPass(pass[0], Valve_String, PassType_Basic, PASSFLAG_BYVAL);
InitPass(pass[1], Valve_POD, PassType_Basic, PASSFLAG_BYVAL);
InitPass(pass[2], Valve_POD, PassType_Basic, PASSFLAG_BYVAL);
InitPass(pass[3], Valve_Bool, PassType_Basic, PASSFLAG_BYVAL);
InitPass(pass[4], Valve_CBaseEntity, PassType_Basic, PASSFLAG_BYVAL);
if (!CreateBaseCall("GiveNamedItem", ValveCall_Player, &pass[4], pass, 4, &pCall))
{
return pContext->ThrowNativeError("\"GiveNamedItem\" not supported by this mod");
} else if (!pCall) {
return pContext->ThrowNativeError("\"GiveNamedItem\" wrapper failed to initialize");
}
}
CBaseEntity *pEntity = NULL;
START_CALL();
DECODE_VALVE_PARAM(1, thisinfo, 0);
DECODE_VALVE_PARAM(2, vparams, 0);
DECODE_VALVE_PARAM(3, vparams, 1);
*(CEconItemView **)(vptr + 12) = NULL;
*(bool *)(vptr + 16) = false;
FINISH_CALL_SIMPLE(&pEntity);
return gamehelpers->EntityToBCompatRef(pEntity);
}
#else
static cell_t GiveNamedItem(IPluginContext *pContext, const cell_t *params)
{
static ValveCall *pCall = NULL;
@ -166,6 +199,7 @@ static cell_t GiveNamedItem(IPluginContext *pContext, const cell_t *params)
return gamehelpers->EntityToBCompatRef(pEntity);
}
#endif
static cell_t GetPlayerWeaponSlot(IPluginContext *pContext, const cell_t *params)
{
@ -528,7 +562,7 @@ static cell_t SlapPlayer(IPluginContext *pContext, const cell_t *params)
CellRecipientFilter rf;
rf.SetToReliable(true);
rf.Initialize(player_list, total_players);
#if SOURCE_ENGINE == SE_ORANGEBOXVALVE || SOURCE_ENGINE == SE_CSS
#if SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_TF2
engsound->EmitSound(rf, params[1], CHAN_AUTO, sound_name, VOL_NORM, ATTN_NORM, 0, PITCH_NORM, 0, &pos);
#elif SOURCE_ENGINE < SE_PORTAL2
engsound->EmitSound(rf, params[1], CHAN_AUTO, sound_name, VOL_NORM, ATTN_NORM, 0, PITCH_NORM, &pos);
@ -1208,6 +1242,16 @@ static cell_t SetClientInfo(IPluginContext *pContext, const cell_t *params)
return 1;
}
static cell_t GetPlayerResourceEntity(IPluginContext *pContext, const cell_t *params)
{
if (gamehelpers->GetHandleEntity(g_ResourceEntity) != NULL)
{
return g_ResourceEntity.GetEntryIndex();
}
return -1;
}
sp_nativeinfo_t g_Natives[] =
{
{"ExtinguishEntity", ExtinguishEntity},
@ -1235,5 +1279,6 @@ sp_nativeinfo_t g_Natives[] =
{"EquipPlayerWeapon", WeaponEquip},
{"ActivateEntity", ActivateEntity},
{"SetClientInfo", SetClientInfo},
{"GetPlayerResourceEntity", GetPlayerResourceEntity},
{NULL, NULL},
};

View File

@ -36,7 +36,7 @@ SH_DECL_HOOK8_void(IVEngineServer, EmitAmbientSound, SH_NOATTRIB, 0, int, const
#if SOURCE_ENGINE >= SE_PORTAL2
SH_DECL_HOOK17(IEngineSound, EmitSound, SH_NOATTRIB, 0, int, IRecipientFilter &, int, int, const char *, unsigned int, const char *, float, float, int, int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int);
SH_DECL_HOOK17(IEngineSound, EmitSound, SH_NOATTRIB, 1, int, IRecipientFilter &, int, int, const char *, unsigned int, const char *, float, soundlevel_t, int, int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int);
#elif SOURCE_ENGINE == SE_ORANGEBOXVALVE || SOURCE_ENGINE == SE_CSS
#elif SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_TF2
SH_DECL_HOOK15_void(IEngineSound, EmitSound, SH_NOATTRIB, 0, IRecipientFilter &, int, int, const char *, float, float, int, int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int);
SH_DECL_HOOK15_void(IEngineSound, EmitSound, SH_NOATTRIB, 1, IRecipientFilter &, int, int, const char *, float, soundlevel_t, int, int, int, const Vector *, const Vector *, CUtlVector<Vector> *, bool, float, int);
#else
@ -265,7 +265,7 @@ int SoundHooks::OnEmitSound(IRecipientFilter &filter, int iEntIndex, int iChanne
float flVolume, soundlevel_t iSoundlevel, int nSeed, int iFlags, int iPitch, const Vector *pOrigin,
const Vector *pDirection, CUtlVector<Vector> *pUtlVecOrigins, bool bUpdatePositions,
float soundtime, int speakerentity)
#elif SOURCE_ENGINE == SE_ORANGEBOXVALVE || SOURCE_ENGINE == SE_CSS
#elif SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_TF2
void SoundHooks::OnEmitSound(IRecipientFilter &filter, int iEntIndex, int iChannel, const char *pSample,
float flVolume, soundlevel_t iSoundlevel, int iFlags, int iPitch, int iSpecialDSP, const Vector *pOrigin,
const Vector *pDirection, CUtlVector<Vector> *pUtlVecOrigins, bool bUpdatePositions,
@ -326,7 +326,7 @@ void SoundHooks::OnEmitSound(IRecipientFilter &filter, int iEntIndex, int iChann
(crf, iEntIndex, iChannel, buffer, -1, buffer, flVolume, iSoundlevel, nSeed, iFlags, iPitch, pOrigin,
pDirection, pUtlVecOrigins, bUpdatePositions, soundtime, speakerentity)
);
#elif SOURCE_ENGINE == SE_ORANGEBOXVALVE || SOURCE_ENGINE == SE_CSS
#elif SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_TF2
RETURN_META_NEWPARAMS(
MRES_IGNORED,
static_cast<void (IEngineSound::*)(IRecipientFilter &, int, int, const char*, float, soundlevel_t,
@ -357,7 +357,7 @@ int SoundHooks::OnEmitSound2(IRecipientFilter &filter, int iEntIndex, int iChann
float flVolume, float flAttenuation, int nSeed, int iFlags, int iPitch, const Vector *pOrigin,
const Vector *pDirection, CUtlVector<Vector> *pUtlVecOrigins, bool bUpdatePositions,
float soundtime, int speakerentity)
#elif SOURCE_ENGINE == SE_ORANGEBOXVALVE || SOURCE_ENGINE == SE_CSS
#elif SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_TF2
void SoundHooks::OnEmitSound2(IRecipientFilter &filter, int iEntIndex, int iChannel, const char *pSample,
float flVolume, float flAttenuation, int iFlags, int iPitch, int iSpecialDSP, const Vector *pOrigin,
const Vector *pDirection, CUtlVector<Vector> *pUtlVecOrigins, bool bUpdatePositions,
@ -419,7 +419,7 @@ void SoundHooks::OnEmitSound2(IRecipientFilter &filter, int iEntIndex, int iChan
(crf, iEntIndex, iChannel, buffer, -1, buffer, flVolume, SNDLVL_TO_ATTN(static_cast<soundlevel_t>(sndlevel)),
nSeed, iFlags, iPitch, pOrigin, pDirection, pUtlVecOrigins, bUpdatePositions, soundtime, speakerentity)
);
#elif SOURCE_ENGINE == SE_ORANGEBOXVALVE || SOURCE_ENGINE == SE_CSS
#elif SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_TF2
RETURN_META_NEWPARAMS(
MRES_IGNORED,
static_cast<void (IEngineSound::*)(IRecipientFilter &, int, int, const char *, float, float,
@ -683,7 +683,7 @@ static cell_t EmitSound(IPluginContext *pContext, const cell_t *params)
soundtime,
speakerentity);
}
#elif SOURCE_ENGINE == SE_ORANGEBOXVALVE || SOURCE_ENGINE == SE_CSS
#elif SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_TF2
if (g_InSoundHook)
{
SH_CALL(enginesoundPatch,
@ -811,7 +811,7 @@ static cell_t EmitSound(IPluginContext *pContext, const cell_t *params)
soundtime,
speakerentity);
}
#elif SOURCE_ENGINE == SE_ORANGEBOXVALVE || SOURCE_ENGINE == SE_CSS
#elif SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_TF2
if (g_InSoundHook)
{
SH_CALL(enginesoundPatch,
@ -984,7 +984,7 @@ static cell_t EmitSentence(IPluginContext *pContext, const cell_t *params)
#endif
flags,
pitch,
#if SOURCE_ENGINE == SE_ORANGEBOXVALVE || SOURCE_ENGINE == SE_CSS
#if SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_TF2
0,
#endif
pOrigin,

View File

@ -63,7 +63,7 @@ public:
#else
void OnEmitAmbientSound(int entindex, const Vector &pos, const char *samp, float vol,
soundlevel_t soundlevel, int fFlags, int pitch, float delay);
#if SOURCE_ENGINE == SE_ORANGEBOXVALVE || SOURCE_ENGINE == SE_CSS
#if SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_TF2
void OnEmitSound(IRecipientFilter& filter, int iEntIndex, int iChannel, const char *pSample, float flVolume,
soundlevel_t iSoundlevel, int iFlags, int iPitch, int iSpecialDSP, const Vector *pOrigin,
@ -82,7 +82,7 @@ public:
float flAttenuation, int iFlags, int iPitch, const Vector *pOrigin,
const Vector *pDirection, CUtlVector<Vector> *pUtlVecOrigins, bool bUpdatePositions,
float soundtime, int speakerentity);
#endif // SOURCE_ENGINE == SE_ORANGEBOXVALVE || SOURCE_ENGINE == SE_CSS
#endif // SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_TF2
#endif // SOURCE_ENGINE >= SE_PORTAL2
private:
size_t _FillInPlayers(int *pl_array, IRecipientFilter *pFilter);

View File

@ -17,5 +17,6 @@ files = [
]
binary.AddSourceFiles('extensions/sqlite', files)
SM.AutoVersion('extensions/sqlite', binary)
SM.ExtractDebugInfo(extension, binary)
binary.SendToJob()

View File

@ -1,15 +1,15 @@
# vim: set ts=2 sw=2 tw=99 noet ft=python:
import os
sdk = SM.sdkInfo['ep2v']
compiler = SM.DefaultHL2Compiler('extensions/tf2', 'ep2v')
sdk = SM.sdkInfo['tf2']
compiler = SM.DefaultHL2Compiler('extensions/tf2', 'tf2')
if compiler.cc.name == 'gcc' or compiler.cc.name == 'clang':
compiler['CFLAGS'].append('-Wno-parentheses')
name = 'game.tf2.ext.' + sdk['ext']
extension = AMBuild.AddJob(name)
binary = Cpp.LibraryBuilder(name, AMBuild, extension, compiler)
SM.PreSetupHL2Job(extension, binary, 'ep2v')
SM.PreSetupHL2Job(extension, binary, 'tf2')
binary.AddSourceFiles('extensions/tf2', [
'extension.cpp',
'natives.cpp',
@ -24,7 +24,8 @@ binary.AddSourceFiles('extensions/tf2', [
'sdk/smsdk_ext.cpp',
'asm/asm.c'
])
SM.PostSetupHL2Job(extension, binary, 'ep2v')
SM.AutoVersion('extensions/tf2', binary)
SM.PostSetupHL2Job(extension, binary, 'tf2')
SM.AutoVersion('extensions/tf2', binary)
SM.ExtractDebugInfo(extension, binary)
binary.SendToJob()

View File

@ -441,6 +441,8 @@ TFClassType ClassnameToType(const char *classname)
trie.insert("demo", TFClass_DemoMan);
trie.insert("medic", TFClass_Medic);
trie.insert("heavy", TFClass_Heavy);
trie.insert("heavyweap", TFClass_Heavy);
trie.insert("heavyweapons", TFClass_Heavy);
trie.insert("hwg", TFClass_Heavy);
trie.insert("pyro", TFClass_Pyro);
trie.insert("spy", TFClass_Spy);

View File

@ -236,7 +236,7 @@ cell_t TF2_AddCondition(IPluginContext *pContext, const cell_t *params)
{
static ICallWrapper *pWrapper = NULL;
// CTFPlayerShared::AddCond(int, float)
// CTFPlayerShared::AddCond(int, float, CBaseEntity *)
if (!pWrapper)
{
REGISTER_NATIVE_ADDR("AddCondition",
@ -259,6 +259,13 @@ cell_t TF2_AddCondition(IPluginContext *pContext, const cell_t *params)
return pContext->ThrowNativeError("Client index %d is not valid", params[1]);
}
CBaseEntity *pInflictor = NULL;
// Compatibility fix for the new inflictor parameter; TF2 seems to only use player entities in it
if (params[0] >= 4 && params[4] > 0 && !(pInflictor = UTIL_GetCBaseEntity(params[4], true)))
{
return pContext->ThrowNativeError("Inflictor index %d is not valid", params[4]);
}
void *obj = (void *)((uint8_t *)pEntity + playerSharedOffset->actual_offset);
unsigned char vstk[sizeof(void *) + sizeof(int) + sizeof(float) + sizeof(CBaseEntity *)];
@ -270,7 +277,7 @@ cell_t TF2_AddCondition(IPluginContext *pContext, const cell_t *params)
vptr += sizeof(int);
*(float *)vptr = *(float *)&params[3];
vptr += sizeof(float);
*(CBaseEntity **)vptr = NULL;
*(CBaseEntity **)vptr = pInflictor;
pWrapper->Execute(vstk, NULL);

View File

@ -15,5 +15,6 @@ binary.AddSourceFiles('extensions/topmenus', [
'sdk/sm_memtable.cpp'
])
SM.AutoVersion('extensions/topmenus', binary)
SM.ExtractDebugInfo(extension, binary)
binary.SendToJob()

View File

@ -14,5 +14,6 @@ binary.AddSourceFiles('extensions/updater', [
'sdk/smsdk_ext.cpp'
])
SM.AutoVersion('extensions/updater', binary)
SM.ExtractDebugInfo(extension, binary)
binary.SendToJob()

View File

@ -24,6 +24,7 @@
"plugin_24602c74f183cfcd157b3d50dee96c52" "" /* UCP Server (Endi) - Version 7.8.3 */
"plugin_78140f1a0f26cd3297767d0598eac4b1" "" /* [Any] PReplay (DarthNinja) - Version 1.0.0 */
"plugin_55923ba6bfe41569a3e4fbd7ca4606e5" "" /* VIP Plugin (World-Source.Ru) - Version 2.0 */
"plugin_4bf983e1d5b61ba0b1ab9a7e53bfda27" "" /* WarMod CS:GO (Twelve-60) */
}
}
}

View File

@ -6,51 +6,51 @@
{
"EndTouch"
{
"windows" "102"
"linux" "103"
"mac" "103"
"windows" "103"
"linux" "104"
"mac" "104"
}
"FireBullets"
{
"windows" "115"
"linux" "116"
"mac" "116"
"windows" "116"
"linux" "117"
"mac" "117"
}
"GetMaxHealth"
{
"windows" "119"
"linux" "120"
"mac" "120"
"windows" "120"
"linux" "121"
"mac" "121"
}
"GroundEntChanged"
{
"windows" "173"
"linux" "174"
"mac" "174"
"windows" "175"
"linux" "176"
"mac" "176"
}
"OnTakeDamage"
{
"windows" "66"
"linux" "67"
"mac" "67"
"windows" "67"
"linux" "68"
"mac" "68"
}
"PreThink"
{
"windows" "356"
"linux" "357"
"mac" "357"
"windows" "362"
"linux" "363"
"mac" "363"
}
"PostThink"
{
"windows" "357"
"linux" "358"
"mac" "358"
"windows" "363"
"linux" "364"
"mac" "364"
}
"Reload"
{
"windows" "281"
"linux" "282"
"mac" "282"
"windows" "309"
"linux" "310"
"mac" "310"
}
"SetTransmit"
{
@ -71,79 +71,79 @@
"mac" "25"
}
"StartTouch"
{
"windows" "100"
"linux" "101"
"mac" "101"
}
"Think"
{
"windows" "50"
"linux" "51"
"mac" "51"
}
"Touch"
{
"windows" "101"
"linux" "102"
"mac" "102"
}
"Think"
{
"windows" "51"
"linux" "52"
"mac" "52"
}
"Touch"
{
"windows" "102"
"linux" "103"
"mac" "103"
}
"TraceAttack"
{
"windows" "64"
"linux" "65"
"mac" "65"
"windows" "65"
"linux" "66"
"mac" "66"
}
"Use"
{
"windows" "99"
"linux" "100"
"mac" "100"
"windows" "100"
"linux" "101"
"mac" "101"
}
"VPhysicsUpdate"
{
"windows" "152"
"linux" "153"
"mac" "153"
"windows" "153"
"linux" "154"
"mac" "154"
}
"Weapon_CanSwitchTo"
{
"windows" "281"
"linux" "282"
"mac" "282"
"windows" "284"
"linux" "285"
"mac" "285"
}
"Weapon_CanUse"
{
"windows" "275"
"linux" "276"
"mac" "276"
}
"Weapon_Drop"
{
"windows" "278"
"linux" "279"
"mac" "279"
}
"Weapon_Equip"
"Weapon_Drop"
{
"windows" "276"
"linux" "277"
"mac" "277"
"windows" "281"
"linux" "282"
"mac" "282"
}
"Weapon_Switch"
"Weapon_Equip"
{
"windows" "279"
"linux" "280"
"mac" "280"
}
"Weapon_Switch"
{
"windows" "282"
"linux" "283"
"mac" "283"
}
// no longer used
"UpdateOnRemove"
{
"windows" "108"
"linux" "109"
"mac" "109"
"windows" "109"
"linux" "110"
"mac" "110"
}
//
}

View File

@ -5,9 +5,7 @@
{
"#supported"
{
"game" "tf"
"game" "hl2mp"
"game" "dod"
}
"Offsets"
@ -169,6 +167,174 @@
//
}
}
// Now this is getting ridiculous
"#default"
{
"#supported"
{
"game" "tf"
"game" "dod"
}
"Offsets"
{
"EndTouch"
{
"windows" "100"
"linux" "101"
"mac" "101"
}
"FireBullets"
{
"windows" "112"
"linux" "113"
"mac" "113"
}
"GetMaxHealth"
{
"windows" "117"
"linux" "118"
"mac" "118"
}
"GroundEntChanged"
{
"windows" "178"
"linux" "179"
"mac" "179"
}
"OnTakeDamage"
{
"windows" "62"
"linux" "63"
"mac" "63"
}
"PreThink"
{
"windows" "331"
"linux" "332"
"mac" "332"
}
"PostThink"
{
"windows" "332"
"linux" "333"
"mac" "333"
}
"Reload"
{
"windows" "271"
"linux" "277"
"mac" "277"
}
"SetTransmit"
{
"windows" "20"
"linux" "21"
"mac" "21"
}
"ShouldCollide"
{
"windows" "16"
"linux" "17"
"mac" "17"
}
"Spawn"
{
"windows" "22"
"linux" "23"
"mac" "23"
}
"StartTouch"
{
"windows" "98"
"linux" "99"
"mac" "99"
}
"Think"
{
"windows" "47"
"linux" "48"
"mac" "48"
}
"Touch"
{
"windows" "99"
"linux" "100"
"mac" "100"
}
"TraceAttack"
{
"windows" "60"
"linux" "61"
"mac" "61"
}
"Use"
{
"windows" "97"
"linux" "98"
"mac" "98"
}
"VPhysicsUpdate"
{
"windows" "157"
"linux" "158"
"mac" "158"
}
"Weapon_CanSwitchTo"
{
"windows" "265"
"linux" "266"
"mac" "266"
}
"Weapon_CanUse"
{
"windows" "259"
"linux" "260"
"mac" "260"
}
"Weapon_Drop"
{
"windows" "262"
"linux" "263"
"mac" "263"
}
"Weapon_Equip"
{
"windows" "260"
"linux" "261"
"mac" "261"
}
"Weapon_Switch"
{
"windows" "263"
"linux" "264"
"mac" "264"
}
// no longer used
"UpdateOnRemove"
{
"windows" "105"
"linux" "106"
"mac" "106"
}
//
}
"Signatures"
{
// no longer used
"IEntityFactoryDictionary"
{
"library" "server"
"windows" "\xB8\x01\x00\x00\x00\x84\x2A\x2A\x2A\x2A\x2A\x75\x1D\x09\x2A\x2A\x2A\x2A\x2A\xB9\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A\x68\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A\x83\xC4\x04\xB8\x2A\x2A\x2A\x2A\xC3"
"linux" "@_Z23EntityFactoryDictionaryv"
"mac" "@_Z23EntityFactoryDictionaryv"
}
//
}
}
"#default"
{

View File

@ -8,101 +8,121 @@
{
"windows" "97"
"linux" "98"
"mac" "98"
}
"FireBullets"
{
"windows" "109"
"linux" "110"
"mac" "110"
}
"OnTakeDamage"
{
"windows" "62"
"linux" "63"
"mac" "63"
}
"PreThink"
{
"windows" "333"
"linux" "334"
"mac" "334"
}
"PostThink"
{
"windows" "334"
"linux" "335"
"mac" "335"
}
"SetTransmit"
{
"windows" "19"
"linux" "20"
"mac" "20"
}
"ShouldCollide"
{
"windows" "15"
"linux" "16"
"mac" "16"
}
"Spawn"
{
"windows" "21"
"linux" "22"
"mac" "22"
}
"StartTouch"
{
"windows" "95"
"linux" "96"
"mac" "96"
}
"Think"
{
"windows" "47"
"linux" "48"
"mac" "48"
}
"Touch"
{
"windows" "96"
"linux" "97"
"mac" "97"
}
"TraceAttack"
{
"windows" "60"
"linux" "61"
"mac" "61"
}
"UpdateOnRemove"
{
"windows" "102"
"linux" "103"
"mac" "103"
}
"Use"
{
"windows" "94"
"linux" "95"
"mac" "95"
}
"VPhysicsUpdate"
{
"windows" "152"
"linux" "153"
"mac" "153"
}
"Weapon_CanSwitchTo"
{
"windows" "265"
"linux" "266"
"mac" "266"
}
"Weapon_CanUse"
{
"windows" "259"
"linux" "260"
"mac" "260"
}
"Weapon_Drop"
{
"windows" "262"
"linux" "263"
"mac" "263"
}
"Weapon_Equip"
{
"windows" "260"
"linux" "261"
"mac" "261"
}
"Weapon_Switch"
{
"windows" "263"
"linux" "264"
"mac" "264"
}
}
@ -113,6 +133,7 @@
"library" "server"
"windows" "\xB8\x01\x00\x00\x00\x84\x2A\x2A\x2A\x2A\x2A\x75\x1D\x09\x2A\x2A\x2A\x2A\x2A\xB9\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A\x68\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A\x83\xC4\x04\xB8\x2A\x2A\x2A\x2A\xC3"
"linux" "@_Z23EntityFactoryDictionaryv"
"mac" "@_Z23EntityFactoryDictionaryv"
}
}
}

View File

@ -24,9 +24,9 @@
}
"GroundEntChanged"
{
"windows" "176"
"linux" "177"
"mac" "177"
"windows" "177"
"linux" "178"
"mac" "178"
}
"OnTakeDamage"
{

View File

@ -0,0 +1,115 @@
"Games"
{
/* HL2:CTF 2.1 */
"hl2ctf"
{
"Offsets"
{
"EndTouch"
{
"windows" "83"
"linux" "84"
}
"FireBullets"
{
"windows" "93"
"Linux" "94"
}
"GroundEntChanged"
{
"windows" "146"
"linux" "147"
}
"OnTakeDamage"
{
"windows" "54"
"linux" "55"
}
"PreThink"
{
"windows" "247"
"linux" "248"
}
"PostThink"
{
"windows" "248"
"linux" "249"
}
"SetTransmit"
{
"windows" "21"
"linux" "22"
}
"ShouldCollide"
{
"windows" "17"
"linux" "18"
}
"Spawn"
{
"windows" "23"
"linux" "24"
}
"StartTouch"
{
"windows" "81"
"linux" "82"
}
"Think"
{
"windows" "45"
"linux" "46"
}
"Touch"
{
"windows" "82"
"linux" "83"
}
"TraceAttack"
{
"windows" "53"
"linux" "54"
}
"VPhysicsUpdate"
{
"windows" "130"
"linux" "131"
}
"Weapon_CanSwitchTo"
{
"windows" "205"
"linux" "206"
}
"Weapon_CanUse"
{
"windows" "199"
"linux" "200"
}
"Weapon_Drop"
{
"windows" "202"
"linux" "203"
}
"Weapon_Equip"
{
"windows" "200"
"linux" "201"
}
"Weapon_Switch"
{
"windows" "203"
"linux" "204"
}
"Reload"
{
"windows" "213"
"linux" "214"
}
"Use"
{
"windows" "80"
"linux" "81"
}
}
}
}

View File

@ -20,11 +20,13 @@
{
"windows" "108"
"linux" "109"
"mac" "109"
}
"FireBullets"
{
"windows" "121"
"linux" "122"
"mac" "122"
}
"GetMaxHealth"
{
@ -36,96 +38,115 @@
{
"windows" "71"
"linux" "72"
"mac" "72"
}
"PreThink"
{
"windows" "355"
"linux" "356"
"mac" "356"
}
"PostThink"
{
"windows" "356"
"linux" "357"
"mac" "357"
}
"Reload"
{
"windows" "280"
"linux" "281"
"mac" "281"
}
"SetTransmit"
{
"windows" "21"
"linux" "22"
"mac" "22"
}
"ShouldCollide"
{
"windows" "17"
"linux" "18"
"mac" "18"
}
"Spawn"
{
"windows" "23"
"linux" "24"
"mac" "24"
}
"StartTouch"
{
"windows" "106"
"linux" "107"
"mac" "107"
}
"Think"
{
"windows" "55"
"linux" "56"
"mac" "56"
}
"Touch"
{
"windows" "107"
"linux" "108"
"mac" "108"
}
"TraceAttack"
{
"windows" "69"
"linux" "70"
"mac" "70"
}
"UpdateOnRemove"
{
"windows" "114"
"linux" "115"
"mac" "115"
}
"Use"
{
"windows" "105"
"linux" "106"
"mac" "106"
}
"VPhysicsUpdate"
{
"windows" "165"
"linux" "166"
"mac" "166"
}
"Weapon_CanSwitchTo"
{
"windows" "285"
"linux" "286"
"mac" "286"
}
"Weapon_CanUse"
{
"windows" "279"
"linux" "280"
"mac" "280"
}
"Weapon_Drop"
{
"windows" "282"
"linux" "283"
"mac" "283"
}
"Weapon_Equip"
{
"windows" "280"
"linux" "281"
"mac" "281"
}
"Weapon_Switch"
{
"windows" "283"
"linux" "284"
"mac" "284"
}
}
@ -136,6 +157,7 @@
"library" "server"
"windows" "\xB8\x01\x00\x00\x00\x84\x2A\x2A\x2A\x2A\x2A\x75\x1D\x09\x2A\x2A\x2A\x2A\x2A\xB9\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A\x68\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A\x83\xC4\x04\xB8\x2A\x2A\x2A\x2A\xC3"
"linux" "@_Z23EntityFactoryDictionaryv"
"mac" "@_Z23EntityFactoryDictionaryv"
}
}
}

View File

@ -159,4 +159,9 @@
{
"game" "synergy"
}
"game.hl2ctf.txt"
{
"game" "hl2ctf"
}
}

View File

@ -239,63 +239,63 @@
{
"GiveNamedItem"
{
"windows" "435"
"linux" "436"
"mac" "436"
"windows" "441"
"linux" "442"
"mac" "442"
}
"RemovePlayerItem"
{
"windows" "285"
"linux" "286"
"mac" "286"
"windows" "288"
"linux" "289"
"mac" "289"
}
"Weapon_GetSlot"
{
"windows" "283"
"linux" "284"
"mac" "284"
"windows" "286"
"linux" "287"
"mac" "287"
}
"Ignite"
{
"windows" "219"
"linux" "220"
"mac" "220"
}
"Extinguish"
{
"windows" "222"
"linux" "223"
"mac" "223"
}
"Extinguish"
{
"windows" "225"
"linux" "226"
"mac" "226"
}
"Teleport"
{
"windows" "111"
"linux" "112"
"mac" "112"
"windows" "112"
"linux" "113"
"mac" "113"
}
"CommitSuicide"
{
"windows" "485"
"linux" "485"
"mac" "485"
"windows" "491"
"linux" "491"
"mac" "491"
}
"GetVelocity"
{
"windows" "136"
"linux" "137"
"mac" "137"
"windows" "137"
"linux" "138"
"mac" "138"
}
"EyeAngles"
{
"windows" "127"
"linux" "128"
"mac" "128"
"windows" "128"
"linux" "129"
"mac" "129"
}
"AcceptInput"
{
"windows" "39"
"linux" "40"
"mac" "40"
"windows" "40"
"linux" "41"
"mac" "41"
}
"SetEntityModel"
{
@ -305,21 +305,21 @@
}
"WeaponEquip"
{
"windows" "276"
"linux" "277"
"mac" "277"
"windows" "279"
"linux" "280"
"mac" "280"
}
"Activate"
{
"windows" "36"
"linux" "37"
"mac" "37"
"windows" "37"
"linux" "38"
"mac" "38"
}
"PlayerRunCmd"
{
"windows" "455"
"linux" "456"
"mac" "456"
"windows" "461"
"linux" "462"
"mac" "462"
}
}
}

View File

@ -21,80 +21,6 @@
"SlapSound2" "player/damage2.wav"
}
}
/* General Temp Entities */
"#default"
{
"#supported"
{
"game" "left4dead2"
"game" "nucleardawn"
}
"Offsets"
{
/* Offset into CBaseTempEntity constructor */
"s_pTempEntities"
{
"windows" "17"
}
"GetTEName"
{
"windows" "4"
"linux" "4"
"mac" "4"
}
"GetTENext"
{
"windows" "8"
"linux" "8"
"mac" "8"
}
"TE_GetServerClass"
{
"windows" "0"
"linux" "0"
"mac" "0"
}
}
"Signatures"
{
"CBaseTempEntity"
{
"library" "server"
"windows" "\x8B\xC1\x8B\x4C\x24\x04\xC7\x00\x2A\x2A\x2A\x2A\x89\x48\x04\x8B\x15\x2A\x2A\x2A\x2A\x89\x50\x08\xA3\x2A\x2A\x2A\x2A\xC2\x04\x00"
}
"s_pTempEntities"
{
"library" "server"
"linux" "@_ZN15CBaseTempEntity15s_pTempEntitiesE"
"mac" "@_ZN15CBaseTempEntity15s_pTempEntitiesE"
}
}
}
/* CGlobalEntityList */
"#default"
{
"#supported"
{
"game" "left4dead2"
"game" "nucleardawn"
}
"Signatures"
{
/* Functions in CGlobalEntityList */
"FindEntityByClassname"
{
"library" "server"
"windows" "\x53\x55\x56\x8B\xF1\x8B\x4C\x24\x10\x85\xC9\x57\x74\x19\x8B\x01\x8B\x50\x08\xFF\xD2\x8B\x00\x25\xFF\x0F\x00\x00\x83\xC0\x01\xC1\xE0\x04\x8B\x3C\x30\xEB\x06\x8B\xBE\x2A\x2A\x2A\x2A\x85\xFF\x74\x39\x8B\x5C\x24\x18\x8B\x2D\x2A\x2A\x2A\x2A\xEB\x03"
"linux" "@_ZN17CGlobalEntityList21FindEntityByClassnameEP11CBaseEntityPKc"
"mac" "@_ZN17CGlobalEntityList21FindEntityByClassnameEP11CBaseEntityPKc"
}
}
}
/* General GameRules */
"#default"
@ -137,43 +63,6 @@
}
}
}
/* IServer interface pointer */
"#default"
{
"Keys"
{
/* Signature for the beginning of IVEngineServer::CreateFakeClient.
*
* The engine binary is not actually scanned in order to look for
* this. SourceHook is used to used to determine the address of the
* function and this signature is used to verify that it contains
* the expected code. A pointer to sv (IServer interface) is used
* here.
*/
"CreateFakeClient_Windows" "\x8B\x44\x24\x2A\x50\xB9\x2A\x2A\x2A\x2A\xE8"
}
"Offsets"
{
/* Offset into IVEngineServer::CreateFakeClient */
"sv"
{
"windows" "6"
}
}
"Signatures"
{
/* CBaseServer object for IServer interface */
"sv"
{
"library" "engine"
"linux" "@sv"
"mac" "@sv"
}
}
}
/* EntityFactoryDictionary function */
"#default"
@ -189,25 +78,6 @@
}
}
}
/* CBaseEntityOutput::FireOutput */
"#default"
{
"#supported"
{
"game" "left4dead2"
}
"Signatures"
{
"FireOutput"
{
"library" "server"
"windows" "\x81\xEC\x1C\x01\x00\x00\x53\x55\x56\x8B\x71\x14\x85\xF6"
"linux" "@_ZN17CBaseEntityOutput10FireOutputE9variant_tP11CBaseEntityS2_f"
"mac" "@_ZN17CBaseEntityOutput10FireOutputE9variant_tP11CBaseEntityS2_f"
}
}
}
/* SetUserInfo data */
"#default"

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