Compare commits

...

105 Commits

Author SHA1 Message Date
Nicholas Hastings
255e2ef6f0 Merge branch '1.7-dev' of https://github.com/alliedmodders/sourcemod into 1.7-dev. 2015-05-30 08:06:56 -04:00
Nicholas Hastings
18f8d10f10 Update versioning for 1.7.2 release. 2015-05-30 08:06:23 -04:00
Nicholas Hastings
a626005cc6 Update changelog for version 1.7.2. 2015-05-30 08:05:13 -04:00
Nicholas Hastings
bf9c96b48f Fix sm_trigger_show default in shipped sourcemod.cfg match default in basetriggers. 2015-05-30 07:56:06 -04:00
Ruben Gonzalez
dca2596788 Update more CS:GO gamedata. 2015-05-28 13:29:35 -04:00
David Anderson
b491345d78 Fix continue in a loop body leaking heap-allocated variables. (bug 6370, r=fyren) 2015-05-27 10:33:07 -04:00
Ruben Gonzalez
8cb2fcdf65 Update CS:GO gamedata for latest update. 2015-05-26 21:53:44 -04:00
Nicholas Hastings
f86c5e9940 Fix regression in admin-sql-threaded when porting to transitional syntax. 2015-05-18 13:22:34 -04:00
Ruben Gonzalez
fd9dbded8b Trigger build. 2015-05-15 20:53:31 -04:00
Ruben Gonzalez
404cd28423 Trigger Build. 2015-05-15 18:30:35 -04:00
Ruben Gonzalez
afaddda8cf Trigger Build 2015-05-15 15:51:46 -04:00
Asher Baker
6c7a6c72aa Correct NameHashSet::add() return type. 2015-05-09 11:56:15 +01:00
Asher Baker
97605a500c Remove check_thunks reliance on Tier0. 2015-05-07 21:56:31 +01:00
Kyle Sanderson
16b7c576d4 Merge pull request #330 from yedpodtrzitko/1.7-dev
Add IsFree check to FindEntityByNetClass in SDKTools.
2015-05-04 18:08:51 -07:00
yed_
f504188854 add IsFree check 2015-05-05 01:06:40 +01:00
Nicholas Hastings
8b2d7a1e49 Trigger build for hl2sdk-dota changes. 2015-05-03 15:08:03 -04:00
Nicholas Hastings
b429c37ab3 Trigger build for hl2sdk-dota changes. 2015-05-03 10:05:53 -04:00
Nicholas Hastings
13cf293f1c Merge pull request #250 from alliedmodders/sdkhooks-newdecls
Convert remainder of sdkhooks.inc to newdecls (r=dvander).
2015-04-20 10:19:23 -07:00
Nicholas Hastings
a2b9c91423 Roll version number. 2015-04-18 15:48:19 -04:00
Nicholas Hastings
cf9aa05a0c Update versioning for 1.7.1 release. 2015-04-18 15:13:41 -04:00
Nicholas Hastings
824b0f9a3c Update changelog for version 1.7.1. 2015-04-18 09:58:37 -04:00
David Anderson
f74e357e91 Merge pull request #288 from klausenbusk/patch-1
Updated KillTimer documentation to reflect "Invalid handles" = runtime error.
2015-04-18 09:41:30 -04:00
David Anderson
15b65468ac Fix bug where the compiler could crash trying to dereference a decayed accessor expression used as |this|. 2015-04-18 08:53:13 -04:00
David Anderson
d64bcc763a Fix bug where complex |this| values could be corrupted while evaluating function arguments. (bug 6329) 2015-04-18 08:51:02 -04:00
Nicholas Hastings
f4ff0e574c Fix CoreConfig init to happen after SMGlobalClasses from logic bin are added.
This fixes OnSourceModConfigChanged not being called for logic classes when
config is first read, matching behavior for core classes. The function is still called
before each class's OnSourceModStartup func.
2015-04-18 08:35:10 -04:00
Nicholas Hastings
4ffe11a235 Enable the "name %s" command blocking on CS:GO as well. 2015-04-17 04:51:24 -07:00
Nicholas Hastings
fc2addf11e Merge pull request #313 from alliedmodders/set-client-name
Add SetClientName native.
2015-04-07 04:39:52 -07:00
Peace-Maker
491d24a028 Add missing debug info for multidimensional strings
new String:INVISIBLE[2][8];

Multidimensional arrays like this wouldn't get their debug info added to
the debug symbols table.
Bug: https://bugs.alliedmods.net/show_bug.cgi?id=6324

See Fyren's comment in the bug report.
This patch recursively checks the parent symbol of array dimensions
until it finds the top symbol and uses that to check for the compound
level.
This still allows for early exiting the loop when going out of scope.
2015-04-04 11:05:36 -04:00
Peace-Maker
9a26ae0526 Fix declaring variable on same line after array
int a[5], b;
b would get a size of |0| on the stack instead of a sizeof(cell_t).
Bug: https://bugs.alliedmods.net/show_bug.cgi?id=6335
2015-04-04 11:03:27 -04:00
Ryan Stecker
8f0067b3b4 Improve the diagnostic given when a function prototype doesn't match an existing definition. 2015-04-04 10:51:10 -04:00
Nicholas Hastings
d68829d301 Fix build. 2015-04-04 10:26:11 -04:00
Nicholas Hastings
a48d5bfe1f Add missing impl for File.ReadUint16. 2015-04-04 10:22:41 -04:00
Nicholas Hastings
e54850e1f9 Add explicit return types to forwards missing them. 2015-04-04 10:21:34 -04:00
InstantMuffin
fd4ac6312c Update functions.inc 2015-04-04 10:17:02 -04:00
Alexander Corn
3c95f191c4 Moved note about releasing resources from OnPluginStart to OnPluginEnd 2015-04-04 10:10:51 -04:00
Nicholas Hastings
a523948ebb Make OpenDirectory error for empty path match error in DirExists. 2015-04-04 10:10:13 -04:00
Nicholas Hastings
fc5149a1c7 Throw an error if DirExists called with empty path. 2015-04-04 10:10:07 -04:00
Nicholas Hastings
50399f25f4 Update TF2 gamedata. 2015-03-31 17:39:50 -04:00
Ruben Gonzalez
1552464465 Fix not being able to block CS_OnCSWeaponDrop and clarify include file. (bug 6334) 2015-03-29 18:39:38 -04:00
Dr!fter
dd401e760c Fix more Freak Fortress gamedata. 2015-03-27 21:59:02 -04:00
Ruben Gonzalez
0c976cd1f0 Fix Fortress Forever gamedata. 2015-03-27 21:47:32 -04:00
Nicholas Hastings
e5fb8984f4 Merge pull request #286 from peace-maker/noradiomenu_regression
Fix crash regression in games that don't support radio style menus (r=psychonic).
2015-03-21 18:46:56 -04:00
Ruben Gonzalez
57c993e17e Merge pull request #303 from alliedmodders/tf2_vstk_fix
Fix some TF2 natives not having the correct vstk size.
2015-03-14 09:51:08 -04:00
Ruben Gonzalez
ec32f3cf2d Update TF2's MakeBleed native for the latest update. 2015-03-12 18:07:12 -04:00
Nicholas Hastings
3764881daa Trigger build for hl2sdk-dota changes. 2015-03-06 11:26:26 -05:00
Ryan Stecker
2754be4066 Fix tag mismatch warning when using SQLite_UseDatabase. (bug 6310) 2015-03-03 23:04:23 -05:00
Peace-Maker
b52054de1e Fix crash in games that don't support radio style menus
Fix regression in ad7d920ce0
GetMenuStyleHandle(MenuStyle_Radio) crashes games, which don't support
the radio menu style. The style is never added to the menu manager, if
it's not supported, so GetMenuStyleHandle tries to call IsSupported on a
nullptr.
2015-03-01 18:48:30 +01:00
Nicholas Hastings
94c982f8cf Merge pull request #267 from 50Wliu/tf2_setclientteam
Add TF2_SetClientTeam to provide symmetry to TF2_GetClientTeam (r=psychonic).
2015-02-26 17:42:32 -05:00
Asher Baker
66b00d4ae7 Updated plugin blacklist. 2015-02-25 01:17:42 +00:00
Asher Baker
784f9f4993 Merge pull request #213 from splewis/find-array-nonzero-blocks
Add block parameter to FindValueInArray native.
2015-02-25 01:16:06 +00:00
Nicholas Hastings
6fb9e1b30e Fix Insurgency s_pTempEntities offset on Windows. 2015-02-22 20:09:03 -05:00
Nicholas Hastings
51c1e17717 Use new IVEngineServer::GetIServer to get IServer* on Insurgency. 2015-02-22 15:16:39 -05:00
Nicholas Hastings
c911af4109 Update Insurgency Windows SDKTools gamedata. 2015-02-22 10:18:45 -05:00
Kyle Sanderson
a67c54f0c0 Root Menu Handles during Display. 2015-02-21 17:36:08 -08:00
Nicholas Hastings
a989a2b791 Trigger build for hl2sdk-dota changes. 2015-02-20 09:17:01 -05:00
Nicholas Hastings
68a1e89c24 Trigger build for hl2sdk-csgo changes. 2015-02-17 15:50:38 -05:00
Nicholas Hastings
289455d538 Trigger build (bug 6308). 2015-02-14 12:03:55 -05:00
Nicholas Hastings
4919e4a002 Roll version number. 2015-02-04 18:25:02 -05:00
Nicholas Hastings
fd0aaf9da9 Update versioning for 1.7.0 release. 2015-02-04 17:33:14 -05:00
Nicholas Hastings
325e95e9be Update changelog for version 1.7.0. 2015-02-04 17:29:10 -05:00
Nicholas Hastings
c2e31deb78 Sync changelog from 1.6-dev branch. 2015-02-04 17:24:56 -05:00
David Anderson
c944ef18b3 Remove sizeof() as a special-case default argument value. 2015-02-04 17:18:11 -05:00
Nicholas Hastings
14af0bae82 Fix crash when creating and destroying a TopMenu without map change (bug 6303). 2015-02-04 17:15:03 -05:00
Nicholas Hastings
efba7bd82a Expose Message_DetermineMulticastRecipients as GetClientsInRange native. 2015-02-03 14:40:15 -05:00
Nicholas Hastings
6da2f6c8ed Fix FindFlagChar not finding char for AdminFlag_Custom6. 2015-02-03 12:42:08 -05:00
Nicholas Hastings
9e6f7a9e89 Fix g_ReverseFlags array size. 2015-02-03 12:41:43 -05:00
Nicholas Hastings
d0ab3e7bd6 Rename g_FlagSet to g_FlagCharSet to avoid some confusion. 2015-02-03 12:41:14 -05:00
Ruben Gonzalez
a6d5212ee9 Initial CSGO GetWeaponPrice fixes 2015-02-01 12:12:31 -05:00
David Anderson
79bb037b66 Don't special case hierarchy-free enumeration constants when used as array indices. (bug 6302) 2015-01-31 22:12:59 -08:00
David Anderson
ea3f491a8e Fix chained field expressions losing lvalue-ness. (bug 6298) 2015-01-31 22:12:58 -08:00
Thordin
aa27b10232 Increased handles to 32k 2015-01-31 22:12:57 -08:00
David Anderson
1ebf70b450 Fix wrong value in transitional DBI callback. (bug 6292) 2015-01-31 22:12:57 -08:00
Nicholas Hastings
3a499036ac Fix incorrect error line show for incorrect return value on forwards (bug 6226). 2015-01-28 14:46:56 -05:00
Nicholas Hastings
6b92f18a86 Don't allow plugins to block LevelInit (wtf). 2015-01-28 14:46:46 -05:00
Kyle Sanderson
60757dde1c Establish a default timeout for MySQL connectivity. 2015-01-23 22:58:06 -08:00
Nicholas Hastings
d5fc57316e Update protobuf include path for Dota build. 2015-01-21 11:11:56 -05:00
Ryan Stecker
1b47398e38 Prevent null auth string comparisons. 2015-01-19 07:49:27 -05:00
Nicholas Hastings
70f42dee65 Fix regression causing "BOT" to no longer be valid in adminsys for Steam identities. 2015-01-17 16:17:43 -05:00
Simone
08db476476 Add missing semicolon. 2015-01-17 16:17:33 -05:00
Ryan Stecker
b1353e2ca4 Use BfRead or Protobuf tags in umsg hook callbacks, rather than a generic Handle. 2015-01-17 16:17:22 -05:00
Nicholas Hastings
6be9c770fe Add PlayerRunCommand gamedata for Dark Messiah. 2015-01-11 11:45:49 -05:00
Nicholas Hastings
83a77bca08 Fix ICommandLine not being found in Dark Messiah. 2015-01-11 11:45:43 -05:00
Nicholas Hastings
1ff913c38f Trigger build for hl2sdk-dota update. 2015-01-09 09:07:46 -05:00
Nicholas Hastings
5383a0596a Update TF2 gamedata. 2015-01-07 14:09:59 -05:00
Asher Baker
a81776f92c Fix threads leaking if they're not joined. (bug 3460, r=dvander) 2015-01-06 20:30:17 +00:00
David Anderson
bcef7365b0 Fix uninitialized variable in decl_enum(). 2015-01-04 12:17:13 -08:00
David Anderson
9e882783f9 Allow "stock static" in addition to "static stock". 2015-01-04 12:17:00 -08:00
David Anderson
00a663c1a3 Remove some heinous preprocessor directives.
Gone:
 - #emit (bah-roken!)
 - #pragma compress (useless)
 - #pragma library (useless)
2015-01-04 12:16:47 -08:00
Nicholas Hastings
5c047ad04b Fix ArrayList.Clear func name. 2015-01-04 12:29:48 -05:00
Nicholas Hastings
5e64de198a Fix typo on ArrayList.Erase native. 2015-01-04 11:59:07 -05:00
David Anderson
b92e4ff688 Fix typos in dbi.inc transitional syntax. 2015-01-03 15:01:44 -05:00
Peace-Maker
224d54aadd Fix missing params in OnTakeDamagePost typedef
Looks like the |weapon| parameter went missing during the switch to the
transitional syntax.

There was no -Post typedef including the |damagecustom| bit at all too.
2015-01-03 15:01:27 -05:00
Nicholas Hastings
bcc6581c1c Don't looks for IServerTools on ep1 games.
(We don't use it and it doesn't exist on most.)
2015-01-01 16:45:54 -05:00
Nicholas Hastings
68c752bf6d Fix SDKHooks causing crash on plugin load/unload or player connect/disconnect if missing gamedata. 2014-12-30 21:09:32 -05:00
Nicholas Hastings
a0bfda89d8 Make EntInfo offset in SDK2013 gamedata apply to all SDK2013 games. 2014-12-30 17:16:27 -05:00
Nicholas Hastings
55cadc7738 Change sm_trigger_show default value to 0 / disabled. 2014-12-29 08:56:58 -08:00
Nicholas Hastings
4d9e94373f Revert "Disable FireOutput detour on Windows for Dota for now."
This reverts commit 516c140810.
2014-12-24 11:01:45 -05:00
Nicholas Hastings
516c140810 Disable FireOutput detour on Windows for Dota for now. 2014-12-24 10:38:16 -05:00
Peace-Maker
6cfced238c Don't unpack mysql verbosely
I doubt we're interested in the filename of every single file
contained in the mysql archive when it's decompressed.

It bloats up the travis build log.
2014-12-23 09:03:22 -05:00
FlaminSarge
27c73d4e3e Denote TFCond multiples of 32 consistently 2014-12-23 09:00:53 -05:00
FlaminSarge
4818aee7b9 Update TFCond enum for Mannpower 2014-12-23 09:00:47 -05:00
Nicholas Hastings
65f52a3cad Update TF2 gamedata. 2014-12-22 17:31:10 -05:00
Nicholas Hastings
49a568bd59 Disable nextmap on Insurgency. 2014-12-20 23:00:48 -05:00
Nicholas Hastings
1575ddb3f3 Move bot auth to after connect to fix old too-early-authid bug now causing crash (r=VoiDeD). 2014-12-19 18:28:08 -05:00
Nicholas Hastings
f9cdc421c3 Trigger build. 2014-12-18 05:10:03 -08:00
98 changed files with 1973 additions and 715 deletions

View File

@ -1,5 +1,720 @@
SourceMod Changelog SourceMod Changelog
SourceMod 1.7.2 [2015-05-30]
URL: http://wiki.alliedmods.net/SourceMod_1.7.2_Release_Notes
User Changes:
- Updated game compatibility for the latest CS:GO updates.
- Fixed potential crash when using SDKTools GameRules_* natives. (PR 330) (yed).
- Fixed regression in v1.7.0 causing admin-sql-threaded plugin to not properly load admins. (bug 6365) (PR 342).
- Fixed leak in plugin heap memory that could lead to "Not enough space on the heap" error. (bug 6370).
----------------------------------------------------------
SourceMod 1.7.1 [2015-04-18]
URL: http://wiki.alliedmods.net/SourceMod_1.7.1_Release_Notes
User Changes:
- Updated game compatibility for CS:GO, TF2, Dota 2, Insurgency, and Fortress Forever.
- Fixed regression causing crash in games that do not support radio menus (PR 286) (Peace-Maker).
- Fixed sm_rename not working on some games, including CS:S and CS:GO (PR 313).
- Fixed some core.cfg values being ignored on start (PR 322).
- Fixed crash when plugins close a menu handle during menu draw (PR 268)
Developer Changes:
- Added tagged TF2_SetClientTeam to provide symmetry to TF2_GetClientTeam (PR 267) (Wliu).
- Added block parameter to FindValueInArray native (PR 213) (splewis).
- Added explicit return types to forwards missing them to avoid future compatibility issues (PR 294).
- Added new SetClientName native to reliably change a player's name on any game (PR 313).
- Fixed tag mismatch warning when using SQLite_UseDatabase (bug 6310) (PR 262) (VoiDeD).
- Fixed not actually being able to block CS_OnCSWeaponDrop (bug 6334) (PR 316).
- Fixed DirExists to throw an error when passed empty string (PR 315).
- Fixed ReadUint16 on File methodmap throwing "not bound" error (PR 265).
- Fixed various include docs (PR 288) (PR 290) (PR 295).
- Fixed issues with declaring variable on same line after array (SP PR 7) (Peace-Maker).
- Fixed debug info for multidimensional strings not being written to smx (SP PR 8) (Peace-Maker).
- Fixed issues with nesting methodmap calls (bug 6329) (SP PR 11) (SP PR 13).
- Improved diagnostic given when function prototype doesn't match an existing definition (PR 291) (VoiDeD).
----------------------------------------------------------
SourceMod 1.7.0 [2015-02-04]
URL: http://wiki.alliedmods.net/SourceMod_1.7.0_Release_Notes
User Changes:
- Updated game compatibility for TF2, CS:GO, and Dota 2.
- Fixed regression in SM 1.6.3 causing load failure on games older than Orangebox. (PR 237)
- Rewrote internal Steam auth ID handling (PR 147, PR 153, PR 155, PR 162, PR 204, PR 210, PR 222, PR 246).
--- admins.cfg now supports Steam2, Steam3, and SteamID 64 formats for the Steam auth provider.
--- admins-simple.ini now supports Steam3 auth IDs in addition to Steam2 IDs.
--- Command targeting now supports both Steam3 auth IDs in addition to Steam2 IDs.
- Added default timeout for MySQL connections to avoid hangs. (PR 248).
- SDKTools' gamerules gamedata is now far less likely to break on updates (PR 220).
- Fixed crash with sm_dump_admcache on Windows (PR 163).
- Fixed SDKHooks causing crash on player join/leave or plugin load/unload if gamedata missing (PR 236).
- Changed default sm_trigger_show ConVar value to 0 / disabled.
Developer Changes:
- Added new SourcePawn Transitional Syntax!
--- New methodmap-based APIs have been added for many existing functions and handle types.
--- New work-in-progress API doc page.
- Added Blocked hook type to SDKHooks (PR 119) (VoiDeD).
- Added OnTakeDamage_Alive hook type to SDKHooks (PR 149).
- Many more File natives now support Valve FS (PR 120, PR 169, PR 178).
- Added SetFilePermissions native (PR 43) (hlstriker).
- Added API for iterating StringMaps (formerly "tries").
- Added natives for accessing command line parameters (PR 164) (VoiDeD).
- Exposed engine Message_DetermineMulticastRecipients as GetClientsInRange native. (PR 234).
- CloseHandle (or delete) on INVALID_HANDLE is now a no-op, instead of an error (PR 74).
- GetClientAuthString is now deprecated. Use GetClientAuthId instead.
- Added OnCoreMapEnd to extension interface (PR 127).
- Fixed IThreader threads leaking if they're not joined. (bug 3460, PR 241).
- TFHoliday updates no longer require a plugin recompile (PR 217).
- Fixed FindFlagChar returning false when passing AdminFlag_Custom6 (bug 6248, PR 203).
- Added support for (entity) CLASSPTR and EDICT Prop_Data fields with GetEntPropEnt and SetEntPropEnt (PR 83).
- Doubled maximum handle count per plugin to 32,768 (PR 215), (Thordin).
- Added support for custom default values with GetEvent* natives, rather than using ""/0 for unset fields (PR 157) (VoiDeD).
- Removed old profiler, and added new, pluggable profiler (with hooks to VProf) (PR 54).
- Added command to dump profiler output (PR 128) (VoiDeD).
- Fixed ICommandLine and related features being reported as unavailable on Dark Messiah.
- Fixed OnPlayerRunCommand forward in SDKTools being unavailable on Dark Messiah.
- SourceMod now uses some C++11 and has newer compiler requirements.
- Added --disable-auto-versioning option to ambuild configure script.
----------------------------------------------------------
SourceMod 1.6.3 [2014-11-25]
URL: http://wiki.alliedmods.net/SourceMod_1.6.3_Release_Notes
User Changes:
- Updated game support for TF2, CS:GO, No More Room in Hell, Insurgency, PVK2 and Fistful of Frags.
- Made changes to make TF2, CSS, DoDS, HL2DM, and SDK 2013 mods less likely to break on game update (PR 174, PR 192).
- Added support for longer key names in languages.cfg (to fix Portuguese) (bug 6282, PR 208).
Developer Changes:
- Updated TF2 player condition and holiday enums (Ross "Powerlord" Bemrose) (PR 183, PR 181).
- Add support for TF2 player conditions >= 96 for condition functions/forwards (PR 205).
----------------------------------------------------------
SourceMod 1.6.2 [2014-09-20]
URL: http://wiki.alliedmods.net/SourceMod_1.6.2_Release_Notes
User Changes:
- Updated game support for TF2, CS:GO, No More Room in Hell and Fistful of Frags.
- Added compatibility shim to force Steam player auth strings to be in "Steam2" rendered format (PR 136).
- Fixed possible performance regression in DBI handling.
Developer Changes:
- Added new GetClientAuthId native to retrieve player auth strings in desired format (PR 159).
- Updated TF2 weapon and player condition enums (FlaminSarge).
----------------------------------------------------------
SourceMod 1.6.1 [2014-08-17]
URL: http://wiki.alliedmods.net/SourceMod_1.6.1_Release_Notes
User Changes:
- Updated game support for CS:GO and Fistful of Frags.
- Added support for Romanian language.
- Re-added languages.cfg, missing from 1.6.0, causing all clients to use server language.
- Fixed a regression in version 1.6.0 that caused certain SDKHooks usage patterns to cause a server crash (PR 107).
- Improved error reporting in basebans plugin when banreasons.txt is missing (PR 115).
- Fixed incorrect logged gravity value for sm_gravity command (Ryan "VoiDeD" Stecker) (PR 116).
- Fixed a regression in version 1.6.0 causing SDKHook_ReloadPost hooks to not fire in plugins (Peace-Maker) (PR 96).
- Added workaround for game bug in TF2_RemoveWeaponSlot to avoid wearable entities left on map (Ryan "VoiDeD" Stecker) (bug 6206, PR 121).
- Removed DisableJIT option from core.cfg. (It was never meant for normal use.)
Developer Changes:
- Added new TF2_RemoveWearable native (Ryan "VoiDeD" Stecker, WildCard65) (PR 114).
- Added new functions for interacting with and playing scripted game sounds (Ross "Powerlord" Bemrose) (bug 5942, PR 65).
- Added new StringToKeyValues natives (Ryan "VoiDeD" Stecker) (PR 74).
----------------------------------------------------------
SourceMod 1.6.0 [2014-07-03]
URL: http://wiki.alliedmods.net/SourceMod_1.6.0_Release_Notes
User Changes:
- Added support for Dota 2 (bug 5656, bug 6068).
- Added support for Source SDK 2013 mods (bug 5917).
- Added support for Insurgency (bug 5951).
- Added support for Contagion (bug 6007).
- Added support for Blade Symphony (bug 5949).
- Updated support for some mods that moved to SDK 2013 - No More Room In Hell, Fistful of Frags, Empires, Synergy.
- Updated gamedata and other support for TF2, DoD:S, HL2:DM, CS:S, CS:GO, Left 4 Dead, and Nuclear Dawn.
- Added support for customizing ban reasons in basebans.sp (bug 5762) (Matthias "House" Kollek).
- Added support for searching all gameinfo search paths when seeking mapcycle file (bug 5839).
- Added sm_reload_translations command (bug 5750).
- Added support for single-file gamedata custom overrides (bug 5386) (Ondrej "RavuAlHemio" Hošek).
- Re-enabled SteamAuthstringValidation config option by default (bug 5791, PR 20).
- Fixed plugins not reaching ext dep lists, making dependent plugin not unload on ext unload (bug 5851) (Peace-Maker).
- Added printing of SendProp flags to netprop dumps (bug 6082).
- Removed support for obsolete plugin_settings.cfg (bug 5605).
- Fixed topmenu sorting not getting refreshed after reloading sorting config (bug 6032) (Peace-Maker).
- Fixed error log filename date sometimes being incorrect (bug 5761) (Matheus "M28" Valadares).
- Dump handle information when a plugin is forcefully unloaded. (bug 5666).
- Fixed sm_cancelvote not resetting rtv state. (bug 5808) (Peace-Maker).
- Fixed Mapchooser dying on single map rotation servers (bug 5179).
- Fixed various problems with unloading ClientPrefs and SourceMod (bug 5874).
- Fixed "sm version" command reporting incorrect compile time in many cases (bug 6078) (SystematicMania).
- Clear default database driver reference if backing extension is unloaded (bug 5934) (Peace-Maker).
- Moved funcommands material and sound definitions to gamedata for easier cross-game support (bug 6085).
- Implement a watchdog timer for scripts that take too long to execute (bug 5837).
- Use Linux game data for offsets and signatures/symbols on OS X if Mac-specific data is not available (bug 6056).
Developer Changes:
- Added an API for off-thread SQL transactions. (bug 3775, PR 26).
- Added string literal concatenation using ellipses "..." (bug 4261, PR 5) (Peace-Maker).
- Added support for nested datatables. (bug 5446).
- Added PbRemoveRepeatedFieldValue native (bug 6066).
- Added support for getting/setting protobuf enum values with PbGetInt, PbSetInt, and PbAddInt natives.
- Removed deprecated PbReadRepeated natives that existed briefly in 1.5.0-dev prerelease versions.
- Added RequestFrame native for one-off next-frame actions (bug 5965).
- Added CS_DMG_HEADSHOT define for CS:S and CS:GO (PR 7) (Bara20).
- Added CS_SLOT_KNIFE define for CS:S and CS:GO (bug 6131).
- Updated TF_WEAPON enum (PR 37) (FlaminSarge).
- Added TFHoliday_AprilFools to TFHoliday enum (bug 6092) (Ross "Powerlord" Bemrose).
- Added new TF2_IsHolidayActive native to TF2 Ext (bug 6095) (Ross "Powerlord" Bemrose).
- Switch TF2 extension to hook CTFGameRules::IsHolidayActive for holiday forward (bug 6137, PR 42).
- Added GetPlayerJingleFile native. (bug 5690) (FlaminSarge).
- Added PrepSDKCall_SetAddress and Address support to PrepSDKCall_SetFromConf (bug 5261).
- Added ability to disable TopMenu Title Caching (bug 6034) (Peace-Maker).
- Added DisplayTopMenuCategory native (bug 6033) (Peace-Maker).
- Added support for Valve search paths to GetFileSize native (bug 5931).
- Fixed invalid entities sometimes passed to OnEntityCreated and OnEntityDestroyed (bug 6119).
- Fixed inconsistencies with OnClientDisconnected foward calls (bug 5988, PR 16).
- Changed OnClientSayCommand to now pass non-silent chat triggers onward (bug 5926) (SystematicMania).
- Changed OnClientSayCommand forwards to strip quotes from chat (bug 5986) (SystematicMania).
- Fixed FindStringIndex native not returning INVALID_STRING_INDEX when string not found (bug 6144, PR 40).
- Fixed GroundEntChanged hooks not being called (bug 6050) (Peace-Maker).
- Fixed INetChannelInfo natives to no longer require clients to be ingame (bug 5775) (SystematicMania).
- Fixed replace param being respected inconsistently in SetTrieArray (bug 6113).
- Fixed crash creating a timer when there are no handles available. (bug 5317) (Peace-Maker).
- Fixed crash in ReconnectClient and InactivateClient natives when IServer ptr is null (bug 6122).
- Fixed StoreFromAddress and LoadFromAddress continuing with bad values, usually crashing after error (bug 6080).
- Fixed compiler bug with multidimensional array variable release (bug 6100).
- Changed float comparison operators to return false for NaN (bug 6107).
- Added support in spcomp for sp/inc files > 32767 lines (bug 5959).
- Fixed FindFlagChar returning '?' for Admin_Custom6.
- Fixed AllPluginsLoaded activities happening before SM is loaded.
- Deduplicated a number of files used by extensions by moving them to the public directory (bug 5341).
- Removed 'state' keyword from compiler (bug 4572) (Ryan "VoiDeD" Stecker).
- Removed LogMessageEx definition from logging.inc because it never existed (bug 5897) (Peace-Maker).
- Removed native override API (bug 5852).
- Call OnLibraryAdded for all available libraries (bug 5925, PR 4).
- Made IGameConfig::GetMemSig return value clearer (bug 6081).
- Switched StringToInt(Ex) from using strtol to strtoul internally (bug 5939).
- Added an spcomp option to print #included files (bug 5997).
- Recompiled Regex extension libpcre against v8.32, enabling utf8, unicode props, and jit (bug 5593).
- Optimized native calls if statically bound (bug 5842).
Internal Changes:
- Now using new AlliedModders Template Library (AMTL) in many places, https://github.com/alliedmodders/amtl
- Ported buildscripts to new AMBuild2 platform, https://github.com/alliedmodders/ambuild
- Moved much logic from core to logic binary to reduce file sizes and compile times (bug 5606, bug 5607, bug 5680, bug 5953, PR 12, PR 13).
- Refactored the JIT to use a newer, simpler macro assembler. (bug 5827).
- Added sourcepawn interpreter (bug 5902).
- Added support for compiling spcomp with emscripten.
- Rewrite IThreader implementation around new synchronization primitives (bug 5862).
- Rewrite DBManager to use the new synchronization primitives (bug 5870).
- Overhauled internals of ClientPrefs extension for improved stability (bug 5538).
- Changed ShareSys to store C++ native lists more optimally (bug 5852).
- Simplified NativeEntry state (bug 5852).
- Changed NativeEntry to use Refcounted to manage (bug 5852).
- Switched Translator and GameConfigs to hash tables (bug 5878).
- Switched numerous subsystems from KTrie to AMTL NameHashSet (bug 5884).
- Refactored Trie natives to use AMTL HashMap instead of KTrie (bug 5892).
- Removed usages of memtables from many subsystems (bug 5899).
- Changed EventHook name storage to use AMTL AString (bug 6188).
- Replaced SH List usages in game extensions with AMTL variants (PR 23).
- Replaced SourceHook list usages in clientprefs with AMTL (PR 25).
- Changed floating-point operations to use SSE when available (bug 5841).
- Moved tracker related opcodes entirely to C++.
- Statically align the stack at function boundaries (bug 5842).
- Removed InfoVars, reassigned DAT from EBP to ESI to preserve C++ stacktraces in JIT code (5844).
- Fixed dereferencing potential null pointer in CPlugin::GetProperty (bug 5725).
- Fixed memory corruption when parsing natives. (bug 5840).
- Fixed some memory errors (bug 5904).
- Fixed unaligned memory access in spcomp.
- Move versioning to a static library to improve trivial build speed (bug 5997).
- Added many missing handle security checks (bug 5595).
- Made GetEntityClassname get and cache m_iClassname offset from worldspawn for ents not having it in datadesc (bug 5654).
- Cache m_iEFlags offset for datamaps dump instead of getting for each ent (bug 5657).
- Fixed mismatched delete [] on thunks in JIT CompData dtor (bug 5639).
- Fixed various memory issues. (bug 5766).
- Added reference counting and use it for CGameConfig and IDatabase (bug 5876).
- Added atomic reference counting and port DBI (bug 5876).
- Replaced usages of deprecated Sourcehook Add/Remove macros (bug 5631).
- Fixed SDKHooks hook ent validation missing first datatable name (bug 5881).
- Fixed case where bots leave server without disconnect notice (hibernation) (PR 20).
- Changed FindConVar to utilize convar cache for improved performance (PR 27) (VoiDeD).
- Gave define value (of 1) to PLATFORM defs to match the same-name defs in some SDKs (PR 10).
- Wrapped ClientPrintf into IGamePlayer (bug 6021).
- Consolidated FileExists usage in logic bin (bug 5931).
- Removed hardcoded paths to tier0/vstdlib in ICommandLine lookup.
- Use updated IServerTools iface on TF2 for getting tempent list and FindEntityByClassname (PR 33).
- Added early exit in entity output detour if entity has no classname to prevent crash.
- Updated SDKTools entity output functions to use core's GetEntityClassname instead of own (PR 39).
- Consolidated SDKTools entity factory lookups.
- Changed SDKTools PlayerRunCmd to a global vtable hook to improve performance (bug 6051).
- Changed SDKHooks to use global vtable hooks to improve performance (bug 6070).
- Added client validation checks to EmitSound SoundsHooks (bug 5873).
- Added missing meta results to some pre-hooks in SDKHooks.
- Replaced magic numbers for sm_show_activity with named constants (PR 14).
----------------------------------------------------------
SourceMod 1.5.3 [2014-03-22]
URL: http://wiki.alliedmods.net/SourceMod_1.5.3_Release_Notes
User Changes:
- Updated support for CS:GO after multiple breaking game updates.
- Updated gamedata support for GoldenEye: Source (Peace-Maker).
- Fixed crash on SDKHooks extension load in Alien Swarm (bug 6059).
- Fixed memory leak from unmanaged forwards never being freed (bug 6025).
- Fixed possible crash when unloading the CStrike extension.
- Fixed crash in SDKHooks Reload post-hook (Peace-Maker).
- Fixed FakeClientCommandEx always leaking memory (bug 5678).
- Fixed extra entity networking occuring with SetEntProp natives on some games.
- Fixed being able to nominate same map multiple times (bug 5109).
- Fixed spurious FindEntityByClassname error being logged on some games and platforms.
- Fixed an Anti-Flood bypass exploit (bug 5394).
- Removed part of Addresses gamedata error handling which could cause false errors to be logged (bug 6044).
- Fixed mapchooser not resetting nominations count when clearing nominations list (bug 5359).
- Improved performances of client convar query handling (bug 6003).
Developer Changes:
- Added GiveAmmo native to SDKTools (bug 6039) (Peace-Maker).
- Added SQL_SetCharset native to (re)set charset even after reconnect (bug 5786) (Peace-Maker).
- Added support for entity references in SDKHooks natives (bug 6069).
- Added support for server passwords to DisplayAskConnectBox stock (bug 5984) (FlaminSarge).
- Renamed SortFunc2D parameters to match documentation (bug 6014) (Peace-Maker).
- Fixed param order in AddToTopMenu function doc (bug 6035) (Peace-Maker).
- Added |any| tag to WritePackCell and ReadPackCell native param/return values (bug 6001).
- Updated SDKHook_TakeDamage native for game updates.
- Added default infinite value for TF2_AddCondition duration.
- Added support for conditions >= 64 in TF2_OnConditionAdded/Removed (bug 5565, bug 5976) (FlaminSarge).
- Updated TFCond and TF customkill enum values (bug 6012) (FlaminSarge).
- Fixed regression causing incorrect return and inability to block in TF2_OnCalcIsAttackCritical forward.
- Fixed TE_* natives operating on incorrect data for some tempents (bug 6072).
- Fixed CS_AliasToWeaponID not returning a valid weaponID for cz75a.
- Fixed CS_GetWeaponPrice returning incorrect value for M4A1 in CS:GO (bug 6045).
- Increased max gamedata byte signature length.
- Ported SM build scripts to AMBuild2 (bug 5997).
----------------------------------------------------------
SourceMod 1.5.2 [2013-10-29]
URL: http://wiki.alliedmods.net/SourceMod_1.5.2_Release_Notes
User Changes:
- Updated gamedata support for TF2, CS:S, CS:GO, and HL2:DM.
- Fixed crash from regression in SDKTools SetClientListening hook refcounting (bug 5956) (KyleS).
- Fixed potential crash when having maps with format characters in name.
- Fixed some nextmap issues with long map names.
- SDKTools no longer requires gamedata for sm_dump_datamaps on TF2, CS:S, HL2:DM, and DoD:S (bug 5968).
Developer Changes:
- Updated TFCond and TF custom dmg enums.
- Updated TF2 critical hit detection logic in TF2_OnCalcIsAttackCritical to handle more cases, including when criticals are disabled (bug 5894).
- Fixed GetEngineVersion native returning a bad value when running on MM:S 1.9.x or earlier (bug 5697).
----------------------------------------------------------
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).
- 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] SourceMod 1.3.6 [2010-10-31]

View File

@ -105,8 +105,8 @@ sm_timeleft_interval 0
// 1 (Enabled) // 1 (Enabled)
// -- // --
// Requires: basetriggers.smx // Requires: basetriggers.smx
// Default: 1 // Default: 0
sm_trigger_show 1 sm_trigger_show 0
// Specifies whether or not to display vote progress to clients in the // Specifies whether or not to display vote progress to clients in the
// "hint" box (near the bottom of the screen in most games). // "hint" box (near the bottom of the screen in most games).

View File

@ -59,7 +59,7 @@ for sdk_name in SM.sdks:
] ]
elif sdk.name == 'dota': elif sdk.name == 'dota':
compiler.cxxincludes += [ compiler.cxxincludes += [
os.path.join(sdk.path, 'common', 'protobuf-2.5.0', 'src'), os.path.join(sdk.path, 'common', 'protobuf-2.6.1', 'src'),
os.path.join(sdk.path, 'public', 'engine', 'protobuf'), os.path.join(sdk.path, 'public', 'engine', 'protobuf'),
os.path.join(sdk.path, 'public', 'game', 'shared', 'protobuf'), os.path.join(sdk.path, 'public', 'game', 'shared', 'protobuf'),
os.path.join(sdk.path, 'public', 'game', 'shared', 'dota', 'protobuf') os.path.join(sdk.path, 'public', 'game', 'shared', 'dota', 'protobuf')

View File

@ -234,7 +234,7 @@ void CHalfLife2::InitLogicalEntData()
void CHalfLife2::InitCommandLine() void CHalfLife2::InitCommandLine()
{ {
char error[256]; char error[256];
#if SOURCE_ENGINE != SE_DARKMESSIAH
if (!is_original_engine) if (!is_original_engine)
{ {
ke::AutoPtr<ILibrary> lib(g_LibSys.OpenLibrary(TIER0_NAME, error, sizeof(error))); ke::AutoPtr<ILibrary> lib(g_LibSys.OpenLibrary(TIER0_NAME, error, sizeof(error)));
@ -253,6 +253,7 @@ void CHalfLife2::InitCommandLine()
} }
} }
else else
#endif
{ {
ke::AutoPtr<ILibrary> lib(g_LibSys.OpenLibrary(VSTDLIB_NAME, error, sizeof(error))); ke::AutoPtr<ILibrary> lib(g_LibSys.OpenLibrary(VSTDLIB_NAME, error, sizeof(error)));
if (lib == NULL) if (lib == NULL)

View File

@ -83,6 +83,10 @@ void CRadioStyle::OnSourceModLevelChange(const char *mapName)
} }
g_bRadioInit = true; g_bRadioInit = true;
// Always register the style. Use IsSupported() to check for validity before use.
g_Menus.AddStyle(this);
const char *msg = g_pGameConf->GetKeyValue("HudRadioMenuMsg"); const char *msg = g_pGameConf->GetKeyValue("HudRadioMenuMsg");
if (!msg || msg[0] == '\0') if (!msg || msg[0] == '\0')
{ {
@ -118,7 +122,6 @@ void CRadioStyle::OnSourceModLevelChange(const char *mapName)
} }
} }
g_Menus.AddStyle(this);
g_Menus.SetDefaultStyle(this); g_Menus.SetDefaultStyle(this);
g_UserMsgs.HookUserMessage(g_ShowMenuId, this, false); g_UserMsgs.HookUserMessage(g_ShowMenuId, this, false);
@ -593,6 +596,7 @@ bool CRadioMenu::DisplayAtItem(int client,
return false; return false;
} }
AutoHandleRooter ahr(this->GetHandle());
return g_RadioMenuStyle.DoClientMenu(client, return g_RadioMenuStyle.DoClientMenu(client,
this, this,
start_item, start_item,

View File

@ -41,6 +41,8 @@
#include "sm_fastlink.h" #include "sm_fastlink.h"
#include <sh_stack.h> #include <sh_stack.h>
#include <compat_wrappers.h> #include <compat_wrappers.h>
#include "logic/common_logic.h"
#include "AutoHandleRooter.h"
using namespace SourceMod; using namespace SourceMod;

View File

@ -408,6 +408,7 @@ bool CValveMenu::DisplayAtItem(int client,
return false; return false;
} }
AutoHandleRooter ahr(this->GetHandle());
return g_ValveMenuStyle.DoClientMenu(client, this, start_item, alt_handler ? alt_handler : m_pHandler, time); return g_ValveMenuStyle.DoClientMenu(client, this, start_item, alt_handler ? alt_handler : m_pHandler, time);
} }

View File

@ -39,6 +39,8 @@
#include "KeyValues.h" #include "KeyValues.h"
#include "sm_fastlink.h" #include "sm_fastlink.h"
#include <compat_wrappers.h> #include <compat_wrappers.h>
#include "logic/common_logic.h"
#include "AutoHandleRooter.h"
using namespace SourceMod; using namespace SourceMod;

View File

@ -536,7 +536,7 @@ bool PlayerManager::OnClientConnect(edict_t *pEntity, const char *pszName, const
if (res) if (res)
{ {
if (!pPlayer->IsAuthorized()) if (!pPlayer->IsAuthorized() && !pPlayer->IsFakeClient())
{ {
m_AuthQueue[++m_AuthQueue[0]] = client; m_AuthQueue[++m_AuthQueue[0]] = client;
} }
@ -622,8 +622,6 @@ void PlayerManager::OnClientPutInServer(edict_t *pEntity, const char *playername
char error[255]; char error[255];
pPlayer->m_bFakeClient = true; pPlayer->m_bFakeClient = true;
pPlayer->UpdateAuthIds();
pPlayer->Authorize();
/* /*
* While we're already filtered to just bots, we'll do other checks to * While we're already filtered to just bots, we'll do other checks to
@ -711,6 +709,8 @@ void PlayerManager::OnClientPutInServer(edict_t *pEntity, const char *playername
m_clconnect_post->PushCell(client); m_clconnect_post->PushCell(client);
m_clconnect_post->Execute(&res, NULL); m_clconnect_post->Execute(&res, NULL);
pPlayer->Authorize();
const char *steamId = pPlayer->GetSteam2Id(); const char *steamId = pPlayer->GetSteam2Id();
/* Now do authorization */ /* Now do authorization */
@ -2003,6 +2003,13 @@ void CPlayer::UpdateAuthIds()
#else #else
authstr = engine->GetPlayerNetworkIDString(m_pEdict); authstr = engine->GetPlayerNetworkIDString(m_pEdict);
#endif #endif
if (!authstr)
{
// engine doesn't have the client's auth string just yet, we can't do anything
return;
}
if (m_AuthID.compare(authstr) == 0) if (m_AuthID.compare(authstr) == 0)
{ {
return; return;

View File

@ -39,15 +39,16 @@
#include "AdminCache.h" #include "AdminCache.h"
#include "Translator.h" #include "Translator.h"
#include "common_logic.h" #include "common_logic.h"
#include "stringutil.h"
#define LEVEL_STATE_NONE 0 #define LEVEL_STATE_NONE 0
#define LEVEL_STATE_LEVELS 1 #define LEVEL_STATE_LEVELS 1
#define LEVEL_STATE_FLAGS 2 #define LEVEL_STATE_FLAGS 2
AdminCache g_Admins; AdminCache g_Admins;
char g_ReverseFlags[26]; char g_ReverseFlags[AdminFlags_TOTAL];
AdminFlag g_FlagLetters[26]; AdminFlag g_FlagLetters[26];
bool g_FlagSet[26]; bool g_FlagCharSet[26];
/* Default flags */ /* Default flags */
AdminFlag g_DefaultFlags[26] = AdminFlag g_DefaultFlags[26] =
@ -71,9 +72,9 @@ public:
memcpy(g_FlagLetters, g_DefaultFlags, sizeof(AdminFlag) * 26); memcpy(g_FlagLetters, g_DefaultFlags, sizeof(AdminFlag) * 26);
for (unsigned int i=0; i<20; i++) for (unsigned int i=0; i<20; i++)
{ {
g_FlagSet[i] = true; g_FlagCharSet[i] = true;
} }
g_FlagSet[25] = true; g_FlagCharSet[25] = true;
} }
} }
private: private:
@ -103,7 +104,7 @@ private:
{ {
m_LevelState = LEVEL_STATE_NONE; m_LevelState = LEVEL_STATE_NONE;
m_IgnoreLevel = 0; m_IgnoreLevel = 0;
memset(g_FlagSet, 0, sizeof(g_FlagSet)); memset(g_FlagCharSet, 0, sizeof(g_FlagCharSet));
} }
SMCResult ReadSMC_NewSection(const SMCStates *states, const char *name) SMCResult ReadSMC_NewSection(const SMCStates *states, const char *name)
{ {
@ -163,7 +164,7 @@ private:
return SMCResult_Continue; return SMCResult_Continue;
} }
g_FlagSet[c] = true; g_FlagCharSet[c] = true;
return SMCResult_Continue; return SMCResult_Continue;
} }
@ -1063,22 +1064,29 @@ bool AdminCache::GetMethodIndex(const char *name, unsigned int *_index)
bool AdminCache::GetUnifiedSteamIdentity(const char *ident, char *out, size_t maxlen) bool AdminCache::GetUnifiedSteamIdentity(const char *ident, char *out, size_t maxlen)
{ {
int len = strlen(ident); int len = strlen(ident);
/* If the id was a steam id strip off the STEAM_*: part */ if (!strcmp(ident, "BOT"))
if (len >= 11 && !strncmp(ident, "STEAM_", 6) && ident[8] != '_')
{ {
// non-bot/lan Steam2 Id // Bots
strncopy(out, ident, maxlen);
return true;
}
else if (len >= 11 && !strncmp(ident, "STEAM_", 6) && ident[8] != '_')
{
// non-bot/lan Steam2 Id, strip off the STEAM_* part
snprintf(out, maxlen, "%s", &ident[8]); snprintf(out, maxlen, "%s", &ident[8]);
return true; return true;
} }
else if (len >= 7 && !strncmp(ident, "[U:", 3) && ident[len-1] == ']') else if (len >= 7 && !strncmp(ident, "[U:", 3) && ident[len-1] == ']')
{ {
// Steam3 Id // Steam3 Id, replicate the Steam2 Post-"STEAM_" part
uint32_t accountId = strtoul(&ident[5], nullptr, 10); uint32_t accountId = strtoul(&ident[5], nullptr, 10);
snprintf(out, maxlen, "%u:%u", accountId & 1, accountId >> 1); snprintf(out, maxlen, "%u:%u", accountId & 1, accountId >> 1);
return true; return true;
} }
else else
{ {
// 64-bit CSteamID, replicate the Steam2 Post-"STEAM_" part
// some constants from steamclientpublic.h // some constants from steamclientpublic.h
static const uint32_t k_EAccountTypeIndividual = 1; static const uint32_t k_EAccountTypeIndividual = 1;
static const int k_EUniverseInvalid = 0; static const int k_EUniverseInvalid = 0;
@ -1577,7 +1585,7 @@ bool AdminCache::FindFlag(char c, AdminFlag *pAdmFlag)
{ {
if (c < 'a' if (c < 'a'
|| c > 'z' || c > 'z'
|| !g_FlagSet[(unsigned)c - (unsigned)'a']) || !g_FlagCharSet[(unsigned)c - (unsigned)'a'])
{ {
return false; return false;
} }
@ -1592,17 +1600,13 @@ bool AdminCache::FindFlag(char c, AdminFlag *pAdmFlag)
bool AdminCache::FindFlagChar(AdminFlag flag, char *c) bool AdminCache::FindFlagChar(AdminFlag flag, char *c)
{ {
if (!g_FlagSet[flag]) char flagchar = g_ReverseFlags[flag];
{
return false;
}
if (c) if (c)
{ {
*c = g_ReverseFlags[flag]; *c = flagchar;
} }
return true; return flagchar != '?';
} }
FlagBits AdminCache::ReadFlagString(const char *flags, const char **end) FlagBits AdminCache::ReadFlagString(const char *flags, const char **end)

View File

@ -38,7 +38,7 @@
#include <am-string.h> #include <am-string.h>
#include "common_logic.h" #include "common_logic.h"
#define HANDLESYS_MAX_HANDLES (1<<14) #define HANDLESYS_MAX_HANDLES (1<<15)
#define HANDLESYS_MAX_TYPES (1<<9) #define HANDLESYS_MAX_TYPES (1<<9)
#define HANDLESYS_MAX_SUBTYPES 0xF #define HANDLESYS_MAX_SUBTYPES 0xF
#define HANDLESYS_SUBTYPE_MASK 0xF #define HANDLESYS_SUBTYPE_MASK 0xF

View File

@ -550,9 +550,22 @@ static cell_t FindValueInArray(IPluginContext *pContext, const cell_t *params)
return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err); return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
} }
// the blocknumber is not guaranteed to always be passed
size_t blocknumber = 0;
if (params[0] >= 3)
{
blocknumber = (size_t) params[3];
}
if (blocknumber >= array->blocksize())
{
return pContext->ThrowNativeError("Invalid block %d (blocksize: %d)", blocknumber, array->blocksize());
}
for (unsigned int i = 0; i < array->size(); i++) for (unsigned int i = 0; i < array->size(); i++)
{ {
if (params[2] == *array->at(i)) cell_t *blk = array->at(i);
if (params[2] == blk[blocknumber])
{ {
return (cell_t) i; return (cell_t) i;
} }
@ -597,7 +610,7 @@ REGISTER_NATIVES(cellArrayNatives)
{"ArrayList.Set", SetArrayCell}, {"ArrayList.Set", SetArrayCell},
{"ArrayList.SetString", SetArrayString}, {"ArrayList.SetString", SetArrayString},
{"ArrayList.SetArray", SetArrayArray}, {"ArrayList.SetArray", SetArrayArray},
{"ArrayList.Erease", RemoveFromArray}, {"ArrayList.Erase", RemoveFromArray},
{"ArrayList.ShiftUp", ShiftArrayUp}, {"ArrayList.ShiftUp", ShiftArrayUp},
{"ArrayList.SwapAt", SwapArrayItems}, {"ArrayList.SwapAt", SwapArrayItems},
{"ArrayList.Clone", CloneArray}, {"ArrayList.Clone", CloneArray},

View File

@ -334,9 +334,9 @@ public:
{ {
m_pDatabase->Close(); m_pDatabase->Close();
} }
m_pFunction->PushCell(BAD_HANDLE);
if (m_ACM == ACM_Old) if (m_ACM == ACM_Old)
m_pFunction->PushCell(BAD_HANDLE); m_pFunction->PushCell(BAD_HANDLE);
m_pFunction->PushCell(BAD_HANDLE);
m_pFunction->PushString("Driver is unloading"); m_pFunction->PushString("Driver is unloading");
m_pFunction->PushCell(m_Data); m_pFunction->PushCell(m_Data);
m_pFunction->Execute(NULL); m_pFunction->Execute(NULL);
@ -355,9 +355,9 @@ public:
} }
} }
m_pFunction->PushCell(m_pDriver->GetHandle());
if (m_ACM == ACM_Old) if (m_ACM == ACM_Old)
m_pFunction->PushCell(hndl); m_pFunction->PushCell(m_pDriver->GetHandle());
m_pFunction->PushCell(hndl);
m_pFunction->PushString(hndl == BAD_HANDLE ? error : ""); m_pFunction->PushString(hndl == BAD_HANDLE ? error : "");
m_pFunction->PushCell(m_Data); m_pFunction->PushCell(m_Data);
m_pFunction->Execute(NULL); m_pFunction->Execute(NULL);

View File

@ -309,7 +309,7 @@ static cell_t sm_OpenDirectory(IPluginContext *pContext, const cell_t *params)
if (!path[0]) if (!path[0])
{ {
return pContext->ThrowNativeError("Invalid file path"); return pContext->ThrowNativeError("Invalid path. An empty path string is not valid, use \".\" to refer to the current working directory.");
} }
Handle_t handle = 0; Handle_t handle = 0;
@ -617,6 +617,11 @@ static cell_t sm_DirExists(IPluginContext *pContext, const cell_t *params)
char *name; char *name;
pContext->LocalToString(params[1], &name); pContext->LocalToString(params[1], &name);
if (!name[0])
{
return pContext->ThrowNativeError("Invalid path. An empty path string is not valid, use \".\" to refer to the current working directory.");
}
if (params[0] >= 2 && params[2] == 1) if (params[0] >= 2 && params[2] == 1)
{ {
char *pathID; char *pathID;
@ -1176,6 +1181,7 @@ REGISTER_NATIVES(filesystem)
{"File.ReadInt8", File_ReadTyped<int8_t>}, {"File.ReadInt8", File_ReadTyped<int8_t>},
{"File.ReadUint8", File_ReadTyped<uint8_t>}, {"File.ReadUint8", File_ReadTyped<uint8_t>},
{"File.ReadInt16", File_ReadTyped<int16_t>}, {"File.ReadInt16", File_ReadTyped<int16_t>},
{"File.ReadUint16", File_ReadTyped<uint16_t>},
{"File.ReadInt32", File_ReadTyped<int32_t>}, {"File.ReadInt32", File_ReadTyped<int32_t>},
{"File.WriteInt8", File_WriteTyped<int8_t>}, {"File.WriteInt8", File_WriteTyped<int8_t>},
{"File.WriteInt16", File_WriteTyped<int16_t>}, {"File.WriteInt16", File_WriteTyped<int16_t>},

View File

@ -572,6 +572,47 @@ static cell_t ReferenceToBCompatRef(IPluginContext *pContext, const cell_t *para
return g_HL2.ReferenceToBCompatRef(params[1]); return g_HL2.ReferenceToBCompatRef(params[1]);
} }
// Must match ClientRangeType enum in halflife.inc
enum class ClientRangeType : cell_t
{
Visibility = 0,
Audibility,
};
static cell_t GetClientsInRange(IPluginContext *pContext, const cell_t *params)
{
cell_t *origin;
pContext->LocalToPhysAddr(params[1], &origin);
Vector vOrigin(sp_ctof(origin[0]), sp_ctof(origin[1]), sp_ctof(origin[2]));
ClientRangeType rangeType = (ClientRangeType) params[2];
CBitVec<ABSOLUTE_PLAYER_LIMIT> players;
engine->Message_DetermineMulticastRecipients(rangeType == ClientRangeType::Audibility, vOrigin, players);
cell_t *outPlayers;
pContext->LocalToPhysAddr(params[3], &outPlayers);
int maxPlayers = params[4];
int curPlayers = 0;
int index = players.FindNextSetBit(0);
while (index > -1 && curPlayers < maxPlayers)
{
int entidx = index + 1;
CPlayer *pPlayer = g_Players.GetPlayerByIndex(entidx);
if (pPlayer && pPlayer->IsInGame())
{
outPlayers[curPlayers++] = entidx;
}
index = players.FindNextSetBit(index + 1);
}
return curPlayers;
}
REGISTER_NATIVES(halflifeNatives) REGISTER_NATIVES(halflifeNatives)
{ {
{"CreateFakeClient", CreateFakeClient}, {"CreateFakeClient", CreateFakeClient},
@ -607,5 +648,6 @@ REGISTER_NATIVES(halflifeNatives)
{"EntIndexToEntRef", IndexToReference}, {"EntIndexToEntRef", IndexToReference},
{"EntRefToEntIndex", ReferenceToIndex}, {"EntRefToEntIndex", ReferenceToIndex},
{"MakeCompatEntRef", ReferenceToBCompatRef}, {"MakeCompatEntRef", ReferenceToBCompatRef},
{"GetClientsInRange", GetClientsInRange},
{NULL, NULL}, {NULL, NULL},
}; };

View File

@ -51,7 +51,9 @@ IPlayerInfoManager *playerinfo = NULL;
IBaseFileSystem *basefilesystem = NULL; IBaseFileSystem *basefilesystem = NULL;
IFileSystem *filesystem = NULL; IFileSystem *filesystem = NULL;
IEngineSound *enginesound = NULL; IEngineSound *enginesound = NULL;
#if SOURCE_ENGINE >= SE_ORANGEBOX
IServerTools *servertools = NULL; IServerTools *servertools = NULL;
#endif
IServerPluginHelpers *serverpluginhelpers = NULL; IServerPluginHelpers *serverpluginhelpers = NULL;
IServerPluginCallbacks *vsp_interface = NULL; IServerPluginCallbacks *vsp_interface = NULL;
int vsp_version = 0; int vsp_version = 0;
@ -70,7 +72,9 @@ bool SourceMod_Core::Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen
GET_V_IFACE_CURRENT(GetFileSystemFactory, basefilesystem, IBaseFileSystem, BASEFILESYSTEM_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(GetFileSystemFactory, filesystem, IFileSystem, FILESYSTEM_INTERFACE_VERSION);
GET_V_IFACE_CURRENT(GetEngineFactory, enginesound, IEngineSound, IENGINESOUND_SERVER_INTERFACE_VERSION); GET_V_IFACE_CURRENT(GetEngineFactory, enginesound, IEngineSound, IENGINESOUND_SERVER_INTERFACE_VERSION);
#if SOURCE_ENGINE >= SE_ORANGEBOX
GET_V_IFACE_CURRENT(GetServerFactory, servertools, IServerTools, VSERVERTOOLS_INTERFACE_VERSION); GET_V_IFACE_CURRENT(GetServerFactory, servertools, IServerTools, VSERVERTOOLS_INTERFACE_VERSION);
#endif
#if SOURCE_ENGINE != SE_DOTA #if SOURCE_ENGINE != SE_DOTA
GET_V_IFACE_CURRENT(GetEngineFactory, serverpluginhelpers, IServerPluginHelpers, INTERFACEVERSION_ISERVERPLUGINHELPERS); GET_V_IFACE_CURRENT(GetEngineFactory, serverpluginhelpers, IServerPluginHelpers, INTERFACEVERSION_ISERVERPLUGINHELPERS);
#endif #endif

View File

@ -102,7 +102,9 @@ extern IPlayerInfoManager *playerinfo;
extern IBaseFileSystem *basefilesystem; extern IBaseFileSystem *basefilesystem;
extern IFileSystem *filesystem; extern IFileSystem *filesystem;
extern IEngineSound *enginesound; extern IEngineSound *enginesound;
#if SOURCE_ENGINE >= SE_ORANGEBOX
extern IServerTools *servertools; extern IServerTools *servertools;
#endif
extern IServerPluginHelpers *serverpluginhelpers; extern IServerPluginHelpers *serverpluginhelpers;
extern IServerPluginCallbacks *vsp_interface; extern IServerPluginCallbacks *vsp_interface;
extern int vsp_version; extern int vsp_version;

View File

@ -176,9 +176,6 @@ bool SourceModBase::InitializeSourceMod(char *error, size_t maxlength, bool late
return false; return false;
} }
/* Initialize CoreConfig to get the SourceMod base path properly - this parses core.cfg */
g_CoreConfig.Initialize();
/* There will always be a path by this point, since it was force-set above. */ /* There will always be a path by this point, since it was force-set above. */
m_GotBasePath = true; m_GotBasePath = true;
@ -276,6 +273,9 @@ void SourceModBase::StartSourceMod(bool late)
InitLogicBridge(); InitLogicBridge();
/* Initialize CoreConfig to get the SourceMod base path properly - this parses core.cfg */
g_CoreConfig.Initialize();
/* Notify! */ /* Notify! */
SMGlobalClass *pBase = SMGlobalClass::head; SMGlobalClass *pBase = SMGlobalClass::head;
while (pBase) while (pBase)

View File

@ -61,8 +61,20 @@ DETOUR_DECL_MEMBER1(DetourHandleBuy, int, const char *, weapon)
#if SOURCE_ENGINE != SE_CSGO #if SOURCE_ENGINE != SE_CSGO
DETOUR_DECL_MEMBER0(DetourWeaponPrice, int) DETOUR_DECL_MEMBER0(DetourWeaponPrice, int)
#elif defined(WIN32)
DETOUR_DECL_MEMBER2(DetourWeaponPrice, int, CEconItemView *, pEconItem, int, iUnknown)
#else
DETOUR_DECL_MEMBER3(DetourWeaponPrice, int, CEconItemView *, pEconItem, int, iUnknown, float, fUnknown)
#endif
{ {
#if SOURCE_ENGINE != SE_CSGO
int price = DETOUR_MEMBER_CALL(DetourWeaponPrice)(); int price = DETOUR_MEMBER_CALL(DetourWeaponPrice)();
#elif defined(WIN32)
int price = DETOUR_MEMBER_CALL(DetourWeaponPrice)(pEconItem, iUnknown);
#else
int price = DETOUR_MEMBER_CALL(DetourWeaponPrice)(pEconItem, iUnknown, fUnknown);
#endif
if (lastclient == -1) if (lastclient == -1)
return price; return price;
@ -71,19 +83,6 @@ DETOUR_DECL_MEMBER0(DetourWeaponPrice, int)
return CallPriceForward(lastclient, weapon_name, price); 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
#if SOURCE_ENGINE != SE_CSGO || !defined(WIN32) #if SOURCE_ENGINE != SE_CSGO || !defined(WIN32)
DETOUR_DECL_MEMBER2(DetourTerminateRound, void, float, delay, int, reason) DETOUR_DECL_MEMBER2(DetourTerminateRound, void, float, delay, int, reason)
@ -178,7 +177,7 @@ DETOUR_DECL_MEMBER3(DetourCSWeaponDrop, void, CBaseEntity *, weapon, bool, bDrop
g_pCSWeaponDropForward->Execute(&result); g_pCSWeaponDropForward->Execute(&result);
if (result >= Pl_Continue) if (result == Pl_Continue)
{ {
#if SOURCE_ENGINE == SE_CSGO #if SOURCE_ENGINE == SE_CSGO
DETOUR_MEMBER_CALL(DetourCSWeaponDrop)(weapon, vec, unknown); DETOUR_MEMBER_CALL(DetourCSWeaponDrop)(weapon, vec, unknown);
@ -201,8 +200,15 @@ bool CreateWeaponPriceDetour()
} }
} }
#if SOURCE_ENGINE == SE_CSGO #if SOURCE_ENGINE == SE_CSGO && defined(WIN32)
DWeaponPrice = DETOUR_CREATE_MEMBER(DetourWeaponPrice, "GetAttributeInt"); void *pGetWeaponPriceAddress = GetWeaponPriceFunction();
if(!pGetWeaponPriceAddress)
{
g_pSM->LogError(myself, "GetWeaponPrice detour could not be initialized - Disabled OnGetWeaponPrice forward.");
}
DWeaponPrice = DETOUR_CREATE_MEMBER(DetourWeaponPrice, pGetWeaponPriceAddress);
#else #else
DWeaponPrice = DETOUR_CREATE_MEMBER(DetourWeaponPrice, "GetWeaponPrice"); DWeaponPrice = DETOUR_CREATE_MEMBER(DetourWeaponPrice, "GetWeaponPrice");
#endif #endif

View File

@ -419,6 +419,7 @@ static cell_t CS_GetTranslatedWeaponAlias(IPluginContext *pContext, const cell_t
static cell_t CS_GetWeaponPrice(IPluginContext *pContext, const cell_t *params) static cell_t CS_GetWeaponPrice(IPluginContext *pContext, const cell_t *params)
{ {
if (!IsValidWeaponID(params[2])) if (!IsValidWeaponID(params[2]))
return pContext->ThrowNativeError("Invalid WeaponID passed for this game"); return pContext->ThrowNativeError("Invalid WeaponID passed for this game");
@ -426,6 +427,7 @@ 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. //Hard code return values for weapons that dont call GetWeaponPrice and always use default value.
#if SOURCE_ENGINE == SE_CSGO #if SOURCE_ENGINE == SE_CSGO
if (id == WEAPON_C4 || id == WEAPON_KNIFE || id == WEAPON_KNIFE_GG) if (id == WEAPON_C4 || id == WEAPON_KNIFE || id == WEAPON_KNIFE_GG)
return 0; return 0;
#else #else
@ -458,23 +460,49 @@ static cell_t CS_GetWeaponPrice(IPluginContext *pContext, const cell_t *params)
#if SOURCE_ENGINE == SE_CSGO #if SOURCE_ENGINE == SE_CSGO
static ICallWrapper *pWrapper = NULL; static ICallWrapper *pWrapper = NULL;
#if defined(WIN32)
if(!pWrapper)
{
void *pGetWeaponPrice = GetWeaponPriceFunction();
if(!pGetWeaponPrice)
{
return pContext->ThrowNativeError("Failed to locate function");
}
PassInfo pass[2];
PassInfo ret;
pass[0].flags = PASSFLAG_BYVAL;
pass[0].type = PassType_Basic;
pass[0].size = sizeof(CEconItemView *);
pass[1].flags = PASSFLAG_BYVAL;
pass[1].type = PassType_Basic;
pass[1].size = sizeof(int);
ret.flags = PASSFLAG_BYVAL;
ret.type = PassType_Basic;
ret.size = sizeof(int);
pWrapper = g_pBinTools->CreateCall(pGetWeaponPrice, CallConv_ThisCall, &ret, pass, 2);
}
#else
if (!pWrapper) if (!pWrapper)
{ {
REGISTER_NATIVE_ADDR("GetAttributeInt", REGISTER_NATIVE_ADDR("GetWeaponPrice",
PassInfo pass[2]; \ PassInfo pass[3]; \
PassInfo ret; \ PassInfo ret; \
pass[0].flags = PASSFLAG_BYVAL; \ pass[0].flags = PASSFLAG_BYVAL; \
pass[0].type = PassType_Basic; \ pass[0].type = PassType_Basic; \
pass[0].size = sizeof(char *); \ pass[0].size = sizeof(CEconItemView *); \
pass[1].flags = PASSFLAG_BYVAL; \ pass[1].flags = PASSFLAG_BYVAL; \
pass[1].type = PassType_Basic; \ pass[1].type = PassType_Basic; \
pass[1].size = sizeof(CEconItemView *); \ pass[1].size = sizeof(int); \
pass[2].flags = PASSFLAG_BYVAL; \
pass[2].type = PassType_Float; \
pass[2].size = sizeof(float); \
ret.flags = PASSFLAG_BYVAL; \ ret.flags = PASSFLAG_BYVAL; \
ret.type = PassType_Basic; \ ret.type = PassType_Basic; \
ret.size = sizeof(int); \ ret.size = sizeof(int); \
pWrapper = g_pBinTools->CreateCall(addr, CallConv_ThisCall, &ret, pass, 2)) pWrapper = g_pBinTools->CreateCall(addr, CallConv_ThisCall, &ret, pass, 3))
} }
#endif
// Get a CEconItemView for the m4 // Get a CEconItemView for the m4
// Found in CCSPlayer::HandleCommand_Buy_Internal // Found in CCSPlayer::HandleCommand_Buy_Internal
// Linux a1 - CCSPlayer *pEntity, v5 - Player Team, a3 - ItemLoadoutSlot -1 use default loadoutslot: // Linux a1 - CCSPlayer *pEntity, v5 - Player Team, a3 - ItemLoadoutSlot -1 use default loadoutslot:
@ -552,14 +580,22 @@ static cell_t CS_GetWeaponPrice(IPluginContext *pContext, const cell_t *params)
pGetView->Execute(vstk_view, &view); pGetView->Execute(vstk_view, &view);
} }
unsigned char vstk[sizeof(void *) * 2 + sizeof(char *)]; #if defined(WIN32)
unsigned char vstk[sizeof(void *) * 2 + sizeof(int)];
#else
unsigned char vstk[sizeof(void *) * 2 + sizeof(int) + sizeof(float)];
#endif
unsigned char *vptr = vstk; unsigned char *vptr = vstk;
*(void **)vptr = info; *(void **)vptr = info;
vptr += sizeof(void *); vptr += sizeof(void *);
*(const char **)vptr = "in game price";
vptr += sizeof(const char *);
*(CEconItemView **)vptr = view; *(CEconItemView **)vptr = view;
vptr += sizeof(CEconItemView *);
*(int *)vptr = 0;
#if !defined(WIN32)
vptr += sizeof(int);
*(float *)vptr = 1.0;
#endif
int price = 0; int price = 0;
pWrapper->Execute(vstk, &price); pWrapper->Execute(vstk, &price);

View File

@ -229,6 +229,56 @@ const char *WeaponIDToAlias(int weaponID)
#endif #endif
return alias; return alias;
} }
#if SOURCE_ENGINE == SE_CSGO && defined(WIN32)
void *GetWeaponPriceFunction()
{
static void *pGetWeaponPriceAddress = NULL;
if(pGetWeaponPriceAddress == NULL)
{
void *pAddress = NULL;
int offset = 0;
int callOffset = 0;
const char* byteCheck = NULL;
if(!g_pGameConf->GetMemSig("GetWeaponPrice", &pAddress) || pAddress == NULL)
{
g_pSM->LogError(myself, "Failed to get GetWeaponPrice address.");
return NULL;
}
if(!g_pGameConf->GetOffset("GetWeaponPriceFunc", &offset))
{
g_pSM->LogError(myself, "Failed to get GetWeaponPriceFunc offset.");
return NULL;
}
byteCheck = g_pGameConf->GetKeyValue("GetWeaponPriceByteCheck");
if(byteCheck == NULL)
{
g_pSM->LogError(myself, "Failed to get GetWeaponPriceByteCheck keyvalue.");
return NULL;
}
uint8_t iByte = strtoul(byteCheck, NULL, 16);
if(iByte != *(uint8_t *)((intptr_t)pAddress + (offset-1)))
{
g_pSM->LogError(myself, "GetWeaponPrice Byte check failed.");
return NULL;
}
callOffset = *(uint32_t *)((intptr_t)pAddress + offset);
pGetWeaponPriceAddress = (void *)((intptr_t)pAddress + offset + callOffset + sizeof(int));
}
return pGetWeaponPriceAddress;
}
#endif
int GetRealWeaponID(int weaponId) int GetRealWeaponID(int weaponId)
{ {
#if SOURCE_ENGINE == SE_CSGO #if SOURCE_ENGINE == SE_CSGO

View File

@ -165,4 +165,6 @@ int GetFakeWeaponID(int weaponId);
bool IsValidWeaponID(int weaponId); bool IsValidWeaponID(int weaponId);
void *GetWeaponPriceFunction();
#endif #endif

View File

@ -96,11 +96,16 @@ MYSQL *Connect(const DatabaseInfo *info, char *error, size_t maxlength)
MYSQL *mysql = mysql_init(NULL); MYSQL *mysql = mysql_init(NULL);
const char *host = NULL, *socket = NULL; const char *host = NULL, *socket = NULL;
decltype(info->maxTimeout) timeout = 60;
if (info->maxTimeout > 0) if (info->maxTimeout > 0)
{ {
mysql_options(mysql, MYSQL_OPT_CONNECT_TIMEOUT, (const char *)&(info->maxTimeout)); timeout = info->maxTimeout;
} }
mysql_options(mysql, MYSQL_OPT_CONNECT_TIMEOUT, (const char *)&timeout);
mysql_options(mysql, MYSQL_OPT_READ_TIMEOUT, (const char *)&timeout);
mysql_options(mysql, MYSQL_OPT_WRITE_TIMEOUT, (const char *)&timeout);
/* Have MySQL automatically reconnect if it times out or loses connection. /* Have MySQL automatically reconnect if it times out or loses connection.
* This will prevent "MySQL server has gone away" errors after a while. * This will prevent "MySQL server has gone away" errors after a while.
*/ */

View File

@ -219,24 +219,6 @@ bool SDKHooks::SDK_OnLoad(char *error, size_t maxlength, bool late)
return false; return false;
} }
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");
playerhelpers->AddClientListener(&g_Interface);
plsys->AddPluginsListener(&g_Interface);
g_pOnEntityCreated = forwards->CreateForward("OnEntityCreated", ET_Ignore, 2, NULL, Param_Cell, Param_String);
g_pOnEntityDestroyed = forwards->CreateForward("OnEntityDestroyed", ET_Ignore, 1, NULL, Param_Cell);
#ifdef GAMEDESC_CAN_CHANGE
g_pOnGetGameNameDescription = forwards->CreateForward("OnGetGameDescription", ET_Hook, 2, NULL, Param_String);
#endif
g_pOnLevelInit = forwards->CreateForward("OnLevelInit", ET_Hook, 2, NULL, Param_String, Param_String);
buffer[0] = '\0'; buffer[0] = '\0';
if (!gameconfs->LoadGameConfigFile("sdkhooks.games", &g_pGameConf, buffer, sizeof(buffer))) if (!gameconfs->LoadGameConfigFile("sdkhooks.games", &g_pGameConf, buffer, sizeof(buffer)))
{ {
@ -257,6 +239,24 @@ bool SDKHooks::SDK_OnLoad(char *error, size_t maxlength, bool late)
entListeners->AddToTail(this); entListeners->AddToTail(this);
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");
playerhelpers->AddClientListener(&g_Interface);
plsys->AddPluginsListener(&g_Interface);
g_pOnEntityCreated = forwards->CreateForward("OnEntityCreated", ET_Ignore, 2, NULL, Param_Cell, Param_String);
g_pOnEntityDestroyed = forwards->CreateForward("OnEntityDestroyed", ET_Ignore, 1, NULL, Param_Cell);
#ifdef GAMEDESC_CAN_CHANGE
g_pOnGetGameNameDescription = forwards->CreateForward("OnGetGameDescription", ET_Hook, 2, NULL, Param_String);
#endif
g_pOnLevelInit = forwards->CreateForward("OnLevelInit", ET_Hook, 2, NULL, Param_String, Param_String);
SetupHooks(); SetupHooks();
#if SOURCE_ENGINE >= SE_ORANGEBOX #if SOURCE_ENGINE >= SE_ORANGEBOX
@ -894,9 +894,6 @@ bool SDKHooks::Hook_LevelInit(char const *pMapName, char const *pMapEntities, ch
g_pOnLevelInit->PushStringEx(g_szMapEntities, sizeof(g_szMapEntities), SM_PARAM_STRING_COPY, SM_PARAM_COPYBACK); g_pOnLevelInit->PushStringEx(g_szMapEntities, sizeof(g_szMapEntities), SM_PARAM_STRING_COPY, SM_PARAM_COPYBACK);
g_pOnLevelInit->Execute(&result); g_pOnLevelInit->Execute(&result);
if(result >= Pl_Handled)
RETURN_META_VALUE(MRES_SUPERCEDE, false);
if(result == Pl_Changed) if(result == Pl_Changed)
RETURN_META_VALUE_NEWPARAMS(MRES_HANDLED, true, &IServerGameDLL::LevelInit, (pMapName, g_szMapEntities, pOldLevel, pLandmarkName, loadGame, background)); RETURN_META_VALUE_NEWPARAMS(MRES_HANDLED, true, &IServerGameDLL::LevelInit, (pMapName, g_szMapEntities, pOldLevel, pLandmarkName, loadGame, background));

View File

@ -50,6 +50,9 @@
*/ */
SH_DECL_HOOK6(IServerGameDLL, LevelInit, SH_NOATTRIB, false, bool, const char *, const char *, const char *, const char *, bool, bool); SH_DECL_HOOK6(IServerGameDLL, LevelInit, SH_NOATTRIB, false, bool, const char *, const char *, const char *, const char *, bool, bool);
#if SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_CSGO
SH_DECL_HOOK1_void_vafmt(IVEngineServer, ClientCommand, SH_NOATTRIB, 0, edict_t *);
#endif
SDKTools g_SdkTools; /**< Global singleton for extension's main interface */ SDKTools g_SdkTools; /**< Global singleton for extension's main interface */
IServerGameEnts *gameents = NULL; IServerGameEnts *gameents = NULL;
@ -261,6 +264,10 @@ bool SDKTools::SDK_OnMetamodLoad(ISmmAPI *ismm, char *error, size_t maxlen, bool
#endif #endif
GET_V_IFACE_ANY(GetEngineFactory, soundemitterbase, ISoundEmitterSystemBase, SOUNDEMITTERSYSTEM_INTERFACE_VERSION); GET_V_IFACE_ANY(GetEngineFactory, soundemitterbase, ISoundEmitterSystemBase, SOUNDEMITTERSYSTEM_INTERFACE_VERSION);
#if SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_CSGO
SH_ADD_HOOK(IVEngineServer, ClientCommand, engine, SH_MEMBER(this, &SDKTools::OnSendClientCommand), false);
#endif
gpGlobals = ismm->GetCGlobals(); gpGlobals = ismm->GetCGlobals();
enginePatch = SH_GET_CALLCLASS(engine); enginePatch = SH_GET_CALLCLASS(engine);
enginesoundPatch = SH_GET_CALLCLASS(engsound); enginesoundPatch = SH_GET_CALLCLASS(engsound);
@ -268,6 +275,14 @@ bool SDKTools::SDK_OnMetamodLoad(ISmmAPI *ismm, char *error, size_t maxlen, bool
return true; return true;
} }
bool SDKTools::SDK_OnMetamodUnload(char *error, size_t maxlen)
{
#if SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_CSGO
SH_REMOVE_HOOK(IVEngineServer, ClientCommand, engine, SH_MEMBER(this, &SDKTools::OnSendClientCommand), false);
#endif
return true;
}
void SDKTools::SDK_OnAllLoaded() void SDKTools::SDK_OnAllLoaded()
{ {
SM_GET_LATE_IFACE(BINTOOLS, g_pBinTools); SM_GET_LATE_IFACE(BINTOOLS, g_pBinTools);
@ -456,6 +471,22 @@ void SDKTools::OnClientPutInServer(int client)
g_Hooks.OnClientPutInServer(client); g_Hooks.OnClientPutInServer(client);
} }
#if SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_CSGO
void SDKTools::OnSendClientCommand(edict_t *pPlayer, const char *szFormat)
{
// Due to legacy code, CS:S and CS:GO still sends "name \"newname\"" to the
// client after aname change. The engine has a change hook on name causing
// it to reset to the player's Steam name. This quashes that to make
// SetClientName work properly.
if (!strncmp(szFormat, "name ", 5))
{
RETURN_META(MRES_SUPERCEDE);
}
RETURN_META(MRES_IGNORED);
}
#endif
class SDKTools_API : public ISDKTools class SDKTools_API : public ISDKTools
{ {
public: public:

View File

@ -83,7 +83,7 @@ public: //public SDKExtension
public: public:
#if defined SMEXT_CONF_METAMOD #if defined SMEXT_CONF_METAMOD
virtual bool SDK_OnMetamodLoad(ISmmAPI *ismm, char *error, size_t maxlen, bool late); virtual bool SDK_OnMetamodLoad(ISmmAPI *ismm, char *error, size_t maxlen, bool late);
//virtual bool SDK_OnMetamodUnload(char *error, size_t maxlen); virtual bool SDK_OnMetamodUnload(char *error, size_t maxlen);
//virtual bool SDK_OnMetamodPauseChange(bool paused, char *error, size_t maxlen); //virtual bool SDK_OnMetamodPauseChange(bool paused, char *error, size_t maxlen);
#endif #endif
public: //IConCommandBaseAccessor public: //IConCommandBaseAccessor
@ -101,6 +101,9 @@ public: // IVoiceServer
#else #else
void OnClientCommand(edict_t *pEntity); void OnClientCommand(edict_t *pEntity);
#endif #endif
#if SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_CSGO
void OnSendClientCommand(edict_t *pPlayer, const char *szFormat);
#endif
public: //ICommandTargetProcessor public: //ICommandTargetProcessor
bool ProcessCommandTarget(cmd_target_info_t *info); bool ProcessCommandTarget(cmd_target_info_t *info);

View File

@ -46,7 +46,7 @@ static CBaseEntity *FindEntityByNetClass(int start, const char *classname)
for (int i = start; i < maxEntities; i++) for (int i = start; i < maxEntities; i++)
{ {
edict_t *current = gamehelpers->EdictOfIndex(i); edict_t *current = gamehelpers->EdictOfIndex(i);
if (current == NULL) if (current == NULL || current->IsFree())
continue; continue;
IServerNetworkable *network = current->GetNetworkable(); IServerNetworkable *network = current->GetNetworkable();

View File

@ -215,9 +215,12 @@ void GetIServer()
|| SOURCE_ENGINE == SE_DODS \ || SOURCE_ENGINE == SE_DODS \
|| SOURCE_ENGINE == SE_HL2DM \ || SOURCE_ENGINE == SE_HL2DM \
|| SOURCE_ENGINE == SE_CSS \ || SOURCE_ENGINE == SE_CSS \
|| SOURCE_ENGINE == SE_SDK2013 || SOURCE_ENGINE == SE_SDK2013 \
|| SOURCE_ENGINE == SE_INSURGENCY
#if SOURCE_ENGINE != SE_INSURGENCY
if (g_SMAPI->GetEngineFactory(false)("VEngineServer022", nullptr)) if (g_SMAPI->GetEngineFactory(false)("VEngineServer022", nullptr))
#endif // !SE_INSURGENCY
{ {
iserver = engine->GetIServer(); iserver = engine->GetIServer();
return; return;

View File

@ -2,7 +2,7 @@
* vim: set ts=4 : * vim: set ts=4 :
* ============================================================================= * =============================================================================
* SourceMod SDKTools Extension * SourceMod SDKTools Extension
* Copyright (C) 2004-2010 AlliedModders LLC. All rights reserved. * Copyright (C) 2004-2010 AlliedModders LLC. All rights reserved.
* ============================================================================= * =============================================================================
* *
* This program is free software; you can redistribute it and/or modify it under * This program is free software; you can redistribute it and/or modify it under
@ -1267,6 +1267,61 @@ static cell_t ActivateEntity(IPluginContext *pContext, const cell_t *params)
return 1; return 1;
} }
static cell_t SetClientName(IPluginContext *pContext, const cell_t *params)
{
if (iserver == NULL)
{
return pContext->ThrowNativeError("IServer interface not supported, file a bug report.");
}
IGamePlayer *player = playerhelpers->GetGamePlayer(params[1]);
IClient *pClient = iserver->GetClient(params[1] - 1);
if (player == NULL || pClient == NULL)
{
return pContext->ThrowNativeError("Invalid client index %d", params[1]);
}
if (!player->IsConnected())
{
return pContext->ThrowNativeError("Client %d is not connected", params[1]);
}
static ValveCall *pCall = NULL;
if (!pCall)
{
ValvePassInfo params[1];
InitPass(params[0], Valve_String, PassType_Basic, PASSFLAG_BYVAL);
if (!CreateBaseCall("SetClientName", ValveCall_Entity, NULL, params, 1, &pCall))
{
return pContext->ThrowNativeError("\"SetClientName\" not supported by this mod");
}
else if (!pCall)
{
return pContext->ThrowNativeError("\"SetClientName\" wrapper failed to initialize");
}
}
// The IClient vtable is +4 from the CBaseClient vtable due to multiple inheritance.
void *pGameClient = (void *)((intptr_t)pClient - 4);
// Change the name in the engine.
START_CALL();
void **ebuf = (void **)vptr;
*ebuf = pGameClient;
DECODE_VALVE_PARAM(2, vparams, 0);
FINISH_CALL_SIMPLE(NULL);
// Notify the server of the change.
#if SOURCE_ENGINE == SE_DOTA
serverClients->ClientSettingsChanged(player->GetIndex());
#else
serverClients->ClientSettingsChanged(player->GetEdict());
#endif
return 1;
}
static cell_t SetClientInfo(IPluginContext *pContext, const cell_t *params) static cell_t SetClientInfo(IPluginContext *pContext, const cell_t *params)
{ {
if (iserver == NULL) if (iserver == NULL)
@ -1418,6 +1473,7 @@ sp_nativeinfo_t g_Natives[] =
{"EquipPlayerWeapon", WeaponEquip}, {"EquipPlayerWeapon", WeaponEquip},
{"ActivateEntity", ActivateEntity}, {"ActivateEntity", ActivateEntity},
{"SetClientInfo", SetClientInfo}, {"SetClientInfo", SetClientInfo},
{"SetClientName", SetClientName},
{"GetPlayerResourceEntity", GetPlayerResourceEntity}, {"GetPlayerResourceEntity", GetPlayerResourceEntity},
{"GivePlayerAmmo", GivePlayerAmmo}, {"GivePlayerAmmo", GivePlayerAmmo},
{NULL, NULL}, {NULL, NULL},

View File

@ -41,11 +41,11 @@ cell_t TF2_MakeBleed(IPluginContext *pContext, const cell_t *params)
{ {
static ICallWrapper *pWrapper = NULL; static ICallWrapper *pWrapper = NULL;
// CTFPlayerShared::MakeBleed(CTFPlayer*, CTFWeaponBase*, float, int=4) // CTFPlayerShared::MakeBleed(CTFPlayer*, CTFWeaponBase*, float, int=4, bool=false)
if(!pWrapper) if(!pWrapper)
{ {
REGISTER_NATIVE_ADDR("MakeBleed", REGISTER_NATIVE_ADDR("MakeBleed",
PassInfo pass[4]; \ PassInfo pass[5]; \
pass[0].flags = PASSFLAG_BYVAL; \ pass[0].flags = PASSFLAG_BYVAL; \
pass[0].size = sizeof(CBaseEntity *); \ pass[0].size = sizeof(CBaseEntity *); \
pass[0].type = PassType_Basic; \ pass[0].type = PassType_Basic; \
@ -58,7 +58,10 @@ cell_t TF2_MakeBleed(IPluginContext *pContext, const cell_t *params)
pass[3].flags = PASSFLAG_BYVAL; \ pass[3].flags = PASSFLAG_BYVAL; \
pass[3].size = sizeof(int); \ pass[3].size = sizeof(int); \
pass[3].type = PassType_Basic; \ pass[3].type = PassType_Basic; \
pWrapper = g_pBinTools->CreateCall(addr, CallConv_ThisCall, NULL, pass, 4)) pass[4].flags = PASSFLAG_BYVAL; \
pass[4].size = sizeof(bool); \
pass[4].type = PassType_Basic; \
pWrapper = g_pBinTools->CreateCall(addr, CallConv_ThisCall, NULL, pass, 5))
} }
CBaseEntity *pEntity; CBaseEntity *pEntity;
@ -75,7 +78,7 @@ cell_t TF2_MakeBleed(IPluginContext *pContext, const cell_t *params)
void *obj = (void *)((uint8_t *)pEntity + playerSharedOffset->actual_offset); void *obj = (void *)((uint8_t *)pEntity + playerSharedOffset->actual_offset);
unsigned char vstk[sizeof(void *) + 2*sizeof(CBaseEntity *) + sizeof(float)]; unsigned char vstk[sizeof(void *) + 2*sizeof(CBaseEntity *) + sizeof(float) + sizeof(int) + sizeof(bool)];
unsigned char *vptr = vstk; unsigned char *vptr = vstk;
*(void **)vptr = obj; *(void **)vptr = obj;
@ -87,6 +90,8 @@ cell_t TF2_MakeBleed(IPluginContext *pContext, const cell_t *params)
*(float *)vptr = sp_ctof(params[3]); *(float *)vptr = sp_ctof(params[3]);
vptr += sizeof(float); vptr += sizeof(float);
*(int *)vptr = 4; *(int *)vptr = 4;
vptr += sizeof(int);
*(bool *)vptr = false;
pWrapper->Execute(vstk, NULL); pWrapper->Execute(vstk, NULL);
@ -98,7 +103,7 @@ cell_t TF2_Burn(IPluginContext *pContext, const cell_t *params)
{ {
static ICallWrapper *pWrapper = NULL; static ICallWrapper *pWrapper = NULL;
// CTFPlayerShared::Burn(CTFPlayer*, CTFWeaponBase*) // CTFPlayerShared::Burn(CTFPlayer*, CTFWeaponBase*, float=-1.0)
if (!pWrapper) if (!pWrapper)
{ {
REGISTER_NATIVE_ADDR("Burn", REGISTER_NATIVE_ADDR("Burn",
@ -129,7 +134,7 @@ cell_t TF2_Burn(IPluginContext *pContext, const cell_t *params)
void *obj = (void *)((uint8_t *)pEntity + playerSharedOffset->actual_offset); void *obj = (void *)((uint8_t *)pEntity + playerSharedOffset->actual_offset);
unsigned char vstk[sizeof(void *) + 2*sizeof(CBaseEntity *)]; unsigned char vstk[sizeof(void *) + 2*sizeof(CBaseEntity *) + sizeof(float)];
unsigned char *vptr = vstk; unsigned char *vptr = vstk;
*(void **)vptr = obj; *(void **)vptr = obj;
@ -155,7 +160,7 @@ cell_t TF2_Disguise(IPluginContext *pContext, const cell_t *params)
{ {
static ICallWrapper *pWrapper = NULL; static ICallWrapper *pWrapper = NULL;
//CTFPlayerShared::Disguise(int, int, CTFPlayer *) //CTFPlayerShared::Disguise(int, int, CTFPlayer *, bool=true)
if (!pWrapper) if (!pWrapper)
{ {
REGISTER_NATIVE_ADDR("Disguise", REGISTER_NATIVE_ADDR("Disguise",
@ -190,7 +195,7 @@ cell_t TF2_Disguise(IPluginContext *pContext, const cell_t *params)
return pContext->ThrowNativeError("Target client index %d is not valid", params[4]); return pContext->ThrowNativeError("Target client index %d is not valid", params[4]);
} }
unsigned char vstk[sizeof(void *) + 2*sizeof(int) + sizeof(bool)]; unsigned char vstk[sizeof(void *) + 2*sizeof(int) + sizeof(CBaseEntity *) + sizeof(bool)];
unsigned char *vptr = vstk; unsigned char *vptr = vstk;

View File

@ -80,12 +80,15 @@ TopMenu::~TopMenu()
delete m_Config.cats[i]; delete m_Config.cats[i];
} }
/* Sweep players */ if (m_clients != NULL)
for (size_t i = 0; i <= (size_t)m_max_clients; i++)
{ {
TearDownClient(&m_clients[i]); /* Sweep players */
for (size_t i = 0; i <= (size_t)m_max_clients; i++)
{
TearDownClient(&m_clients[i]);
}
free(m_clients);
} }
free(m_clients);
} }
unsigned int TopMenu::CalcMemUsage() unsigned int TopMenu::CalcMemUsage()

View File

@ -25,10 +25,66 @@
"plugin_7b3ce69f15e61cc896228cb8424be589" "" /* UCP Server (Endi) - Version 7.8.2 */ "plugin_7b3ce69f15e61cc896228cb8424be589" "" /* UCP Server (Endi) - Version 7.8.2 */
"plugin_24602c74f183cfcd157b3d50dee96c52" "" /* UCP Server (Endi) - Version 7.8.3 */ "plugin_24602c74f183cfcd157b3d50dee96c52" "" /* UCP Server (Endi) - Version 7.8.3 */
"plugin_43bd225c5fdcd3af35729ca9d481b20d" "" /* UCP Server (Endi) - Version 8.3 */ "plugin_43bd225c5fdcd3af35729ca9d481b20d" "" /* UCP Server (Endi) - Version 8.3 */
"plugin_aaeeeedeca7bdbdd630ddc5868daade7" "" /* UCP Server (Endi) - Version 8.4 */
"plugin_78140f1a0f26cd3297767d0598eac4b1" "" /* [Any] PReplay (DarthNinja) - Version 1.0.0 */ "plugin_78140f1a0f26cd3297767d0598eac4b1" "" /* [Any] PReplay (DarthNinja) - Version 1.0.0 */
"plugin_55923ba6bfe41569a3e4fbd7ca4606e5" "" /* VIP Plugin (World-Source.Ru) - Version 2.0 */ "plugin_55923ba6bfe41569a3e4fbd7ca4606e5" "" /* VIP Plugin (wS) - Version 2.0 */
"plugin_4bf983e1d5b61ba0b1ab9a7e53bfda27" "" /* WarMod CS:GO (Twelve-60) */ "plugin_4bf983e1d5b61ba0b1ab9a7e53bfda27" "" /* WarMod CS:GO (Twelve-60) */
"plugin_08574c4295afdaa5f613b8ceef96ecc3" "" /* AlliedBans (TommY) - Version 3.140902A */ "plugin_08574c4295afdaa5f613b8ceef96ecc3" "" /* AlliedBans (TommY) - Version 3.140902A */
"plugin_035ef79cb06a3ebcfaf277641577fdc6" "" /* Ability Levels (wS) - Version v1.1.1 */
"plugin_ce9183f87bf265408cb1c78534cc4863" "" /* Ability Levels Commands (wS) - Version 1.0.1 */
"plugin_d6386cf822f095289b011ca2f47ae6c4" "" /* AdMiN (wS) - Version v2.3.1 */
"plugin_02ef75b4af8c3f1d7998befdd8ed7586" "" /* Jail Control (wS) - Version v2.4.3 */
"plugin_a0c93519819ad79c3c2e27830c7edeff" "" /* Knife Arena (wS) - Version 1.2.7 */
"plugin_daf0ad0dd7c3aa732b9c1cb7a9cbb3cf" "" /* Round Start Effects (wS) - Version 1.2 */
"plugin_c473a87937edf5967db777f1cf04f725" "" /* Continuous Attack (wS) - Version 1.0 */
"plugin_12d7f2697110d4d67f33ca8b2a81c490" "" /* STORE (wS) - Version 2.1.5 */
"plugin_d134bd59c6f8dc2b8df27be31fd966b1" "" /* STORE (Auction) (wS) - Version 1.0 */
"plugin_159560d50105f9a58fa8a94de56c5fc4" "" /* STORE (Bhop) (wS) - Version 1.2 */
"plugin_99d45e0bfd4d4fdd0513cd84c50dca31" "" /* STORE (Credits Giver) (wS) - Version 1.2 */
"plugin_989d2075869168645c7a761ff41f69f6" "" /* STORE (Critical Grenade) (wS) - Version 1.1 */
"plugin_34eddaa68248ff140daad09a58c619de" "" /* STORE (Double Jump) (wS) - Version 1.0 */
"plugin_7bda86011e3365d90bee6dd88f213ae6" "" /* STORE (Enemy Skin) (wS) - Version 1.1 */
"plugin_4f2b15a5b260936149a3123504c1ac7c" "" /* STORE (Gifts) (wS) - Version 1.2 */
"plugin_c1b560cd688de12bebdeaa04999dc3d4" "" /* STORE (Gravity) (wS) - Version 1.1 */
"plugin_79e80527430bba85d311a79cd729b914" "" /* STORE (Health) (wS) - Version 1.2 */
"plugin_79fd13ceb7227c34571833a31d2a4957" "" /* STORE (Lasers) (wS) - Version 1.2 */
"plugin_7c83004d88445d84bf4291fec678614d" "" /* STORE (Money) (wS) - Version 1.3 */
"plugin_b98d853e0387ff44e4e58822949bb5f5" "" /* STORE (Respawn) (wS) - Version 1.2 */
"plugin_d45ef7eb8ef26a46e6ea8e7dc2640ed5" "" /* STORE (Show Credits) (wS) - Version 1.3 */
"plugin_624d31eecf19f9a4a7d87b7d2d2d14aa" "" /* STORE (Skins) (wS) - Version 1.2 */
"plugin_8b2f4f60a77d1e81e6e7026ff6316920" "" /* STORE (Speed) (wS) - Version 1.2 */
"plugin_643e1c5bf55c6ed10763dd46d4620aa4" "" /* STORE (Trails) (wS) - Version 1.2 */
"plugin_b75c6ba4f569c57bc6df906f1a4dfd4f" "" /* STORE (Transfer Credits) (wS) - Version 1.2 */
"plugin_93122ae52ae37c4a13eb9da25562e234" "" /* Teleporter (wS) - Version v1.0 */
"plugin_41f8b0b9b67fa207acf229bdf6251765" "" /* VIP Module (Ammo) (wS) - Version 1.0 */
"plugin_c9ff989b36ff12fcf3b8c93b42ada242" "" /* VIP Module (Anti Flash) (wS) - Version 1.1 */
"plugin_3c9c13133eb8d83c2b4221ca102d90ac" "" /* VIP Module (Armor) (wS) - Version 1.0 */
"plugin_b6eb66fe6fe44a907073825a02932317" "" /* VIP Module (Aura) (wS) - Version 1.1 */
"plugin_d6e99dbf976f4011399075dd4e2c95a8" "" /* VIP Module (BHOP|Double Jump|Parachute) (wS) - Version 1.4.7 */
"plugin_490fdd8bf0457878e89d383180c86e3d" "" /* VIP Module (Chat) (wS) - Version 1.2.1 */
"plugin_1655ed45b5c016bcfd703f8bc59cee69" "" /* VIP Module (DMG Changer) (wS) - Version 1.1 */
"plugin_0b194f78df428423927ba8868bcf3300" "" /* VIP Module (Drop Any Weapon) (wS) - Version 1.2 */
"plugin_0e574d5ffaac4600cd883270b55dc30a" "" /* VIP Module (Flags|Immunity) (wS) - Version 1.1 */
"plugin_a415a21bf430fa8b67b5ca73c9e46fb3" "" /* VIP Module (Gravity) (wS) - Version 1.1 */
"plugin_57d0852c9619c20c57e8a1d6b6f6b9da" "" /* VIP Module (Grenade Explode Effect) (wS) - Version 1.1 */
"plugin_ae385eb0ef6eaf12fb704051b17ac0e8" "" /* VIP Module (Grenade Model) (wS) - Version 1.0 */
"plugin_1915c17c700c2d6dd0c543f04ffcfb5c" "" /* VIP Module (Grenade Trail) (wS) - Version 1.2 */
"plugin_28c7754b3782b5b2f64243b5ac80088e" "" /* VIP Module (Hostage Rescue) (wS) - Version 1.0 */
"plugin_e3f382addaf9d83201dae58e816222e9" "" /* VIP Module (HP Regen) (wS) - Version 1.1 */
"plugin_8c6b5b2813dd289db3294346887d0160" "" /* VIP Module (Kill Cash) (wS) - Version 1.1 */
"plugin_21d22920b63ab7683b86e36aae239996" "" /* VIP Module (Kill HP) (wS) - Version 1.1 */
"plugin_7fb93bf5756a2d8542ca565d8d9aa65a" "" /* VIP Module (More Grenades) (wS) - Version 1.2.1 */
"plugin_43af503aec909771eb5e71fd65a411bb" "" /* VIP Module (Quick Defuse) (wS) - Version 1.1 */
"plugin_cf69750c2be3baf0fe6dd5dc21de257d" "" /* VIP Module (Reset Score) (wS) - Version 1.1 */
"plugin_f50c61c3d3c2f1f1393272c84dbe798d" "" /* VIP Module (Respawn) (wS) - Version 1.1 */
"plugin_43643c4b9ee9ed14fced7b06dd006e7f" "" /* VIP Module (Skins) (wS) - Version 1.2.5 */
"plugin_831bb87c8882c5e17408717cc829c7b6" "" /* VIP Module (Smoke Aura) (wS) - Version 1.1 */
"plugin_fd0550b620e4b280fbf5812478d97a0b" "" /* VIP Module (Speed) (wS) - Version 1.1 */
"plugin_249d893b2f699b51a757f9a0f76408e3" "" /* VIP Module (Team) (wS) - Version 1.1 */
"plugin_9bf46f7ecbf9a94fd4b3f922bb2f1003" "" /* VIP Module (Teleport) (wS) - Version 1.0 */
"plugin_229bb55fb7f4d9e6df47682847201031" "" /* VIP Test (wS) - Version 1.2 */
"plugin_4a9943bb6c831c605c3e4aef38d9c789" "" /* VIP Module (Trails) (wS) - Version 1.2 */
"plugin_2296f1162a2f1886fcad5601c1597835" "" /* VIP (!vips) (wS) - Version 1.2.1 */
} }
} }
} }

View File

@ -29,13 +29,6 @@
"windows" "11" "windows" "11"
"linux" "13" "linux" "13"
} }
"EntInfo"
{
"windows" "4"
"linux" "4"
"mac" "4"
}
} }
"Signatures" "Signatures"
@ -71,13 +64,6 @@
{ {
"windows" "11" "windows" "11"
} }
"EntInfo"
{
"windows" "4"
"linux" "4"
"mac" "4"
}
} }
"Signatures" "Signatures"
@ -102,5 +88,15 @@
{ {
"UseInvalidUniverseInSteam2IDs" "1" "UseInvalidUniverseInSteam2IDs" "1"
} }
"Offsets"
{
"EntInfo"
{
"windows" "4"
"linux" "4"
"mac" "4"
}
}
} }
} }

View File

@ -47,17 +47,17 @@
"mac" "294" "mac" "294"
} }
"PreThink" "PreThink"
{
"windows" "365"
"linux" "366"
"mac" "366"
}
"PostThink"
{ {
"windows" "366" "windows" "366"
"linux" "367" "linux" "367"
"mac" "367" "mac" "367"
} }
"PostThink"
{
"windows" "367"
"linux" "368"
"mac" "368"
}
"Reload" "Reload"
{ {
"windows" "308" "windows" "308"

View File

@ -156,6 +156,15 @@
"windows" "17" "windows" "17"
} }
/**
* CBaseClient::SetName(char const*);
* Has string "(%d)%-0.*s"
*/
"SetClientName"
{
"windows" "16"
}
/** /**
* Offset into CBaseClient - Used by CBaseServer::UpdateUserSettings to determine when changes have been made. * Offset into CBaseClient - Used by CBaseServer::UpdateUserSettings to determine when changes have been made.
* Find CBaseClient::UpdateUserSettings (strings "net_maxroutable", "cl_updaterate" etc) and the offset is set to 0 near the end. * Find CBaseClient::UpdateUserSettings (strings "net_maxroutable", "cl_updaterate" etc) and the offset is set to 0 near the end.

View File

@ -210,6 +210,17 @@
"linux" "64" "linux" "64"
"mac" "64" "mac" "64"
} }
/**
* CBaseClient::SetName(char const*);
* Linux offset straight from VTable dump.
* Has string "(%d)%-0.*s"
*/
"SetClientName"
{
"windows" "16"
"linux" "63"
"mac" "63"
}
/** /**
* Offset into CBaseClient - Used by CBaseServer::UpdateUserSettings to determine when changes have been made. * Offset into CBaseClient - Used by CBaseServer::UpdateUserSettings to determine when changes have been made.
* Find CBaseClient::UpdateUserSettings (strings "net_maxroutable", "cl_updaterate" etc) and the offset is set to 0 near the end. * Find CBaseClient::UpdateUserSettings (strings "net_maxroutable", "cl_updaterate" etc) and the offset is set to 0 near the end.

View File

@ -205,6 +205,17 @@
"linux" "63" "linux" "63"
"mac" "63" "mac" "63"
} }
/**
* CBaseClient::SetName(char const*);
* Linux offset straight from VTable dump.
* Has string "(%d)%-0.*s"
*/
"SetClientName"
{
"windows" "16"
"linux" "62"
"mac" "62"
}
/** /**
* Offset into CBaseClient - Used by CBaseServer::UpdateUserSettings to determine when changes have been made. * Offset into CBaseClient - Used by CBaseServer::UpdateUserSettings to determine when changes have been made.
* Find CBaseClient::UpdateUserSettings (strings "net_maxroutable", "cl_updaterate" etc) and the offset is set to 0 near the end. * Find CBaseClient::UpdateUserSettings (strings "net_maxroutable", "cl_updaterate" etc) and the offset is set to 0 near the end.

View File

@ -220,6 +220,17 @@
"SetUserCvar" "SetUserCvar"
{ {
/* Not 100% sure on this, why would windows change and not linux - TEST ME */ /* Not 100% sure on this, why would windows change and not linux - TEST ME */
"windows" "28"
"linux" "65"
"mac" "65"
}
/**
* CBaseClient::SetName(char const*);
* Linux offset straight from VTable dump.
* Has string "(%d)%-0.*s"
*/
"SetClientName"
{
"windows" "27" "windows" "27"
"linux" "64" "linux" "64"
"mac" "64" "mac" "64"
@ -252,9 +263,9 @@
{ {
"GiveNamedItem" "GiveNamedItem"
{ {
"windows" "445" "windows" "446"
"linux" "446" "linux" "447"
"mac" "446" "mac" "447"
} }
"RemovePlayerItem" "RemovePlayerItem"
{ {
@ -288,9 +299,9 @@
} }
"CommitSuicide" "CommitSuicide"
{ {
"windows" "495" "windows" "496"
"linux" "495" "linux" "496"
"mac" "495" "mac" "496"
} }
"GetVelocity" "GetVelocity"
{ {
@ -330,9 +341,9 @@
} }
"PlayerRunCmd" "PlayerRunCmd"
{ {
"windows" "465" "windows" "466"
"linux" "466" "linux" "467"
"mac" "466" "mac" "467"
} }
"GiveAmmo" "GiveAmmo"
{ {

View File

@ -193,6 +193,17 @@
"linux" "58" "linux" "58"
"mac" "58" "mac" "58"
} }
/**
* CBaseClient::SetName(char const*);
* Linux offset straight from VTable dump.
* Has string "(%d)%-0.*s"
*/
"SetClientName"
{
"windows" "17"
"linux" "57"
"mac" "57"
}
/** /**
* Offset into CBaseClient - Used by CBaseServer::UpdateUserSettings to determine when changes have been made. * Offset into CBaseClient - Used by CBaseServer::UpdateUserSettings to determine when changes have been made.
* Find CBaseClient::UpdateUserSettings (strings "net_maxroutable", "cl_updaterate" etc) and the offset is set to 0 near the end. * Find CBaseClient::UpdateUserSettings (strings "net_maxroutable", "cl_updaterate" etc) and the offset is set to 0 near the end.

View File

@ -225,6 +225,15 @@
"windows" "17" "windows" "17"
} }
/**
* CBaseClient::SetName(char const*);
* Has string "(%d)%-0.*s"
*/
"SetClientName"
{
"windows" "16"
}
"UpdateUserSettings" "UpdateUserSettings"
{ {
"windows" "7" "windows" "7"
@ -297,6 +306,10 @@
{ {
"windows" "32" "windows" "32"
} }
"PlayerRunCmd"
{
"windows" "327"
}
} }
"Signatures" "Signatures"

View File

@ -250,6 +250,17 @@
"SetUserCvar" "SetUserCvar"
{ {
"windows" "26" "windows" "26"
"linux" "63"
"mac" "63"
}
/**
* CBaseClient::SetName(char const*);
* Linux offset straight from VTable dump.
* Has string "(%d)%-0.*s"
*/
"SetClientName"
{
"windows" "25"
"linux" "62" "linux" "62"
"mac" "62" "mac" "62"
} }

View File

@ -256,6 +256,16 @@
"windows" "17" "windows" "17"
"linux" "53" "linux" "53"
} }
/**
* CBaseClient::SetName(char const*);
* Linux offset straight from VTable dump.
* Has string "(%d)%-0.*s"
*/
"SetClientName"
{
"windows" "16"
"linux" "52"
}
/** /**
* Offset into CBaseClient - Used by CBaseServer::UpdateUserSettings to determine when changes have been made. * Offset into CBaseClient - Used by CBaseServer::UpdateUserSettings to determine when changes have been made.
* Find CBaseClient::UpdateUserSettings (strings "net_maxroutable", "cl_updaterate" etc) and the offset is set to 0 near the end. * Find CBaseClient::UpdateUserSettings (strings "net_maxroutable", "cl_updaterate" etc) and the offset is set to 0 near the end.

View File

@ -219,6 +219,16 @@
"windows" "17" "windows" "17"
"linux" "55" "linux" "55"
} }
/**
* CBaseClient::SetName(char const*);
* Linux offset straight from VTable dump.
* Has string "(%d)%-0.*s"
*/
"SetClientName"
{
"windows" "16"
"linux" "54"
}
/** /**
* Offset into CBaseClient - Used by CBaseServer::UpdateUserSettings to determine when changes have been made. * Offset into CBaseClient - Used by CBaseServer::UpdateUserSettings to determine when changes have been made.
* Find CBaseClient::UpdateUserSettings (strings "net_maxroutable", "cl_updaterate" etc) and the offset is set to 0 near the end. * Find CBaseClient::UpdateUserSettings (strings "net_maxroutable", "cl_updaterate" etc) and the offset is set to 0 near the end.

View File

@ -237,6 +237,17 @@
"linux" "58" "linux" "58"
"mac" "58" "mac" "58"
} }
/**
* CBaseClient::SetName(char const*);
* Linux offset straight from VTable dump.
* Has string "(%d)%-0.*s"
*/
"SetClientName"
{
"windows" "17"
"linux" "57"
"mac" "57"
}
/** /**
* Offset into CBaseClient - Used by CBaseServer::UpdateUserSettings to determine when changes have been made. * Offset into CBaseClient - Used by CBaseServer::UpdateUserSettings to determine when changes have been made.
* Find CBaseClient::UpdateUserSettings (strings "net_maxroutable", "cl_updaterate" etc) and the offset is set to 0 near the end. * Find CBaseClient::UpdateUserSettings (strings "net_maxroutable", "cl_updaterate" etc) and the offset is set to 0 near the end.

View File

@ -183,6 +183,14 @@
{ {
"windows" "17" "windows" "17"
} }
/**
* CBaseClient::SetName(char const*);
* Has string "(%d)%-0.*s"
*/
"SetClientName"
{
"windows" "16"
}
/** /**
* Offset into CBaseClient - Used by CBaseServer::UpdateUserSettings to determine when changes have been made. * Offset into CBaseClient - Used by CBaseServer::UpdateUserSettings to determine when changes have been made.
* Find CBaseClient::UpdateUserSettings (strings "net_maxroutable", "cl_updaterate" etc) and the offset is set to 0 near the end. * Find CBaseClient::UpdateUserSettings (strings "net_maxroutable", "cl_updaterate" etc) and the offset is set to 0 near the end.

View File

@ -35,7 +35,7 @@
/* Offset into CBaseTempEntity constructor */ /* Offset into CBaseTempEntity constructor */
"s_pTempEntities" "s_pTempEntities"
{ {
"windows" "19" "windows" "16"
} }
"GetTEName" "GetTEName"
{ {
@ -62,7 +62,7 @@
"CBaseTempEntity" "CBaseTempEntity"
{ {
"library" "server" "library" "server"
"windows" "\x55\x8B\xEC\x8B\xC1\x8B\x4D\x08\xC7\x00\x2A\x2A\x2A\x2A\x89\x48\x2A\x8B" "windows" "\x55\x8B\xEC\x8B\x45\x08\x89\x41\x04\xC7\x01\x2A\x2A\x2A\x2A\xA1"
} }
"s_pTempEntities" "s_pTempEntities"
{ {
@ -82,7 +82,7 @@
"FindEntityByClassname" "FindEntityByClassname"
{ {
"library" "server" "library" "server"
"windows" "\x55\x8B\xEC\x53\x56\x8B\xF1\x8B\x4D\x08\x57\x85\xC9\x74\x2A\x8B\x01\x8B\x50\x08\xFF\xD2\x8B\x00\x83\xF8\xFF\x75\x2A\xB8\xFF\x1F\x00\x00\x8D\x04\x40\x8B\x74\xC6\x2A\xEB" "windows" "\x55\x8B\xEC\x53\x56\x8B\xF1\x8B\x4D\x08\x57\x85\xC9\x74\x26\x8B\x01\xFF\x50\x08\x8B\x00\x83\xF8\xFF\x75\x0E\xB8\xFF\x1F\x00\x00\x8D\x04\x40\x8B\x74\xC6\x10\xEB\x12\x0F\xB7\xC0\x8D\x04\x40\x8B\x74\xC6\x10\xEB\x06\x8B\xB6\x2A\x2A\x2A\x2A\x85\xF6\x74\x4C"
"linux" "@_ZN17CGlobalEntityList21FindEntityByClassnameEP11CBaseEntityPKc" "linux" "@_ZN17CGlobalEntityList21FindEntityByClassnameEP11CBaseEntityPKc"
"mac" "@_ZN17CGlobalEntityList21FindEntityByClassnameEP11CBaseEntityPKc" "mac" "@_ZN17CGlobalEntityList21FindEntityByClassnameEP11CBaseEntityPKc"
} }
@ -102,7 +102,7 @@
/* Offset into CreateGameRulesObject */ /* Offset into CreateGameRulesObject */
"g_pGameRules" "g_pGameRules"
{ {
"windows" "2" "windows" "5"
} }
} }
@ -119,7 +119,7 @@
"CreateGameRulesObject" "CreateGameRulesObject"
{ {
"library" "server" "library" "server"
"windows" "\x8B\x0D\x2A\x2A\x2A\x2A\x85\xC9\x74\x2A\x8B\x01\x8B\x50\x2A\x6A\x01\xFF\xD2" "windows" "\x55\x8B\xEC\x8B\x0D\x2A\x2A\x2A\x2A\x85\xC9\x74\x07\x8B"
} }
"g_pGameRules" "g_pGameRules"
{ {
@ -130,43 +130,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" "\x55\x8B\xEC\x8B\x2A\x2A\x50\xB9\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A\x85\xC0\x75"
}
"Offsets"
{
/* Offset into IVEngineServer::CreateFakeClient */
"sv"
{
"windows" "8"
}
}
"Signatures"
{
/* CBaseServer object for IServer interface */
"sv"
{
"library" "engine"
"linux" "@sv"
"mac" "@sv"
}
}
}
/* EntityFactoryDictionary function */ /* EntityFactoryDictionary function */
"#default" "#default"
{ {
@ -175,7 +138,7 @@
"EntityFactory" "EntityFactory"
{ {
"library" "server" "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" "windows" "\xA1\x2A\x2A\x2A\x2A\xA8\x01\x75\x1F\x83\xC8\x01\xB9\x2A\x2A\x2A\x2A\xA3\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A\x68\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A\x83\xC4\x04\xB8"
"linux" "@_Z23EntityFactoryDictionaryv" "linux" "@_Z23EntityFactoryDictionaryv"
"mac" "@_Z23EntityFactoryDictionaryv" "mac" "@_Z23EntityFactoryDictionaryv"
} }
@ -190,7 +153,7 @@
"FireOutput" "FireOutput"
{ {
"library" "server" "library" "server"
"windows" "\x55\x8B\xEC\x81\x2A\x2A\x2A\x2A\x2A\x53\x56\x8B\x71\x2A\x57" "windows" "\x55\x8B\xEC\x81\xEC\x2A\x2A\x2A\x2A\x53\x8B\xC1\xC7\x45\x2A\x2A\x2A\x2A\x00\x56\x57\x89"
"linux" "@_ZN17CBaseEntityOutput10FireOutputE9variant_tP11CBaseEntityS2_f" "linux" "@_ZN17CBaseEntityOutput10FireOutputE9variant_tP11CBaseEntityS2_f"
"mac" "@_ZN17CBaseEntityOutput10FireOutputE9variant_tP11CBaseEntityS2_f" "mac" "@_ZN17CBaseEntityOutput10FireOutputE9variant_tP11CBaseEntityS2_f"
} }
@ -214,6 +177,17 @@
"linux" "67" "linux" "67"
"mac" "67" "mac" "67"
} }
/**
* CBaseClient::SetName(char const*);
* Linux offset straight from VTable dump.
* Has string "(%d)%-0.*s"
*/
"SetClientName"
{
"windows" "19"
"linux" "66"
"mac" "66"
}
/** /**
* Offset into CBaseClient - Used by CBaseServer::UpdateUserSettings to determine when changes have been made. * Offset into CBaseClient - Used by CBaseServer::UpdateUserSettings to determine when changes have been made.
* Find CBaseClient::UpdateUserSettings (strings "net_maxroutable", "cl_updaterate" etc) and the offset is set to 0 near the end. * Find CBaseClient::UpdateUserSettings (strings "net_maxroutable", "cl_updaterate" etc) and the offset is set to 0 near the end.

View File

@ -225,6 +225,17 @@
"linux" "63" "linux" "63"
"mac" "63" "mac" "63"
} }
/**
* CBaseClient::SetName(char const*);
* Linux offset straight from VTable dump.
* Has string "(%d)%-0.*s"
*/
"SetClientName"
{
"windows" "16"
"linux" "62"
"mac" "62"
}
/** /**
* Offset into CBaseClient - Used by CBaseServer::UpdateUserSettings to determine when changes have been made. * Offset into CBaseClient - Used by CBaseServer::UpdateUserSettings to determine when changes have been made.
* Find CBaseClient::UpdateUserSettings (strings "net_maxroutable", "cl_updaterate" etc) and the offset is set to 0 near the end. * Find CBaseClient::UpdateUserSettings (strings "net_maxroutable", "cl_updaterate" etc) and the offset is set to 0 near the end.

View File

@ -102,6 +102,17 @@
"linux" "63" "linux" "63"
"mac" "63" "mac" "63"
} }
/**
* CBaseClient::SetName(char const*);
* Linux offset straight from VTable dump.
* Has string "(%d)%-0.*s"
*/
"SetClientName"
{
"windows" "16"
"linux" "62"
"mac" "62"
}
/** /**
* Offset into CBaseClient - Used by CBaseServer::UpdateUserSettings to determine when changes have been made. * Offset into CBaseClient - Used by CBaseServer::UpdateUserSettings to determine when changes have been made.
* Find CBaseClient::UpdateUserSettings (strings "net_maxroutable", "cl_updaterate" etc) and the offset is set to 0 near the end. * Find CBaseClient::UpdateUserSettings (strings "net_maxroutable", "cl_updaterate" etc) and the offset is set to 0 near the end.

View File

@ -91,6 +91,17 @@
"linux" "58" "linux" "58"
"mac" "58" "mac" "58"
} }
/**
* CBaseClient::SetName(char const*);
* Linux offset straight from VTable dump.
* Has string "(%d)%-0.*s"
*/
"SetClientName"
{
"windows" "17"
"linux" "57"
"mac" "57"
}
/** /**
* Offset into CBaseClient - Used by CBaseServer::UpdateUserSettings to determine when changes have been made. * Offset into CBaseClient - Used by CBaseServer::UpdateUserSettings to determine when changes have been made.
* Find CBaseClient::UpdateUserSettings (strings "net_maxroutable", "cl_updaterate" etc) and the offset is set to 0 near the end. * Find CBaseClient::UpdateUserSettings (strings "net_maxroutable", "cl_updaterate" etc) and the offset is set to 0 near the end.

View File

@ -180,6 +180,14 @@
/* Not 100% sure on this, why would windows change and not linux - TEST ME */ /* Not 100% sure on this, why would windows change and not linux - TEST ME */
"windows" "17" "windows" "17"
} }
/**
* CBaseClient::SetName(char const*);
* Has string "(%d)%-0.*s"
*/
"SetClientName"
{
"windows" "16"
}
/** /**
* Offset into CBaseClient - Used by CBaseServer::UpdateUserSettings to determine when changes have been made. * Offset into CBaseClient - Used by CBaseServer::UpdateUserSettings to determine when changes have been made.
* Find CBaseClient::UpdateUserSettings (strings "net_maxroutable", "cl_updaterate" etc) and the offset is set to 0 near the end. * Find CBaseClient::UpdateUserSettings (strings "net_maxroutable", "cl_updaterate" etc) and the offset is set to 0 near the end.

View File

@ -113,22 +113,22 @@
"CreateGameRulesObject" "CreateGameRulesObject"
{ {
"library" "server" "library" "server"
"windows" "\x8B\x0D\x2A\x2A\x2A\x2A\x85\xC9\x74\x09\x8B\x01\x8B\x50\x2C\x6A\x01" "windows" "\x8B\x0D\x2A\x2A\x2A\x2A\x85\xC9\x74\x2A\x8B\x01\x8B\x50\x2C\x6A\x01\xFF\xD2\x53\x56\x8B"
} }
"FindEntityByClassname" "FindEntityByClassname"
{ {
"library" "server" "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\x04\x00\x01\x00\x85\xFF\x74\x39\x8B\x5C\x24\x18\x8B\x2D\x2A\x2A\x2A\x2A\xEB\x03" "windows" "\x53\x55\x56\x8B\xF1\x8B\x4C\x24\x10\x85\xC9\x57\x74\x2A\x8B\x01\x8B\x50\x08\xFF\xD2\x8B\x00\x25\xFF\x0F\x00\x00\x83\xC0\x01\xC1\xE0\x04\x8B\x3C\x30\xEB\x2A\x8B\xBE\x04\x00\x01\x00\x85\xFF\x74\x2A\x8B\x5C\x24\x18\x8B\x2D\x2A\x2A\x2A\x2A\xEB\x2A\x8D\x49\x00\x8B\x37\x85\xF6\x75\x2A\x68\x2A\x2A\x2A\x2A\xFF\xD5\x83\xC4\x04\xEB\x2A\x39\x5E\x34\x74\x2A\x53\x8B\xCE\xE8\x2A\x2A\x2A\x2A\x84\xC0"
} }
"DispatchSpawn" "DispatchSpawn"
{ {
"library" "server" "library" "server"
"windows" "\x53\x55\x56\x8B\x74\x24\x10\x85\xF6\x57\x0F\x84\x2A\x2A\x2A\x2A\x8B\x1D\x2A\x2A\x2A\x2A\x8B\x03\x8B\x50\x60\x8B\xCB" "windows" "\x53\x55\x56\x8B\x74\x24\x10\x85\xF6\x57\x0F\x84\x2A\x2A\x2A\x2A\x8B\x1D\x2A\x2A\x2A\x2A\x8B\x03"
} }
"CreateEntityByName" "CreateEntityByName"
{ {
"library" "server" "library" "server"
"windows" "\x56\x8B\x74\x24\x0C\x83\xFE\xFF\x57\x8B\x7C\x24\x0C\x74\x27\x8B\x0D\x2A\x2A\x2A\x2A\x8B\x01\x8B\x50\x54\x56\xFF\xD2" "windows" "\x56\x8B\x74\x24\x0C\x83\xFE\xFF\x57\x8B\x7C\x2A\x2A\x74\x2A\x8B\x0D\x2A\x2A\x2A\x2A\x8B\x01\x8B"
} }
"FireOutput" "FireOutput"
{ {

View File

@ -125,6 +125,17 @@
"linux" "63" "linux" "63"
"mac" "63" "mac" "63"
} }
/**
* CBaseClient::SetName(char const*);
* Linux offset straight from VTable dump.
* Has string "(%d)%-0.*s"
*/
"SetClientName"
{
"windows" "16"
"linux" "62"
"mac" "62"
}
/** /**
* Offset into CBaseClient - Used by CBaseServer::UpdateUserSettings to determine when changes have been made. * Offset into CBaseClient - Used by CBaseServer::UpdateUserSettings to determine when changes have been made.
* Find CBaseClient::UpdateUserSettings (strings "net_maxroutable", "cl_updaterate" etc) and the offset is set to 0 near the end. * Find CBaseClient::UpdateUserSettings (strings "net_maxroutable", "cl_updaterate" etc) and the offset is set to 0 near the end.

View File

@ -13,6 +13,10 @@
{ {
"csgo" "csgo"
{ {
"Keys"
{
"GetWeaponPriceByteCheck" "E9"
}
"Offsets" "Offsets"
{ {
//Offset of szClassName in CCSWeaponInfo //Offset of szClassName in CCSWeaponInfo
@ -52,7 +56,7 @@
//Offset into HandleCommand_Buy_Internal //Offset into HandleCommand_Buy_Internal
"CCSPlayerInventoryOffset" "CCSPlayerInventoryOffset"
{ {
"windows" "285" "windows" "55"
"linux" "32" "linux" "32"
"mac" "109" "mac" "109"
} }
@ -62,6 +66,15 @@
"linux" "9" "linux" "9"
"mac" "9" "mac" "9"
} }
"GetWeaponPriceFunc"
{
"windows" "84"
}
//This is GetWeaponPriceFunc offset -1 (only used by GDC)
"GetWeaponPriceFuncGDC"
{
"windows" "83"
}
} }
"Signatures" "Signatures"
{ {
@ -82,7 +95,7 @@
"HandleCommand_Buy_Internal"//Wildcard first 6 bytes for getting address for weapon price. "HandleCommand_Buy_Internal"//Wildcard first 6 bytes for getting address for weapon price.
{ {
"library" "server" "library" "server"
"windows" "\x2A\x2A\x2A\x2A\x2A\x2A\x81\xEC\x2A\x2A\x2A\x2A\x83\x3D\x2A\x2A\x2A\x2A\x00\x53\x56\x57\x8B\xF9" "windows" "\x2A\x2A\x2A\x2A\x2A\x2A\x81\xEC\x64\x01\x00\x00\x53\x56\x57\x6A\x00\x8B\xF9\xE8\x2A\x2A\x2A\x2A\x33\xC9\x84\xC0"
"linux" "@_ZN9CCSPlayer26HandleCommand_Buy_InternalEPKcib" "linux" "@_ZN9CCSPlayer26HandleCommand_Buy_InternalEPKcib"
"mac" "@_ZN9CCSPlayer26HandleCommand_Buy_InternalEPKcib" "mac" "@_ZN9CCSPlayer26HandleCommand_Buy_InternalEPKcib"
} }
@ -96,7 +109,7 @@
"TerminateRound" "TerminateRound"
{ {
"library" "server" "library" "server"
"windows" "\x55\x8B\xEC\x83\x2A\x2A\x83\x2A\x2A\x53\x56\x57\x8B\xF9\xF3\x0F\x2A\x2A\x2A\x2A\x33\xDB\xC7\x2A\x2A\x2A\x00\x00\x00\x00\x89" "windows" "\x55\x8B\xEC\x83\xE4\xF8\x83\xEC\x3C\x53\x8B\xD9\xF3\x0F\x11\x4C\x24\x18\x56\x57\x89\x2A\x2A\x2A\x83"
"linux" "@_ZN12CCSGameRules14TerminateRoundEfi" "linux" "@_ZN12CCSGameRules14TerminateRoundEfi"
"mac" "@_ZN12CCSGameRules14TerminateRoundEfi" "mac" "@_ZN12CCSGameRules14TerminateRoundEfi"
} }
@ -143,13 +156,13 @@
"linux" "@_ZN9CCSPlayer10SetClanTagEPKc" "linux" "@_ZN9CCSPlayer10SetClanTagEPKc"
"mac" "@_ZN9CCSPlayer10SetClanTagEPKc" "mac" "@_ZN9CCSPlayer10SetClanTagEPKc"
} }
//Wild card first 6 bytes since we call it and detour it. //In windows this is CCSPlayer::GetWeaponPrice NOT CCSWeaponInfo::GetWeaponPrice
"GetAttributeInt" "GetWeaponPrice"
{ {
"library" "server" "library" "server"
"windows" "\x2A\x2A\x2A\x2A\x2A\x2A\x83\xEC\x1C\x53\x8B\x5D\x0C\xC7\x44\x24\x04\x00\x00\x00\x00\x56\x8B\xF1\x89\x74\x24\x0C\x57\x8B\x7D\x08\x85\xDB\x74\x2A\x80\x7B\x2A\x2A\x74\x2A\xE8\x2A\x2A\x2A\x2A\x57" "windows" "\x55\x8B\xEC\x8B\xD1\x8B\x4D\x08\x83\xF9\x33\x75\x2A\x83\xBA"
"linux" "@_ZNK16FileWeaponInfo_t15GetAttributeIntEPKcPK13CEconItemView" "linux" "@_ZNK13CCSWeaponInfo14GetWeaponPriceEPK13CEconItemViewif"
"mac" "@_ZNK16FileWeaponInfo_t15GetAttributeIntEPKcPK13CEconItemView" "mac" "@_ZNK13CCSWeaponInfo14GetWeaponPriceEPK13CEconItemViewif"
} }
"SetModelFromClass" "SetModelFromClass"
{ {

View File

@ -81,9 +81,9 @@
"MakeBleed" "MakeBleed"
{ {
"library" "server" "library" "server"
"windows" "\x55\x8B\xEC\x83\xEC\x20\x56\x8B\xF1\x89\x75\xF8\x8B\x8E" "windows" "\x55\x8B\xEC\x83\xEC\x24\x56\x8B\xF1\x89\x75\xF8\x8B\x8E\x2A\x2A\x2A\x2A\x8B\x01"
"linux" "@_ZN15CTFPlayerShared9MakeBleedEP9CTFPlayerP13CTFWeaponBasefi" "linux" "@_ZN15CTFPlayerShared9MakeBleedEP9CTFPlayerP13CTFWeaponBasefib"
"mac" "@_ZN15CTFPlayerShared9MakeBleedEP9CTFPlayerP13CTFWeaponBasefi" "mac" "@_ZN15CTFPlayerShared9MakeBleedEP9CTFPlayerP13CTFWeaponBasefib"
} }
"IsPlayerInDuel" "IsPlayerInDuel"
{ {
@ -118,17 +118,17 @@
"mac" "326" "mac" "326"
} }
"CalcIsAttackCriticalHelper" "CalcIsAttackCriticalHelper"
{
"windows" "384"
"linux" "391"
"mac" "391"
}
"CalcIsAttackCriticalHelperNoCrits"
{ {
"windows" "385" "windows" "385"
"linux" "392" "linux" "392"
"mac" "392" "mac" "392"
} }
"CalcIsAttackCriticalHelperNoCrits"
{
"windows" "386"
"linux" "393"
"mac" "393"
}
// CTFGameRules::IsHolidayActive // CTFGameRules::IsHolidayActive
"IsHolidayActive" "IsHolidayActive"

View File

@ -350,7 +350,7 @@ public void OnReceiveUser(Database db, DBResultSet rs, const char[] error, any d
/** /**
* Cache user info -- [0] = db id, [1] = cache id, [2] = groups * Cache user info -- [0] = db id, [1] = cache id, [2] = groups
*/ */
char[][] user_lookup = new char[num_accounts][3]; int[][] user_lookup = new int[num_accounts][3];
int total_users = 0; int total_users = 0;
while (rs.FetchRow()) while (rs.FetchRow())

View File

@ -71,7 +71,7 @@ public OnPluginStart()
LoadTranslations("common.phrases"); LoadTranslations("common.phrases");
LoadTranslations("basetriggers.phrases"); LoadTranslations("basetriggers.phrases");
g_Cvar_TriggerShow = CreateConVar("sm_trigger_show", "1", "Display triggers message to all players? (0 off, 1 on, def. 1)", 0, true, 0.0, true, 1.0); g_Cvar_TriggerShow = CreateConVar("sm_trigger_show", "0", "Display triggers message to all players? (0 off, 1 on, def. 0)", 0, true, 0.0, true, 1.0);
g_Cvar_TimeleftInterval = CreateConVar("sm_timeleft_interval", "0.0", "Display timeleft every x seconds. Default 0.", 0, true, 0.0, true, 1800.0); g_Cvar_TimeleftInterval = CreateConVar("sm_timeleft_interval", "0.0", "Display timeleft every x seconds. Default 0.", 0, true, 0.0, true, 1800.0);
g_Cvar_FriendlyFire = FindConVar("mp_friendlyfire"); g_Cvar_FriendlyFire = FindConVar("mp_friendlyfire");

View File

@ -63,17 +63,15 @@
* the Handle or add categories. * the Handle or add categories.
* *
* @param topmenu Handle to the admin menu's TopMenu. * @param topmenu Handle to the admin menu's TopMenu.
* @noreturn
*/ */
forward OnAdminMenuCreated(Handle topmenu); forward void OnAdminMenuCreated(Handle topmenu);
/** /**
* Called when the admin menu is ready to have items added. * Called when the admin menu is ready to have items added.
* *
* @param topmenu Handle to the admin menu's TopMenu. * @param topmenu Handle to the admin menu's TopMenu.
* @noreturn
*/ */
forward OnAdminMenuReady(Handle topmenu); forward void OnAdminMenuReady(Handle topmenu);
/** /**
* Retrieves the Handle to the admin top menu. * Retrieves the Handle to the admin top menu.

View File

@ -67,7 +67,7 @@ methodmap ArrayList < Handle {
public native ArrayList(int blocksize=1, int startsize=0); public native ArrayList(int blocksize=1, int startsize=0);
// Clears an array of all entries. This is the same as Resize(0). // Clears an array of all entries. This is the same as Resize(0).
public native void ClearArray(); public native void Clear();
// Clones an array, returning a new handle with the same size and data. // Clones an array, returning a new handle with the same size and data.
// This should NOT be confused with CloneHandle. This is a completely new // This should NOT be confused with CloneHandle. This is a completely new
@ -202,8 +202,10 @@ methodmap ArrayList < Handle {
// value cannot be located, -1 will be returned. // value cannot be located, -1 will be returned.
// //
// @param item Value to search for // @param item Value to search for
// @param block Optionally which block to search in
// @return Array index, or -1 on failure // @return Array index, or -1 on failure
public native int FindValue(any item); // @error Invalid block index
public native int FindValue(any item, int block=0);
// Retrieve the size of the array. // Retrieve the size of the array.
property int Length { property int Length {
@ -431,7 +433,8 @@ native int FindStringInArray(Handle array, const char[] item);
* *
* @param array Array Handle. * @param array Array Handle.
* @param item Value to search for * @param item Value to search for
* @param block Optionally which block to search in
* @return Array index, or -1 on failure * @return Array index, or -1 on failure
* @error Invalid Handle * @error Invalid Handle or invalid block
*/ */
native int FindValueInArray(Handle array, any item); native int FindValueInArray(Handle array, any item, int block=0);

View File

@ -41,7 +41,7 @@
* @param client Client index * @param client Client index
* @param muteState True if client was muted, false otherwise * @param muteState True if client was muted, false otherwise
*/ */
forward BaseComm_OnClientMute(client, bool:muteState); forward void BaseComm_OnClientMute(client, bool:muteState);
/** /**
* Called when a client is gagged or ungagged * Called when a client is gagged or ungagged
@ -49,7 +49,7 @@
* @param client Client index * @param client Client index
* @param gagState True if client was gaged, false otherwise * @param gagState True if client was gaged, false otherwise
*/ */
forward BaseComm_OnClientGag(client, bool:gagState); forward void BaseComm_OnClientGag(client, bool:gagState);
/** /**
* Returns whether or not a client is gagged * Returns whether or not a client is gagged

View File

@ -156,7 +156,7 @@ native bool:AreClientCookiesCached(client);
* *
* @param client Client index. * @param client Client index.
*/ */
forward OnClientCookiesCached(client); forward void OnClientCookiesCached(client);
/** /**
* Cookie Menu Callback prototype * Cookie Menu Callback prototype

View File

@ -144,7 +144,7 @@ forward Action:CS_OnBuyCommand(client, const String:weapon[]);
/** /**
* Called when CSWeaponDrop is called * Called when CSWeaponDrop is called
* Return Plugin_Continue to allow the call or return a * Return Plugin_Continue to allow the call or return a
* higher action to deny. * higher action to block.
* *
* @param client Client index * @param client Client index
* @param weaponIndex Weapon index * @param weaponIndex Weapon index

View File

@ -477,15 +477,13 @@ stock Database SQLite_UseDatabase(const char[] database,
char[] error, char[] error,
maxlength) maxlength)
{ {
new Handle kv, Handle db; KeyValues kv = CreateKeyValues("");
kv.SetString("driver", "sqlite");
kv.SetString("database", database);
kv = CreateKeyValues(""); Database db = SQL_ConnectCustom(kv, error, maxlength, false);
KvSetString(kv, "driver", "sqlite");
KvSetString(kv, "database", database);
db = SQL_ConnectCustom(kv, error, int maxlength, false); delete kv;
CloseHandle(kv);
return db; return db;
} }
@ -641,7 +639,7 @@ stock bool SQL_QuoteString(Handle database,
maxlength, maxlength,
&written=0) &written=0)
{ {
return SQL_EscapeString(database, string, buffer, int maxlength, written); return SQL_EscapeString(database, string, buffer, maxlength, written);
} }
/** /**

View File

@ -318,10 +318,10 @@ native Call_PushString(const String:value[]);
* @param value String to push. * @param value String to push.
* @param length Length of string buffer. * @param length Length of string buffer.
* @param szflags Flags determining how string should be handled. * @param szflags Flags determining how string should be handled.
* See SP_PARAM_STRING_* constants for details. * See SM_PARAM_STRING_* constants for details.
* The default (0) is to push ASCII. * The default (0) is to push ASCII.
* @param cpflags Whether or not changes should be copied back to the input array. * @param cpflags Whether or not changes should be copied back to the input array.
* See SP_PARAM_* constants for details. * See SM_PARAM_* constants for details.
* @noreturn * @noreturn
* @error Called before a call has been started. * @error Called before a call has been started.
*/ */

View File

@ -624,3 +624,21 @@ native EntRefToEntIndex(ref);
*/ */
native MakeCompatEntRef(ref); native MakeCompatEntRef(ref);
enum ClientRangeType
{
RangeType_Visibility = 0,
RangeType_Audibility,
}
/**
* Find clients that are potentially in range of a position.
*
* @param origin Coordinates from which to test range.
* @param rangeType Range type to use for filtering clients.
* @param clients Array to which found client indexes will be written.
* @param size Maximum size of clients array.
* @return Number of client indexes written to clients array.
*/
native int GetClientsInRange(float origin[3], ClientRangeType rangeType, int[] clients, int size);

View File

@ -371,7 +371,7 @@ methodmap Menu < Handle
int[] players = new int[MaxClients]; int[] players = new int[MaxClients];
for (int i = 1; i <= MaxClients; i++) { for (int i = 1; i <= MaxClients; i++) {
if (!IsClientInGame(i) || IsFakeClient(i)) if (!IsClientInGame(i) || IsFakeClient(i))
continue continue;
players[total++] = i; players[total++] = i;
} }
return this.DisplayVote(players, total, time, flags); return this.DisplayVote(players, total, time, flags);

View File

@ -264,7 +264,9 @@ typeset SDKHookCB
// OnTakeDamagePost // OnTakeDamagePost
// OnTakeDamageAlivePost // OnTakeDamageAlivePost
function void (int victim, int attacker, int inflictor, float damage, int damagetype); function void (int victim, int attacker, int inflictor, float damage, int damagetype);
function void (int victim, int attacker, int inflictor, float damage, int damagetype, const float damageForce[3], const float damagePosition[3]); function void (int victim, int attacker, int inflictor, float damage, int damagetype, int weapon, const float damageForce[3], const float damagePosition[3]);
function void (int victim, int attacker, int inflictor, float damage, int damagetype, int weapon,
const float damageForce[3], const float damagePosition[3], int damagecustom);
// FireBulletsPost // FireBulletsPost
function void (int client, int shots, const char[] weaponname); function void (int client, int shots, const char[] weaponname);
@ -297,17 +299,15 @@ typeset SDKHookCB
* *
* @param entity Entity index * @param entity Entity index
* @param classname Class name * @param classname Class name
* @noreturn
*/ */
forward OnEntityCreated(entity, const String:classname[]); forward void OnEntityCreated(int entity, const char[] classname);
/** /**
* @brief When an entity is destroyed * @brief When an entity is destroyed
* *
* @param entity Entity index * @param entity Entity index
* @noreturn
*/ */
forward OnEntityDestroyed(entity); forward void OnEntityDestroyed(int entity);
/** /**
* @brief When the game description is retrieved * @brief When the game description is retrieved
@ -315,18 +315,18 @@ forward OnEntityDestroyed(entity);
* @note Not supported on ep2v. * @note Not supported on ep2v.
* *
* @param gameDesc Game description * @param gameDesc Game description
* @noreturn * @return Plugin_Changed if gameDesc has been edited, else no change.
*/ */
forward Action:OnGetGameDescription(String:gameDesc[64]); forward Action OnGetGameDescription(char gameDesc[64]);
/** /**
* @brief When the level is initialized * @brief When the level is initialized
* *
* @param mapName Name of the map * @param mapName Name of the map
* @param mapEntities Entities of the map * @param mapEntities Entities of the map
* @noreturn * @return Plugin_Changed if mapEntities has been edited, else no change.
*/ */
forward Action:OnLevelInit(const String:mapName[], String:mapEntities[2097152]); forward Action OnLevelInit(const char[] mapName, char mapEntities[2097152]);
/** /**
* @brief Hooks an entity * @brief Hooks an entity
@ -334,9 +334,8 @@ forward Action:OnLevelInit(const String:mapName[], String:mapEntities[2097152]);
* @param entity Entity index * @param entity Entity index
* @param type Type of function to hook * @param type Type of function to hook
* @param callback Function to call when hook is called * @param callback Function to call when hook is called
* @noreturn
*/ */
native SDKHook(entity, SDKHookType:type, SDKHookCB:callback); native void SDKHook(int entity, SDKHookType type, SDKHookCB callback);
/** /**
* @brief Hooks an entity * @brief Hooks an entity
@ -346,7 +345,7 @@ native SDKHook(entity, SDKHookType:type, SDKHookCB:callback);
* @param callback Function to call when hook is called * @param callback Function to call when hook is called
* @return bool Hook Successful * @return bool Hook Successful
*/ */
native bool:SDKHookEx(entity, SDKHookType:type, SDKHookCB:callback); native bool SDKHookEx(int entity, SDKHookType type, SDKHookCB callback);
/** /**
* @brief Unhooks an entity * @brief Unhooks an entity
@ -354,9 +353,8 @@ native bool:SDKHookEx(entity, SDKHookType:type, SDKHookCB:callback);
* @param entity Entity index * @param entity Entity index
* @param type Type of function to unhook * @param type Type of function to unhook
* @param callback Callback function to unhook * @param callback Callback function to unhook
* @noreturn
*/ */
native SDKUnhook(entity, SDKHookType:type, SDKHookCB:callback); native void SDKUnhook(int entity, SDKHookType type, SDKHookCB callback);
/** /**
* @brief Applies damage to an entity * @brief Applies damage to an entity
@ -371,9 +369,10 @@ native SDKUnhook(entity, SDKHookType:type, SDKHookCB:callback);
* @param weapon Weapon index (orangebox and later) or -1 for unspecified * @param weapon Weapon index (orangebox and later) or -1 for unspecified
* @param damageForce Velocity of damage force * @param damageForce Velocity of damage force
* @param damagePosition Origin of damage * @param damagePosition Origin of damage
* @noreturn
*/ */
native SDKHooks_TakeDamage(entity, inflictor, attacker, Float:damage, damageType=DMG_GENERIC, weapon=-1, const Float:damageForce[3]=NULL_VECTOR, const Float:damagePosition[3]=NULL_VECTOR); native void SDKHooks_TakeDamage(int entity, int inflictor, int attacker,
float damage, int damageType=DMG_GENERIC, int weapon=-1,
const float damageForce[3]=NULL_VECTOR, const float damagePosition[3]=NULL_VECTOR);
/** /**
* @brief Forces a client to drop the specified weapon * @brief Forces a client to drop the specified weapon
@ -382,15 +381,15 @@ native SDKHooks_TakeDamage(entity, inflictor, attacker, Float:damage, damageType
* @param weapon Weapon entity index. * @param weapon Weapon entity index.
* @param vecTarget Location to toss weapon to, or NULL_VECTOR for default. * @param vecTarget Location to toss weapon to, or NULL_VECTOR for default.
* @param vecVelocity Velocity at which to toss weapon, or NULL_VECTOR for default. * @param vecVelocity Velocity at which to toss weapon, or NULL_VECTOR for default.
* @noreturn
* @error Invalid client or weapon entity, weapon not owned by client. * @error Invalid client or weapon entity, weapon not owned by client.
*/ */
native SDKHooks_DropWeapon(client, weapon, const Float:vecTarget[3]=NULL_VECTOR, const Float:vecVelocity[3]=NULL_VECTOR); native void SDKHooks_DropWeapon(int client, int weapon, const float vecTarget[3]=NULL_VECTOR,
const float vecVelocity[3]=NULL_VECTOR);
/** /**
* Do not edit below this line! * Do not edit below this line!
*/ */
public Extension:__ext_sdkhooks = public Extension __ext_sdkhooks =
{ {
name = "SDKHooks", name = "SDKHooks",
file = "sdkhooks.ext", file = "sdkhooks.ext",

View File

@ -332,6 +332,15 @@ native ActivateEntity(entity);
*/ */
native SetClientInfo(client, const String:key[], const String:value[]); native SetClientInfo(client, const String:key[], const String:value[]);
/**
* Changes a client's name.
*
* @param client Player's index.
* @param name New name.
* @error Invalid client index, or client not connected.
*/
native void SetClientName(int client, const char[] name);
/** /**
* Gives ammo of a certain type to a player. * Gives ammo of a certain type to a player.
* This natives obeys the maximum amount of ammo a player can carry per ammo type. * This natives obeys the maximum amount of ammo a player can carry per ammo type.

View File

@ -92,10 +92,6 @@ enum APLRes
* If any run-time error is thrown during this callback, the plugin will be marked * If any run-time error is thrown during this callback, the plugin will be marked
* as failed. * as failed.
* *
* It is not necessary to close any handles or remove hooks in this function.
* SourceMod guarantees that plugin shutdown automatically and correctly releases
* all resources.
*
* @noreturn * @noreturn
*/ */
forward void OnPluginStart(); forward void OnPluginStart();
@ -132,6 +128,10 @@ forward APLRes:AskPluginLoad2(Handle:myself, bool:late, String:error[], err_max)
/** /**
* Called when the plugin is about to be unloaded. * Called when the plugin is about to be unloaded.
* *
* It is not necessary to close any handles or remove hooks in this function.
* SourceMod guarantees that plugin shutdown automatically and correctly releases
* all resources.
*
* @noreturn * @noreturn
*/ */
forward void OnPluginEnd(); forward void OnPluginEnd();

View File

@ -107,7 +107,7 @@ enum TFCond
TFCond_RegenBuffed, TFCond_RegenBuffed,
TFCond_MarkedForDeath, TFCond_MarkedForDeath,
TFCond_NoHealingDamageBuff, TFCond_NoHealingDamageBuff,
TFCond_SpeedBuffAlly, //32 TFCond_SpeedBuffAlly, // 32
TFCond_HalloweenCritCandy, TFCond_HalloweenCritCandy,
TFCond_CritCanteen, TFCond_CritCanteen,
TFCond_CritDemoCharge, TFCond_CritDemoCharge,
@ -164,6 +164,15 @@ enum TFCond
TFCond_SwimmingCurse, TFCond_SwimmingCurse,
TFCond_HalloweenKartNoTurn, TFCond_HalloweenKartNoTurn,
TFCond_HalloweenKartCage, TFCond_HalloweenKartCage,
TFCond_HasRune,
TFCond_RuneStrength,
TFCond_RuneHaste,
TFCond_RuneRegen,
TFCond_RuneResist,
TFCond_RuneVampire,
TFCond_RuneWarlock,
TFCond_RunePrecision, // 96
TFCond_RuneAgility,
}; };
const Float:TFCondDuration_Infinite = -1.0; const Float:TFCondDuration_Infinite = -1.0;
@ -390,32 +399,26 @@ native TF2_RemoveWearable(client, wearable);
* *
* @param client Index of the client to which the conditon is being added. * @param client Index of the client to which the conditon is being added.
* @param condition Condition that is being added. * @param condition Condition that is being added.
* @noreturn
*/ */
forward TF2_OnConditionAdded(client, TFCond:condition); forward void TF2_OnConditionAdded(client, TFCond:condition);
/** /**
* Called after a condition is removed from a player * Called after a condition is removed from a player
* *
* @param client Index of the client to which the condition is being removed. * @param client Index of the client to which the condition is being removed.
* @param condition Condition that is being removed. * @param condition Condition that is being removed.
* @noreturn
*/ */
forward TF2_OnConditionRemoved(client, TFCond:condition); forward void TF2_OnConditionRemoved(client, TFCond:condition);
/** /**
* Called when the server enters the Waiting for Players round state * Called when the server enters the Waiting for Players round state
*
* @noreturn
*/ */
forward TF2_OnWaitingForPlayersStart(); forward void TF2_OnWaitingForPlayersStart();
/** /**
* Called when the server exits the Waiting for Players round state * Called when the server exits the Waiting for Players round state
*
* @noreturn
*/ */
forward TF2_OnWaitingForPlayersEnd(); forward void TF2_OnWaitingForPlayersEnd();
/** /**
* Called when a player attempts to use a teleporter to decide if the player should be allowed to teleport. * Called when a player attempts to use a teleporter to decide if the player should be allowed to teleport.

View File

@ -330,6 +330,19 @@ stock TFTeam:TF2_GetClientTeam(client)
return TFTeam:GetClientTeam(client); return TFTeam:GetClientTeam(client);
} }
/**
* Changes a client's current team.
*
* @param client Client index.
* @param team TFTeam team symbol.
* @noreturn
* @error Invalid client index.
*/
stock TF2_ChangeClientTeam(client, TFTeam:team)
{
ChangeClientTeam(client, _:team);
}
/** /**
* Gets a client's current class. * Gets a client's current class.
* *

View File

@ -96,6 +96,7 @@ native Handle:CreateTimer(Float:interval, Timer:func, any:data=INVALID_HANDLE, f
* @param autoClose If autoClose is true, the data that was passed to CreateTimer() will * @param autoClose If autoClose is true, the data that was passed to CreateTimer() will
* be closed as a handle if TIMER_DATA_HNDL_CLOSE was not specified. * be closed as a handle if TIMER_DATA_HNDL_CLOSE was not specified.
* @noreturn * @noreturn
* @error Invalid handles will cause a run time error.
*/ */
native KillTimer(Handle:timer, bool:autoClose=false); native KillTimer(Handle:timer, bool:autoClose=false);

View File

@ -151,19 +151,39 @@ native Handle:StartMessageEx(UserMsg:msg, clients[], numClients, flags=0);
native EndMessage(); native EndMessage();
/** /**
* Called when a message is hooked * Hook function types for user messages.
* */
* @param msg_id Message index. typeset MsgHook
* @param msg Handle to the input bit buffer or protobuf. {
* @param players Array containing player indexes. /**
* @param playersNum Number of players in the array. * Called when a bit buffer based usermessage is hooked
* @param reliable True if message is reliable, false otherwise. *
* @param init True if message is an initmsg, false otherwise. * @param msg_id Message index.
* @return Ignored for normal hooks. For intercept hooks, Plugin_Handled * @param msg Handle to the input bit buffer.
* blocks the message from being sent, and Plugin_Continue * @param players Array containing player indexes.
* resumes normal functionality. * @param playersNum Number of players in the array.
*/ * @param reliable True if message is reliable, false otherwise.
typedef MsgHook = function Action (UserMsg msg_id, Handle msg, const int[] players, int playersNum, bool reliable, bool init); * @param init True if message is an initmsg, false otherwise.
* @return Ignored for normal hooks. For intercept hooks, Plugin_Handled
* blocks the message from being sent, and Plugin_Continue
* resumes normal functionality.
*/
function Action (UserMsg msg_id, BfRead msg, const int[] players, int playersNum, bool reliable, bool init);
/**
* Called when a protobuf based usermessage is hooked
*
* @param msg_id Message index.
* @param msg Handle to the input protobuf.
* @param players Array containing player indexes.
* @param playersNum Number of players in the array.
* @param reliable True if message is reliable, false otherwise.
* @param init True if message is an initmsg, false otherwise.
* @return Ignored for normal hooks. For intercept hooks, Plugin_Handled
* blocks the message from being sent, and Plugin_Continue
* resumes normal functionality.
*/
function Action (UserMsg msg_id, Protobuf msg, const int[] players, int playersNum, bool reliable, bool init);
};
/** /**
* Called when a message hook has completed. * Called when a message hook has completed.

View File

@ -63,7 +63,8 @@ public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max
|| StrEqual(game, "left4dead2", false) || StrEqual(game, "left4dead2", false)
|| StrEqual(game, "garrysmod", false) || StrEqual(game, "garrysmod", false)
|| StrEqual(game, "swarm", false) || StrEqual(game, "swarm", false)
|| StrEqual(game, "dota", false)) || StrEqual(game, "dota", false)
|| GetEngineVersion() == Engine_Insurgency)
{ {
strcopy(error, err_max, "Nextmap is incompatible with this game"); strcopy(error, err_max, "Nextmap is incompatible with this game");
return APLRes_SilentFailure; return APLRes_SilentFailure;

View File

@ -50,9 +50,6 @@ public Plugin:myinfo =
TopMenu hTopMenu; TopMenu hTopMenu;
/* Used to get the SDK / Engine version. */ /* Used to get the SDK / Engine version. */
/* This is used in sm_rename and sm_changeteam */
new EngineVersion:g_ModVersion = Engine_Unknown;
#include "playercommands/slay.sp" #include "playercommands/slay.sp"
#include "playercommands/slap.sp" #include "playercommands/slap.sp"
#include "playercommands/rename.sp" #include "playercommands/rename.sp"
@ -66,8 +63,6 @@ public OnPluginStart()
RegAdminCmd("sm_slay", Command_Slay, ADMFLAG_SLAY, "sm_slay <#userid|name>"); RegAdminCmd("sm_slay", Command_Slay, ADMFLAG_SLAY, "sm_slay <#userid|name>");
RegAdminCmd("sm_rename", Command_Rename, ADMFLAG_SLAY, "sm_rename <#userid|name>"); RegAdminCmd("sm_rename", Command_Rename, ADMFLAG_SLAY, "sm_rename <#userid|name>");
g_ModVersion = GetEngineVersion();
/* Account for late loading */ /* Account for late loading */
TopMenu topmenu; TopMenu topmenu;
if (LibraryExists("adminmenu") && ((topmenu = GetAdminTopMenu()) != null)) if (LibraryExists("adminmenu") && ((topmenu = GetAdminTopMenu()) != null))

View File

@ -37,22 +37,8 @@ PerformRename(client, target)
{ {
LogAction(client, target, "\"%L\" renamed \"%L\" to \"%s\")", client, target, g_NewName[target]); LogAction(client, target, "\"%L\" renamed \"%L\" to \"%s\")", client, target, g_NewName[target]);
/* Used on OB / L4D engine */ SetClientName(target, g_NewName[target]);
if (g_ModVersion != Engine_SourceSDK2006)
{
SetClientInfo(target, "name", g_NewName[target]);
}
else /* Used on CSS and EP1 / older engine */
{
if (!IsPlayerAlive(target)) /* Lets tell them about the player renamed on the next round since they're dead. */
{
decl String:m_TargetName[MAX_NAME_LENGTH];
GetClientName(target, m_TargetName, sizeof(m_TargetName));
ReplyToCommand(client, "[SM] %t", "Dead Player Rename", m_TargetName);
}
ClientCommand(target, "name %s", g_NewName[target]);
}
g_NewName[target][0] = '\0'; g_NewName[target][0] = '\0';
} }

View File

@ -1 +1 @@
1.7.0-dev 1.7.2

View File

@ -58,6 +58,23 @@ CDetour *CDetourManager::CreateDetour(void *callbackfunction, void **trampoline,
return NULL; return NULL;
} }
CDetour *CDetourManager::CreateDetour(void *callbackfunction, void **trampoline, void *pAddress)
{
CDetour *detour = new CDetour(callbackfunction, trampoline, pAddress);
if (detour)
{
if (!detour->Init(spengine, gameconf))
{
delete detour;
return NULL;
}
return detour;
}
return NULL;
}
CDetour::CDetour(void *callbackfunction, void **trampoline, const char *signame) CDetour::CDetour(void *callbackfunction, void **trampoline, const char *signame)
{ {
enabled = false; enabled = false;
@ -71,6 +88,19 @@ CDetour::CDetour(void *callbackfunction, void **trampoline, const char *signame)
this->trampoline = trampoline; this->trampoline = trampoline;
} }
CDetour::CDetour(void*callbackfunction, void **trampoline, void *pAddress)
{
enabled = false;
detoured = false;
detour_address = pAddress;
detour_trampoline = NULL;
this->signame = NULL;
this->detour_callback = callbackfunction;
spengine = NULL;
gameconf = NULL;
this->trampoline = trampoline;
}
bool CDetour::Init(ISourcePawnEngine *spengine, IGameConfig *gameconf) bool CDetour::Init(ISourcePawnEngine *spengine, IGameConfig *gameconf)
{ {
this->spengine = spengine; this->spengine = spengine;
@ -100,11 +130,16 @@ bool CDetour::IsEnabled()
bool CDetour::CreateDetour() bool CDetour::CreateDetour()
{ {
if (!gameconf->GetMemSig(signame, &detour_address)) if (signame && !gameconf->GetMemSig(signame, &detour_address))
{ {
g_pSM->LogError(myself, "Could not locate %s - Disabling detour", signame); g_pSM->LogError(myself, "Could not locate %s - Disabling detour", signame);
return false; return false;
} }
else if(!detour_address)
{
g_pSM->LogError(myself, "Invalid detour address passed - Disabling detour to prevent crashes");
return false;
}
if (!detour_address) if (!detour_address)
{ {

View File

@ -167,6 +167,7 @@ public:
protected: protected:
CDetour(void *callbackfunction, void **trampoline, const char *signame); CDetour(void *callbackfunction, void **trampoline, const char *signame);
CDetour(void*callbackfunction, void **trampoline, void *pAddress);
bool Init(ISourcePawnEngine *spengine, IGameConfig *gameconf); bool Init(ISourcePawnEngine *spengine, IGameConfig *gameconf);
private: private:
@ -239,6 +240,7 @@ public:
* Note we changed the netadr_s reference into a void* to avoid needing to define the type * Note we changed the netadr_s reference into a void* to avoid needing to define the type
*/ */
static CDetour *CreateDetour(void *callbackfunction, void **trampoline, const char *signame); static CDetour *CreateDetour(void *callbackfunction, void **trampoline, const char *signame);
static CDetour *CreateDetour(void *callbackfunction, void **trampoline, void *pAddress);
friend class CBlocker; friend class CBlocker;
friend class CDetour; friend class CDetour;

View File

@ -174,6 +174,11 @@ class Thread
if (!initialized_) if (!initialized_)
delete data; delete data;
} }
~Thread() {
if (!Succeeded())
return;
pthread_detach(thread_);
}
bool Succeeded() const { bool Succeeded() const {
return initialized_; return initialized_;
@ -183,6 +188,7 @@ class Thread
if (!Succeeded()) if (!Succeeded())
return; return;
pthread_join(thread_, NULL); pthread_join(thread_, NULL);
initialized_ = false;
} }
private: private:

View File

@ -4,6 +4,8 @@
#define _GNU_SOURCE #define _GNU_SOURCE
#include <dlfcn.h> #include <dlfcn.h>
#include <string.h> #include <string.h>
#include <stdio.h>
#include <stdlib.h>
#define REG_EAX 0 #define REG_EAX 0
#define REG_ECX 1 #define REG_ECX 1
@ -13,8 +15,6 @@
#define IA32_MOV_REG_IMM 0xB8 // encoding is +r <imm32> #define IA32_MOV_REG_IMM 0xB8 // encoding is +r <imm32>
#endif #endif
extern void Msg( const char *, ... );
/** /**
* Checks if a call to a fpic thunk has just been written into dest. * Checks if a call to a fpic thunk has just been written into dest.
* If found replaces it with a direct mov that sets the required register to the value of pc. * If found replaces it with a direct mov that sets the required register to the value of pc.
@ -25,9 +25,7 @@ extern void Msg( const char *, ... );
*/ */
void check_thunks(unsigned char *dest, unsigned char *pc) void check_thunks(unsigned char *dest, unsigned char *pc)
{ {
#if defined WIN32 #ifndef WIN32
return;
#else
/* Step write address back 4 to the start of the function address */ /* Step write address back 4 to the start of the function address */
unsigned char *writeaddr = dest - 4; unsigned char *writeaddr = dest - 4;
unsigned char *calloffset = *(unsigned char **)writeaddr; unsigned char *calloffset = *(unsigned char **)writeaddr;
@ -64,7 +62,10 @@ void check_thunks(unsigned char *dest, unsigned char *pc)
} }
default: default:
{ {
Msg("Unknown thunk: %c\n", *(calladdr+1)); printf("Unknown thunk: %c\n", *(calladdr+1));
#ifndef NDEBUG
abort();
#endif
break; break;
} }
} }
@ -81,8 +82,6 @@ void check_thunks(unsigned char *dest, unsigned char *pc)
*(void **)writeaddr = (void *)pc; *(void **)writeaddr = (void *)pc;
writeaddr += 4; writeaddr += 4;
} }
return;
#endif #endif
} }

View File

@ -117,12 +117,12 @@ public:
return table_.findForAdd(aKey); return table_.findForAdd(aKey);
} }
void add(Insert &i, const T &value) bool add(Insert &i, const T &value)
{ {
return table_.add(i, value); return table_.add(i, value);
} }
void add(Insert &i, ke::Moveable<T> value) bool add(Insert &i, ke::Moveable<T> value)
{ {
return table_.add(i, value); return table_.add(i, value);
} }

View File

@ -2,14 +2,14 @@ a billion and nanas
joys of buildbot, part 2: buildbot and the very lonely square-shaped duck joys of buildbot, part 2: buildbot and the very lonely square-shaped duck
joys of buildbot, part 3: an accidental event proves troublesome for a psychic fish joys of buildbot, part 3: an accidental event proves troublesome for a psychic fish
joys of buildbot, part 4: a transient mummy is perplexed by a broken wand joys of buildbot, part 4: a transient mummy is perplexed by a broken wand
buildbot has horrible blugs buildbot has horrible bloogs
i am the very model of a modern major general I am the very model of a modern major general
It's no wonder the build always falls over when we call it pushing. It's no wonder the build always falls over when we call it pushing.
h h
i i
D D
S S
! !!!
joys of buildbot, part 5: a watermelon's diatribes need not be cause for spilling the queen's tea joys of buildbot, part 5: a watermelon's diatribes need not be cause for spilling the queen's tea
crab crab
joys of buildbot, part 6: a merry metal matchturtle mocks mostly and mainly in Madrid. joys of buildbot, part 6: a merry metal matchturtle mocks mostly and mainly in Madrid.
@ -17,11 +17,11 @@ joys of buildbot, part nana: if you don't do as you are told, buildbot-san, you
DS saves us from Valve again. DS saves us from Valve again.
Pants will save us from certain death. Pants will save us from certain death.
Invaders' blood marches through my veins, like GIANT RADIOACTIVE RUBBER PANTS! Invaders' blood marches through my veins, like GIANT RADIOACTIVE RUBBER PANTS!
THE PANTS COMMAND COMMAND ME! DO NOT IGNORE MY VEINS. ¡ THE PANTS COMMAND COMMAND ME! DO NOT IGNORE MY VEINS. !
This file sure has gotten big. This file sure has gotten big.
sawce is rukia and loves anime, sushi, and macs sawce is rukia and loves anime, sushi, and macs
ur ur
she calls it a mayonegg oh, it's so cute. she sometimes takes a little pack of mayonnaise, and she'll squirt it in her mouth all over, and then she'll take an egg and kind of... mmmmm. she calls it a mayonegg
not me not me
javaliabuf64k.. javaliabuf64k..
"line 29" rhymes... kinda. <-- CONFIRMED "line 29" rhymes... kinda. <-- CONFIRMED
@ -68,3 +68,5 @@ Buildbot, I hereby challenge you to an honorable prison stabbing to the death!
Bees. Bees.
Beads. Beads.
snakesssssssss; maple snakesssssssss; maple
pie?
Your tier1 tower is under attack..

View File

@ -79,10 +79,6 @@ typedef struct s_arginfo { /* function argument info */
unsigned char hasdefault; /* bit0: is there a default value? bit6: "tagof"; bit7: "sizeof" */ unsigned char hasdefault; /* bit0: is there a default value? bit6: "tagof"; bit7: "sizeof" */
union { union {
cell val; /* default value */ cell val; /* default value */
struct {
char *symname; /* name of another symbol */
short level; /* indirection level for that symbol */
} size; /* used for "sizeof" default value */
struct { struct {
cell *data; /* values of default array */ cell *data; /* values of default array */
int size; /* complete length of default array */ int size; /* complete length of default array */
@ -230,10 +226,6 @@ typedef struct s_symbol {
#define flgDEPRECATED 0x01 /* symbol is deprecated (avoid use) */ #define flgDEPRECATED 0x01 /* symbol is deprecated (avoid use) */
#define uCOUNTOF 0x20 /* set in the "hasdefault" field of the arginfo struct */
#define uTAGOF 0x40 /* set in the "hasdefault" field of the arginfo struct */
#define uSIZEOF 0x80 /* set in the "hasdefault" field of the arginfo struct */
#define uMAINFUNC "main" #define uMAINFUNC "main"
#define uENTRYFUNC "entry" #define uENTRYFUNC "entry"
@ -256,6 +248,20 @@ typedef struct value_s {
char boolresult; /* boolean result for relational operators */ char boolresult; /* boolean result for relational operators */
cell *arrayidx; /* last used array indices, for checking self assignment */ cell *arrayidx; /* last used array indices, for checking self assignment */
// Returns whether the value can be rematerialized based on static
// information, or whether it is the result of an expression.
bool canRematerialize() const {
switch (ident) {
case iVARIABLE:
case iCONSTEXPR:
return true;
case iREFERENCE:
return sym->vclass == sLOCAL;
default:
return false;
}
}
/* when ident == iACCESSOR */ /* when ident == iACCESSOR */
struct methodmap_method_s *accessor; struct methodmap_method_s *accessor;
} value; } value;
@ -264,6 +270,10 @@ typedef struct value_s {
typedef struct svalue_s { typedef struct svalue_s {
value val; value val;
int lvalue; int lvalue;
bool canRematerialize() const {
return val.canRematerialize();
}
} svalue; } svalue;
#define DECLFLAG_ARGUMENT 0x02 // The declaration is for an argument. #define DECLFLAG_ARGUMENT 0x02 // The declaration is for an argument.
@ -487,7 +497,6 @@ enum TokenKind {
tpDEFINE, tpDEFINE,
tpELSE, /* #else */ tpELSE, /* #else */
tpELSEIF, /* #elseif */ tpELSEIF, /* #elseif */
tpEMIT,
tpENDIF, tpENDIF,
tpENDINPUT, tpENDINPUT,
tpENDSCRPT, tpENDSCRPT,
@ -724,6 +733,7 @@ void startfunc(char *fname);
void endfunc(void); void endfunc(void);
void alignframe(int numbytes); void alignframe(int numbytes);
void rvalue(value *lval); void rvalue(value *lval);
void rvalue(svalue *sval);
void address(symbol *ptr,regid reg); void address(symbol *ptr,regid reg);
void store(value *lval); void store(value *lval);
void loadreg(cell address,regid reg); void loadreg(cell address,regid reg);
@ -990,7 +1000,7 @@ typedef struct array_info_s
} array_info_t; } array_info_t;
enum FatalError { enum FatalError {
FIRST_FATAL_ERROR = 180, FIRST_FATAL_ERROR = 182,
FATAL_ERROR_READ = FIRST_FATAL_ERROR, FATAL_ERROR_READ = FIRST_FATAL_ERROR,
FATAL_ERROR_WRITE, FATAL_ERROR_WRITE,

View File

@ -1445,12 +1445,25 @@ static void dodecl(const token_t *tok)
return; return;
} }
int fpublic = (tok->id == tPUBLIC); int fpublic = FALSE, fstock = FALSE, fstatic = FALSE, fconst = FALSE;
int fstock = (tok->id == tSTOCK); switch (tok->id) {
int fstatic = (tok->id == tSTATIC); case tPUBLIC:
fpublic = TRUE;
break;
case tSTOCK:
fstock = TRUE;
if (matchtoken(tSTATIC))
fstatic = TRUE;
break;
case tSTATIC:
fstatic = TRUE;
if (fstatic && matchtoken(tSTOCK)) // For compatibility, we must include this case. Though "stock" should
fstock = TRUE; // come first.
if (matchtoken(tSTOCK))
fstock = TRUE;
break;
}
int flags = DECLFLAG_MAYBE_FUNCTION | DECLFLAG_VARIABLE | DECLFLAG_ENUMROOT; int flags = DECLFLAG_MAYBE_FUNCTION | DECLFLAG_VARIABLE | DECLFLAG_ENUMROOT;
if (tok->id == tNEW) if (tok->id == tNEW)
@ -1462,7 +1475,13 @@ static void dodecl(const token_t *tok)
decl.type.tag = 0; decl.type.tag = 0;
} }
if (!decl.opertok && (tok->id == tNEW || decl.type.has_postdims || !lexpeek('('))) { // Hacky bag o' hints as to whether this is a variable decl.
bool probablyVariable = tok->id == tNEW ||
decl.type.has_postdims ||
!lexpeek('(') ||
((decl.type.usage & uCONST) == uCONST);
if (!decl.opertok && probablyVariable) {
if (tok->id == tNEW && decl.type.is_new) if (tok->id == tNEW && decl.type.is_new)
error(143); error(143);
if (decl.type.tag & STRUCTTAG) { if (decl.type.tag & STRUCTTAG) {
@ -3459,10 +3478,9 @@ static int reparse_new_decl(declinfo_t *decl, int flags)
// //
// Reset the fact that we saw an array. // Reset the fact that we saw an array.
decl->type.numdim = 0; decl->type.numdim = 0;
decl->type.size = 0;
decl->type.enumroot = NULL; decl->type.enumroot = NULL;
decl->type.ident = iVARIABLE; decl->type.ident = iVARIABLE;
decl->type.size = 0; decl->type.size = 1;
decl->type.has_postdims = false; decl->type.has_postdims = false;
if (matchtoken('[')) if (matchtoken('['))
parse_old_array_dims(decl, flags); parse_old_array_dims(decl, flags);
@ -4628,9 +4646,9 @@ static void decl_enum(int vclass)
char *str; char *str;
int tag,explicittag; int tag,explicittag;
cell increment,multiplier; cell increment,multiplier;
constvalue *enumroot;
LayoutSpec spec; LayoutSpec spec;
symbol *enumsym = nullptr; symbol *enumsym = nullptr;
constvalue *enumroot = nullptr;
/* get an explicit tag, if any (we need to remember whether an explicit /* get an explicit tag, if any (we need to remember whether an explicit
* tag was passed, even if that explicit tag was "_:", so we cannot call * tag was passed, even if that explicit tag was "_:", so we cannot call
@ -5515,8 +5533,8 @@ static int newfunc(declinfo_t *decl, const int *thistag, int fpublic, int fstati
// Check that return tags match. // Check that return tags match.
if ((sym->usage & uPROTOTYPED) && !compare_tag(sym->tag, decl->type.tag)) { if ((sym->usage & uPROTOTYPED) && !compare_tag(sym->tag, decl->type.tag)) {
int old_fline = fline; int old_fline = fline;
fline = sym->lnumber; fline = funcline;
error(25); error(180, type_to_name(sym->tag), type_to_name(decl->type.tag));
fline = old_fline; fline = old_fline;
} }
@ -5593,12 +5611,7 @@ static int argcompare(arginfo *a1,arginfo *a2)
* Pawn currently does not forbid them) */ * Pawn currently does not forbid them) */
} else { } else {
if (result) { if (result) {
if ((a1->hasdefault & uSIZEOF)!=0 || (a1->hasdefault & uTAGOF)!=0 || (a1->hasdefault & uCOUNTOF)!=0) result= a1->defvalue.val==a2->defvalue.val;
result= a1->hasdefault==a2->hasdefault
&& strcmp(a1->defvalue.size.symname,a2->defvalue.size.symname)==0
&& a1->defvalue.size.level==a2->defvalue.size.level;
else
result= a1->defvalue.val==a2->defvalue.val;
} /* if */ } /* if */
} /* if */ } /* if */
if (result) if (result)
@ -5731,13 +5744,10 @@ static int declargs(symbol *sym, int chkshadow, const int *thistag)
} else { } else {
/* check the argument with the earlier definition */ /* check the argument with the earlier definition */
if (argcnt>oldargcnt || !argcompare(&sym->dim.arglist[argcnt],&arg)) if (argcnt>oldargcnt || !argcompare(&sym->dim.arglist[argcnt],&arg))
error(25); /* function definition does not match prototype */ error(181, arg.name); /* function argument does not match prototype */
/* may need to free default array argument and the tag list */ /* may need to free default array argument and the tag list */
if (arg.ident==iREFARRAY && arg.hasdefault) if (arg.ident==iREFARRAY && arg.hasdefault)
free(arg.defvalue.array.data); free(arg.defvalue.array.data);
else if ((arg.ident==iVARIABLE
&& ((arg.hasdefault & uSIZEOF)!=0 || (arg.hasdefault & uTAGOF)!=0)) || (arg.hasdefault & uCOUNTOF)!=0)
free(arg.defvalue.size.symname);
free(arg.tags); free(arg.tags);
} /* if */ } /* if */
argcnt++; argcnt++;
@ -5745,47 +5755,6 @@ static int declargs(symbol *sym, int chkshadow, const int *thistag)
/* if the next token is not ",", it should be ")" */ /* if the next token is not ",", it should be ")" */
needtoken(')'); needtoken(')');
} /* if */ } /* if */
/* resolve any "sizeof" arguments (now that all arguments are known) */
assert(sym->dim.arglist!=NULL);
arglist=sym->dim.arglist;
for (idx=0; idx<argcnt && arglist[idx].ident!=0; idx++) {
if ((arglist[idx].hasdefault & uSIZEOF)!=0
|| (arglist[idx].hasdefault & uTAGOF)!=0
|| (arglist[idx].hasdefault & uCOUNTOF)!=0) {
int altidx;
/* Find the argument with the name mentioned after the "sizeof". Note
* that we cannot use findloc here because we need the arginfo struct,
* not the symbol.
*/
ptr=arglist[idx].defvalue.size.symname;
assert(ptr!=NULL);
for (altidx=0; altidx<argcnt && strcmp(ptr,arglist[altidx].name)!=0; altidx++)
/* nothing */;
if (altidx>=argcnt) {
error(17,ptr); /* undefined symbol */
} else {
assert(arglist[idx].defvalue.size.symname!=NULL);
/* check the level against the number of dimensions */
if (arglist[idx].defvalue.size.level>0
&& arglist[idx].defvalue.size.level>=arglist[altidx].numdim)
error(28,arglist[idx].name); /* invalid subscript */
/* check the type of the argument whose size to take; for a iVARIABLE
* or a iREFERENCE, this is always 1 (so the code is redundant)
*/
assert(arglist[altidx].ident!=iVARARGS);
if (arglist[altidx].ident!=iREFARRAY
&& (((arglist[idx].hasdefault & uSIZEOF)!=0)
|| (arglist[idx].hasdefault & uCOUNTOF)!=0)) {
if ((arglist[idx].hasdefault & uTAGOF)!=0) {
error(81,arglist[idx].name); /* cannot take "tagof" an indexed array */
} else {
assert(arglist[altidx].ident==iVARIABLE || arglist[altidx].ident==iREFERENCE);
error(223,ptr); /* redundant sizeof */
} /* if */
} /* if */
} /* if */
} /* if */
} /* for */
sym->usage|=uPROTOTYPED; sym->usage|=uPROTOTYPED;
errorset(sRESET,0); /* reset error flag (clear the "panic mode")*/ errorset(sRESET,0); /* reset error flag (clear the "panic mode")*/
@ -5883,42 +5852,9 @@ static void doarg(declinfo_t *decl, int offset, int fpublic, int chkshadow, argi
unsigned char size_tag_token; unsigned char size_tag_token;
assert(type->ident==iVARIABLE || type->ident==iREFERENCE); assert(type->ident==iVARIABLE || type->ident==iREFERENCE);
arg->hasdefault=TRUE; /* argument has a default value */ arg->hasdefault=TRUE; /* argument has a default value */
size_tag_token=(unsigned char)(matchtoken(tSIZEOF) ? uSIZEOF : 0); exprconst(&arg->defvalue.val,&arg->defvalue_tag,NULL);
if (size_tag_token==0) assert(type->numtags <= 1);
size_tag_token=(unsigned char)(matchtoken(tTAGOF) ? uTAGOF : 0); matchtag(type->tags[0], arg->defvalue_tag, TRUE);
if (size_tag_token==0)
size_tag_token=(unsigned char)(matchtoken(tCELLSOF) ? uCOUNTOF : 0);
if (size_tag_token!=0) {
int paranthese;
if (type->ident==iREFERENCE)
error(66, decl->name); /* argument may not be a reference */
paranthese=0;
while (matchtoken('('))
paranthese++;
if (needtoken(tSYMBOL)) {
/* save the name of the argument whose size id to take */
char *name;
cell val;
tokeninfo(&val,&name);
if ((arg->defvalue.size.symname=duplicatestring(name)) == NULL)
error(FATAL_ERROR_OOM); /* insufficient memory */
arg->defvalue.size.level=0;
if (size_tag_token==uSIZEOF || size_tag_token==uCOUNTOF) {
while (matchtoken('[')) {
arg->defvalue.size.level+=(short)1;
needtoken(']');
} /* while */
} /* if */
if (type->ident==iVARIABLE) /* make sure we set this only if not a reference */
arg->hasdefault |= size_tag_token; /* uSIZEOF or uTAGOF */
} /* if */
while (paranthese--)
needtoken(')');
} else {
exprconst(&arg->defvalue.val,&arg->defvalue_tag,NULL);
assert(type->numtags > 0);
matchtag(type->tags[0], arg->defvalue_tag, TRUE);
} /* if */
} /* if */ } /* if */
} /* if */ } /* if */
arg->ident=(char)type->ident; arg->ident=(char)type->ident;
@ -6538,7 +6474,20 @@ static int testsymbols(symbol *root,int level,int testlabs,int testconst)
int entry=FALSE; int entry=FALSE;
symbol *sym=root->next; symbol *sym=root->next;
while (sym!=NULL && sym->compound>=level) { symbol *parent;
while (sym!=NULL) {
if (sym->compound < level) {
parent = sym->parent;
if (parent == NULL || (parent->ident != iARRAY && parent->ident != iREFARRAY))
break;
/* This is one dimension of a multidimensional array. Find the top symbol. */
while (parent->parent != NULL && (parent->parent->ident == iARRAY || parent->parent->ident == iREFARRAY)) {
parent = parent->parent;
}
/* Only the top symbol gets the compound level set. */
if (parent->compound < level)
break;
}
switch (sym->ident) { switch (sym->ident) {
case iLABEL: case iLABEL:
if (testlabs) { if (testlabs) {
@ -7304,6 +7253,7 @@ static int dofor(void)
save_nestlevel=nestlevel; save_nestlevel=nestlevel;
save_endlessloop=endlessloop; save_endlessloop=endlessloop;
pushstacklist(); pushstacklist();
pushheaplist();
addwhile(wq); addwhile(wq);
skiplab=getlabel(); skiplab=getlabel();
@ -7401,6 +7351,8 @@ static int dofor(void)
setlabel(wq[wqEXIT]); setlabel(wq[wqEXIT]);
delwhile(); delwhile();
popheaplist();
assert(nestlevel>=save_nestlevel); assert(nestlevel>=save_nestlevel);
if (nestlevel>save_nestlevel) { if (nestlevel>save_nestlevel) {
/* Clean up the space and the symbol table for the local /* Clean up the space and the symbol table for the local

View File

@ -1036,10 +1036,6 @@ static int command(void)
} /* if */ } /* if */
if (!cp_set(name)) if (!cp_set(name))
error(FATAL_ERROR_NO_CODEPAGE); error(FATAL_ERROR_NO_CODEPAGE);
} else if (strcmp(str,"compress")==0) {
cell val;
preproc_expr(&val,NULL);
sc_compress=(int)val; /* switch code packing on/off */
} else if (strcmp(str,"ctrlchar")==0) { } else if (strcmp(str,"ctrlchar")==0) {
while (*lptr<=' ' && *lptr!='\0') while (*lptr<=' ' && *lptr!='\0')
lptr++; lptr++;
@ -1059,70 +1055,6 @@ static int command(void)
lptr=(unsigned char*)strchr((char*)lptr,'\0'); /* skip to end (ignore "extra characters on line") */ lptr=(unsigned char*)strchr((char*)lptr,'\0'); /* skip to end (ignore "extra characters on line") */
} else if (strcmp(str,"dynamic")==0) { } else if (strcmp(str,"dynamic")==0) {
preproc_expr(&pc_stksize,NULL); preproc_expr(&pc_stksize,NULL);
} else if (!strcmp(str,"library")
||!strcmp(str,"reqclass")
||!strcmp(str,"loadlib")
||!strcmp(str,"explib")
||!strcmp(str,"expclass")
||!strcmp(str,"defclasslib")) {
char name[sNAMEMAX+1],sname[sNAMEMAX+1];
const char *prefix="";
sname[0]='\0';
sname[1]='\0';
if (!strcmp(str,"library"))
prefix="??li_";
else if (!strcmp(str,"reqclass"))
prefix="??rc_";
else if (!strcmp(str,"loadlib"))
prefix="??f_";
else if (!strcmp(str,"explib"))
prefix="??el_";
else if (!strcmp(str,"expclass"))
prefix="??ec_";
else if (!strcmp(str,"defclasslib"))
prefix="??d_";
while (*lptr<=' ' && *lptr!='\0')
lptr++;
if (*lptr=='"') {
lptr=getstring((unsigned char*)name,sizeof name,lptr);
} else {
int i;
for (i=0; i<sizeof name && (alphanum(*lptr) || *lptr=='-'); i++,lptr++)
name[i]=*lptr;
name[i]='\0';
if (!strncmp(str,"exp",3) || !strncmp(str,"def",3)) {
while (*lptr && isspace(*lptr))
lptr++;
for (i=1; i<sizeof sname && alphanum(*lptr); i++,lptr++)
sname[i]=*lptr;
sname[i]='\0';
if (!sname[1]) {
error(45);
} else {
sname[0]='_';
}
}
} /* if */
if (strlen(name)==0) {
curlibrary=NULL;
} else if (strcmp(name,"-")==0) {
pc_addlibtable=FALSE;
} else {
/* add the name if it does not yet exist in the table */
char newname[sNAMEMAX+1];
if (strlen(name)+strlen(prefix)+strlen(sname)<=sNAMEMAX) {
strcpy(newname,prefix);
strcat(newname,name);
strcat(newname,sname);
if (find_constval(&libname_tab,newname,0)==NULL) {
if (!strcmp(str,"library") || !strcmp(str,"reqclass")) {
curlibrary=append_constval(&libname_tab,newname,1,0);
} else {
append_constval(&libname_tab,newname,1,0);
}
}
}
} /* if */
} else if (strcmp(str,"rational")==0) { } else if (strcmp(str,"rational")==0) {
char name[sNAMEMAX+1]; char name[sNAMEMAX+1];
cell digits=0; cell digits=0;
@ -1222,62 +1154,6 @@ static int command(void)
inpf=NULL; inpf=NULL;
} /* if */ } /* if */
break; break;
#if !defined NOEMIT
case tpEMIT: {
/* write opcode to output file */
char name[40];
int i;
while (*lptr<=' ' && *lptr!='\0')
lptr++;
for (i=0; i<40 && (isalpha(*lptr) || *lptr=='.'); i++,lptr++)
name[i]=(char)tolower(*lptr);
name[i]='\0';
stgwrite("\t");
stgwrite(name);
stgwrite(" ");
code_idx+=opcodes(1);
/* write parameter (if any) */
while (*lptr<=' ' && *lptr!='\0')
lptr++;
if (*lptr!='\0') {
symbol *sym;
tok=lex(&val,&str);
switch (tok) {
case tNUMBER:
case tRATIONAL:
outval(val,FALSE);
code_idx+=opargs(1);
break;
case tSYMBOL:
sym=findloc(str);
if (sym==NULL)
sym=findglb(str,sSTATEVAR);
if (sym==NULL || (sym->ident!=iFUNCTN && sym->ident!=iREFFUNC && (sym->usage & uDEFINE)==0)) {
error(17,str); /* undefined symbol */
} else {
outval(sym->addr,FALSE);
/* mark symbol as "used", unknown whether for read or write */
markusage(sym,uREAD | uWRITTEN);
code_idx+=opargs(1);
} /* if */
break;
default: {
char s2[20];
extern const char *sc_tokens[];/* forward declaration */
if (tok<256)
sprintf(s2,"%c",(char)tok);
else
strcpy(s2,sc_tokens[tok-tFIRST]);
error(1,sc_tokens[tSYMBOL-tFIRST],s2);
break;
} /* case */
} /* switch */
} /* if */
stgwrite("\n");
check_empty(lptr);
break;
} /* case */
#endif
#if !defined NO_DEFINE #if !defined NO_DEFINE
case tpDEFINE: { case tpDEFINE: {
ret=CMD_DEFINE; ret=CMD_DEFINE;
@ -2047,7 +1923,7 @@ const char *sc_tokens[] = {
"volatile", "volatile",
"while", "while",
"with", "with",
"#assert", "#define", "#else", "#elseif", "#emit", "#endif", "#endinput", "#assert", "#define", "#else", "#elseif", "#endif", "#endinput",
"#endscript", "#error", "#file", "#if", "#include", "#line", "#pragma", "#endscript", "#error", "#file", "#if", "#include", "#line", "#pragma",
"#tryinclude", "#undef", "#tryinclude", "#undef",
";", ";", "-integer value-", "-rational value-", "-identifier-", ";", ";", "-integer value-", "-rational value-", "-identifier-",
@ -2858,9 +2734,6 @@ static void free_symbol(symbol *sym)
for (arg=sym->dim.arglist; arg->ident!=0; arg++) { for (arg=sym->dim.arglist; arg->ident!=0; arg++) {
if (arg->ident==iREFARRAY && arg->hasdefault) if (arg->ident==iREFARRAY && arg->hasdefault)
free(arg->defvalue.array.data); free(arg->defvalue.array.data);
else if (arg->ident==iVARIABLE
&& ((arg->hasdefault & uSIZEOF)!=0 || (arg->hasdefault & uTAGOF)!=0))
free(arg->defvalue.size.symname);
assert(arg->tags!=NULL); assert(arg->tags!=NULL);
free(arg->tags); free(arg->tags);
} /* for */ } /* for */

View File

@ -2227,7 +2227,11 @@ restart:
* from the field and save the size of the field too. * from the field and save the size of the field too.
*/ */
assert(lval2.sym==NULL || lval2.sym->dim.array.level==0); assert(lval2.sym==NULL || lval2.sym->dim.array.level==0);
if (lval2.sym!=NULL && lval2.sym->dim.array.length>0 && sym->dim.array.level==0) { if (lval2.sym &&
lval2.sym->parent &&
lval2.sym->dim.array.length > 0 &&
sym->dim.array.level==0)
{
lval1->tag=lval2.sym->x.tags.index; lval1->tag=lval2.sym->x.tags.index;
lval1->constval=lval2.sym->dim.array.length; lval1->constval=lval2.sym->dim.array.length;
} /* if */ } /* if */
@ -2280,8 +2284,11 @@ restart:
* from the field and save the size of the field too. Otherwise, the * from the field and save the size of the field too. Otherwise, the
* tag is the one from the array symbol. * tag is the one from the array symbol.
*/ */
if (lval2.ident==iCONSTEXPR && lval2.sym!=NULL if (lval2.ident==iCONSTEXPR &&
&& lval2.sym->dim.array.length>0 && sym->dim.array.level==0) lval2.sym &&
lval2.sym->parent &&
lval2.sym->dim.array.length > 0 &&
sym->dim.array.level == 0)
{ {
lval1->tag=lval2.sym->x.tags.index; lval1->tag=lval2.sym->x.tags.index;
lval1->constval=lval2.sym->dim.array.length; lval1->constval=lval2.sym->dim.array.length;
@ -2310,15 +2317,17 @@ restart:
lval1->constval=0; lval1->constval=0;
} /* if */ } /* if */
/* a cell in an array is an lvalue, a character in an array is not
* always a *valid* lvalue */
lvalue = TRUE;
// If there's a call/fetch coming up, keep parsing. // If there's a call/fetch coming up, keep parsing.
if (matchtoken('.')) { if (matchtoken('.')) {
lexpush(); lexpush();
goto restart; goto restart;
} }
/* a cell in an array is an lvalue, a character in an array is not return lvalue;
* always a *valid* lvalue */
return TRUE;
} else { /* tok=='(' -> function(...) */ } else { /* tok=='(' -> function(...) */
svalue thisval; svalue thisval;
thisval.val = *lval1; thisval.val = *lval1;
@ -2334,6 +2343,7 @@ restart:
implicitthis = &thisval; implicitthis = &thisval;
break; break;
case FER_Accessor: case FER_Accessor:
lvalue = TRUE;
goto restart; goto restart;
default: default:
assert(false); assert(false);
@ -2652,7 +2662,7 @@ enum {
* Generates code to call a function. This routine handles default arguments * Generates code to call a function. This routine handles default arguments
* and positional as well as named parameters. * and positional as well as named parameters.
*/ */
static void callfunction(symbol *sym, const svalue *implicitthis, value *lval_result, int matchparanthesis) static void callfunction(symbol *sym, const svalue *aImplicitThis, value *lval_result, int matchparanthesis)
{ {
static long nest_stkusage=0L; static long nest_stkusage=0L;
static int nesting=0; static int nesting=0;
@ -2670,7 +2680,7 @@ static int nesting=0;
symbol *symret; symbol *symret;
cell lexval; cell lexval;
char *lexstr; char *lexstr;
int pending_this = (implicitthis ? TRUE : FALSE); bool pending_this = !!aImplicitThis;
assert(sym!=NULL); assert(sym!=NULL);
lval_result->ident=iEXPRESSION; /* preset, may be changed later */ lval_result->ident=iEXPRESSION; /* preset, may be changed later */
@ -2708,6 +2718,78 @@ static int nesting=0;
error(234,sym->name,ptr); /* deprecated (probably a native function) */ error(234,sym->name,ptr); /* deprecated (probably a native function) */
} /* if */ } /* if */
svalue implicit_this;
bool has_complex_this = false;
if (aImplicitThis) {
implicit_this = *aImplicitThis;
has_complex_this = !implicit_this.canRematerialize();
}
// If we have an implicit |this|, and it requires evaluating an expression
// to compute, then we have to save PRI across each argument. The reason is
// that Pawn will evaluate arguments like so:
//
// x[5].z(1, 2)
//
// Resolves to:
//
// begin:
// load.s.pri x
// add.pri.c 5 * sizeof(cell)
// marked:
// push.pri ; this
// const.pri 1
// push.pri
// const.pri 2
// push.pri 2
// finished:
// push.c 3 ; argc
//
// The expressions from "marked" to "finished" are reversed, so that
// arguments appear in order. Thus the final sequence is:
//
// begin:
// load.s.pri x
// add.pri.c 5 * sizeof(cell)
// marked:
// const.pri 2
// push.pri 2
// const.pri 1
// push.pri
// push.pri ; this
// finished:
// push.c 3 ; argc
//
// To account for this, if |this| requires evaluation, we evaluate it ahead
// of time and store it on the stack, so we can extract it again later.
// Because there is no opcode to do this, we have to play hot potato like so:
//
// begin:
// load.s.pri x
// add.pri.c 5 * sizeof(cell)
// marked:
// const.pri 2
// pop.alt ; pop |this|
// push.pri 2
// push.alt ; re-push |this|
// const.pri 1
// pop.alt ; pop |this|
// push.pri
// push.alt ; re-push |this|
// finished:
// push.c 3 ; argc
//
if (has_complex_this) {
// Compute an rvalue of |implicit_this|. Note that if it's an accessor,
// this reduces it to an iEXPRESSION. That's ok. We don't touch it
// otherwise though, so the type checking logic below basically acts the
// same. We are careful to not double-evaluate however.
if (implicit_this.lvalue)
rvalue(&implicit_this);
pushreg(sPRI);
nest_stkusage++;
}
/* run through the arguments */ /* run through the arguments */
arg=sym->dim.arglist; arg=sym->dim.arglist;
assert(arg!=NULL); assert(arg!=NULL);
@ -2778,8 +2860,8 @@ static int nesting=0;
if (arg[argidx].ident!=0 && arg[argidx].numtags==1) /* set the expected tag, if any */ if (arg[argidx].ident!=0 && arg[argidx].numtags==1) /* set the expected tag, if any */
lval.cmptag=arg[argidx].tags[0]; lval.cmptag=arg[argidx].tags[0];
if (pending_this) { if (pending_this) {
lval = implicitthis->val; lval = implicit_this.val;
lvalue = implicitthis->lvalue; lvalue = implicit_this.lvalue;
} else { } else {
lvalue = hier14(&lval); lvalue = hier14(&lval);
if (lvalue && lval.ident == iACCESSOR) { if (lvalue && lval.ident == iACCESSOR) {
@ -2791,7 +2873,7 @@ static int nesting=0;
switch (arg[argidx].ident) { switch (arg[argidx].ident) {
case 0: case 0:
/* On the first pass, we donm't have all of the parameter info. /* On the first pass, we donm't have all of the parameter info.
* Hpwever, use information must be marked anyway, otherwise vars * However, use information must be marked anyway, otherwise vars
* declared previously will be omitted in the second psas. See * declared previously will be omitted in the second psas. See
* SourceMod bug 4643. * SourceMod bug 4643.
*/ */
@ -2800,6 +2882,10 @@ static int nesting=0;
markusage(lval.sym, uREAD); markusage(lval.sym, uREAD);
break; break;
case iVARARGS: case iVARARGS:
// hier13() should filter non-methodmap functions, and |this| is
// always an iVARIABLE.
assert(!pending_this);
/* always pass by reference */ /* always pass by reference */
if (lval.ident==iVARIABLE || lval.ident==iREFERENCE) { if (lval.ident==iVARIABLE || lval.ident==iREFERENCE) {
assert(lval.sym!=NULL); assert(lval.sym!=NULL);
@ -2841,11 +2927,20 @@ static int nesting=0;
if (lval.ident==iLABEL || lval.ident==iFUNCTN || lval.ident==iREFFUNC if (lval.ident==iLABEL || lval.ident==iFUNCTN || lval.ident==iREFFUNC
|| lval.ident==iARRAY || lval.ident==iREFARRAY) || lval.ident==iARRAY || lval.ident==iREFARRAY)
error(35,argidx+1); /* argument type mismatch */ error(35,argidx+1); /* argument type mismatch */
if (lvalue)
rvalue(&lval); /* get value (direct or indirect) */ if (lvalue) {
// Note: do not load anything if the implicit this was pre-evaluted
// for being too complex.
if (!(pending_this && has_complex_this))
rvalue(&lval); /* get value (direct or indirect) */
}
/* otherwise, the expression result is already in PRI */ /* otherwise, the expression result is already in PRI */
assert(arg[argidx].numtags>0); assert(arg[argidx].numtags>0);
check_userop(NULL,lval.tag,arg[argidx].tags[0],2,NULL,&lval.tag);
// Do not allow user operators to transform |this|.
if (!pending_this)
check_userop(NULL,lval.tag,arg[argidx].tags[0],2,NULL,&lval.tag);
if (!checktags_string(arg[argidx].tags, arg[argidx].numtags, &lval)) if (!checktags_string(arg[argidx].tags, arg[argidx].numtags, &lval))
checktag(arg[argidx].tags, arg[argidx].numtags, lval.tag); checktag(arg[argidx].tags, arg[argidx].numtags, lval.tag);
if (lval.tag!=0) if (lval.tag!=0)
@ -2853,6 +2948,10 @@ static int nesting=0;
argidx++; /* argument done */ argidx++; /* argument done */
break; break;
case iREFERENCE: case iREFERENCE:
// hier13() should filter non-methodmap functions, and |this| is
// always an iVARIABLE.
assert(!pending_this);
if (!lvalue) if (!lvalue)
error(35,argidx+1); /* argument type mismatch */ error(35,argidx+1); /* argument type mismatch */
if (lval.sym!=NULL && (lval.sym->usage & uCONST)!=0 && (arg[argidx].usage & uCONST)==0) if (lval.sym!=NULL && (lval.sym->usage & uCONST)!=0 && (arg[argidx].usage & uCONST)==0)
@ -2876,6 +2975,10 @@ static int nesting=0;
markusage(lval.sym,uWRITTEN); markusage(lval.sym,uWRITTEN);
break; break;
case iREFARRAY: case iREFARRAY:
// hier13() should filter non-methodmap functions, and |this| is
// always an iVARIABLE.
assert(!pending_this);
if (lval.ident!=iARRAY && lval.ident!=iREFARRAY if (lval.ident!=iARRAY && lval.ident!=iREFARRAY
&& lval.ident!=iARRAYCELL && lval.ident!=iARRAYCHAR) && lval.ident!=iARRAYCELL && lval.ident!=iARRAYCHAR)
{ {
@ -2961,19 +3064,31 @@ static int nesting=0;
argidx++; /* argument done */ argidx++; /* argument done */
break; break;
} /* switch */ } /* switch */
pushreg(sPRI); /* store the function argument on the stack */
markexpr(sPARM,NULL,0); /* mark the end of a sub-expression */ // If we are processing |this| and it's complex, then it was never
nest_stkusage++; // actually evaluated as an argument, so don't push it.
if (!(pending_this && has_complex_this)) {
// If we have a complex |this|, pop it as ALT, push the evaluated
// argument, then push |this| again. This makes sure |this| is
// always the last argument.
if (has_complex_this) {
popreg(sALT);
pushreg(sPRI); /* store the function argument on the stack */
pushreg(sALT);
} else {
pushreg(sPRI); /* store the function argument on the stack */
}
markexpr(sPARM,NULL,0); /* mark the end of a sub-expression */
nest_stkusage++;
}
} /* if */ } /* if */
assert(arglist[argpos]!=ARG_UNHANDLED); assert(arglist[argpos]!=ARG_UNHANDLED);
nargs++; nargs++;
/** // We can already have decided it was time to close because of pending_this.
* We can already have decided it was time to close because of pending_this. // If that's the case, then bail out now.
* If that's the case, then bail out now.
*/
if (pending_this && close) { if (pending_this && close) {
pending_this = FALSE; pending_this = false;
break; break;
} }
@ -2992,20 +3107,13 @@ static int nesting=0;
} /* if */ } /* if */
} /* if */ } /* if */
pending_this = FALSE; pending_this = false;
} while (!close && freading && !matchtoken(tENDEXPR)); /* do */ } while (!close && freading && !matchtoken(tENDEXPR)); /* do */
} /* if */ } /* if */
/* check remaining function arguments (they may have default values) */ /* check remaining function arguments (they may have default values) */
for (argidx=0; arg[argidx].ident!=0 && arg[argidx].ident!=iVARARGS; argidx++) { for (argidx=0; arg[argidx].ident!=0 && arg[argidx].ident!=iVARARGS; argidx++) {
if (arglist[argidx]==ARG_DONE) if (arglist[argidx]==ARG_DONE)
continue; /* already seen and handled this argument */ continue; /* already seen and handled this argument */
/* in this first stage, we also skip the arguments with uSIZEOF and uTAGOF;
* these are handled last
*/
if ((arg[argidx].hasdefault & uSIZEOF)!=0 || (arg[argidx].hasdefault & uTAGOF)!=0) {
assert(arg[argidx].ident==iVARIABLE);
continue;
} /* if */
stgmark((char)(sEXPRSTART+argidx));/* mark beginning of new expression in stage */ stgmark((char)(sEXPRSTART+argidx));/* mark beginning of new expression in stage */
if (arg[argidx].hasdefault) { if (arg[argidx].hasdefault) {
if (arg[argidx].ident==iREFARRAY) { if (arg[argidx].ident==iREFARRAY) {
@ -3053,50 +3161,8 @@ static int nesting=0;
nargs++; nargs++;
arglist[argidx]=ARG_DONE; arglist[argidx]=ARG_DONE;
} /* for */ } /* for */
/* now a second loop to catch the arguments with default values that are
* the "sizeof" or "tagof" of other arguments
*/
for (argidx=0; arg[argidx].ident!=0 && arg[argidx].ident!=iVARARGS; argidx++) {
constvalue *asz;
cell array_sz;
if (arglist[argidx]==ARG_DONE)
continue; /* already seen and handled this argument */
stgmark((char)(sEXPRSTART+argidx));/* mark beginning of new expression in stage */
assert(arg[argidx].ident==iVARIABLE); /* if "sizeof", must be single cell */
/* if unseen, must be "sizeof" or "tagof" */
assert((arg[argidx].hasdefault & uSIZEOF)!=0 || (arg[argidx].hasdefault & uTAGOF)!=0);
if ((arg[argidx].hasdefault & uSIZEOF)!=0) {
/* find the argument; if it isn't found, the argument's default value
* was a "sizeof" of a non-array (a warning for this was already given
* when declaring the function)
*/
asz=find_constval(&arrayszlst,arg[argidx].defvalue.size.symname,
arg[argidx].defvalue.size.level);
if (asz!=NULL) {
array_sz=asz->value;
if (array_sz==0)
error(163,arg[argidx].name); /* indeterminate array size in "sizeof" expression */
} else {
array_sz=1;
} /* if */
} else {
asz=find_constval(&taglst,arg[argidx].defvalue.size.symname,
arg[argidx].defvalue.size.level);
if (asz != NULL) {
array_sz=asz->value; /* must be set, because it just was exported */
} else {
array_sz=0;
} /* if */
} /* if */
ldconst(array_sz,sPRI);
pushreg(sPRI); /* store the function argument on the stack */
markexpr(sPARM,NULL,0);
nest_stkusage++;
if (arglist[argidx]==ARG_UNHANDLED)
nargs++;
arglist[argidx]=ARG_DONE;
} /* for */
stgmark(sENDREORDER); /* mark end of reversed evaluation */ stgmark(sENDREORDER); /* mark end of reversed evaluation */
pushval((cell)nargs /* *sizeof(cell)*/ ); pushval((cell)nargs /* *sizeof(cell)*/ );
nest_stkusage++; nest_stkusage++;
ffcall(sym,NULL,nargs); ffcall(sym,NULL,nargs);

View File

@ -426,6 +426,16 @@ void rvalue(value *lval)
} /* if */ } /* if */
} }
// Wrapper that automatically markes lvalues as decayed if they are accessors,
// since it is illegal to evaluate them twice.
void rvalue(svalue *sval)
{
int ident = sval->val.ident;
rvalue(&sval->val);
if (ident == iACCESSOR)
sval->lvalue = FALSE;
}
/* Get the address of a symbol into the primary or alternate register (used /* Get the address of a symbol into the primary or alternate register (used
* for arrays, and for passing arguments by reference). * for arrays, and for passing arguments by reference).
*/ */

View File

@ -223,6 +223,8 @@ static const char *errmsg[] = {
/*177*/ "static method '%s' must be invoked via its type (try '%s.%s')\n", /*177*/ "static method '%s' must be invoked via its type (try '%s.%s')\n",
/*178*/ "cannot coerce %s[] to %s[]; storage classes differ\n", /*178*/ "cannot coerce %s[] to %s[]; storage classes differ\n",
/*179*/ "cannot assign %s[] to %s[], storage classes differ\n", /*179*/ "cannot assign %s[] to %s[], storage classes differ\n",
/*180*/ "function return type differs from prototype. expected '%s', but got '%s'\n",
/*181*/ "function argument named '%s' differs from prototype\n",
#else #else
"\315e\306\227\266k\217:\235\277bu\201fo\220\204\223\012", "\315e\306\227\266k\217:\235\277bu\201fo\220\204\223\012",
"\202l\224\250s\205g\346\356e\233\201(\243\315\214\267\202) \253 f\255low ea\305 \042c\353e\042\012", "\202l\224\250s\205g\346\356e\233\201(\243\315\214\267\202) \253 f\255low ea\305 \042c\353e\042\012",
@ -386,24 +388,24 @@ static const char *errmsg[] = {
static const char *fatalmsg[] = { static const char *fatalmsg[] = {
#ifdef SCPACK #ifdef SCPACK
/*180*/ "cannot read from file: \"%s\"\n", /*182*/ "cannot read from file: \"%s\"\n",
/*181*/ "cannot write to file: \"%s\"\n", /*183*/ "cannot write to file: \"%s\"\n",
/*182*/ "table overflow: \"%s\"\n", /*184*/ "table overflow: \"%s\"\n",
/* table can be: loop table /* table can be: loop table
* literal table * literal table
* staging buffer * staging buffer
* option table (response file) * option table (response file)
* peephole optimizer table * peephole optimizer table
*/ */
/*183*/ "insufficient memory\n", /*185*/ "insufficient memory\n",
/*184*/ "invalid assembler instruction \"%s\"\n", /*186*/ "invalid assembler instruction \"%s\"\n",
/*185*/ "numeric overflow, exceeding capacity\n", /*187*/ "numeric overflow, exceeding capacity\n",
/*186*/ "compiled script exceeds the maximum memory size (%ld bytes)\n", /*188*/ "compiled script exceeds the maximum memory size (%ld bytes)\n",
/*187*/ "too many error messages on one line\n", /*189*/ "too many error messages on one line\n",
/*188*/ "codepage mapping file not found\n", /*190*/ "codepage mapping file not found\n",
/*189*/ "invalid path: \"%s\"\n", /*191*/ "invalid path: \"%s\"\n",
/*190*/ "assertion failed: %s\n", /*192*/ "assertion failed: %s\n",
/*191*/ "user error: %s\n", /*193*/ "user error: %s\n",
#else #else
"\256\214a\204from \344le:\354", "\256\214a\204from \344le:\354",
"\256writ\200\266 \344le:\354", "\256writ\200\266 \344le:\354",

View File

@ -0,0 +1,32 @@
native void printnum(int x);
methodmap X
{
public void GetValue() {
printnum(view_as<int>(this));
}
public void SetValue(const char[] key, any value) {
printnum(view_as<int>(this));
}
};
int Sandwich(const char[] value)
{
return 999;
}
//////////////////////////////////
X gTargets[] = {
view_as<X>(10),
view_as<X>(20),
view_as<X>(30),
}
// Should print 30 three times.
public main()
{
printnum(view_as<int>(gTargets[2]));
gTargets[2].GetValue();
gTargets[2].SetValue("TargetBanTime", Sandwich("hello"));
}

View File

@ -2,4 +2,4 @@
(2) : error 141: natives, forwards, and public functions cannot return arrays (2) : error 141: natives, forwards, and public functions cannot return arrays
(3) : error 143: new-style declarations should not have "new" (3) : error 143: new-style declarations should not have "new"
(5) : error 121: cannot specify array dimensions on both type and name (5) : error 121: cannot specify array dimensions on both type and name
(9) : error 025: function heading differs from prototype (11) : error 025: function heading differs from prototype

View File

@ -0,0 +1,9 @@
stock void crab(int[] eggs, int numEggs = sizeof(eggs))
{
}
public main()
{
int eggs[12];
crab(eggs);
}

View File

@ -0,0 +1 @@
(1) : error 163: indeterminate array size in "sizeof" expression (symbol "eggs")

View File

@ -0,0 +1,5 @@
static stock const X = 5;
stock static const Y = 6;
public main()
{}

View File

@ -0,0 +1,7 @@
static stock const X = 5;
stock static const Y = 6;
public main()
{
return X + Y;
}

View File

@ -1 +1 @@
dev rel

View File

@ -7,7 +7,7 @@ ismac=0
iswin=0 iswin=0
archive_ext=tar.gz archive_ext=tar.gz
decomp="tar zxvf" decomp="tar zxf"
if [ `uname` = "Darwin" ]; then if [ `uname` = "Darwin" ]; then
ismac=1 ismac=1

View File

@ -324,6 +324,8 @@
"CalcDominationAndRevenge_Offset" "CalcDomRevPatch" "CalcDominationAndRevenge_Offset" "CalcDomRevPatch"
"CalcDominationAndRevenge_Byte_Win" "0F" "CalcDominationAndRevenge_Byte_Win" "0F"
"CalcDominationAndRevenge_Byte_Lin" "74" "CalcDominationAndRevenge_Byte_Lin" "74"
"GetWeaponPrice_Offset" "GetWeaponPriceFuncGDC"
"GetWeaponPrice_Byte_Win" "E9"
} }
} }

View File

@ -16,12 +16,6 @@
"en" "Rename player" "en" "Rename player"
} }
"Dead Player Rename"
{
"#format" "{1:s}"
"en" "{1} will be renamed on the next round."
}
"Slap player" "Slap player"
{ {
"en" "Slap player" "en" "Slap player"