Compare commits

...
Author SHA1 Message Date
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
Nicholas Hastings 7304747f79 Merge pull request #222 from alliedmodders/auth-ogrekill
Don't recalculate Steam ID every frame when waiting for validated auth.
2014-12-17 20:41:22 -05:00
Nicholas Hastings 17fcd5a37f Merge pull request #223 from alliedmodders/zo
Change /d2Zi+ flag on msvc builds to /Zo.
2014-12-17 19:35:14 -05:00
David Anderson d413a6bd2f Merge pull request #227 from VoiDeD/newdecls-retag-warning
Old style retagging should emit a compiler warning when newdecls are required.
2014-12-17 15:30:08 -08:00
Ryan Stecker 154d84668b Old style retagging should emit a compiler warning when newdecls are required. 2014-12-17 16:37:39 -06:00
David Anderson 58194c5d99 Merge pull request #225 from powerlord/votecallback-fix
Add new-style API compatibility for VoteHandler.
2014-12-16 13:29:09 -08:00
Ross Bemrose 844fad263a Add new-style API compatibility for VoteHandler. 2014-12-16 16:06:20 -05:00
David Anderson e250eb66d1 Merge pull request #224 from VoiDeD/umsg-fix
Fix UserMessageToBfWrite and UserMessageToBfRead
2014-12-15 22:23:47 -08:00
Ryan Stecker 20ed5c338c Fix UserMessageToBfWrite and UserMessageToBfRead not working correctly for non-protobuf usermessages. 2014-12-15 23:07:53 -06:00
David Anderson b4199e5aa3 Merge pull request #221 from alliedmodders/tr-db
Transitional syntax support for DBI.
2014-12-14 18:37:53 -08:00
David Anderson b60ef1669c Update SQL plugins for transitional syntax. 2014-12-14 18:37:32 -08:00
Nicholas Hastings 7e8473b61a Remove /Zo on debug builds and add on release builds. 2014-12-14 16:03:42 -05:00
Nicholas Hastings ed87e048b4 Merge pull request #220 from alliedmodders/gamerules-no-gamedata
Fixup SDKTools to not require byte sig or symbol to get g_pGameRules (r=VoiDeD).
2014-12-14 15:29:14 -05:00
Nicholas Hastings 0d67bcc5ba Add null-check on serverclass in gamerules lookup. 2014-12-14 15:21:54 -05:00
Nicholas Hastings 03abafce3d Change /d2Zi+ flag on msvc builds to /Zo.
http://msdn.microsoft.com/en-us/library/dn785163.aspx
2014-12-14 14:59:16 -05:00
Nicholas Hastings 67fcd9e2c6 Populate auth ids (if available) when initializing CPlayer instance. 2014-12-14 14:56:19 -05:00
David Anderson bab1110bc0 Disallow coercion to/from char[] and any[]. 2014-12-14 02:00:58 -08:00
Nicholas Hastings d51a57cc34 In UpdatePlayerAuth, don't update SteamIDs if AuthID hasn't changed. 2014-12-13 19:40:22 -05:00
Nicholas Hastings de12f64c14 Convert CPlayer::m_AuthID to ke::AString. 2014-12-13 19:39:44 -05:00
David Anderson b1cb06c5ce Update DBI for transitional syntax. 2014-12-13 16:34:58 -08:00
Nicholas Hastings 88cb74213c Add support for getting g_pGameRules without a byte signature / symbol. 2014-12-13 16:35:32 -05:00
David Anderson 5a814c40b3 Merge pull request #207 from alliedmodders/tr-menus
Update menu transitional syntax.
2014-12-13 13:29:52 -08:00
David Anderson 1328984e0b Update plugins for transitional methods. 2014-12-13 13:29:15 -08:00
David Anderson 722a23c818 Redo menu methodmaps. 2014-12-13 12:53:30 -08:00
David Anderson 5959d6ed54 Merge pull request #198 from alliedmodders/tr-events
Port events to transitional syntax.
2014-12-13 12:51:58 -08:00
David Anderson 28eb663f9b Port events to transitional syntax. 2014-12-13 12:51:16 -08:00
Nicholas Hastings 939b10bd8e Refactor SDKTools to not expose gamerules ptr ptr outside of vglobals.cpp. 2014-12-13 15:48:51 -05:00
David Anderson b607bfeca9 Reserve 'builtin' as a keyword. 2014-12-12 21:29:28 -08:00
David Anderson f9d92b0eba Merge pull request #219 from alliedmodders/static-methods
Add support for static methods on methodmaps.
2014-12-12 12:24:28 -08:00
David Anderson 61bf7de101 Revert adminmenu API changes. 2014-12-12 10:10:46 -08:00
David Anderson 5b69efe5d4 Add static method support to methodmaps. 2014-12-12 10:10:46 -08:00
David Anderson afeae84340 Replace symbol proxies with type symbols.
Proxies were rather hacky and complicated, and only existed as a
workaround for oddities with constructors. This patch replaces them with
actual type symbols, a very tiny step to semantically getting rid of tags.

This greatly simplifies how we implement constructors, and paves the way
for using methodmap symbols in field expressions.

Since non-value symbols are new to spcomp1, we place a rather
pigeonholed check into primary() to make sure non-value symbols don't
escape into expressions.
2014-12-12 10:10:43 -08:00
Nicholas Hastings 46d620cb6a Merge pull request #217 from alliedmodders/tf2-holidayvars
Convert TFHoliday values to pubvars.
2014-12-10 08:31:15 -05:00
David Anderson 0295f817b8 Allow int: and void: tags, but warn. 2014-12-10 02:36:30 -08:00
David Anderson 18cc1b414b Fix some compile errors in new-style includes. 2014-12-10 02:12:53 -08:00
David Anderson a9e252314d Use typeset in sdkhooks.inc. 2014-12-10 01:13:08 -08:00
Kyle Sanderson bc4081718b Merge pull request #218 from KyleSanderson/damageeeee
Return the 'e' to OnTakeDamagAlive comment.
2014-12-09 23:20:20 -08:00
David Anderson 1ee3067575 Gracefully error on newly reserved keywords. 2014-12-09 23:18:11 -08:00
David Anderson 94bed806fe Reserve many keywords. 2014-12-09 23:04:13 -08:00
David Anderson 9c98edd104 Rename "union" semantics to "typeset". 2014-12-09 22:36:42 -08:00
Kyle Sanderson 0375aedd47 Return the 'e' to OnTakeDamagAlive comment. 2014-12-09 22:21:46 -08:00
Nicholas Hastings 09060c265f Convert TFHoliday values to pubvars. 2014-12-09 20:21:24 -05:00
Ruben Gonzalez 8a8917ba2e Update TF2 gamedata. 2014-12-08 20:26:14 -05:00
Nicholas Hastings 25859e29ca Merge pull request #211 from Bara20/patch-1
Fix warning in files.inc (r=psychonic).
2014-12-02 08:20:02 -05:00
Bara a91d5bf754 Fix warning in files.inc 2014-12-02 03:35:56 +01:00
David Anderson 68e0645813 Add a view_as operator. 2014-11-30 19:08:25 -08:00
David Anderson cb4fdf1aa9 Update plugins for new syntax. 2014-11-30 18:57:38 -08:00
David Anderson 157549e119 Fix a bug where aliased constructors of nullable methodmaps could not be used. 2014-11-30 18:56:37 -08:00
David Anderson 9f5c8b60ae Add a "new" keyword for constructing nullable methodmaps. 2014-11-30 18:38:26 -08:00
Nicholas Hastings e7e43e38a5 Merge pull request #210 from alliedmodders/more-clientprefs-newauth
Fix clientprefs IsAuthIdConnected (again) (r=asherkin).
2014-11-26 18:55:57 -05:00
Nicholas Hastings 19f2f46655 Update PVKII gamedata. 2014-11-25 10:13:37 -05:00
Asher Baker 50898d7a4f Merge pull request #208 from asherkin/long-lang-codes
Support long key names for languages (bug 6282)
2014-11-24 19:07:18 +00:00
Asher Baker ced026cecc Support long key names for languages. (bug 6282) 2014-11-22 22:18:49 +00:00
David Anderson 62c243f0a5 Fix reading the wrong symbol name when throw argument errors. 2014-11-22 12:23:57 -08:00
Nicholas Hastings b0ceac9d74 Fix clientprefs IsAuthIdConnected (again). 2014-11-22 10:00:40 -08:00
David Anderson 673ff572c5 Disallow retagging enums or using implicit-int as an enum tag. 2014-11-20 19:30:22 -08:00
Nicholas Hastings f573bdf784 Merge pull request #209 from splewis/master
Add missing convars.inc to buildbot package script (r=psychonic).
2014-11-20 06:33:02 -05:00
Sean Lewis b7036de9e9 Add missing convars.inc to buildbot package script. 2014-11-20 03:01:46 -06:00
David Anderson 08388de7dd Merge pull request #199 from alliedmodders/tr-convars
Port ConVars to transitional syntax.
2014-11-19 22:38:56 -08:00
David Anderson be6da2f810 Merge pull request #173 from alliedmodders/tr-smc
Port SMC parsing API to transitional syntax.
2014-11-19 22:38:19 -08:00
Nicholas Hastings f38fd6a550 Merge pull request #205 from alliedmodders/tf2condex3
Add support for TF2 player conditions above >= 96 (r=asherkin).
2014-11-19 17:15:56 -05:00
David Anderson 0511543c76 Merge pull request #206 from alliedmodders/tr-files
Port files.inc to transitional syntax.
2014-11-18 18:56:07 -08:00
Nicholas Hastings db434acd27 Fix typo in CPlayer::GetSteam3Id doing length check on wrong var. 2014-11-16 10:07:08 -05:00
Nicholas Hastings 50400cf029 Remove unused variables. 2014-11-15 19:35:47 -05:00
Nicholas Hastings b85f4d776e Merge pull request #204 from alliedmodders/more-clientprefs-newauth
Fix SetAuthIdCookie's IsAuthIdConnect function's issues with mixed authid types (r=asherkin).
2014-11-15 19:35:13 -05:00
David Anderson 79143d8b6e Port files.inc to transitional syntax. 2014-11-15 13:42:28 -08:00
David Anderson f25953bb6c Merge pull request #187 from alliedmodders/tr-arrays
Update ArrayList for transitional syntax.
2014-11-15 13:04:29 -08:00
David Anderson 461dc3af3d Merge pull request #189 from alliedmodders/tr-tries
Port string maps to transitional syntax.
2014-11-15 12:52:37 -08:00
David Anderson 5e362ec169 Merge branch 'tr-bitbuf' 2014-11-15 12:49:39 -08:00
David Anderson e46d5d211d Merge pull request #196 from alliedmodders/tr-protobuf
Add transitional syntax support for Protobuf natives.
2014-11-15 12:47:46 -08:00
David Anderson 758a7c955c Merge pull request #188 from alliedmodders/tr-stack
Port adt_stack to transitional syntax.
2014-11-15 12:47:21 -08:00
David Anderson 4cb29eb054 Port adt_stack to transitional syntax. 2014-11-15 12:46:17 -08:00
Nicholas Hastings d3a4c972e2 Add static_assert on ConBitVecAndNot hack so it gets updated on next cond count change. 2014-11-15 11:31:18 -05:00
Nicholas Hastings 1cf43b4ec2 Fix off-by-one error with FindNextSetBit in cond checks. 2014-11-15 11:22:43 -05:00
Nicholas Hastings a369d51f23 Merge pull request #183 from powerlord/tf2-halloween-2014
New Halloween 2014 conditions (r=psychonic).
2014-11-15 10:12:48 -05:00
Nicholas Hastings 849df7895b Update TF2 extension for new m_nPlayerCondEx3 player conditions field. 2014-11-15 10:08:07 -05:00
Nicholas Hastings ea86eee74e Fix SetAuthIdCookie's IsAuthIdConnect function's issues with mixed auth id types. 2014-11-15 09:34:49 -05:00
Nicholas Hastings f42a1fe0e4 Merge pull request #201 from DoctorMcKay/tf2-getclientteam
Added TF2_GetClientTeam stock (r=psychonic).
2014-11-15 08:06:27 -05:00
Nicholas Hastings 5a9b5e5e21 Update CS:GO gamedata. 2014-11-12 04:36:18 -08:00
Alexander Corn 1562530cdd Added TF2_GetClientTeam stock
Also fixed some weird spacing and language in doc comments
2014-11-11 02:23:44 -05:00
Asher Baker 93470fbdc6 Merge pull request #190 from asherkin/emscripten-asm-fix
Use GCC builtins for bsr/bsf where available.
2014-11-11 00:15:17 +00:00
Ross Bemrose f55bc6719d Add condition 87 back. 2014-11-10 14:44:26 -05:00
Nicholas Hastings d6533e3219 Merge pull request #192 from alliedmodders/no-random-iface
Use directly-exported random functions on vstdlib rather than IUniformRandomStream (r=dvander).
2014-11-10 13:26:12 -05:00
David Anderson cfa0d9341e Remove handling of class pseudokeyword since there is no C++ API to use it. 2014-11-09 18:12:30 -08:00
David Anderson 2cfe54f34b Port BitBuffers to transitional syntax. 2014-11-09 16:56:50 -08:00
David Anderson 4a66b67d81 Port remaining .sp files. 2014-11-09 16:52:06 -08:00
David Anderson 110440988d Port gag.sp. 2014-11-09 16:37:07 -08:00
David Anderson 4a14b776db Port basecomm.sp. 2014-11-09 16:35:52 -08:00
David Anderson fb5b552f86 Port basecommands.sp. 2014-11-09 16:35:45 -08:00
David Anderson 614fa86311 Port basechat.sp. 2014-11-09 16:31:17 -08:00
David Anderson 9980930dff Port antiflood. 2014-11-09 16:30:41 -08:00
David Anderson e68c228a36 Port basevotes.sp. 2014-11-09 16:29:44 -08:00
David Anderson 8fd0cbecf7 Port funvotes.sp. 2014-11-09 16:28:03 -08:00
David Anderson c425305cde Port mapchooser. 2014-11-09 16:25:52 -08:00
David Anderson 59fbeb4f2c Port nominations. 2014-11-09 16:11:36 -08:00
David Anderson d68eea6dea Port randomcycle. 2014-11-09 16:10:31 -08:00
David Anderson 86d4cdc0c4 Port rockthevote. 2014-11-09 16:10:25 -08:00
David Anderson 16330d1c4c Port reservedslots. 2014-11-09 16:10:13 -08:00
David Anderson 65dfd3cdd1 Add C++ definitions. 2014-11-09 15:39:13 -08:00
David Anderson 9886eea487 Use new-style. 2014-11-09 15:09:46 -08:00
David Anderson affff9eeb7 Move ConVar API into its own include. 2014-11-09 15:02:42 -08:00
David Anderson 6b714dafe3 Add transitional syntax support for Protobuf natives. 2014-11-09 14:19:16 -08:00
David Anderson 801b7ec9e2 Merge pull request #194 from alliedmodders/keyword-this
Define 'this' as a keyword.
2014-11-09 13:09:22 -08:00
David Anderson 4bc7b9243a Define 'this' as a keyword. 2014-11-09 13:01:35 -08:00
David Anderson 8479c2f067 Port SMC parsing API to transitional syntax. 2014-11-09 12:33:07 -08:00
David Anderson 53a1dbdafd Merge pull request #193 from alliedmodders/rm-assert-macro
Remove use of macros in mapchooser.
2014-11-09 12:14:35 -08:00
David Anderson 4802d4bae2 Remove use of macros in mapchooser. 2014-11-09 12:13:52 -08:00
David Anderson 6e045ef43c Merge pull request #191 from alliedmodders/inc-fixups
Fix some syntax errors in include files.
2014-11-09 11:25:59 -08:00
Nicholas Hastings f3fcdeda9d Use directly-exported random functions on vstdlib rather than IUniformRandomStream. 2014-11-09 10:59:10 -05:00
David Anderson c37174cb97 Fix some syntax errors in include files. 2014-11-09 02:03:09 -08:00
David Anderson 22df518ab5 Fix a bug where local dynamic array declarations could be mistakenly parsed as old decls (bug 6280). 2014-11-09 00:15:09 -08:00
David Anderson c228be83d6 Revert "Fix a bug where local dynamic array declarations could be mistakenly parsed as old decls."
This reverts commit 046f167b6e.
2014-11-09 00:15:00 -08:00
David Anderson 046f167b6e Fix a bug where local dynamic array declarations could be mistakenly parsed as old decls (bug 6279). 2014-11-09 00:12:44 -08:00
David Anderson 099f299113 Fix trailing commas in array literals changing the result of sizeof(). 2014-11-08 23:15:23 -08:00
David Anderson 4c377f21f9 Mark symbols as read when using sizeof(). 2014-11-08 20:45:43 -08:00
David Anderson 704e9579f7 Fix comparisons of derived tags (bug 6239). 2014-11-08 20:27:39 -08:00
Asher Baker 686cf9c5ba Use GCC builtins for bsr/bsf where available. 2014-11-09 04:15:49 +00:00
David Anderson 7609d19e32 Fix bug where bad carriage returns mess up line endings. 2014-11-08 18:04:45 -08:00
David Anderson 6ba4bcb955 Port string maps to transitional syntax. 2014-11-08 17:43:28 -08:00
David Anderson 3cc5c198b4 Allow dynamic char arrays. 2014-11-08 17:39:43 -08:00
David Anderson 919a31df57 Update ArrayList for transitional syntax. 2014-11-08 16:31:33 -08:00
David Anderson cd0ac3ae37 Merge pull request #185 from powerlord/tr-event
Update events.inc to Transitional syntax.
2014-11-08 15:56:20 -08:00
David Anderson 17b9ee91e6 Merge pull request #177 from alliedmodders/tr-keyvalues
Port KeyValues to the transitional syntax.
2014-11-08 15:54:58 -08:00
David Anderson f020b5682e Port KeyValues to the transitional syntax. 2014-11-08 15:54:40 -08:00
David Anderson 78687080b1 Merge pull request #178 from alliedmodders/fs-redux
Simplify filesystem natives.
2014-11-08 15:46:10 -08:00
David Anderson f16501d34a Simplify filesystem native implementation. 2014-11-08 15:44:35 -08:00
David Anderson 3c13c87f1c Merge pull request #186 from alliedmodders/fix-arrays
Define post-fix arrays as determinate and pre-fix arrays as indeterminate.
2014-11-08 12:08:56 -08:00
Nicholas Hastings b7c4faf063 Merge pull request #169 from alliedmodders/vfsdir-fixes
Fixes for OpenDirectory with use_valve_fs (r=asherkin).
2014-11-08 13:19:54 -05:00
Nicholas Hastings 0d24804839 Merge pull request #174 from alliedmodders/eliminate-more-gamedata
Eliminate the need for more gamedata on some games (r=asherkin).
2014-11-08 12:52:53 -05:00
David Anderson dbee1bcd08 Add an error check after calling doexpr2(). 2014-11-08 03:07:34 -08:00
David Anderson 512cbc73a0 Fix a loophole with static local variables. 2014-11-08 02:54:29 -08:00
David Anderson 039572060e Add new dynamic array syntax. 2014-11-08 02:48:13 -08:00
David Anderson f08e53f5d2 Make sizeof on indeterminate arrays an error. 2014-11-08 02:07:43 -08:00
David Anderson 6d507ceb27 Add a special case for assigning a string literal to a char array. 2014-11-08 02:04:11 -08:00
David Anderson 70e095f320 Define post-fix arrays as determinate and pre-fix arrays as indeterminate. 2014-11-07 22:39:00 -08:00
David Anderson a8796543af Use symbols for fatal errors and bump them by 20 slots. 2014-11-07 17:41:33 -08:00
David Anderson 2c31b99ce3 Move is_new and has_postdims bits out of declinfo and into typeinfo. 2014-11-07 17:05:27 -08:00
Ross Bemrose 9175c081ee Changed all the char something[] to char[] something as per dvander's comments. 2014-11-07 19:13:46 -05:00
David Anderson b89bd36335 Merge pull request #184 from powerlord/sminc-pragma-newdecls-forward-fix
Add return types to OnPluginEnd, OnPluginPauseChange, and OnGameFrame.
2014-11-07 14:27:21 -08:00
Ross Bemrose 3579977b28 Added missing SetBroadcast to Event methodmap. 2014-11-07 16:47:20 -05:00
Ross Bemrose 21ea3c03b5 Something was throwing fits when those were Event earlier. 2014-11-07 16:30:29 -05:00
Ross Bemrose e7ec41e872 Fix timers.inc's OnMapTimeLeftChanged forward while I'm at it. 2014-11-07 16:01:50 -05:00
Ross Bemrose b76c948c95 Update condition names. Remove condition 87 for now. 2014-11-07 15:44:03 -05:00
Ross Bemrose 159f2c8335 Add return types to OnPluginEnd, OnPluginPauseChange, and OnGameFrame 2014-11-07 15:22:49 -05:00
Ross Bemrose 66bfd126b2 Initial pass for converting events.inc. 2014-11-07 14:35:45 -05:00
Ross Bemrose e7f6a99087 New Halloween 2014 conditions. 2014-11-07 11:16:26 -05:00
Nicholas Hastings 89e7d1c45c Merge pull request #181 from powerlord/tf2-holiday-spyvengy
New Holiday as per Halloween update (r=psychonic).
2014-11-06 06:48:05 -05:00
David Anderson b2e957db83 Merge pull request #182 from powerlord/tr-convar
Transitional syntax support for ConVars.
2014-11-05 23:12:41 -08:00
Ross Bemrose 67f9069382 Updated the named with the ones bailopan suggested. 2014-11-05 16:34:04 -05:00
Ross Bemrose 3fff07b33d Changed ConVarChanged to take a ConVar variable. Backwards compatible with Handle variables (I tested this to make sure). 2014-11-05 15:50:03 -05:00
Ross Bemrose 87a21c7ff8 Add HookChange and UnhookChange to ConVar. 2014-11-05 15:26:03 -05:00
Asher Baker a463ed5cf2 Updated IDA scripts for 6.5. 2014-11-05 16:37:12 +00:00
Ross Bemrose 0f9d2203a4 New Holiday as per Halloween update. 2014-11-05 11:01:04 -05:00
Ross Bemrose 89f6e4736f Merge branch 'master' of https://github.com/alliedmodders/sourcemod into tr-convar 2014-11-05 10:43:28 -05:00
Nicholas Hastings 04578dfee9 Merge pull request #180 from VoiDeD/tf2-gd-nov4-2014
Update MakeBleed signature.
2014-11-04 20:25:50 -05:00
Ryan Stecker 7f36ef65a9 Update MakeBleed signature. 2014-11-04 19:09:10 -06:00
Ross Bemrose 286d484207 Rearrange order of methods in methodmap. Add missing Reset method to methodmap. 2014-10-31 17:21:37 -04:00
Ross Bemrose cdc2b11a09 Add a ConVar class. 2014-10-31 17:06:42 -04:00
Nicholas Hastings c7109ca651 Merge pull request #170 from alliedmodders/tr-datapack
Add transitional syntax support for datapack.inc (r=dvander).
2014-10-31 08:49:12 -04:00
David Anderson 8c8d9b072a Fix more line-endings. 2014-10-30 21:30:12 -07:00
David Anderson 9c6c0f37ed Fix line-endings. 2014-10-30 21:25:23 -07:00
David Anderson 613b06f6c0 Improve error messages when we can't find a typeexpr on a method. 2014-10-30 21:15:48 -07:00
David Anderson 97c3a2bc6e Fix a crash when we fail to parse a typexpr in a global declaration. 2014-10-30 21:09:10 -07:00
David Anderson 91a863c20c Merge pull request #171 from alliedmodders/ts-topmenus
Port TopMenus to transitional syntax.
2014-10-30 19:21:35 -07:00
David Anderson b97335ccb0 Port TopMenus to transitional syntax. 2014-10-30 19:20:33 -07:00
Nicholas Hastings 67d839e568 Merge pull request #176 from VoiDeD/tf2-gd-oct30-2014
Update TF2 gamedata.
2014-10-30 22:10:11 -04:00
Ryan Stecker 5484f35dfb Update CTFPlayerShared::Burn signature. 2014-10-30 21:08:30 -05:00
Ryan Stecker 749bf80bcb Update TF2 vfunc gamedata. 2014-10-30 21:07:21 -05:00
David Anderson 0a545b12a4 Merge pull request #175 from alliedmodders/allow-any
Allow any in new-style natives.
2014-10-30 17:50:45 -07:00
David Anderson eaff5c9364 Allow any in new-style natives. 2014-10-30 17:19:01 -07:00
Nicholas Hastings f0dd129344 Eliminate need for FindEntityByClassname gamedata on sdk2013 and soon css/dods/hl2dm (already on tf2). 2014-10-30 19:25:26 -04:00
Nicholas Hastings 749701014d Eliminate need for sv gamedata on sdk2013 and soon css/dods/hl2dm (already on tf2). 2014-10-30 19:25:13 -04:00
Nicholas Hastings 10cee734dc Eliminate need for s_pTempEnts gamedata on sdk2013 and soon css/dods/hl2dm (already on tf2). 2014-10-30 19:24:53 -04:00
Nicholas Hastings 72c18cc3d9 Missing changes from last commit 2014-10-30 19:24:00 -04:00
Nicholas Hastings 350dd2ebc7 Eliminate need for gEntList gamedata on tf2/sdk2013 and soon dods/css/hl2dm. 2014-10-30 19:23:27 -04:00
Nicholas Hastings 5d78a5ff93 Fix Fistful of Frags Weapon_GetSlot offset. 2014-10-30 17:31:52 -04:00
Nicholas Hastings c15470b583 Update more Insurgency gamedata. 2014-10-30 17:31:23 -04:00
Nicholas Hastings e5eb291b67 Update Insurgency gamedata. 2014-10-30 04:34:36 -07:00
Nicholas Hastings 7ddced67cb Update NMRiH gamedata. 2014-10-30 06:54:09 -04:00
David Anderson a7303568d6 Merge pull request #172 from alliedmodders/fix-setters
Fix a crash when properties have setters but not getters.
2014-10-29 23:09:23 -07:00
David Anderson e7fc06910b Fix a crash when properties have setters but not getters. 2014-10-29 20:51:03 -07:00
Nicholas Hastings 86ddf1fea0 Revert accidental reverting of tf-regex merge. 2014-10-29 20:51:34 -04:00
Nicholas Hastings c9696ca230 Merge branch 'master' of https://github.com/alliedmodders/sourcemod 2014-10-29 20:23:41 -04:00
Nicholas Hastings 4dcc1590bb Update TF2 gamedata. 2014-10-29 20:21:20 -04:00
Nicholas Hastings 585786b465 Fix inconsistent spacing in methodmap decl. 2014-10-28 14:20:34 -04:00
David Anderson 3ec1b3a271 Merge pull request #168 from alliedmodders/tr-regex
Add transitional syntax support for regex.inc.
2014-10-28 11:19:02 -07:00
Nicholas Hastings de045b5ab6 Add transitional syntax support for datapack.inc. 2014-10-28 14:06:11 -04:00
Nicholas Hastings 9021b23bc2 Fix crash on OpenDirectory with use_valve_fs if path not found.
Also fixes minor memory leak on bad path.
2014-10-28 13:57:40 -04:00
Nicholas Hastings dca15ebabf Fix OpenDirectory with use_valve_fs requirement of trailing slash. 2014-10-28 13:53:27 -04:00
David Anderson 5874709407 Add transitional syntax support for regex.inc. 2014-10-27 22:05:37 -07:00
Nicholas Hastings ba0d41a69d Update Fistful of Frags gamedata. 2014-10-24 17:17:07 -04:00
David Anderson 76d26044f6 Fix build. 2014-10-21 21:51:15 -07:00
David Anderson 75335dbef3 Merge pull request #156 from Bara20/patch-2
Fix undefined symbol: clock_gettime.
2014-10-21 12:42:18 -07:00
David Anderson 6bd1285d66 Merge pull request #164 from VoiDeD/sp-commandline
Expose ICommandLine to plugins.
2014-10-21 12:25:51 -07:00
Nicholas Hastings f8ffe23c6e Merge pull request #162 from alliedmodders/steam3-bans
Allow Steam IDs in Steam3 format for sm_addban (r=asherkin).
2014-10-20 21:14:54 -04:00
Nicholas Hastings 77dc5ac7ed Fix build. 2014-10-14 17:47:44 -04:00
Nicholas Hastings 37c29775d4 Fix OnTakeDamage_Alive gamedata lookup in SDKHooks. 2014-10-14 17:36:55 -04:00
Ruben Gonzalez 5ce46e1537 Update windows CS:GO CheckWinLimit signature 2014-10-10 19:24:20 -04:00
Ryan Stecker a580f8c270 Whoops, forgot my hat. 2014-10-09 18:19:40 -05:00
Ryan Stecker d702371b15 Number -> Int, per recommendation. 2014-10-08 21:47:15 -05:00
Nicholas Hastings a3336b1dcf Fix typo causing compile error strcmp -> strncmp 2014-10-08 18:02:05 -07:00
Nicholas Hastings bba2a714a6 Merge pull request #163 from alliedmodders/admdump-crash
Fix crash on Windows when dumping admin cache to file (r=asherkin).
2014-10-08 20:53:11 -04:00
Nicholas Hastings 512fae4c25 Fix crash on Windows when dumping admin cache to file. 2014-10-08 17:31:02 -07:00
Nicholas Hastings d76f62b863 Allow Steam IDs in Steam3 format for sm_addban 2014-10-08 17:29:56 -07:00
Ryan Stecker 2aba6d9d42 Fix linux build. 2014-10-07 17:19:16 -05:00
Ryan Stecker f2a80e33fd Expose some of ICommandLine to plugins. 2014-10-07 16:16:02 -05:00
Nicholas Hastings ac96bb177a Merge pull request #157 from VoiDeD/getevent-defaults
Expose optional default values for the GetEvent* SP functions (r=psychonic)..
2014-10-05 09:14:30 -04:00
Nicholas Hastings 909d523da0 Trigger build for hl2sdk-tf2 changes. 2014-10-01 19:06:36 -04:00
Nicholas Hastings 02aad65d21 Trigger build for hl2sdk-tf2 changes. 2014-10-01 18:53:42 -04:00
Nicholas Hastings 0a9cabdecd Trigger build for hl2sdk-tf2 changes (bug 6259). 2014-09-26 08:31:15 -04:00
Nicholas Hastings 9eb1b3e73e Merge pull request #158 from VoiDeD/te-const-clients
Clients array in TE_Send should be const (r=psychonic).
2014-09-19 18:29:48 -04:00
Nicholas Hastings 0f6063af60 Re-add DBI query throttling (r=dvander). 2014-09-18 22:02:32 -04:00
David Anderson d4fb74ef9a Fix regression where duplicate function names were not an error. 2014-09-16 22:32:46 -07:00
Asher Baker 55a5c745d4 Updated plugin blacklist. 2014-09-16 10:47:21 +01:00
Ryan Stecker a80e049352 Clients array in TE_Send should be const. 2014-09-14 19:08:54 -05:00
Ryan Stecker 981ffdfc82 Fix linux build. 2014-09-13 03:13:33 -05:00
Ryan Stecker 3ffd4cd835 Expose optional default values for the GetEvent* SP functions. 2014-09-12 16:39:21 -05:00
Nicholas Hastings 570570f7a0 Fix regression causing inconsistencies in clientprefs auth id handling (r=VoiDeD). 2014-09-12 13:04:37 -07:00
Nicholas Hastings e72ff963f5 Fix regression in auth causing crash on L4D and newer (r=VoiDeD). 2014-09-12 12:02:45 -07:00
Ruben Gonzalez af273e8e66 Update linux CSGO gamedata 2014-09-12 12:26:27 -04:00
Nicholas Hastings a82dd5e0c3 Update CS:GO linux ClanTagOffset. 2014-09-12 06:50:36 -04:00
Nicholas Hastings e4569cb2b9 Disable RTTI for more game-agnostic extensions. 2014-09-11 17:41:25 -07:00
Nicholas Hastings 47450bb98c Disable RTTI for game-agnostic extensions 2014-09-11 17:28:24 -07:00
Nicholas Hastings c62e7458f9 Disable RTTI for Loader, Logic, and JIT bins 2014-09-11 17:15:59 -07:00
Bara d493bc701d Fix undefined symbol: clock_gettime
[SM] Extension dbi.mysql.ext.so failed to load: /home/csgo/csgo/addons/sourcemod/extensions/dbi.mysql.ext.so: undefined symbol: clock_gettime
2014-09-12 01:52:20 +02:00
Nicholas Hastings f0fe427fee Link libstdc++ on linux for CS:GO. 2014-09-11 19:23:10 -04:00
Nicholas Hastings 7f0b163b31 Merge pull request #155 from alliedmodders/onclientauth-steam2
Make OnClientAuthorized use Steam2 ids where available (r=asherkin).
2014-09-11 13:02:28 -04:00
Nicholas Hastings 49c22a404d Trigger build for hl2sdk-tf2 changes. 2014-09-10 20:59:13 -04:00
Nicholas Hastings e6fd19fb8c Fix crash regression from typo in 892edd9650 2014-09-09 22:05:59 -04:00
Nicholas Hastings 96f8d635c3 Re-enable -Wformat and -Wformat-security in builds 2014-09-09 22:05:07 -04:00
Nicholas Hastings 9a9446400d Nuke spurious NULL checks in spcomp to appease Clang 3.5 2014-09-09 22:04:24 -04:00
Nicholas Hastings 8a1c6bd833 Fix client listener OnClientAuthorized to match new doc 2014-09-09 18:20:52 -07:00
Nicholas Hastings e0c25cfe08 Fix typo, fix build 2014-09-09 18:12:34 -07:00
Nicholas Hastings 6d7115d62f Update the missed steamid nullcheck in clientprefs 2014-09-09 18:04:39 -07:00
Nicholas Hastings 96fbb7ecda Unify Player::GetSteamXId returns, clarify doc, and fix checks 2014-09-09 17:57:54 -07:00
Nicholas Hastings 775a35c5ab Update OnClientAuthorized function doc 2014-09-09 17:56:29 -07:00
Nicholas Hastings 9e6fcc7673 Make OnClientAuthorized use Steam2 ids where available 2014-09-09 17:43:01 -07:00
Nicholas Hastings acdd9e12ea Merge pull request #152 from alliedmodders/error-sp-warnings
Treat SourcePawn warnings as errors when building (r=dvander).
2014-09-09 17:01:44 -04:00
Nicholas Hastings a597277a64 Merge pull request #153 from alliedmodders/auth-fixups
More auth fixups for Steam auth (bug 6243, r=asherkin).
2014-09-09 16:24:57 -04:00
Nicholas Hastings b3dada65fa Fix build. 2014-09-09 13:21:01 -07:00
Nicholas Hastings 8a9a793453 Merge pull request #151 from alliedmodders/menu-natives-logic
Move menu natives from core to logic (r=asherkin).
2014-09-09 15:51:11 -04:00
David Anderson d1aa9a3513 Merge branch 'calli-7' 2014-09-07 15:08:51 -07:00
David Anderson 06f52aa7ce Merge pull request #141 from alliedmodders/calli-5
Rewrite the assembly pipeline.
2014-09-07 15:04:00 -07:00
David Anderson 60eb8ca4bd Merge branch 'master' into calli-5
Conflicts:
	public/amtl/am-utility.h
2014-09-07 15:03:28 -07:00
David Anderson 5b85f41fec Use the correct string table for tag names. 2014-09-07 15:02:09 -07:00
Kyle Sanderson cd4978d60e Merge pull request #154 from VoiDeD/sdkhooks-inc-fix
Fix sdkhooks.inc compile error
2014-09-06 22:10:22 -07:00
Ryan Stecker 07acec6550 Fix sdkhooks.inc compile error 2014-09-06 20:19:55 -05:00
Nicholas Hastings 66ab609000 Make admins_simple.ini bind Steam3 ids as steam auth 2014-09-05 13:16:55 -07:00
Nicholas Hastings 29d428adc2 Add support for auto-converting '_' to ':' with Steam3 Id targetting 2014-09-05 13:08:51 -07:00
Nicholas Hastings 5b1caec738 Treat sp warnings as errors when building 2014-09-05 08:26:23 -07:00
Nicholas Hastings ad7d920ce0 Move menu natives from core to logic 2014-09-05 08:24:40 -07:00
Nicholas Hastings 7fff73ad64 Fix syntax error in sdkhooks.inc. 2014-09-05 08:18:04 -04:00
Nicholas Hastings 215bbb8324 Make SteamID targetting explicit to Steam IDs...
rather than NetworkIDs which could be any form and similar to names.
Also make explicit support for both Steam2 and Steam3 formats
2014-09-04 16:25:12 -07:00
Nicholas Hastings 1bf4eb80bd Cache Steam ID and rendered forms when caching networkID 2014-09-04 16:14:34 -07:00
Nicholas Hastings f1dc24c089 Move Steam2/3 id rendering logic to CPlayer 2014-09-04 15:27:44 -07:00
Nicholas Hastings 892edd9650 Allow BindIdentity and FindAdminByIdentity to take more SteamID formats for steam auth type 2014-09-04 15:26:12 -07:00
Nicholas Hastings ec46e12c50 Replace usages of GetClientAuthString with GetClientAuthId 2014-09-04 12:49:06 -07:00
David Anderson 37638ba6fd Remove support for multiple tags on an argument. 2014-09-04 09:59:43 -07:00
David Anderson 8da4179c64 Merge pull request #150 from alliedmodders/fix-dbi
Fix DBI after AMTL changes.
2014-09-04 09:51:30 -07:00
David Anderson a1dc1101f7 Fix build. 2014-09-03 22:33:05 -07:00
David Anderson a00adaf9fb Sync with AMTL one last time. 2014-09-03 22:05:10 -07:00
David Anderson 8686957dee Final sync of AMTL. 2014-09-03 21:48:48 -07:00
David Anderson e6e90fb8b8 Sync am-string. 2014-09-03 21:45:44 -07:00
David Anderson 6068d341c8 Sync am-hashmap. 2014-09-03 21:44:51 -07:00
David Anderson 105cd27d19 Sync am-utility.h from upstream. 2014-09-03 21:40:03 -07:00
David Anderson e608057304 Sync a change from AMTL. 2014-09-03 21:31:06 -07:00
David Anderson 448c55c0f2 Fix DBI after AMTL changes. 2014-09-03 21:11:17 -07:00
Nicholas Hastings a7cdf17d90 Merge pull request #147 from alliedmodders/new-auth
Expose explicit client auth id formats (r=asherkin).
2014-09-03 18:50:24 -04:00
Nicholas Hastings b2b82f4a86 Add gamedata for SDKHooks Blocked and OnTakeDamage_Alive for many games. 2014-09-03 18:49:14 -04:00
Nicholas Hastings 6da7219f9f Merge pull request #149 from alliedmodders/ontakedamage_alive
Add OnTakeDamage_Alive hook support to SDKHooks (bug 6249, r=asherkin).
2014-09-03 18:35:06 -04:00
Nicholas Hastings 7f3656215b Consistency Fixes (ID->Id, AuthString->AuthId) 2014-09-03 15:13:30 -07:00
Nicholas Hastings be55587d70 Add OnTakeDamage_Alive hook support to SDKHooks (bug=6249). 2014-09-03 17:45:34 -04:00
David Anderson 40b1067ef7 Merge pull request #148 from alliedmodders/warnings-as-errors
Add a flag for warnings-as-errors.
2014-09-03 11:10:56 -07:00
David Anderson 01d1c0c806 Add a flag for warnings-as-errors. 2014-09-03 11:04:25 -07:00
Nicholas Hastings 3fba1d2817 Fix some nits 2014-09-03 10:50:11 -07:00
Nicholas Hastings e6ff9c36ed Merge pull request #119 from VoiDeD/sdkhooks-blocked
Implement SDKHook_Blocked and SDKHook_BlockedPost (r=psychonic).
2014-09-03 10:50:38 -04:00
Nicholas Hastings e11fec9ba1 Rename GetClientAuthString2 to GetClientAuthId 2014-09-02 18:11:36 -07:00
Nicholas Hastings d0c701793c Document possibly-unexpected yet valid auth strings 2014-09-02 17:47:33 -07:00
Nicholas Hastings eafd6626ec Fix true return when validation wanted and steam id pending 2014-09-02 17:44:11 -07:00
Nicholas Hastings e3b87a5ca4 Spin new logic into GetClientAuthString2...
and mark GetClientAuthString as deprecated, using 1.6.x GetClientAuthString behavior
2014-09-02 17:43:10 -07:00
Nicholas Hastings 8c89b72fbc Expose explicit client auth string formats 2014-09-02 14:40:39 -07:00
Ryan Stecker cae1d0dec1 Don't override hook result in BlockedPost. 2014-09-02 13:01:18 -05:00
Ryan Stecker 88c6d3d9a7 Merge remote-tracking branch 'upstream/master' into sdkhooks-blocked 2014-09-02 00:04:54 -05:00
Nicholas Hastings e9e35979a4 Update core AMBuild script for hl2sdk-csgo and hl2sdk-dota protobuf changes. 2014-09-01 11:25:55 -04:00
David Anderson 9d337dd1a9 Merge pull request #146 from alliedmodders/unions
Add a "union" keyword to replace funcenum.
2014-08-31 16:02:59 -04:00
Nicholas Hastings e093c7f72a Merge pull request #120 from alliedmodders/wip-valve-fs2
Add support for Valve FS to natives that use file handles (r=asherkin).
2014-08-30 14:25:53 -04:00
Nicholas Hastings ac121ec4d2 Merge branch 'master' of https://github.com/alliedmodders/sourcemod 2014-08-29 09:54:13 -07:00
Nicholas Hastings b81c44cf49 Update for hl2sdk-dota changes 2014-08-29 09:53:43 -07:00
David Anderson a136049392 Merge pull request #142 from VoiDeD/array-commas
Allow trailing commas in string array declarations. (bug 6239)
2014-08-29 11:21:14 -04:00
David Anderson a1b7c32b29 Add a "union" keyword to replace funcenum. 2014-08-28 14:02:08 -07:00
Ryan Stecker 302dc1cb8a Add test. 2014-08-26 14:58:58 -05:00
David Anderson 6db4f31a10 Remove weird tag flags. 2014-08-24 20:47:07 -07:00
David Anderson 63e5ab18ff Remove support for multiple tags on an argument. 2014-08-24 18:59:51 -07:00
David Anderson d230711e4d Bump SourcePawn version to 1.7 to match SourceMod. 2014-08-23 19:26:51 -07:00
Ryan Stecker 74908098f4 Allow trailing commas in string array declarations. (bug 6239) 2014-08-23 18:15:08 -05:00
David Anderson 078ee76491 Re-add .dbg.natives. 2014-08-23 13:40:50 -07:00
David Anderson 98ec07a419 Add debug info tables to smxbuilder. 2014-08-23 13:26:03 -07:00
David Anderson c4056aea5d Rewrite the assembly pipeline.
This patch uses SmxBuilder from spcomp2 to replace the old assemble()
pipeline. Instead of generating into an old AMX structure, and then
decoding that into SMX, we now directly generate into SMX. This greatly
simplifies code generation and smx building.
2014-08-23 13:25:58 -07:00
David Anderson 7a51d5d549 Remove unused variables. 2014-08-23 13:25:48 -07:00
Nicholas Hastings 89f5d6ecfb Merge pull request #140 from FlaminSarge/tf_enums_2014jun
Update TF2 enums for Love & War (r=psychonic).
2014-08-23 09:32:35 -04:00
David Anderson 9267d0c803 Eliminate Newborn/NoAddRef (bug 5907, r=ds). 2014-08-22 22:50:25 -07:00
David Anderson 0cf8eb2854 Fix Windows build more. 2014-08-22 21:07:49 -07:00
David Anderson d20ba38d6b Fix Windows build. 2014-08-22 20:47:18 -07:00
David Anderson 4d42fa0305 Fix Windows build. 2014-08-22 20:41:24 -07:00
David Anderson 860a5db5ea Merge pull request #139 from alliedmodders/fix-mac-build
Fix Mac build on apple-clang 5.0.
2014-08-22 20:34:38 -07:00
David Anderson 666b6b97ee Fix Mac build on apple-clang 5.0. 2014-08-22 20:30:35 -07:00
David Anderson d562593d31 Fix build. 2014-08-22 18:27:46 -07:00
David Anderson 27c3866b90 Merge branch 'calli-4' 2014-08-22 10:10:48 -07:00
David Anderson 50f3ec8da2 Merge branch 'calli-3' 2014-08-22 09:59:11 -07:00
David Anderson f42651a813 Merge branch 'calli-2' 2014-08-22 09:58:14 -07:00
David Anderson 91f0f1001b Merge pull request #134 from alliedmodders/calli
Simplify how functags work.
2014-08-22 09:54:48 -07:00
Nicholas Hastings 51d32bca77 Clarify return value commit on RemoveFile 2014-08-22 07:21:12 -07:00
Nicholas Hastings 9d6fea857b Fix another syntax error in files.inc 2014-08-22 06:55:45 -07:00
Nicholas Hastings 8d60fecb96 Fix syntax errors in files.inc 2014-08-22 06:30:25 -07:00
Nicholas Hastings 73115f7afa Add support for specifying gameinfo search path when using valveFS in file natives 2014-08-22 06:00:43 -07:00
Nicholas Hastings b95e7ff145 Add missing use_valve_fs param to CreateDirectory native def 2014-08-22 05:59:41 -07:00
Nicholas Hastings e1158889e5 Fix backwards use_valve_fs logic for OpenDirectory 2014-08-22 05:56:23 -07:00
David Anderson a09735a4c7 Remove SC_FUNC and SC_VDEFINE. 2014-08-22 00:53:47 -07:00
David Anderson 6291374b35 Move rtti hacks. 2014-08-22 00:41:32 -07:00
David Anderson dcd246c7ef Port scvars to C++. 2014-08-22 00:39:03 -07:00
David Anderson 29fbbade69 Port sc1 to C++. 2014-08-22 00:38:04 -07:00
David Anderson 48d228e2b1 Port sc2 to C++. 2014-08-22 00:23:02 -07:00
David Anderson 4608050bd2 Port sc3 to C++. 2014-08-22 00:17:00 -07:00
David Anderson 234b4907ed Port sc4 to C++. 2014-08-22 00:12:16 -07:00
David Anderson 9c005d93ed Port sc5 to C++. 2014-08-22 00:09:28 -07:00
David Anderson 3eb1faa470 Port sc6 to C++. 2014-08-22 00:07:40 -07:00
David Anderson 142fbaafdd Port sc7 to C++. 2014-08-22 00:04:48 -07:00
David Anderson afd6009fda Port scexpand and sci18n to C++. 2014-08-22 00:00:31 -07:00
David Anderson 3e8157c6bc Port lstring and sclist to C++. 2014-08-21 23:58:19 -07:00
David Anderson 2ba4fb180e Move scstate.c to C++. 2014-08-21 23:54:10 -07:00
David Anderson 261188fd1b Port a bunch of legwork files to C++. 2014-08-21 23:53:11 -07:00
David Anderson 5a4c50ce55 Port sp_symhash to C++. 2014-08-21 23:36:26 -07:00
FlaminSarge c70543839f Update TF2 enums for Love & War 2014-08-21 23:14:14 -07:00
David Anderson f5efdbf6f5 Remove hardtabs and fix style issues. 2014-08-21 22:42:22 -07:00
David Anderson 25241fa278 Remove file. 2014-08-21 22:19:25 -07:00
David Anderson 225954a27c Modernize the smx headers. 2014-08-21 22:16:07 -07:00
Ruben Gonzalez 3e1495d692 Update NMRIH gamedata. 2014-08-21 09:33:25 -04:00
Nicholas Hastings 5716927cbf Fix compile error on with MSVC. 2014-08-20 21:37:47 -04:00
Nicholas Hastings 09250f89cc Merge pull request #133 from alliedmodders/logger-logic
Move Logger and core natives from core to logic (r=dvander).
2014-08-20 06:43:31 -04:00
David Anderson 233aa5d2df Merge pull request #135 from alliedmodders/typedef-fix
Fix typedefs not fixing string sizes (bug 6220).
2014-08-20 00:30:08 -07:00
David Anderson 1f51393e26 Fix typedefs not fixing string sizes (bug 6220). 2014-08-20 00:26:09 -07:00
David Anderson d91d69f72e Remove newline. 2014-08-20 00:06:33 -07:00
David Anderson 96a73eb86f Deleting CONTRIBUTOR.md (until an up-to-date link is available). 2014-08-20 00:02:01 -07:00
David Anderson e5e2c1fa3d Simplify functag handling. 2014-08-20 00:00:24 -07:00
David Anderson 942a3cd155 Another dedent. 2014-08-19 22:32:02 -07:00
David Anderson 8dc4fcc728 Remove allowproccall code, dedent a block. 2014-08-19 22:29:13 -07:00
David Anderson 385d3708a3 Fix style issues in sctracker.c. 2014-08-19 22:17:10 -07:00
David Anderson 5cf2475e2e Merge pull request #132 from alliedmodders/fix-variadic-args
Fix returning strings from functions with variadic arguments.
2014-08-19 21:36:31 -07:00
Ruben Gonzalez 9f2a0f6748 Update FoF gamedata. 2014-08-18 08:56:39 -04:00
Nicholas Hastings e9ba251c1c Fix link errors. 2014-08-17 11:11:55 -04:00
Nicholas Hastings e4645332aa Convert missed files in logic to use logger from logic. 2014-08-17 11:06:43 -04:00
David Anderson 56cf6e723e Remove unnecessary changes. 2014-08-17 01:21:35 -07:00
David Anderson cef9d9d162 Fix returning strings from functions with variadic arguments. 2014-08-17 01:17:10 -07:00
Nicholas Hastings 1ca837ea2c Merge pull request #131 from VoiDeD/removewearable-optional
Mark TF2_RemoveWearable as optional (r=psychonic).
2014-08-16 13:23:01 -04:00
Ryan Stecker 2037cfc36d Mark TF2_RemoveWearable as optional. 2014-08-16 12:10:31 -05:00
Nicholas Hastings 8ffdfb6a0c Merge pull request #43 from hlstriker/master
Added a new function SetFilePermissions to set permissions of a file (r=psychonic).
2014-08-16 10:02:09 -04:00
Kyle Sanderson 766b6e1770 Merge pull request #127 from alliedmodders/coremapend
Add OnCoreMapEnd to extension's interface.
2014-08-15 20:48:59 -07:00
Ruben Gonzalez 31087dcb57 Merge pull request #130 from VoiDeD/regex-errors
Fix typo related to invalid regex handle errors.
2014-08-14 14:13:42 -04:00
Ryan Stecker d873b20573 Fix typo related to invalid regex handle errors. 2014-08-14 12:24:51 -05:00
Nicholas Hastings 486910a9a1 Add missing files 2014-08-13 14:26:18 -07:00
Nicholas Hastings 17d5af0e2f Move Logger and Core natives to Logic 2014-08-13 14:24:35 -07:00
Asher Baker f570fa414b Reformatted compiler output a little. (r=dvander) 2014-08-12 18:35:43 +00:00
David Anderson 4b8e26463a Merge pull request #122 from peace-maker/datapack_funcpointer
Add WritePackFunction and ReadPackFunction natives
2014-08-12 10:33:27 -07:00
David Anderson b92efc1df1 Merge pull request #128 from VoiDeD/profile-dump
Add a command to dump profiling output.
2014-08-12 10:31:30 -07:00
Nicholas Hastings 25f8570279 Merge pull request #124 from alliedmodders/csgo-cl-language
Fix automatic language detection on CS:GO (bug 6163) (r=asherkin).
2014-08-11 07:37:11 -04:00
Ryan Stecker 0bde28cc17 Add a command to dump profiling output. 2014-08-09 13:32:05 -05:00
Ruben Gonzalez 2ba0b794ea Added note to know what version OnCoreMapEnd was added to. 2014-08-08 10:57:38 -04:00
Ruben Gonzalez 7a88386568 Add OnCoreMapEnd to extension's interface. 2014-08-08 01:01:47 -04:00
Nicholas Hastings 4e5b1a58ce Add ValveFS support to more filesystem functions: OpenDirectory (CloseHandle on directory) ReadDirEntry DirExists CreateDirectory RenameFile 2014-08-06 13:15:24 -07:00
Nicholas Hastings 3edd1ce658 Remove inaccurate note on GetClientLanguage function doc. 2014-08-05 10:40:14 -04:00
Asher Baker 84e5e20362 Merge pull request #125 from WildCard65/wearablesfix
Actually remove extra wearables.
2014-08-05 15:02:14 +01:00
WildCard65 dfba8757f7 Remove un-needed whitespace 2014-08-05 09:15:55 -04:00
WildCard65 15304a0059 Actually remove extra wearables.
Old logic was to try to get extra wearables on a non-existent entity.
2014-08-05 09:14:02 -04:00
Nicholas Hastings ccc818d06e Fix automatic language detection on CS:GO (bug 6163). 2014-08-05 01:41:44 -04:00
David Anderson 000cb2b4dd Merge pull request #123 from alliedmodders/sp2-compat
Introduce a typedef keyword.
2014-08-03 22:27:27 -07:00
David Anderson ad376ff0b8 Introduce a typedef keyword. 2014-08-03 21:51:34 -07:00
David Anderson 09edda93ad Fix style atrocities in sc1.c. 2014-08-03 18:53:58 -07:00
Peace-Maker bfcfbbe107 Add WritePackFunction and ReadPackFunction natives
Adds type safety to CDataPack. Cells can't be read as Float anymore. Now
you're able to store a function pointer in a datapack and be sure the
pointer can't be read as a cell and a cell can't be read as a function
pointer.
2014-08-04 02:05:25 +02:00
Nicholas Hastings f2b19e6c87 Add more accurate return value for DeleteFile when using Valve FS. 2014-08-03 09:10:02 -04:00
Nicholas Hastings 836cde4e21 Merge pull request #121 from VoiDeD/bug-6206
Remove the extra wearables of weapons in TF2_RemoveWeaponSlot (r=psychonic).
2014-08-02 22:02:14 -04:00
Ryan Stecker 14823723bd Remove the extra wearables of weapons in TF2_RemoveWeaponSlot. 2014-08-02 20:57:55 -05:00
Ryan Stecker 601aac440e Implement SDKHook_Blocked and SDKHook_BlockedPost. 2014-08-01 21:35:41 -05:00
Nicholas Hastings 573aea20fb More progress:
Abstracted many fs funcs with helper class.
Removed much duplicated code.
Fixed ReadFile assuming FS errors for ValveFS.
Added ValveFS support for ReadFileString, WriteFile, WriteFileString, DeleteFile.
Added missing param in doc for OpenFile.
2014-08-01 12:38:51 -07:00
Nicholas Hastings 5e7e7ce551 Improved FPrint(f) passthrough 2014-08-01 06:09:09 -07:00
Ruben Gonzalez c116353285 WiP addition of support for ValveFS to many more filesystem natives. 2014-07-31 20:56:07 -04:00
Kyle Sanderson 678e743819 Merge pull request #116 from VoiDeD/funcommands-gravity
Fix PerformGravity's logging format.
2014-07-30 17:59:52 -07:00
Ryan Stecker ff5ec0ea28 Fix PerformGravity's logging format. 2014-07-30 18:22:12 -05:00
Nicholas Hastings 8d5fe316e0 Merge pull request #114 from VoiDeD/tf2-removewearable
Implement TF2_RemoveWearable native (r=psychonic).
2014-07-30 18:43:34 -04:00
Kyle Sanderson c4a1e3c819 Merge pull request #107 from alliedmodders/sdkhackfix
Copy SDKHooks vector instead of taking a reference.
2014-07-30 15:42:49 -07:00
Kyle Sanderson ab72841704 Rename SDKHooks function and variable to be friendlier. 2014-07-30 15:34:51 -07:00
Ryan Stecker 75d5b0c972 Add more TF2_RemoveWearable documentation. 2014-07-30 17:28:51 -05:00
Asher Baker dd7a1764e4 Merge pull request #115 from asherkin/basebans-load
Improved error reporting in basebans custom reasons loading.
2014-07-30 20:52:51 +01:00
Asher Baker eab6ac748f Improved error reporting in basebans custom reasons loading. 2014-07-30 16:30:01 +01:00
Nicholas Hastings b979d707db Update Fistful of Frags gamedata. 2014-07-30 06:35:45 -04:00
Ryan Stecker 4a400d9569 Implement TF2_RemoveWearable native. 2014-07-29 20:31:27 -05:00
Kyle Sanderson ba0406930d Pre-allocate 8 elements to skip trivial reallocations near the beginning of the vectors life. 2014-07-29 02:48:13 -07:00
Kyle Sanderson be79dee6e0 Store only the callback as per VoiDeD, re-eval if HookList changes. 2014-07-29 02:46:49 -07:00
Kyle Sanderson 97610edda4 HackFix: Mimic forwardsys style of pawn calling. 2014-07-28 15:51:34 -07:00
Asher Baker 803a54b773 Merge pull request #113 from VoiDeD/spcomp-include-path
Fix not adding the "include" directory to the spcomp search path.
2014-07-24 22:23:43 +01:00
Ryan Stecker fad5c590b6 Fix not adding the "include" directory to the spcomp search path. 2014-07-24 15:35:44 -05:00
David Anderson 2553d02698 Fix build. 2014-07-24 10:40:51 -04:00
David Anderson da71cfed5a Merge pull request #112 from alliedmodders/dynamic-scp
Generate .scp files as part of the build process.
2014-07-24 09:01:49 -04:00
David Anderson 34e57b77b1 Fix spacing. 2014-07-24 08:54:52 -04:00
David Anderson fa446f74a1 Generate .scp files as part of the build process. 2014-07-24 07:58:03 -04:00
David Anderson 94b64cd6fc Regen sc5.scp. 2014-07-24 06:55:57 -04:00
David Anderson abcd106273 Merge pull request #111 from alliedmodders/bug6199
Improve error messaging for reserved keywords (bug 6199).
2014-07-24 06:53:51 -04:00
David Anderson 97e821dd6f Improve error messaging for reserved keywords (bug 6199). 2014-07-24 06:51:03 -04:00
David Anderson 6e48ded1a6 Merge pull request #109 from alliedmodders/binreloc
Enable binreloc for OS X.
2014-07-24 03:24:52 -07:00
David Anderson 1cc6120741 Merge pull request #110 from alliedmodders/bug6200
Add GetNativeFunction (bug 6200).
2014-07-24 03:24:37 -07:00
David Anderson 2a46f8f881 Add GetNativeFunction (bug 6200). 2014-07-23 23:36:11 -07:00
David Anderson 3fc05056b0 Rename <unknown> to __unknown__ to quell sc7 asserts. 2014-07-23 23:25:12 -07:00
David Anderson f41b3a2b06 Enable binreloc for OS X. 2014-07-23 23:21:03 -07:00
David Anderson 654dcd8ff0 Merge pull request #108 from VoiDeD/bug-6187
Fix message string for error 102.
2014-07-23 17:11:09 -07:00
Ryan Stecker 6a2ec15041 Fix error message 102 to include the spectype that's missing.
Additionally this fixes invalid usage of error 102 in grow_stgbuffer.
2014-07-23 18:52:22 -05:00
David Anderson 59efdafbaf Merge pull request #106 from VoiDeD/spcomp-file-handles
Close file handle on success in pc_opensrc.
2014-07-22 15:43:29 -07:00
Ryan Stecker f3671e55db Close file handle on success in pc_opensrc. 2014-07-22 17:33:26 -05:00
David Anderson b6d8cb9fcf Merge pull request #105 from alliedmodders/fix-varargs
Fix bug in variadic argument parsing. (bug 6195)
2014-07-21 23:12:26 -07:00
David Anderson 2a99eecdb6 Fix bug in variadic argument parsing. 2014-07-21 23:01:35 -07:00
David Anderson 57303f4310 Merge pull request #103 from alliedmodders/fix-incdec
Fix postinc/dec operations on accessors.
2014-07-20 21:24:57 -07:00
David Anderson 88c614c1ba Merge pull request #104 from alliedmodders/fix-structs
Clean up the struct syntax and force it to use newdecls.
2014-07-20 21:19:15 -07:00
David Anderson b1c400190a Merge pull request #101 from alliedmodders/sp2-incs
Block off operators for post-transitional compiler.
2014-07-20 21:19:07 -07:00
David Anderson 686890ec10 Clean up the struct syntax and force it to use newdecls. 2014-07-20 12:16:23 -07:00
David Anderson 8aa28e2c8d More indentation, spacing, and style fixes in sc1.c. 2014-07-20 11:50:57 -07:00
David Anderson 16177e9ecc Fix indentation, spacing, and style in declstruct(). 2014-07-20 11:46:02 -07:00
David Anderson 2b74f1bd61 Remove unused function. 2014-07-20 11:19:48 -07:00
David Anderson 5daa420aed Fix inc/dec operations on accessors. 2014-07-20 11:18:38 -07:00
David Anderson d2c7064e2b Merge pull request #102 from alliedmodders/fix-map-check
Check for null map in matchtag().
2014-07-20 10:36:34 -07:00
David Anderson 4051756576 Check for null map in matchtag(). 2014-07-20 10:15:49 -07:00
David Anderson 51f97d1298 Block off operators for post-transitional compiler. 2014-07-20 01:02:44 -07:00
David Anderson 8436a3ea6c Merge pull request #100 from alliedmodders/delete-crash
Mark usage correctly when invoking special natives.
2014-07-17 22:38:25 -07:00
David Anderson b0e98b16ec Mark usage correctly when invoking special natives. 2014-07-17 22:30:13 -07:00
David Anderson 7948755b3b Merge pull request #99 from alliedmodders/any-newdecls
Allow the any type in non-native newdecls.
2014-07-17 21:49:25 -07:00
David Anderson f79f5df5ab Allow the any type in non-native newdecls. 2014-07-17 21:43:59 -07:00
David Anderson b84b70d0f1 Merge pull request #98 from alliedmodders/fix-nullable
Fix nullable comparisons.
2014-07-17 21:29:07 -07:00
David Anderson beeb848724 Rename. 2014-07-17 21:19:31 -07:00
David Anderson 805b66e539 Fix null not working with comparisons. 2014-07-17 21:18:49 -07:00
David Anderson 8125faeb70 Merge pull request #97 from alliedmodders/bug-6179
Fix const with newdecls and a varargs bug. (bug 6179)
2014-07-17 20:55:23 -07:00
David Anderson 84344c1592 Fix const with newdecls and a varargs bug. (bug 6179) 2014-07-17 20:44:54 -07:00
Nicholas Hastings ac371aa639 Merge pull request #96 from peace-maker/reloadpost_hook
Fix regression. SDKHook_ReloadPost never firing (r=psychonic).
2014-07-16 15:09:44 -04:00
Peace-Maker 1181144e57 Fix regression. SDKHook_ReloadPost never firing
The switch to vtable hooks typo'd the ReloadPost hooks.
2014-07-16 20:40:52 +02:00
David Anderson 3a2f2e621d Remove references to the DisableJIT option. r=psychonic 2014-07-15 09:42:49 -07:00
David Anderson 9c6b82f3a5 Merge pull request #89 from alliedmodders/bug-6176
Fix crash with malformed arguments (bug 6176).
2014-07-13 11:26:57 -07:00
David Anderson 2ea9ec50b5 Merge pull request #91 from alliedmodders/bug-6183
Show errors for methods that are unused. (bug 6183)
2014-07-13 11:24:51 -07:00
David Anderson 58a3cb4a06 Merge pull request #90 from alliedmodders/bug-6178
Allow chaining off method calls. (bug 6178)
2014-07-13 11:24:22 -07:00
Nicholas Hastings a8a64cabee Update some Contagion gamedata. 2014-07-13 10:15:18 -04:00
David Anderson 71fb0d1d18 Address review comment. 2014-07-12 21:21:07 -07:00
David Anderson cd6997cd0b Merge pull request #88 from alliedmodders/bug-6175
Fix and formalize newline and semicolon behavior in methodmaps. (bug 6175)
2014-07-12 20:45:35 -07:00
David Anderson 5dd5b5131b Show errors for methods that are unused. (bug 6183) 2014-07-12 10:28:29 -07:00
David Anderson 1a83ca57fc Allow chaining off method calls. (bug 6178) 2014-07-12 10:05:43 -07:00
David Anderson 21d3a7f93e Fix crash with malformed arguments (bug 6176). 2014-07-12 09:31:51 -07:00
David Anderson 294fdee1e6 Clarify lexpop(). 2014-07-12 00:09:05 -07:00
David Anderson 3d3e5c40c2 Fix and formalize newline and semicolon behavior in methodmaps. (bug 6175) 2014-07-12 00:07:34 -07:00
Ruben Gonzalez 9e1fef9775 Update TerminateRound code and gamedata for update. 2014-07-11 09:18:47 -04:00
David Anderson b0bfec0f8f Merge pull request #87 from alliedmodders/bug-6174
Fix "static stock" not working (bug 6174).
2014-07-10 23:41:59 -07:00
David Anderson 919e859a6d Fix "static stock" not working (bug 6174). 2014-07-10 23:18:07 -07:00
David Anderson c47cfa6fa8 Merge pull request #86 from VoiDeD/transitional-functags
Give functags their correct types for transitional syntax.
2014-07-10 15:27:03 -07:00
Ryan Stecker c38b4a4d1d Give functags their correct types for transitional syntax. 2014-07-10 16:55:22 -05:00
Nicholas Hastings 44b2b02a1e Merge pull request #85 from alliedmodders/more-prop-data-types
Fix regression stopping -1 from being a valid value in SetEntPropEnt (r=VoiDeD).
2014-07-09 22:47:54 -04:00
Nicholas Hastings 31a79231f8 Fix regression stopping -1 from being a valid value in SetEntPropEnt. 2014-07-09 22:23:20 -04:00
Nicholas Hastings d4c676aed2 Merge pull request #83 from alliedmodders/more-prop-data-types
Add support to Get/SetEntPropEnt for FIELD_CLASSPTR and FIELD_EDICT datadesc fields (r=KyleS).
2014-07-09 21:00:49 -04:00
Nicholas Hastings 0b5e587db9 Remove unnecessary null check. 2014-07-09 20:33:38 -04:00
Nicholas Hastings f7a64167fc Fix Dota 2 build. 2014-07-09 19:25:45 -04:00
Nicholas Hastings 3a94bd4fef Add support to Get/SetEntPropEnt for FIELD_CLASSPTR and FIELD_CLASSPTR datadesc fields. 2014-07-09 17:32:32 -04:00
David Anderson d9420cab49 Merge pull request #82 from VoiDeD/fix-version
Update version for manual builds of the 1.7 branch.
2014-07-09 09:53:40 -07:00
Ryan Stecker 226c0a456d Update version for manual builds of the 1.7 branch. 2014-07-09 11:03:02 -05:00
David Anderson 1e0155ad17 Merge pull request #81 from alliedmodders/unkeyword-class
Unkeyword "class", make it contextual.
2014-07-08 09:24:11 -07:00
David Anderson aa299d187b Merge pull request #80 from alliedmodders/lockdown-funcs
Begin locking down function types.
2014-07-08 09:23:55 -07:00
David Anderson 02b7f42811 Unkeyword "class", make it contextual. 2014-07-08 00:44:34 -07:00
David Anderson e76f553957 Begin locking down function types. 2014-07-08 00:26:37 -07:00
David Anderson d2b7126e1d Merge pull request #79 from alliedmodders/fix-null-func
Add a nullfunc_t type for INVALID_FUNCTION.
2014-07-08 00:17:47 -07:00
David Anderson 3fe22687e9 Revert. 2014-07-08 00:06:52 -07:00
David Anderson 2ade122cd2 Merge branch 'master' into fix-null-func
Conflicts:
	sourcepawn/compiler/sc5.scp
2014-07-08 00:06:04 -07:00
David Anderson e57a323dc8 WIP. 2014-07-07 23:31:31 -07:00
Asher Baker af791a30df Merge pull request #72 from VoiDeD/keyvalue-from-string
Implement StringToKeyValues.
2014-07-07 13:49:24 +01:00
David Anderson ff31d8df49 Update nominations.sp and improve compiler error messaging. 2014-07-06 23:59:15 -07:00
David Anderson 8e5992685a Merge branch 'master' into redo-noms 2014-07-06 23:49:18 -07:00
David Anderson af557fdd5e Use setters. 2014-07-06 23:46:45 -07:00
David Anderson 27d5ce45f5 Merge branch 'master' into noms 2014-07-06 23:42:41 -07:00
David Anderson 44316d63cc Add setters and fix some methodmap bugs. 2014-07-06 23:37:43 -07:00
David Anderson 97e0c84e6d Merge pull request #73 from alliedmodders/nullable
Add nullable types and tighten up some new type system semantics.
2014-07-06 11:45:09 -07:00
David Anderson 76edcb16ac Merge pull request #78 from VoiDeD/class-keyword
Fix usage of `class` keyword in some includes.
2014-07-06 10:46:07 -07:00
Nicholas Hastings 63aeeb8672 Merge pull request #70 from VoiDeD/classname-no-world-entity
GetEntityClassname should handle the case where the world entity has not been created yet (r=psychonic).
2014-07-06 11:26:01 -04:00
Ryan Stecker 312f003031 Fix usage of class keyword in some includes. 2014-07-06 07:15:22 -05:00
David Anderson dbedd6712a Remove VoteInProgress from Menu map. 2014-07-05 14:36:14 -07:00
David Anderson f18a83e03e Fix some menu API oddities. 2014-07-05 14:34:32 -07:00
David Anderson 1277bbd50e Mark the expression before flushing the staging buffer. 2014-07-05 14:15:44 -07:00
David Anderson a7de88dd42 Port nominations.sp to the transitional syntax and API. 2014-07-05 14:00:52 -07:00
David Anderson e5b1b630bb Port some includes to transitional API. 2014-07-05 13:58:07 -07:00
David Anderson db9ee5326a Allow CloseHandle() on nulls. 2014-07-05 13:52:44 -07:00
David Anderson 9ae3256bc0 Rename the null tag to null_t. 2014-07-05 13:31:10 -07:00
David Anderson a7342f3fa2 Fix AMBuildScript compatibility issue with older objdirs. 2014-07-05 13:28:55 -07:00
David Anderson 49380620e0 Merge branch 'master' into nullable 2014-07-05 13:24:45 -07:00
David Anderson 9ff38bcf80 Add nulls, and more newdecl and type system features.
New null_t type has a constant "null", which can be assigned to objects.
Methodmaps can now be "nullable", accepting null_t types.
The delete keyword now zaps non-const lvalue inputs.
Fixed some newdecl arguments not accepting references.
Allow functag matching to coerce arguments and return values.
Allow functags to accept new-style types as a return value.
2014-07-05 13:20:06 -07:00
Ryan Stecker fc54903fd0 Add test. 2014-07-05 12:01:17 -05:00
David Anderson 68ab7f0a12 Merge pull request #61 from VoiDeD/ambuild-disable-auto-versioning
Add an ambuild configure option to disable auto versioning.
2014-07-05 09:39:35 -07:00
David Anderson fece28935e Merge pull request #71 from VoiDeD/jit-spew
Only spew JIT compilation and opcodes when built with JIT_SPEW defined.
2014-07-05 09:38:45 -07:00
Ryan Stecker 6864bf0068 Only spew JIT compilation and opcodes when built with JIT_SPEW defined. 2014-07-05 10:57:08 -05:00
Ryan Stecker 3c079bcca0 GetEntityClassname should handle the case where the world entity has not been created yet. 2014-07-05 10:37:16 -05:00
David Anderson 3f220bca0d Merge pull request #69 from alliedmodders/pragma-newdecls
Add #pragma newdecls required|optional.
2014-07-05 01:21:18 -07:00
David Anderson 96bbd4d7e0 Fix potential bugs in restoring newdecl state. 2014-07-05 01:13:45 -07:00
David Anderson da33c79d8b Add #pragma newdecls required|optional. 2014-07-05 01:08:14 -07:00
David Anderson bfc65b086a Fix bug in newdecls in for loop initializers. 2014-07-05 00:48:32 -07:00
David Anderson 680a8e0283 Fix tests. 2014-07-05 00:44:46 -07:00
David Anderson 0e4b913312 Merge pull request #68 from alliedmodders/declloc
Add support for new-style declarations in local variables.
2014-07-05 00:00:20 -07:00
David Anderson f62769108c Fix some local declarations not working. 2014-07-04 23:53:16 -07:00
David Anderson 9a2bdd3792 Add -Wno-sometimes-uninitialized. 2014-07-04 23:10:23 -07:00
David Anderson 386b178ef3 Fix uninitialized variable warning. 2014-07-04 23:00:00 -07:00
David Anderson 79d9a49d28 Fix compiler bug. 2014-07-04 22:46:55 -07:00
David Anderson 376eb9725e Add support for new-style declarations in local variables. 2014-07-04 21:16:39 -07:00
David Anderson 5d753c2697 Merge pull request #67 from alliedmodders/glbdecls
Add support for new-style declarations in globals.
2014-07-04 17:21:26 -07:00
David Anderson 1c41f905f9 Add some tests and errors for bad void usage. 2014-07-04 17:14:40 -07:00
David Anderson dfa9a8f134 Add tests. 2014-07-04 17:01:12 -07:00
David Anderson 49eee8c04e Fix regression in methodmap tagging. 2014-07-04 16:55:33 -07:00
David Anderson 58b9fd57b2 Remove unused "no-postdims" flag. 2014-07-04 16:41:38 -07:00
David Anderson 7e770908fb Add support for decl lists. 2014-07-04 16:37:52 -07:00
David Anderson 3cf9e56a19 Fix various bugs in global newdecl support. 2014-07-04 14:31:56 -07:00
Nicholas Hastings ffa1887c48 Merge pull request #65 from powerlord/master
New functions for SDKTools to get information from game_sound files (r=psychonic).
2014-07-04 17:17:00 -04:00
Ryan Stecker 878a82a6e5 Implement StringToKeyValues. 2014-07-04 12:04:38 -05:00
David Anderson 19815d42c3 Add new-style declaration support for global declarations. 2014-07-04 00:37:39 -07:00
Ross Bemrose 966841afbd Make sure the edict isn't free.
return GetParametersForSoundEx's return value instead of always true.
2014-07-03 14:13:36 -04:00
Ross Bemrose e1d4ed0e34 Fixed overwriting the same copy/pasted line twice instead of once per new native. 2014-07-03 13:19:19 -04:00
Nicholas Hastings cde927112a Merge pull request #66 from alliedmodders/tf2-iserver
Switch TF2 to use IVEngineServer::GetIServer in SDKTools to find IServer ptr (r=voided).
2014-07-03 12:45:18 -04:00
Nicholas Hastings 3254f6f362 Switch TF2 to use IVEngineServer::GetIServer in SDKTools to find IServer ptr. 2014-07-03 12:26:52 -04:00
David Anderson 932a8028ca Merge pull request #60 from VoiDeD/ambuild-remove-tp-flag
Remove the /TP (compile as C++) msvc flag from projects that should be compiling as C.
2014-07-03 09:24:51 -07:00
David Anderson bdb5ef506b Merge pull request #64 from alliedmodders/newdecl
New declaration syntax: arguments.
2014-07-03 09:18:25 -07:00
Ross Bemrose d25ab6349c Commit new version of bug 5942: New functions for SDKTools to get information from game_sound files. 2014-07-03 10:20:53 -04:00
David Anderson 438fade64f Bug fixes. 2014-07-03 00:34:11 -07:00
David Anderson a15153e9b8 Improve error messaging. 2014-07-03 00:21:18 -07:00
David Anderson ed4cca0225 Bug fixes. 2014-07-03 00:14:12 -07:00
David Anderson 86cd906371 Remove typeinfo_t::type. 2014-07-02 23:17:30 -07:00
David Anderson cb46de97e1 Merge pull request #63 from alliedmodders/memsrc
Use in-memory buffers for reading files, and handle newlines better.
2014-07-02 23:07:46 -07:00
David Anderson 153bbba641 WIP. 2014-07-02 23:01:00 -07:00
David Anderson e46c49abe0 Fix bug. 2014-07-02 21:59:04 -07:00
David Anderson 10c8b78a16 Use in-memory buffers for reading files, and handle newlines better. 2014-07-02 21:52:17 -07:00
Ryan Stecker db98c98a1a Remove the /TP (compile as C++) msvc flag from projects that should be compiling as C. 2014-07-02 13:46:39 -05:00
Ryan Stecker d4f4a7eed0 Add an ambuild configure option to disable auto versioning. 2014-07-02 13:29:59 -05:00
Nicholas Hastings e6f6e6df70 Merge pull request #59 from alliedmodders/csgo-weapon-drop
Update CStrike extension CSWeaponDrop to use Vector overload on CS:GO (r=asherkin).
2014-07-02 10:44:04 -04:00
Nicholas Hastings eeba5b93c5 Update CStrike extension CSWeaponDrop to use Vector overload on CS:GO. 2014-07-02 10:08:56 -04:00
David Anderson 84f9b2bf35 Remove accidental files. 2014-07-01 22:06:33 -07:00
Scott Ehlert b1da6958ff Merge pull request #58 from alliedmodders/bug6164
Use -Wno-deprecated-register on clang 3.4+ or Apple clang 5.1+ only (bug 6164, r=psychonic).
2014-07-01 20:30:08 -05:00
Nicholas Hastings 5e596819c5 Update CS:GO CSWeaponDrop gamedata. 2014-07-01 21:06:39 -04:00
Scott Ehlert 415b6ea174 Use -Wno-deprecated-register on clang 3.4+ or Apple clang 5.1+ only (bug 6164). 2014-07-01 16:13:22 -05:00
Nicholas Hastings 0e015027fc Merge pull request #57 from VoiDeD/reservedslots-override-fix
sm_reskick_immunity access check should not check for commands (r=psychonic).
2014-07-01 10:18:04 -04:00
Ryan Stecker 9c1dd0565f sm_reskick_immunity access check should not check for commands. 2014-07-01 09:07:40 -05:00
David Anderson beb557aa56 Add unstaged changes. 2014-06-30 20:11:18 -07:00
David Anderson 6f3b08bbae Initial import of new decl parsing structure. 2014-06-30 20:10:15 -07:00
Scott Ehlert 553b07b722 Merge pull request #56 from peace-maker/gitignorefix
Fix .gitignore typo (r=ds).
2014-06-30 21:23:51 -05:00
Peace-Maker c2c7f090ba Fix .gitignore typo
VS build directories weren't excluded correctly
2014-06-30 15:06:22 +02:00
Peace-Maker 909c6ec594 Refresh sorting of topmenu after (re)LoadTopMenuConfig (bug 6032, r=psychonic). 2014-06-29 21:07:55 -04:00
Nicholas Hastings aedd1eb49c Add HudText gamedata support for Synergy (bug 6161). 2014-06-29 20:23:07 -04:00
Nicholas Hastings 6e34a530b4 Update Dota Linux EntityFactoryDictionary gamedata. 2014-06-28 17:04:43 -04:00
Nicholas Hastings 367c557a77 Update Synergy gamedata and switch NMRiH gamedata on linux to use symbols. 2014-06-28 09:52:03 -04:00
Andrew 3022b665dd Initialized the mask variable.
Moved the FPERM_ defines into the .cpp and removed the header file.
2014-06-27 16:43:51 -04:00
David Anderson 5cf0c08165 Merge pull request #55 from alliedmodders/nts
New type system.
2014-06-26 23:04:54 -07:00
David Anderson b8bd7c517e Add parsing functions. 2014-06-26 21:05:19 -07:00
David Anderson 6a5da160ad Fix build. 2014-06-25 01:06:48 -07:00
David Anderson 99f4cdb3e4 New type system. 2014-06-24 23:37:14 -07:00
David Anderson 2ae04ee1df Merge pull request #54 from alliedmodders/profiling
Add a general profiling abstraction layer.
2014-06-24 20:56:05 -07:00
David Anderson b26552d74c Improve usability of start/stop. 2014-06-24 20:55:53 -07:00
David Anderson f9defa7b37 Remove JIT registration API; this needs more time. 2014-06-24 20:44:30 -07:00
David Anderson fac52a2897 Fill out API more. 2014-06-24 01:18:16 -07:00
David Anderson ec61d4d188 Add a general profiling abstraction layer. 2014-06-24 01:04:13 -07:00
David Anderson 99c0879086 Fix build. 2014-06-23 20:17:40 -07:00
David Anderson b064556081 Merge pull request #50 from alliedmodders/map-api
Add transitional API for maps (aka tries).
2014-06-23 20:06:42 -07:00
David Anderson 2724659be8 Rename to StringMap. 2014-06-23 20:06:13 -07:00
Nicholas Hastings 3983dc10ed Update non-auto version for 1.7.0 for compiled plugins. 2014-06-23 19:46:26 -04:00
Nicholas Hastings c5e2d49b8f Merge pull request #52 from alliedmodders/bug-6137
Update TF2_IsHolidayActive native to virtually call gamerules IsHolidayActive (bug 6137, r=VoiDeD).
2014-06-23 19:39:14 -04:00
Nicholas Hastings bbdf40160c Add missing thisptr to call. 2014-06-23 19:24:27 -04:00
Nicholas Hastings de0f49248d Update TF2_IsHolidayActive native to virtually call gamerules IsHolidayActive. 2014-06-23 16:23:49 -04:00
David Anderson 92ace5497f More MSVC fixes. 2014-06-22 22:47:17 -07:00
David Anderson 8005009420 Workaround buggy C99 support in MSVC. 2014-06-22 22:44:16 -07:00
David Anderson 4ee04b8a7b Add transitional API for maps (aka tries). 2014-06-22 22:32:08 -07:00
David Anderson d7b66c2515 Merge pull request #49 from alliedmodders/methodmaps-inline-3
Add property accessors to methodmaps.
2014-06-22 22:16:57 -07:00
David Anderson 123c7f6b06 Fix METHOD_NAMEMAX. 2014-06-22 22:16:41 -07:00
David Anderson a17ad1c5a5 Add property accessors to methodmaps. 2014-06-22 22:02:02 -07:00
Nicholas Hastings dbcfbdb21a Merge pull request #42 from alliedmodders/bug-6137
Switch TF2 extension to hook CTFGameRules::IsHolidayActive for holiday forward (bug 6137, r=VoiDeD).
2014-06-22 21:23:27 -04:00
David Anderson 50b0019302 Merge pull request #48 from alliedmodders/methodmaps-inline-3
Add support for fully inline functions in methodmaps.
2014-06-22 14:20:15 -07:00
David Anderson b6eb3b041b Fix bug in requiring braces for new methods. 2014-06-22 13:28:35 -07:00
David Anderson 354022888f Add support for fully inline functions in methodmaps. 2014-06-22 13:21:46 -07:00
David Anderson 3ba47a71fd Merge pull request #47 from alliedmodders/fix-dbi-leak
Fix a Handle leak when reporting transaction errors.
2014-06-22 12:26:45 -07:00
David Anderson b64551e984 Fix a Handle leak when reporting transaction errors. 2014-06-22 11:05:20 -07:00
David Anderson 90e8607586 Merge pull request #46 from alliedmodders/methodmaps-inline-2
Add support for inline native methods on methodmaps.
2014-06-22 01:58:22 -07:00
David Anderson ffd97a1fd0 Fix typeexpr unknown token not reporting an error message. 2014-06-22 01:46:43 -07:00
David Anderson 5b12f456ac Add support for inline native methods. 2014-06-22 01:44:23 -07:00
David Anderson c4f2b8348e Merge pull request #45 from alliedmodders/methodmaps-inline
Introduce 4-token lookahead buffer.
2014-06-21 23:56:58 -07:00
David Anderson 8f6c13b220 Merge pull request #44 from alliedmodders/methodmaps-dtor-fix
Allow base destructors to run and fix some error reporting.
2014-06-21 23:37:12 -07:00
David Anderson 10a511a35e Introduce 4-token lookahead buffer. 2014-06-21 23:35:55 -07:00
David Anderson 861953d736 Allow base destructors to run and fix some error reporting. 2014-06-21 12:27:04 -07:00
David Anderson 63ad5eff18 Introduce basic methodmaps (PR #38).
commit 1e5213d43fdd170bb0c30af914a4e40610014b2b
Author: David Anderson <[email protected]>
Date:   Sat Jun 21 04:09:27 2014 -0700

    Quell MSVC C99 bugs.

commit f2e166c5925fda49b5abeadc0aa0f9156b99cf11
Author: David Anderson <[email protected]>
Date:   Sat Jun 21 03:59:23 2014 -0700

    Fix varying levels of stupid memory errors.

commit b0773d7be45345351ab1c1738681d5215a97f3f3
Author: David Anderson <[email protected]>
Date:   Sat Jun 21 03:36:39 2014 -0700

    Fix memory leak in parsing some control flow structures.

commit 5aca55713cfc2dd09c5900132fc4a6be51e3e309
Author: David Anderson <[email protected]>
Date:   Sat Jun 21 03:35:17 2014 -0700

    Fix memory leak in struct parsing.

commit b46ec5cd281b46177e83c4f0a4acac9cc1065c53
Author: David Anderson <[email protected]>
Date:   Sat Jun 21 03:32:03 2014 -0700

    Fix build.

commit 17bbbb9a46bfc00862adca7d3e15369a48e9ac0f
Merge: c083409 2107599
Author: David Anderson <[email protected]>
Date:   Sat Jun 21 01:26:27 2014 -0700

    Merge branch 'master' into methodmaps

commit c083409b569abff13f24d3b8c47f8ff199036840
Author: David Anderson <[email protected]>
Date:   Fri Jun 20 23:49:36 2014 -0700

    Add VS2k13 support.

commit b7993778494d538cb1c1965116030142a7f7765b
Author: David Anderson <[email protected]>
Date:   Fri Jun 20 01:28:08 2014 -0700

    Implement destructors.

commit 1a340dec260d079ed1b79351ed7b50b58a997cea
Author: David Anderson <[email protected]>
Date:   Fri Jun 20 00:08:04 2014 -0700

    Add some tests.

commit 12db52ee64eb009ead9294495e9034c63ab75b09
Author: David Anderson <[email protected]>
Date:   Fri Jun 20 00:05:49 2014 -0700

    Initial implementation of constructors.

commit 074669a658caa2822aa864164b615a244c00a0bc
Author: David Anderson <[email protected]>
Date:   Thu Jun 19 22:42:35 2014 -0700

    Add simple test harness.

commit 27c1e3cf14e1e6c5cf35c80c792cce2744b804d7
Author: David Anderson <[email protected]>
Date:   Thu Jun 19 22:15:42 2014 -0700

    Big refactoring for new syntax.

commit f3c37fdc919e76ee0815e2394cbe8d221f9fc0ca
Author: David Anderson <[email protected]>
Date:   Thu Jun 19 22:12:54 2014 -0700

    Refactor tests for the new syntax.

commit 6211f392f8e722b907474cf380cfac4347e46b8e
Author: David Anderson <[email protected]>
Date:   Wed Jun 18 22:25:48 2014 -0700

    Make lexer tokens an enum.

commit 5210b013756b0b00de3a61c6490685c768ff8cbd
Author: David Anderson <[email protected]>
Date:   Tue Jun 17 06:48:15 2014 -0700

    Add comment.

commit 06688ff4aced14077dd21a9cc1db4c26c7420ff3
Author: David Anderson <[email protected]>
Date:   Tue Jun 17 06:46:10 2014 -0700

    Allow |this| to be a base type of the methodmap.

commit 05cf3682020e0e6d9f47b1a0a6727b9edbfe7622
Author: David Anderson <[email protected]>
Date:   Mon Jun 16 22:11:58 2014 -0700

    Unify duplicate typesymbol checking.

commit 09161bf2691c8c1ed25b9b70fda01c336f21aa0b
Author: David Anderson <[email protected]>
Date:   Mon Jun 16 19:53:36 2014 -0700

    Close loophole that allowed methodmaps for enums.

commit 5bb4aeba89fec47a4de7a7532d27830999d1fcb4
Author: David Anderson <[email protected]>
Date:   Mon Jun 16 01:50:42 2014 -0700

    Add tests and dbi/handle changes.

commit b9203e2491daec2a8073874d6375949483778d14
Author: David Anderson <[email protected]>
Date:   Mon Jun 16 01:38:29 2014 -0700

    Ensure methodmap tags are fixed.

commit 878b80fd87a2ea500d3a28ce2d53f616d1efe5e8
Author: David Anderson <[email protected]>
Date:   Mon Jun 16 01:36:04 2014 -0700

    Implement inheritance.

commit 6ba9e004fbae18ad68056368ddd0affdc78659f1
Author: David Anderson <[email protected]>
Date:   Mon Jun 16 01:31:00 2014 -0700

    Refactor matchtag() to not be insane.

commit 4ede6343b0682c6df98fa869153828e92f891bcc
Author: David Anderson <[email protected]>
Date:   Mon Jun 16 01:20:50 2014 -0700

    Fix indenting.

commit e3ddef8916e3dd5f4ff0fe571d6e1c3acd163352
Author: David Anderson <[email protected]>
Date:   Mon Jun 16 01:20:27 2014 -0700

    Initial prototype.
2014-06-21 04:10:15 -07:00
Andrew f3299b2c8c Added a new function SetFilePermissions to set permissions of a file. I'm not sure about the Windows implementation. See this feature request: https://bugs.alliedmods.net/show_bug.cgi?id=6152 2014-06-21 00:45:07 -04:00
Nicholas Hastings fe485836f1 Remove redundant code. 2014-06-19 23:48:15 -04:00
Nicholas Hastings 1daf629a42 Remove dead variable. 2014-06-19 23:34:35 -04:00
Nicholas Hastings 151c6d246e Switch TF2 extension to hook CTFGameRules::IsHolidayActive for holiday forward (bug 6137). 2014-06-19 23:22:47 -04:00
Nicholas Hastings 210759907d Merge pull request #41 from alliedmodders/c++11
Enable C++11 on posix (r=dvander).
2014-06-19 21:20:13 -04:00
Nicholas Hastings 8b7ce5eed2 Enable C++ support on "like" gcc builds. 2014-06-19 20:59:15 -04:00
Nicholas Hastings 4a75be1c92 Fix KE_OVERRIDE typo in amtl (already fixed upstream). 2014-06-19 20:58:26 -04:00
Nicholas Hastings 3d114e5506 Update linux platform check in KePlatform.h to be consistent with others. 2014-06-19 20:57:54 -04:00
Nicholas Hastings 58158ce607 Merge pull request #40 from alliedmodders/fix-invalid-string-index
Fix FindStringIndex native not returning INVALID_STRING_INDEX when string not found (bug 6144, r=DS).
2014-06-19 14:40:16 -04:00
Nicholas Hastings 0f39825699 Merge pull request #39 from alliedmodders/outputs-getentclassname
Update SDKTools entity output functions to use core's GetEntityClassname instead of own (r=DS).
2014-06-19 14:39:49 -04:00
Nicholas Hastings 291ef6fdc4 Fix FindStringIndex native not returning INVALID_STRING_INDEX when string not found (bug 6144). 2014-06-19 11:40:01 -04:00
Nicholas Hastings 75254bbf25 Update SDKTools entity output functions to use core's GetEntityClassname instead of own. 2014-06-19 11:27:26 -04:00
Nicholas Hastings b0e466edae Revert "Disable FireOutput gamedata on TF2 until proper fix is found."
This reverts commit 9af7eefe07.
2014-06-19 00:34:41 -04:00
Nicholas Hastings e95309a603 Add early-exit in entity output detour if entity has no classname. 2014-06-19 00:33:54 -04:00
Nicholas Hastings 9af7eefe07 Disable FireOutput gamedata on TF2 until proper fix is found. 2014-06-18 23:16:20 -04:00
Nicholas Hastings b5c5aba588 Revert "Update TF2 FireOutput gamedata."
This reverts commit 633f219cf7.
2014-06-18 23:15:38 -04:00
Ryan Stecker 633f219cf7 Update TF2 FireOutput gamedata. 2014-06-18 22:01:59 -04:00
Nicholas Hastings 13f27821ad Bump version for master branch. 2014-06-18 19:24:06 -04:00
520 changed files with 26162 additions and 15706 deletions
+3 -3
View File
@@ -14,9 +14,9 @@
*.user
# Build directories
CrazyDebug.*/
Debug.*/
Release.*/
CrazyDebug*/
Debug*/
Release*/
LIB-Release/
LIB-Debug/
+22 -7
View File
@@ -73,7 +73,9 @@ class SMConfig(object):
self.versionlib = None
def use_auto_versioning(self):
return builder.backend == 'amb2'
if builder.backend != 'amb2':
return False
return not getattr(builder.options, 'disable_auto_versioning', False)
@property
def tag(self):
@@ -163,14 +165,15 @@ class SMConfig(object):
'-fno-strict-aliasing',
'-Wall',
'-Werror',
'-Wno-uninitialized',
'-Wno-unused',
'-Wno-switch',
'-Wno-format',
'-Wno-format-security',
'-Wno-array-bounds',
'-msse',
'-m32',
]
cxx.cxxflags += [
'-std=c++11',
]
have_gcc = cxx.vendor == 'gcc'
have_clang = cxx.vendor == 'clang'
@@ -181,6 +184,15 @@ class SMConfig(object):
cxx.cflags += ['-Wno-narrowing']
if (have_gcc and cxx.version >= '4.7') or (have_clang and cxx.version >= '3'):
cxx.cxxflags += ['-Wno-delete-non-virtual-dtor']
if have_gcc and cxx.version >= '4.8':
cxx.cflags += ['-Wno-unused-result']
if have_clang:
cxx.cxxflags += ['-Wno-implicit-exception-spec-mismatch']
if cxx.version >= 'apple-clang-5.1' or cxx.version >= 'clang-3.4':
cxx.cxxflags += ['-Wno-deprecated-register']
else:
cxx.cxxflags += ['-Wno-deprecated']
cxx.cflags += ['-Wno-sometimes-uninitialized']
cxx.linkflags += ['-m32']
cxx.cxxflags += [
@@ -204,6 +216,8 @@ class SMConfig(object):
'_CRT_NONSTDC_NO_DEPRECATE',
'_ITERATOR_DEBUG_LEVEL=0',
]
if cxx.version < 1800:
cxx.defines += 'strtoull=_strtoui64'
cxx.cflags += [
'/W3',
]
@@ -235,7 +249,7 @@ class SMConfig(object):
if cxx.like('gcc'):
cxx.cflags += ['-O3']
elif cxx.like('msvc'):
cxx.cflags += ['/Ox']
cxx.cflags += ['/Ox', '/Zo']
cxx.linkflags += ['/OPT:ICF', '/OPT:REF']
# Debugging
@@ -243,8 +257,6 @@ class SMConfig(object):
cxx.defines += ['DEBUG', '_DEBUG']
if cxx.like('msvc'):
cxx.cflags += ['/Od', '/RTC1']
if cxx.version >= 1600:
cxx.cflags += ['/d2Zi+']
# This needs to be after our optimization flags which could otherwise disable it.
if cxx.vendor == 'msvc':
@@ -381,6 +393,9 @@ class SMConfig(object):
if builder.target_platform in ['linux', 'mac']:
compiler.defines += ['NO_HOOK_MALLOC', 'NO_MALLOC_OVERRIDE']
if sdk.name == 'csgo' and builder.target_platform == 'linux':
compiler.linkflags += ['-lstdc++']
for path in paths:
compiler.cxxincludes += [os.path.join(sdk.path, *path)]
-6
View File
@@ -1,6 +0,0 @@
Contributing
------------
Please visit [our wiki](https://wiki.alliedmods.net/Contributing_to_SourceMod) for information on how to contribute to Sourcemod.
As a sidenote, [Travis](https://travis-ci.org/alliedmodders/sourcemod) will automatically build your PR to make sure it compiles on Linux.
+678
View File
@@ -1,5 +1,683 @@
SourceMod Changelog
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]
-8
View File
@@ -132,13 +132,5 @@
* passed. You can disable this feature by setting the value to "0".
*/
"SlowScriptTimeout" "8"
/**
* Disable the SourcePawn just-in-time compiler. This is intended for C++ developers using
* debugging tools and finding it difficult to inspect JIT stack frames. The interpreter
* is not as well-tested as the JIT and will make script execution roughly 10X slower, so
* it is not intended for general purpose use.
*/
"DisableJIT" "no"
}
+2
View File
@@ -31,4 +31,6 @@ run.options.add_option('-s', '--sdks', default='all', dest='sdks',
'comma-delimited list of engine names (default: %default)')
run.options.add_option('--breakpad-dump', action='store_true', dest='breakpad_dump',
default=False, help='Dump and upload breakpad symbols')
run.options.add_option('--disable-auto-versioning', action='store_true', dest='disable_auto_versioning',
default=False, help='Disable the auto versioning script')
run.Configure()
+6 -8
View File
@@ -9,7 +9,6 @@ project.sources += [
'sm_stringutil.cpp',
'MenuVoting.cpp',
'smn_events.cpp',
'smn_menus.cpp',
'CDataPack.cpp',
'frame_hooks.cpp',
'smn_nextmap.cpp',
@@ -31,7 +30,6 @@ project.sources += [
'smn_console.cpp',
'UserMessages.cpp',
'MenuManager.cpp',
'smn_core.cpp',
'smn_hudtext.cpp',
'smn_usermsgs.cpp',
'MenuStyle_Base.cpp',
@@ -41,7 +39,9 @@ project.sources += [
'MenuStyle_Radio.cpp',
'sm_autonatives.cpp',
'sm_srvcmds.cpp',
'ConsoleDetours.cpp'
'ConsoleDetours.cpp',
'vprof_tool.cpp',
'smn_commandline.cpp',
]
for sdk_name in SM.sdks:
@@ -52,17 +52,14 @@ for sdk_name in SM.sdks:
compiler = binary.compiler
if sdk.name == 'csgo':
# Protobuf 2.3 headers have some signed/unsigned compares. I believe that it's fixed in later versions, but Valve.
if compiler.cxx.behavior == 'gcc':
compiler.cflags += ['-Wno-sign-compare']
compiler.cxxincludes += [
os.path.join(sdk.path, 'common', 'protobuf-2.3.0', 'src'),
os.path.join(sdk.path, 'common', 'protobuf-2.5.0', 'src'),
os.path.join(sdk.path, 'public', 'engine', 'protobuf'),
os.path.join(sdk.path, 'public', 'game', 'shared', 'csgo', 'protobuf')
]
elif sdk.name == 'dota':
compiler.cxxincludes += [
os.path.join(sdk.path, 'common', 'protobuf-2.4.1', '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', 'game', 'shared', 'protobuf'),
os.path.join(sdk.path, 'public', 'game', 'shared', 'dota', 'protobuf')
@@ -109,6 +106,7 @@ for sdk_name in SM.sdks:
binary.sources += [
os.path.join(sdk.path, 'public', 'engine', 'protobuf', 'networkbasetypes.pb.cc'),
os.path.join(sdk.path, 'public', 'engine', 'protobuf', 'netmessages.pb.cc'),
os.path.join(sdk.path, 'public', 'engine', 'protobuf', 'network_connection.pb.cc'),
os.path.join(sdk.path, 'public', 'game', 'shared', 'protobuf', 'ai_activity.pb.cc'),
os.path.join(sdk.path, 'public', 'game', 'shared', 'protobuf', 'usermessages.pb.cc'),
os.path.join(sdk.path, 'public', 'game', 'shared', 'dota', 'protobuf', 'dota_commonmessages.pb.cc'),
+84 -10
View File
@@ -76,9 +76,12 @@ void CDataPack::ResetSize()
size_t CDataPack::CreateMemory(size_t size, void **addr)
{
CheckSize(sizeof(size_t) + size);
CheckSize(sizeof(char) + sizeof(size_t) + size);
size_t pos = m_curptr - m_pBase;
*(char *)m_curptr = Raw;
m_curptr += sizeof(char);
*(size_t *)m_curptr = size;
m_curptr += sizeof(size_t);
@@ -88,14 +91,17 @@ size_t CDataPack::CreateMemory(size_t size, void **addr)
}
m_curptr += size;
m_size += sizeof(size_t) + size;
m_size += sizeof(char) + sizeof(size_t) + size;
return pos;
}
void CDataPack::PackCell(cell_t cell)
{
CheckSize(sizeof(size_t) + sizeof(cell_t));
CheckSize(sizeof(char) + sizeof(size_t) + sizeof(cell_t));
*(char *)m_curptr = Cell;
m_curptr += sizeof(char);
*(size_t *)m_curptr = sizeof(cell_t);
m_curptr += sizeof(size_t);
@@ -103,12 +109,15 @@ void CDataPack::PackCell(cell_t cell)
*(cell_t *)m_curptr = cell;
m_curptr += sizeof(cell_t);
m_size += sizeof(size_t) + sizeof(cell_t);
m_size += sizeof(char) + sizeof(size_t) + sizeof(cell_t);
}
void CDataPack::PackFloat(float val)
{
CheckSize(sizeof(size_t) + sizeof(float));
CheckSize(sizeof(char) + sizeof(size_t) + sizeof(float));
*(char *)m_curptr = Float;
m_curptr += sizeof(char);
*(size_t *)m_curptr = sizeof(float);
m_curptr += sizeof(size_t);
@@ -116,15 +125,18 @@ void CDataPack::PackFloat(float val)
*(float *)m_curptr = val;
m_curptr += sizeof(float);
m_size += sizeof(size_t) + sizeof(float);
m_size += sizeof(char) + sizeof(size_t) + sizeof(float);
}
void CDataPack::PackString(const char *string)
{
size_t len = strlen(string);
size_t maxsize = sizeof(size_t) + len + 1;
size_t maxsize = sizeof(char) + sizeof(size_t) + len + 1;
CheckSize(maxsize);
*(char *)m_curptr = String;
m_curptr += sizeof(char);
// Pack the string length first for buffer overrun checking.
*(size_t *)m_curptr = len;
m_curptr += sizeof(size_t);
@@ -160,10 +172,16 @@ bool CDataPack::SetPosition(size_t pos) const
cell_t CDataPack::ReadCell() const
{
if (!IsReadable(sizeof(size_t) + sizeof(cell_t)))
if (!IsReadable(sizeof(char) + sizeof(size_t) + sizeof(cell_t)))
{
return 0;
}
if (*reinterpret_cast<char *>(m_curptr) != Cell)
{
return 0;
}
m_curptr += sizeof(char);
if (*reinterpret_cast<size_t *>(m_curptr) != sizeof(cell_t))
{
return 0;
@@ -178,10 +196,16 @@ cell_t CDataPack::ReadCell() const
float CDataPack::ReadFloat() const
{
if (!IsReadable(sizeof(size_t) + sizeof(float)))
if (!IsReadable(sizeof(char) + sizeof(size_t) + sizeof(float)))
{
return 0;
}
if (*reinterpret_cast<char *>(m_curptr) != Float)
{
return 0;
}
m_curptr += sizeof(char);
if (*reinterpret_cast<size_t *>(m_curptr) != sizeof(float))
{
return 0;
@@ -201,10 +225,15 @@ bool CDataPack::IsReadable(size_t bytes) const
const char *CDataPack::ReadString(size_t *len) const
{
if (!IsReadable(sizeof(size_t)))
if (!IsReadable(sizeof(char) + sizeof(size_t)))
{
return NULL;
}
if (*reinterpret_cast<char *>(m_curptr) != String)
{
return NULL;
}
m_curptr += sizeof(char);
size_t real_len = *(size_t *)m_curptr;
@@ -237,6 +266,11 @@ void *CDataPack::ReadMemory(size_t *size) const
{
return NULL;
}
if (*reinterpret_cast<char *>(m_curptr) != Raw)
{
return NULL;
}
m_curptr += sizeof(char);
size_t bytecount = *(size_t *)m_curptr;
m_curptr += sizeof(size_t);
@@ -257,3 +291,43 @@ void *CDataPack::ReadMemory(size_t *size) const
return ptr;
}
void CDataPack::PackFunction(cell_t function)
{
CheckSize(sizeof(char) + sizeof(size_t) + sizeof(cell_t));
*(char *)m_curptr = Function;
m_curptr += sizeof(char);
*(size_t *)m_curptr = sizeof(cell_t);
m_curptr += sizeof(size_t);
*(cell_t *)m_curptr = function;
m_curptr += sizeof(cell_t);
m_size += sizeof(char) + sizeof(size_t) + sizeof(cell_t);
}
cell_t CDataPack::ReadFunction() const
{
if (!IsReadable(sizeof(char) + sizeof(size_t) + sizeof(cell_t)))
{
return 0;
}
if (*reinterpret_cast<char *>(m_curptr) != Function)
{
return 0;
}
m_curptr += sizeof(char);
if (*reinterpret_cast<size_t *>(m_curptr) != sizeof(cell_t))
{
return 0;
}
m_curptr += sizeof(size_t);
cell_t val = *reinterpret_cast<cell_t *>(m_curptr);
m_curptr += sizeof(cell_t);
return val;
}
+10
View File
@@ -51,12 +51,14 @@ public: //IDataReader
const char *ReadString(size_t *len) const;
void *GetMemory() const;
void *ReadMemory(size_t *size) const;
cell_t ReadFunction() const;
public: //IDataPack
void ResetSize();
void PackCell(cell_t cell);
void PackFloat(float val);
void PackString(const char *string);
size_t CreateMemory(size_t size, void **addr);
void PackFunction(cell_t function);
public:
void Initialize();
private:
@@ -66,6 +68,14 @@ private:
mutable char *m_curptr;
size_t m_capacity;
size_t m_size;
enum DataPackType {
Raw,
Cell,
Float,
String,
Function
};
};
#endif //_INCLUDE_SOURCEMOD_CDATAPACK_H_
+1 -1
View File
@@ -383,7 +383,7 @@ bool ConCmdManager::AddAdminCommand(IPluginFunction *pFunction,
{
if (!m_CmdGrps.add(i, group))
return false;
i->value = NoAddRef(new CommandGroup());
i->value = new CommandGroup();
}
Ref<CommandGroup> cmdgroup = i->value;
+12 -2
View File
@@ -648,8 +648,11 @@ QueryCvarCookie_t ConVarManager::QueryClientConVar(edict_t *pPlayer, const char
return InvalidQueryCvarCookie;
}
ConVarQuery query = {cookie, pCallback, (cell_t)hndl, IndexOfEdict(pPlayer)};
m_ConVarQueries.push_back(query);
if (pCallback != NULL)
{
ConVarQuery query = { cookie, pCallback, (cell_t) hndl, IndexOfEdict(pPlayer) };
m_ConVarQueries.push_back(query);
}
#endif
return cookie;
@@ -753,6 +756,13 @@ void ConVarManager::OnQueryCvarValueFinished(QueryCvarCookie_t cookie, CEntityIn
void ConVarManager::OnQueryCvarValueFinished(QueryCvarCookie_t cookie, edict_t *pPlayer, EQueryCvarValueStatus result, const char *cvarName, const char *cvarValue)
#endif // SE_DOTA
{
#if SOURCE_ENGINE == SE_CSGO
if (g_Players.HandleConVarQuery(cookie, pPlayer, result, cvarName, cvarValue))
{
return;
}
#endif
IPluginFunction *pCallback = NULL;
cell_t value = 0;
List<ConVarQuery>::iterator iter;
+3 -3
View File
@@ -195,7 +195,7 @@ class GenericCommandHooker : public IConCommandLinkListener
size_t index;
if (!FindVtable(vtable, index))
{
g_Logger.LogError("Console detour tried to unhook command \"%s\" but it wasn't found", pBase->GetName());
logger->LogError("Console detour tried to unhook command \"%s\" but it wasn't found", pBase->GetName());
return;
}
@@ -219,7 +219,7 @@ public:
if (dispatch.thisptroffs < 0)
{
g_Logger.LogError("Command filter could not determine ConCommand layout");
logger->LogError("Command filter could not determine ConCommand layout");
return false;
}
@@ -228,7 +228,7 @@ public:
if (!vtables.size())
{
g_Logger.LogError("Command filter could not find any cvars!");
logger->LogError("Command filter could not find any cvars!");
return false;
}
+3 -3
View File
@@ -262,7 +262,7 @@ void CoreConfig::Initialize()
{
/* :TODO: This won't actually log or print anything :( - So fix that somehow */
const char *error = textparsers->GetSMCErrorString(err);
g_Logger.LogFatal("[SM] Error encountered parsing core config file: %s", error ? error : "");
logger->LogFatal("[SM] Error encountered parsing core config file: %s", error ? error : "");
}
}
@@ -274,7 +274,7 @@ SMCResult CoreConfig::ReadSMC_KeyValue(const SMCStates *states, const char *key,
if (err == ConfigResult_Reject)
{
/* This is a fatal error */
g_Logger.LogFatal("Config error (key: %s) (value: %s) %s", key, value, error);
logger->LogFatal("Config error (key: %s) (value: %s) %s", key, value, error);
}
return SMCResult_Continue;
@@ -469,7 +469,7 @@ bool SM_ExecuteConfig(IPlugin *pl, AutoConfig *cfg, bool can_create)
}
else
{
g_Logger.LogError("Failed to auto generate config for %s, make sure the directory has write permission.", pl->GetFilename());
logger->LogError("Failed to auto generate config for %s, make sure the directory has write permission.", pl->GetFilename());
return can_create;
}
}
+1 -1
View File
@@ -155,7 +155,7 @@ void EventManager::FireGameEvent(IGameEvent *pEvent)
Just need to add ourselves as a listener to make our hook on IGameEventManager2::FireEvent work */
}
#if SOURCE_ENGINE >= SE_LEFT4DEAD
#if SOURCE_ENGINE >= SE_LEFT4DEAD && SOURCE_ENGINE != SE_DOTA
int EventManager::GetEventDebugID()
{
return EVENT_DEBUG_ID_INIT;
+1 -1
View File
@@ -110,7 +110,7 @@ public: // IPluginsListener
void OnPluginUnloaded(IPlugin *plugin);
public: // IGameEventListener2
void FireGameEvent(IGameEvent *pEvent);
#if SOURCE_ENGINE >= SE_LEFT4DEAD
#if SOURCE_ENGINE >= SE_LEFT4DEAD && SOURCE_ENGINE != SE_DOTA
int GetEventDebugID();
#endif
public:
+40 -18
View File
@@ -153,6 +153,18 @@ void CHalfLife2::OnSourceModAllInitialized_Post()
void CHalfLife2::InitLogicalEntData()
{
#if SOURCE_ENGINE == SE_TF2 \
|| SOURCE_ENGINE == SE_DODS \
|| SOURCE_ENGINE == SE_HL2DM \
|| SOURCE_ENGINE == SE_CSS \
|| SOURCE_ENGINE == SE_SDK2013
if (g_SMAPI->GetServerFactory(false)("VSERVERTOOLS003", nullptr))
{
g_EntList = servertools->GetEntityList();
}
#endif
char *addr = NULL;
/*
@@ -162,21 +174,24 @@ void CHalfLife2::InitLogicalEntData()
* If symbols aren't present (Windows or stripped Linux/Mac),
* attempt find via LevelShutdown + offset
*/
if (g_pGameConf->GetMemSig("gEntList", (void **)&addr))
if (!g_EntList)
{
#if !defined PLATFORM_WINDOWS
if (!addr)
if (g_pGameConf->GetMemSig("gEntList", (void **) &addr))
{
// Key exists so notify if lookup fails, but try other method.
g_Logger.LogError("Failed lookup of gEntList directly - Reverting to lookup via LevelShutdown");
}
else
{
#endif
g_EntList = reinterpret_cast<void *>(addr);
#if !defined PLATFORM_WINDOWS
}
if (!addr)
{
// Key exists so notify if lookup fails, but try other method.
logger->LogError("Failed lookup of gEntList directly - Reverting to lookup via LevelShutdown");
}
else
{
#endif
g_EntList = reinterpret_cast<void *>(addr);
#if !defined PLATFORM_WINDOWS
}
#endif
}
}
if (!g_EntList)
@@ -186,7 +201,7 @@ void CHalfLife2::InitLogicalEntData()
int offset;
if (!g_pGameConf->GetOffset("gEntList", &offset))
{
g_Logger.LogError("Logical Entities not supported by this mod (gEntList) - Reverting to networkable entities only");
logger->LogError("Logical Entities not supported by this mod (gEntList) - Reverting to networkable entities only");
return;
}
@@ -198,7 +213,7 @@ void CHalfLife2::InitLogicalEntData()
// If we have g_EntList from either of the above methods, make sure we can get the offset from it to EntInfo as well
if (g_EntList && !g_pGameConf->GetOffset("EntInfo", &entInfoOffset))
{
g_Logger.LogError("Logical Entities not supported by this mod (EntInfo) - Reverting to networkable entities only");
logger->LogError("Logical Entities not supported by this mod (EntInfo) - Reverting to networkable entities only");
g_EntList = NULL;
return;
}
@@ -211,7 +226,7 @@ void CHalfLife2::InitLogicalEntData()
if (!g_EntList && !g_pEntInfoList)
{
g_Logger.LogError("Failed lookup of gEntList - Reverting to networkable entities only");
logger->LogError("Failed lookup of gEntList - Reverting to networkable entities only");
return;
}
}
@@ -219,13 +234,13 @@ void CHalfLife2::InitLogicalEntData()
void CHalfLife2::InitCommandLine()
{
char error[256];
#if SOURCE_ENGINE != SE_DARKMESSIAH
if (!is_original_engine)
{
ke::AutoPtr<ILibrary> lib(g_LibSys.OpenLibrary(TIER0_NAME, error, sizeof(error)));
if (lib == NULL)
{
g_Logger.LogError("Could not load %s: %s", TIER0_NAME, error);
logger->LogError("Could not load %s: %s", TIER0_NAME, error);
return;
}
@@ -238,11 +253,12 @@ void CHalfLife2::InitCommandLine()
}
}
else
#endif
{
ke::AutoPtr<ILibrary> lib(g_LibSys.OpenLibrary(VSTDLIB_NAME, error, sizeof(error)));
if (lib == NULL)
{
g_Logger.LogError("Could not load %s: %s", VSTDLIB_NAME, error);
logger->LogError("Could not load %s: %s", VSTDLIB_NAME, error);
return;
}
@@ -251,7 +267,7 @@ void CHalfLife2::InitCommandLine()
if (m_pGetCommandLine == NULL)
{
g_Logger.LogError("Could not locate any command line functionality");
logger->LogError("Could not locate any command line functionality");
}
}
@@ -1170,6 +1186,12 @@ const char *CHalfLife2::GetEntityClassname(CBaseEntity *pEntity)
if (offset == -1)
{
CBaseEntity *pGetterEnt = ReferenceToEntity(0);
if (pGetterEnt == NULL)
{
// If we don't have a world entity yet, we'll have to rely on the given entity
pGetterEnt = pEntity;
}
datamap_t *pMap = GetDataMap(pGetterEnt);
sm_datatable_info_t info;
+5 -515
View File
@@ -39,61 +39,12 @@
#include "logic_bridge.h"
#include <sourcemod_version.h>
Logger g_Logger;
bool g_in_game_log_hook = false;
static LoggerCore g_LoggerCore;
SH_DECL_HOOK1_void(IVEngineServer, LogPrint, SH_NOATTRIB, false, const char *);
/**
* :TODO: This should be creating the log folder if it doesn't exist
*/
ConfigResult Logger::OnSourceModConfigChanged(const char *key,
const char *value,
ConfigSource source,
char *error,
size_t maxlength)
{
if (strcasecmp(key, "Logging") == 0)
{
bool state;
if (strcasecmp(value, "on") == 0)
{
state = true;
} else if (strcasecmp(value, "off") == 0) {
state = false;
} else {
UTIL_Format(error, maxlength, "Invalid value: must be \"on\" or \"off\"");
return ConfigResult_Reject;
}
if (source == ConfigSource_Console)
{
state ? EnableLogging() : DisableLogging();
} else {
m_InitialState = state;
}
return ConfigResult_Accept;
} else if (strcasecmp(key, "LogMode") == 0) {
if (strcasecmp(value, "daily") == 0)
{
m_Mode = LoggingMode_Daily;
} else if (strcasecmp(value, "map") == 0) {
m_Mode = LoggingMode_PerMap;
} else if (strcasecmp(value, "game") == 0) {
m_Mode = LoggingMode_Game;
} else {
UTIL_Format(error, maxlength, "Invalid value: must be [daily|map|game]");
return ConfigResult_Reject;
}
return ConfigResult_Accept;
}
return ConfigResult_Ignore;
}
static void HookLogPrint(const char *message)
{
g_in_game_log_hook = true;
@@ -104,477 +55,16 @@ static void HookLogPrint(const char *message)
RETURN_META(MRES_SUPERCEDE);
}
void Logger::OnSourceModStartup(bool late)
void LoggerCore::OnSourceModStartup(bool late)
{
InitLogger(m_Mode);
SH_ADD_HOOK(IVEngineServer, LogPrint, engine, SH_STATIC(HookLogPrint), false);
}
void Logger::OnSourceModAllShutdown()
void LoggerCore::OnSourceModAllShutdown()
{
CloseLogger();
SH_REMOVE_HOOK(IVEngineServer, LogPrint, engine, SH_STATIC(HookLogPrint), false);
}
void Logger::OnSourceModLevelChange(const char *mapName)
{
MapChange(mapName);
}
void Logger::_NewMapFile()
{
if (!m_Active)
{
return;
}
/* Append "Log file closed" to previous log file */
_CloseFile();
char _filename[256];
int i = 0;
time_t t;
GetAdjustedTime(&t);
tm *curtime = localtime(&t);
while (true)
{
g_SourceMod.BuildPath(Path_SM, _filename, sizeof(_filename), "logs/L%02d%02d%03d.log", curtime->tm_mon + 1, curtime->tm_mday, i);
FILE *fp = fopen(_filename, "r");
if (!fp)
{
break;
}
fclose(fp);
i++;
}
m_NrmFileName.assign(_filename);
FILE *fp = fopen(m_NrmFileName.c_str(), "w");
if (!fp)
{
char error[255];
g_LibSys.GetPlatformError(error, sizeof(error));
LogFatal("[SM] Unexpected fatal logging error (file \"%s\")", m_NrmFileName.c_str());
LogFatal("[SM] Platform returned error: \"%s\"", error);
LogFatal("[SM] Logging has been disabled.");
m_Active = false;
return;
} else {
char date[32];
strftime(date, sizeof(date), "%m/%d/%Y - %H:%M:%S", curtime);
fprintf(fp, "L %s: SourceMod log file started (file \"L%02d%02d%03d.log\") (Version \"%s\")\n", date, curtime->tm_mon + 1, curtime->tm_mday, i, SOURCEMOD_VERSION);
fclose(fp);
}
}
void Logger::_CloseFile()
{
if (!m_Active)
{
return;
}
FILE *fp = NULL;
if (!m_NrmFileName.empty())
{
fp = fopen(m_NrmFileName.c_str(), "r+");
if (fp)
{
fseek(fp, 0, SEEK_END);
LogMessage("Log file closed.");
fclose(fp);
}
m_NrmFileName.clear();
}
if (!m_ErrMapStart)
{
return;
}
fp = fopen(m_ErrFileName.c_str(), "r+");
if (fp)
{
fseek(fp, 0, SEEK_END);
LogError("Error log file session closed.");
fclose(fp);
}
m_ErrFileName.clear();
}
void Logger::InitLogger(LoggingMode mode)
{
m_Mode = mode;
m_Active = m_InitialState;
time_t t;
GetAdjustedTime(&t);
tm *curtime = localtime(&t);
m_NrmCurDay = curtime->tm_mday;
m_ErrCurDay = curtime->tm_mday;
char _filename[256];
g_SourceMod.BuildPath(Path_SM, _filename, sizeof(_filename), "logs/errors_%04d%02d%02d.log", curtime->tm_year + 1900, curtime->tm_mon + 1, curtime->tm_mday);
m_ErrFileName.assign(_filename);
switch (m_Mode)
{
case LoggingMode_PerMap:
{
if (!m_Active)
{
m_DelayedStart = true;
}
break;
}
case LoggingMode_Daily:
{
g_SourceMod.BuildPath(Path_SM, _filename, sizeof(_filename), "logs/L%04d%02d%02d.log", curtime->tm_year + 1900, curtime->tm_mon + 1, curtime->tm_mday);
m_NrmFileName.assign(_filename);
m_DailyPrintHdr = true;
break;
}
default:
{
/* do nothing... */
break;
}
}
}
void Logger::CloseLogger()
{
_CloseFile();
}
void Logger::LogToOpenFile(FILE *fp, const char *msg, ...)
{
if (!m_Active)
{
return;
}
va_list ap;
va_start(ap, msg);
LogToOpenFileEx(fp, msg, ap);
va_end(ap);
}
void Logger::LogToFileOnly(FILE *fp, const char *msg, ...)
{
if (!m_Active)
{
return;
}
va_list ap;
va_start(ap, msg);
LogToFileOnlyEx(fp, msg, ap);
va_end(ap);
}
void Logger::LogToOpenFileEx(FILE *fp, const char *msg, va_list ap)
{
if (!m_Active)
{
return;
}
static ConVar *sv_logecho = icvar->FindVar("sv_logecho");
char buffer[3072];
UTIL_FormatArgs(buffer, sizeof(buffer), msg, ap);
char date[32];
time_t t;
GetAdjustedTime(&t);
tm *curtime = localtime(&t);
strftime(date, sizeof(date), "%m/%d/%Y - %H:%M:%S", curtime);
fprintf(fp, "L %s: %s\n", date, buffer);
if (!sv_logecho || sv_logecho->GetBool())
{
g_SMAPI->ConPrintf("L %s: %s\n", date, buffer);
}
}
void Logger::LogToFileOnlyEx(FILE *fp, const char *msg, va_list ap)
{
if (!m_Active)
{
return;
}
char buffer[3072];
UTIL_FormatArgs(buffer, sizeof(buffer), msg, ap);
char date[32];
time_t t;
GetAdjustedTime(&t);
tm *curtime = localtime(&t);
strftime(date, sizeof(date), "%m/%d/%Y - %H:%M:%S", curtime);
fprintf(fp, "L %s: %s\n", date, buffer);
fflush(fp);
}
void Logger::LogMessage(const char *vafmt, ...)
{
va_list ap;
va_start(ap, vafmt);
LogMessageEx(vafmt, ap);
va_end(ap);
}
void Logger::LogMessageEx(const char *vafmt, va_list ap)
{
if (!m_Active)
{
return;
}
if (m_Mode == LoggingMode_Game)
{
_PrintToGameLog(vafmt, ap);
return;
}
if (m_DelayedStart)
{
m_DelayedStart = false;
_NewMapFile();
}
time_t t;
GetAdjustedTime(&t);
tm *curtime = localtime(&t);
FILE *fp = NULL;
if (m_Mode == LoggingMode_PerMap)
{
fp = fopen(m_NrmFileName.c_str(), "a+");
if (!fp)
{
_NewMapFile();
fp = fopen(m_NrmFileName.c_str(), "a+");
if (!fp)
{
goto print_error;
}
}
} else {
if (m_NrmCurDay != curtime->tm_mday)
{
char _filename[256];
g_SourceMod.BuildPath(Path_SM, _filename, sizeof(_filename), "logs/L%04d%02d%02d.log", curtime->tm_year + 1900, curtime->tm_mon + 1, curtime->tm_mday);
m_NrmFileName.assign(_filename);
m_NrmCurDay = curtime->tm_mday;
m_DailyPrintHdr = true;
}
fp = fopen(m_NrmFileName.c_str(), "a+");
}
if (fp)
{
if (m_DailyPrintHdr)
{
char date[32];
m_DailyPrintHdr = false;
strftime(date, sizeof(date), "%m/%d/%Y - %H:%M:%S", curtime);
fprintf(fp, "L %s: SourceMod log file session started (file \"L%04d%02d%02d.log\") (Version \"%s\")\n", date, curtime->tm_year + 1900, curtime->tm_mon + 1, curtime->tm_mday, SOURCEMOD_VERSION);
}
LogToOpenFileEx(fp, vafmt, ap);
fclose(fp);
} else {
goto print_error;
}
return;
print_error:
char error[255];
g_LibSys.GetPlatformError(error, sizeof(error));
LogFatal("[SM] Unexpected fatal logging error (file \"%s\")", m_NrmFileName.c_str());
LogFatal("[SM] Platform returned error: \"%s\"", error);
LogFatal("[SM] Logging has been disabled.");
m_Active = false;
}
void Logger::LogError(const char *vafmt, ...)
{
va_list ap;
va_start(ap, vafmt);
LogErrorEx(vafmt, ap);
va_end(ap);
}
void Logger::LogErrorEx(const char *vafmt, va_list ap)
{
if (!m_Active)
{
return;
}
time_t t;
GetAdjustedTime(&t);
tm *curtime = localtime(&t);
if (curtime->tm_mday != m_ErrCurDay)
{
char _filename[256];
g_SourceMod.BuildPath(Path_SM, _filename, sizeof(_filename), "logs/errors_%04d%02d%02d.log", curtime->tm_year + 1900, curtime->tm_mon + 1, curtime->tm_mday);
m_ErrFileName.assign(_filename);
m_ErrCurDay = curtime->tm_mday;
m_ErrMapStart = false;
}
FILE *fp = fopen(m_ErrFileName.c_str(), "a+");
if (fp)
{
if (!m_ErrMapStart)
{
char date[32];
strftime(date, sizeof(date), "%m/%d/%Y - %H:%M:%S", curtime);
fprintf(fp, "L %s: SourceMod error session started\n", date);
fprintf(fp, "L %s: Info (map \"%s\") (file \"errors_%04d%02d%02d.log\")\n", date, m_CurMapName.c_str(), curtime->tm_year + 1900, curtime->tm_mon + 1, curtime->tm_mday);
m_ErrMapStart = true;
}
LogToOpenFileEx(fp, vafmt, ap);
fclose(fp);
}
else
{
char error[255];
g_LibSys.GetPlatformError(error, sizeof(error));
LogFatal("[SM] Unexpected fatal logging error (file \"%s\")", m_NrmFileName.c_str());
LogFatal("[SM] Platform returned error: \"%s\"", error);
LogFatal("[SM] Logging has been disabled.");
m_Active = false;
return;
}
}
void Logger::MapChange(const char *mapname)
{
m_CurMapName.assign(mapname);
switch (m_Mode)
{
case LoggingMode_Daily:
{
LogMessage("-------- Mapchange to %s --------", mapname);
break;
}
case LoggingMode_PerMap:
{
_NewMapFile();
break;
}
default:
{
/* Do nothing... */
break;
}
}
if (m_ErrMapStart)
{
LogError("Error log file session closed.");
}
m_ErrMapStart = false;
}
void Logger::_PrintToGameLog(const char *fmt, va_list ap)
{
char msg[3072];
size_t len;
len = vsnprintf(msg, sizeof(msg)-2, fmt, ap);
len = (len >= sizeof(msg)) ? (sizeof(msg) - 2) : len;
msg[len++] = '\n';
msg[len] = '\0';
Engine_LogPrintWrapper(msg);
}
const char *Logger::GetLogFileName(LogType type) const
{
switch (type)
{
case LogType_Normal:
{
return m_NrmFileName.c_str();
}
case LogType_Error:
{
return m_ErrFileName.c_str();
}
default:
{
return "";
}
}
}
LoggingMode Logger::GetLoggingMode() const
{
return m_Mode;
}
void Logger::EnableLogging()
{
if (m_Active)
{
return;
}
m_Active = true;
LogMessage("[SM] Logging enabled manually by user.");
}
void Logger::DisableLogging()
{
if (!m_Active)
{
return;
}
LogMessage("[SM] Logging disabled manually by user.");
m_Active = false;
}
void Logger::LogFatal(const char *msg, ...)
{
va_list ap;
va_start(ap, msg);
LogFatalEx(msg, ap);
va_end(ap);
}
void Logger::LogFatalEx(const char *msg, va_list ap)
{
/* :TODO: make this print all pretty-like
* In fact, the pretty log printing function should be abstracted.
* It's already implemented twice which is bad.
*/
char path[PLATFORM_MAX_PATH];
g_SourceMod.BuildPath(Path_Game, path, sizeof(path), "sourcemod_fatal.log");
FILE *fp = fopen(path, "at");
if (fp)
{
m_Active = true;
LogToOpenFileEx(fp, msg, ap);
m_Active = false;
fclose(fp);
}
}
bool g_in_game_log_hook = false;
void Engine_LogPrintWrapper(const char *msg)
{
if (g_in_game_log_hook)
+1 -64
View File
@@ -38,76 +38,13 @@
using namespace SourceHook;
enum LogType
class LoggerCore : public SMGlobalClass
{
LogType_Normal,
LogType_Error
};
enum LoggingMode
{
LoggingMode_Daily,
LoggingMode_PerMap,
LoggingMode_Game
};
class Logger : public SMGlobalClass
{
public:
Logger() : m_Mode(LoggingMode_Daily), m_ErrMapStart(false),
m_Active(false), m_DelayedStart(false), m_DailyPrintHdr(false),
m_InitialState(true)
{
}
public: //SMGlobalClass
ConfigResult OnSourceModConfigChanged(const char *key,
const char *value,
ConfigSource source,
char *error,
size_t maxlength);
void OnSourceModStartup(bool late);
void OnSourceModAllShutdown();
void OnSourceModLevelChange(const char *mapName);
public:
void InitLogger(LoggingMode mode);
void CloseLogger();
void EnableLogging();
void DisableLogging();
void LogMessage(const char *msg, ...);
void LogMessageEx(const char *msg, va_list ap);
void LogError(const char *msg, ...);
void LogErrorEx(const char *msg, va_list ap);
void LogFatal(const char *msg, ...);
void LogFatalEx(const char *msg, va_list ap);
void LogToOpenFile(FILE *fp, const char *msg, ...);
void LogToOpenFileEx(FILE *fp, const char *msg, va_list ap);
/* This version does not print to console, and is thus thread-safe */
void LogToFileOnly(FILE *fp, const char *msg, ...);
void LogToFileOnlyEx(FILE *fp, const char *msg, va_list ap);
void MapChange(const char *mapname);
const char *GetLogFileName(LogType type) const;
LoggingMode GetLoggingMode() const;
private:
void _CloseFile();
void _NewMapFile();
void _PrintToGameLog(const char *fmt, va_list ap);
private:
String m_NrmFileName;
String m_ErrFileName;
String m_CurMapName;
LoggingMode m_Mode;
int m_NrmCurDay;
int m_ErrCurDay;
bool m_ErrMapStart;
bool m_Active;
bool m_DelayedStart;
bool m_DailyPrintHdr;
bool m_InitialState;
};
void Engine_LogPrintWrapper(const char *msg);
extern bool g_in_game_log_hook;
extern Logger g_Logger;
#endif // _INCLUDE_SOURCEMOD_CLOGGER_H_
+3 -11
View File
@@ -261,15 +261,6 @@ CRadioDisplay *CRadioStyle::MakeRadioDisplay(CRadioMenu *menu)
return display;
}
IMenuPanel *CRadioStyle::MakeRadioDisplay(const char *str, int keys)
{
CRadioDisplay *pPanel = MakeRadioDisplay(NULL);
pPanel->DirectSet(str, keys);
return pPanel;
}
void CRadioStyle::FreeRadioDisplay(CRadioDisplay *display)
{
m_FreeDisplays.push(display);
@@ -336,11 +327,12 @@ void CRadioDisplay::Reset()
keys = 0;
}
void CRadioDisplay::DirectSet(const char *str, int keymap)
bool CRadioDisplay::DirectSet(const char *str)
{
m_Title.clear();
m_BufferText.assign(str);
keys = keymap;
return true;
}
unsigned int CRadioDisplay::GetCurrentKey()
+1 -3
View File
@@ -101,7 +101,6 @@ public:
CRadioDisplay *MakeRadioDisplay(CRadioMenu *menu=NULL);
void FreeRadioDisplay(CRadioDisplay *display);
CRadioMenuPlayer *GetRadioMenuPlayer(int client);
IMenuPanel *MakeRadioDisplay(const char *str, int keys);
private:
CRadioMenuPlayer *m_players;
CStack<CRadioDisplay *> m_FreeDisplays;
@@ -129,8 +128,7 @@ public: //IMenuPanel
bool SetCurrentKey(unsigned int key);
int GetAmountRemaining();
unsigned int GetApproxMemUsage();
public:
void DirectSet(const char *str, int keymap);
bool DirectSet(const char *str);
private:
String m_BufferText;
String m_Title;
+2
View File
@@ -75,6 +75,7 @@ public: //IMenuStyle
IBaseMenu *CreateMenu(IMenuHandler *pHandler, IdentityToken_t *pOwner);
unsigned int GetMaxPageItems();
unsigned int GetApproxMemUsage();
bool IsSupported() { return true; }
private:
void HookCreateMessage(edict_t *pEdict, DIALOG_TYPE type, KeyValues *kv, IServerPluginCallbacks *plugin);
private:
@@ -105,6 +106,7 @@ public:
bool SetCurrentKey(unsigned int key);
int GetAmountRemaining();
unsigned int GetApproxMemUsage();
bool DirectSet(const char *str) { return false; }
private:
KeyValues *m_pKv;
unsigned int m_NextPos;
+3 -2
View File
@@ -36,6 +36,7 @@
#include "sm_stringutil.h"
#include "sourcehook.h"
#include "sm_srvcmds.h"
#include "logic_bridge.h"
NextMapManager g_NextMap;
@@ -130,7 +131,7 @@ void NextMapManager::HookChangeLevel(const char *map, const char *unknown, const
{
if (g_forcedChange)
{
g_Logger.LogMessage("[SM] Changed map to \"%s\"", map);
logger->LogMessage("[SM] Changed map to \"%s\"", map);
RETURN_META(MRES_IGNORED);
}
@@ -141,7 +142,7 @@ void NextMapManager::HookChangeLevel(const char *map, const char *unknown, const
RETURN_META(MRES_IGNORED);
}
g_Logger.LogMessage("[SM] Changed map to \"%s\"", newmap);
logger->LogMessage("[SM] Changed map to \"%s\"", newmap);
UTIL_Format(m_tempChangeInfo.m_mapName, sizeof(m_tempChangeInfo.m_mapName), newmap);
UTIL_Format(m_tempChangeInfo.m_changeReason, sizeof(m_tempChangeInfo.m_changeReason), "Normal level change");
+236 -67
View File
@@ -403,12 +403,9 @@ void PlayerManager::RunAuthChecks()
for (unsigned int i=1; i<=m_AuthQueue[0]; i++)
{
pPlayer = &m_Players[m_AuthQueue[i]];
#if SOURCE_ENGINE == SE_DOTA
authstr = engine->GetPlayerNetworkIDString(pPlayer->m_iIndex - 1);
#else
authstr = engine->GetPlayerNetworkIDString(pPlayer->m_pEdict);
#endif
pPlayer->SetAuthString(authstr);
pPlayer->UpdateAuthIds();
authstr = pPlayer->m_AuthID.chars();
if (!pPlayer->IsAuthStringValidated())
{
@@ -425,6 +422,8 @@ void PlayerManager::RunAuthChecks()
unsigned int client = m_AuthQueue[i];
m_AuthQueue[i] = 0;
removed++;
const char *steamId = pPlayer->GetSteam2Id();
/* Send to extensions */
List<IClientListener *>::iterator iter;
@@ -432,7 +431,7 @@ void PlayerManager::RunAuthChecks()
for (iter=m_hooks.begin(); iter!=m_hooks.end(); iter++)
{
pListener = (*iter);
pListener->OnClientAuthorized(client, authstr);
pListener->OnClientAuthorized(client, steamId ? steamId : authstr);
if (!pPlayer->IsConnected())
{
break;
@@ -444,7 +443,8 @@ void PlayerManager::RunAuthChecks()
{
/* :TODO: handle the case of a player disconnecting in the middle */
m_clauth->PushCell(client);
m_clauth->PushString(authstr);
/* For legacy reasons, people are expecting the Steam2 id here if using Steam auth */
m_clauth->PushString(steamId ? steamId : authstr);
m_clauth->Execute(NULL);
}
@@ -502,6 +502,9 @@ bool PlayerManager::OnClientConnect(edict_t *pEntity, const char *pszName, const
/* Get the client's language */
if (m_QueryLang)
{
#if SOURCE_ENGINE == SE_CSGO
pPlayer->m_LangId = translator->GetServerLanguage();
#else
const char *name;
if (!pPlayer->IsFakeClient() && (name=engine->GetClientConVarValue(client, "cl_language")))
{
@@ -510,6 +513,7 @@ bool PlayerManager::OnClientConnect(edict_t *pEntity, const char *pszName, const
} else {
pPlayer->m_LangId = translator->GetServerLanguage();
}
#endif
}
List<IClientListener *>::iterator iter;
@@ -532,7 +536,7 @@ bool PlayerManager::OnClientConnect(edict_t *pEntity, const char *pszName, const
if (res)
{
if (!pPlayer->IsAuthorized())
if (!pPlayer->IsAuthorized() && !pPlayer->IsFakeClient())
{
m_AuthQueue[++m_AuthQueue[0]] = client;
}
@@ -616,14 +620,7 @@ void PlayerManager::OnClientPutInServer(edict_t *pEntity, const char *playername
{
/* Run manual connection routines */
char error[255];
const char *authid;
#if SOURCE_ENGINE == SE_DOTA
authid = engine->GetPlayerNetworkIDString(client - 1);
#else
authid = engine->GetPlayerNetworkIDString(pEntity);
#endif
pPlayer->SetAuthString(authid);
pPlayer->Authorize();
pPlayer->m_bFakeClient = true;
/*
@@ -712,21 +709,33 @@ void PlayerManager::OnClientPutInServer(edict_t *pEntity, const char *playername
m_clconnect_post->PushCell(client);
m_clconnect_post->Execute(&res, NULL);
pPlayer->Authorize();
const char *steamId = pPlayer->GetSteam2Id();
/* Now do authorization */
for (iter=m_hooks.begin(); iter!=m_hooks.end(); iter++)
{
pListener = (*iter);
pListener->OnClientAuthorized(client, authid);
pListener->OnClientAuthorized(client, steamId ? steamId : pPlayer->m_AuthID.chars());
}
/* Finally, tell plugins */
if (m_clauth->GetFunctionCount())
{
m_clauth->PushCell(client);
m_clauth->PushString(authid);
/* For legacy reasons, people are expecting the Steam2 id here if using Steam auth */
m_clauth->PushString(steamId ? steamId : pPlayer->m_AuthID.chars());
m_clauth->Execute(NULL);
}
pPlayer->Authorize_Post();
}
#if SOURCE_ENGINE == SE_CSGO
else
{
// Not a bot
pPlayer->m_LanguageCookie = g_ConVarManager.QueryClientConVar(pEntity, "cl_language", NULL, 0);
}
#endif
if (playerinfo)
{
@@ -1227,7 +1236,7 @@ void PlayerManager::OnClientSettingsChanged(edict_t *pEntity)
if ((networkid_force = engine->GetClientConVarValue(client, "networkid_force")) && networkid_force[0] != '\0')
{
unsigned int accountId = pPlayer->GetSteamAccountID();
g_Logger.LogMessage("\"%s<%d><STEAM_1:%d:%d><>\" has bad networkid (id \"%s\") (ip \"%s\")",
logger->LogMessage("\"%s<%d><STEAM_1:%d:%d><>\" has bad networkid (id \"%s\") (ip \"%s\")",
new_name, pPlayer->GetUserId(), accountId & 1, accountId >> 1, networkid_force, pPlayer->GetIPAddress());
pPlayer->Kick("NetworkID spoofing detected.");
@@ -1541,22 +1550,47 @@ void PlayerManager::ProcessCommandTarget(cmd_target_info_t *info)
}
/* Do we need to look for a steam id? */
int steamIdType = 0;
if (strncmp(&info->pattern[1], "STEAM_", 6) == 0)
{
size_t p, len;
steamIdType = 2;
}
else if (strncmp(&info->pattern[1], "[U:", 3) == 0)
{
steamIdType = 3;
}
if (steamIdType > 0)
{
char new_pattern[256];
strcpy(new_pattern, "STEAM_");
len = strlen(&info->pattern[7]);
for (p = 0; p < len; p++)
if (steamIdType == 2)
{
new_pattern[6 + p] = info->pattern[7 + p];
if (new_pattern[6 + p] == '_')
size_t p, len;
strcpy(new_pattern, "STEAM_");
len = strlen(&info->pattern[7]);
for (p = 0; p < len; p++)
{
new_pattern[6 + p] = ':';
new_pattern[6 + p] = info->pattern[7 + p];
if (new_pattern[6 + p] == '_')
{
new_pattern[6 + p] = ':';
}
}
new_pattern[6 + p] = '\0';
}
else
{
size_t p = 0;
char c;
while ((c = info->pattern[p + 1]) != '\0')
{
new_pattern[p] = (c == '_') ? ':' : c;
++p;
}
new_pattern[p] = '\0';
}
new_pattern[6 + p] = '\0';
for (int i = 1; i <= max_clients; i++)
{
@@ -1568,8 +1602,10 @@ void PlayerManager::ProcessCommandTarget(cmd_target_info_t *info)
{
continue;
}
const char *authstr = pTarget->GetAuthString(false); // We want to make it easy for people to be kicked/banned, so don't require validation for command targets.
if (authstr && strcmp(authstr, new_pattern) == 0)
// We want to make it easy for people to be kicked/banned, so don't require validation for command targets.
const char *steamId = steamIdType == 2 ? pTarget->GetSteam2Id(false) : pTarget->GetSteam3Id(false);
if (steamId && strcmp(steamId, new_pattern) == 0)
{
if ((info->reason = FilterCommandTarget(pAdmin, pTarget, info->flags))
== COMMAND_TARGET_VALID)
@@ -1862,6 +1898,24 @@ void CmdMaxplayersCallback()
g_Players.MaxPlayersChanged();
}
#if SOURCE_ENGINE == SE_CSGO
bool PlayerManager::HandleConVarQuery(QueryCvarCookie_t cookie, edict_t *pPlayer, EQueryCvarValueStatus result, const char *cvarName, const char *cvarValue)
{
for (int i = 1; i <= m_maxClients; i++)
{
if (m_Players[i].m_LanguageCookie == cookie)
{
unsigned int langid;
m_Players[i].m_LangId = (translator->GetLanguageByName(cvarValue, &langid)) ? langid : translator->GetServerLanguage();
return true;
}
}
return false;
}
#endif
/*******************
*** PLAYER CODE ***
@@ -1885,7 +1939,9 @@ CPlayer::CPlayer()
m_bIsSourceTV = false;
m_bIsReplay = false;
m_Serial.value = -1;
m_SteamAccountID = 0;
#if SOURCE_ENGINE == SE_CSGO
m_LanguageCookie = InvalidQueryCvarCookie;
#endif
}
void CPlayer::Initialize(const char *name, const char *ip, edict_t *pEntity)
@@ -1907,6 +1963,8 @@ void CPlayer::Initialize(const char *name, const char *ip, edict_t *pEntity)
*ptr = '\0';
}
m_IpNoPort.assign(ip2);
UpdateAuthIds();
}
void CPlayer::Connect()
@@ -1931,14 +1989,112 @@ void CPlayer::Connect()
}
}
void CPlayer::SetAuthString(const char *steamid)
void CPlayer::UpdateAuthIds()
{
if (m_IsAuthorized)
{
return;
}
// First cache engine networkid
const char *authstr;
#if SOURCE_ENGINE == SE_DOTA
authstr = engine->GetPlayerNetworkIDString(m_iIndex - 1);
#else
authstr = engine->GetPlayerNetworkIDString(m_pEdict);
#endif
m_AuthID.assign(steamid);
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)
{
return;
}
m_AuthID = authstr;
// Then, cache SteamId
if (IsFakeClient())
{
m_SteamId = k_steamIDNil;
}
else
{
#if SOURCE_ENGINE < SE_ORANGEBOX
const char * pAuth = GetAuthString();
/* STEAM_0:1:123123 | STEAM_ID_LAN | STEAM_ID_PENDING */
if (pAuth && (strlen(pAuth) > 10) && pAuth[8] != '_')
{
m_SteamId = CSteamID(atoi(&pAuth[8]) | (atoi(&pAuth[10]) << 1),
k_unSteamUserDesktopInstance, k_EUniversePublic, k_EAccountTypeIndividual);
}
#else
const CSteamID *steamId;
#if SOURCE_ENGINE == SE_DOTA
steamId = engine->GetClientSteamID(m_iIndex);
#else
steamId = engine->GetClientSteamID(m_pEdict);
#endif
if (steamId)
{
m_SteamId = (*steamId);
}
#endif
}
// Now cache Steam2/3 rendered ids
if (IsFakeClient())
{
m_Steam2Id = "BOT";
m_Steam3Id = "BOT";
return;
}
if (!m_SteamId.IsValid())
{
if (g_HL2.IsLANServer())
{
m_Steam2Id = "STEAM_ID_LAN";
m_Steam3Id = "STEAM_ID_LAN";
return;
}
else
{
m_Steam2Id = "STEAM_ID_PENDING";
m_Steam3Id = "STEAM_ID_PENDING";
}
return;
}
EUniverse steam2universe = m_SteamId.GetEUniverse();
const char *keyUseInvalidUniverse = g_pGameConf->GetKeyValue("UseInvalidUniverseInSteam2IDs");
if (keyUseInvalidUniverse && atoi(keyUseInvalidUniverse) == 1)
{
steam2universe = k_EUniverseInvalid;
}
char szAuthBuffer[64];
snprintf(szAuthBuffer, sizeof(szAuthBuffer), "STEAM_%u:%u:%u", steam2universe, m_SteamId.GetAccountID() & 1, m_SteamId.GetAccountID() >> 1);
m_Steam2Id = szAuthBuffer;
// TODO: make sure all hl2sdks' steamclientpublic.h have k_unSteamUserDesktopInstance.
if (m_SteamId.GetUnAccountInstance() == 1 /* k_unSteamUserDesktopInstance */)
{
snprintf(szAuthBuffer, sizeof(szAuthBuffer), "[U:%u:%u]", m_SteamId.GetEUniverse(), m_SteamId.GetAccountID());
}
else
{
snprintf(szAuthBuffer, sizeof(szAuthBuffer), "[U:%u:%u:%u]", m_SteamId.GetEUniverse(), m_SteamId.GetAccountID(), m_SteamId.GetUnAccountInstance());
}
m_Steam3Id = szAuthBuffer;
}
// Ensure a valid AuthString is set before calling.
@@ -1955,7 +2111,10 @@ void CPlayer::Disconnect()
m_IsAuthorized = false;
m_Name.clear();
m_Ip.clear();
m_AuthID.clear();
m_AuthID = "";
m_SteamId = k_steamIDNil;
m_Steam2Id = "";
m_Steam3Id = "";
m_pEdict = NULL;
m_Info = NULL;
m_bAdminCheckSignalled = false;
@@ -1965,7 +2124,9 @@ void CPlayer::Disconnect()
m_bIsSourceTV = false;
m_bIsReplay = false;
m_Serial.value = -1;
m_SteamAccountID = 0;
#if SOURCE_ENGINE == SE_CSGO
m_LanguageCookie = InvalidQueryCvarCookie;
#endif
}
void CPlayer::SetName(const char *name)
@@ -1995,42 +2156,50 @@ const char *CPlayer::GetAuthString(bool validated)
return NULL;
}
return m_AuthID.c_str();
return m_AuthID.chars();
}
const CSteamID &CPlayer::GetSteamId(bool validated)
{
if (validated && !IsAuthStringValidated())
{
static const CSteamID invalidId = k_steamIDNil;
return invalidId;
}
return m_SteamId;
}
const char *CPlayer::GetSteam2Id(bool validated)
{
if (!m_Steam2Id.length() || (validated && !IsAuthStringValidated()))
{
return NULL;
}
return m_Steam2Id.chars();
}
const char *CPlayer::GetSteam3Id(bool validated)
{
if (!m_Steam3Id.length() || (validated && !IsAuthStringValidated()))
{
return NULL;
}
return m_Steam3Id.chars();
}
unsigned int CPlayer::GetSteamAccountID(bool validated)
{
if (IsFakeClient() || (validated && !IsAuthStringValidated()))
if (!IsFakeClient() && (!validated || IsAuthStringValidated()))
{
return 0;
const CSteamID &id = GetSteamId();
if (id.IsValid())
return id.GetAccountID();
}
if (m_SteamAccountID != 0)
{
return m_SteamAccountID;
}
#if SOURCE_ENGINE < SE_ORANGEBOX
const char * pAuth = GetAuthString();
/* STEAM_0:1:123123 | STEAM_ID_LAN | STEAM_ID_PENDING */
if (pAuth && (strlen(pAuth) > 10) && pAuth[8] != '_')
{
m_SteamAccountID = (atoi(&pAuth[8]) | (atoi(&pAuth[10]) << 1));
}
#else
unsigned long long *steamId;
#if SOURCE_ENGINE == SE_DOTA
steamId = (unsigned long long *)engine->GetClientSteamID(m_iIndex);
#else
steamId = (unsigned long long *)engine->GetClientSteamID(m_pEdict);
#endif
if (steamId)
{
m_SteamAccountID = (*steamId & 0xFFFFFFFF);
}
#endif
return m_SteamAccountID;
return 0;
}
edict_t *CPlayer::GetEdict()
@@ -2296,7 +2465,7 @@ void CPlayer::DoBasicAdminChecks()
}
/* Check steam id */
if ((id = adminsys->FindAdminByIdentity("steam", m_AuthID.c_str())) != INVALID_ADMIN_ID)
if ((id = adminsys->FindAdminByIdentity("steam", m_AuthID.chars())) != INVALID_ADMIN_ID)
{
if (g_Players.CheckSetAdmin(client, this, id))
{
+18 -3
View File
@@ -41,8 +41,11 @@
#include <sh_string.h>
#include <sh_list.h>
#include <sh_vector.h>
#include <am-string.h>
#include "ConVarManager.h"
#include <steam/steamclientpublic.h>
using namespace SourceHook;
#define PLAYER_LIFE_UNKNOWN 0
@@ -71,6 +74,10 @@ public:
const char *GetIPAddress();
const char *GetAuthString(bool validated = true);
unsigned int GetSteamAccountID(bool validated = true);
const CSteamID &GetSteamId(bool validated = true);
uint64_t GetSteamId64(bool validated = true) { return GetSteamId(validated).ConvertToUint64(); }
const char *GetSteam2Id(bool validated = true);
const char *GetSteam3Id(bool validated = true);
edict_t *GetEdict();
bool IsInGame();
bool WasCountedAsInGame();
@@ -103,7 +110,7 @@ private:
void Disconnect();
void SetName(const char *name);
void DumpAdmin(bool deleting);
void SetAuthString(const char *auth);
void UpdateAuthIds();
void Authorize();
void Authorize_Post();
void DoPostConnectAuthorization();
@@ -116,7 +123,9 @@ private:
String m_Name;
String m_Ip;
String m_IpNoPort;
String m_AuthID;
ke::AString m_AuthID;
ke::AString m_Steam2Id;
ke::AString m_Steam3Id;
AdminId m_Admin;
bool m_TempAdmin;
edict_t *m_pEdict;
@@ -130,7 +139,10 @@ private:
bool m_bIsSourceTV;
bool m_bIsReplay;
serial_t m_Serial;
unsigned int m_SteamAccountID;
CSteamID m_SteamId;
#if SOURCE_ENGINE == SE_CSGO
QueryCvarCookie_t m_LanguageCookie;
#endif
};
class PlayerManager :
@@ -211,6 +223,9 @@ public:
unsigned int GetReplyTo();
unsigned int SetReplyTo(unsigned int reply);
void MaxPlayersChanged(int newvalue = -1);
#if SOURCE_ENGINE == SE_CSGO
bool HandleConVarQuery(QueryCvarCookie_t cookie, edict_t *pPlayer, EQueryCvarValueStatus result, const char *cvarName, const char *cvarValue);
#endif
private:
#if SOURCE_ENGINE == SE_DOTA
void OnServerActivate();
+10 -1
View File
@@ -19,6 +19,12 @@ if builder.target_platform == 'linux':
elif builder.target_platform == 'mac':
binary.compiler.cflags += ['-Wno-deprecated-declarations']
binary.compiler.postlink += ['-framework', 'CoreServices']
if binary.compiler.vendor == 'gcc' or binary.compiler.vendor == 'clang':
binary.compiler.cxxflags += ['-fno-rtti']
elif binary.compiler.vendor == 'msvc':
binary.compiler.cxxflags += ['/GR-']
binary.sources += [
'common_logic.cpp',
'smn_adt_array.cpp',
@@ -33,7 +39,6 @@ binary.sources += [
'TextParsers.cpp',
'smn_textparse.cpp',
'smn_adt_trie.cpp',
'Profiler.cpp',
'smn_functions.cpp',
'smn_timers.cpp',
'smn_players.cpp',
@@ -66,6 +71,10 @@ binary.sources += [
'AdminCache.cpp',
'sm_trie.cpp',
'smn_console.cpp',
'ProfileTools.cpp',
'Logger.cpp',
'smn_core.cpp',
'smn_menus.cpp',
]
if builder.target_platform == 'windows':
binary.sources += ['thread/WinThreads.cpp']
+97 -23
View File
@@ -39,15 +39,16 @@
#include "AdminCache.h"
#include "Translator.h"
#include "common_logic.h"
#include "stringutil.h"
#define LEVEL_STATE_NONE 0
#define LEVEL_STATE_LEVELS 1
#define LEVEL_STATE_FLAGS 2
AdminCache g_Admins;
char g_ReverseFlags[26];
char g_ReverseFlags[AdminFlags_TOTAL];
AdminFlag g_FlagLetters[26];
bool g_FlagSet[26];
bool g_FlagCharSet[26];
/* Default flags */
AdminFlag g_DefaultFlags[26] =
@@ -71,9 +72,9 @@ public:
memcpy(g_FlagLetters, g_DefaultFlags, sizeof(AdminFlag) * 26);
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:
@@ -103,7 +104,7 @@ private:
{
m_LevelState = LEVEL_STATE_NONE;
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)
{
@@ -163,7 +164,7 @@ private:
return SMCResult_Continue;
}
g_FlagSet[c] = true;
g_FlagCharSet[c] = true;
return SMCResult_Continue;
}
@@ -198,11 +199,11 @@ private:
if (!m_bFileNameLogged)
{
smcore.LogError("[SM] Parse error(s) detected in file \"%s\":", m_File);
logger->LogError("[SM] Parse error(s) detected in file \"%s\":", m_File);
m_bFileNameLogged = true;
}
smcore.LogError("[SM] (Line %d): %s", states ? states->line : 0, buffer);
logger->LogError("[SM] (Line %d): %s", states ? states->line : 0, buffer);
}
private:
bool m_bFileNameLogged;
@@ -1056,6 +1057,65 @@ bool AdminCache::GetMethodIndex(const char *name, unsigned int *_index)
return false;
}
/*
* Converts Steam2 id, Steam3 id, or SteamId64 to unified, legacy
* admin identity format. (account id part of Steam2 format)
*/
bool AdminCache::GetUnifiedSteamIdentity(const char *ident, char *out, size_t maxlen)
{
int len = strlen(ident);
if (!strcmp(ident, "BOT"))
{
// 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]);
return true;
}
else if (len >= 7 && !strncmp(ident, "[U:", 3) && ident[len-1] == ']')
{
// Steam3 Id, replicate the Steam2 Post-"STEAM_" part
uint32_t accountId = strtoul(&ident[5], nullptr, 10);
snprintf(out, maxlen, "%u:%u", accountId & 1, accountId >> 1);
return true;
}
else
{
// 64-bit CSteamID, replicate the Steam2 Post-"STEAM_" part
// some constants from steamclientpublic.h
static const uint32_t k_EAccountTypeIndividual = 1;
static const int k_EUniverseInvalid = 0;
static const int k_EUniverseMax = 5;
static const unsigned int k_unSteamUserWebInstance = 4;
uint64_t steamId = strtoull(ident, nullptr, 10);
if (steamId > 0)
{
// Make some attempt at being sure it's a valid id rather than other number,
// even though we're only going to use the lower 32 bits.
uint32_t accountId = steamId & 0xFFFFFFFF;
uint32_t accountType = (steamId >> 52) & 0xF;
int universe = steamId >> 56;
uint32_t accountInstance = (steamId >> 32) & 0xFFFFF;
if (accountId > 0
&& universe > k_EUniverseInvalid && universe < k_EUniverseMax
&& accountType == k_EAccountTypeIndividual && accountInstance <= k_unSteamUserWebInstance
)
{
snprintf(out, maxlen, "%u:%u", accountId & 1, accountId >> 1);
return true;
}
}
}
return false;
}
bool AdminCache::BindAdminIdentity(AdminId id, const char *auth, const char *ident)
{
if (ident[0] == '\0')
@@ -1073,10 +1133,14 @@ bool AdminCache::BindAdminIdentity(AdminId id, const char *auth, const char *ide
if (!m_AuthTables.retrieve(auth, &method))
return false;
/* If the id was a steam id strip off the STEAM_*: part */
if (strcmp(auth, "steam") == 0 && strncmp(ident, "STEAM_", 6) == 0)
/* If the auth type is steam, the id could be in a number of formats. Unify it. */
char steamIdent[16];
if (strcmp(auth, "steam") == 0)
{
ident += 8;
if (!GetUnifiedSteamIdentity(ident, steamIdent, sizeof(steamIdent)))
return false;
ident = steamIdent;
}
if (method->identities.contains(ident))
@@ -1097,10 +1161,14 @@ AdminId AdminCache::FindAdminByIdentity(const char *auth, const char *identity)
if (!m_AuthTables.retrieve(auth, &method))
return INVALID_ADMIN_ID;
/* If the id was a steam id strip off the STEAM_*: part */
if (strcmp(auth, "steam") == 0 && strncmp(identity, "STEAM_", 6) == 0)
/* If the auth type is steam, the id could be in a number of formats. Unify it. */
char steamIdent[16];
if (strcmp(auth, "steam") == 0)
{
identity += 8;
if (!GetUnifiedSteamIdentity(identity, steamIdent, sizeof(steamIdent)))
return INVALID_ADMIN_ID;
identity = steamIdent;
}
AdminId id;
@@ -1517,7 +1585,7 @@ bool AdminCache::FindFlag(char c, AdminFlag *pAdmFlag)
{
if (c < 'a'
|| c > 'z'
|| !g_FlagSet[(unsigned)c - (unsigned)'a'])
|| !g_FlagCharSet[(unsigned)c - (unsigned)'a'])
{
return false;
}
@@ -1532,17 +1600,13 @@ bool AdminCache::FindFlag(char c, AdminFlag *pAdmFlag)
bool AdminCache::FindFlagChar(AdminFlag flag, char *c)
{
if (!g_FlagSet[flag])
{
return false;
}
char flagchar = g_ReverseFlags[flag];
if (c)
{
*c = g_ReverseFlags[flag];
*c = flagchar;
}
return true;
return flagchar != '?';
}
FlagBits AdminCache::ReadFlagString(const char *flags, const char **end)
@@ -1702,7 +1766,7 @@ void iterator_group_grp_override(FILE *fp, const char *key, OverrideRule rule)
fprintf(fp, "\t\t\t\"@%s\"\t\t\"%s\"\n", key, str);
}
void AdminCache::DumpCache(FILE *fp)
bool AdminCache::DumpCache(const char *filename)
{
int *itable;
AdminId aid;
@@ -1711,6 +1775,12 @@ void AdminCache::DumpCache(FILE *fp)
unsigned int num;
AdminUser *pAdmin;
AdminGroup *pGroup;
FILE *fp;
if ((fp = fopen(filename, "wt")) == NULL)
{
return false;
}
fprintf(fp, "\"Groups\"\n{\n");
@@ -1841,6 +1911,10 @@ void AdminCache::DumpCache(FILE *fp)
for (FlagMap::iterator iter = m_CmdOverrides.iter(); !iter.empty(); iter.next())
iterator_glob_basic_override(fp, iter->key.chars(), iter->value);
fprintf(fp, "}\n");
fclose(fp);
return true;
}
AdminGroup *AdminCache::GetGroup(GroupId gid)
+2 -1
View File
@@ -183,7 +183,7 @@ public: //IAdminSystem
bool IsValidAdmin(AdminId id);
bool CheckClientCommandAccess(int client, const char *cmd, FlagBits cmdflags);
public:
void DumpCache(FILE *fp);
bool DumpCache(const char *filename);
AdminGroup *GetGroup(GroupId gid);
AdminUser *GetUser(AdminId id);
const char *GetString(int idx);
@@ -198,6 +198,7 @@ private:
bool GetMethodIndex(const char *name, unsigned int *_index);
const char *GetMethodName(unsigned int index);
void NameFlag(const char *str, AdminFlag flag);
bool GetUnifiedSteamIdentity(const char *ident, char *out, size_t maxlen);
public:
typedef StringHashMap<FlagBits> FlagMap;
+14 -3
View File
@@ -89,11 +89,11 @@ void DBManager::OnSourceModLevelChange(const char *mapName)
ke::AutoLock lock(&m_ConfigLock);
if ((err = textparsers->ParseFile_SMC(m_Filename, this, &states)) != SMCError_Okay)
{
smcore.LogError("[SM] Detected parse error(s) in file \"%s\"", m_Filename);
logger->LogError("[SM] Detected parse error(s) in file \"%s\"", m_Filename);
if (err != SMCError_Custom)
{
const char *txt = textparsers->GetSMCErrorString(err);
smcore.LogError("[SM] Line %d: %s", states.line, txt);
logger->LogError("[SM] Line %d: %s", states.line, txt);
}
}
}
@@ -541,7 +541,7 @@ bool DBManager::AddToThreadQueue(IDBThreadOperation *op, PrioQueueLevel prio)
{
if (!s_OneTimeThreaderErrorMsg)
{
smcore.LogError("[SM] Unable to create db threader (error unknown)");
logger->LogError("[SM] Unable to create db threader (error unknown)");
s_OneTimeThreaderErrorMsg = true;
}
m_Worker = NULL;
@@ -615,6 +615,17 @@ void DBManager::ThreadMain()
ke::AutoLock lock(&m_ThinkLock);
m_ThinkQueue.push(op);
}
if (!m_Terminate)
{
ke::AutoUnlock unlock(&m_QueueEvent);
#ifdef _WIN32
Sleep(20);
#else
usleep(20000);
#endif
}
}
if (m_Terminate)
+20 -19
View File
@@ -32,6 +32,7 @@
#include <IPluginSys.h>
#include <stdarg.h>
#include "DebugReporter.h"
#include "Logger.h"
DebugReport g_DbgReporter;
@@ -49,7 +50,7 @@ void DebugReport::OnDebugSpew(const char *msg, ...)
smcore.FormatArgs(buffer, sizeof(buffer), msg, ap);
va_end(ap);
smcore.Log("[SM] %s", buffer);
g_Logger.LogMessage("[SM] %s", buffer);
}
void DebugReport::GenerateError(IPluginContext *ctx, cell_t func_idx, int err, const char *message, ...)
@@ -71,12 +72,12 @@ void DebugReport::GenerateErrorVA(IPluginContext *ctx, cell_t func_idx, int err,
if (error)
{
smcore.LogError("[SM] Plugin \"%s\" encountered error %d: %s", plname, err, error);
g_Logger.LogError("[SM] Plugin \"%s\" encountered error %d: %s", plname, err, error);
} else {
smcore.LogError("[SM] Plugin \"%s\" encountered unknown error %d", plname, err);
g_Logger.LogError("[SM] Plugin \"%s\" encountered unknown error %d", plname, err);
}
smcore.LogError("[SM] %s", buffer);
g_Logger.LogError("[SM] %s", buffer);
if (func_idx != -1)
{
@@ -86,7 +87,7 @@ void DebugReport::GenerateErrorVA(IPluginContext *ctx, cell_t func_idx, int err,
sp_public_t *function;
if (ctx->GetRuntime()->GetPublicByIndex(func_idx, &function) == SP_ERROR_NONE)
{
smcore.LogError("[SM] Unable to call function \"%s\" due to above error(s).", function->name);
g_Logger.LogError("[SM] Unable to call function \"%s\" due to above error(s).", function->name);
}
}
}
@@ -106,18 +107,18 @@ void DebugReport::GenerateCodeError(IPluginContext *pContext, uint32_t code_addr
if (error)
{
smcore.LogError("[SM] Plugin \"%s\" encountered error %d: %s", plname, err, error);
g_Logger.LogError("[SM] Plugin \"%s\" encountered error %d: %s", plname, err, error);
} else {
smcore.LogError("[SM] Plugin \"%s\" encountered unknown error %d", plname, err);
g_Logger.LogError("[SM] Plugin \"%s\" encountered unknown error %d", plname, err);
}
smcore.LogError("[SM] %s", buffer);
g_Logger.LogError("[SM] %s", buffer);
IPluginDebugInfo *pDebug;
if ((pDebug = pContext->GetRuntime()->GetDebugInfo()) == NULL)
{
smcore.LogError("[SM] Debug mode is not enabled for \"%s\"", plname);
smcore.LogError("[SM] To enable debug mode, edit plugin_settings.cfg, or type: sm plugins debug %d on",
g_Logger.LogError("[SM] Debug mode is not enabled for \"%s\"", plname);
g_Logger.LogError("[SM] To enable debug mode, edit plugin_settings.cfg, or type: sm plugins debug %d on",
_GetPluginIndex(pContext));
return;
}
@@ -125,9 +126,9 @@ void DebugReport::GenerateCodeError(IPluginContext *pContext, uint32_t code_addr
const char *name;
if (pDebug->LookupFunction(code_addr, &name) == SP_ERROR_NONE)
{
smcore.LogError("[SM] Unable to call function \"%s\" due to above error(s).", name);
g_Logger.LogError("[SM] Unable to call function \"%s\" due to above error(s).", name);
} else {
smcore.LogError("[SM] Unable to call function (name unknown, address \"%x\").", code_addr);
g_Logger.LogError("[SM] Unable to call function (name unknown, address \"%x\").", code_addr);
}
}
@@ -139,7 +140,7 @@ void DebugReport::OnContextExecuteError(IPluginContext *ctx, IContextTrace *erro
if (n_err != SP_ERROR_NATIVE)
{
smcore.LogError("[SM] Plugin encountered error %d: %s",
g_Logger.LogError("[SM] Plugin encountered error %d: %s",
n_err,
error->GetErrorString());
}
@@ -149,26 +150,26 @@ void DebugReport::OnContextExecuteError(IPluginContext *ctx, IContextTrace *erro
const char *custerr;
if ((custerr=error->GetCustomErrorString()) != NULL)
{
smcore.LogError("[SM] Native \"%s\" reported: %s", lastname, custerr);
g_Logger.LogError("[SM] Native \"%s\" reported: %s", lastname, custerr);
} else {
smcore.LogError("[SM] Native \"%s\" encountered a generic error.", lastname);
g_Logger.LogError("[SM] Native \"%s\" encountered a generic error.", lastname);
}
}
if (!error->DebugInfoAvailable())
{
smcore.LogError("[SM] Debug mode is not enabled for \"%s\"", plname);
smcore.LogError("[SM] To enable debug mode, edit plugin_settings.cfg, or type: sm plugins debug %d on",
g_Logger.LogError("[SM] Debug mode is not enabled for \"%s\"", plname);
g_Logger.LogError("[SM] To enable debug mode, edit plugin_settings.cfg, or type: sm plugins debug %d on",
_GetPluginIndex(ctx));
return;
}
CallStackInfo stk_info;
int i = 0;
smcore.LogError("[SM] Displaying call stack trace for plugin \"%s\":", plname);
g_Logger.LogError("[SM] Displaying call stack trace for plugin \"%s\":", plname);
while (error->GetTraceInfo(&stk_info))
{
smcore.LogError("[SM] [%d] Line %d, %s::%s()",
g_Logger.LogError("[SM] [%d] Line %d, %s::%s()",
i++,
stk_info.line,
stk_info.filename,
+19 -1
View File
@@ -606,7 +606,7 @@ IExtension *CExtensionManager::LoadAutoExtension(const char *path, bool bErrorOn
{
if (bErrorOnMissing || libsys->IsPathFile(p->GetPath()))
{
smcore.LogError("[SM] Unable to load extension \"%s\": %s", path, error);
logger->LogError("[SM] Unable to load extension \"%s\": %s", path, error);
}
p->SetError(error);
@@ -1360,6 +1360,24 @@ void CExtensionManager::CallOnCoreMapStart(edict_t *pEdictList, int edictCount,
}
}
void CExtensionManager::CallOnCoreMapEnd()
{
IExtensionInterface *pAPI;
List<CExtension *>::iterator iter;
for (iter=m_Libs.begin(); iter!=m_Libs.end(); iter++)
{
if ((pAPI = (*iter)->GetAPI()) == NULL)
{
continue;
}
if (pAPI->GetExtensionVersion() > 7)
{
pAPI->OnCoreMapEnd();
}
}
}
const CVector<IExtension *> *CExtensionManager::ListExtensions()
{
CVector<IExtension *> *list = new CVector<IExtension *>();
+1
View File
@@ -173,6 +173,7 @@ public:
void AddLibrary(IExtension *pSource, const char *library);
bool LibraryExists(const char *library);
void CallOnCoreMapStart(edict_t *pEdictList, int edictCount, int clientMax);
void CallOnCoreMapEnd();
void AddRawDependency(IExtension *ext, IdentityToken_t *other, void *iface);
const CVector<IExtension *> *ListExtensions();
void FreeExtensionList(const CVector<IExtension *> *list);
+15 -14
View File
@@ -301,8 +301,8 @@ SMCResult CGameConfig::ReadSMC_NewSection(const SMCStates *states, const char *n
if (error[0] != '\0')
{
m_IgnoreLevel = 1;
smcore.LogError("[SM] Error while parsing CRC section for \"%s\" (%s):", m_Game, m_CurFile);
smcore.LogError("[SM] %s", error);
logger->LogError("[SM] Error while parsing CRC section for \"%s\" (%s):", m_Game, m_CurFile);
logger->LogError("[SM] %s", error);
} else {
m_ParseState = PSTATE_GAMEDEFS_CRC_BINARY;
}
@@ -335,8 +335,8 @@ SMCResult CGameConfig::ReadSMC_NewSection(const SMCStates *states, const char *n
{
if (strcmp(name, "linux") != 0 && strcmp(name, "windows") != 0 && strcmp(name, "mac") != 0)
{
smcore.LogError("[SM] Error while parsing Address section for \"%s\" (%s):", m_Address, m_CurFile);
smcore.LogError("[SM] Unrecognized platform \"%s\"", name);
logger->LogError("[SM] Error while parsing Address section for \"%s\" (%s):", m_Address, m_CurFile);
logger->LogError("[SM] Unrecognized platform \"%s\"", name);
}
m_IgnoreLevel = 1;
}
@@ -435,7 +435,7 @@ SMCResult CGameConfig::ReadSMC_KeyValue(const SMCStates *states, const char *key
}
else
{
smcore.LogError("[SM] Error parsing Address \"%s\", does not support more than %d read offsets (gameconf \"%s\")", m_Address, limit, m_CurFile);
logger->LogError("[SM] Error parsing Address \"%s\", does not support more than %d read offsets (gameconf \"%s\")", m_Address, limit, m_CurFile);
}
} else if (strcmp(key, "signature") == 0) {
strncopy(m_AddressSignature, value, sizeof(m_AddressSignature));
@@ -503,7 +503,7 @@ SMCResult CGameConfig::ReadSMC_LeavingSection(const SMCStates *states)
if (((strcmp(m_Game, "*") != 0) && strcmp(m_Game, "#default") != 0)
&& (!m_Offsets.retrieve(m_offset)))
{
smcore.LogError("[SM] Unable to find property %s.%s (file \"%s\") (mod \"%s\")",
logger->LogError("[SM] Unable to find property %s.%s (file \"%s\") (mod \"%s\")",
m_Class,
m_Prop,
m_CurFile,
@@ -556,7 +556,7 @@ SMCResult CGameConfig::ReadSMC_LeavingSection(const SMCStates *states)
void *final_addr = NULL;
if (addrInBase == NULL)
{
smcore.LogError("[SM] Unrecognized library \"%s\" (gameconf \"%s\")",
logger->LogError("[SM] Unrecognized library \"%s\" (gameconf \"%s\")",
s_TempSig.library,
m_CurFile);
}
@@ -570,7 +570,7 @@ SMCResult CGameConfig::ReadSMC_LeavingSection(const SMCStates *states)
if (VirtualQuery(addrInBase, &mem, sizeof(mem)))
final_addr = g_MemUtils.ResolveSymbol(mem.AllocationBase, &s_TempSig.sig[1]);
else
smcore.LogError("[SM] Unable to find library \"%s\" in memory (gameconf \"%s\")", s_TempSig.library, m_File);
logger->LogError("[SM] Unable to find library \"%s\" in memory (gameconf \"%s\")", s_TempSig.library, m_File);
#elif defined PLATFORM_POSIX
Dl_info info;
/* GNU only: returns 0 on error, inconsistent! >:[ */
@@ -585,12 +585,12 @@ SMCResult CGameConfig::ReadSMC_LeavingSection(const SMCStates *states)
final_addr = dlsym(handle, &s_TempSig.sig[1]);
dlclose(handle);
} else {
smcore.LogError("[SM] Unable to load library \"%s\" (gameconf \"%s\")",
logger->LogError("[SM] Unable to load library \"%s\" (gameconf \"%s\")",
s_TempSig.library,
m_File);
}
} else {
smcore.LogError("[SM] Unable to find library \"%s\" in memory (gameconf \"%s\")",
logger->LogError("[SM] Unable to find library \"%s\" in memory (gameconf \"%s\")",
s_TempSig.library,
m_File);
}
@@ -827,8 +827,8 @@ bool CGameConfig::Reparse(char *error, size_t maxlength)
{
const char *msg = textparsers->GetSMCErrorString(err);
smcore.LogError("[SM] Error parsing master gameconf file \"%s\":", path);
smcore.LogError("[SM] Error %d on line %d, col %d: %s",
logger->LogError("[SM] Error parsing master gameconf file \"%s\":", path);
logger->LogError("[SM] Error %d on line %d, col %d: %s",
err,
state.line,
state.col,
@@ -915,8 +915,8 @@ bool CGameConfig::EnterFile(const char *file, char *error, size_t maxlength)
{
const char *msg = textparsers->GetSMCErrorString(err);
smcore.LogError("[SM] Error parsing gameconfig file \"%s\":", m_CurFile);
smcore.LogError("[SM] Error %d on line %d, col %d: %s",
logger->LogError("[SM] Error parsing gameconfig file \"%s\":", m_CurFile);
logger->LogError("[SM] Error %d on line %d, col %d: %s",
err,
state.line,
state.col,
@@ -1082,6 +1082,7 @@ bool GameConfigManager::LoadGameConfigFile(const char *file, IGameConfig **_pCon
}
pConfig = new CGameConfig(file);
pConfig->AddRef();
/* :HACKHACK: Don't parse the main config file */
bool retval = true;
+2 -2
View File
@@ -957,8 +957,8 @@ bool HandleSystem::InitAccessDefaults(TypeAccess *pTypeAccess, HandleAccess *pHa
}
#define HANDLE_LOG_VERY_BAD(message, ...) \
smcore.LogFatal(message, ##__VA_ARGS__); \
smcore.LogError(message, ##__VA_ARGS__);
logger->LogFatal(message, ##__VA_ARGS__); \
logger->LogError(message, ##__VA_ARGS__);
bool HandleSystem::TryAndFreeSomeHandles()
{
+1 -1
View File
@@ -38,7 +38,7 @@
#include <am-string.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_SUBTYPES 0xF
#define HANDLESYS_SUBTYPE_MASK 0xF
+551
View File
@@ -0,0 +1,551 @@
/**
* vim: set ts=4 sw=4 :
* =============================================================================
* SourceMod
* Copyright (C) 2004-2009 AlliedModders LLC. All rights reserved.
* =============================================================================
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, version 3.0, as published by the
* Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*
* As a special exception, AlliedModders LLC gives you permission to link the
* code of this program (as well as its derivative works) to "Half-Life 2," the
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
* by the Valve Corporation. You must obey the GNU General Public License in
* all respects for all other code used. Additionally, AlliedModders LLC grants
* this exception to all derivative works. AlliedModders LLC defines further
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
* or <http://www.sourcemod.net/license.php>.
*
* Version: $Id$
*/
#include <time.h>
#include <cstdarg>
#include "Logger.h"
#include <sourcemod_version.h>
#include <ISourceMod.h>
Logger g_Logger;
/**
* :TODO: This should be creating the log folder if it doesn't exist
*/
ConfigResult Logger::OnSourceModConfigChanged(const char *key,
const char *value,
ConfigSource source,
char *error,
size_t maxlength)
{
if (strcasecmp(key, "Logging") == 0)
{
bool state;
if (strcasecmp(value, "on") == 0)
{
state = true;
} else if (strcasecmp(value, "off") == 0) {
state = false;
} else {
smcore.Format(error, maxlength, "Invalid value: must be \"on\" or \"off\"");
return ConfigResult_Reject;
}
if (source == ConfigSource_Console)
{
state ? EnableLogging() : DisableLogging();
} else {
m_InitialState = state;
}
return ConfigResult_Accept;
} else if (strcasecmp(key, "LogMode") == 0) {
if (strcasecmp(value, "daily") == 0)
{
m_Mode = LoggingMode_Daily;
} else if (strcasecmp(value, "map") == 0) {
m_Mode = LoggingMode_PerMap;
} else if (strcasecmp(value, "game") == 0) {
m_Mode = LoggingMode_Game;
} else {
smcore.Format(error, maxlength, "Invalid value: must be [daily|map|game]");
return ConfigResult_Reject;
}
return ConfigResult_Accept;
}
return ConfigResult_Ignore;
}
void Logger::OnSourceModStartup(bool late)
{
InitLogger(m_Mode);
}
void Logger::OnSourceModAllShutdown()
{
CloseLogger();
}
void Logger::OnSourceModLevelChange(const char *mapName)
{
MapChange(mapName);
}
void Logger::_NewMapFile()
{
if (!m_Active)
{
return;
}
/* Append "Log file closed" to previous log file */
_CloseFile();
char _filename[256];
int i = 0;
time_t t = g_pSM->GetAdjustedTime();
tm *curtime = localtime(&t);
while (true)
{
g_pSM->BuildPath(Path_SM, _filename, sizeof(_filename), "logs/L%02d%02d%03d.log", curtime->tm_mon + 1, curtime->tm_mday, i);
FILE *fp = fopen(_filename, "r");
if (!fp)
{
break;
}
fclose(fp);
i++;
}
m_NrmFileName.assign(_filename);
FILE *fp = fopen(m_NrmFileName.c_str(), "w");
if (!fp)
{
char error[255];
libsys->GetPlatformError(error, sizeof(error));
LogFatal("[SM] Unexpected fatal logging error (file \"%s\")", m_NrmFileName.c_str());
LogFatal("[SM] Platform returned error: \"%s\"", error);
LogFatal("[SM] Logging has been disabled.");
m_Active = false;
return;
} else {
char date[32];
strftime(date, sizeof(date), "%m/%d/%Y - %H:%M:%S", curtime);
fprintf(fp, "L %s: SourceMod log file started (file \"L%02d%02d%03d.log\") (Version \"%s\")\n", date, curtime->tm_mon + 1, curtime->tm_mday, i, SOURCEMOD_VERSION);
fclose(fp);
}
}
void Logger::_CloseFile()
{
if (!m_Active)
{
return;
}
FILE *fp = NULL;
if (!m_NrmFileName.empty())
{
fp = fopen(m_NrmFileName.c_str(), "r+");
if (fp)
{
fseek(fp, 0, SEEK_END);
LogMessage("Log file closed.");
fclose(fp);
}
m_NrmFileName.clear();
}
if (!m_ErrMapStart)
{
return;
}
fp = fopen(m_ErrFileName.c_str(), "r+");
if (fp)
{
fseek(fp, 0, SEEK_END);
LogError("Error log file session closed.");
fclose(fp);
}
m_ErrFileName.clear();
}
void Logger::InitLogger(LoggingMode mode)
{
m_Mode = mode;
m_Active = m_InitialState;
time_t t = g_pSM->GetAdjustedTime();
tm *curtime = localtime(&t);
m_NrmCurDay = curtime->tm_mday;
m_ErrCurDay = curtime->tm_mday;
char _filename[256];
g_pSM->BuildPath(Path_SM, _filename, sizeof(_filename), "logs/errors_%04d%02d%02d.log", curtime->tm_year + 1900, curtime->tm_mon + 1, curtime->tm_mday);
m_ErrFileName.assign(_filename);
switch (m_Mode)
{
case LoggingMode_PerMap:
{
if (!m_Active)
{
m_DelayedStart = true;
}
break;
}
case LoggingMode_Daily:
{
g_pSM->BuildPath(Path_SM, _filename, sizeof(_filename), "logs/L%04d%02d%02d.log", curtime->tm_year + 1900, curtime->tm_mon + 1, curtime->tm_mday);
m_NrmFileName.assign(_filename);
m_DailyPrintHdr = true;
break;
}
default:
{
/* do nothing... */
break;
}
}
}
void Logger::CloseLogger()
{
_CloseFile();
}
void Logger::LogToOpenFile(FILE *fp, const char *msg, ...)
{
if (!m_Active)
{
return;
}
va_list ap;
va_start(ap, msg);
LogToOpenFileEx(fp, msg, ap);
va_end(ap);
}
void Logger::LogToFileOnly(FILE *fp, const char *msg, ...)
{
if (!m_Active)
{
return;
}
va_list ap;
va_start(ap, msg);
LogToFileOnlyEx(fp, msg, ap);
va_end(ap);
}
void Logger::LogToOpenFileEx(FILE *fp, const char *msg, va_list ap)
{
if (!m_Active)
{
return;
}
static ConVar *sv_logecho = smcore.FindConVar("sv_logecho");
char buffer[3072];
smcore.FormatArgs(buffer, sizeof(buffer), msg, ap);
char date[32];
time_t t = g_pSM->GetAdjustedTime();
tm *curtime = localtime(&t);
strftime(date, sizeof(date), "%m/%d/%Y - %H:%M:%S", curtime);
fprintf(fp, "L %s: %s\n", date, buffer);
if (!sv_logecho || smcore.GetCvarBool(sv_logecho))
{
static char conBuffer[4096];
smcore.Format(conBuffer, sizeof(conBuffer), "L %s: %s\n", date, buffer);
smcore.ConPrint(conBuffer);
}
}
void Logger::LogToFileOnlyEx(FILE *fp, const char *msg, va_list ap)
{
if (!m_Active)
{
return;
}
char buffer[3072];
smcore.FormatArgs(buffer, sizeof(buffer), msg, ap);
char date[32];
time_t t = g_pSM->GetAdjustedTime();
tm *curtime = localtime(&t);
strftime(date, sizeof(date), "%m/%d/%Y - %H:%M:%S", curtime);
fprintf(fp, "L %s: %s\n", date, buffer);
fflush(fp);
}
void Logger::LogMessage(const char *vafmt, ...)
{
va_list ap;
va_start(ap, vafmt);
LogMessageEx(vafmt, ap);
va_end(ap);
}
void Logger::LogMessageEx(const char *vafmt, va_list ap)
{
if (!m_Active)
{
return;
}
if (m_Mode == LoggingMode_Game)
{
_PrintToGameLog(vafmt, ap);
return;
}
if (m_DelayedStart)
{
m_DelayedStart = false;
_NewMapFile();
}
time_t t = g_pSM->GetAdjustedTime();
tm *curtime = localtime(&t);
FILE *fp = NULL;
if (m_Mode == LoggingMode_PerMap)
{
fp = fopen(m_NrmFileName.c_str(), "a+");
if (!fp)
{
_NewMapFile();
fp = fopen(m_NrmFileName.c_str(), "a+");
if (!fp)
{
goto print_error;
}
}
} else {
if (m_NrmCurDay != curtime->tm_mday)
{
char _filename[256];
g_pSM->BuildPath(Path_SM, _filename, sizeof(_filename), "logs/L%04d%02d%02d.log", curtime->tm_year + 1900, curtime->tm_mon + 1, curtime->tm_mday);
m_NrmFileName.assign(_filename);
m_NrmCurDay = curtime->tm_mday;
m_DailyPrintHdr = true;
}
fp = fopen(m_NrmFileName.c_str(), "a+");
}
if (fp)
{
if (m_DailyPrintHdr)
{
char date[32];
m_DailyPrintHdr = false;
strftime(date, sizeof(date), "%m/%d/%Y - %H:%M:%S", curtime);
fprintf(fp, "L %s: SourceMod log file session started (file \"L%04d%02d%02d.log\") (Version \"%s\")\n", date, curtime->tm_year + 1900, curtime->tm_mon + 1, curtime->tm_mday, SOURCEMOD_VERSION);
}
LogToOpenFileEx(fp, vafmt, ap);
fclose(fp);
} else {
goto print_error;
}
return;
print_error:
char error[255];
libsys->GetPlatformError(error, sizeof(error));
LogFatal("[SM] Unexpected fatal logging error (file \"%s\")", m_NrmFileName.c_str());
LogFatal("[SM] Platform returned error: \"%s\"", error);
LogFatal("[SM] Logging has been disabled.");
m_Active = false;
}
void Logger::LogError(const char *vafmt, ...)
{
va_list ap;
va_start(ap, vafmt);
LogErrorEx(vafmt, ap);
va_end(ap);
}
void Logger::LogErrorEx(const char *vafmt, va_list ap)
{
if (!m_Active)
{
return;
}
time_t t = g_pSM->GetAdjustedTime();
tm *curtime = localtime(&t);
if (curtime->tm_mday != m_ErrCurDay)
{
char _filename[256];
g_pSM->BuildPath(Path_SM, _filename, sizeof(_filename), "logs/errors_%04d%02d%02d.log", curtime->tm_year + 1900, curtime->tm_mon + 1, curtime->tm_mday);
m_ErrFileName.assign(_filename);
m_ErrCurDay = curtime->tm_mday;
m_ErrMapStart = false;
}
FILE *fp = fopen(m_ErrFileName.c_str(), "a+");
if (fp)
{
if (!m_ErrMapStart)
{
char date[32];
strftime(date, sizeof(date), "%m/%d/%Y - %H:%M:%S", curtime);
fprintf(fp, "L %s: SourceMod error session started\n", date);
fprintf(fp, "L %s: Info (map \"%s\") (file \"errors_%04d%02d%02d.log\")\n", date, m_CurMapName.c_str(), curtime->tm_year + 1900, curtime->tm_mon + 1, curtime->tm_mday);
m_ErrMapStart = true;
}
LogToOpenFileEx(fp, vafmt, ap);
fclose(fp);
}
else
{
char error[255];
libsys->GetPlatformError(error, sizeof(error));
LogFatal("[SM] Unexpected fatal logging error (file \"%s\")", m_NrmFileName.c_str());
LogFatal("[SM] Platform returned error: \"%s\"", error);
LogFatal("[SM] Logging has been disabled.");
m_Active = false;
return;
}
}
void Logger::MapChange(const char *mapname)
{
m_CurMapName.assign(mapname);
switch (m_Mode)
{
case LoggingMode_Daily:
{
LogMessage("-------- Mapchange to %s --------", mapname);
break;
}
case LoggingMode_PerMap:
{
_NewMapFile();
break;
}
default:
{
/* Do nothing... */
break;
}
}
if (m_ErrMapStart)
{
LogError("Error log file session closed.");
}
m_ErrMapStart = false;
}
void Logger::_PrintToGameLog(const char *fmt, va_list ap)
{
char msg[3072];
size_t len;
len = vsnprintf(msg, sizeof(msg)-2, fmt, ap);
len = (len >= sizeof(msg)) ? (sizeof(msg) - 2) : len;
msg[len++] = '\n';
msg[len] = '\0';
smcore.LogToGame(msg);
}
const char *Logger::GetLogFileName(LogType type) const
{
switch (type)
{
case LogType_Normal:
{
return m_NrmFileName.c_str();
}
case LogType_Error:
{
return m_ErrFileName.c_str();
}
default:
{
return "";
}
}
}
LoggingMode Logger::GetLoggingMode() const
{
return m_Mode;
}
void Logger::EnableLogging()
{
if (m_Active)
{
return;
}
m_Active = true;
LogMessage("[SM] Logging enabled manually by user.");
}
void Logger::DisableLogging()
{
if (!m_Active)
{
return;
}
LogMessage("[SM] Logging disabled manually by user.");
m_Active = false;
}
void Logger::LogFatal(const char *msg, ...)
{
va_list ap;
va_start(ap, msg);
LogFatalEx(msg, ap);
va_end(ap);
}
void Logger::LogFatalEx(const char *msg, va_list ap)
{
/* :TODO: make this print all pretty-like
* In fact, the pretty log printing function should be abstracted.
* It's already implemented twice which is bad.
*/
char path[PLATFORM_MAX_PATH];
g_pSM->BuildPath(Path_Game, path, sizeof(path), "sourcemod_fatal.log");
FILE *fp = fopen(path, "at");
if (fp)
{
m_Active = true;
LogToOpenFileEx(fp, msg, ap);
m_Active = false;
fclose(fp);
}
}
+111
View File
@@ -0,0 +1,111 @@
/**
* vim: set ts=4 :
* =============================================================================
* SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
* =============================================================================
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, version 3.0, as published by the
* Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*
* As a special exception, AlliedModders LLC gives you permission to link the
* code of this program (as well as its derivative works) to "Half-Life 2," the
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
* by the Valve Corporation. You must obey the GNU General Public License in
* all respects for all other code used. Additionally, AlliedModders LLC grants
* this exception to all derivative works. AlliedModders LLC defines further
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
* or <http://www.sourcemod.net/license.php>.
*
* Version: $Id$
*/
#ifndef _INCLUDE_SOURCEMOD_CLOGGER_H_
#define _INCLUDE_SOURCEMOD_CLOGGER_H_
#include <stdio.h>
#include <sh_string.h>
#include "common_logic.h"
using namespace SourceHook;
enum LogType
{
LogType_Normal,
LogType_Error
};
enum LoggingMode
{
LoggingMode_Daily,
LoggingMode_PerMap,
LoggingMode_Game
};
class Logger : public SMGlobalClass, public ILogger
{
public:
Logger() : m_Mode(LoggingMode_Daily), m_ErrMapStart(false),
m_Active(false), m_DelayedStart(false), m_DailyPrintHdr(false),
m_InitialState(true)
{
}
public: //SMGlobalClass
ConfigResult OnSourceModConfigChanged(const char *key,
const char *value,
ConfigSource source,
char *error,
size_t maxlength);
void OnSourceModStartup(bool late);
void OnSourceModAllShutdown();
void OnSourceModLevelChange(const char *mapName);
public:
void InitLogger(LoggingMode mode);
void CloseLogger();
void EnableLogging();
void DisableLogging();
void LogMessage(const char *msg, ...);
void LogMessageEx(const char *msg, va_list ap);
void LogError(const char *msg, ...);
void LogErrorEx(const char *msg, va_list ap);
void LogFatal(const char *msg, ...);
void LogFatalEx(const char *msg, va_list ap);
void LogToOpenFile(FILE *fp, const char *msg, ...);
void LogToOpenFileEx(FILE *fp, const char *msg, va_list ap);
/* This version does not print to console, and is thus thread-safe */
void LogToFileOnly(FILE *fp, const char *msg, ...);
void LogToFileOnlyEx(FILE *fp, const char *msg, va_list ap);
void MapChange(const char *mapname);
const char *GetLogFileName(LogType type) const;
LoggingMode GetLoggingMode() const;
private:
void _CloseFile();
void _NewMapFile();
void _PrintToGameLog(const char *fmt, va_list ap);
private:
String m_NrmFileName;
String m_ErrFileName;
String m_CurMapName;
LoggingMode m_Mode;
int m_NrmCurDay;
int m_ErrCurDay;
bool m_ErrMapStart;
bool m_Active;
bool m_DelayedStart;
bool m_DailyPrintHdr;
bool m_InitialState;
};
extern Logger g_Logger;
#endif // _INCLUDE_SOURCEMOD_CLOGGER_H_
+7 -6
View File
@@ -42,6 +42,7 @@
#include "GameConfigs.h"
#include "common_logic.h"
#include "Translator.h"
#include "Logger.h"
CPluginManager g_PluginSys;
HandleType_t g_PluginType = 0;
@@ -844,8 +845,8 @@ void CPluginManager::LoadPluginsFromDir(const char *basedir, const char *localpa
{
char error[256];
libsys->GetPlatformError(error, sizeof(error));
smcore.LogError("[SM] Failure reading from plugins path: %s", localpath);
smcore.LogError("[SM] Platform returned error: %s", error);
g_Logger.LogError("[SM] Failure reading from plugins path: %s", localpath);
g_Logger.LogError("[SM] Platform returned error: %s", error);
return;
}
@@ -990,9 +991,9 @@ LoadRes CPluginManager::_LoadPlugin(CPlugin **aResult, const char *path, bool de
} else {
if (bulletinUrl[0] != '\0')
{
smcore.Log("%s: Known malware detected. See %s for more info, blocking disabled in core.cfg", pPlugin->GetFilename(), bulletinUrl);
g_Logger.LogMessage("%s: Known malware detected. See %s for more info, blocking disabled in core.cfg", pPlugin->GetFilename(), bulletinUrl);
} else {
smcore.Log("%s: Possible malware or illegal plugin detected, blocking disabled in core.cfg", pPlugin->GetFilename());
g_Logger.LogMessage("%s: Possible malware or illegal plugin detected, blocking disabled in core.cfg", pPlugin->GetFilename());
}
}
}
@@ -1094,7 +1095,7 @@ void CPluginManager::LoadAutoPlugin(const char *plugin)
if ((res=_LoadPlugin(&pl, plugin, false, PluginType_MapUpdated, error, sizeof(error))) == LoadRes_Failure)
{
smcore.LogError("[SM] Failed to load plugin \"%s\": %s.", plugin, error);
g_Logger.LogError("[SM] Failed to load plugin \"%s\": %s.", plugin, error);
pl->SetErrorState(
pl->GetStatus() <= Plugin_Created ? Plugin_BadLoad : pl->GetStatus(),
"%s",
@@ -1136,7 +1137,7 @@ void CPluginManager::LoadAll_SecondPass()
error[0] = '\0';
if (!RunSecondPass(pPlugin, error, sizeof(error)))
{
smcore.LogError("[SM] Unable to load plugin \"%s\": %s", pPlugin->GetFilename(), error);
g_Logger.LogError("[SM] Unable to load plugin \"%s\": %s", pPlugin->GetFilename(), error);
pPlugin->SetErrorState(Plugin_Failed, "%s", error);
}
}
+190
View File
@@ -0,0 +1,190 @@
// vim: set ts=4 sw=4 tw=99 noet :
// =============================================================================
// SourceMod
// Copyright (C) 2004-2014 AlliedModders LLC. All rights reserved.
// =============================================================================
//
// This program is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License, version 3.0, as published by the
// Free Software Foundation.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
// details.
//
// You should have received a copy of the GNU General Public License along with
// this program. If not, see <http://www.gnu.org/licenses/>.
//
// As a special exception, AlliedModders LLC gives you permission to link the
// code of this program (as well as its derivative works) to "Half-Life 2," the
// "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
// by the Valve Corporation. You must obey the GNU General Public License in
// all respects for all other code used. Additionally, AlliedModders LLC grants
// this exception to all derivative works. AlliedModders LLC defines further
// exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
// or <http://www.sourcemod.net/license.php>.
#include "ProfileTools.h"
#include <stdarg.h>
ProfileToolManager g_ProfileToolManager;
ProfileToolManager::ProfileToolManager()
: active_(nullptr),
default_(nullptr)
{
}
void
ProfileToolManager::OnSourceModAllInitialized()
{
rootmenu->AddRootConsoleCommand2("prof", "Profiling", this);
}
void
ProfileToolManager::OnSourceModShutdown()
{
rootmenu->RemoveRootConsoleCommand("prof", this);
}
IProfilingTool *
ProfileToolManager::FindToolByName(const char *name)
{
for (size_t i = 0; i < tools_.length(); i++) {
if (strcmp(tools_[i]->Name(), name) == 0)
return tools_[i];
}
return nullptr;
}
static void
render_help(const char *fmt, ...)
{
char buffer[2048];
va_list ap;
va_start(ap, fmt);
smcore.FormatArgs(buffer, sizeof(buffer), fmt, ap);
va_end(ap);
rootmenu->ConsolePrint("%s", buffer);
}
void
ProfileToolManager::StartFromConsole(IProfilingTool *tool)
{
if (active_) {
rootmenu->ConsolePrint("A profile is already active using %s.", active_->Name());
return;
}
active_ = tool;
if (!active_->Start()) {
rootmenu->ConsolePrint("Failed to attach to or start %s.", active_->Name());
active_ = nullptr;
return;
}
g_pSourcePawn2->SetProfilingTool(active_);
g_pSourcePawn2->EnableProfiling();
rootmenu->ConsolePrint("Started profiling with %s.", active_->Name());
default_ = active_;
}
void
ProfileToolManager::OnRootConsoleCommand2(const char *cmdname, const ICommandArgs *args)
{
if (tools_.length() == 0) {
rootmenu->ConsolePrint("No profiling tools are enabled.");
return;
}
if (args->ArgC() >= 3) {
cmdname = args->Arg(2);
if (strcmp(cmdname, "list") == 0) {
rootmenu->ConsolePrint("Profiling tools:");
for (size_t i = 0; i < tools_.length(); i++) {
rootmenu->DrawGenericOption(tools_[i]->Name(), tools_[i]->Description());
}
return;
}
if (strcmp(cmdname, "stop") == 0) {
if (!active_) {
rootmenu->ConsolePrint("No profiler is active.");
return;
}
g_pSourcePawn2->DisableProfiling();
g_pSourcePawn2->SetProfilingTool(nullptr);
active_->Stop(render_help);
active_ = nullptr;
return;
}
if (strcmp(cmdname, "dump") == 0) {
if (active_) {
// if we have an active profiler, dump it
active_->Dump();
return;
}
}
if (args->ArgC() < 4) {
if (strcmp(cmdname, "start") == 0) {
if (!default_) {
default_ = FindToolByName("vprof");
if (!default_ && tools_.length() > 0)
default_ = tools_[0];
if (!default_) {
rootmenu->ConsolePrint("Could not find any profiler to use.");
return;
}
}
StartFromConsole(default_);
return;
}
}
if (args->ArgC() < 4) {
rootmenu->ConsolePrint("You must specify a profiling tool name.");
return;
}
const char *toolname = args->Arg(3);
if (strcmp(cmdname, "start") == 0) {
IProfilingTool *tool = FindToolByName(toolname);
if (!tool) {
rootmenu->ConsolePrint("No tool with the name \"%s\" was found.", toolname);
return;
}
StartFromConsole(tool);
return;
}
if (strcmp(cmdname, "dump") == 0) {
IProfilingTool *tool = FindToolByName(toolname);
if (!tool) {
rootmenu->ConsolePrint("No tool with the name \"%s\" was found.", toolname);
return;
}
tool->Dump();
return;
}
if (strcmp(cmdname, "help") == 0) {
IProfilingTool *tool = FindToolByName(toolname);
if (!tool) {
rootmenu->ConsolePrint("No tool with the name \"%s\" was found.", toolname);
return;
}
tool->RenderHelp(render_help);
return;
}
}
rootmenu->ConsolePrint("Profiling commands:");
rootmenu->DrawGenericOption("list", "List all available profiling tools.");
rootmenu->DrawGenericOption("start", "Start a profile with a given tool.");
rootmenu->DrawGenericOption("stop", "Stop the current profile session.");
rootmenu->DrawGenericOption("dump", "Dumps output from the current profile session.");
rootmenu->DrawGenericOption("help", "Display help text for a profiler.");
}
+87
View File
@@ -0,0 +1,87 @@
// vim: set ts=4 sw=4 tw=99 noet :
// =============================================================================
// SourceMod
// Copyright (C) 2004-2014 AlliedModders LLC. All rights reserved.
// =============================================================================
//
// This program is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License, version 3.0, as published by the
// Free Software Foundation.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
// details.
//
// You should have received a copy of the GNU General Public License along with
// this program. If not, see <http://www.gnu.org/licenses/>.
//
// As a special exception, AlliedModders LLC gives you permission to link the
// code of this program (as well as its derivative works) to "Half-Life 2," the
// "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
// by the Valve Corporation. You must obey the GNU General Public License in
// all respects for all other code used. Additionally, AlliedModders LLC grants
// this exception to all derivative works. AlliedModders LLC defines further
// exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
// or <http://www.sourcemod.net/license.php>.
#ifndef _include_sourcemod_logic_profile_tool_manager_h_
#define _include_sourcemod_logic_profile_tool_manager_h_
#include <sp_vm_api.h>
#include <am-vector.h>
#include <IShareSys.h>
#include <IRootConsoleMenu.h>
#include "common_logic.h"
using namespace SourcePawn;
class ProfileToolManager
: public SMGlobalClass,
public IRootConsoleCommand
{
public:
ProfileToolManager();
// SMGlobalClass
void OnSourceModAllInitialized() KE_OVERRIDE;
void OnSourceModShutdown() KE_OVERRIDE;
// IRootConsoleCommand
void OnRootConsoleCommand2(const char *cmdname, const ICommandArgs *args) KE_OVERRIDE;
void RegisterTool(IProfilingTool *tool) {
tools_.append(tool);
}
bool IsActive() const {
return !!active_;
}
// If we get problems with plugins not being able to balance the profile
// scopes, we should add a safety net that automatically clears any pending
// scopes.
void EnterScope(const char *group, const char *name) {
if (active_)
active_->EnterScope(group, name);
}
void LeaveScope() {
if (active_)
active_->LeaveScope();
}
IProfilingTool *FindToolByName(const char *name);
private:
void StartFromConsole(IProfilingTool *tool);
private:
ke::Vector<IProfilingTool *> tools_;
IProfilingTool *active_;
IProfilingTool *default_;
bool enabled_;
};
extern ProfileToolManager g_ProfileToolManager;
#endif // _include_sourcemod_logic_profile_tool_manager_h_
-516
View File
@@ -1,516 +0,0 @@
/**
* vim: set ts=4 sw=4 tw=99 noet :
* =============================================================================
* SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
* =============================================================================
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, version 3.0, as published by the
* Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*
* As a special exception, AlliedModders LLC gives you permission to link the
* code of this program (as well as its derivative works) to "Half-Life 2," the
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
* by the Valve Corporation. You must obey the GNU General Public License in
* all respects for all other code used. Additionally, AlliedModders LLC grants
* this exception to all derivative works. AlliedModders LLC defines further
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
* or <http://www.sourcemod.net/license.php>.
*
* Version: $Id$
*/
#include "Profiler.h"
#include <ISourceMod.h>
#if defined PLATFORM_POSIX
#include <sys/time.h>
#include <time.h>
#endif
#include <IPluginSys.h>
#include "stringutil.h"
ProfileEngine g_Profiler;
IProfiler *sm_profiler = &g_Profiler;
#if defined PLATFORM_WINDOWS
double WINDOWS_PERFORMANCE_FREQUENCY;
#endif
class EmptyProfiler : public IProfiler
{
public:
void OnNativeBegin(IPluginContext *pContext, sp_native_t *native)
{
}
void OnNativeEnd()
{
}
void OnFunctionBegin(IPluginContext *pContext, const char *name)
{
}
void OnFunctionEnd()
{
}
int OnCallbackBegin(IPluginContext *pContext, sp_public_t *pubfunc)
{
return 0;
}
void OnCallbackEnd(int serial)
{
}
} s_EmptyProfiler;
inline void InitProfPoint(prof_point_t &pt)
{
#if defined PLATFORM_WINDOWS
QueryPerformanceCounter(&pt.value);
#elif defined PLATFORM_POSIX
gettimeofday(&pt.value, NULL);
#endif
pt.is_set = true;
}
ProfileEngine::ProfileEngine()
{
m_serial = 0;
#if defined PLATFORM_WINDOWS
LARGE_INTEGER pf;
if (QueryPerformanceFrequency(&pf))
{
WINDOWS_PERFORMANCE_FREQUENCY = 1.0 / (double)(pf.QuadPart);
}
else
{
WINDOWS_PERFORMANCE_FREQUENCY = -1.0;
}
#endif
if (IsEnabled())
{
InitProfPoint(m_ProfStart);
}
else
{
sm_profiler = &s_EmptyProfiler;
}
}
bool ProfileEngine::IsEnabled()
{
#if defined PLATFORM_WINDOWS
return (WINDOWS_PERFORMANCE_FREQUENCY > 0.0);
#elif defined PLATFORM_POSIX
return true;
#endif
}
inline double DiffProfPoints(const prof_point_t &start, const prof_point_t &end)
{
double seconds;
#if defined PLATFORM_WINDOWS
LONGLONG diff;
diff = end.value.QuadPart - start.value.QuadPart;
seconds = diff * WINDOWS_PERFORMANCE_FREQUENCY;
#elif defined PLATFORM_POSIX
seconds = (double)(end.value.tv_sec - start.value.tv_sec);
if (start.value.tv_usec > end.value.tv_usec)
{
seconds -= 1.0;
seconds += (double)(1000000 - (start.value.tv_usec - end.value.tv_usec)) / 1000000.0;
}
else
{
seconds += (double)(end.value.tv_usec - start.value.tv_usec) / 1000000.0;
}
#endif
return seconds;
}
inline double CalcAtomTime(const prof_atom_t &atom)
{
if (!atom.end.is_set)
{
return atom.base_time;
}
return atom.base_time + DiffProfPoints(atom.start, atom.end);
}
void ProfileEngine::OnNativeBegin(IPluginContext *pContext, sp_native_t *native)
{
PushProfileStack(pContext, SP_PROF_NATIVES, native->name);
}
void ProfileEngine::OnNativeEnd()
{
assert(!m_AtomStack.empty());
assert(m_AtomStack.front().atom_type == SP_PROF_NATIVES);
PopProfileStack(&m_Natives);
}
void ProfileEngine::OnFunctionBegin(IPluginContext *pContext, const char *name)
{
PushProfileStack(pContext, SP_PROF_FUNCTIONS, name);
}
void ProfileEngine::OnFunctionEnd()
{
assert(!m_AtomStack.empty());
assert(m_AtomStack.front().atom_type == SP_PROF_FUNCTIONS);
PopProfileStack(&m_Functions);
}
int ProfileEngine::OnCallbackBegin(IPluginContext *pContext, sp_public_t *pubfunc)
{
PushProfileStack(pContext, SP_PROF_CALLBACKS, pubfunc->name);
return m_serial;
}
void ProfileEngine::OnCallbackEnd(int serial)
{
assert(!m_AtomStack.empty());
/**
* Account for the situation where the JIT discards the
* stack because there was an RTE of sorts.
*/
if (m_AtomStack.front().atom_type != SP_PROF_CALLBACKS
&& m_AtomStack.front().atom_serial != serial)
{
prof_atom_t atom;
double total_time;
/* There was an error, and we need to discard things. */
total_time = 0.0;
while (!m_AtomStack.empty()
&& m_AtomStack.front().atom_type != SP_PROF_CALLBACKS
&& m_AtomStack.front().atom_serial != serial)
{
total_time += CalcAtomTime(m_AtomStack.front());
m_AtomStack.pop();
}
/**
* Now we can end and discard ourselves, without saving the data.
* Since this data is all erroneous anyway, we don't care if it's
* not totally accurate.
*/
assert(!m_AtomStack.empty());
atom = m_AtomStack.front();
m_AtomStack.pop();
/* Note: We don't need to resume ourselves because end is set by Pause(). */
total_time += CalcAtomTime(atom);
ResumeParent(total_time);
return;
}
PopProfileStack(&m_Callbacks);
}
void ProfileEngine::PushProfileStack(IPluginContext *ctx, int type, const char *name)
{
prof_atom_t atom;
PauseParent();
atom.atom_type = type;
atom.base_time = 0.0;
atom.ctx = ctx->GetContext();
atom.name = name;
atom.end.is_set = false;
if (type == SP_PROF_CALLBACKS)
{
atom.atom_serial = ++m_serial;
}
else
{
atom.atom_serial = 0;
}
m_AtomStack.push(atom);
/* Note: We do this after because the stack could grow and skew results */
InitProfPoint(m_AtomStack.front().start);
}
void ProfileEngine::PopProfileStack(ProfileReport *reporter)
{
double total_time;
prof_atom_t &atom = m_AtomStack.front();
/* We're okay to cache our used time. */
InitProfPoint(atom.end);
total_time = CalcAtomTime(atom);
/* Now it's time to save this! This may do a lot of computations which
* is why we've cached the time beforehand.
*/
reporter->SaveAtom(atom);
m_AtomStack.pop();
/* Finally, tell our parent how much time we used. */
ResumeParent(total_time);
}
void ProfileEngine::PauseParent()
{
if (m_AtomStack.empty())
{
return;
}
InitProfPoint(m_AtomStack.front().end);
}
void ProfileEngine::ResumeParent(double addTime)
{
if (m_AtomStack.empty())
{
return;
}
prof_atom_t &atom = m_AtomStack.front();
/* Move its "paused time" to its base (known) time,
* then reset the start/end. Note that since CalcAtomTime()
* reads the base time, we SHOULD NOT use += to add.
*/
atom.base_time = CalcAtomTime(atom);
atom.base_time += addTime;
InitProfPoint(atom.start);
atom.end.is_set = false;
}
void ProfileEngine::Clear()
{
m_Natives.Clear();
m_Callbacks.Clear();
m_Functions.Clear();
InitProfPoint(m_ProfStart);
}
void ProfileEngine::OnSourceModAllInitialized()
{
rootmenu->AddRootConsoleCommand2("profiler", "Profiler commands", this);
}
void ProfileEngine::OnSourceModShutdown()
{
rootmenu->RemoveRootConsoleCommand("profiler", this);
}
void ProfileEngine::OnRootConsoleCommand2(const char *cmdname, const ICommandArgs *command)
{
if (command->ArgC() >= 3)
{
if (strcmp(command->Arg(2), "flush") == 0)
{
FILE *fp;
char path[256];
g_pSM->BuildPath(Path_SM, path, sizeof(path), "logs/profile_%d.xml", (int)time(NULL));
if ((fp = fopen(path, "wt")) == NULL)
{
rootmenu->ConsolePrint("Failed, could not open file for writing: %s", path);
return;
}
GenerateReport(fp);
fclose(fp);
Clear();
rootmenu->ConsolePrint("Profiler report generated as: %s\n", path);
return;
}
else if (strcmp(command->Arg(2), "report") == 0)
{
FILE *fp;
char path[256];
g_pSM->BuildPath(Path_SM, path, sizeof(path), "logs/profile_%d.xml", (int)time(NULL));
if ((fp = fopen(path, "wt")) == NULL)
{
rootmenu->ConsolePrint("Failed, could not open file for writing: %s", path);
return;
}
GenerateReport(fp);
fclose(fp);
rootmenu->ConsolePrint("Profiler report generated as: %s\n", path);
return;
}
else if (strcmp(command->Arg(2), "clear") == 0)
{
Clear();
rootmenu->ConsolePrint("Profiler statistics cleared.\n");
return;
}
}
rootmenu->ConsolePrint("Profiler commands:");
rootmenu->DrawGenericOption("flush", "Flushes statistics to disk and starts over");
rootmenu->DrawGenericOption("report", "Flushes statistics to disk");
rootmenu->DrawGenericOption("clear", "Clears statistics");
}
bool ProfileEngine::GenerateReport(FILE *fp)
{
time_t t;
double total_time;
prof_point_t end_time;
InitProfPoint(end_time);
total_time = DiffProfPoints(m_ProfStart, end_time);
t = time(NULL);
fprintf(fp, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n");
fprintf(fp, "<profile time=\"%d\" uptime=\"%f\">\n", (int)t, total_time);
WriteReport(fp, &m_Natives, "natives");
WriteReport(fp, &m_Callbacks, "callbacks");
WriteReport(fp, &m_Functions, "functions");
fprintf(fp, "</profile>\n");
return true;
}
void ProfileEngine::WriteReport(FILE *fp, ProfileReport *report, const char *name)
{
size_t i, num;
prof_atom_report_t *ar;
char new_name[512];
fprintf(fp, " <report name=\"%s\">\n", name);
num = report->GetNumReports();
for (i = 0; i < num; i++)
{
ar = report->GetReport(i);
strncopy(new_name, ar->atom_name, sizeof(new_name));
UTIL_ReplaceAll(new_name, sizeof(new_name), "<", "&lt;", true);
UTIL_ReplaceAll(new_name, sizeof(new_name), ">", "&gt;", true);
fprintf(fp, " <item name=\"%s\" numcalls=\"%d\" mintime=\"%f\" maxtime=\"%f\" totaltime=\"%f\"/>\n",
new_name,
ar->num_calls,
ar->min_time,
ar->max_time,
ar->total_time);
}
fprintf(fp, " </report>\n");
}
ProfileReport::~ProfileReport()
{
for (size_t i = 0; i < m_Reports.size(); i++)
{
delete m_Reports[i];
}
}
void ProfileReport::Clear()
{
m_ReportLookup.clear();
for (size_t i = 0; i < m_Reports.size(); i++)
{
delete m_Reports[i];
}
m_Reports.clear();
}
size_t ProfileReport::GetNumReports()
{
return m_Reports.size();
}
prof_atom_report_t *ProfileReport::GetReport(size_t i)
{
return m_Reports[i];
}
void ProfileReport::SaveAtom(const prof_atom_t &atom)
{
double atom_time;
char full_name[256];
prof_atom_report_t *report;
if (atom.atom_type == SP_PROF_NATIVES)
{
smcore.strncopy(full_name, atom.name, sizeof(full_name));
}
else
{
IPlugin *pl;
const char *file;
file = "unknown";
if ((pl = pluginsys->FindPluginByContext(atom.ctx)) != NULL)
{
file = pl->GetFilename();
}
smcore.Format(full_name, sizeof(full_name), "%s!%s", file, atom.name);
}
atom_time = CalcAtomTime(atom);
if (!m_ReportLookup.retrieve(full_name, &report))
{
report = new prof_atom_report_t;
smcore.strncopy(report->atom_name, full_name, sizeof(report->atom_name));
report->max_time = atom_time;
report->min_time = atom_time;
report->num_calls = 1;
report->total_time = atom_time;
m_ReportLookup.insert(full_name, report);
m_Reports.push_back(report);
}
else
{
if (atom_time > report->max_time)
{
report->max_time = atom_time;
}
if (atom_time < report->min_time)
{
report->min_time = atom_time;
}
report->num_calls++;
report->total_time += atom_time;
}
}
-136
View File
@@ -1,136 +0,0 @@
/**
* vim: set ts=4 sw=4 tw=99 noet :
* =============================================================================
* SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
* =============================================================================
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, version 3.0, as published by the
* Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*
* As a special exception, AlliedModders LLC gives you permission to link the
* code of this program (as well as its derivative works) to "Half-Life 2," the
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
* by the Valve Corporation. You must obey the GNU General Public License in
* all respects for all other code used. Additionally, AlliedModders LLC grants
* this exception to all derivative works. AlliedModders LLC defines further
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
* or <http://www.sourcemod.net/license.php>.
*
* Version: $Id$
*/
#ifndef _INCLUDE_SOURCEMOD_PLUGIN_PROFILER_H_
#define _INCLUDE_SOURCEMOD_PLUGIN_PROFILER_H_
#include <sp_vm_api.h>
#include <sm_platform.h>
#include <sh_vector.h>
#include <sh_stack.h>
#include <sm_namehashset.h>
#include <stdio.h>
#include "common_logic.h"
#include <IRootConsoleMenu.h>
using namespace SourcePawn;
using namespace SourceHook;
struct prof_point_t
{
#if defined PLATFORM_WINDOWS
LARGE_INTEGER value;
#elif defined PLATFORM_POSIX
struct timeval value;
#endif
bool is_set;
};
struct prof_atom_t
{
int atom_type; /* Type of object we're profiling */
int atom_serial; /* Serial number, if appropriate */
sp_context_t *ctx; /* Plugin context. */
const char *name; /* Name of the function */
prof_point_t start; /* Start time */
prof_point_t end; /* End time */
double base_time; /* Known time from children or pausing. */
};
struct prof_atom_report_t
{
char atom_name[256]; /* Full name to shove to logs */
double total_time; /* Total time spent executing, in s */
unsigned int num_calls; /* Number of invocations */
double min_time; /* Min time spent in one call, in s */
double max_time; /* Max time spent in one call, in s */
static inline bool matches(const char *name, const prof_atom_report_t *report)
{
return strcmp(report->atom_name, name) == 0;
}
};
class ProfileReport
{
public:
~ProfileReport();
public:
void SaveAtom(const prof_atom_t &atom);
size_t GetNumReports();
prof_atom_report_t *GetReport(size_t i);
void Clear();
private:
NameHashSet<prof_atom_report_t *> m_ReportLookup;
CVector<prof_atom_report_t *> m_Reports;
};
class ProfileEngine :
public SMGlobalClass,
public IRootConsoleCommand,
public IProfiler
{
public:
ProfileEngine();
public:
bool IsEnabled();
bool GenerateReport(FILE *fp);
void Clear();
public: //SMGlobalClass
void OnSourceModAllInitialized();
void OnSourceModShutdown();
public: //IRootConsoleCommand
void OnRootConsoleCommand2(const char *cmdname, const ICommandArgs *command);
public: //IProfiler
void OnNativeBegin(IPluginContext *pContext, sp_native_t *native);
void OnNativeEnd() ;
void OnFunctionBegin(IPluginContext *pContext, const char *name);
void OnFunctionEnd();
int OnCallbackBegin(IPluginContext *pContext, sp_public_t *pubfunc);
void OnCallbackEnd(int serial);
private:
void PushProfileStack(IPluginContext *ctx, int type, const char *name);
void PopProfileStack(ProfileReport *reporter);
void PauseParent();
void ResumeParent(double addTime);
void WriteReport(FILE *fp, ProfileReport *report, const char *name);
private:
CStack<prof_atom_t> m_AtomStack;
ProfileReport m_Callbacks;
ProfileReport m_Functions;
ProfileReport m_Natives;
int m_serial;
prof_point_t m_ProfStart;
};
extern IProfiler *sm_profiler;
#endif //_INCLUDE_SOURCEMOD_PLUGIN_PROFILER_H_
+2 -2
View File
@@ -375,7 +375,7 @@ PassRef<Native> ShareSystem::AddNativeToCache(CNativeOwner *pOwner, const sp_nat
if (i.found())
return NULL;
Ref<Native> entry = Newborn<Native>(new Native(pOwner, ntv));
Ref<Native> entry = new Native(pOwner, ntv);
m_NtvCache.insert(ntv->name, entry);
return entry;
}
@@ -415,7 +415,7 @@ PassRef<Native> ShareSystem::AddFakeNative(IPluginFunction *pFunc, const char *n
CNativeOwner *owner = g_PluginSys.GetPluginByCtx(fake->ctx->GetContext());
entry = Newborn<Native>(new Native(owner, fake.take()));
entry = new Native(owner, fake.take());
m_NtvCache.insert(name, entry);
return entry;
+1 -1
View File
@@ -1077,7 +1077,7 @@ const char *TextParsers::GetSMCErrorString(SMCError err)
NULL,
"Stream failed to open",
"Stream returned read error",
NULL,
"Callback error",
"Un-quoted section has invalid tokens",
"Section declared without header",
"Section declared with unknown tokens",
+21 -13
View File
@@ -96,11 +96,11 @@ void CPhraseFile::ParseWarning(const char *message, ...)
if (!m_FileLogged)
{
smcore.LogError("[SM] Warning(s) encountered in translation file \"%s\"", m_File.c_str());
logger->LogError("[SM] Warning(s) encountered in translation file \"%s\"", m_File.c_str());
m_FileLogged = true;
}
smcore.LogError("[SM] %s", buffer);
logger->LogError("[SM] %s", buffer);
}
void CPhraseFile::ReparseFile()
@@ -142,8 +142,8 @@ void CPhraseFile::ReparseFile()
msg = m_ParseError.c_str();
}
smcore.LogError("[SM] Fatal error encountered parsing translation file \"%s\"", m_File.c_str());
smcore.LogError("[SM] Error (line %d, column %d): %s", states.line, states.col, msg);
logger->LogError("[SM] Fatal error encountered parsing translation file \"%s\"", m_File.c_str());
logger->LogError("[SM] Error (line %d, column %d): %s", states.line, states.col, msg);
}
const char *code;
@@ -175,10 +175,10 @@ void CPhraseFile::ReparseFile()
msg = m_ParseError.c_str();
}
smcore.LogError("[SM] Fatal error encountered parsing translation file \"%s/%s\"",
logger->LogError("[SM] Fatal error encountered parsing translation file \"%s/%s\"",
code,
m_File.c_str());
smcore.LogError("[SM] Error (line %d, column %d): %s",
logger->LogError("[SM] Error (line %d, column %d): %s",
states.line,
states.col,
msg);
@@ -831,13 +831,13 @@ void Translator::RebuildLanguageDatabase()
str_err = m_CustomError.c_str();
}
smcore.LogError("[SM] Failed to parse language header file: \"%s\"", path);
smcore.LogError("[SM] Parse error (line %d, column %d): %s", states.line, states.col, str_err);
logger->LogError("[SM] Failed to parse language header file: \"%s\"", path);
logger->LogError("[SM] Parse error (line %d, column %d): %s", states.line, states.col, str_err);
}
if (!m_LCodeLookup.retrieve(m_InitialLang, &m_ServerLang))
{
smcore.LogError("Server language was set to bad language \"%s\" -- reverting to English", m_InitialLang);
logger->LogError("Server language was set to bad language \"%s\" -- reverting to English", m_InitialLang);
smcore.strncopy(m_InitialLang, "en", sizeof(m_InitialLang));
m_ServerLang = SOURCEMOD_LANGUAGE_ENGLISH;
@@ -845,7 +845,7 @@ void Translator::RebuildLanguageDatabase()
if (!m_Languages.size())
{
smcore.LogError("[SM] Fatal error, no languages found! Translation will not work.");
logger->LogError("[SM] Fatal error, no languages found! Translation will not work.");
}
for (size_t i=0; i<m_Files.size(); i++)
@@ -872,7 +872,7 @@ SMCResult Translator::ReadSMC_NewSection(const SMCStates *states, const char *na
if (!m_InLanguageSection)
{
smcore.LogError("[SM] Warning: Unrecognized section \"%s\" in languages.cfg", name);
logger->LogError("[SM] Warning: Unrecognized section \"%s\" in languages.cfg", name);
}
return SMCResult_Continue;
@@ -887,6 +887,14 @@ SMCResult Translator::ReadSMC_LeavingSection(const SMCStates *states)
SMCResult Translator::ReadSMC_KeyValue(const SMCStates *states, const char *key, const char *value)
{
size_t len = strlen(key);
if (len >= sizeof(((Language *)0)->m_code2))
{
logger->LogError("[SM] Warning encountered parsing languages.cfg file.");
logger->LogError("[SM] Invalid language code \"%s\" is too long.", key);
}
AddLanguage(key, value);
return SMCResult_Continue;
@@ -1025,11 +1033,11 @@ bool CoreTranslate(char *buffer, size_t maxlength, const char *format, unsigned
{
if (fail_phrase != NULL)
{
smcore.LogError("[SM] Could not find core phrase: %s", fail_phrase);
logger->LogError("[SM] Could not find core phrase: %s", fail_phrase);
}
else
{
smcore.LogError("[SM] Unknown fatal error while translating a core phrase.");
logger->LogError("[SM] Unknown fatal error while translating a core phrase.");
}
return false;
+1 -1
View File
@@ -54,7 +54,7 @@ enum PhraseParseState
struct Language
{
char m_code2[4];
char m_code2[32];
int m_CanonicalName;
};
+15 -4
View File
@@ -35,7 +35,6 @@
#include <stdarg.h>
#include "common_logic.h"
#include "TextParsers.h"
#include "Profiler.h"
#include "sm_crc32.h"
#include "MemoryUtils.h"
#include "stringutil.h"
@@ -50,6 +49,8 @@
#include "ExtensionSys.h"
#include "ForwardSys.h"
#include "AdminCache.h"
#include "ProfileTools.h"
#include "Logger.h"
sm_core_t smcore;
IHandleSys *handlesys = &g_HandleSys;
@@ -72,6 +73,9 @@ ISourcePawnEngine *g_pSourcePawn;
ISourcePawnEngine2 *g_pSourcePawn2;
CNativeOwner g_CoreNatives;
IScriptManager *scripts = &g_PluginSys;
IExtensionSys *extsys = &g_Extensions;
ILogger *logger = &g_Logger;
IMenuManager *menus;
static void AddCorePhraseFile(const char *filename)
{
@@ -104,16 +108,20 @@ static void DumpHandles(void (*dumpfn)(const char *fmt, ...))
g_HandleSys.Dump(dumpfn);
}
static void DumpAdminCache(FILE *f)
static bool DumpAdminCache(const char *filename)
{
g_Admins.DumpCache(f);
return g_Admins.DumpCache(filename);
}
static void RegisterProfiler(IProfilingTool *tool)
{
g_ProfileToolManager.RegisterTool(tool);
}
static sm_logic_t logic =
{
NULL,
g_pThreader,
sm_profiler,
&g_Translator,
stristr,
CoreTranslate,
@@ -128,6 +136,7 @@ static sm_logic_t logic =
AddNatives,
DumpHandles,
DumpAdminCache,
RegisterProfiler,
&g_PluginSys,
&g_ShareSys,
&g_Extensions,
@@ -135,6 +144,7 @@ static sm_logic_t logic =
&g_Forwards,
&g_Admins,
NULL,
&g_Logger,
-1.0f
};
@@ -153,6 +163,7 @@ static void logic_init(const sm_core_t* core, sm_logic_t* _logic)
timersys = core->timersys;
playerhelpers = core->playerhelpers;
gamehelpers = core->gamehelpers;
menus = core->menus;
g_pSourcePawn = *core->spe1;
g_pSourcePawn2 = *core->spe2;
SMGlobalClass::head = core->listeners;
+3
View File
@@ -53,6 +53,9 @@ extern IPlayerManager *playerhelpers;
extern IAdminSystem *adminsys;
extern IGameHelpers *gamehelpers;
extern IScriptManager *scripts;
extern IExtensionSys *extsys;
extern ILogger *logger;
extern IMenuManager *menus;
#endif /* _INCLUDE_SOURCEMOD_COMMON_LOGIC_H_ */
+95
View File
@@ -0,0 +1,95 @@
/**
* vim: set ts=4 sw=4 tw=99 noet :
* =============================================================================
* SourceMod
* Copyright (C) 2004-2014 AlliedModders LLC. All rights reserved.
* =============================================================================
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, version 3.0, as published by the
* Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*
* As a special exception, AlliedModders LLC gives you permission to link the
* code of this program (as well as its derivative works) to "Half-Life 2," the
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
* by the Valve Corporation. You must obey the GNU General Public License in
* all respects for all other code used. Additionally, AlliedModders LLC grants
* this exception to all derivative works. AlliedModders LLC defines further
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
* or <http://www.sourcemod.net/license.php>.
*
* Version: $Id$
*/
#ifndef _include_sourcemod_handle_helpers_h_
#define _include_sourcemod_handle_helpers_h_
#include "common_logic.h"
// T must be a pointer type.
template <typename T>
class OpenHandle
{
public:
OpenHandle()
: t_(),
error_(HandleError_None)
{}
explicit OpenHandle(T *t)
: t_(t),
error_(HandleError_None)
{}
OpenHandle(const OpenHandle &other)
: t_(other.t_),
error_(other.error_)
{}
OpenHandle(IPluginContext *cx, Handle_t handle, HandleType_t type)
: t_(NULL)
{
HandleSecurity sec(cx->GetIdentity(), g_pCoreIdent);
error_ = handlesys->ReadHandle(handle, type, &sec, (void **)&t_);
if (error_ != HandleError_None)
cx->ThrowNativeError("invalid handle %x (error: %d)", handle, error_);
}
bool Ok() const {
return t_ && error_ == HandleError_None;
}
operator T *() const {
assert(Ok());
return t_;
}
T *operator *() const {
assert(Ok());
return t_;
}
T *operator ->() const {
assert(Ok());
return t_;
}
OpenHandle &operator =(T *t) {
t_ = t;
error_ = HandleError_None;
return *this;
}
OpenHandle &operator =(const OpenHandle &other) {
t_ = other.t_;
error_ = other.error_;
return *this;
}
private:
T *t_;
HandleError error_;
};
#endif // _include_sourcemod_handle_helpers_h_
+29 -8
View File
@@ -52,7 +52,7 @@ using namespace SourceHook;
* Add 1 to the RHS of this expression to bump the intercom file
* This is to prevent mismatching core/logic binaries
*/
#define SM_LOGIC_MAGIC (0x0F47C0DE - 28)
#define SM_LOGIC_MAGIC (0x0F47C0DE - 29)
#if defined SM_LOGIC
class IVEngineServer
@@ -83,6 +83,7 @@ class IFileSystem_Logic
public:
virtual const char *FindFirstEx(const char *pWildCard, const char *pPathID, FileFindHandle_t *pHandle) = 0;
virtual const char *FindNext(FileFindHandle_t handle) = 0;
virtual bool FindIsDirectory(FileFindHandle_t handle) = 0;
virtual void FindClose(FileFindHandle_t handle) = 0;
virtual FileHandle_t Open(const char *pFileName, const char *pOptions, const char *pathID = 0) = 0;
virtual void Close(FileHandle_t file) = 0;
@@ -90,6 +91,17 @@ public:
virtual bool EndOfFile(FileHandle_t file) = 0;
virtual bool FileExists(const char *pFileName, const char *pPathID = 0) = 0;
virtual unsigned int Size(const char *pFileName, const char *pPathID = 0) = 0;
virtual int Read(void* pOutput, int size, FileHandle_t file) = 0;
virtual int Write(void const* pInput, int size, FileHandle_t file) = 0;
virtual void Seek(FileHandle_t file, int post, int seekType) = 0;
virtual unsigned int Tell(FileHandle_t file) = 0;
virtual int FPrint(FileHandle_t file, const char *pData) = 0;
virtual void Flush(FileHandle_t file) = 0;
virtual bool IsOk(FileHandle_t file) = 0;
virtual void RemoveFile(const char *pRelativePath, const char *pathID = 0) = 0;
virtual void RenameFile(char const *pOldPath, char const *pNewPath, const char *pathID = 0) = 0;
virtual bool IsDirectory(const char *pFileName, const char *pathID = 0) = 0;
virtual void CreateDirHierarchy(const char *path, const char *pathID = 0) = 0;
};
namespace SourceMod
@@ -108,6 +120,7 @@ namespace SourceMod
class IPhraseCollection;
class ITranslator;
class IGameConfig;
class IMenuManager;
}
class IVEngineServer;
@@ -211,6 +224,15 @@ public:
virtual void AddRawDependency(IExtension *myself, IdentityToken_t *token, void *iface) = 0;
virtual const CVector<IExtension *> *ListExtensions() = 0;
virtual void FreeExtensionList(const CVector<IExtension *> *list) = 0;
virtual void CallOnCoreMapEnd() = 0;
};
class ILogger
{
public:
virtual void LogMessage(const char *msg, ...) = 0;
virtual void LogError(const char *msg, ...) = 0;
virtual void LogFatal(const char *msg, ...) = 0;
};
class AutoPluginList
@@ -267,19 +289,17 @@ struct sm_core_t
ITimerSystem *timersys;
IPlayerManager *playerhelpers;
IGameHelpers *gamehelpers;
IMenuManager *menus;
ISourcePawnEngine **spe1;
ISourcePawnEngine2 **spe2;
/* Functions */
ConVar * (*FindConVar)(const char*);
unsigned int (*strncopy)(char*, const char*, size_t);
char * (*TrimWhitespace)(char *, size_t &);
void (*LogError)(const char*, ...);
void (*LogFatal)(const char*, ...);
void (*Log)(const char*, ...);
void (*LogToFile)(FILE *fp, const char*, ...);
void (*LogToGame)(const char *message);
void (*ConPrint)(const char *message);
const char * (*GetCvarString)(ConVar*);
bool (*GetCvarBool)(ConVar*);
size_t (*Format)(char*, size_t, const char*, ...);
size_t (*FormatArgs)(char*, size_t, const char*,va_list ap);
bool (*gnprintf)(char *, size_t, const char *, IPhraseCollection *, void **,
@@ -317,7 +337,6 @@ struct sm_logic_t
{
SMGlobalClass *head;
IThreader *threader;
IProfiler *profiler;
ITranslator *translator;
const char *(*stristr)(const char *, const char *);
bool (*CoreTranslate)(char *, size_t, const char *, unsigned int, size_t *, ...);
@@ -326,12 +345,13 @@ struct sm_logic_t
char *(*ReplaceEx)(char *, size_t, const char *, size_t, const char *, size_t, bool);
size_t (*DecodeHexString)(unsigned char *, size_t, const char *);
IGameConfig * (*GetCoreGameConfig)();
bool (*OnLogPrint)(const char *msg); // true to supercede
bool (*OnLogPrint)(const char *msg); // true to supersede
IDebugListener *debugger;
void (*GenerateError)(IPluginContext *, cell_t, int, const char *, ...);
void (*AddNatives)(sp_nativeinfo_t *natives);
void (*DumpHandles)(void (*dumpfn)(const char *fmt, ...));
void (*DumpAdminCache)(FILE *);
bool (*DumpAdminCache)(const char *filename);
void (*RegisterProfiler)(IProfilingTool *tool);
IScriptManager *scripts;
IShareSys *sharesys;
IExtensionSys *extsys;
@@ -339,6 +359,7 @@ struct sm_logic_t
IForwardManager *forwardsys;
IAdminSystem *adminsys;
IdentityToken_t *core_ident;
ILogger *logger;
float sentinel;
};
+22
View File
@@ -582,5 +582,27 @@ REGISTER_NATIVES(cellArrayNatives)
{"CloneArray", CloneArray},
{"FindStringInArray", FindStringInArray},
{"FindValueInArray", FindValueInArray},
// Transitional syntax support.
{"ArrayList.ArrayList", CreateArray},
{"ArrayList.Clear", ClearArray},
{"ArrayList.Length.get", GetArraySize},
{"ArrayList.Resize", ResizeArray},
{"ArrayList.Get", GetArrayCell},
{"ArrayList.GetString", GetArrayString},
{"ArrayList.GetArray", GetArrayArray},
{"ArrayList.Push", PushArrayCell},
{"ArrayList.PushString", PushArrayString},
{"ArrayList.PushArray", PushArrayArray},
{"ArrayList.Set", SetArrayCell},
{"ArrayList.SetString", SetArrayString},
{"ArrayList.SetArray", SetArrayArray},
{"ArrayList.Erase", RemoveFromArray},
{"ArrayList.ShiftUp", ShiftArrayUp},
{"ArrayList.SwapAt", SwapArrayItems},
{"ArrayList.Clone", CloneArray},
{"ArrayList.FindString", FindStringInArray},
{"ArrayList.FindValue", FindValueInArray},
{NULL, NULL},
};
+87 -2
View File
@@ -1,8 +1,8 @@
/**
* vim: set ts=4 :
* vim: set ts=4 sw=4 tw=99 noet :
* =============================================================================
* SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
* Copyright (C) 2004-2014 AlliedModders LLC. All rights reserved.
* =============================================================================
*
* This program is free software; you can redistribute it and/or modify it under
@@ -32,6 +32,7 @@
#include <stdlib.h>
#include "common_logic.h"
#include "CellArray.h"
#include "handle_helpers.h"
HandleType_t htCellStack;
@@ -293,6 +294,79 @@ static cell_t IsStackEmpty(IPluginContext *pContext, const cell_t *params)
return 0;
}
static cell_t ArrayStack_Pop(IPluginContext *pContext, const cell_t *params)
{
OpenHandle<CellArray> array(pContext, params[1], htCellStack);
if (!array.Ok())
return 0;
if (array->size() == 0)
return pContext->ThrowNativeError("stack is empty");
cell_t *blk = array->at(array->size() - 1);
cell_t idx = (size_t)params[2];
cell_t rval;
if (params[3] == 0) {
if (idx >= array->blocksize())
return pContext->ThrowNativeError("Invalid block %d (blocksize: %d)", idx, array->blocksize());
rval = blk[idx];
} else {
if (idx >= array->blocksize() * 4)
return pContext->ThrowNativeError("Invalid byte %d (blocksize: %d bytes)", idx, array->blocksize() * 4);
rval = (cell_t)*((char *)blk + idx);
}
array->remove(array->size() - 1);
return rval;
}
static cell_t ArrayStack_PopString(IPluginContext *pContext, const cell_t *params)
{
OpenHandle<CellArray> array(pContext, params[1], htCellStack);
if (!array.Ok())
return 0;
if (array->size() == 0)
return pContext->ThrowNativeError("stack is empty");
size_t idx = array->size() - 1;
cell_t *blk = array->at(idx);
cell_t *pWritten;
pContext->LocalToPhysAddr(params[4], &pWritten);
size_t numWritten;
pContext->StringToLocalUTF8(params[2], params[3], (char *)blk, &numWritten);
*pWritten = (cell_t)numWritten;
array->remove(idx);
return 1;
}
static cell_t ArrayStack_PopArray(IPluginContext *pContext, const cell_t *params)
{
OpenHandle<CellArray> array(pContext, params[1], htCellStack);
if (!array.Ok())
return 0;
if (array->size() == 0)
return pContext->ThrowNativeError("stack is empty");
cell_t *addr;
pContext->LocalToPhysAddr(params[2], &addr);
size_t idx = array->size() - 1;
cell_t *blk = array->at(idx);
size_t indexes = array->blocksize();
if (params[3] != -1 && (size_t)params[3] <= array->blocksize())
indexes = params[3];
memcpy(addr, blk, sizeof(cell_t) * indexes);
array->remove(idx);
return 0;
}
REGISTER_NATIVES(cellStackNatives)
{
{"CreateStack", CreateStack},
@@ -303,5 +377,16 @@ REGISTER_NATIVES(cellStackNatives)
{"PushStackArray", PushStackArray},
{"PushStackCell", PushStackCell},
{"PushStackString", PushStackString},
// Transitional syntax support.
{"ArrayStack.ArrayStack", CreateStack},
{"ArrayStack.Pop", ArrayStack_Pop},
{"ArrayStack.PopString", ArrayStack_PopString},
{"ArrayStack.PopArray", ArrayStack_PopArray},
{"ArrayStack.Push", PushStackCell},
{"ArrayStack.PushString", PushStackString},
{"ArrayStack.PushArray", PushStackArray},
{"ArrayStack.Empty.get", IsStackEmpty},
{NULL, NULL},
};
+21 -3
View File
@@ -163,7 +163,7 @@ private:
cell_t data_;
};
struct CellTrie : public ke::Refcounted<CellTrie>
struct CellTrie
{
StringHashMap<Entry> map;
};
@@ -204,8 +204,7 @@ public: //IHandleTypeDispatch
{
if (type == htCellTrie)
{
CellTrie *pTrie = (CellTrie *)object;
pTrie->Release();
delete (CellTrie *)object;
} else {
TrieSnapshot *snapshot = (TrieSnapshot *)object;
delete snapshot;
@@ -646,9 +645,28 @@ REGISTER_NATIVES(trieNatives)
{"SetTrieString", SetTrieString},
{"SetTrieValue", SetTrieValue},
{"GetTrieSize", GetTrieSize},
{"CreateTrieSnapshot", CreateTrieSnapshot},
{"TrieSnapshotLength", TrieSnapshotLength},
{"TrieSnapshotKeyBufferSize", TrieSnapshotKeyBufferSize},
{"GetTrieSnapshotKey", GetTrieSnapshotKey},
// Transitional syntax support.
{"StringMap.StringMap", CreateTrie},
{"StringMap.Clear", ClearTrie},
{"StringMap.GetArray", GetTrieArray},
{"StringMap.GetString", GetTrieString},
{"StringMap.GetValue", GetTrieValue},
{"StringMap.Remove", RemoveFromTrie},
{"StringMap.SetArray", SetTrieArray},
{"StringMap.SetString", SetTrieString},
{"StringMap.SetValue", SetTrieValue},
{"StringMap.Size.get", GetTrieSize},
{"StringMap.Snapshot", CreateTrieSnapshot},
{"StringMapSnapshot.Length.get", TrieSnapshotLength},
{"StringMapSnapshot.KeyBufferSize", TrieSnapshotKeyBufferSize},
{"StringMapSnapshot.GetKey", GetTrieSnapshotKey},
{NULL, NULL},
};
+41 -38
View File
@@ -32,14 +32,14 @@
#include <time.h>
#include <string.h>
#include <stdlib.h>
#include "sm_stringutil.h"
#include "sm_globals.h"
#include "sourcemod.h"
#include "LibrarySys.h"
#include "TimerSys.h"
#include "common_logic.h"
#include "Logger.h"
#include <ISourceMod.h>
#include <ITranslator.h>
#include <sourcehook.h>
#include <sh_memory.h>
#include "logic_bridge.h"
#if defined PLATFORM_WINDOWS
#include <windows.h>
@@ -50,9 +50,11 @@
#endif
HandleType_t g_PlIter;
ConVar sm_datetime_format("sm_datetime_format", "%m/%d/%Y - %H:%M:%S", 0, "Default formatting time rules");
IForward *g_OnLogAction = NULL;
static ConVar *sm_datetime_format = NULL;
class CoreNativeHelpers :
public SMGlobalClass,
public IHandleTypeDispatch
@@ -75,6 +77,8 @@ public:
Param_Cell,
Param_Cell,
Param_String);
sm_datetime_format = smcore.FindConVar("sm_datetime_format");
}
void OnHandleDestroy(HandleType_t type, void *object)
{
@@ -119,14 +123,14 @@ void LogAction(Handle_t hndl, int type, int client, int target, const char *mess
g_Logger.LogMessage("[%s] %s", logtag, message);
}
static cell_t ThrowError(IPluginContext *pContext, const cell_t *params)
static cell_t ThrowError(IPluginContext *pContext, const cell_t *params)
{
char buffer[512];
g_SourceMod.SetGlobalTarget(SOURCEMOD_SERVER_LANGUAGE);
g_pSM->SetGlobalTarget(SOURCEMOD_SERVER_LANGUAGE);
g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 1);
g_pSM->FormatString(buffer, sizeof(buffer), pContext, params, 1);
if (pContext->GetLastNativeError() == SP_ERROR_NONE)
{
@@ -138,7 +142,7 @@ static cell_t ThrowError(IPluginContext *pContext, const cell_t *params)
static cell_t GetTime(IPluginContext *pContext, const cell_t *params)
{
time_t t = GetAdjustedTime();
time_t t = g_pSM->GetAdjustedTime();
cell_t *addr;
pContext->LocalToPhysAddr(params[1], &addr);
@@ -168,14 +172,14 @@ static cell_t FormatTime(IPluginContext *pContext, const cell_t *params)
if (format == NULL)
{
format = const_cast<char *>(sm_datetime_format.GetString());
format = const_cast<char *>(smcore.GetCvarString(sm_datetime_format));
}
#if defined SUBPLATFORM_SECURECRT
_invalid_parameter_handler handler = _set_invalid_parameter_handler(_ignore_invalid_parameter);
#endif
time_t t = (params[4] == -1) ? GetAdjustedTime() : (time_t)params[4];
time_t t = (params[4] == -1) ? g_pSM->GetAdjustedTime() : (time_t)params[4];
size_t written = strftime(buffer, params[2], format, localtime(&t));
#if defined SUBPLATFORM_SECURECRT
@@ -384,7 +388,7 @@ static cell_t SetFailState(IPluginContext *pContext, const cell_t *params)
{
char buffer[2048];
g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 1);
g_pSM->FormatString(buffer, sizeof(buffer), pContext, params, 1);
if (pContext->GetLastNativeError() != SP_ERROR_NONE)
{
pPlugin->SetErrorState(Plugin_Error, "%s", str);
@@ -433,14 +437,14 @@ static cell_t AutoExecConfig(IPluginContext *pContext, const cell_t *params)
static char temp_file[PLATFORM_MAX_PATH];
char *ptr;
g_LibSys.GetFileFromPath(temp_str, sizeof(temp_str), plugin->GetFilename());
libsys->GetFileFromPath(temp_str, sizeof(temp_str), plugin->GetFilename());
if ((ptr = strstr(temp_str, ".smx")) != NULL)
{
*ptr = '\0';
}
/* We have the raw filename! */
UTIL_Format(temp_file, sizeof(temp_file), "plugin.%s", temp_str);
g_pSM->Format(temp_file, sizeof(temp_file), "plugin.%s", temp_str);
cfg = temp_file;
}
@@ -506,8 +510,8 @@ static cell_t LibraryExists(IPluginContext *pContext, const cell_t *params)
static cell_t sm_LogAction(IPluginContext *pContext, const cell_t *params)
{
char buffer[2048];
g_SourceMod.SetGlobalTarget(SOURCEMOD_SERVER_LANGUAGE);
g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 3);
g_pSM->SetGlobalTarget(SOURCEMOD_SERVER_LANGUAGE);
g_pSM->FormatString(buffer, sizeof(buffer), pContext, params, 3);
if (pContext->GetLastNativeError() != SP_ERROR_NONE)
{
@@ -527,7 +531,7 @@ static cell_t LogToFile(IPluginContext *pContext, const cell_t *params)
pContext->LocalToString(params[1], &file);
char path[PLATFORM_MAX_PATH];
g_SourceMod.BuildPath(Path_Game, path, sizeof(path), "%s", file);
g_pSM->BuildPath(Path_Game, path, sizeof(path), "%s", file);
FILE *fp = fopen(path, "at");
if (!fp)
@@ -536,8 +540,8 @@ static cell_t LogToFile(IPluginContext *pContext, const cell_t *params)
}
char buffer[2048];
g_SourceMod.SetGlobalTarget(SOURCEMOD_SERVER_LANGUAGE);
g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2);
g_pSM->SetGlobalTarget(SOURCEMOD_SERVER_LANGUAGE);
g_pSM->FormatString(buffer, sizeof(buffer), pContext, params, 2);
if (pContext->GetLastNativeError() != SP_ERROR_NONE)
{
@@ -560,7 +564,7 @@ static cell_t LogToFileEx(IPluginContext *pContext, const cell_t *params)
pContext->LocalToString(params[1], &file);
char path[PLATFORM_MAX_PATH];
g_SourceMod.BuildPath(Path_Game, path, sizeof(path), "%s", file);
g_pSM->BuildPath(Path_Game, path, sizeof(path), "%s", file);
FILE *fp = fopen(path, "at");
if (!fp)
@@ -569,8 +573,8 @@ static cell_t LogToFileEx(IPluginContext *pContext, const cell_t *params)
}
char buffer[2048];
g_SourceMod.SetGlobalTarget(SOURCEMOD_SERVER_LANGUAGE);
g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2);
g_pSM->SetGlobalTarget(SOURCEMOD_SERVER_LANGUAGE);
g_pSM->FormatString(buffer, sizeof(buffer), pContext, params, 2);
if (pContext->GetLastNativeError() != SP_ERROR_NONE)
{
@@ -653,10 +657,10 @@ static cell_t RequireFeature(IPluginContext *pContext, const cell_t *params)
char default_message[255];
SMPlugin *pPlugin = scripts->FindPluginByContext(pContext->GetContext());
g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 3);
g_pSM->FormatString(buffer, sizeof(buffer), pContext, params, 3);
if (pContext->GetLastNativeError() != SP_ERROR_NONE || buffer[0] == '\0')
{
UTIL_Format(default_message, sizeof(default_message), "Feature \"%s\" not available", name);
g_pSM->Format(default_message, sizeof(default_message), "Feature \"%s\" not available", name);
msg = default_message;
}
pPlugin->SetErrorState(Plugin_Error, "%s", msg);
@@ -743,19 +747,19 @@ static cell_t StoreToAddress(IPluginContext *pContext, const cell_t *params)
REGISTER_NATIVES(coreNatives)
{
{"AutoExecConfig", AutoExecConfig},
{"GetPluginFilename", GetPluginFilename},
{"GetPluginInfo", GetPluginInfo},
{"GetPluginIterator", GetPluginIterator},
{"GetPluginStatus", GetPluginStatus},
{"GetSysTickCount", GetSysTickCount},
{"ThrowError", ThrowError},
{"GetTime", GetTime},
{"IsPluginDebugging", IsPluginDebugging},
{"FormatTime", FormatTime},
{"GetPluginIterator", GetPluginIterator},
{"MorePlugins", MorePlugins},
{"ReadPlugin", ReadPlugin},
{"ThrowError", ThrowError},
{"GetPluginStatus", GetPluginStatus},
{"GetPluginFilename", GetPluginFilename},
{"IsPluginDebugging", IsPluginDebugging},
{"GetPluginInfo", GetPluginInfo},
{"SetFailState", SetFailState},
{"FormatTime", FormatTime},
{"GetSysTickCount", GetSysTickCount},
{"AutoExecConfig", AutoExecConfig},
{"MarkNativeAsOptional", MarkNativeAsOptional},
{"RegPluginLibrary", RegPluginLibrary},
{"LibraryExists", LibraryExists},
@@ -770,5 +774,4 @@ REGISTER_NATIVES(coreNatives)
{"LoadFromAddress", LoadFromAddress},
{"StoreToAddress", StoreToAddress},
{NULL, NULL},
};
};
+82 -7
View File
@@ -289,14 +289,20 @@ private:
Handle_t m_MyHandle;
};
enum AsyncCallbackMode {
ACM_Old,
ACM_New
};
class TConnectOp : public IDBThreadOperation
{
public:
TConnectOp(IPluginFunction *func, IDBDriver *driver, const char *_dbname, cell_t data)
TConnectOp(IPluginFunction *func, IDBDriver *driver, const char *_dbname, AsyncCallbackMode acm, cell_t data)
{
m_pFunction = func;
m_pDriver = driver;
m_pDatabase = NULL;
m_ACM = acm;
m_Data = data;
error[0] = '\0';
strncopy(dbname, _dbname, sizeof(dbname));
@@ -328,7 +334,8 @@ public:
{
m_pDatabase->Close();
}
m_pFunction->PushCell(BAD_HANDLE);
if (m_ACM == ACM_Old)
m_pFunction->PushCell(BAD_HANDLE);
m_pFunction->PushCell(BAD_HANDLE);
m_pFunction->PushString("Driver is unloading");
m_pFunction->PushCell(m_Data);
@@ -348,7 +355,8 @@ public:
}
}
m_pFunction->PushCell(m_pDriver->GetHandle());
if (m_ACM == ACM_Old)
m_pFunction->PushCell(m_pDriver->GetHandle());
m_pFunction->PushCell(hndl);
m_pFunction->PushString(hndl == BAD_HANDLE ? error : "");
m_pFunction->PushCell(m_Data);
@@ -363,6 +371,7 @@ private:
IPluginFunction *m_pFunction;
IDBDriver *m_pDriver;
IDatabase *m_pDatabase;
AsyncCallbackMode m_ACM;
char dbname[64];
char error[255];
cell_t m_Data;
@@ -401,7 +410,7 @@ static cell_t SQL_Connect(IPluginContext *pContext, const cell_t *params)
return hndl;
}
static cell_t SQL_TConnect(IPluginContext *pContext, const cell_t *params)
static cell_t ConnectToDbAsync(IPluginContext *pContext, const cell_t *params, AsyncCallbackMode acm)
{
IPluginFunction *pf = pContext->GetFunctionById(params[1]);
if (!pf)
@@ -442,7 +451,8 @@ static cell_t SQL_TConnect(IPluginContext *pContext, const cell_t *params)
if (!pInfo || !driver)
{
pf->PushCell(BAD_HANDLE);
pf->PushCell(BAD_HANDLE);
if (acm == ACM_Old)
pf->PushCell(BAD_HANDLE);
pf->PushString(error);
pf->PushCell(0);
pf->Execute(NULL);
@@ -457,7 +467,7 @@ static cell_t SQL_TConnect(IPluginContext *pContext, const cell_t *params)
}
/* Finally, add to the thread if we can */
TConnectOp *op = new TConnectOp(pf, driver, conf, params[3]);
TConnectOp *op = new TConnectOp(pf, driver, conf, acm, params[3]);
IPlugin *pPlugin = scripts->FindPluginByContext(pContext->GetContext());
if (pPlugin->GetProperty("DisallowDBThreads", NULL)
|| !g_DBMan.AddToThreadQueue(op, PrioQueue_High))
@@ -471,6 +481,16 @@ static cell_t SQL_TConnect(IPluginContext *pContext, const cell_t *params)
return 1;
}
static cell_t SQL_TConnect(IPluginContext *pContext, const cell_t *params)
{
return ConnectToDbAsync(pContext, params, ACM_Old);
}
static cell_t Database_Connect(IPluginContext *pContext, const cell_t *params)
{
return ConnectToDbAsync(pContext, params, ACM_New);
}
static cell_t SQL_ConnectEx(IPluginContext *pContext, const cell_t *params)
{
IDBDriver *driver;
@@ -1350,6 +1370,20 @@ static cell_t SQL_ReadDriver(IPluginContext *pContext, const cell_t *params)
return driver->GetHandle();
}
static cell_t Database_Driver_get(IPluginContext *pContext, const cell_t *params)
{
IDatabase *db1=NULL;
HandleError err;
if ((err = g_DBMan.ReadHandle(params[1], DBHandle_Database, (void **)&db1))
!= HandleError_None)
{
return pContext->ThrowNativeError("Invalid database Handle 1/%x (error: %d)", params[1], err);
}
return db1->GetDriver()->GetHandle();
}
static cell_t SQL_CheckConfig(IPluginContext *pContext, const cell_t *params)
{
char *name;
@@ -1672,6 +1706,8 @@ public:
failure_->PushCell(failIndex_);
failure_->PushArray(data, txn_->entries.length());
failure_->Execute(NULL);
handlesys->FreeHandle(dbh, &sec);
}
}
@@ -1741,9 +1777,48 @@ static cell_t SQL_ExecuteTransaction(IPluginContext *pContext, const cell_t *par
REGISTER_NATIVES(dbNatives)
{
// Transitional syntax support.
{"DBDriver.Find", SQL_GetDriver},
{"DBDriver.GetIdentifier", SQL_GetDriverIdent},
{"DBDriver.GetProduct", SQL_GetDriverProduct},
{"DBResultSet.FetchMoreResults", SQL_FetchMoreResults},
{"DBResultSet.HasResults.get", SQL_HasResultSet},
{"DBResultSet.RowCount.get", SQL_GetRowCount},
{"DBResultSet.FieldCount.get", SQL_GetFieldCount},
{"DBResultSet.AffectedRows.get", SQL_GetAffectedRows},
{"DBResultSet.InsertId.get", SQL_GetInsertId},
{"DBResultSet.FieldNameToNum", SQL_FieldNameToNum},
{"DBResultSet.FieldNumToName", SQL_FieldNumToName},
{"DBResultSet.FetchRow", SQL_FetchRow},
{"DBResultSet.MoreRows.get", SQL_MoreRows},
{"DBResultSet.Rewind", SQL_Rewind},
{"DBResultSet.FetchString", SQL_FetchString},
{"DBResultSet.FetchFloat", SQL_FetchFloat},
{"DBResultSet.FetchInt", SQL_FetchInt},
{"DBResultSet.IsFieldNull", SQL_IsFieldNull},
{"DBResultSet.FetchSize", SQL_FetchSize},
{"Transaction.Transaction", SQL_CreateTransaction},
{"Transaction.AddQuery", SQL_AddQuery},
{"DBStatement.BindInt", SQL_BindParamInt},
{"DBStatement.BindFloat", SQL_BindParamFloat},
{"DBStatement.BindString", SQL_BindParamString},
{"Database.Connect", Database_Connect},
{"Database.Driver.get", Database_Driver_get},
{"Database.SetCharset", SQL_SetCharset},
{"Database.Escape", SQL_QuoteString},
{"Database.IsSameConnection", SQL_IsSameConnection},
{"Database.Execute", SQL_ExecuteTransaction},
// Note: The callback is ABI compatible so we can re-use the native.
{"Database.Query", SQL_TQuery},
{"SQL_BindParamInt", SQL_BindParamInt},
{"SQL_BindParamFloat", SQL_BindParamFloat},
{"SQL_BindParamString", SQL_BindParamString},\
{"SQL_BindParamString", SQL_BindParamString},
{"SQL_CheckConfig", SQL_CheckConfig},
{"SQL_Connect", SQL_Connect},
{"SQL_ConnectEx", SQL_ConnectEx},
+49 -2
View File
@@ -148,6 +148,27 @@ static cell_t smn_WritePackString(IPluginContext *pContext, const cell_t *params
return 1;
}
static cell_t smn_WritePackFunction(IPluginContext *pContext, const cell_t *params)
{
Handle_t hndl = static_cast<Handle_t>(params[1]);
HandleError herr;
HandleSecurity sec;
IDataPack *pDataPack;
sec.pOwner = pContext->GetIdentity();
sec.pIdentity = g_pCoreIdent;
if ((herr = handlesys->ReadHandle(hndl, g_DataPackType, &sec, (void **)&pDataPack))
!= HandleError_None)
{
return pContext->ThrowNativeError("Invalid data pack handle %x (error %d)", hndl, herr);
}
pDataPack->PackFunction(params[2]);
return 1;
}
static cell_t smn_ReadPackCell(IPluginContext *pContext, const cell_t *params)
{
Handle_t hndl = static_cast<Handle_t>(params[1]);
@@ -164,7 +185,7 @@ static cell_t smn_ReadPackCell(IPluginContext *pContext, const cell_t *params)
return pContext->ThrowNativeError("Invalid data pack handle %x (error %d)", hndl, herr);
}
if (!pDataPack->IsReadable(sizeof(size_t) + sizeof(cell_t)))
if (!pDataPack->IsReadable(sizeof(char) + sizeof(size_t) + sizeof(cell_t)))
{
return pContext->ThrowNativeError("DataPack operation is out of bounds.");
}
@@ -188,7 +209,7 @@ static cell_t smn_ReadPackFloat(IPluginContext *pContext, const cell_t *params)
return pContext->ThrowNativeError("Invalid data pack handle %x (error %d)", hndl, herr);
}
if (!pDataPack->IsReadable(sizeof(size_t) + sizeof(float)))
if (!pDataPack->IsReadable(sizeof(char) + sizeof(size_t) + sizeof(float)))
{
return pContext->ThrowNativeError("DataPack operation is out of bounds.");
}
@@ -223,6 +244,30 @@ static cell_t smn_ReadPackString(IPluginContext *pContext, const cell_t *params)
return 1;
}
static cell_t smn_ReadPackFunction(IPluginContext *pContext, const cell_t *params)
{
Handle_t hndl = static_cast<Handle_t>(params[1]);
HandleError herr;
HandleSecurity sec;
IDataPack *pDataPack;
sec.pOwner = pContext->GetIdentity();
sec.pIdentity = g_pCoreIdent;
if ((herr = handlesys->ReadHandle(hndl, g_DataPackType, &sec, (void **)&pDataPack))
!= HandleError_None)
{
return pContext->ThrowNativeError("Invalid data pack handle %x (error %d)", hndl, herr);
}
if (!pDataPack->IsReadable(sizeof(char) + sizeof(size_t) + sizeof(cell_t)))
{
return pContext->ThrowNativeError("DataPack operation is out of bounds.");
}
return pDataPack->ReadFunction();
}
static cell_t smn_ResetPack(IPluginContext *pContext, const cell_t *params)
{
Handle_t hndl = static_cast<Handle_t>(params[1]);
@@ -318,9 +363,11 @@ REGISTER_NATIVES(datapacknatives)
{"WritePackCell", smn_WritePackCell},
{"WritePackFloat", smn_WritePackFloat},
{"WritePackString", smn_WritePackString},
{"WritePackFunction", smn_WritePackFunction},
{"ReadPackCell", smn_ReadPackCell},
{"ReadPackFloat", smn_ReadPackFloat},
{"ReadPackString", smn_ReadPackString},
{"ReadPackFunction", smn_ReadPackFunction},
{"ResetPack", smn_ResetPack},
{"GetPackPosition", smn_GetPackPosition},
{"SetPackPosition", smn_SetPackPosition},
+1
View File
@@ -441,6 +441,7 @@ REGISTER_NATIVES(nativeNatives)
{"GetNativeArray", GetNativeArray},
{"GetNativeCell", GetNativeCell},
{"GetNativeCellRef", GetNativeCellRef},
{"GetNativeFunction", GetNativeCell},
{"GetNativeString", GetNativeString},
{"GetNativeStringLength", GetNativeStringLength},
{"FormatNativeString", FormatNativeString},
File diff suppressed because it is too large Load Diff
+1
View File
@@ -36,6 +36,7 @@
#include "MersenneTwister.h"
#include <IPluginSys.h>
#include <am-utility.h>
#include <am-float.h>
/****************************************
* *
+4
View File
@@ -53,6 +53,10 @@ static cell_t sm_IsValidHandle(IPluginContext *pContext, const cell_t *params)
static cell_t sm_CloseHandle(IPluginContext *pContext, const cell_t *params)
{
Handle_t hndl = static_cast<Handle_t>(params[1]);
if (!hndl)
return 0;
HandleSecurity sec;
sec.pIdentity = NULL;
+2 -2
View File
@@ -202,8 +202,8 @@ public:
{
errmsg = "Unknown error";
}
smcore.LogError("[SM] Could not parse file \"%s\"", m_ConfigFile);
smcore.LogError("[SM] Error on line %d (col %d): %s", states.line, states.col, errmsg);
logger->LogError("[SM] Could not parse file \"%s\"", m_ConfigFile);
logger->LogError("[SM] Error on line %d (col %d): %s", states.line, states.col, errmsg);
}
else
{
+159 -75
View File
@@ -29,20 +29,16 @@
* Version: $Id$
*/
#include "sm_globals.h"
#include "common_logic.h"
#include <sh_stack.h>
#include "MenuManager.h"
#include "MenuStyle_Valve.h"
#include "MenuStyle_Radio.h"
#include "PlayerManager.h"
#include "sm_stringutil.h"
#include "sourcemm_api.h"
#include <IMenuManager.h>
#include <IPlayerHelpers.h>
#include "DebugReporter.h"
#if defined MENU_DEBUG
#include "Logger.h"
#endif
#include "ChatTriggers.h"
#include "logic_bridge.h"
#include "sourcemod.h"
#include <ISourceMod.h>
#include <stdlib.h>
#if defined CreateMenu
#undef CreateMenu
@@ -68,6 +64,50 @@ enum MenuAction
MenuAction_DisplayItem = (1<<9), /**< the odd duck */
};
static HandleError ReadMenuHandle(Handle_t handle, IBaseMenu **menu)
{
static HandleType_t menuType = NO_HANDLE_TYPE;
if (menuType == NO_HANDLE_TYPE && !handlesys->FindHandleType("IBaseMenu", &menuType))
{
// This should never happen so exact error doesn't matter.
return HandleError_Index;
}
HandleSecurity sec;
sec.pIdentity = g_pCoreIdent;
sec.pOwner = NULL;
return handlesys->ReadHandle(handle, menuType, &sec, (void **)menu);
}
static HandleError ReadStyleHandle(Handle_t handle, IMenuStyle **style)
{
static HandleType_t styleType = NO_HANDLE_TYPE;
if (styleType == NO_HANDLE_TYPE && !handlesys->FindHandleType("IMenuStyle", &styleType))
{
// This should never happen so exact error doesn't matter.
return HandleError_Index;
}
HandleSecurity sec;
sec.pIdentity = g_pCoreIdent;
sec.pOwner = g_pCoreIdent;
return handlesys->ReadHandle(handle, styleType, &sec, (void **)style);
}
static IMenuStyle &ValveMenuStyle()
{
static IMenuStyle *valveMenuStyle = menus->FindStyleByName("valve");
return *valveMenuStyle;
}
static IMenuStyle &RadioMenuStyle()
{
static IMenuStyle *radioMenuStyle = menus->FindStyleByName("radio");
return *radioMenuStyle;
}
class CPanelHandler : public IMenuHandler
{
friend class MenuNativeHelpers;
@@ -269,13 +309,13 @@ void CPanelHandler::OnMenuSelect(IBaseMenu *menu, int client, unsigned int item)
{
if (m_pFunc)
{
unsigned int old_reply = g_ChatTriggers.SetReplyTo(SM_REPLY_CHAT);
unsigned int old_reply = playerhelpers->SetReplyTo(SM_REPLY_CHAT);
m_pFunc->PushCell(BAD_HANDLE);
m_pFunc->PushCell(MenuAction_Select);
m_pFunc->PushCell(client);
m_pFunc->PushCell(item);
m_pFunc->Execute(NULL);
g_ChatTriggers.SetReplyTo(old_reply);
playerhelpers->SetReplyTo(old_reply);
}
g_MenuHelpers.FreePanelHandler(this);
}
@@ -330,18 +370,18 @@ void CMenuHandler::OnMenuSelect2(IBaseMenu *menu, int client, unsigned int item,
s_CurSelectPosition = &first_item;
unsigned int old_reply = g_ChatTriggers.SetReplyTo(SM_REPLY_CHAT);
unsigned int old_reply = playerhelpers->SetReplyTo(SM_REPLY_CHAT);
DoAction(menu, MenuAction_Select, client, item);
g_ChatTriggers.SetReplyTo(old_reply);
playerhelpers->SetReplyTo(old_reply);
s_CurSelectPosition = old_pos;
}
void CMenuHandler::OnMenuCancel(IBaseMenu *menu, int client, MenuCancelReason reason)
{
unsigned int old_reply = g_ChatTriggers.SetReplyTo(SM_REPLY_CHAT);
unsigned int old_reply = playerhelpers->SetReplyTo(SM_REPLY_CHAT);
DoAction(menu, MenuAction_Cancel, client, (cell_t)reason);
g_ChatTriggers.SetReplyTo(old_reply);
playerhelpers->SetReplyTo(old_reply);
}
void CMenuHandler::OnMenuEnd(IBaseMenu *menu, MenuEndReason reason)
@@ -470,7 +510,7 @@ void CMenuHandler::OnMenuVoteResults(IBaseMenu *menu, const menu_vote_result_t *
if ((err = pContext->HeapAlloc(client_array_size, &client_array_address, &client_array_base))
!= SP_ERROR_NONE)
{
logicore.GenerateError(pContext, m_fnVoteResult, err, "Menu callback could not allocate %d bytes for client list.", client_array_size * sizeof(cell_t));
g_DbgReporter.GenerateError(pContext, m_fnVoteResult, err, "Menu callback could not allocate %d bytes for client list.", client_array_size * sizeof(cell_t));
no_call = true;
} else {
cell_t target_offs = sizeof(cell_t) * results->num_clients;
@@ -503,7 +543,7 @@ void CMenuHandler::OnMenuVoteResults(IBaseMenu *menu, const menu_vote_result_t *
if ((err = pContext->HeapAlloc(item_array_size, &item_array_address, &item_array_base))
!= SP_ERROR_NONE)
{
logicore.GenerateError(pContext, m_fnVoteResult, err, "Menu callback could not allocate %d bytes for item list.", item_array_size);
g_DbgReporter.GenerateError(pContext, m_fnVoteResult, err, "Menu callback could not allocate %d bytes for item list.", item_array_size);
no_call = true;
} else {
cell_t target_offs = sizeof(cell_t) * results->num_items;
@@ -592,14 +632,14 @@ inline IMenuStyle *GetStyleFromCell(cell_t cell)
if (cell == MenuStyle_Valve)
{
return &g_ValveMenuStyle;
return &ValveMenuStyle();
} else if (cell == MenuStyle_Radio
&& g_RadioMenuStyle.IsSupported())
&& RadioMenuStyle().IsSupported())
{
return &g_RadioMenuStyle;
return &RadioMenuStyle();
}
return g_Menus.GetDefaultStyle();
return menus->GetDefaultStyle();
}
/***********************************
@@ -608,7 +648,7 @@ inline IMenuStyle *GetStyleFromCell(cell_t cell)
static cell_t CreateMenu(IPluginContext *pContext, const cell_t *params)
{
IMenuStyle *style = g_Menus.GetDefaultStyle();
IMenuStyle *style = menus->GetDefaultStyle();
IPluginFunction *pFunction;
if ((pFunction=pContext->GetFunctionById(params[1])) == NULL)
@@ -635,7 +675,7 @@ static cell_t DisplayMenu(IPluginContext *pContext, const cell_t *params)
HandleError err;
IBaseMenu *menu;
if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
if ((err = ReadMenuHandle(params[1], &menu)) != HandleError_None)
{
return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
}
@@ -649,7 +689,7 @@ static cell_t DisplayMenuAtItem(IPluginContext *pContext, const cell_t *params)
HandleError err;
IBaseMenu *menu;
if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
if ((err = ReadMenuHandle(params[1], &menu)) != HandleError_None)
{
return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
}
@@ -659,7 +699,7 @@ static cell_t DisplayMenuAtItem(IPluginContext *pContext, const cell_t *params)
static cell_t VoteMenu(IPluginContext *pContext, const cell_t *params)
{
if (g_Menus.IsVoteInProgress())
if (menus->IsVoteInProgress())
{
return pContext->ThrowNativeError("A vote is already in progress");
}
@@ -668,7 +708,7 @@ static cell_t VoteMenu(IPluginContext *pContext, const cell_t *params)
HandleError err;
IBaseMenu *menu;
if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
if ((err = ReadMenuHandle(params[1], &menu)) != HandleError_None)
{
return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
}
@@ -682,7 +722,7 @@ static cell_t VoteMenu(IPluginContext *pContext, const cell_t *params)
flags = params[5];
}
if (!g_Menus.StartVote(menu, params[3], addr, params[4], flags))
if (!menus->StartVote(menu, params[3], addr, params[4], flags))
{
return 0;
}
@@ -696,7 +736,7 @@ static cell_t AddMenuItem(IPluginContext *pContext, const cell_t *params)
HandleError err;
IBaseMenu *menu;
if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
if ((err = ReadMenuHandle(params[1], &menu)) != HandleError_None)
{
return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
}
@@ -717,7 +757,7 @@ static cell_t InsertMenuItem(IPluginContext *pContext, const cell_t *params)
HandleError err;
IBaseMenu *menu;
if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
if ((err = ReadMenuHandle(params[1], &menu)) != HandleError_None)
{
return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
}
@@ -738,7 +778,7 @@ static cell_t RemoveMenuItem(IPluginContext *pContext, const cell_t *params)
HandleError err;
IBaseMenu *menu;
if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
if ((err = ReadMenuHandle(params[1], &menu)) != HandleError_None)
{
return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
}
@@ -752,7 +792,7 @@ static cell_t RemoveAllMenuItems(IPluginContext *pContext, const cell_t *params)
HandleError err;
IBaseMenu *menu;
if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
if ((err = ReadMenuHandle(params[1], &menu)) != HandleError_None)
{
return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
}
@@ -768,7 +808,7 @@ static cell_t GetMenuItem(IPluginContext *pContext, const cell_t *params)
HandleError err;
IBaseMenu *menu;
if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
if ((err = ReadMenuHandle(params[1], &menu)) != HandleError_None)
{
return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
}
@@ -797,7 +837,7 @@ static cell_t SetMenuPagination(IPluginContext *pContext, const cell_t *params)
HandleError err;
IBaseMenu *menu;
if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
if ((err = ReadMenuHandle(params[1], &menu)) != HandleError_None)
{
return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
}
@@ -811,7 +851,7 @@ static cell_t GetMenuPagination(IPluginContext *pContext, const cell_t *params)
HandleError err;
IBaseMenu *menu;
if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
if ((err = ReadMenuHandle(params[1], &menu)) != HandleError_None)
{
return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
}
@@ -825,7 +865,7 @@ static cell_t GetMenuItemCount(IPluginContext *pContext, const cell_t *params)
HandleError err;
IBaseMenu *menu;
if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
if ((err = ReadMenuHandle(params[1], &menu)) != HandleError_None)
{
return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
}
@@ -839,13 +879,13 @@ static cell_t SetMenuTitle(IPluginContext *pContext, const cell_t *params)
HandleError err;
IBaseMenu *menu;
if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
if ((err = ReadMenuHandle(params[1], &menu)) != HandleError_None)
{
return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
}
char buffer[1024];
g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2);
g_pSM->FormatString(buffer, sizeof(buffer), pContext, params, 2);
menu->SetDefaultTitle(buffer);
@@ -858,7 +898,7 @@ static cell_t GetMenuTitle(IPluginContext *pContext, const cell_t *params)
HandleError err;
IBaseMenu *menu;
if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
if ((err = ReadMenuHandle(params[1], &menu)) != HandleError_None)
{
return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
}
@@ -877,7 +917,7 @@ static cell_t CreatePanelFromMenu(IPluginContext *pContext, const cell_t *params
HandleError err;
IBaseMenu *menu;
if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
if ((err = ReadMenuHandle(params[1], &menu)) != HandleError_None)
{
return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
}
@@ -898,7 +938,7 @@ static cell_t GetMenuExitButton(IPluginContext *pContext, const cell_t *params)
HandleError err;
IBaseMenu *menu;
if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
if ((err = ReadMenuHandle(params[1], &menu)) != HandleError_None)
{
return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
}
@@ -912,7 +952,7 @@ static cell_t GetMenuExitBackButton(IPluginContext *pContext, const cell_t *para
HandleError err;
IBaseMenu *menu;
if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
if ((err = ReadMenuHandle(params[1], &menu)) != HandleError_None)
{
return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
}
@@ -926,7 +966,7 @@ static cell_t SetMenuExitButton(IPluginContext *pContext, const cell_t *params)
HandleError err;
IBaseMenu *menu;
if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
if ((err = ReadMenuHandle(params[1], &menu)) != HandleError_None)
{
return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
}
@@ -952,7 +992,7 @@ static cell_t SetMenuNoVoteButton(IPluginContext *pContext, const cell_t *params
HandleError err;
IBaseMenu *menu;
if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
if ((err = ReadMenuHandle(params[1], &menu)) != HandleError_None)
{
return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
}
@@ -978,7 +1018,7 @@ static cell_t SetMenuExitBackButton(IPluginContext *pContext, const cell_t *para
HandleError err;
IBaseMenu *menu;
if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
if ((err = ReadMenuHandle(params[1], &menu)) != HandleError_None)
{
return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
}
@@ -1003,19 +1043,19 @@ static cell_t CancelMenu(IPluginContext *pContext, const cell_t *params)
HandleError err;
IBaseMenu *menu;
if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
if ((err = ReadMenuHandle(params[1], &menu)) != HandleError_None)
{
return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
}
g_Menus.CancelMenu(menu);
menus->CancelMenu(menu);
return 1;
}
static cell_t IsVoteInProgress(IPluginContext *pContext, const cell_t *params)
{
return g_Menus.IsVoteInProgress() ? 1 : 0;
return menus->IsVoteInProgress() ? 1 : 0;
}
static cell_t GetMenuStyle(IPluginContext *pContext, const cell_t *params)
@@ -1024,7 +1064,7 @@ static cell_t GetMenuStyle(IPluginContext *pContext, const cell_t *params)
HandleError err;
IBaseMenu *menu;
if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
if ((err = ReadMenuHandle(params[1], &menu)) != HandleError_None)
{
return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
}
@@ -1051,12 +1091,12 @@ static cell_t CreatePanel(IPluginContext *pContext, const cell_t *params)
if (hndl != 0)
{
if ((err=g_Menus.ReadStyleHandle(params[1], &style)) != HandleError_None)
if ((err = ReadStyleHandle(params[1], &style)) != HandleError_None)
{
return pContext->ThrowNativeError("MenuStyle handle %x is invalid (error %d)", hndl, err);
}
} else {
style = g_Menus.GetDefaultStyle();
style = menus->GetDefaultStyle();
}
IMenuPanel *panel = style->CreatePanel();
@@ -1079,12 +1119,12 @@ static cell_t CreateMenuEx(IPluginContext *pContext, const cell_t *params)
if (hndl != 0)
{
if ((err=g_Menus.ReadStyleHandle(params[1], &style)) != HandleError_None)
if ((err = ReadStyleHandle(params[1], &style)) != HandleError_None)
{
return pContext->ThrowNativeError("MenuStyle handle %x is invalid (error %d)", hndl, err);
}
} else {
style = g_Menus.GetDefaultStyle();
style = menus->GetDefaultStyle();
}
IPluginFunction *pFunction;
@@ -1114,12 +1154,12 @@ static cell_t GetClientMenu(IPluginContext *pContext, const cell_t *params)
if (hndl != 0)
{
if ((err=g_Menus.ReadStyleHandle(params[1], &style)) != HandleError_None)
if ((err = ReadStyleHandle(params[1], &style)) != HandleError_None)
{
return pContext->ThrowNativeError("MenuStyle handle %x is invalid (error %d)", hndl, err);
}
} else {
style = g_Menus.GetDefaultStyle();
style = menus->GetDefaultStyle();
}
return style->GetClientMenu(params[1], NULL);
@@ -1133,12 +1173,12 @@ static cell_t CancelClientMenu(IPluginContext *pContext, const cell_t *params)
if (hndl != 0)
{
if ((err=g_Menus.ReadStyleHandle(params[1], &style)) != HandleError_None)
if ((err = ReadStyleHandle(params[1], &style)) != HandleError_None)
{
return pContext->ThrowNativeError("MenuStyle handle %x is invalid (error %d)", hndl, err);
}
} else {
style = g_Menus.GetDefaultStyle();
style = menus->GetDefaultStyle();
}
return style->CancelClientMenu(params[1], params[2] ? true : false) ? 1 : 0;
@@ -1152,12 +1192,12 @@ static cell_t GetMaxPageItems(IPluginContext *pContext, const cell_t *params)
if (hndl != 0)
{
if ((err=g_Menus.ReadStyleHandle(params[1], &style)) != HandleError_None)
if ((err = ReadStyleHandle(params[1], &style)) != HandleError_None)
{
return pContext->ThrowNativeError("MenuStyle handle %x is invalid (error %d)", hndl, err);
}
} else {
style = g_Menus.GetDefaultStyle();
style = menus->GetDefaultStyle();
}
return style->GetMaxPageItems();
@@ -1354,7 +1394,7 @@ static cell_t GetMenuOptionFlags(IPluginContext *pContext, const cell_t *params)
HandleError err;
IBaseMenu *menu;
if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
if ((err = ReadMenuHandle(params[1], &menu)) != HandleError_None)
{
return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
}
@@ -1368,7 +1408,7 @@ static cell_t SetMenuOptionFlags(IPluginContext *pContext, const cell_t *params)
HandleError err;
IBaseMenu *menu;
if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
if ((err = ReadMenuHandle(params[1], &menu)) != HandleError_None)
{
return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
}
@@ -1380,12 +1420,12 @@ static cell_t SetMenuOptionFlags(IPluginContext *pContext, const cell_t *params)
static cell_t CancelVote(IPluginContext *pContxt, const cell_t *params)
{
if (!g_Menus.IsVoteInProgress())
if (!menus->IsVoteInProgress())
{
return pContxt->ThrowNativeError("No vote is in progress");
}
g_Menus.CancelVoting();
menus->CancelVoting();
return 1;
}
@@ -1396,7 +1436,7 @@ static cell_t SetVoteResultCallback(IPluginContext *pContext, const cell_t *para
HandleError err;
IBaseMenu *menu;
if ((err=g_Menus.ReadMenuHandle(params[1], &menu)) != HandleError_None)
if ((err = ReadMenuHandle(params[1], &menu)) != HandleError_None)
{
return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
}
@@ -1422,7 +1462,7 @@ static cell_t SetVoteResultCallback(IPluginContext *pContext, const cell_t *para
static cell_t CheckVoteDelay(IPluginContext *pContext, const cell_t *params)
{
return g_Menus.GetRemainingVoteDelay();
return menus->GetRemainingVoteDelay();
}
static cell_t GetMenuSelectionPosition(IPluginContext *pContext, const cell_t *params)
@@ -1441,17 +1481,17 @@ static cell_t IsClientInVotePool(IPluginContext *pContext, const cell_t *params)
IGamePlayer *pPlayer;
client = params[1];
if ((pPlayer = g_Players.GetPlayerByIndex(client)) == NULL)
if ((pPlayer = playerhelpers->GetGamePlayer(client)) == NULL)
{
return pContext->ThrowNativeError("Invalid client index %d", client);
}
if (!g_Menus.IsVoteInProgress())
if (!menus->IsVoteInProgress())
{
return pContext->ThrowNativeError("No vote is in progress");
}
return g_Menus.IsClientInVotePool(client) ? 1 : 0;
return menus->IsClientInVotePool(client) ? 1 : 0;
}
static cell_t RedrawClientVoteMenu(IPluginContext *pContext, const cell_t *params)
@@ -1460,17 +1500,17 @@ static cell_t RedrawClientVoteMenu(IPluginContext *pContext, const cell_t *param
IGamePlayer *pPlayer;
client = params[1];
if ((pPlayer = g_Players.GetPlayerByIndex(client)) == NULL)
if ((pPlayer = playerhelpers->GetGamePlayer(client)) == NULL)
{
return pContext->ThrowNativeError("Invalid client index %d", client);
}
if (!g_Menus.IsVoteInProgress())
if (!menus->IsVoteInProgress())
{
return pContext->ThrowNativeError("No vote is in progress");
}
if (!g_Menus.IsClientInVotePool(client))
if (!menus->IsClientInVotePool(client))
{
return pContext->ThrowNativeError("Client is not in the voting pool");
}
@@ -1481,7 +1521,7 @@ static cell_t RedrawClientVoteMenu(IPluginContext *pContext, const cell_t *param
revote = false;
}
return g_Menus.RedrawClientVoteMenu2(client, revote) ? 1 : 0;
return menus->RedrawClientVoteMenu2(client, revote) ? 1 : 0;
}
class EmptyMenuHandler : public IMenuHandler
@@ -1492,7 +1532,7 @@ public:
static cell_t InternalShowMenu(IPluginContext *pContext, const cell_t *params)
{
int client = params[1];
CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
IGamePlayer *pPlayer = playerhelpers->GetGamePlayer(client);
if (pPlayer == NULL)
{
@@ -1503,7 +1543,7 @@ static cell_t InternalShowMenu(IPluginContext *pContext, const cell_t *params)
return pContext->ThrowNativeError("Client %d is not in game", client);
}
if (!g_RadioMenuStyle.IsSupported())
if (!RadioMenuStyle().IsSupported())
{
return pContext->ThrowNativeError("Radio menus are not supported on this mod");
}
@@ -1511,13 +1551,16 @@ static cell_t InternalShowMenu(IPluginContext *pContext, const cell_t *params)
char *str;
pContext->LocalToString(params[2], &str);
IMenuPanel *pPanel = g_RadioMenuStyle.MakeRadioDisplay(str, params[4]);
IMenuPanel *pPanel = RadioMenuStyle().CreatePanel();
if (pPanel == NULL)
{
return 0;
}
pPanel->DirectSet(str);
pPanel->SetSelectableKeys(params[4]);
IMenuHandler *pHandler;
CPanelHandler *pActualHandler = NULL;
if (params[5] != -1)
@@ -1602,6 +1645,47 @@ REGISTER_NATIVES(menuNatives)
{"SetVoteResultCallback", SetVoteResultCallback},
{"VoteMenu", VoteMenu},
{"SetMenuNoVoteButton", SetMenuNoVoteButton},
// Transitional syntax support.
{"Panel.Panel", CreatePanel},
{"Panel.TextRemaining.get", GetPanelTextRemaining},
{"Panel.CurrentKey.get", GetPanelCurrentKey},
{"Panel.CurrentKey.set", SetPanelCurrentKey},
{"Panel.Style", GetPanelStyle},
{"Panel.CanDrawFlags", CanPanelDrawFlags},
{"Panel.SetTitle", SetPanelTitle},
{"Panel.SetKeys", SetPanelKeys},
{"Panel.Send", SendPanelToClient},
{"Panel.DrawItem", DrawPanelItem},
{"Panel.DrawText", DrawPanelText},
{"Menu.Menu", CreateMenu},
{"Menu.Display", DisplayMenu},
{"Menu.DisplayAt", DisplayMenuAtItem},
{"Menu.AddItem", AddMenuItem},
{"Menu.InsertItem", InsertMenuItem},
{"Menu.RemoveItem", RemoveMenuItem},
{"Menu.RemoveAllItems", RemoveAllMenuItems},
{"Menu.GetItem", GetMenuItem},
{"Menu.GetTitle", GetMenuTitle},
{"Menu.SetTitle", SetMenuTitle},
{"Menu.ToPanel", CreatePanelFromMenu},
{"Menu.Cancel", CancelMenu},
{"Menu.DisplayVote", VoteMenu},
{"Menu.Pagination.get", GetMenuPagination},
{"Menu.Pagination.set", SetMenuPagination},
{"Menu.OptionFlags.get", GetMenuOptionFlags},
{"Menu.OptionFlags.set", SetMenuOptionFlags},
{"Menu.ExitButton.get", GetMenuExitButton},
{"Menu.ExitButton.set", SetMenuExitButton},
{"Menu.ExitBackButton.get", GetMenuExitBackButton},
{"Menu.ExitBackButton.set", SetMenuExitBackButton},
{"Menu.NoVoteButton.set", SetMenuNoVoteButton},
{"Menu.VoteResultCallback.set", SetVoteResultCallback},
{"Menu.ItemCount.get", GetMenuItemCount},
{"Menu.Style.get", GetMenuStyle},
{"Menu.Selection.get", GetMenuSelectionPosition},
{NULL, NULL},
};
+88 -16
View File
@@ -37,12 +37,21 @@
#include <ITranslator.h>
#include <sh_string.h>
#include <sh_list.h>
#include "GameConfigs.h"
#include "CellArray.h"
#include "AutoHandleRooter.h"
using namespace SourceHook;
using namespace SourceMod;
#ifndef PRIu64
#ifdef _WIN32
#define PRIu64 "I64u"
#else
#define PRIu64 "llu"
#endif
#endif
static const int kActivityNone = 0;
static const int kActivityNonAdmins = 1; // Show admin activity to non-admins anonymously.
static const int kActivityNonAdminsNames = 2; // If 1 is specified, admin names will be shown.
@@ -120,7 +129,7 @@ public: //ICommandTargetProcessor
Handle_t hndl = handlesys->CreateHandleEx(htCellArray, array, &sec, NULL, NULL);
AutoHandleCloner ahc(hndl, sec);
if (ahc.getClone() == BAD_HANDLE) {
smcore.LogError("[SM] Could not allocate a handle (%s, %d)", __FILE__, __LINE__);
logger->LogError("[SM] Could not allocate a handle (%s, %d)", __FILE__, __LINE__);
delete array;
return false;
}
@@ -322,9 +331,17 @@ static cell_t sm_GetClientIP(IPluginContext *pCtx, const cell_t *params)
return 1;
}
static cell_t sm_GetClientAuthStr(IPluginContext *pCtx, const cell_t *params)
// Must match clients.inc
enum class AuthIdType
{
Engine = 0,
Steam2,
Steam3,
SteamId64,
};
static cell_t SteamIdToLocal(IPluginContext *pCtx, int index, AuthIdType authType, cell_t local_addr, size_t bytes, bool validate)
{
int index = params[1];
if ((index < 1) || (index > playerhelpers->GetMaxClients()))
{
return pCtx->ThrowNativeError("Client index %d is invalid", index);
@@ -335,25 +352,79 @@ static cell_t sm_GetClientAuthStr(IPluginContext *pCtx, const cell_t *params)
{
return pCtx->ThrowNativeError("Client %d is not connected", index);
}
bool validate = true;
if (params[0] > 3)
{
validate = !!params[4];
}
const char *authstr = pPlayer->GetAuthString(validate);
if (!authstr || authstr[0] == '\0')
const char *authstr;
switch (authType)
{
return 0;
}
case AuthIdType::Engine:
authstr = pPlayer->GetAuthString(validate);
if (!authstr || authstr[0] == '\0')
{
return 0;
}
pCtx->StringToLocal(params[2], static_cast<size_t>(params[3]), authstr);
pCtx->StringToLocal(local_addr, bytes, authstr);
break;
case AuthIdType::Steam2:
authstr = pPlayer->GetSteam2Id(validate);
if (!authstr || authstr[0] == '\0')
{
return 0;
}
pCtx->StringToLocal(local_addr, bytes, authstr);
break;
case AuthIdType::Steam3:
authstr = pPlayer->GetSteam3Id(validate);
if (!authstr || authstr[0] == '\0')
{
return 0;
}
pCtx->StringToLocal(local_addr, bytes, authstr);
break;
case AuthIdType::SteamId64:
{
if (pPlayer->IsFakeClient() || gamehelpers->IsLANServer())
{
return 0;
}
uint64_t steamId = pPlayer->GetSteamId64(validate);
if (steamId == 0)
{
return 0;
}
char szAuth[64];
snprintf(szAuth, sizeof(szAuth), "%" PRIu64, steamId);
pCtx->StringToLocal(local_addr, bytes, szAuth);
}
break;
}
return 1;
}
static cell_t sm_GetClientAuthStr(IPluginContext *pCtx, const cell_t *params)
{
bool validate = true;
if (params[0] >= 4)
{
validate = !!params[4];
}
return SteamIdToLocal(pCtx, params[1], AuthIdType::Steam2, params[2], (size_t)params[3], validate);
}
static cell_t sm_GetClientAuthId(IPluginContext *pCtx, const cell_t *params)
{
return SteamIdToLocal(pCtx, params[1], (AuthIdType)params[2], params[3], (size_t)params[4], params[5] != 0);
}
static cell_t sm_GetSteamAccountID(IPluginContext *pCtx, const cell_t *params)
{
int index = params[1];
@@ -1540,6 +1611,7 @@ REGISTER_NATIVES(playernatives)
{ "CanUserTarget", CanUserTarget },
{ "ChangeClientTeam", ChangeClientTeam },
{ "GetClientAuthString", sm_GetClientAuthStr },
{ "GetClientAuthId", sm_GetClientAuthId },
{ "GetSteamAccountID", sm_GetSteamAccountID },
{ "GetClientCount", sm_GetClientCount },
{ "GetClientInfo", sm_GetClientInfo },
+31
View File
@@ -36,6 +36,7 @@
#include <stdint.h>
#include <sys/time.h>
#endif
#include "ProfileTools.h"
struct Profiler
{
@@ -185,12 +186,42 @@ static cell_t GetProfilerTime(IPluginContext *pContext, const cell_t *params)
return sp_ftoc(fTime);
}
static cell_t EnterProfilingEvent(IPluginContext *pContext, const cell_t *params)
{
char *group;
pContext->LocalToString(params[1], &group);
char *name;
pContext->LocalToString(params[2], &name);
const char *groupname = NULL;
if (strcmp(group, "all") != 0)
groupname = group;
g_ProfileToolManager.EnterScope(groupname, name);
return 1;
}
static cell_t LeaveProfilingEvent(IPluginContext *pContext, const cell_t *params)
{
g_ProfileToolManager.LeaveScope();
return 1;
}
static cell_t IsProfilingActive(IPluginContext *pContext, const cell_t *params)
{
return g_ProfileToolManager.IsActive() ? 1 : 0;
}
REGISTER_NATIVES(profilerNatives)
{
{"CreateProfiler", CreateProfiler},
{"GetProfilerTime", GetProfilerTime},
{"StartProfiling", StartProfiling},
{"StopProfiling", StopProfiling},
{"EnterProfilingEvent", EnterProfilingEvent},
{"LeaveProfilingEvent", LeaveProfilingEvent},
{"IsProfilingActive", IsProfilingActive},
{NULL, NULL},
};
+76 -60
View File
@@ -1,8 +1,8 @@
/**
* vim: set ts=4 :
* vim: set ts=4 sw=4 tw=99 noet :
* =============================================================================
* SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
* Copyright (C) 2004-2014 AlliedModders LLC. All rights reserved.
* =============================================================================
*
* This program is free software; you can redistribute it and/or modify it under
@@ -32,6 +32,7 @@
#include "common_logic.h"
#include <ITextParsers.h>
#include <ISourceMod.h>
#include "handle_helpers.h"
HandleType_t g_TypeSMC = 0;
@@ -199,90 +200,51 @@ static cell_t SMC_CreateParser(IPluginContext *pContext, const cell_t *params)
static cell_t SMC_SetParseStart(IPluginContext *pContext, const cell_t *params)
{
Handle_t hndl = (Handle_t)params[1];
HandleError err;
ParseInfo *parse;
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
if ((err=handlesys->ReadHandle(hndl, g_TypeSMC, &sec, (void **)&parse))
!= HandleError_None)
{
return pContext->ThrowNativeError("Invalid SMC Parse Handle %x (error %d)", hndl, err);
}
OpenHandle<ParseInfo> parse(pContext, params[1], g_TypeSMC);
if (!parse.Ok())
return 0;
parse->parse_start = pContext->GetFunctionById((funcid_t)params[2]);
return 1;
}
static cell_t SMC_SetParseEnd(IPluginContext *pContext, const cell_t *params)
{
Handle_t hndl = (Handle_t)params[1];
HandleError err;
ParseInfo *parse;
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
if ((err=handlesys->ReadHandle(hndl, g_TypeSMC, &sec, (void **)&parse))
!= HandleError_None)
{
return pContext->ThrowNativeError("Invalid SMC Parse Handle %x (error %d)", hndl, err);
}
OpenHandle<ParseInfo> parse(pContext, params[1], g_TypeSMC);
if (!parse.Ok())
return 0;
parse->parse_end = pContext->GetFunctionById((funcid_t)params[2]);
return 1;
}
static cell_t SMC_SetReaders(IPluginContext *pContext, const cell_t *params)
{
Handle_t hndl = (Handle_t)params[1];
HandleError err;
ParseInfo *parse;
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
if ((err=handlesys->ReadHandle(hndl, g_TypeSMC, &sec, (void **)&parse))
!= HandleError_None)
{
return pContext->ThrowNativeError("Invalid SMC Parse Handle %x (error %d)", hndl, err);
}
OpenHandle<ParseInfo> parse(pContext, params[1], g_TypeSMC);
if (!parse.Ok())
return 0;
parse->new_section = pContext->GetFunctionById((funcid_t)params[2]);
parse->key_value = pContext->GetFunctionById((funcid_t)params[3]);
parse->end_section = pContext->GetFunctionById((funcid_t)params[4]);
return 1;
}
static cell_t SMC_SetRawLine(IPluginContext *pContext, const cell_t *params)
{
Handle_t hndl = (Handle_t)params[1];
HandleError err;
ParseInfo *parse;
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
if ((err=handlesys->ReadHandle(hndl, g_TypeSMC, &sec, (void **)&parse))
!= HandleError_None)
{
return pContext->ThrowNativeError("Invalid SMC Parse Handle %x (error %d)", hndl, err);
}
OpenHandle<ParseInfo> parse(pContext, params[1], g_TypeSMC);
if (!parse.Ok())
return 0;
parse->raw_line = pContext->GetFunctionById((funcid_t)params[2]);
return 1;
}
static cell_t SMC_ParseFile(IPluginContext *pContext, const cell_t *params)
{
Handle_t hndl = (Handle_t)params[1];
HandleError err;
ParseInfo *parse;
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
if ((err=handlesys->ReadHandle(hndl, g_TypeSMC, &sec, (void **)&parse))
!= HandleError_None)
{
return pContext->ThrowNativeError("Invalid SMC Parse Handle %x (error %d)", hndl, err);
}
OpenHandle<ParseInfo> parse(pContext, params[1], g_TypeSMC);
if (!parse.Ok())
return 0;
char *file;
pContext->LocalToString(params[2], &file);
@@ -299,21 +261,63 @@ static cell_t SMC_ParseFile(IPluginContext *pContext, const cell_t *params)
*c_line = states.line;
*c_col = states.col;
return (cell_t)p_err;
}
static cell_t SMC_GetErrorString(IPluginContext *pContext, const cell_t *params)
{
const char *str = textparsers->GetSMCErrorString((SMCError)params[1]);
if (!str)
{
return 0;
}
pContext->StringToLocal(params[2], params[3], str);
return 1;
}
static cell_t SMCParser_OnEnterSection_set(IPluginContext *pContext, const cell_t *params)
{
OpenHandle<ParseInfo> parse(pContext, params[1], g_TypeSMC);
if (!parse.Ok())
return 0;
parse->new_section = pContext->GetFunctionById((funcid_t)params[2]);
return 1;
}
static cell_t SMCParser_OnLeaveSection_set(IPluginContext *pContext, const cell_t *params)
{
OpenHandle<ParseInfo> parse(pContext, params[1], g_TypeSMC);
if (!parse.Ok())
return 0;
parse->end_section = pContext->GetFunctionById((funcid_t)params[2]);
return 1;
}
static cell_t SMCParser_OnKeyValue_set(IPluginContext *pContext, const cell_t *params)
{
OpenHandle<ParseInfo> parse(pContext, params[1], g_TypeSMC);
if (!parse.Ok())
return 0;
parse->key_value = pContext->GetFunctionById((funcid_t)params[2]);
return 1;
}
static cell_t SMCParser_GetErrorString(IPluginContext *pContext, const cell_t *params)
{
OpenHandle<ParseInfo> parse(pContext, params[1], g_TypeSMC);
if (!parse.Ok())
return 0;
const char *str = "no error";
if (params[2]) {
str = textparsers->GetSMCErrorString((SMCError)params[2]);
if (!str)
str = "unknown error";
}
pContext->StringToLocal(params[3], params[4], str);
return 1;
}
@@ -326,5 +330,17 @@ REGISTER_NATIVES(textNatives)
{"SMC_SetParseEnd", SMC_SetParseEnd},
{"SMC_SetReaders", SMC_SetReaders},
{"SMC_SetRawLine", SMC_SetRawLine},
// Transitional syntax support.
{"SMCParser.SMCParser", SMC_CreateParser},
{"SMCParser.ParseFile", SMC_ParseFile},
{"SMCParser.OnStart.set", SMC_SetParseStart},
{"SMCParser.OnEnd.set", SMC_SetParseEnd},
{"SMCParser.OnEnterSection.set", SMCParser_OnEnterSection_set},
{"SMCParser.OnLeaveSection.set", SMCParser_OnLeaveSection_set},
{"SMCParser.OnKeyValue.set", SMCParser_OnKeyValue_set},
{"SMCParser.OnRawLine.set", SMC_SetRawLine},
{"SMCParser.GetErrorString", SMCParser_GetErrorString},
{NULL, NULL},
};
+59 -39
View File
@@ -43,6 +43,7 @@
#include "logic_bridge.h"
#include "PlayerManager.h"
#include "HalfLife2.h"
#include "MenuManager.h"
#include "CoreConfig.h"
#include "ConCmdManager.h"
#include "IDBDriver.h"
@@ -86,6 +87,7 @@ IExtensionSys *extsys;
IHandleSys *handlesys;
IForwardManager *forwardsys;
IAdminSystem *adminsys;
ILogger *logger;
class VEngineServer_Logic : public IVEngineServer_Logic
{
@@ -146,6 +148,10 @@ public:
{
return filesystem->FindNext(handle);
}
bool FindIsDirectory(FileFindHandle_t handle)
{
return filesystem->FindIsDirectory(handle);
}
void FindClose(FileFindHandle_t handle)
{
filesystem->FindClose(handle);
@@ -174,6 +180,50 @@ public:
{
return filesystem->Size(pFileName, pPathID);
}
int Read(void* pOutput, int size, FileHandle_t file)
{
return filesystem->Read(pOutput, size, file);
}
int Write(void const* pInput, int size, FileHandle_t file)
{
return filesystem->Write(pInput, size, file);
}
void Seek(FileHandle_t file, int pos, int seekType)
{
filesystem->Seek(file, pos, (FileSystemSeek_t) seekType);
}
unsigned int Tell(FileHandle_t file)
{
return filesystem->Tell(file);
}
int FPrint(FileHandle_t file, const char *pData)
{
return filesystem->FPrintf(file, "%s", pData);
}
void Flush(FileHandle_t file)
{
filesystem->Flush(file);
}
bool IsOk(FileHandle_t file)
{
return filesystem->IsOk(file);
}
void RemoveFile(const char *pRelativePath, const char *pathID)
{
filesystem->RemoveFile(pRelativePath, pathID);
}
void RenameFile(char const *pOldPath, char const *pNewPath, const char *pathID)
{
filesystem->RenameFile(pOldPath, pNewPath, pathID);
}
bool IsDirectory(const char *pFileName, const char *pathID)
{
return filesystem->IsDirectory(pFileName, pathID);
}
void CreateDirHierarchy(const char *path, const char *pathID)
{
filesystem->CreateDirHierarchy(path, pathID);
}
};
static VFileSystem_Logic logic_filesystem;
@@ -251,46 +301,13 @@ static VPlayerInfo_Logic logic_playerinfo;
static ConVar sm_show_activity("sm_show_activity", "13", FCVAR_SPONLY, "Activity display setting (see sourcemod.cfg)");
static ConVar sm_immunity_mode("sm_immunity_mode", "1", FCVAR_SPONLY, "Mode for deciding immunity protection");
static ConVar sm_datetime_format("sm_datetime_format", "%m/%d/%Y - %H:%M:%S", 0, "Default formatting time rules");
static ConVar *find_convar(const char *name)
{
return icvar->FindVar(name);
}
static void log_error(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
g_Logger.LogErrorEx(fmt, ap);
va_end(ap);
}
static void log_fatal(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
g_Logger.LogFatalEx(fmt, ap);
va_end(ap);
}
static void log_message(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
g_Logger.LogMessageEx(fmt, ap);
va_end(ap);
}
static void log_to_file(FILE *fp, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
g_Logger.LogToOpenFileEx(fp, fmt, ap);
va_end(ap);
}
static void log_to_game(const char *message)
{
Engine_LogPrintWrapper(message);
@@ -306,6 +323,11 @@ static const char *get_cvar_string(ConVar* cvar)
return cvar->GetString();
}
static bool get_cvar_bool(ConVar* cvar)
{
return cvar->GetBool();
}
static bool get_game_name(char *buffer, size_t maxlength)
{
KeyValues *pGameInfo = new KeyValues("GameInfo");
@@ -555,19 +577,17 @@ static sm_core_t core_bridge =
&g_Timers,
&g_Players,
&g_HL2,
&g_Menus,
&g_pSourcePawn,
&g_pSourcePawn2,
/* Functions */
find_convar,
strncopy,
UTIL_TrimWhitespace,
log_error,
log_fatal,
log_message,
log_to_file,
log_to_game,
conprint,
get_cvar_string,
get_cvar_bool,
UTIL_Format,
UTIL_FormatArgs,
gnprintf,
@@ -628,7 +648,6 @@ void InitLogicBridge()
glob->m_pGlobalClassNext = logicore.head;
g_pThreader = logicore.threader;
g_pSourcePawn2->SetProfiler(logicore.profiler);
translator = logicore.translator;
scripts = logicore.scripts;
sharesys = logicore.sharesys;
@@ -637,6 +656,7 @@ void InitLogicBridge()
handlesys = logicore.handlesys;
forwardsys = logicore.forwardsys;
adminsys = logicore.adminsys;
logger = logicore.logger;
}
bool StartLogicBridge(char *error, size_t maxlength)
+1
View File
@@ -48,5 +48,6 @@ extern IExtensionSys *extsys;
extern IHandleSys *handlesys;
extern IForwardManager *forwardsys;
extern IAdminSystem *adminsys;
extern ILogger *logger;
#endif /* _INCLUDE_SOURCEMOD_LOGIC_BRIDGE_H_ */
+1 -7
View File
@@ -424,21 +424,15 @@ CON_COMMAND(sm_reload_translations, "Reparses all loaded translation files")
CON_COMMAND(sm_dump_admcache, "Dumps the admin cache for debugging")
{
FILE *fp;
char buffer[PLATFORM_MAX_PATH];
g_SourceMod.BuildPath(Path_SM, buffer, sizeof(buffer), "data/admin_cache_dump.txt");
if ((fp = fopen(buffer, "wt")) == NULL)
if (!logicore.DumpAdminCache(buffer))
{
g_RootMenu.ConsolePrint("Could not open file for writing: %s", buffer);
return;
}
logicore.DumpAdminCache(fp);
g_RootMenu.ConsolePrint("Admin cache dumped to: %s", buffer);
fclose(fp);
}
+1
View File
@@ -39,6 +39,7 @@
#include "logic_bridge.h"
#include "sourcemod.h"
#include <am-utility.h>
#include <am-float.h>
#define LADJUST 0x00000004 /* left adjustment */
#define ZEROPAD 0x00000080 /* zero (as opposed to blank) pad */
+33
View File
@@ -717,6 +717,39 @@ REGISTER_NATIVES(bitbufnatives)
{"BfReadVecNormal", smn_BfReadVecNormal},
{"BfReadAngles", smn_BfReadAngles},
{"BfGetNumBytesLeft", smn_BfGetNumBytesLeft},
// Transitional syntax support.
{"BfWrite.WriteBool", smn_BfWriteBool},
{"BfWrite.WriteByte", smn_BfWriteByte},
{"BfWrite.WriteChar", smn_BfWriteChar},
{"BfWrite.WriteShort", smn_BfWriteShort},
{"BfWrite.WriteWord", smn_BfWriteWord},
{"BfWrite.WriteNum", smn_BfWriteNum},
{"BfWrite.WriteFloat", smn_BfWriteFloat},
{"BfWrite.WriteString", smn_BfWriteString},
{"BfWrite.WriteEntity", smn_BfWriteEntity},
{"BfWrite.WriteAngle", smn_BfWriteAngle},
{"BfWrite.WriteCoord", smn_BfWriteCoord},
{"BfWrite.WriteVecCoord", smn_BfWriteVecCoord},
{"BfWrite.WriteVecNormal", smn_BfWriteVecNormal},
{"BfWrite.WriteAngles", smn_BfWriteAngles},
{"BfRead.ReadBool", smn_BfReadBool},
{"BfRead.ReadByte", smn_BfReadByte},
{"BfRead.ReadChar", smn_BfReadChar},
{"BfRead.ReadShort", smn_BfReadShort},
{"BfRead.ReadWord", smn_BfReadWord},
{"BfRead.ReadNum", smn_BfReadNum},
{"BfRead.ReadFloat", smn_BfReadFloat},
{"BfRead.ReadString", smn_BfReadString},
{"BfRead.ReadEntity", smn_BfReadEntity},
{"BfRead.ReadAngle", smn_BfReadAngle},
{"BfRead.ReadCoord", smn_BfReadCoord},
{"BfRead.ReadVecCoord", smn_BfReadVecCoord},
{"BfRead.ReadVecNormal", smn_BfReadVecNormal},
{"BfRead.ReadAngles", smn_BfReadAngles},
{"BfRead.BytesLeft.get", smn_BfGetNumBytesLeft},
{NULL, NULL}
};
+131
View File
@@ -0,0 +1,131 @@
/**
* vim: set ts=4 :
* =============================================================================
* SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
* =============================================================================
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, version 3.0, as published by the
* Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*
* As a special exception, AlliedModders LLC gives you permission to link the
* code of this program (as well as its derivative works) to "Half-Life 2," the
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
* by the Valve Corporation. You must obey the GNU General Public License in
* all respects for all other code used. Additionally, AlliedModders LLC grants
* this exception to all derivative works. AlliedModders LLC defines further
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
* or <http://www.sourcemod.net/license.php>.
*
* Version: $Id$
*/
#include "HalfLife2.h"
static cell_t sm_GetCommandLine(IPluginContext *pCtx, const cell_t *params)
{
ICommandLine *pCmdLine = g_HL2.GetValveCommandLine();
if (pCmdLine == NULL)
{
return pCtx->ThrowNativeError("Unable to get valve command line");
}
const char *commandLine = pCmdLine->GetCmdLine();
if (commandLine == NULL)
{
return 0;
}
pCtx->StringToLocal(params[1], params[2], commandLine);
return 1;
}
static cell_t sm_GetCommandLineParam(IPluginContext *pCtx, const cell_t *params)
{
ICommandLine *pCmdLine = g_HL2.GetValveCommandLine();
if (pCmdLine == NULL)
{
return pCtx->ThrowNativeError("Unable to get valve command line");
}
char *param = NULL;
char *defValue = NULL;
pCtx->LocalToString(params[1], &param);
pCtx->LocalToString(params[4], &param);
const char *value = pCmdLine->ParmValue(param, defValue);
pCtx->StringToLocal(params[2], params[3], value);
return 1;
}
static cell_t sm_GetCommandLineParamInt(IPluginContext *pCtx, const cell_t *params)
{
ICommandLine *pCmdLine = g_HL2.GetValveCommandLine();
if (pCmdLine == NULL)
{
return pCtx->ThrowNativeError("Unable to get valve command line");
}
char *param = NULL;
pCtx->LocalToString(params[1], &param);
return pCmdLine->ParmValue(param, params[2]);
}
static cell_t sm_GetCommandLineParamFloat(IPluginContext *pCtx, const cell_t *params)
{
ICommandLine *pCmdLine = g_HL2.GetValveCommandLine();
if (pCmdLine == NULL)
{
return pCtx->ThrowNativeError("Unable to get valve command line");
}
char *param = NULL;
pCtx->LocalToString(params[1], &param);
float value = pCmdLine->ParmValue(param, sp_ctof(params[2]));
return sp_ftoc(value);
}
static cell_t sm_FindCommandLineParam(IPluginContext *pCtx, const cell_t *params)
{
ICommandLine *pCmdLine = g_HL2.GetValveCommandLine();
if (pCmdLine == NULL)
{
return pCtx->ThrowNativeError("Unable to get valve command line");
}
char *param = NULL;
pCtx->LocalToString(params[1], &param);
return pCmdLine->FindParm(param);
}
REGISTER_NATIVES(commandlinenatives)
{
{"GetCommandLine", sm_GetCommandLine},
{"GetCommandLineParam", sm_GetCommandLineParam},
{"GetCommandLineParamInt", sm_GetCommandLineParamInt},
{"GetCommandLineParamFloat", sm_GetCommandLineParamFloat},
{"FindCommandLineParam", sm_FindCommandLineParam},
{NULL, NULL},
};
+78 -10
View File
@@ -1182,28 +1182,19 @@ static cell_t SendConVarValue(IPluginContext *pContext, const cell_t *params)
CPlayer *pPlayer = g_Players.GetPlayerByIndex(params[1]);
if (!pPlayer)
{
return pContext->ThrowNativeError("Client index %d is invalid", params[1]);
}
if (!pPlayer->IsConnected())
{
return pContext->ThrowNativeError("Client %d is not connected", params[1]);
}
if (pPlayer->IsFakeClient())
{
return pContext->ThrowNativeError("Client %d is fake and cannot be targeted", params[1]);
}
INetChannel *netchan = static_cast<INetChannel *>(engine->GetPlayerNetInfo(params[1]));
if (netchan == NULL)
{
return 0;
}
netchan->SendData(buffer);
return 1;
}
@@ -1216,7 +1207,7 @@ static cell_t AddCommandListener(IPluginContext *pContext, const cell_t *params)
if (strcasecmp(name, "sm") == 0)
{
g_Logger.LogError("Request to register \"sm\" command denied.");
logger->LogError("Request to register \"sm\" command denied.");
return 0;
}
@@ -1247,6 +1238,59 @@ static cell_t RemoveCommandListener(IPluginContext *pContext, const cell_t *para
return 1;
}
static cell_t ConVar_BoolValue_set(IPluginContext *pContext, const cell_t *params)
{
static cell_t new_params[5] = {
4,
params[1],
params[2],
0, /* Default replicate setting. */
0, /* Default replicate setting. */
};
return sm_SetConVarNum(pContext, new_params);
}
static cell_t ConVar_IntValue_set(IPluginContext *pContext, const cell_t *params)
{
static cell_t new_params[5] = {
4,
params[1],
params[2],
0, /* Default replicate setting. */
0, /* Default replicate setting. */
};
return sm_SetConVarNum(pContext, new_params);
}
static cell_t ConVar_FloatValue_set(IPluginContext *pContext, const cell_t *params)
{
static cell_t new_params[5] = {
4,
params[1],
params[2],
0, /* Default replicate setting. */
0, /* Default replicate setting. */
};
return sm_SetConVarFloat(pContext, new_params);
}
static cell_t ConVar_ReplicateToClient(IPluginContext *pContext, const cell_t *params)
{
// Old version is (client, handle, value).
// New version is (handle, client, value).
static cell_t new_params[4] = {
3,
params[2],
params[1],
params[3],
};
return SendConVarValue(pContext, new_params);
}
REGISTER_NATIVES(consoleNatives)
{
{"CreateConVar", sm_CreateConVar},
@@ -1287,5 +1331,29 @@ REGISTER_NATIVES(consoleNatives)
{"SendConVarValue", SendConVarValue},
{"AddCommandListener", AddCommandListener},
{"RemoveCommandListener", RemoveCommandListener},
// Transitional syntax support.
{"ConVar.BoolValue.get", sm_GetConVarBool},
{"ConVar.BoolValue.set", ConVar_BoolValue_set},
{"ConVar.FloatValue.get", sm_GetConVarFloat},
{"ConVar.FloatValue.set", ConVar_FloatValue_set},
{"ConVar.IntValue.get", sm_GetConVarInt},
{"ConVar.IntValue.set", ConVar_IntValue_set},
{"ConVar.Flags.get", sm_GetConVarFlags},
{"ConVar.Flags.set", sm_SetConVarFlags},
{"ConVar.SetBool", sm_SetConVarNum},
{"ConVar.SetInt", sm_SetConVarNum},
{"ConVar.SetFloat", sm_SetConVarFloat},
{"ConVar.GetString", sm_GetConVarString},
{"ConVar.SetString", sm_SetConVarString},
{"ConVar.RestoreDefault", sm_ResetConVar},
{"ConVar.GetDefault", GetConVarDefault},
{"ConVar.GetBounds", sm_GetConVarBounds},
{"ConVar.SetBounds", sm_SetConVarBounds},
{"ConVar.GetName", sm_GetConVarName},
{"ConVar.ReplicateToClient", ConVar_ReplicateToClient},
{"ConVar.AddChangeHook", sm_HookConVarChange},
{"ConVar.RemoveChangeHook", sm_UnhookConVarChange},
{NULL, NULL}
};
+112 -30
View File
@@ -1519,6 +1519,13 @@ static cell_t SetEntPropFloat(IPluginContext *pContext, const cell_t *params)
return 1;
}
enum PropEntType
{
PropEnt_Handle,
PropEnt_Entity,
PropEnt_Edict,
};
static cell_t GetEntPropEnt(IPluginContext *pContext, const cell_t *params)
{
CBaseEntity *pEntity;
@@ -1526,6 +1533,7 @@ static cell_t GetEntPropEnt(IPluginContext *pContext, const cell_t *params)
int offset;
int bit_count;
edict_t *pEdict;
PropEntType type;
int element = 0;
if (params[0] >= 4)
@@ -1548,12 +1556,23 @@ static cell_t GetEntPropEnt(IPluginContext *pContext, const cell_t *params)
FIND_PROP_DATA(td);
if (td->fieldType != FIELD_EHANDLE)
switch (td->fieldType)
{
return pContext->ThrowNativeError("Data field %s is not an entity (%d != %d)",
case FIELD_EHANDLE:
type = PropEnt_Handle;
break;
case FIELD_CLASSPTR:
type = PropEnt_Entity;
break;
#if SOURCE_ENGINE != SE_DOTA
case FIELD_EDICT:
type = PropEnt_Edict;
break;
#endif
default:
return pContext->ThrowNativeError("Data field %s is not an entity nor edict (%d)",
prop,
td->fieldType,
FIELD_EHANDLE);
td->fieldType);
}
CHECK_SET_PROP_DATA_OFFSET();
@@ -1562,6 +1581,7 @@ static cell_t GetEntPropEnt(IPluginContext *pContext, const cell_t *params)
}
case Prop_Send:
{
type = PropEnt_Handle;
FIND_PROP_SEND(DPT_Int, "integer");
break;
}
@@ -1571,13 +1591,34 @@ static cell_t GetEntPropEnt(IPluginContext *pContext, const cell_t *params)
}
}
CBaseHandle &hndl = *(CBaseHandle *)((uint8_t *)pEntity + offset);
CBaseEntity *pHandleEntity = g_HL2.ReferenceToEntity(hndl.GetEntryIndex());
switch (type)
{
case PropEnt_Handle:
{
CBaseHandle &hndl = *(CBaseHandle *) ((uint8_t *) pEntity + offset);
CBaseEntity *pHandleEntity = g_HL2.ReferenceToEntity(hndl.GetEntryIndex());
if (!pHandleEntity || hndl != reinterpret_cast<IHandleEntity *>(pHandleEntity)->GetRefEHandle())
return -1;
if (!pHandleEntity || hndl != reinterpret_cast<IHandleEntity *>(pHandleEntity)->GetRefEHandle())
return -1;
return g_HL2.EntityToBCompatRef(pHandleEntity);
return g_HL2.EntityToBCompatRef(pHandleEntity);
}
case PropEnt_Entity:
{
CBaseEntity *pPropEntity = *(CBaseEntity **) ((uint8_t *) pEntity + offset);
return g_HL2.EntityToBCompatRef(pPropEntity);
}
case PropEnt_Edict:
{
edict_t *pEdict = *(edict_t **) ((uint8_t *) pEntity + offset);
if (!pEdict || pEdict->IsFree())
return -1;
return IndexOfEdict(pEdict);
}
}
return -1;
}
static cell_t SetEntPropEnt(IPluginContext *pContext, const cell_t *params)
@@ -1587,6 +1628,7 @@ static cell_t SetEntPropEnt(IPluginContext *pContext, const cell_t *params)
int offset;
int bit_count;
edict_t *pEdict;
PropEntType type;
int element = 0;
if (params[0] >= 5)
@@ -1609,12 +1651,25 @@ static cell_t SetEntPropEnt(IPluginContext *pContext, const cell_t *params)
FIND_PROP_DATA(td);
if (td->fieldType != FIELD_EHANDLE)
switch (td->fieldType)
{
return pContext->ThrowNativeError("Data field %s is not an entity (%d != %d)",
case FIELD_EHANDLE:
type = PropEnt_Handle;
break;
case FIELD_CLASSPTR:
type = PropEnt_Entity;
break;
#if SOURCE_ENGINE != SE_DOTA
case FIELD_EDICT:
type = PropEnt_Edict;
if (!pEdict)
return pContext->ThrowNativeError("Edict %d is invalid", params[1]);
break;
#endif
default:
return pContext->ThrowNativeError("Data field %s is not an entity nor edict (%d)",
prop,
td->fieldType,
FIELD_EHANDLE);
td->fieldType);
}
CHECK_SET_PROP_DATA_OFFSET();
@@ -1623,6 +1678,7 @@ static cell_t SetEntPropEnt(IPluginContext *pContext, const cell_t *params)
}
case Prop_Send:
{
type = PropEnt_Handle;
FIND_PROP_SEND(DPT_Int, "integer");
break;
}
@@ -1632,28 +1688,54 @@ static cell_t SetEntPropEnt(IPluginContext *pContext, const cell_t *params)
}
}
CBaseHandle &hndl = *(CBaseHandle *)((uint8_t *)pEntity + offset);
if (params[4] == -1)
CBaseEntity *pOther = GetEntity(params[4]);
if (!pOther && params[4] != -1)
{
hndl.Set(NULL);
return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[4]), params[4]);
}
else
{
CBaseEntity *pOther = GetEntity(params[4]);
if (!pOther)
{
return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[4]), params[4]);
switch (type)
{
case PropEnt_Handle:
{
CBaseHandle &hndl = *(CBaseHandle *) ((uint8_t *) pEntity + offset);
hndl.Set((IHandleEntity *) pOther);
if (params[2] == Prop_Send && (pEdict != NULL))
{
g_HL2.SetEdictStateChanged(pEdict, offset);
}
}
IHandleEntity *pHandleEnt = (IHandleEntity *)pOther;
hndl.Set(pHandleEnt);
}
if (params[2] == Prop_Send && (pEdict != NULL))
{
g_HL2.SetEdictStateChanged(pEdict, offset);
break;
case PropEnt_Entity:
{
*(CBaseEntity **) ((uint8_t *) pEntity + offset) = pOther;
break;
}
case PropEnt_Edict:
{
edict_t *pOtherEdict = NULL;
if (pOther)
{
IServerNetworkable *pNetworkable = ((IServerUnknown *) pOther)->GetNetworkable();
if (!pNetworkable)
{
return pContext->ThrowNativeError("Entity %d (%d) does not have a valid edict", g_HL2.ReferenceToIndex(params[4]), params[4]);
}
pOtherEdict = pNetworkable->GetEdict();
if (!pOtherEdict || pOtherEdict->IsFree())
{
return pContext->ThrowNativeError("Entity %d (%d) does not have a valid edict", g_HL2.ReferenceToIndex(params[4]), params[4]);
}
}
*(edict_t **) ((uint8_t *) pEntity + offset) = pOtherEdict;
break;
}
}
return 1;
+44 -4
View File
@@ -207,7 +207,13 @@ static cell_t sm_GetEventBool(IPluginContext *pContext, const cell_t *params)
char *key;
pContext->LocalToString(params[2], &key);
return pInfo->pEvent->GetBool(key);
bool defValue = false;
if (params[0] > 2)
{
defValue = !!params[3];
}
return pInfo->pEvent->GetBool(key, defValue);
}
static cell_t sm_GetEventInt(IPluginContext *pContext, const cell_t *params)
@@ -226,7 +232,13 @@ static cell_t sm_GetEventInt(IPluginContext *pContext, const cell_t *params)
char *key;
pContext->LocalToString(params[2], &key);
return pInfo->pEvent->GetInt(key);
int defValue = 0;
if (params[0] > 2)
{
defValue = params[3];
}
return pInfo->pEvent->GetInt(key, defValue);
}
static cell_t sm_GetEventFloat(IPluginContext *pContext, const cell_t *params)
@@ -245,7 +257,13 @@ static cell_t sm_GetEventFloat(IPluginContext *pContext, const cell_t *params)
char *key;
pContext->LocalToString(params[2], &key);
float value = pInfo->pEvent->GetFloat(key);
float defValue = 0.0f;
if (params[0] > 2)
{
defValue = sp_ctof(params[3]);
}
float value = pInfo->pEvent->GetFloat(key, defValue);
return sp_ftoc(value);
}
@@ -266,7 +284,14 @@ static cell_t sm_GetEventString(IPluginContext *pContext, const cell_t *params)
char *key;
pContext->LocalToString(params[2], &key);
pContext->StringToLocalUTF8(params[3], params[4], pInfo->pEvent->GetString(key), NULL);
char *defValue = NULL;
if (params[0] > 4)
{
pContext->LocalToString(params[5], &defValue);
}
const char *value = pInfo->pEvent->GetString(key, defValue ? defValue : "");
pContext->StringToLocalUTF8(params[3], params[4], value, NULL);
return 1;
}
@@ -393,6 +418,21 @@ REGISTER_NATIVES(gameEventNatives)
{"SetEventFloat", sm_SetEventFloat},
{"SetEventString", sm_SetEventString},
{"SetEventBroadcast", sm_SetEventBroadcast},
// Transitional syntax support.
{"Event.Fire", sm_FireEvent},
{"Event.Cancel", sm_CancelCreatedEvent},
{"Event.GetName", sm_GetEventName},
{"Event.GetBool", sm_GetEventBool},
{"Event.GetInt", sm_GetEventInt},
{"Event.GetFloat", sm_GetEventFloat},
{"Event.GetString", sm_GetEventString},
{"Event.SetBool", sm_SetEventBool},
{"Event.SetInt", sm_SetEventInt},
{"Event.SetFloat", sm_SetEventFloat},
{"Event.SetString", sm_SetEventString},
{"Event.BroadcastDisabled.set", sm_SetEventBroadcast},
{NULL, NULL}
};
+47 -3
View File
@@ -35,9 +35,11 @@
#include "PlayerManager.h"
#include "HalfLife2.h"
#include <vstdlib/random.h>
static cell_t SetRandomSeed(IPluginContext *pContext, const cell_t *params)
{
engrandom->SetSeed(params[1]);
::RandomSeed(params[1]);
return 1;
}
@@ -47,14 +49,14 @@ static cell_t GetRandomFloat(IPluginContext *pContext, const cell_t *params)
float fMin = sp_ctof(params[1]);
float fMax = sp_ctof(params[2]);
float fRandom = engrandom->RandomFloat(fMin, fMax);
float fRandom = ::RandomFloat(fMin, fMax);
return sp_ftoc(fRandom);
}
static cell_t GetRandomInt(IPluginContext *pContext, const cell_t *params)
{
return engrandom->RandomInt(params[1], params[2]);
return ::RandomInt(params[1], params[2]);
}
static cell_t IsMapValid(IPluginContext *pContext, const cell_t *params)
@@ -570,6 +572,47 @@ static cell_t ReferenceToBCompatRef(IPluginContext *pContext, const cell_t *para
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)
{
{"CreateFakeClient", CreateFakeClient},
@@ -605,5 +648,6 @@ REGISTER_NATIVES(halflifeNatives)
{"EntIndexToEntRef", IndexToReference},
{"EntRefToEntIndex", ReferenceToIndex},
{"MakeCompatEntRef", ReferenceToBCompatRef},
{"GetClientsInRange", GetClientsInRange},
{NULL, NULL},
};
+76
View File
@@ -797,6 +797,32 @@ static cell_t smn_FileToKeyValues(IPluginContext *pCtx, const cell_t *params)
return g_HL2.KVLoadFromFile(kv, basefilesystem, path);
}
static cell_t smn_StringToKeyValues(IPluginContext *pCtx, const cell_t *params)
{
Handle_t hndl = static_cast<Handle_t>(params[1]);
HandleError herr;
HandleSecurity sec;
KeyValueStack *pStk;
KeyValues *kv;
sec.pOwner = NULL;
sec.pIdentity = g_pCoreIdent;
if ((herr=handlesys->ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
!= HandleError_None)
{
return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
}
char *buffer;
char *resourceName;
pCtx->LocalToString(params[2], &buffer);
pCtx->LocalToString(params[3], &resourceName);
kv = pStk->pCurRoot.front();
return kv->LoadFromBuffer(resourceName, buffer);
}
static cell_t smn_KvSetEscapeSequences(IPluginContext *pCtx, const cell_t *params)
{
Handle_t hndl = static_cast<Handle_t>(params[1]);
@@ -1075,6 +1101,18 @@ static cell_t smn_KvGetSectionSymbol(IPluginContext *pCtx, const cell_t *params)
return 1;
}
static cell_t KeyValues_Import(IPluginContext *pContext, const cell_t *params)
{
// This version takes (dest, src). The original is (src, dest).
cell_t new_params[3] = {
2,
params[2],
params[1],
};
return smn_CopySubkeys(pContext, new_params);
}
static KeyValueNatives s_KeyValueNatives;
REGISTER_NATIVES(keyvaluenatives)
@@ -1101,6 +1139,7 @@ REGISTER_NATIVES(keyvaluenatives)
{"KvGetDataType", smn_KvGetDataType},
{"KeyValuesToFile", smn_KeyValuesToFile},
{"FileToKeyValues", smn_FileToKeyValues},
{"StringToKeyValues", smn_StringToKeyValues},
{"KvSetEscapeSequences", smn_KvSetEscapeSequences},
{"KvDeleteThis", smn_KvDeleteThis},
{"KvDeleteKey", smn_KvDeleteKey},
@@ -1112,5 +1151,42 @@ REGISTER_NATIVES(keyvaluenatives)
{"KvGetSectionSymbol", smn_KvGetSectionSymbol},
{"KvGetVector", smn_KvGetVector},
{"KvSetVector", smn_KvSetVector},
// Transitional syntax support.
{"KeyValues.KeyValues", smn_CreateKeyValues},
{"KeyValues.SetString", smn_KvSetString},
{"KeyValues.SetNum", smn_KvSetNum},
{"KeyValues.SetUInt64", smn_KvSetUInt64},
{"KeyValues.SetFloat", smn_KvSetFloat},
{"KeyValues.SetColor", smn_KvSetColor},
{"KeyValues.GetString", smn_KvGetString},
{"KeyValues.GetNum", smn_KvGetNum},
{"KeyValues.GetFloat", smn_KvGetFloat},
{"KeyValues.GetColor", smn_KvGetColor},
{"KeyValues.GetUInt64", smn_KvGetUInt64},
{"KeyValues.JumpToKey", smn_KvJumpToKey},
{"KeyValues.JumpToKeySymbol", smn_KvJumpToKeySymbol},
{"KeyValues.GotoNextKey", smn_KvGotoNextKey},
{"KeyValues.GotoFirstSubKey", smn_KvGotoFirstSubKey},
{"KeyValues.GoBack", smn_KvGoBack},
{"KeyValues.Rewind", smn_KvRewind},
{"KeyValues.GetSectionName", smn_KvGetSectionName},
{"KeyValues.SetSectionName", smn_KvSetSectionName},
{"KeyValues.GetDataType", smn_KvGetDataType},
{"KeyValues.SetEscapeSequences", smn_KvSetEscapeSequences},
{"KeyValues.DeleteThis", smn_KvDeleteThis},
{"KeyValues.DeleteKey", smn_KvDeleteKey},
{"KeyValues.NodesInStack", smn_KvNodesInStack},
{"KeyValues.SavePosition", smn_KvSavePosition},
{"KeyValues.FindKeyById", smn_FindKeyById},
{"KeyValues.GetNameSymbol", smn_GetNameSymbol},
{"KeyValues.GetSectionSymbol", smn_KvGetSectionSymbol},
{"KeyValues.GetVector", smn_KvGetVector},
{"KeyValues.SetVector", smn_KvSetVector},
{"KeyValues.Import", KeyValues_Import},
{"KeyValues.ImportFromFile", smn_FileToKeyValues},
{"KeyValues.ImportFromString", smn_StringToKeyValues},
{"KeyValues.ExportToFile", smn_KeyValuesToFile},
{NULL, NULL}
};
+33 -1
View File
@@ -811,6 +811,38 @@ REGISTER_NATIVES(protobufnatives)
{"PbReadMessage", smn_PbReadMessage},
{"PbReadRepeatedMessage", smn_PbReadRepeatedMessage},
{"PbAddMessage", smn_PbAddMessage},
// Transitional syntax.
{"Protobuf.ReadInt", smn_PbReadInt},
{"Protobuf.ReadFloat", smn_PbReadFloat},
{"Protobuf.ReadBool", smn_PbReadBool},
{"Protobuf.ReadString", smn_PbReadString},
{"Protobuf.ReadColor", smn_PbReadColor},
{"Protobuf.ReadAngle", smn_PbReadAngle},
{"Protobuf.ReadVector", smn_PbReadVector},
{"Protobuf.ReadVector2D", smn_PbReadVector2D},
{"Protobuf.GetRepeatedFieldCount", smn_PbGetRepeatedFieldCount},
{"Protobuf.SetInt", smn_PbSetInt},
{"Protobuf.SetFloat", smn_PbSetFloat},
{"Protobuf.SetBool", smn_PbSetBool},
{"Protobuf.SetString", smn_PbSetString},
{"Protobuf.SetColor", smn_PbSetColor},
{"Protobuf.SetAngle", smn_PbSetAngle},
{"Protobuf.SetVector", smn_PbSetVector},
{"Protobuf.SetVector2D", smn_PbSetVector2D},
{"Protobuf.AddInt", smn_PbAddInt},
{"Protobuf.AddFloat", smn_PbAddFloat},
{"Protobuf.AddBool", smn_PbAddBool},
{"Protobuf.AddString", smn_PbAddString},
{"Protobuf.AddColor", smn_PbAddColor},
{"Protobuf.AddAngle", smn_PbAddAngle},
{"Protobuf.AddVector", smn_PbAddVector},
{"Protobuf.AddVector2D", smn_PbAddVector2D},
{"Protobuf.RemoveRepeatedFieldValue", smn_PbRemoveRepeatedFieldValue},
{"Protobuf.ReadMessage", smn_PbReadMessage},
{"Protobuf.ReadRepeatedMessage", smn_PbReadRepeatedMessage},
{"Protobuf.AddMessage", smn_PbAddMessage},
{NULL, NULL}
};
@@ -820,7 +852,7 @@ REGISTER_NATIVES(protobufnatives)
@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@ @@@@@@@@@@@@@
@@@@@@@@ @@@@@@@@@@@@@
@@@@@@@@ o @@@@@@@@@@@@@
@@@@@@ @@@@@@@@@@@@@@@
0000 @@@@@@@@@@@@@@@@@@@@@
000000000 @@@@@@@@@@@@@@@@@@@
+7 -3
View File
@@ -45,13 +45,15 @@ ISmmPluginManager *g_pMMPlugins = NULL;
CGlobalVars *gpGlobals = NULL;
ICvar *icvar = NULL;
IGameEventManager2 *gameevents = NULL;
IUniformRandomStream *engrandom = NULL;
CallClass<IVEngineServer> *enginePatch = NULL;
CallClass<IServerGameDLL> *gamedllPatch = NULL;
IPlayerInfoManager *playerinfo = NULL;
IBaseFileSystem *basefilesystem = NULL;
IFileSystem *filesystem = NULL;
IEngineSound *enginesound = NULL;
#if SOURCE_ENGINE >= SE_ORANGEBOX
IServerTools *servertools = NULL;
#endif
IServerPluginHelpers *serverpluginhelpers = NULL;
IServerPluginCallbacks *vsp_interface = NULL;
int vsp_version = 0;
@@ -67,10 +69,12 @@ bool SourceMod_Core::Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen
GET_V_IFACE_CURRENT(GetServerFactory, serverClients, IServerGameClients, INTERFACEVERSION_SERVERGAMECLIENTS);
GET_V_IFACE_CURRENT(GetEngineFactory, icvar, ICvar, CVAR_INTERFACE_VERSION);
GET_V_IFACE_CURRENT(GetEngineFactory, gameevents, IGameEventManager2, INTERFACEVERSION_GAMEEVENTSMANAGER2);
GET_V_IFACE_CURRENT(GetEngineFactory, engrandom, IUniformRandomStream, VENGINE_SERVER_RANDOM_INTERFACE_VERSION);
GET_V_IFACE_CURRENT(GetFileSystemFactory, basefilesystem, IBaseFileSystem, BASEFILESYSTEM_INTERFACE_VERSION);
GET_V_IFACE_CURRENT(GetFileSystemFactory, filesystem, IFileSystem, FILESYSTEM_INTERFACE_VERSION);
GET_V_IFACE_CURRENT(GetEngineFactory, enginesound, IEngineSound, IENGINESOUND_SERVER_INTERFACE_VERSION);
#if SOURCE_ENGINE >= SE_ORANGEBOX
GET_V_IFACE_CURRENT(GetServerFactory, servertools, IServerTools, VSERVERTOOLS_INTERFACE_VERSION);
#endif
#if SOURCE_ENGINE != SE_DOTA
GET_V_IFACE_CURRENT(GetEngineFactory, serverpluginhelpers, IServerPluginHelpers, INTERFACEVERSION_ISERVERPLUGINHELPERS);
#endif
@@ -167,7 +171,7 @@ void SourceMod_Core::OnVSPListening(IServerPluginCallbacks *iface)
/* This shouldn't happen */
if (!iface)
{
g_Logger.LogFatal("Metamod:Source version is out of date. SourceMod requires 1.4.2 or greater.");
logger->LogFatal("Metamod:Source version is out of date. SourceMod requires 1.4.2 or greater.");
return;
}
+4 -2
View File
@@ -47,9 +47,9 @@
#include <eiface.h>
#include <igameevents.h>
#include <iplayerinfo.h>
#include <random.h>
#include <filesystem.h>
#include <IEngineSound.h>
#include <toolframework/itoolentity.h>
#ifndef METAMOD_PLAPI_VERSION
#include <metamod_wrappers.h>
@@ -98,11 +98,13 @@ extern CGlobalVars *gpGlobals;
extern IGameEventManager2 *gameevents;
extern SourceHook::CallClass<IVEngineServer> *enginePatch;
extern SourceHook::CallClass<IServerGameDLL> *gamedllPatch;
extern IUniformRandomStream *engrandom;
extern IPlayerInfoManager *playerinfo;
extern IBaseFileSystem *basefilesystem;
extern IFileSystem *filesystem;
extern IEngineSound *enginesound;
#if SOURCE_ENGINE >= SE_ORANGEBOX
extern IServerTools *servertools;
#endif
extern IServerPluginHelpers *serverpluginhelpers;
extern IServerPluginCallbacks *vsp_interface;
extern int vsp_version;
+5 -4
View File
@@ -395,6 +395,7 @@ void SourceModBase::LevelShutdown()
{
g_pOnMapEnd->Execute(NULL);
}
extsys->CallOnCoreMapEnd();
g_Timers.RemoveMapChangeTimers();
@@ -572,9 +573,9 @@ void SourceModBase::LogMessage(IExtension *pExt, const char *format, ...)
if (tag)
{
g_Logger.LogMessage("[%s] %s", tag, buffer);
logger->LogMessage("[%s] %s", tag, buffer);
} else {
g_Logger.LogMessage("%s", buffer);
logger->LogMessage("%s", buffer);
}
}
@@ -591,9 +592,9 @@ void SourceModBase::LogError(IExtension *pExt, const char *format, ...)
if (tag)
{
g_Logger.LogError("[%s] %s", tag, buffer);
logger->LogError("[%s] %s", tag, buffer);
} else {
g_Logger.LogError("%s", buffer);
logger->LogError("%s", buffer);
}
}
+117
View File
@@ -0,0 +1,117 @@
// vim: set ts=4 sw=4 tw=99 noet :
// =============================================================================
// SourceMod
// Copyright (C) 2004-2014 AlliedModders LLC. All rights reserved.
// =============================================================================
//
// This program is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License, version 3.0, as published by the
// Free Software Foundation.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
// details.
//
// You should have received a copy of the GNU General Public License along with
// this program. If not, see <http://www.gnu.org/licenses/>.
//
// As a special exception, AlliedModders LLC gives you permission to link the
// code of this program (as well as its derivative works) to "Half-Life 2," the
// "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
// by the Valve Corporation. You must obey the GNU General Public License in
// all respects for all other code used. Additionally, AlliedModders LLC grants
// this exception to all derivative works. AlliedModders LLC defines further
// exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
// or <http://www.sourcemod.net/license.php>.
#include "vprof_tool.h"
#include "logic_bridge.h"
#include "sourcemod.h"
#include "sourcemm_api.h"
#define VPROF_ENABLED
#define RAD_TELEMETRY_DISABLED
#include <tier0/vprof.h>
VProfTool sVProfTool;
VProfTool::VProfTool()
: active_(false)
{
}
void
VProfTool::OnSourceModAllInitialized()
{
logicore.RegisterProfiler(this);
}
const char *
VProfTool::Name()
{
return "vprof";
}
const char *
VProfTool::Description()
{
return "Valve built-in profiler";
}
bool
VProfTool::Start()
{
g_VProfCurrentProfile.Start();
return IsActive();
}
void
VProfTool::Stop(void (*render)(const char *fmt, ...))
{
g_VProfCurrentProfile.Stop();
RenderHelp(render);
}
void
VProfTool::Dump()
{
g_VProfCurrentProfile.Pause();
g_VProfCurrentProfile.OutputReport(VPRT_FULL);
g_VProfCurrentProfile.Resume();
}
bool
VProfTool::IsActive()
{
return g_VProfCurrentProfile.IsEnabled();
}
bool
VProfTool::IsAttached()
{
return true;
}
void
VProfTool::EnterScope(const char *group, const char *name)
{
if (IsActive()) {
if (!group)
group = VPROF_BUDGETGROUP_OTHER_UNACCOUNTED;
g_VProfCurrentProfile.EnterScope(name, 1, group, false, 0);
}
}
void
VProfTool::LeaveScope()
{
if (IsActive())
g_VProfCurrentProfile.ExitScope();
}
void
VProfTool::RenderHelp(void (*render)(const char *fmt, ...))
{
render("Use 'sm prof dump vprof' or one of the vprof_generate_report commands in your console to analyze a profile session.");
}
+61
View File
@@ -0,0 +1,61 @@
// vim: set ts=4 sw=4 tw=99 noet :
// =============================================================================
// SourceMod
// Copyright (C) 2004-2014 AlliedModders LLC. All rights reserved.
// =============================================================================
//
// This program is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License, version 3.0, as published by the
// Free Software Foundation.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
// details.
//
// You should have received a copy of the GNU General Public License along with
// this program. If not, see <http://www.gnu.org/licenses/>.
//
// As a special exception, AlliedModders LLC gives you permission to link the
// code of this program (as well as its derivative works) to "Half-Life 2," the
// "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
// by the Valve Corporation. You must obey the GNU General Public License in
// all respects for all other code used. Additionally, AlliedModders LLC grants
// this exception to all derivative works. AlliedModders LLC defines further
// exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
// or <http://www.sourcemod.net/license.php>.
#ifndef _include_sourcemod_core_vprof_bridge_h_
#define _include_sourcemod_core_vprof_bridge_h_
#include <sp_vm_api.h>
#include "sm_globals.h"
#include <am-utility.h>
class VProfTool
: public IProfilingTool,
public SMGlobalClass
{
public:
VProfTool();
// IProfilingTool
const char *Name() KE_OVERRIDE;
const char *Description() KE_OVERRIDE;
bool Start() KE_OVERRIDE;
void Stop(void (*render)(const char *fmt, ...)) KE_OVERRIDE;
void Dump() KE_OVERRIDE;
bool IsActive() KE_OVERRIDE;
bool IsAttached() KE_OVERRIDE;
void EnterScope(const char *group, const char *name) KE_OVERRIDE;
void LeaveScope() KE_OVERRIDE;
void RenderHelp(void (*render)(const char *fmt, ...)) KE_OVERRIDE;
// SMGlobalClass
void OnSourceModAllInitialized() KE_OVERRIDE;
private:
bool active_;
};
#endif // _include_sourcemod_core_vprof_bridge_h_
+4
View File
@@ -8,6 +8,10 @@ binary.compiler.cxxincludes += [
os.path.join(builder.sourcePath, 'public', 'jit'),
os.path.join(builder.sourcePath, 'public', 'jit', 'x86'),
]
if binary.compiler.vendor == 'gcc' or binary.compiler.vendor == 'clang':
binary.compiler.cxxflags += ['-fno-rtti']
elif binary.compiler.vendor == 'msvc':
binary.compiler.cxxflags += ['/GR-']
binary.sources += [
'extension.cpp',
+4
View File
@@ -5,6 +5,10 @@ binary = SM.ExtLibrary(builder, 'clientprefs.ext')
binary.compiler.cxxincludes += [
os.path.join(SM.mms_root, 'core', 'sourcehook'),
]
if binary.compiler.vendor == 'gcc' or binary.compiler.vendor == 'clang':
binary.compiler.cxxflags += ['-fno-rtti']
elif binary.compiler.vendor == 'msvc':
binary.compiler.cxxflags += ['/GR-']
binary.sources += [
'extension.cpp',
+2 -2
View File
@@ -159,7 +159,7 @@ void CookieManager::OnClientAuthorized(int client, const char *authstring)
g_ClientPrefs.AttemptReconnection();
TQueryOp *op = new TQueryOp(Query_SelectData, player->GetSerial());
UTIL_strncpy(op->m_params.steamId, authstring, MAX_NAME_LENGTH);
UTIL_strncpy(op->m_params.steamId, GetPlayerCompatAuthId(player), MAX_NAME_LENGTH);
g_ClientPrefs.AddQueryToQueue(op);
}
@@ -181,7 +181,7 @@ void CookieManager::OnClientDisconnecting(int client)
if (player)
{
pAuth = player->GetAuthString();
pAuth = GetPlayerCompatAuthId(player);
g_ClientPrefs.ClearQueryCache(player->GetSerial());
}
+6 -27
View File
@@ -219,7 +219,7 @@ void ClientPrefs::DatabaseConnect()
char error[256];
int errCode = 0;
Database = Newborn<IDatabase>(Driver->Connect(DBInfo, true, error, sizeof(error)));
Database = AdoptRef(Driver->Connect(DBInfo, true, error, sizeof(error)));
if (!Database)
{
@@ -349,32 +349,11 @@ void ClientPrefs::ProcessQueryCache()
cachedQueries.clear();
}
size_t IsAuthIdConnected(char *authID)
const char *GetPlayerCompatAuthId(IGamePlayer *pPlayer)
{
IGamePlayer *player;
const char *authString;
for (int playerIndex = playerhelpers->GetMaxClients()+1; --playerIndex > 0;)
{
player = playerhelpers->GetGamePlayer(playerIndex);
if (player == NULL || !player->IsConnected())
{
continue;
}
authString = player->GetAuthString();
if (authString == NULL || authString[0] == '\0')
{
continue;
}
if (strcmp(authString, authID) == 0)
{
return playerIndex;
}
}
return 0;
/* For legacy reasons, OnClientAuthorized gives the Steam2 id here if using Steam auth */
const char *steamId = pPlayer->GetSteam2Id();
return steamId ? steamId : pPlayer->GetAuthString();
}
void ClientPrefs::CatchLateLoadClients()
@@ -394,7 +373,7 @@ void ClientPrefs::CatchLateLoadClients()
continue;
}
g_CookieManager.OnClientAuthorized(i, pPlayer->GetAuthString());
g_CookieManager.OnClientAuthorized(i, GetPlayerCompatAuthId(pPlayer));
}
}
+1 -1
View File
@@ -181,7 +181,7 @@ public:
}
};
size_t IsAuthIdConnected(char *authID);
const char *GetPlayerCompatAuthId(IGamePlayer *pPlayer);
extern sp_nativeinfo_t g_ClientPrefNatives[];
+25
View File
@@ -83,6 +83,31 @@ cell_t FindClientPrefCookie(IPluginContext *pContext, const cell_t *params)
NULL);
}
size_t IsAuthIdConnected(char *authID)
{
IGamePlayer *player;
const char *authString;
for (int playerIndex = playerhelpers->GetMaxClients()+1; --playerIndex > 0;)
{
player = playerhelpers->GetGamePlayer(playerIndex);
if (player == NULL || !player->IsAuthorized())
{
continue;
}
if (!strcmp(player->GetAuthString(), authID)
|| !strcmp(player->GetSteam2Id(), authID)
|| !strcmp(player->GetSteam3Id(), authID)
)
{
return playerIndex;
}
}
return 0;
}
cell_t SetAuthIdCookie(IPluginContext *pContext, const cell_t *params)
{
g_ClientPrefs.AttemptReconnection();
+40 -20
View File
@@ -61,9 +61,21 @@ DETOUR_DECL_MEMBER1(DetourHandleBuy, int, const char *, weapon)
#if SOURCE_ENGINE != SE_CSGO
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
{
int price = DETOUR_MEMBER_CALL(DetourWeaponPrice)();
#if SOURCE_ENGINE != SE_CSGO
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)
return price;
@@ -71,19 +83,6 @@ DETOUR_DECL_MEMBER0(DetourWeaponPrice, int)
return CallPriceForward(lastclient, weapon_name, price);
}
#else
DETOUR_DECL_MEMBER2(DetourWeaponPrice, int, const char *, szAttribute, CEconItemView *, pEconItem)
{
int price = DETOUR_MEMBER_CALL(DetourWeaponPrice)(szAttribute, pEconItem);
if(lastclient == -1 || strcmp(szAttribute, "in game price") != 0)
return price;
const char *weapon_name = reinterpret_cast<char *>(this+weaponNameOffset);
return CallPriceForward(lastclient, weapon_name, price);
}
#endif
#if SOURCE_ENGINE != SE_CSGO || !defined(WIN32)
DETOUR_DECL_MEMBER2(DetourTerminateRound, void, float, delay, int, reason)
@@ -152,12 +151,20 @@ DETOUR_DECL_MEMBER1(DetourTerminateRound, void, int, reason)
#endif
}
DETOUR_DECL_MEMBER3(DetourCSWeaponDrop, void, CBaseEntity *, weapon, bool, something, bool, toss)
#if SOURCE_ENGINE == SE_CSGO
DETOUR_DECL_MEMBER3(DetourCSWeaponDrop, void, CBaseEntity *, weapon, Vector, vec, bool, unknown)
#else
DETOUR_DECL_MEMBER3(DetourCSWeaponDrop, void, CBaseEntity *, weapon, bool, bDropShield, bool, bThrowForward)
#endif
{
if (g_pIgnoreCSWeaponDropDetour)
{
g_pIgnoreCSWeaponDropDetour = false;
DETOUR_MEMBER_CALL(DetourCSWeaponDrop)(weapon, something, toss);
#if SOURCE_ENGINE == SE_CSGO
DETOUR_MEMBER_CALL(DetourCSWeaponDrop)(weapon, vec, unknown);
#else
DETOUR_MEMBER_CALL(DetourCSWeaponDrop)(weapon, bDropShield, bThrowForward);
#endif
return;
}
@@ -170,8 +177,14 @@ DETOUR_DECL_MEMBER3(DetourCSWeaponDrop, void, CBaseEntity *, weapon, bool, somet
g_pCSWeaponDropForward->Execute(&result);
if (result == Pl_Continue)
DETOUR_MEMBER_CALL(DetourCSWeaponDrop)(weapon, something, toss);
if (result >= Pl_Continue)
{
#if SOURCE_ENGINE == SE_CSGO
DETOUR_MEMBER_CALL(DetourCSWeaponDrop)(weapon, vec, unknown);
#else
DETOUR_MEMBER_CALL(DetourCSWeaponDrop)(weapon, bDropShield, bThrowForward);
#endif
}
return;
}
@@ -187,8 +200,15 @@ bool CreateWeaponPriceDetour()
}
}
#if SOURCE_ENGINE == SE_CSGO
DWeaponPrice = DETOUR_CREATE_MEMBER(DetourWeaponPrice, "GetAttributeInt");
#if SOURCE_ENGINE == SE_CSGO && defined(WIN32)
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
DWeaponPrice = DETOUR_CREATE_MEMBER(DetourWeaponPrice, "GetWeaponPrice");
#endif
+70 -11
View File
@@ -226,6 +226,20 @@ static cell_t CS_DropWeapon(IPluginContext *pContext, const cell_t *params)
static ICallWrapper *pWrapper = NULL;
if (!pWrapper)
{
#if SOURCE_ENGINE == SE_CSGO
REGISTER_NATIVE_ADDR("CSWeaponDrop",
PassInfo pass[3]; \
pass[0].flags = PASSFLAG_BYVAL; \
pass[0].type = PassType_Basic; \
pass[0].size = sizeof(CBaseEntity *); \
pass[1].flags = PASSFLAG_BYVAL; \
pass[1].type = PassType_Basic; \
pass[1].size = sizeof(Vector); \
pass[2].flags = PASSFLAG_BYVAL; \
pass[2].type = PassType_Basic; \
pass[2].size = sizeof(bool); \
pWrapper = g_pBinTools->CreateCall(addr, CallConv_ThisCall, NULL, pass, 3))
#else
REGISTER_NATIVE_ADDR("CSWeaponDrop",
PassInfo pass[3]; \
pass[0].flags = PASSFLAG_BYVAL; \
@@ -238,6 +252,7 @@ static cell_t CS_DropWeapon(IPluginContext *pContext, const cell_t *params)
pass[2].type = PassType_Basic; \
pass[2].size = sizeof(bool); \
pWrapper = g_pBinTools->CreateCall(addr, CallConv_ThisCall, NULL, pass, 3))
#endif
}
CBaseEntity *pEntity;
@@ -270,7 +285,11 @@ static cell_t CS_DropWeapon(IPluginContext *pContext, const cell_t *params)
if (params[4] == 1 && g_pCSWeaponDropDetoured)
g_pIgnoreCSWeaponDropDetour = true;
#if SOURCE_ENGINE == SE_CSGO
unsigned char vstk[sizeof(CBaseEntity *) * 2 + sizeof(bool) + sizeof(Vector)];
#else
unsigned char vstk[sizeof(CBaseEntity *) * 2 + sizeof(bool) * 2];
#endif
unsigned char *vptr = vstk;
// <psychonic> first one is always false. second is true to toss, false to just drop
@@ -278,9 +297,15 @@ static cell_t CS_DropWeapon(IPluginContext *pContext, const cell_t *params)
vptr += sizeof(CBaseEntity *);
*(CBaseEntity **)vptr = pWeapon;
vptr += sizeof(CBaseEntity *);
#if SOURCE_ENGINE == SE_CSGO
*(Vector *)vptr = vec3_origin;
vptr += sizeof(Vector);
*(bool *)vptr = false;
#else
*(bool *)vptr = false;
vptr += sizeof(bool);
*(bool *)vptr = (params[3]) ? true : false;
#endif
pWrapper->Execute(vstk, NULL);
@@ -347,12 +372,10 @@ static cell_t CS_TerminateRound(IPluginContext *pContext, const cell_t *params)
float delay = sp_ctof(params[1]);
int reason = params[2];
signed int unknown = 1;//We might want to find what this is?
__asm
{
push reason
movss xmm1, delay
mov edi, unknown
mov ecx, gamerules
call addr
}
@@ -396,6 +419,7 @@ static cell_t CS_GetTranslatedWeaponAlias(IPluginContext *pContext, const cell_t
static cell_t CS_GetWeaponPrice(IPluginContext *pContext, const cell_t *params)
{
if (!IsValidWeaponID(params[2]))
return pContext->ThrowNativeError("Invalid WeaponID passed for this game");
@@ -403,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.
#if SOURCE_ENGINE == SE_CSGO
if (id == WEAPON_C4 || id == WEAPON_KNIFE || id == WEAPON_KNIFE_GG)
return 0;
#else
@@ -435,23 +460,49 @@ static cell_t CS_GetWeaponPrice(IPluginContext *pContext, const cell_t *params)
#if SOURCE_ENGINE == SE_CSGO
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)
{
REGISTER_NATIVE_ADDR("GetAttributeInt",
PassInfo pass[2]; \
REGISTER_NATIVE_ADDR("GetWeaponPrice",
PassInfo pass[3]; \
PassInfo ret; \
pass[0].flags = PASSFLAG_BYVAL; \
pass[0].type = PassType_Basic; \
pass[0].size = sizeof(char *); \
pass[0].size = sizeof(CEconItemView *); \
pass[1].flags = PASSFLAG_BYVAL; \
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.type = PassType_Basic; \
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
// Found in CCSPlayer::HandleCommand_Buy_Internal
// Linux a1 - CCSPlayer *pEntity, v5 - Player Team, a3 - ItemLoadoutSlot -1 use default loadoutslot:
@@ -529,14 +580,22 @@ static cell_t CS_GetWeaponPrice(IPluginContext *pContext, const cell_t *params)
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;
*(void **)vptr = info;
vptr += sizeof(void *);
*(const char **)vptr = "in game price";
vptr += sizeof(const char *);
*(CEconItemView **)vptr = view;
vptr += sizeof(CEconItemView *);
*(int *)vptr = 0;
#if !defined(WIN32)
vptr += sizeof(int);
*(float *)vptr = 1.0;
#endif
int price = 0;
pWrapper->Execute(vstk, &price);
+50
View File
@@ -229,6 +229,56 @@ const char *WeaponIDToAlias(int weaponID)
#endif
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)
{
#if SOURCE_ENGINE == SE_CSGO
+2
View File
@@ -165,4 +165,6 @@ int GetFakeWeaponID(int weaponId);
bool IsValidWeaponID(int weaponId);
void *GetWeaponPriceFunction();
#endif
+4
View File
@@ -8,6 +8,10 @@ binary.compiler.includes += [
os.path.join(builder.sourcePath, 'extensions', 'curl', 'curl-src', 'include')
]
binary.compiler.defines += ['CURL_STATICLIB']
if binary.compiler.vendor == 'gcc' or binary.compiler.vendor == 'clang':
binary.compiler.cxxflags += ['-fno-rtti']
elif binary.compiler.vendor == 'msvc':
binary.compiler.cxxflags += ['/GR-']
binary.compiler.postlink += [libcurl.binary]
if builder.target_platform == 'linux':
binary.compiler.postlink += ['-lrt']
+4
View File
@@ -2,6 +2,10 @@
import os
binary = SM.ExtLibrary(builder, 'geoip.ext')
if binary.compiler.vendor == 'gcc' or binary.compiler.vendor == 'clang':
binary.compiler.cxxflags += ['-fno-rtti']
elif binary.compiler.vendor == 'msvc':
binary.compiler.cxxflags += ['/GR-']
if builder.target_platform == 'windows':
binary.compiler.postlink += ['wsock32.lib']
+7 -1
View File
@@ -7,14 +7,20 @@ if SM.mysql_root:
os.path.join(SM.mysql_root, 'include'),
os.path.join(SM.mms_root, 'core', 'sourcehook')
]
if binary.compiler.vendor == 'gcc' or binary.compiler.vendor == 'clang':
binary.compiler.cxxflags += ['-fno-rtti']
elif binary.compiler.vendor == 'msvc':
binary.compiler.cxxflags += ['/GR-']
if builder.target_platform == 'linux' or builder.target_platform == 'mac':
binary.compiler.postlink += [
os.path.join(SM.mysql_root, 'lib', 'libmysqlclient_r.a'),
'-lz',
'-lpthread',
'-lm'
'-lm',
]
if builder.target_platform == 'linux':
binary.compiler.postlink += ['-lrt']
elif builder.target_platform == 'windows':
binary.compiler.postlink += [
os.path.join(SM.mysql_root, 'lib', 'opt', 'mysqlclient.lib'),
+3
View File
@@ -101,6 +101,9 @@ MyDatabase::MyDatabase(MYSQL *mysql, const DatabaseInfo *info, bool persistent)
m_Info.driver = NULL;
m_Info.maxTimeout = info->maxTimeout;
m_Info.port = info->port;
// DBI, for historical reasons, guarantees an initial refcount of 1.
AddRef();
}
MyDatabase::~MyDatabase()
+6 -1
View File
@@ -96,11 +96,16 @@ MYSQL *Connect(const DatabaseInfo *info, char *error, size_t maxlength)
MYSQL *mysql = mysql_init(NULL);
const char *host = NULL, *socket = NULL;
decltype(info->maxTimeout) timeout = 60;
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.
* This will prevent "MySQL server has gone away" errors after a while.
*/
+4
View File
@@ -5,6 +5,10 @@ binary = SM.ExtLibrary(builder, 'regex.ext')
binary.compiler.cxxincludes += [
os.path.join(SM.mms_root, 'core', 'sourcehook'),
]
if binary.compiler.vendor == 'gcc' or binary.compiler.vendor == 'clang':
binary.compiler.cxxflags += ['-fno-rtti']
elif binary.compiler.vendor == 'msvc':
binary.compiler.cxxflags += ['/GR-']
if builder.target_platform == 'linux':
path = os.path.join(builder.sourcePath, 'extensions', 'regex', 'lib_linux', 'libpcre.a')
+2 -2
View File
@@ -106,7 +106,7 @@ static cell_t MatchRegex(IPluginContext *pCtx, const cell_t *params)
if ((err=g_pHandleSys->ReadHandle(hndl, g_RegexHandle, &sec, (void **)&x)) != HandleError_None)
{
return pCtx->ThrowNativeError("Invalid file handle %x (error %d)", hndl, err);
return pCtx->ThrowNativeError("Invalid regex handle %x (error %d)", hndl, err);
}
if (!x)
@@ -159,7 +159,7 @@ static cell_t GetRegexSubString(IPluginContext *pCtx, const cell_t *params)
if ((err=g_pHandleSys->ReadHandle(hndl, g_RegexHandle, &sec, (void **)&x)) != HandleError_None)
{
return pCtx->ThrowNativeError("Invalid file handle %x (error %d)", hndl, err);
return pCtx->ThrowNativeError("Invalid regex handle %x (error %d)", hndl, err);
}
if (!x)
+162 -145
View File
@@ -88,6 +88,10 @@ HookTypeData g_HookTypes[SDKHook_MAXHOOKS] =
{"Reload", "DT_BaseCombatWeapon", false},
{"ReloadPost", "DT_BaseCombatWeapon", false},
{"GetMaxHealth", "", false},
{"Blocked", "", false},
{"BlockedPost", "", false},
{"OnTakeDamageAlive", "DT_BaseCombatCharacter", false},
{"OnTakeDamageAlivePost", "DT_BaseCombatCharacter", false},
};
SDKHooks g_Interface;
@@ -166,6 +170,7 @@ SH_DECL_MANUALHOOK0(GetMaxHealth, 0, 0, 0, int);
#endif
SH_DECL_MANUALHOOK1_void(GroundEntChanged, 0, 0, 0, void *);
SH_DECL_MANUALHOOK1(OnTakeDamage, 0, 0, 0, int, CTakeDamageInfoHack &);
SH_DECL_MANUALHOOK1(OnTakeDamage_Alive, 0, 0, 0, int, CTakeDamageInfoHack &);
SH_DECL_MANUALHOOK0_void(PreThink, 0, 0, 0);
SH_DECL_MANUALHOOK0_void(PostThink, 0, 0, 0);
SH_DECL_MANUALHOOK0(Reload, 0, 0, 0, bool);
@@ -191,6 +196,7 @@ SH_DECL_MANUALHOOK1(Weapon_CanUse, 0, 0, 0, bool, CBaseCombatWeapon *);
SH_DECL_MANUALHOOK3_void(Weapon_Drop, 0, 0, 0, CBaseCombatWeapon *, const Vector *, const Vector *);
SH_DECL_MANUALHOOK1_void(Weapon_Equip, 0, 0, 0, CBaseCombatWeapon *);
SH_DECL_MANUALHOOK2(Weapon_Switch, 0, 0, 0, bool, CBaseCombatWeapon *, int);
SH_DECL_MANUALHOOK1_void(Blocked, 0, 0, 0, CBaseEntity *);
/**
@@ -213,6 +219,26 @@ bool SDKHooks::SDK_OnLoad(char *error, size_t maxlength, bool late)
return false;
}
buffer[0] = '\0';
if (!gameconfs->LoadGameConfigFile("sdkhooks.games", &g_pGameConf, buffer, sizeof(buffer)))
{
if (buffer[0])
{
g_pSM->Format(error, maxlength, "Could not read sdkhooks.games gamedata: %s", buffer);
}
return false;
}
CUtlVector<IEntityListener *> *entListeners = EntListeners();
if (!entListeners)
{
g_pSM->Format(error, maxlength, "Failed to setup entity listeners");
return false;
}
entListeners->AddToTail(this);
sharesys->AddDependency(myself, "bintools.ext", true, true);
sharesys->AddNatives(myself, g_Natives);
sharesys->RegisterLibrary(myself, "sdkhooks");
@@ -231,26 +257,6 @@ bool SDKHooks::SDK_OnLoad(char *error, size_t maxlength, bool late)
#endif
g_pOnLevelInit = forwards->CreateForward("OnLevelInit", ET_Hook, 2, NULL, Param_String, Param_String);
buffer[0] = '\0';
if (!gameconfs->LoadGameConfigFile("sdkhooks.games", &g_pGameConf, buffer, sizeof(buffer)))
{
if (buffer[0])
{
g_pSM->Format(error, maxlength, "Could not read sdkhooks.games gamedata: %s", buffer);
}
return false;
}
CUtlVector<IEntityListener *> *entListeners = EntListeners();
if (!entListeners)
{
g_pSM->Format(error, maxlength, "Failed to setup entity listeners");
return false;
}
entListeners->AddToTail(this);
SetupHooks();
#if SOURCE_ENGINE >= SE_ORANGEBOX
@@ -438,6 +444,21 @@ FeatureStatus SDKHooks::GetFeatureStatus(FeatureType type, const char *name)
/**
* Functions
*/
static void PopulateCallbackList(const ke::Vector<HookList> &source, ke::Vector<IPluginFunction *> &destination, int entity)
{
destination.ensure(8); /* Skip trivial allocations as AMTL uses length<<1. */
for (size_t iter = 0; iter < source.length(); ++iter)
{
if (source[iter].entity != entity)
{
continue;
}
destination.append(source[iter].callback);
}
}
cell_t SDKHooks::Call(int entity, SDKHookType type, int other)
{
return Call(gamehelpers->ReferenceToEntity(entity), type, gamehelpers->ReferenceToEntity(other));
@@ -461,17 +482,14 @@ cell_t SDKHooks::Call(CBaseEntity *pEnt, SDKHookType type, CBaseEntity *pOther)
continue;
}
ke::Vector<HookList> &pawnlist = vtablehooklist[entry]->hooks;
int entity = gamehelpers->EntityToBCompatRef(pEnt);
int other = gamehelpers->EntityToBCompatRef(pOther);
for (entry = 0; entry < pawnlist.length(); ++entry)
{
if (entity != pawnlist[entry].entity)
{
continue;
}
IPluginFunction *callback = pawnlist[entry].callback;
ke::Vector<IPluginFunction *> callbackList;
PopulateCallbackList(vtablehooklist[entry]->hooks, callbackList, entity);
for (entry = 0; entry < callbackList.length(); ++entry)
{
IPluginFunction *callback = callbackList[entry];
callback->PushCell(entity);
callback->PushCell(other);
@@ -500,6 +518,7 @@ void SDKHooks::SetupHooks()
CHECKOFFSET(FireBullets, false, true);
CHECKOFFSET(GroundEntChanged, false, true);
CHECKOFFSET(OnTakeDamage, true, true);
CHECKOFFSET(OnTakeDamage_Alive,true, true);
CHECKOFFSET(PreThink, true, true);
CHECKOFFSET(PostThink, true, true);
CHECKOFFSET(Reload, true, true);
@@ -517,6 +536,7 @@ void SDKHooks::SetupHooks()
CHECKOFFSET_W(Equip, true, true);
CHECKOFFSET_W(Switch, true, true);
CHECKOFFSET(VPhysicsUpdate, true, true);
CHECKOFFSET(Blocked, true, true);
// this one is in a class all its own -_-
offset = 0;
@@ -591,6 +611,12 @@ HookReturn SDKHooks::Hook(int entity, SDKHookType type, IPluginFunction *callbac
case SDKHook_OnTakeDamagePost:
hookid = SH_ADD_MANUALVPHOOK(OnTakeDamage, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_OnTakeDamagePost), true);
break;
case SDKHook_OnTakeDamage_Alive:
hookid = SH_ADD_MANUALVPHOOK(OnTakeDamage_Alive, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_OnTakeDamage_Alive), false);
break;
case SDKHook_OnTakeDamage_AlivePost:
hookid = SH_ADD_MANUALVPHOOK(OnTakeDamage_Alive, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_OnTakeDamage_AlivePost), true);
break;
case SDKHook_PreThink:
hookid = SH_ADD_MANUALVPHOOK(PreThink, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_PreThink), false);
break;
@@ -687,6 +713,12 @@ HookReturn SDKHooks::Hook(int entity, SDKHookType type, IPluginFunction *callbac
case SDKHook_ShouldCollide:
hookid = SH_ADD_MANUALVPHOOK(ShouldCollide, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_ShouldCollide), false);
break;
case SDKHook_Blocked:
hookid = SH_ADD_MANUALVPHOOK(Blocked, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_Blocked), false);
break;
case SDKHook_BlockedPost:
hookid = SH_ADD_MANUALVPHOOK(Blocked, pEnt, SH_MEMBER(&g_Interface, &SDKHooks::Hook_BlockedPost), true);
break;
}
vhook.SetHookID(hookid);
@@ -862,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->Execute(&result);
if(result >= Pl_Handled)
RETURN_META_VALUE(MRES_SUPERCEDE, false);
if(result == Pl_Changed)
RETURN_META_VALUE_NEWPARAMS(MRES_HANDLED, true, &IServerGameDLL::LevelInit, (pMapName, g_szMapEntities, pOldLevel, pLandmarkName, loadGame, background));
@@ -914,15 +943,11 @@ void SDKHooks::Hook_FireBulletsPost(const FireBulletsInfo_t &info)
const char *weapon = pInfo->GetWeaponName();
ke::Vector<HookList> &pawnlist = vtablehooklist[entry]->hooks;
for (entry = 0; entry < pawnlist.length(); ++entry)
ke::Vector<IPluginFunction *> callbackList;
PopulateCallbackList(vtablehooklist[entry]->hooks, callbackList, entity);
for (entry = 0; entry < callbackList.length(); ++entry)
{
if (entity != pawnlist[entry].entity)
{
continue;
}
IPluginFunction *callback = pawnlist[entry].callback;
IPluginFunction *callback = callbackList[entry];
callback->PushCell(entity);
callback->PushCell(info.m_iShots);
callback->PushString(weapon?weapon:"");
@@ -956,15 +981,11 @@ int SDKHooks::Hook_GetMaxHealth()
cell_t res = Pl_Continue;
ke::Vector<HookList> &pawnlist = vtablehooklist[entry]->hooks;
for (entry = 0; entry < pawnlist.length(); ++entry)
ke::Vector<IPluginFunction *> callbackList;
PopulateCallbackList(vtablehooklist[entry]->hooks, callbackList, entity);
for (entry = 0; entry < callbackList.length(); ++entry)
{
if (entity != pawnlist[entry].entity)
{
continue;
}
IPluginFunction *callback = pawnlist[entry].callback;
IPluginFunction *callback = callbackList[entry];
callback->PushCell(entity);
callback->PushCellByRef(&new_max);
callback->Execute(&res);
@@ -985,12 +1006,12 @@ void SDKHooks::Hook_GroundEntChangedPost(void *pVar)
Call(META_IFACEPTR(CBaseEntity), SDKHook_GroundEntChangedPost);
}
int SDKHooks::Hook_OnTakeDamage(CTakeDamageInfoHack &info)
int SDKHooks::HandleOnTakeDamageHook(CTakeDamageInfoHack &info, SDKHookType hookType)
{
CBaseEntity *pEntity = META_IFACEPTR(CBaseEntity);
CVTableHook vhook(pEntity);
ke::Vector<CVTableList *> &vtablehooklist = g_HookList[SDKHook_OnTakeDamage];
ke::Vector<CVTableList *> &vtablehooklist = g_HookList[hookType];
for (size_t entry = 0; entry < vtablehooklist.length(); ++entry)
{
if (vhook != vtablehooklist[entry]->vtablehook)
@@ -1006,22 +1027,18 @@ int SDKHooks::Hook_OnTakeDamage(CTakeDamageInfoHack &info)
int weapon = info.GetWeapon();
Vector force = info.GetDamageForce();
cell_t damageForce[3] = {sp_ftoc(force.x), sp_ftoc(force.y), sp_ftoc(force.z)};
cell_t damageForce[3] = { sp_ftoc(force.x), sp_ftoc(force.y), sp_ftoc(force.z) };
Vector pos = info.GetDamagePosition();
cell_t damagePosition[3] = {sp_ftoc(pos.x), sp_ftoc(pos.y), sp_ftoc(pos.z)};
cell_t damagePosition[3] = { sp_ftoc(pos.x), sp_ftoc(pos.y), sp_ftoc(pos.z) };
cell_t res, ret = Pl_Continue;
ke::Vector<HookList> &pawnlist = vtablehooklist[entry]->hooks;
for (entry = 0; entry < pawnlist.length(); ++entry)
ke::Vector<IPluginFunction *> callbackList;
PopulateCallbackList(vtablehooklist[entry]->hooks, callbackList, entity);
for (entry = 0; entry < callbackList.length(); ++entry)
{
if (entity != pawnlist[entry].entity)
{
continue;
}
IPluginFunction *callback = pawnlist[entry].callback;
IPluginFunction *callback = callbackList[entry];
callback->PushCell(entity);
callback->PushCellByRef(&attacker);
callback->PushCellByRef(&inflictor);
@@ -1029,23 +1046,23 @@ int SDKHooks::Hook_OnTakeDamage(CTakeDamageInfoHack &info)
callback->PushCellByRef(&damagetype);
callback->PushCellByRef(&weapon);
callback->PushArray(damageForce, 3, SM_PARAM_COPYBACK);
callback->PushArray(damagePosition, 3, SM_PARAM_COPYBACK);
callback->PushArray(damagePosition, 3, SM_PARAM_COPYBACK);
callback->PushCell(info.GetDamageCustom());
callback->Execute(&res);
if(res >= ret)
if (res >= ret)
{
ret = res;
if(ret == Pl_Changed)
if (ret == Pl_Changed)
{
CBaseEntity *pEntAttacker = gamehelpers->ReferenceToEntity(attacker);
if(!pEntAttacker)
if (!pEntAttacker)
{
callback->GetParentRuntime()->GetDefaultContext()->ThrowNativeError("Entity %d for attacker is invalid", attacker);
RETURN_META_VALUE(MRES_IGNORED, 0);
}
CBaseEntity *pEntInflictor = gamehelpers->ReferenceToEntity(inflictor);
if(!pEntInflictor)
if (!pEntInflictor)
{
callback->GetParentRuntime()->GetDefaultContext()->ThrowNativeError("Entity %d for inflictor is invalid", inflictor);
RETURN_META_VALUE(MRES_IGNORED, 0);
@@ -1067,12 +1084,12 @@ int SDKHooks::Hook_OnTakeDamage(CTakeDamageInfoHack &info)
}
}
}
if(ret >= Pl_Handled)
if (ret >= Pl_Handled)
RETURN_META_VALUE(MRES_SUPERCEDE, 1);
if(ret == Pl_Changed)
RETURN_META_VALUE(MRES_HANDLED, 1);
if (ret == Pl_Changed)
RETURN_META_VALUE(MRES_HANDLED, 1);
break;
}
@@ -1080,12 +1097,12 @@ int SDKHooks::Hook_OnTakeDamage(CTakeDamageInfoHack &info)
RETURN_META_VALUE(MRES_IGNORED, 0);
}
int SDKHooks::Hook_OnTakeDamagePost(CTakeDamageInfoHack &info)
int SDKHooks::HandleOnTakeDamageHookPost(CTakeDamageInfoHack &info, SDKHookType hookType)
{
CBaseEntity *pEntity = META_IFACEPTR(CBaseEntity);
CVTableHook vhook(pEntity);
ke::Vector<CVTableList *> &vtablehooklist = g_HookList[SDKHook_OnTakeDamagePost];
ke::Vector<CVTableList *> &vtablehooklist = g_HookList[hookType];
for (size_t entry = 0; entry < vtablehooklist.length(); ++entry)
{
if (vhook != vtablehooklist[entry]->vtablehook)
@@ -1095,15 +1112,11 @@ int SDKHooks::Hook_OnTakeDamagePost(CTakeDamageInfoHack &info)
int entity = gamehelpers->EntityToBCompatRef(pEntity);
ke::Vector<HookList> &pawnlist = vtablehooklist[entry]->hooks;
for (entry = 0; entry < pawnlist.length(); ++entry)
ke::Vector<IPluginFunction *> callbackList;
PopulateCallbackList(vtablehooklist[entry]->hooks, callbackList, entity);
for (entry = 0; entry < callbackList.length(); ++entry)
{
if (entity != pawnlist[entry].entity)
{
continue;
}
IPluginFunction *callback = pawnlist[entry].callback;
IPluginFunction *callback = callbackList[entry];
callback->PushCell(entity);
callback->PushCell(info.GetAttacker());
callback->PushCell(info.GetInflictor());
@@ -1112,11 +1125,11 @@ int SDKHooks::Hook_OnTakeDamagePost(CTakeDamageInfoHack &info)
callback->PushCell(info.GetWeapon());
Vector force = info.GetDamageForce();
cell_t damageForce[3] = {sp_ftoc(force.x), sp_ftoc(force.y), sp_ftoc(force.z)};
cell_t damageForce[3] = { sp_ftoc(force.x), sp_ftoc(force.y), sp_ftoc(force.z) };
callback->PushArray(damageForce, 3);
Vector pos = info.GetDamagePosition();
cell_t damagePosition[3] = {sp_ftoc(pos.x), sp_ftoc(pos.y), sp_ftoc(pos.z)};
cell_t damagePosition[3] = { sp_ftoc(pos.x), sp_ftoc(pos.y), sp_ftoc(pos.z) };
callback->PushArray(damagePosition, 3);
callback->PushCell(info.GetDamageCustom());
@@ -1130,6 +1143,26 @@ int SDKHooks::Hook_OnTakeDamagePost(CTakeDamageInfoHack &info)
RETURN_META_VALUE(MRES_IGNORED, 0);
}
int SDKHooks::Hook_OnTakeDamage(CTakeDamageInfoHack &info)
{
return HandleOnTakeDamageHook(info, SDKHook_OnTakeDamage);
}
int SDKHooks::Hook_OnTakeDamagePost(CTakeDamageInfoHack &info)
{
return HandleOnTakeDamageHookPost(info, SDKHook_OnTakeDamagePost);
}
int SDKHooks::Hook_OnTakeDamage_Alive(CTakeDamageInfoHack &info)
{
return HandleOnTakeDamageHook(info, SDKHook_OnTakeDamage_Alive);
}
int SDKHooks::Hook_OnTakeDamage_AlivePost(CTakeDamageInfoHack &info)
{
return HandleOnTakeDamageHookPost(info, SDKHook_OnTakeDamage_AlivePost);
}
void SDKHooks::Hook_PreThink()
{
Call(META_IFACEPTR(CBaseEntity), SDKHook_PreThink);
@@ -1168,15 +1201,11 @@ bool SDKHooks::Hook_Reload()
int entity = gamehelpers->EntityToBCompatRef(pEntity);
cell_t res = Pl_Continue;
ke::Vector<HookList> &pawnlist = vtablehooklist[entry]->hooks;
for (entry = 0; entry < pawnlist.length(); ++entry)
ke::Vector<IPluginFunction *> callbackList;
PopulateCallbackList(vtablehooklist[entry]->hooks, callbackList, entity);
for (entry = 0; entry < callbackList.length(); ++entry)
{
if (entity != pawnlist[entry].entity)
{
continue;
}
IPluginFunction *callback = pawnlist[entry].callback;
IPluginFunction *callback = callbackList[entry];
callback->PushCell(entity);
callback->Execute(&res);
}
@@ -1195,7 +1224,7 @@ bool SDKHooks::Hook_ReloadPost()
CBaseEntity *pEntity = META_IFACEPTR(CBaseEntity);
CVTableHook vhook(pEntity);
ke::Vector<CVTableList *> &vtablehooklist = g_HookList[SDKHook_Reload];
ke::Vector<CVTableList *> &vtablehooklist = g_HookList[SDKHook_ReloadPost];
for (size_t entry = 0; entry < vtablehooklist.length(); ++entry)
{
if (vhook != vtablehooklist[entry]->vtablehook)
@@ -1206,15 +1235,11 @@ bool SDKHooks::Hook_ReloadPost()
int entity = gamehelpers->EntityToBCompatRef(pEntity);
cell_t origreturn = META_RESULT_ORIG_RET(bool) ? 1 : 0;
ke::Vector<HookList> &pawnlist = vtablehooklist[entry]->hooks;
for (entry = 0; entry < pawnlist.length(); ++entry)
ke::Vector<IPluginFunction *> callbackList;
PopulateCallbackList(vtablehooklist[entry]->hooks, callbackList, entity);
for (entry = 0; entry < callbackList.length(); ++entry)
{
if (entity != pawnlist[entry].entity)
{
continue;
}
IPluginFunction *callback = pawnlist[entry].callback;
IPluginFunction *callback = callbackList[entry];
callback->PushCell(entity);
callback->PushCell(origreturn);
callback->Execute(NULL);
@@ -1253,15 +1278,11 @@ bool SDKHooks::Hook_ShouldCollide(int collisionGroup, int contentsMask)
cell_t origRet = ((META_RESULT_STATUS >= MRES_OVERRIDE)?(META_RESULT_OVERRIDE_RET(bool)):(META_RESULT_ORIG_RET(bool))) ? 1 : 0;
cell_t res = 0;
ke::Vector<HookList> &pawnlist = vtablehooklist[entry]->hooks;
for (entry = 0; entry < pawnlist.length(); ++entry)
ke::Vector<IPluginFunction *> callbackList;
PopulateCallbackList(vtablehooklist[entry]->hooks, callbackList, entity);
for (entry = 0; entry < callbackList.length(); ++entry)
{
if (entity != pawnlist[entry].entity)
{
continue;
}
IPluginFunction *callback = pawnlist[entry].callback;
IPluginFunction *callback = callbackList[entry];
callback->PushCell(entity);
callback->PushCell(collisionGroup);
callback->PushCell(contentsMask);
@@ -1301,15 +1322,11 @@ void SDKHooks::Hook_Spawn()
int entity = gamehelpers->EntityToBCompatRef(pEntity);
cell_t res = Pl_Continue;
ke::Vector<HookList> &pawnlist = vtablehooklist[entry]->hooks;
for (entry = 0; entry < pawnlist.length(); ++entry)
ke::Vector<IPluginFunction *> callbackList;
PopulateCallbackList(vtablehooklist[entry]->hooks, callbackList, entity);
for (entry = 0; entry < callbackList.length(); ++entry)
{
if (entity != pawnlist[entry].entity)
{
continue;
}
IPluginFunction *callback = pawnlist[entry].callback;
IPluginFunction *callback = callbackList[entry];
callback->PushCell(entity);
callback->Execute(&res);
}
@@ -1399,15 +1416,11 @@ void SDKHooks::Hook_TraceAttack(CTakeDamageInfoHack &info, const Vector &vecDir,
int ammotype = info.GetAmmoType();
cell_t res, ret = Pl_Continue;
ke::Vector<HookList> &pawnlist = vtablehooklist[entry]->hooks;
for (entry = 0; entry < pawnlist.length(); ++entry)
ke::Vector<IPluginFunction *> callbackList;
PopulateCallbackList(vtablehooklist[entry]->hooks, callbackList, entity);
for (entry = 0; entry < callbackList.length(); ++entry)
{
if (entity != pawnlist[entry].entity)
{
continue;
}
IPluginFunction *callback = pawnlist[entry].callback;
IPluginFunction *callback = callbackList[entry];
callback->PushCell(entity);
callback->PushCellByRef(&attacker);
callback->PushCellByRef(&inflictor);
@@ -1477,15 +1490,11 @@ void SDKHooks::Hook_TraceAttackPost(CTakeDamageInfoHack &info, const Vector &vec
int entity = gamehelpers->EntityToBCompatRef(pEntity);
ke::Vector<HookList> &pawnlist = vtablehooklist[entry]->hooks;
for (entry = 0; entry < pawnlist.length(); ++entry)
ke::Vector<IPluginFunction *> callbackList;
PopulateCallbackList(vtablehooklist[entry]->hooks, callbackList, entity);
for (entry = 0; entry < callbackList.length(); ++entry)
{
if (entity != pawnlist[entry].entity)
{
continue;
}
IPluginFunction *callback = pawnlist[entry].callback;
IPluginFunction *callback = callbackList[entry];
callback->PushCell(entity);
callback->PushCell(info.GetAttacker());
callback->PushCell(info.GetInflictor());
@@ -1521,15 +1530,11 @@ void SDKHooks::Hook_Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE
int caller = gamehelpers->EntityToBCompatRef(pCaller);
cell_t ret = Pl_Continue;
ke::Vector<HookList> &pawnlist = vtablehooklist[entry]->hooks;
for (entry = 0; entry < pawnlist.length(); ++entry)
ke::Vector<IPluginFunction *> callbackList;
PopulateCallbackList(vtablehooklist[entry]->hooks, callbackList, entity);
for (entry = 0; entry < callbackList.length(); ++entry)
{
if (entity != pawnlist[entry].entity)
{
continue;
}
IPluginFunction *callback = pawnlist[entry].callback;
IPluginFunction *callback = callbackList[entry];
callback->PushCell(entity);
callback->PushCell(activator);
callback->PushCell(caller);
@@ -1564,15 +1569,11 @@ void SDKHooks::Hook_UsePost(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_T
int activator = gamehelpers->EntityToBCompatRef(pActivator);
int caller = gamehelpers->EntityToBCompatRef(pCaller);
ke::Vector<HookList> &pawnlist = vtablehooklist[entry]->hooks;
for (entry = 0; entry < pawnlist.length(); ++entry)
ke::Vector<IPluginFunction *> callbackList;
PopulateCallbackList(vtablehooklist[entry]->hooks, callbackList, entity);
for (entry = 0; entry < callbackList.length(); ++entry)
{
if (entity != pawnlist[entry].entity)
{
continue;
}
IPluginFunction *callback = pawnlist[entry].callback;
IPluginFunction *callback = callbackList[entry];
callback->PushCell(entity);
callback->PushCell(activator);
callback->PushCell(caller);
@@ -1612,6 +1613,22 @@ void SDKHooks::Hook_VPhysicsUpdatePost(IPhysicsObject *pPhysics)
Call(META_IFACEPTR(CBaseEntity), SDKHook_VPhysicsUpdatePost);
}
void SDKHooks::Hook_Blocked(CBaseEntity *pOther)
{
cell_t result = Call(META_IFACEPTR(CBaseEntity), SDKHook_Blocked, pOther);
if(result >= Pl_Handled)
RETURN_META(MRES_SUPERCEDE);
RETURN_META(MRES_IGNORED);
}
void SDKHooks::Hook_BlockedPost(CBaseEntity *pOther)
{
Call(META_IFACEPTR(CBaseEntity), SDKHook_BlockedPost, pOther);
RETURN_META(MRES_IGNORED);
}
bool SDKHooks::Hook_WeaponCanSwitchTo(CBaseCombatWeapon *pWeapon)
{
cell_t result = Call(META_IFACEPTR(CBaseEntity), SDKHook_WeaponCanSwitchTo, pWeapon);
+354 -342
View File
@@ -1,349 +1,361 @@
#ifndef _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_
#define _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_
#include "smsdk_ext.h"
#include <ISDKHooks.h>
#include <IBinTools.h>
#include <convar.h>
#include <sh_list.h>
#include <amtl/am-vector.h>
#include <vtable_hook_helper.h>
#include <iplayerinfo.h>
#include <shareddefs.h>
#if SOURCE_ENGINE >= SE_ORANGEBOX
#include <itoolentity.h>
#endif
#include "takedamageinfohack.h"
#ifndef METAMOD_PLAPI_VERSION
#define GetCGlobals pGlobals
#define GetEngineFactory engineFactory
#define GetServerFactory serverFactory
#endif
#if SOURCE_ENGINE >= SE_CSS && SOURCE_ENGINE != SE_LEFT4DEAD
#define GETMAXHEALTH_IS_VIRTUAL
#endif
#if SOURCE_ENGINE != SE_HL2DM && SOURCE_ENGINE != SE_DODS && SOURCE_ENGINE != SE_CSS && SOURCE_ENGINE != SE_TF2 && SOURCE_ENGINE != SE_LEFT4DEAD2 && SOURCE_ENGINE != SE_CSGO && SOURCE_ENGINE != SE_NUCLEARDAWN
#define GAMEDESC_CAN_CHANGE
#endif
#if SOURCE_ENGINE == SE_DOTA
class CEntityKeyValues;
#endif
/**
* Globals
*/
struct HookTypeData
{
const char *name;
const char *dtReq;
bool supported;
};
enum SDKHookType
{
SDKHook_EndTouch,
SDKHook_FireBulletsPost,
SDKHook_OnTakeDamage,
SDKHook_OnTakeDamagePost,
SDKHook_PreThink,
SDKHook_PostThink,
SDKHook_SetTransmit,
SDKHook_Spawn,
SDKHook_StartTouch,
SDKHook_Think,
SDKHook_Touch,
SDKHook_TraceAttack,
SDKHook_TraceAttackPost,
SDKHook_WeaponCanSwitchTo,
SDKHook_WeaponCanUse,
SDKHook_WeaponDrop,
SDKHook_WeaponEquip,
SDKHook_WeaponSwitch,
SDKHook_ShouldCollide,
SDKHook_PreThinkPost,
SDKHook_PostThinkPost,
SDKHook_ThinkPost,
SDKHook_EndTouchPost,
SDKHook_GroundEntChangedPost,
SDKHook_SpawnPost,
SDKHook_StartTouchPost,
SDKHook_TouchPost,
SDKHook_VPhysicsUpdate,
SDKHook_VPhysicsUpdatePost,
SDKHook_WeaponCanSwitchToPost,
SDKHook_WeaponCanUsePost,
SDKHook_WeaponDropPost,
SDKHook_WeaponEquipPost,
SDKHook_WeaponSwitchPost,
SDKHook_Use,
SDKHook_UsePost,
SDKHook_Reload,
SDKHook_ReloadPost,
SDKHook_GetMaxHealth,
SDKHook_MAXHOOKS
};
enum HookReturn
{
HookRet_Successful,
HookRet_InvalidEntity,
HookRet_InvalidHookType,
HookRet_NotSupported,
HookRet_BadEntForHookType,
};
#if SOURCE_ENGINE >= SE_CSS
typedef void *(*ReticulateSplines)();
#endif
/**
* Classes
*/
class IPhysicsObject;
class CDmgAccumulator;
typedef CBaseEntity CBaseCombatWeapon;
struct HookList
{
public:
int entity;
IPluginFunction *callback;
};
class CVTableList
{
public:
CVTableList() : vtablehook(NULL)
{
};
~CVTableList()
{
delete vtablehook;
};
public:
CVTableHook *vtablehook;
ke::Vector<HookList> hooks;
};
#ifndef _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_
#define _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_
#include "smsdk_ext.h"
#include <ISDKHooks.h>
#include <IBinTools.h>
#include <convar.h>
#include <sh_list.h>
#include <amtl/am-vector.h>
#include <vtable_hook_helper.h>
#include <iplayerinfo.h>
#include <shareddefs.h>
#if SOURCE_ENGINE >= SE_ORANGEBOX
#include <itoolentity.h>
#endif
#include "takedamageinfohack.h"
#ifndef METAMOD_PLAPI_VERSION
#define GetCGlobals pGlobals
#define GetEngineFactory engineFactory
#define GetServerFactory serverFactory
#endif
#if SOURCE_ENGINE >= SE_CSS && SOURCE_ENGINE != SE_LEFT4DEAD
#define GETMAXHEALTH_IS_VIRTUAL
#endif
#if SOURCE_ENGINE != SE_HL2DM && SOURCE_ENGINE != SE_DODS && SOURCE_ENGINE != SE_CSS && SOURCE_ENGINE != SE_TF2 && SOURCE_ENGINE != SE_LEFT4DEAD2 && SOURCE_ENGINE != SE_CSGO && SOURCE_ENGINE != SE_NUCLEARDAWN
#define GAMEDESC_CAN_CHANGE
#endif
#if SOURCE_ENGINE == SE_DOTA
class CEntityKeyValues;
#endif
/**
* Globals
*/
struct HookTypeData
{
const char *name;
const char *dtReq;
bool supported;
};
enum SDKHookType
{
SDKHook_EndTouch,
SDKHook_FireBulletsPost,
SDKHook_OnTakeDamage,
SDKHook_OnTakeDamagePost,
SDKHook_PreThink,
SDKHook_PostThink,
SDKHook_SetTransmit,
SDKHook_Spawn,
SDKHook_StartTouch,
SDKHook_Think,
SDKHook_Touch,
SDKHook_TraceAttack,
SDKHook_TraceAttackPost,
SDKHook_WeaponCanSwitchTo,
SDKHook_WeaponCanUse,
SDKHook_WeaponDrop,
SDKHook_WeaponEquip,
SDKHook_WeaponSwitch,
SDKHook_ShouldCollide,
SDKHook_PreThinkPost,
SDKHook_PostThinkPost,
SDKHook_ThinkPost,
SDKHook_EndTouchPost,
SDKHook_GroundEntChangedPost,
SDKHook_SpawnPost,
SDKHook_StartTouchPost,
SDKHook_TouchPost,
SDKHook_VPhysicsUpdate,
SDKHook_VPhysicsUpdatePost,
SDKHook_WeaponCanSwitchToPost,
SDKHook_WeaponCanUsePost,
SDKHook_WeaponDropPost,
SDKHook_WeaponEquipPost,
SDKHook_WeaponSwitchPost,
SDKHook_Use,
SDKHook_UsePost,
SDKHook_Reload,
SDKHook_ReloadPost,
SDKHook_GetMaxHealth,
SDKHook_Blocked,
SDKHook_BlockedPost,
SDKHook_OnTakeDamage_Alive,
SDKHook_OnTakeDamage_AlivePost,
SDKHook_MAXHOOKS
};
enum HookReturn
{
HookRet_Successful,
HookRet_InvalidEntity,
HookRet_InvalidHookType,
HookRet_NotSupported,
HookRet_BadEntForHookType,
};
#if SOURCE_ENGINE >= SE_CSS
typedef void *(*ReticulateSplines)();
#endif
/**
* Classes
*/
class IPhysicsObject;
class CDmgAccumulator;
typedef CBaseEntity CBaseCombatWeapon;
struct HookList
{
public:
int entity;
IPluginFunction *callback;
};
class CVTableList
{
public:
CVTableList() : vtablehook(NULL)
{
};
~CVTableList()
{
delete vtablehook;
};
public:
CVTableHook *vtablehook;
ke::Vector<HookList> hooks;
};
class IEntityListener
{
public:
virtual void OnEntityCreated( CBaseEntity *pEntity ) {};
virtual void OnEntitySpawned( CBaseEntity *pEntity ) {};
virtual void OnEntityDeleted( CBaseEntity *pEntity ) {};
};
class SDKHooks :
public SDKExtension,
public IConCommandBaseAccessor,
public IPluginsListener,
public IFeatureProvider,
public IEntityListener,
public IClientListener,
public ISDKHooks
{
public:
/**
* @brief This is called after the initial loading sequence has been processed.
*
* @param error Error message buffer.
* @param maxlength Size of error message buffer.
* @param late Whether or not the module was loaded after map load.
* @return True to succeed loading, false to fail.
*/
virtual bool SDK_OnLoad(char *error, size_t maxlength, bool late);
/**
* @brief This is called right before the extension is unloaded.
*/
virtual void SDK_OnUnload();
/**
* @brief This is called once all known extensions have been loaded.
* Note: It is is a good idea to add natives here, if any are provided.
*/
virtual void SDK_OnAllLoaded();
/**
* @brief Called when the pause state is changed.
*/
//virtual void SDK_OnPauseChange(bool paused);
/**
* @brief this is called when Core wants to know if your extension is working.
*
* @param error Error message buffer.
* @param maxlength Size of error message buffer.
* @return True if working, false otherwise.
*/
//virtual bool QueryRunning(char *error, size_t maxlength);
/** Returns version string */
virtual const char *GetExtensionVerString();
/** Returns date string */
virtual const char *GetExtensionDateString();
public:
#if defined SMEXT_CONF_METAMOD
/**
* @brief Called when Metamod is attached, before the extension version is called.
*
* @param error Error buffer.
* @param maxlength Maximum size of error buffer.
* @param late Whether or not Metamod considers this a late load.
* @return True to succeed, false to fail.
*/
virtual bool SDK_OnMetamodLoad(ISmmAPI *ismm, char *error, size_t maxlength, bool late);
/**
* @brief Called when Metamod is detaching, after the extension version is called.
* NOTE: By default this is blocked unless sent from SourceMod.
*
* @param error Error buffer.
* @param maxlength Maximum size of error buffer.
* @return True to succeed, false to fail.
*/
//virtual bool SDK_OnMetamodUnload(char *error, size_t maxlength);
/**
* @brief Called when Metamod's pause state is changing.
* NOTE: By default this is blocked unless sent from SourceMod.
*
* @param paused Pause state being set.
* @param error Error buffer.
* @param maxlength Maximum size of error buffer.
* @return True to succeed, false to fail.
*/
//virtual bool SDK_OnMetamodPauseChange(bool paused, char *error, size_t maxlength);
#endif
public: // IPluginsListener
virtual void OnPluginLoaded(IPlugin *plugin);
virtual void OnPluginUnloaded(IPlugin *plugin);
public: // IConCommandBaseAccessor
virtual bool RegisterConCommandBase(ConCommandBase *pVar);
public: // IFeatureProvider
virtual FeatureStatus GetFeatureStatus(FeatureType type, const char *name);
public: // IEntityListener
virtual void OnEntityCreated(CBaseEntity *pEntity);
virtual void OnEntityDeleted(CBaseEntity *pEntity);
public: // IClientListener
virtual void OnClientPutInServer(int client);
virtual void OnClientDisconnecting(int client);
public: // ISDKHooks
virtual void AddEntityListener(ISMEntityListener *listener);
virtual void RemoveEntityListener(ISMEntityListener *listener);
private:
SourceHook::List<ISMEntityListener *> m_EntListeners;
public:
/**
* Functions
*/
};
class SDKHooks :
public SDKExtension,
public IConCommandBaseAccessor,
public IPluginsListener,
public IFeatureProvider,
public IEntityListener,
public IClientListener,
public ISDKHooks
{
public:
/**
* @brief This is called after the initial loading sequence has been processed.
*
* @param error Error message buffer.
* @param maxlength Size of error message buffer.
* @param late Whether or not the module was loaded after map load.
* @return True to succeed loading, false to fail.
*/
virtual bool SDK_OnLoad(char *error, size_t maxlength, bool late);
/**
* @brief This is called right before the extension is unloaded.
*/
virtual void SDK_OnUnload();
/**
* @brief This is called once all known extensions have been loaded.
* Note: It is is a good idea to add natives here, if any are provided.
*/
virtual void SDK_OnAllLoaded();
/**
* @brief Called when the pause state is changed.
*/
//virtual void SDK_OnPauseChange(bool paused);
/**
* @brief this is called when Core wants to know if your extension is working.
*
* @param error Error message buffer.
* @param maxlength Size of error message buffer.
* @return True if working, false otherwise.
*/
//virtual bool QueryRunning(char *error, size_t maxlength);
/** Returns version string */
virtual const char *GetExtensionVerString();
/** Returns date string */
virtual const char *GetExtensionDateString();
public:
#if defined SMEXT_CONF_METAMOD
/**
* @brief Called when Metamod is attached, before the extension version is called.
*
* @param error Error buffer.
* @param maxlength Maximum size of error buffer.
* @param late Whether or not Metamod considers this a late load.
* @return True to succeed, false to fail.
*/
virtual bool SDK_OnMetamodLoad(ISmmAPI *ismm, char *error, size_t maxlength, bool late);
/**
* @brief Called when Metamod is detaching, after the extension version is called.
* NOTE: By default this is blocked unless sent from SourceMod.
*
* @param error Error buffer.
* @param maxlength Maximum size of error buffer.
* @return True to succeed, false to fail.
*/
//virtual bool SDK_OnMetamodUnload(char *error, size_t maxlength);
/**
* @brief Called when Metamod's pause state is changing.
* NOTE: By default this is blocked unless sent from SourceMod.
*
* @param paused Pause state being set.
* @param error Error buffer.
* @param maxlength Maximum size of error buffer.
* @return True to succeed, false to fail.
*/
//virtual bool SDK_OnMetamodPauseChange(bool paused, char *error, size_t maxlength);
#endif
public: // IPluginsListener
virtual void OnPluginLoaded(IPlugin *plugin);
virtual void OnPluginUnloaded(IPlugin *plugin);
public: // IConCommandBaseAccessor
virtual bool RegisterConCommandBase(ConCommandBase *pVar);
public: // IFeatureProvider
virtual FeatureStatus GetFeatureStatus(FeatureType type, const char *name);
public: // IEntityListener
virtual void OnEntityCreated(CBaseEntity *pEntity);
virtual void OnEntityDeleted(CBaseEntity *pEntity);
public: // IClientListener
virtual void OnClientPutInServer(int client);
virtual void OnClientDisconnecting(int client);
public: // ISDKHooks
virtual void AddEntityListener(ISMEntityListener *listener);
virtual void RemoveEntityListener(ISMEntityListener *listener);
private:
SourceHook::List<ISMEntityListener *> m_EntListeners;
public:
/**
* Functions
*/
cell_t Call(int entity, SDKHookType type, int other=INVALID_EHANDLE_INDEX);
cell_t Call(CBaseEntity *pEnt, SDKHookType type, int other=INVALID_EHANDLE_INDEX);
cell_t Call(CBaseEntity *pEnt, SDKHookType type, CBaseEntity *pOther);
void SetupHooks();
HookReturn Hook(int entity, SDKHookType type, IPluginFunction *pCallback);
void Unhook(int entity, SDKHookType type, IPluginFunction *pCallback);
/**
* IServerGameDLL & IVEngineServer Hook Handlers
*/
#ifdef GAMEDESC_CAN_CHANGE
const char *Hook_GetGameDescription();
#endif
const char *Hook_GetMapEntitiesString();
bool Hook_LevelInit(char const *pMapName, char const *pMapEntities, char const *pOldLevel, char const *pLandmarkName, bool loadGame, bool background);
/**
* CBaseEntity Hook Handlers
*/
void Hook_EndTouch(CBaseEntity *pOther);
void Hook_EndTouchPost(CBaseEntity *pOther);
void Hook_FireBulletsPost(const FireBulletsInfo_t &info);
#ifdef GETMAXHEALTH_IS_VIRTUAL
int Hook_GetMaxHealth();
#endif
void Hook_GroundEntChangedPost(void *pVar);
int Hook_OnTakeDamage(CTakeDamageInfoHack &info);
int Hook_OnTakeDamagePost(CTakeDamageInfoHack &info);
void Hook_PreThink();
void Hook_PreThinkPost();
void Hook_PostThink();
void Hook_PostThinkPost();
bool Hook_Reload();
bool Hook_ReloadPost();
void Hook_SetTransmit(CCheckTransmitInfo *pInfo, bool bAlways);
bool Hook_ShouldCollide(int collisonGroup, int contentsMask);
#if SOURCE_ENGINE == SE_DOTA
void Hook_Spawn(CEntityKeyValues *kv);
void Hook_SpawnPost(CEntityKeyValues *kv);
#else
void Hook_Spawn();
void Hook_SpawnPost();
#endif
void Hook_StartTouch(CBaseEntity *pOther);
void Hook_StartTouchPost(CBaseEntity *pOther);
void Hook_Think();
void Hook_ThinkPost();
void Hook_Touch(CBaseEntity *pOther);
void Hook_TouchPost(CBaseEntity *pOther);
#if SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_TF2 || SOURCE_ENGINE == SE_SDK2013
void Hook_TraceAttack(CTakeDamageInfoHack &info, const Vector &vecDir, trace_t *ptr, CDmgAccumulator *pAccumulator);
void Hook_TraceAttackPost(CTakeDamageInfoHack &info, const Vector &vecDir, trace_t *ptr, CDmgAccumulator *pAccumulator);
#else
void Hook_TraceAttack(CTakeDamageInfoHack &info, const Vector &vecDir, trace_t *ptr);
void Hook_TraceAttackPost(CTakeDamageInfoHack &info, const Vector &vecDir, trace_t *ptr);
#endif
void Hook_UpdateOnRemove();
void Hook_Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value);
void Hook_UsePost(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value);
void Hook_VPhysicsUpdate(IPhysicsObject *pPhysics);
void Hook_VPhysicsUpdatePost(IPhysicsObject *pPhysics);
bool Hook_WeaponCanSwitchTo(CBaseCombatWeapon *pWeapon);
bool Hook_WeaponCanSwitchToPost(CBaseCombatWeapon *pWeapon);
bool Hook_WeaponCanUse(CBaseCombatWeapon *pWeapon);
bool Hook_WeaponCanUsePost(CBaseCombatWeapon *pWeapon);
void Hook_WeaponDrop(CBaseCombatWeapon *pWeapon, const Vector *pvecTarget, const Vector *pVelocity);
void Hook_WeaponDropPost(CBaseCombatWeapon *pWeapon, const Vector *pvecTarget, const Vector *pVelocity);
void Hook_WeaponEquip(CBaseCombatWeapon *pWeapon);
void Hook_WeaponEquipPost(CBaseCombatWeapon *pWeapon);
bool Hook_WeaponSwitch(CBaseCombatWeapon *pWeapon, int viewmodelindex);
bool Hook_WeaponSwitchPost(CBaseCombatWeapon *pWeapon, int viewmodelindex);
private:
void HandleEntityCreated(CBaseEntity *pEntity, int ref);
void HandleEntityDeleted(CBaseEntity *pEntity, int ref);
void Unhook(CBaseEntity *pEntity);
void Unhook(IPluginContext *pContext);
};
extern CGlobalVars *gpGlobals;
extern ke::Vector<CVTableList *> g_HookList[SDKHook_MAXHOOKS];
extern ICvar *icvar;
#if SOURCE_ENGINE >= SE_ORANGEBOX
extern IServerTools *servertools;
#endif
#endif // _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_
cell_t Call(CBaseEntity *pEnt, SDKHookType type, int other=INVALID_EHANDLE_INDEX);
cell_t Call(CBaseEntity *pEnt, SDKHookType type, CBaseEntity *pOther);
void SetupHooks();
HookReturn Hook(int entity, SDKHookType type, IPluginFunction *pCallback);
void Unhook(int entity, SDKHookType type, IPluginFunction *pCallback);
/**
* IServerGameDLL & IVEngineServer Hook Handlers
*/
#ifdef GAMEDESC_CAN_CHANGE
const char *Hook_GetGameDescription();
#endif
const char *Hook_GetMapEntitiesString();
bool Hook_LevelInit(char const *pMapName, char const *pMapEntities, char const *pOldLevel, char const *pLandmarkName, bool loadGame, bool background);
/**
* CBaseEntity Hook Handlers
*/
void Hook_EndTouch(CBaseEntity *pOther);
void Hook_EndTouchPost(CBaseEntity *pOther);
void Hook_FireBulletsPost(const FireBulletsInfo_t &info);
#ifdef GETMAXHEALTH_IS_VIRTUAL
int Hook_GetMaxHealth();
#endif
void Hook_GroundEntChangedPost(void *pVar);
int Hook_OnTakeDamage(CTakeDamageInfoHack &info);
int Hook_OnTakeDamagePost(CTakeDamageInfoHack &info);
int Hook_OnTakeDamage_Alive(CTakeDamageInfoHack &info);
int Hook_OnTakeDamage_AlivePost(CTakeDamageInfoHack &info);
void Hook_PreThink();
void Hook_PreThinkPost();
void Hook_PostThink();
void Hook_PostThinkPost();
bool Hook_Reload();
bool Hook_ReloadPost();
void Hook_SetTransmit(CCheckTransmitInfo *pInfo, bool bAlways);
bool Hook_ShouldCollide(int collisonGroup, int contentsMask);
#if SOURCE_ENGINE == SE_DOTA
void Hook_Spawn(CEntityKeyValues *kv);
void Hook_SpawnPost(CEntityKeyValues *kv);
#else
void Hook_Spawn();
void Hook_SpawnPost();
#endif
void Hook_StartTouch(CBaseEntity *pOther);
void Hook_StartTouchPost(CBaseEntity *pOther);
void Hook_Think();
void Hook_ThinkPost();
void Hook_Touch(CBaseEntity *pOther);
void Hook_TouchPost(CBaseEntity *pOther);
#if SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_TF2 || SOURCE_ENGINE == SE_SDK2013
void Hook_TraceAttack(CTakeDamageInfoHack &info, const Vector &vecDir, trace_t *ptr, CDmgAccumulator *pAccumulator);
void Hook_TraceAttackPost(CTakeDamageInfoHack &info, const Vector &vecDir, trace_t *ptr, CDmgAccumulator *pAccumulator);
#else
void Hook_TraceAttack(CTakeDamageInfoHack &info, const Vector &vecDir, trace_t *ptr);
void Hook_TraceAttackPost(CTakeDamageInfoHack &info, const Vector &vecDir, trace_t *ptr);
#endif
void Hook_UpdateOnRemove();
void Hook_Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value);
void Hook_UsePost(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value);
void Hook_VPhysicsUpdate(IPhysicsObject *pPhysics);
void Hook_VPhysicsUpdatePost(IPhysicsObject *pPhysics);
void Hook_Blocked(CBaseEntity *pOther);
void Hook_BlockedPost(CBaseEntity *pOther);
bool Hook_WeaponCanSwitchTo(CBaseCombatWeapon *pWeapon);
bool Hook_WeaponCanSwitchToPost(CBaseCombatWeapon *pWeapon);
bool Hook_WeaponCanUse(CBaseCombatWeapon *pWeapon);
bool Hook_WeaponCanUsePost(CBaseCombatWeapon *pWeapon);
void Hook_WeaponDrop(CBaseCombatWeapon *pWeapon, const Vector *pvecTarget, const Vector *pVelocity);
void Hook_WeaponDropPost(CBaseCombatWeapon *pWeapon, const Vector *pvecTarget, const Vector *pVelocity);
void Hook_WeaponEquip(CBaseCombatWeapon *pWeapon);
void Hook_WeaponEquipPost(CBaseCombatWeapon *pWeapon);
bool Hook_WeaponSwitch(CBaseCombatWeapon *pWeapon, int viewmodelindex);
bool Hook_WeaponSwitchPost(CBaseCombatWeapon *pWeapon, int viewmodelindex);
private:
void HandleEntityCreated(CBaseEntity *pEntity, int ref);
void HandleEntityDeleted(CBaseEntity *pEntity, int ref);
void Unhook(CBaseEntity *pEntity);
void Unhook(IPluginContext *pContext);
private:
int HandleOnTakeDamageHook(CTakeDamageInfoHack &info, SDKHookType hookType);
int HandleOnTakeDamageHookPost(CTakeDamageInfoHack &info, SDKHookType hookType);
};
extern CGlobalVars *gpGlobals;
extern ke::Vector<CVTableList *> g_HookList[SDKHook_MAXHOOKS];
extern ICvar *icvar;
#if SOURCE_ENGINE >= SE_ORANGEBOX
extern IServerTools *servertools;
#endif
#endif // _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_

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