Compare commits

...
Author SHA1 Message Date
Nicholas Hastings 7b0bbbd463 Removing -dev tags from version. 2012-04-13 20:37:24 -04:00
Nicholas Hastings b1a904c7a5 Updated changelog for version 1.4.2. 2012-04-13 20:35:57 -04:00
David Anderson 7a124f2aa2 Fix bug in lower-casing API guarantee (r=fyren). 2012-04-13 16:50:44 -07:00
FlaminSarge b002adc509 Fixed potential player lag issue when "drugged" (bug 5217, r=asherkin). 2012-04-14 00:15:50 +01:00
FlaminSarge 2e34f2e67c Fixed sm_drug not toggling correctly (bug 5218, r=psychonic). 2012-04-14 00:12:56 +01:00
Ryan Stecker 315a5c642e Fixed return value of VoteMenuToAll (bug 5254, r=asherkin). 2012-04-14 00:07:39 +01:00
Drifter 3697bc3866 Fixed crash with StoreToAddress if memory wasn't writable (bug 5252, r=asherkin). 2012-04-14 00:00:25 +01:00
Scott Ehlert a63ea2a68d Fixed build scripts for OS X 10.7 build slave. 2012-03-21 21:35:07 -05:00
Scott Ehlert e299092ff5 Removed hardcoded SDK path for curl on OS X. 2012-03-21 22:04:05 -05:00
Reuben Morais f0b69facb3 Removed hardcoded SDK path on OS X (bug 5032, r=ds). 2012-03-21 21:27:26 -05:00
Reuben Morais ab8563f0d4 Followup, re-added check for invalid HL2SDK paths (bug 5023, r=ds). 2012-03-21 21:25:34 -05:00
Michael Busby 1d666b09e2 Fixed StoreToAddress always writing 32 bits and throwing an error (bug 5248, r=asherkin). 2012-03-11 18:07:24 -05:00
Nicholas Hastings 8fcd0478a1 Added better cross-engine support for finding Valve commandline (bug 5216, r=asherkin). 2012-03-04 15:19:58 -05:00
Nicholas Hastings 3c50ed1cf2 Added new TFHoliday_Christmas to TFHoliday enum (bug 5194, r=asherkin). 2011-12-16 09:43:05 -05:00
Nicholas Hastings 3a28a09f15 Added new TF2 weapon defines (r=me). 2011-12-16 00:24:03 -05:00
Nicholas Hastings 8e8f284cc3 Updated linux CS:S ClanTagOffset gamedata. 2011-12-08 14:52:20 -05:00
Nicholas Hastings fa4e61b877 Bump to 1.4.2-dev. 2011-12-07 22:47:31 -05:00
Nicholas Hastings a39d94ffe9 Added tag sourcemod-1.4.1 for changeset f74e1dea2ef2 2011-12-07 21:12:31 -05:00
Nicholas Hastings 4326c3d431 Bump stuff for release build. 2011-12-07 21:11:35 -05:00
Nicholas Hastings dc5aca5f20 Added gamedata support for No More Room in Hell (bug 5162). 2011-12-07 20:17:34 -05:00
Brian Simon 9182d92d86 Increased ServerCommandEx's internal buffer (bug 5169, r=asherkin). 2011-12-07 12:13:52 -05:00
Nicholas Hastings 8dc95a114c Backed out changeset: 294fded6a0d0 (bug 4902, bug 5068). 2011-12-07 11:58:09 -05:00
Nicholas Hastings caf22b7233 Added gamedata support for Adreneline Gamer 2 (bug 5186). 2011-12-07 11:54:53 -05:00
Nicholas Hastings 465bebb170 Fixed typo in basebans ban reason (bug 5188, r=me). 2011-12-06 14:42:30 -05:00
Nicholas Hastings f3006a478f Removed GLIBC_2.7 dependency from spcomp (r=fyren). 2011-12-06 14:29:32 -05:00
Nicholas Hastings 9887f9da48 Updated gamedata for Garry's Mod. 2011-12-02 10:04:28 -05:00
Nicholas Hastings cfe11be9c9 Updated gamedata for HL2MP and DOD:S. 2011-11-29 18:09:51 -05:00
Nicholas Hastings 4118905620 Fixed CS:S gamedata. 2011-11-07 18:23:56 -05:00
Nicholas Hastings 3b7b0d27cb Updated gamedata for today's CS:S update. If wrong, blame gdc! 2011-11-07 18:01:49 -05:00
Nicholas Hastings 9a1713a9f8 Updated TF2_OnIsHolidayActive ret behavior to match doc (bug 5155, r=fyren). 2011-11-04 10:01:33 -04:00
Nicholas Hastings 2995531ca6 Fixed a few minor spacing things in sp incs to not fool API parser. 2011-11-04 10:01:33 -04:00
Nicholas Hastings 46e10e10a0 Fixed sp MaxClients not being updated on map changes after load (bug 5160, r=fyren). 2011-11-04 10:01:28 -04:00
Nicholas Hastings 8fadaff281 Fixed TFHoliday enum (bug 5155, r=asherkin). 2011-11-03 10:03:01 -04:00
Nicholas Hastings fccc1ebb50 Fixed ff trigger printing in triggerer's language to all (bug 5161, r=asherkin). 2011-11-03 09:59:14 -04:00
Nicholas Hastings 03b183e492 Added new TF2 deathflag and dmg custom defines (bug 5157, r=asherkin). 2011-11-03 09:06:59 -04:00
Nicholas Hastings 0e37d2c1bf Registered basecomm as lib to allow requiring it (bug 5156, r=asherkin). 2011-11-03 09:06:22 -04:00
otstrel f7daefc76e Fixed "not connected" error in reserved slots plugin (bug 5158, r=psychonic). 2011-11-03 09:05:40 -04:00
Nicholas Hastings 071b013f5e Preemptive gamedata update for tonight's TF2 update. 2011-11-02 18:24:12 -04:00
Fyren e69d16ff71 Bump to 1.4.1-dev. 2011-10-28 19:50:55 -07:00
Fyren 1f599c8771 Added tag sourcemod-1.4.0 for changeset ddd707c3454c 2011-10-28 19:49:17 -07:00
Fyren 9389a0f138 Bump stuff for release build. 2011-10-28 18:24:01 -07:00
Nicholas Hastings 997687c3ab Updated changelog. 2011-10-28 21:18:51 -04:00
Nicholas Hastings fe05b6c2d0 Updated Dino D-Day gamedata for today's update. 2011-10-28 20:27:44 -04:00
Nicholas Hastings 097ca03761 Added missing EYE def to halflife.inc, updated EYE def# (bug 5151, r=asherkn). 2011-10-28 19:09:40 -04:00
Nicholas Hastings f182cd1d6a TF2 ext fixes for TF2 holiday system changes (bug 5150, r=asherkin). 2011-10-28 19:07:40 -04:00
Nicholas Hastings 4d54bfa6b4 Preemptive gamedata update for tonight's TF2 update. 2011-10-27 20:28:26 -04:00
Nicholas Hastings 28d1dab18a Small fixes to reservedslots, including ep2v Replay/SourceTV fix (bug 5094, r=fyren). 2011-10-20 21:42:18 -04:00
Nicholas Hastings f3d19a860a Added detection of Replay and SourceTV, and natives to query (bug 5124, r=fyren). 2011-10-20 21:39:57 -04:00
Nicholas Hastings 5732e34f50 Added check for element in Get/SetEntProp funcs >= 0 (bug 5141, r=fyren). 2011-10-20 21:35:50 -04:00
Asher Baker ca94a61acf Fixed ServerCommandEx native appending to buffer instead of overwriting (bug 5047, r=fyren). 2011-10-17 11:02:42 -04:00
Brian Simon a875c61b5f Added RootConsoleMenu iface support to sample ext (bug 5021, r=psychonic). 2011-10-17 10:55:44 -04:00
David Anderson 5ec70c9e0d Fixed shutdown bug in SDKTools (created EntOutputMgr shutdown func) (bug 5063, r=fyren). 2011-10-17 10:47:13 -04:00
GoD-Tony 4b0373408d Moved client language detection to be earlier (on connect) (bug 3714, r=psychonic). 2011-10-15 12:07:55 -04:00
Nicholas Hastings 7f8c4eff39 Updated GMod gamedata. 2011-10-14 15:21:12 -04:00
Don 00f152910b Added native to clientprefs to alter data on a disconnected player (bug 3882, r=pred). 2011-10-14 11:28:53 -04:00
Nicholas Hastings 95fdeb03c3 Move marking of mapstarted to before calling of map start notifs. (bug 5119, r=asherkin). 2011-10-14 09:25:42 -04:00
Nicholas Hastings 66e9ef9cf6 Updated HL2DM and DOD:S gamedata. 2011-10-13 20:06:40 -04:00
Peace-Maker 6b3221f1da Updated CS:S gamedata. 2011-10-13 19:15:02 -04:00
GoD-Tony 25ad7bcf5e Updated TF2 gamedata for today's update. 2011-10-13 18:31:24 -04:00
GoD-Tony 9a04a6bdb1 Added optional autoload of sdktools to cstrike ext.(bug 5125, r=psychonic). 2011-10-13 13:17:37 -04:00
Nicholas Hastings 1b9fb906e2 Added CS_GetClanTag and CS_SetClanTag natives to cstrike ext (bug 5122, r=fyren). 2011-10-13 13:17:29 -04:00
Nicholas Hastings e23d7ca51b Added TextMsg destination constants to IGameHelpers header (bug 5123, r=fyren). 2011-10-13 13:17:22 -04:00
Fyren 92773c2e1b Fixed client serials not getting cleared on disconnect (bug 5121, r=psychonic). 2011-10-12 00:51:58 -04:00
Nicholas Hastings 776889cfbb Removed error when optional ext dep is missing (bug 5112, r=fyren). 2011-10-11 22:51:24 -04:00
Nicholas Hastings 67163e14e6 Added checks to avoid crashing in some natives before map start (bug 5119, r=fyren). 2011-10-11 22:50:21 -04:00
Nicholas Hastings 45f68840ed Fixed multiple small issues with KickClient/Ex natives (bug 5120, r=fyren). 2011-10-11 19:50:53 -04:00
Nicholas Hastings 325ae5e977 Added better Nuclear Dawn compatibility to base plugins (bug 5117, r=fyren). 2011-10-11 19:47:20 -04:00
Nicholas Hastings 14919c65d9 Fixed wrong values for unsigned, >= 16-bit props in GetEntProp (bug 5105, r=fyren). 2011-10-11 19:41:56 -04:00
Nicholas Hastings 8888e88dc4 Updated tf2 inc files with more condition and custom dmg defs (bug 5118, r=asherkin). 2011-10-10 21:44:36 -04:00
javalia 0533664f90 Removed non-existant param from SetTrieString function doc (bug 5108, r=dvander). 2011-10-10 16:02:44 -04:00
Peace-Maker 64b824f457 Added gamedata for HL2CTF (bug 5114, r=psychonic). 2011-10-10 15:59:48 -04:00
Nicholas Hastings b6592d799f Updated Nuclear Dawn gamedata to use ShowMenu (now works). 2011-09-26 13:54:17 -04:00
Drifter c89711a863 Updated cstrike ext WeaponPrice offset. 2011-09-20 16:21:17 -04:00
Drifter 91a1292b12 Updated cstrike ext gamedata. 2011-09-16 11:36:37 -04:00
Paul Clothier b2d469cb84 Updated TF2 SetPowerplayEnabled gamedata (bug 5095, r=psychonic). 2011-09-15 18:43:33 -04:00
Nicholas Hastings 4f41da34c6 Merge. 2011-09-10 12:10:05 -04:00
Nicholas Hastings f136f2dcaf Added CheckAccess native to check cmd/override access of AdminId (bug 5083, r=fyren). 2011-09-10 12:08:38 -04:00
Reuben Morais e6df54537a Changed build system so that it no longer requires all SDKs to be available (bug 5023, r=ds). 2011-09-09 18:37:09 -05:00
Nicholas Hastings e62278859e Validate ent index bounds in LookupEntity (bug 5080, r=fyren). 2011-09-09 15:29:17 -04:00
Peace-Maker 51b91bce6d Updated Nuclear Dawn gamedata. 2011-09-08 19:59:09 -04:00
Nicholas Hastings d96a23d4f2 Fixed build. 2011-09-03 14:23:46 -04:00
javalia 98e049b336 Added GetDistGainFromSoundLevel native to SDKTools (bug 5066, r=dvander). 2011-09-03 14:18:08 -04:00
FlaminSarge 3c297f5d1d Fixed typo in tf2_stocks (persistant -> persistent) (bug 5074, r=psychonic). 2011-09-03 14:11:38 -04:00
FlaminSarge d64d196409 Fixed mixup of arrow stab and telefrag defs in tf2_stocks (bug 5074, r=psychonic). 2011-09-03 14:10:24 -04:00
Nicholas Hastings b1638e79c0 Added missing clientnatives files to sdktools proj file (NPOTB). 2011-08-29 13:55:11 -04:00
Nicholas Hastings 13753757d4 Fixed error in sdktools msvc10 proj file (NPOTB). 2011-08-28 16:18:48 -04:00
Nicholas Hastings 739e341218 Fixed Nuclear Dawn menus. 2011-08-25 13:58:12 -04:00
Nicholas Hastings fda282604d Added gamedata support for Nuclear Dawn. 2011-08-25 13:20:26 -04:00
Fyren 2cd7fa68d6 Reshove. 2011-08-20 16:45:44 -07:00
Fyren d78a0c87b8 Backed out changeset 42462959f48d 2011-08-20 16:44:16 -07:00
Fyren 88d4abeaf8 Shove. 2011-08-20 16:41:14 -07:00
Nicholas Hastings 1c0abbfce6 Partially fixed build. 2011-08-20 19:21:27 -04:00
Nicholas Hastings 1492e12ca2 Added support for E.Y.E Divine Cybermancy (bug 5035, r=fyren). 2011-08-20 18:58:37 -04:00
Nicholas Hastings 2b9a39e2eb Updated Fortress Forever gamedata to include support for newer features. 2011-08-20 13:25:38 -04:00
Nicholas Hastings 301ae447b4 Added more new TF2 weapon and custom damage defs (bug 5055, r=asherkin). 2011-08-20 13:25:07 -04:00
Asher Baker 3d47010cbd Fail to load a metamod-enabled extension if it refuses to attach to MM:S (bug 5042, r=dvander). 2011-08-15 20:19:07 +01:00
Asher Baker dd0ff999e4 Backed out changeset: 602945928c23 2011-08-15 20:06:14 +01:00
Asher Baker 05e5c93e91 Fail to load a metamod-enabled extension if it refuses to attach to MM:S (bug 5042, r=dvander). 2011-08-15 19:30:56 +01:00
Asher Baker 1bd97730ce Added a reset argument to 'sm cvars' (bug 5043, r=psychonic). 2011-08-14 21:42:32 +01:00
Fyren 458378be66 Let logic binary access ServerLang value on startup (bug 4675, r=dvander). 2011-07-24 19:52:22 -07:00
David Anderson c01101dbd0 Fix build. 2011-07-24 19:44:15 -07:00
Michael (LumiStance) f7364111f2 Fix corner cases with ExplodeString (bug 4629, r=dvander).
--HG--
extra : rebase_source : ebb338bc93d32544e66c16fcba4494d5eae7ee8e
2011-07-24 19:30:15 -07:00
Nicholas Hastings f3b84b8670 Added gamedata for International Online Soccer: Source (bug 5019). 2011-07-22 13:48:34 -04:00
Asher Baker ec11a31d9d Updated sm_rcon to use new ServerCommandEx native (bug 5018, r=ds). 2011-07-18 03:25:01 +01:00
Asher Baker 2271469d1b Added ServerCommandEx native to get the response when running a command (bug 3873, r=ds). 2011-07-18 03:23:03 +01:00
Asher Baker 7fe92d87c2 Added missing brackets back to l4d and l4d2 gamedata (bug 5016, r=psychonic). 2011-07-16 17:55:43 -04:00
Drifter 6046b8fb79 Fixed CS_GetWeaponPrice for some weapon (bug 4994, r=psychonic). 2011-07-14 12:57:18 -04:00
FlaminSarge a65239a8af Added defines for more new TF2 conditions to tf2.inc (bug 5000, r=psychonic). 2011-07-14 12:53:05 -04:00
Nicholas Hastings 746cd5f49c Merge. 2011-07-12 20:07:51 -04:00
Nicholas Hastings 75c315ad8a Fixed maxClients not being updated correctly in some cases/areas (bug 4986, r=fyren). 2011-07-12 20:06:08 -04:00
Nicholas Hastings c1926c6e25 Added FireOutput gamedata support for The Hidden. 2011-07-12 19:58:37 -04:00
Nicholas Hastings 3f8ba353b7 Updated Fistful of Frags gamedata for FoF 3.6 release. 2011-07-12 19:58:30 -04:00
Nicholas Hastings 39a2152a46 Reverted FindEntityByClassname gamedata obliteration from 7aea1316eff7 per bug 4963. 2011-07-12 19:58:16 -04:00
Nicholas Hastings ddd967534b Sped up native impl. of FindEntityByClassname (bug 4963, r=fyren). 2011-07-12 19:48:28 -04:00
Fyren 4d52fe0490 Revert 3336, try fix #2 (bug 4852, r=dvander) 2011-07-09 20:47:43 -07:00
Nicholas Hastings 264ffa80ce Backed out changeset: b5969264060e 2011-07-08 07:55:20 -04:00
Nicholas Hastings 258a9c636a Backed out changeset: 049c7073d1a4 2011-07-08 07:54:21 -04:00
Nicholas Hastings 8015d1827c Backed out changeset: 9007dacc012d 2011-07-08 07:53:31 -04:00
Nicholas Hastings ae10bc6601 Backed out changeset: 344daca49587 2011-07-08 07:53:14 -04:00
Nicholas Hastings 51c27afcd2 Fixed more crashes related to early, nonzero maxclients (bug 5008, r=dvander). 2011-07-07 21:31:07 -04:00
Nicholas Hastings e09d4f2cf2 Merge. 2011-07-07 19:53:56 -04:00
Nicholas Hastings 7e87f56699 Fixed nonzero maxClients startup crash in SDKTools (bug 5010, r=bee). 2011-07-07 19:51:05 -04:00
Scott Ehlert ca9150a731 Triggering build, ugh. 2011-07-07 11:25:00 -05:00
Nicholas Hastings 5250d819d0 Triggering a build, hoping for luck. 2011-07-07 09:27:24 -04:00
Nicholas Hastings d93413a4ae Fixed use of m_Players before init'd in PlayerManager (bug 5008, r=dvander). 2011-07-06 22:34:23 -04:00
Nicholas Hastings bb7f7eff51 Added native interface for Basecomm plugin (bug 2594, r=fyren). 2011-07-06 22:34:21 -04:00
Brian Simon 838e8c7b35 Added InactivateClient and ReconnectClient natives to SDKTools (bug 4931, r=fyren). 2011-07-06 18:11:02 -04:00
David Anderson bb48a16466 Fix compiler creating bogus arrays when missing a dimension (bug 4902, r=fyren). 2011-07-06 17:56:40 -04:00
David Anderson a02ff01d84 Prevent declaring arrays that the compiler is too buggy to handle (bug 4977, r=fyren). 2011-07-06 17:56:03 -04:00
David Anderson 66d27d6ac5 Fix return omission with else-after-return (bug 4852, r=fyren). 2011-07-06 17:55:14 -04:00
Nicholas Hastings 5ba82ef0fc Removed maxClients caching in core (bug 5007, bug 4986, r=fyren). 2011-07-06 17:50:37 -04:00
David Anderson 053b522aff Fixed some vars not being marked for init on first compile pass (bug 4643, r=fyren). 2011-07-06 17:50:26 -04:00
Nicholas Hastings 4521f80e5a Added ability in SDKTools to get/set prop values on gamerules class (bug 4983, r=fyren). 2011-07-06 17:37:35 -04:00
Nicholas Hastings f24efc17c1 Fixed TF2 OnConditionAdded/Removed forwards to catch all cases (bug 4982, r=fyren). 2011-07-06 17:37:35 -04:00
Nicholas Hastings f32d3849e5 Merge. 2011-07-06 15:30:19 -04:00
Michael Busby f2fb064ea6 Fixed typo in GetEntDataFloat function doc (bug 4993, r=psychonic). 2011-07-06 15:27:41 -04:00
Nicholas Hastings ce5093f91f BaseComm now uses CommandListeners for chat hooks (bug 4991, r=fyren). 2011-07-06 15:24:43 -04:00
David Anderson 75121588c4 Clobber 2011-07-04 15:33:11 -07:00
javalia 1ff0f478d4 Increase symbol name limit to 63 characters (bug 4564, r=dvander). 2011-07-04 15:26:08 -07:00
David Anderson 6c68082359 Fix crash when dynamic arrays run out of memory (bug 4632, r=fyren). 2011-07-04 01:57:19 -07:00
David Anderson a752d220cc Use active, not passive FTP. 2011-06-29 16:05:18 -07:00
Drifter ee1bbd5994 Added new CS_GetWeaponPrice native to cstrike extension (bug 4985, r=psychonic). 2011-06-28 20:32:55 -04:00
Michael Busby 91368e5656 Fixed typo in keyvalues.inc doc (bug 4990, r=psychonic). 2011-06-28 20:26:40 -04:00
Drifter c4c554b420 Added some small fixes for new CStrike patch (2ddc75e24c53) (bug 4732, r=psychonic). 2011-06-28 20:16:05 -04:00
Nicholas Hastings 52ec8bf049 Fixed build. 2011-06-27 09:35:38 -04:00
Nicholas Hastings 5c40e02ee6 Added support for gamedata lookups from matchmaking_ds lib (bug 4158, r=Fyren). 2011-06-27 09:30:52 -04:00
Nicholas Hastings d2a89c5856 Added gamedata for TF2 SetInWaitingForPlayers (bug 4704). 2011-06-27 08:29:11 -04:00
Nicholas Hastings 9ec3f1b89d Fixed TF2_RemoveCondition not always removing conditions (bug 4981, r=asherkin). 2011-06-26 21:00:03 -04:00
Nicholas Hastings 3ab81c764d Added more TF2 condition defines (bug 4979, r=asherkin). 2011-06-26 20:55:18 -04:00
Nicholas Hastings c072ce8f0c Fixed TF2 RemoveCondition gamedata. 2011-06-26 18:10:29 -04:00
Nicholas Hastings e44dbd0e77 Merge. 2011-06-26 18:09:55 -04:00
Nicholas Hastings ec12022550 Added msvc10 project files for TF2 ext (NPOTB). 2011-06-26 10:54:12 -04:00
Drifer e0f670499c Add a number of useful forwards and natives to the cstrike extension (bug 4732, r=fyren). 2011-06-26 01:25:42 -07:00
David Anderson 177cc87985 Doc improvement. 2011-06-25 15:31:11 -07:00
David Anderson 3e387f35e9 Updated credits. 2011-06-25 15:26:09 -07:00
Nicholas Hastings 7037723993 Fixed TF2 identifiers and condition stocks (bug 4974, r=me). 2011-06-24 19:45:16 -04:00
Scott Ehlert b1098d6287 Using gcc 4.4 from Debian 6 for Linux builds now. 2011-06-24 17:29:05 -05:00
Nicholas Hastings be222a16ce Updated TF2 identifiers and condition stocks. 2011-06-24 02:01:03 -04:00
Nicholas Hastings 17f9a3eba6 Updated TF2 gamedata. 2011-06-24 00:53:17 -04:00
Scott Ehlert 0ee77c0e7d Triggering a build. 2011-06-23 21:21:27 -05:00
Nicholas Hastings b92fa45da7 Triggering build. 2011-06-23 19:14:58 -04:00
Nicholas Hastings e64c2fc110 Triggering build. 2011-06-23 18:09:31 -04:00
Nicholas Hastings 49a6508888 Added msvc10 project for SDKTools (NPOTB). 2011-06-22 09:46:56 -04:00
David Anderson 859678536f Fixed crash on plugin unload when two cmds exist with same name, different casing (bug 4698, r=Fyren). 2011-06-20 13:30:14 -04:00
Nicholas Hastings 9a5f788807 Normalized line endings in IGameHelpers.h to appease FYREN. 2011-06-18 14:36:20 -04:00
Nicholas Hastings 84b3b1d29c Added HintTextMsg to IGameHelpers (bug 4950, r=Fyren). 2011-06-18 14:34:17 -04:00
Nicholas Hastings 80eb18a425 Moved GetEntityClassname to end of entity.inc to fix plugin compile errors (bug 4798). 2011-06-18 14:31:46 -04:00
Scott Ehlert 3e1ab53abd Fixed clang OS X build. 2011-06-17 18:21:17 -05:00
Scott Ehlert 18c119b4d5 Removed -static-libgcc for Mac OS X build (no bug, r=dvander).
This fixes the ld warning: could not create compact unwind for __Unwind_Resume: non-standard register 0 being saved in prolog
2011-06-17 18:00:32 -05:00
Nicholas Hastings e67a65c0db Fixed build. 2011-06-16 15:59:27 -04:00
Scott Ehlert 4c878c4963 Fixed crash in MemoryUtils::ResolveSymbol() on OS X Lion (10.7) (bug 4951, r=dvander). 2011-06-15 16:02:05 -05:00
Nicholas Hastings e8fbe0f36c Fixed uninit'ed string and other minor issues in basetriggers (bug 4945, r=fyren). 2011-06-05 23:13:25 -04:00
Nicholas Hastings 243b7e25f8 Added array element selection with Get/SetEntProp* on arrays (bug 4160, r=fyren). 2011-06-05 21:52:36 -04:00
John Schoenick f1a4a08c7f Fixed regression in FindEntityByClassname from bug 4899 (bug 4941, r=predcrab). 2011-06-01 20:36:16 -04:00
Fyren c0fa36b9a1 Added support for language aliases (bug 4858, r=dvander). 2011-05-25 21:10:18 -04:00
Nicholas Hastings 835b2d7ced Slight ep1 gamedata cleanup. 2011-05-25 20:56:30 -04:00
Nicholas Hastings 13c2381ba7 Added gamedata for Eternal Silence (bug 4880). 2011-05-25 20:50:51 -04:00
Fyren fbc8e899dd Forcing build. 2011-05-25 13:57:17 -04:00
Nicholas Hastings 5ee8c8ce91 Backed out changeset: a7a73225f8ee 2011-05-25 13:56:34 -04:00
Nicholas Hastings 971793d6a1 Backed out changeset: 065beec73902 2011-05-25 13:56:13 -04:00
Nicholas Hastings 9d7a905fb1 Backed out changeset: 65eb3df32b1c 2011-05-25 13:31:14 -04:00
Nicholas Hastings 731f002175 Backed out changeset: abe4ce9d3e0e 2011-05-25 13:30:40 -04:00
Nicholas Hastings 7e6f3bfd83 Adjusting the proper set of flags this time. 2011-05-25 11:25:20 -04:00
Nicholas Hastings 3e14739b29 Attempting to fix SDKTools build. 2011-05-25 11:21:16 -04:00
Nicholas Hastings d7fb6b2892 Fixed invalid client errors from late-load of SourceTV (bug 4881, r=fyren). 2011-05-25 08:31:12 -04:00
Nicholas Hastings 7527f441ae Switched to using IServerTools in SDKTools where possible. (bug 4899, r=fyren). 2011-05-25 08:27:27 -04:00
Nicholas Hastings 5228ee1d91 Updated garrysmod gamedata. 2011-05-24 20:36:09 -04:00
Nicholas Hastings 297a98e065 Handle leak notice now prints to error log (as well as fatal) (bug 4929, r=dvander). 2011-05-24 18:37:45 -04:00
Nicholas Hastings 727d8afd94 Updated core msvc10 proj file (no smn_profiler) (NPOTB). 2011-05-24 18:35:09 -04:00
Nicholas Hastings c292fba3df Updated core msvc9 proj file (engine defs, -smn_profiler, mms17 -> mms18) (NPOTB). 2011-05-24 18:34:45 -04:00
Nicholas Hastings 9954ff55f5 Added msvc10 project file for sm logic. (NPOTB). 2011-05-24 14:21:24 -04:00
Fyren fefd84d431 Translator now properly falls back on bad server language (bug 4861, r=dvander). 2011-05-24 13:25:28 -04:00
Fyren b4a7d21b9e Removed compiler double include check (bug 4863, r=dvander). 2011-05-24 10:49:40 -04:00
Nicholas Hastings d03e051611 Fixed var names and docs for TF2_MakeBleed native (bug 4928, r=fyren). 2011-05-24 10:17:48 -04:00
John Schoenick e8c141d775 Make SQL_LastInsertId and SQL_GetAffectedRows work on query handles, allowing their use with threaded queries 2011-05-14 20:21:37 -07:00
David Anderson 5b45e29533 Move profile natives to logic, add linux support (bug 4927, r=ds). 2011-05-22 02:04:34 -07:00
FlaminSarge 024d094459 Added TF2 megaheal cond defines to tf2 incs (bug 4916, r=psychonic). 2011-05-12 11:33:50 -04:00
Gareth Clarke df977577e2 Updated ep2v SetUserCvar gamedata (bug 4904). 2011-05-06 08:07:40 -04:00
Scott Ehlert b63b94bc81 Updated buildbot scripts to support clang builders. 2011-05-01 00:17:11 -05:00
Scott Ehlert 7e514f5d34 Moved -static-libgcc to linker flags. 2011-05-01 00:09:25 -05:00
Scott Ehlert cb2de2e5c4 Avoid depending on __isoc99_sscanf@GLIBC_2.7 when building on Linux with glibc >= 2.7 (bug 4894, r=dvander). 2011-04-28 02:43:55 -05:00
Nicholas Hastings f2fedbc3e6 Merge. 2011-04-25 19:05:48 -04:00
Nicholas Hastings 8ef686fd21 Updated dinodday gamedata for today's game update. 2011-04-25 19:05:01 -04:00
Nicholas Hastings 4c96e9a17d Updated zps gamedata for today's game update. 2011-04-25 19:04:34 -04:00
Scott Ehlert 939bc00b2b Added detection for clang compiler and fixed various warnings triggered by it (bug 4878, r=dvander). 2011-04-23 21:53:53 -05:00
Nicholas Hastings 0b06d3412e Updated Windows signature for GMod CreateEntityByName. 2011-04-17 16:12:45 -04:00
Nicholas Hastings 94f6f60105 Merge. 2011-04-15 15:40:38 -04:00
Nicholas Hastings 4bd6bc9683 Updated Garry's Mod gamedata. 2011-04-15 15:16:47 -04:00
David Anderson 3c59621425 Backed out changeset d6853d8d39fd 2011-04-15 10:59:10 -07:00
David Anderson a37e2ab26a Fix bug where globals can be assigned invalid memory (bug 4643, r=ds). 2011-04-15 10:50:09 -07:00
Nicholas Hastings d099febf7b Added new param to CTFPlayerShared::Disguise call in TF2 ext (bug 4866, r=fyren). 2011-04-15 12:11:32 -04:00
Nicholas Hastings b9f82332c8 Shortened __ext name for ClientPrefs to avoid hitting symbol limit (bug 4839). 2011-04-15 02:06:50 -04:00
Nicholas Hastings c02c4c6d6a Gamedata update for CS:S, TF2, DOD:S, and HL2DM. 2011-04-15 01:34:18 -04:00
Nicholas Hastings 17476ec137 Triggering build to (hopefully) fix load on linux. 2011-04-15 00:34:51 -04:00
Nicholas Hastings ee51a68c6f Triggering build... again. 2011-04-14 23:35:08 -04:00
Nicholas Hastings 0120ce5d7c Merge. 2011-04-14 23:30:04 -04:00
Nicholas Hastings 42c6e640fc Triggering build. 2011-04-14 23:26:39 -04:00
Scott Ehlert bc571316b9 Triggering a build for goodness sake. 2011-04-14 20:53:59 -05:00
Scott Ehlert 3cc1af9618 Triggering a build. 2011-04-13 20:25:10 -05:00
Scott Ehlert 6957bf504b Triggering a build. 2011-04-13 19:05:41 -05:00
Scott Ehlert d47dd70141 Attempt #2 at meaningful bootstrap error message. 2011-04-13 18:37:41 -05:00
Scott Ehlert 86eb2360db Attempt at getting a meaningful error message out of buildbot bootstrap. 2011-04-13 18:30:34 -05:00
Scott Ehlert c55e350cb2 Triggering a build, argh. 2011-04-13 17:08:39 -05:00
Scott Ehlert b0fe032b8d Triggering a build. 2011-04-13 16:44:20 -05:00
Scott Ehlert aa25870fb8 Triggering a build. 2011-04-13 16:09:36 -05:00
Nicholas Hastings a8118ea8f4 Merge. 2011-04-13 08:31:02 -04:00
Nicholas Hastings 1a344c1441 SetEntProp now marks edict state as changed at offset (bug 4855, r=fyren). 2011-04-13 08:13:49 -04:00
Berni 86a1641ac1 Fix compiler hanging when #including a directory (bug 4822, r=dvander) 2011-04-13 04:02:22 -07:00
Nicholas Hastings 10129fa568 Removed gEntList failure notify on Windows. (bug 4832, r=fyren). 2011-04-11 22:30:03 -04:00
David Anderson 935a8d36da Triggering build. 2011-04-09 18:18:59 -07:00
Nicholas Hastings 2516a3af8a Updated hgignore to catch msvc temp files (npotb). 2011-04-09 15:52:58 -04:00
Nicholas Hastings 120a265fc3 Removed core/msvc10/sourcemod_mm.sdf from version control (npotb). 2011-04-09 15:43:10 -04:00
Nicholas Hastings 33aebeb727 Added forwards to TF2 ext for cond addition and removal (bug 4851, r=fyren). 2011-04-09 00:33:55 -04:00
Nicholas Hastings 7e06cfb471 Added gamedata for Dino d-day. 2011-04-09 00:29:57 -04:00
Berni f2bcff69a9 Added GetEntityClassname stock (bug 4798, r=dvander). 2011-04-09 00:29:46 -04:00
Nicholas Hastings 39b7d175b9 Merge 2011-04-07 23:03:51 -04:00
Nicholas Hastings b9cebe8d87 triggering build. 2011-04-07 23:01:16 -04:00
Scott Ehlert 6814cfbcd7 Triggering a build, please. 2011-04-07 15:09:56 -05:00
Scott Ehlert 2884696024 Triggering a build, perhaps. 2011-04-07 14:51:56 -05:00
David Anderson 6930046bc6 Triggering build. 2011-04-07 04:16:38 -05:00
David Anderson 174cbfe3b9 Triggering build. 2011-04-07 04:13:54 -05:00
David Anderson 611c7633cf Triggering build. 2011-04-07 04:05:00 -05:00
David Anderson 822d4269c4 Pushing build. 2011-04-07 04:04:02 -05:00
David Anderson 8fd16efc33 Triggering build. 2011-04-07 03:58:20 -05:00
Nicholas Hastings ef082d855c Fixed some gamedata lookups requiring symbols on linux/mac (bug 4832, r=fyren). 2011-04-04 13:44:19 -04:00
Nicholas Hastings a5c4739804 Added better cross-engine entity flag compatibility. (bug 4809, r=fyren). 2011-04-04 13:37:29 -04:00
Nicholas Hastings d1f1a88ffd Mark clientprefs natives as optional when ext not required. (bug 4839, r=fyren). 2011-03-24 09:48:36 -04:00
David Anderson c05f6b7bf3 Trigger build. 2011-03-22 21:45:20 -07:00
Nicholas Hastings 4b5fa26cd6 Changed some instances of LogMessage to LogAction. (bug 4649, r=fyren). 2011-03-20 19:37:25 -04:00
Nicholas Hastings 0162d18343 Updated SM core vcxproj. MMSOURCE17 -> 18, Removed files moved to logic. (NPOTB) 2011-03-13 14:03:33 -04:00
Nicholas Hastings b6415818f6 Added new TF2 condition defines (bug 4834, r=fyren). 2011-03-13 14:03:26 -04:00
David Anderson e16efbf58b Upgraded symstore. 2011-03-12 23:01:29 -08:00
Nicholas Hastings 46804d0faf SM Central fixes for new language natives (bug 4613). 2011-03-12 23:56:04 -05:00
Dr\!fter a81567e2d6 Add OnClientSettingsChanged to IPlayerHelpers (bug 4812, r=fyren) 2011-03-08 12:59:42 -08:00
databomb 217670b54a Fix precedence of voice mute flag versus specific client overrides (bug 4826, r=fyren) 2011-03-08 12:23:34 -08:00
databomb f2e19c0387 Fix mistaken unhooking of voice hooks (bug 4804, r=fyren) 2011-03-08 12:17:21 -08:00
Fyren 9799970042 Update spcomp Makefile 2011-03-08 12:07:06 -08:00
GoD-Tony ca75d0d765 Added new language natives (bug 4613, r+a13=dvander). 2011-03-08 08:38:21 -05:00
Asher Baker 0824e49000 Added missing files to the spcomp project file (bug 4824, r=dvander). 2011-03-07 15:05:51 +07:00
Nicholas Hastings c3a98db0ea Fixed SetTeamScore not updating score on client (bug 2736, r=fyren). 2011-02-28 19:40:21 -05:00
Nicholas Hastings f27685717b Updated SDKTools vc project file (NPOTB). 2011-03-01 21:25:02 -05:00
Nicholas Hastings 55034bfa6f Merge 2011-03-01 21:22:09 -05:00
Nicholas Hastings 6f8b420d0d Backed out changeset: 6da59ea19165 2011-03-01 21:22:01 -05:00
Nicholas Hastings 2ed7e14a99 Merge. 2011-02-28 19:47:14 -05:00
Nicholas Hastings ee3bcef8ab Updated Empires Mod gamedata for version 2.31a. 2011-02-28 19:45:44 -05:00
Nicholas Hastings adbcb97515 Fixed graphical glitches with funcommands effects in L4D1 (bug 3486, r=fyren). 2011-02-28 19:45:36 -05:00
Nicholas Hastings c667723958 Added identifier for new TF2 flag event, 'returned' (bug 4808, r=fyren). 2011-02-28 19:44:41 -05:00
Nicholas Hastings d94634398e Updated TF2 condition idenifiers (bug 4801, r=fyren).
Added TFCond_InHealRadius (amputator glow) and fixed TFCond_Healing.
2011-02-28 19:43:08 -05:00
Nicholas Hastings f348e58508 Fixed SetTeamScore not updating score on client (bug 2736, r=fyren). 2011-02-28 19:40:21 -05:00
David Anderson 60f16970ac Trigger build. 2011-02-27 23:58:10 -08:00
David Anderson 39c5eafafc Trigger build. 2011-02-27 23:33:15 -08:00
David Anderson b7f6c223d8 Push build. 2011-02-27 23:04:10 -08:00
Nicholas Hastings bf9a65338b Forcing build to see if upload is fixed. 2011-02-27 12:43:13 -05:00
Nicholas Hastings 5b3ae5eff9 Updated ZPS gamedata. 2011-02-07 15:50:27 -05:00
Asher Baker f80a8d306b Added defines for TF2 weapon slots (r=dvander). 2011-02-01 14:45:19 -05:00
Nicholas Hastings 9ed9060940 Updated CSPromod gamedata. 2011-02-01 13:50:17 -05:00
Nicholas Hastings 5453e60099 Updated customkill and deathflag defines in tf2_stocks (bug 4799, r=dvander). 2011-01-16 20:25:44 -05:00
Nicholas Hastings 3de61b69ad Raised MAXPLAYERS from 64 to 65 (bug 4490, r=dvander). 2011-01-16 20:06:55 -05:00
Erik Minekus 322a4ed05d Fixed bug in nominations that could cause "Unknown command" error (bug 4797, r=psychonic). 2011-01-16 20:00:44 -05:00
Nicholas Hastings 8f3b4afcf7 Removed tv_enable hook to fix rare max client count issue (bug 4791, r=fyren). 2011-01-12 18:59:34 -05:00
Nicholas Hastings ebdc6b94fc forcing build. 2011-01-12 06:47:13 -05:00
Nicholas Hastings a7218d2e59 Added missing SOURCE_SDK_BLOODYGOODTIME define to halflife.inc (bug 4780, rs=dvander). 2011-01-12 00:30:47 -05:00
Nicholas Hastings 6d93beac8e maybe i was too impatient... 2011-01-12 00:12:06 -05:00
Nicholas Hastings 1fb1309e77 forcing build 2011-01-12 00:07:20 -05:00
Nicholas Hastings 5916f40b7a Added Bloody Good Time gamedata (bug 4780, r=fyren). 2011-01-11 23:36:32 -05:00
Nicholas Hastings 5226714bbd Added support for Bloody Good Time (bug 4780, r=fyren). 2011-01-11 23:35:58 -05:00
Asher Baker dabf486a9f Added missing MENUFLAG_BUTTON_NOVOTE define to menus.inc (bug 4217, r=psychonic). 2011-01-04 11:02:39 -05:00
Zach Kanzler c78f4407ea Exposed ProcessCommandTarget in IPlayerHelpers (bug 4742, r=fyren). 2010-12-31 20:04:59 -05:00
Asher Baker fae4127ddc Added missing unhooking of ClientConnect in PlayerManager (bug 4749, r=fyren). 2010-12-31 20:02:41 -05:00
Zach Kanzler 9cc1497e9e Fixed namespace-related compile issue in INativeInvoker.h (bug 4750, r=fyren). 2010-12-31 20:00:07 -05:00
Nicholas Hastings cdd64d52eb Updated Garry's Mod gamedata (bug 4762, r=fyren). 2010-12-19 14:10:36 -05:00
Nicholas Hastings 4d319c12f8 Updated TF2 includes with new weapon and condition identifiers (bug 4761, r=fyren). 2010-12-18 17:07:42 -05:00
Nicholas Hastings 8fc3e4ab12 Updated HL2DM gamedata (bug 4756, r=fyren). 2010-12-18 00:11:51 -05:00
Nicholas Hastings ed7d68d6a7 Updated DOD:S gamedata (bug 4755, r=fyren). 2010-12-18 00:03:31 -05:00
Nicholas Hastings 59820519ce Updated CS:S gamedata (bug 4754, r=fyren). 2010-12-18 00:03:04 -05:00
Nicholas Hastings 767c807a40 Updated TF2 gamedata (bug 4753, r=DS). 2010-12-17 23:08:49 -05:00
Nicholas Hastings d25adc1b10 Updated Goldeneye:Source gamedata (bug 4751, r=fyren). 2010-12-17 23:07:54 -05:00
Nicholas Hastings 35f0067fe5 Updated Garry's Mod gamedata (bug 4747, r=fyren). 2010-12-15 21:29:59 -05:00
Nicholas Hastings f1b01dd086 Triggering build to fix bug 4729 on L4D1 now. 2010-12-13 15:37:39 -05:00
Asher Baker 3df08d64e2 Fix permissions check in antiflood (bug 4584, r=dvander). 2010-12-12 18:13:05 -08:00
Erik Minekus f56cc43331 Fixed sm_rtv printing "unknown command" (bug 4730, r=psychonic). 2010-12-04 15:28:15 -05:00
Scott Ehlert b4b37daaf6 Triggering build to fix bug 4729. 2010-12-03 23:58:41 -08:00
Nicholas Hastings 1f187d24c8 Updated TF2_GetPlayerConditionFlags to match Valve's current logic. 2010-12-03 17:12:06 -05:00
Nicholas Hastings 5b806a467b Fixed BanClient always banning by IP address (bug 4626, r=fyren). 2010-11-30 13:09:30 -05:00
Jason Booth 20d14d5a10 Fixed profiler flush not clearing, added 'report' and 'clear' (bug 4674, r=dvander). 2010-11-30 13:08:30 -05:00
Nicholas Hastings 043b2df345 Fixed voting crash when client console, chat, and SourceTV are enabled (bug 4676, r=fyren). 2010-11-30 13:04:13 -05:00
Nicholas Hastings 9ec7feb9ab Fixed CDetour crash in TF2 extension when last plugin using forward is unloaded (bug 4713, r=fyren). 2010-11-28 22:41:48 -05:00
Nicholas Hastings 57cf6db4e0 Fixed TF2 GetHoliday Windows signature (bug 4714, r=fyren). 2010-11-24 20:46:17 -05:00
Nicholas Hastings 61b677c073 Add GetGameRules to ISDKTools (bug 4707, r=fyren) 2010-11-19 23:02:27 -05:00
Nicholas Hastings 264e42a4c5 Merge 2010-11-19 15:52:41 -05:00
Nicholas Hastings 251fd660f9 Backed out changeset: 07fb9b761438 2010-11-19 15:52:33 -05:00
Matt Woodrow 6459f53263 Why, oh why, do you do this to me gcc? 2010-11-19 18:16:24 +13:00
Matt Woodrow 55c8d93862 gcc strikes again with the no newline error. Bustage fix 2010-11-19 18:12:40 +13:00
Matt Woodrow c6f83f8c14 Bustage fix. Thanks for nothing Crimson 2010-11-19 18:07:28 +13:00
Brett Powell c9eaca0e56 Add WaitingForPlayers forwards to TF2 extension (bug 4704, r=pred) 2010-11-19 17:58:46 +13:00
Brett Powell 6267c17c6b Extend Nominations API (bug 4677, r=pred) 2010-11-19 17:39:53 +13:00
Brett Powell 616113d384 Add GetGameRules to ISDKTools (bug 4707, r=pred) 2010-11-19 17:37:26 +13:00
Nicholas Hastings ac738aff10 TF2 GetHoliday detour now detours UTIL_GetHoliday (bug 4700, r=fyren). 2010-11-09 21:12:38 -05:00
A.W. Stanley 7627bf80b9 Added TF2_IsPlayerInDuel native to TF2 extension (bug 4695, r=psychonic). 2010-11-07 19:05:32 -05:00
Scott Ehlert 172abb2710 Added support for L4D on Mac OS X (bug 4684, r=fyren). 2010-10-29 20:04:50 -05:00
Scott Ehlert a643c6ef1e Fixed sample ext makefiles for L4D Linux builds (bug 4681, r=fyren). 2010-10-28 12:42:13 -07:00
Nicholas Hastings 64bfb0961e Updated TF2 customkill defines (bug 4682, r=fyren). 2010-10-28 10:23:30 -04:00
Scott Ehlert 68d822f50a Fixed loading L4D on Linux (bug 4681, r=dvander). 2010-10-27 22:05:56 -07:00
Fyren 56e3bab02a vcproj crap (NPOTB) 2010-10-20 05:13:48 -07:00
Fyren 9dd5ab4ebd Fix Windows entity output hooks (bug 4644, r=dvander) 2010-10-20 05:10:13 -07:00
David Anderson b1ef86de75 Follow-up fixes to database conf reading (bug 4286, r=fyren). 2010-10-16 22:27:34 -07:00
Fyren b4a0d7a5b7 Use SH strings for database configs (bug 4286, r=dvander) 2010-10-16 03:52:36 -07:00
Scott Ehlert e6a93a799a Added support for L4D2 on Mac OS X (bug 4647, r=fyren). 2010-10-14 18:27:37 -05:00
Nicholas Hastings 4e175f9cd6 Updated Gmod gamedata (bug 4652, r=fyren). 2010-10-07 18:35:26 -04:00
Nicholas Hastings 62e3fe1414 Merge. 2010-10-06 20:47:16 -04:00
Nicholas Hastings eeb7285528 Updated CSS/DODS/TF2/HL2DM CommitSuicide offset (bug 4650, r=fyren). 2010-10-06 20:46:29 -04:00
Scott Ehlert 0340b62b7c Triggering build against L4D2 SDK changes.
This should fix sm_kick.
2010-10-05 23:32:27 -07:00
Scott Ehlert 5488f60260 Triggering build against L4D1 SDK changes. 2010-10-05 20:07:14 -07:00
Fyren be7ef860d5 Revert mistaken vsound.cpp change 2010-10-04 19:45:21 -07:00
Zach Kanzler 9aba700d8c Added GetMessageName to IUserMessages (bug 4573, r=pred). 2010-10-02 17:58:06 -04:00
Nicholas Hastings 7972acf5bf Added one more missing enum value in tf2_stocks. 2010-10-01 15:24:30 -04:00
Fyren 430c001d58 Static gamedata checker (NPOTB) 2010-10-01 12:15:43 -07:00
Nicholas Hastings 943777e5d0 Fixed/updated TF2_DisguisePlayer (bug 4641, r=fyren). 2010-10-01 10:46:21 -04:00
Nicholas Hastings c086c3b03b Updated more TF2 gamedata and fixed RemoveCondition call (bug 4641, r=fyren). 2010-10-01 09:07:51 -04:00
Nicholas Hastings e517eceb24 Shortened names of some symbols in tf2_stocks (bug 4642, r=fyren). 2010-10-01 08:50:18 -04:00
Nicholas Hastings 7fb57a4064 Updated TF2 includes with more defined identifiers (bug 4640, r=dvander). 2010-09-30 23:40:42 -04:00
Nicholas Hastings 888bca13c0 Updated HL2DM gamedata (bug 4636, r=fyren). 2010-09-30 20:09:10 -04:00
psychonic 8b39e0631d Updated DODS gamedata (bug 4638, r=fyren). 2010-09-30 17:24:19 -04:00
psychonic d0d0148a58 Updated TF2 gamedata (bug 4635, r=fyren). 2010-09-30 17:23:54 -04:00
psychonic a73b62c5bf Updated CSS gamedata (bug 4637, r=fyren). 2010-09-30 17:23:37 -04:00
Nicholas Hastings bee0afd301 forcing build 2010-08-27 20:15:28 -04:00
Nicholas Hastings 8f37940f4c Updated cstrike ext gamedata for 2010-08-26 update (bug 4595, r=fyren). 2010-08-26 22:23:07 -04:00
Nicholas Hastings 0fa8d8cb51 Updated Gmod gamedata, including linux support (bug 4569, r=fyren). 2010-08-24 19:23:57 -04:00
Nicholas Hastings 1f589d0d5d Added AMXX Pawn geshi generation script. 2010-08-23 13:53:44 -04:00
Nicholas Hastings ad36745a7c Normalized spacing and fixed warnings with newest geshi in (Source)Pawn geshi script. 2010-08-23 13:52:42 -04:00
Scott Ehlert 99b9860ea5 Added Alien Swarm build config for sample extension (bug 4530, r=psychonic). 2010-08-20 10:42:16 -05:00
Scott Ehlert dc5f82cce2 Fixed alignment on a couple of SourcePawn debugging structures on OS X (bug 4578, r=dvander).
This problem only affected plugins compiled with a fairly old version of spcomp.
2010-08-19 22:51:42 -05:00
Nicholas Hastings dc3050537b Fixed timeleft not getting reset on Game_Commencing in CS:S (bug 4557, r=fyren). 2010-08-19 21:57:09 -04:00
Nicholas Hastings 5acd0dd2d1 Fixed Curl lib AMBuilder script failing with vs2010 (bug 4575, r=ds). 2010-08-19 13:03:14 -04:00
Scott Ehlert 0d933a1901 Disabled nextmap plugin on Alien Swarm (bug 4571, r=fyren). 2010-08-16 15:13:47 -05:00
Nicholas Hastings 9f21865caf Fixed typo in edd61d1e1e26 (bug 4542) 2010-08-05 19:24:30 -04:00
Nicholas Hastings 2ba81d3fef Added initial gamedata for Alien Swarm (bug 4530, r=ds). 2010-08-02 12:28:38 -04:00
Erik Minekus bcc1c2e658 Fixed typos in some usage replies (bug 4552, r=dvander). 2010-08-02 09:44:49 -04:00
Nicholas Hastings 5fa8972ae6 Fixed Ignite crash on Fistful of Frags (bug 4556, r=fyren). 2010-08-02 09:37:36 -04:00
Nicholas Hastings 96363a0ce3 Fixed Firearms Source FireOutput signature (bug 4555, r=fyren). 2010-08-02 09:36:10 -04:00
Scott Ehlert 817fa9d9be Oh, fixed package script for new bintools binary (bug 4548). 2010-08-01 15:09:48 -05:00
Scott Ehlert 89334bb459 Bintools extension no longer needs a separate build for each engine (bug 4548, r=dvander). 2010-08-01 14:57:54 -05:00
Scott Ehlert 0ae2d99599 Fixed potential crash with IMemUtils::FindPattern on Linux (bug 4554, r=dvander). 2010-07-31 16:06:22 -05:00
Scott Ehlert e1199a02ee Fixed missing version string and compile date for MySQL extension (bug 4547, r=dvander). 2010-07-28 14:48:51 -05:00
Scott Ehlert 9408a61eb1 Ugh, fixed builds for real. How did that even happen? 2010-07-27 20:28:27 -05:00
Scott Ehlert 78d7e1bdfe Hopefully fixed build. 2010-07-27 18:02:37 -05:00
Scott Ehlert dd44a0aaea Added support for Alien Swarm (bug 4530, r=dvander). 2010-07-27 17:32:32 -05:00
Nicholas Hastings b3144dd19a Added gamedata for Fistful of Frags (bug 3883, r=fyren). 2010-07-26 19:26:32 -04:00
Nicholas Hastings 2722e96fac Two more phrases in ice.sp are now able to use translations (bug 4540, r=fyren). 2010-07-26 19:11:06 -04:00
pheadxdll 488de0014e Added TF2_MakeBleed native to TF2 ext (bug 4542, r=fyren,psychonic). 2010-07-26 11:06:08 -04:00
Zach Callear 9c2e0ebd4c Fixed living players hearing dead players if alltalk is disabled while deadtalk is on (bug 4533, r=fyren). 2010-07-26 08:23:49 -04:00
Nicholas Hastings 28cc96cfd0 Fixed errors and missing effects caused by missing sprites on L4D2 (bug 4512, r=fyren). 2010-07-26 08:15:52 -04:00
Erik Minekus 4ab3b15efd Added TF2 object stocks (bug 4536, r=psychonic). 2010-07-23 21:23:35 -04:00
Nicholas Hastings ff363e3893 Added gamedata for Firearms: Source (bug 4537 r=fyren). 2010-07-23 21:16:15 -04:00
Nicholas Hastings cd2c10b6dc Added support for logical entities to gamedata for Synergy. (bug 4534, r=fyren) 2010-07-22 21:38:55 -04:00
Scott Ehlert 563e981902 Fixed Linux and OS X builds. 2010-07-21 22:23:56 -05:00
Fyren c3e20d5d12 FireOutput detour in SDKTools now uses CDetour (bug 4416, r=pred). 2010-07-21 22:09:03 -05:00
Nicholas Hastings 2802486671 Fixed a couple small things in npp xml generation script. 2010-07-21 08:46:52 -04:00
Nicholas Hastings 1507d03c21 Updated TF2 conditions enum and defines (bug 4526, r=fyren) 2010-07-20 11:21:37 -04:00
Jason Booth fbbf193345 Fixed duplicated entries and unnecessary file locking in ProfViewer (bug 4510, r=dvander) 2010-07-18 21:39:15 -04:00
Jason Booth 78e51e6b11 Fixed problems with ProfViewer project file (bug 4510, r=dvander) 2010-07-18 21:37:18 -04:00
Nicholas Hastings be2bbec526 Fixed PlayerRunCmd being hooked when not used. (bug 3990, r=fyren) 2010-07-18 15:43:56 -04:00
Scott Ehlert a366096ef4 Added MSVC10 project file for sample extension (bug 4521, r=dvander). 2010-07-15 15:19:14 -05:00
Scott Ehlert c72222f718 Updated docs on replicate and notify params for SetConVar* and ResetConVar (bug 4517, r=pred). 2010-07-14 20:29:53 -05:00
Scott Ehlert fba0ec93bf Fixed replicate and notify params not working on old engine games (bug 4516, r=pred).
This also fixes an issue where clients could be notified of convar changes twice on newer engines (Orange Box and later).
2010-07-14 20:29:45 -05:00
Scott Ehlert 86f767e1aa Made name param of GetConVarName() non-const (bug 4515, r=pred). 2010-07-14 20:29:29 -05:00
Scott Ehlert 7e54192713 Added gamedata for DOD:S on Mac OS X. (bug 4513, r=dvander). 2010-07-12 21:03:25 -05:00
David Anderson e76a73e276 Fixed Windows build fo' realz. 2010-07-11 18:06:06 -07:00
David Anderson ccf0490624 Windows build fix. 2010-07-11 17:45:35 -07:00
David Anderson fe2721e04e Merge. 2010-07-11 17:33:09 -07:00
David Anderson fdd1a9afef Use hash table for global name lookups (bug 4496, r=fyren). 2010-07-11 17:32:46 -07:00
Scott Ehlert abf7aed880 Triggering a build to compile against L4D2 SDK changes (bug 4509). 2010-07-11 03:00:30 -05:00
Nicholas Hastings d986c7cdc0 Fixed TF2 sigs that broke with recent update (bug 4506, r=fyren) 2010-07-08 21:07:06 -04:00
Scott Ehlert 9d5e994c01 Bleh, fixed compiler error in console.inc caused by previous changeset. 2010-07-07 02:27:59 -05:00
Scott Ehlert 6f16fc77b8 Added GetConVarDefault() native (bug 4502, r=dvander). 2010-07-06 17:32:58 -05:00
David Anderson 651dfb796c Merge. 2010-07-02 18:17:16 -07:00
David Anderson 4f2fc17a8f Fixed staging buffers reallocating on every operation (bug 3820, r=fyren+fyren). 2010-07-02 18:16:50 -07:00
David Anderson 7bc019547f Fixed O(n) insertion of debug strings (bug 4495, r=fyren). 2010-07-02 18:16:15 -07:00
David Anderson f8c2629a3e Fixed O(n^2) generation of debug info tables (bug 4493, r=fyren). 2010-07-02 18:15:59 -07:00
David Anderson b5b4bff2fc Fixed bogus assert in callfunction (bug 4487, r=fyren). 2010-07-02 18:15:21 -07:00
David Anderson 7054b92a14 Fixed bogus assert about name lengths (bug 4486, r=fyren). 2010-07-02 18:12:31 -07:00
Nicholas Hastings 5856f9a45f Gmod gamedata update (bug 4489, r=fyren) 2010-06-29 18:17:25 -04:00
Fyren cec10060c6 How did I even do that. 2010-06-28 17:25:06 -07:00
Fyren 74a479ab41 Fix build 2010-06-28 16:41:08 -07:00
Nicholas Hastings e51ab09bb1 Backed out changeset: f1bfc4089ce5 2010-06-28 19:17:10 -04:00
Nicholas Hastings 0cd98bc353 Another try at fixing build. 2010-06-28 19:12:37 -04:00
Nicholas Hastings 158f9b0dc7 Backed out changeset: 54086a5d694b 2010-06-28 19:12:05 -04:00
Nicholas Hastings 95fe6eaf86 Fix build. 2010-06-28 19:03:16 -04:00
Nicholas Hastings 40b4859b16 newline 2010-06-28 18:37:43 -04:00
Nicholas Hastings e4832f0d08 Added forward/detour for TF2's GetHoliday function (bug 4462, r=pred) 2010-06-28 17:48:14 -04:00
_KaszpiR_ 5d5400a9ac Added FindFlagChar native. (bug 3776, r=dvander) 2010-06-27 19:17:25 -04:00
David Anderson f439cad46c Removed code now dead from CS:S Orange Box move (bug 4399, r=ds). 2010-06-23 23:35:28 -07:00
Nicholas Hastings 9fe2e8e31a Removed cstrike ep1 and cstrike_beta builds and references. 2010-06-23 23:49:06 -04:00
Erik Minekus 92d3fc3d8c Fixed lack of error checking on sm_motd. (bug 4460, r=dvander) 2010-06-23 23:41:47 -04:00
Nicholas Hastings 5d89599799 Backed out changeset: 6c4d95b625ea 2010-06-23 23:40:53 -04:00
Erik Minekus 2eb5b5eb67 Fixed lack of error checking on sm_motd. 2010-06-23 23:39:39 -04:00
Nicholas Hastings 45549a8173 Cstrike ext now recognizes and loads on cstrike_beta (bug 4399, r=fyren) 2010-06-23 10:08:08 -04:00
devicenull d7ebf2edc1 Fixed inaccuracy in CommandListener documentation 2010-06-23 09:22:49 -04:00
Greyscale a9aed2e557 Removed unnecessary tag from return value of SetArrayCell 2010-06-23 09:17:21 -04:00
Nicholas Hastings d691a0cf24 Ep2v cstrike ext now gets added to package. 2010-06-23 08:54:56 -04:00
Nicholas Hastings cbaa959521 Adding building of cstrike ext for ep2v (bug 4399, r=fyren) 2010-06-23 08:19:19 -04:00
Nicholas Hastings 2f128113b6 Added missing TF2 critcola condflag define (bug 4464, r=fyren) 2010-06-22 19:31:33 -04:00
Nicholas Hastings 70251a8b2e Updated TF2 'Burn' signature (bug 4463, r=fyren) 2010-06-22 19:26:07 -04:00
Fyren e332f4e12b Possible dynamic array dimension fix (bug 4428, r=dvander) 2010-06-19 15:15:23 -07:00
Nicholas Hastings 9a140ff93f Fixed outputname null pointer crash in sdktools (bug 4422, r=fyren) 2010-06-14 09:32:50 -04:00
David Anderson 97ab5dd1b5 Fixed switch case comparisons failing with large numbers (bug 4457, r=pred). 2010-06-13 20:26:58 -07:00
Scott Ehlert 075b4e92a9 Added gamedata for TF2 on Mac OS X. (bug 4455, r=dvander). 2010-06-10 17:12:52 -05:00
Nicholas Hastings f22dcfe03c Added missing FireOutput and PlayerRunCmd gamedata for zombie_master (bug 4452, r=fyren) 2010-06-07 19:35:34 -04:00
Scott Ehlert 124086419e Fixed IMemUtils::ResolveSymbol() on Mac OS X (bug 4448, r=dvander). 2010-06-07 13:26:45 -05:00
Nicholas Hastings 0712db0d29 Merge. 2010-06-06 20:53:13 -04:00
Nicholas Hastings 895f7edd12 Added new player condition (TFCond_CritCola) to tf2.inc. (bug 4447, r=fyren) 2010-06-06 20:51:35 -04:00
Matt Woodrow a3c5c0c23a Merge 2010-06-07 10:33:47 +12:00
Matt Woodrow f7a3a6c17b Fixed clientprefs deleting cookies twice in rare cases (bug 4412, r=Fyren) 2010-06-07 10:30:33 +12:00
Nicholas Hastings 98bec2580e Fixed OnClientConnected forward not firing for bots (bug 4443, r=fyren) 2010-06-06 17:53:38 -04:00
Fyren 5ca2d469a8 Fix sdktools voice memory corruption (bug 4415, r=dvander) 2010-06-05 23:15:29 -07:00
Scott Ehlert b413405876 Added gamedata for CS:S Beta (ep2v) on Mac OS X. (bug 4399, r=dvander). 2010-06-04 17:14:52 -05:00
Nicholas Hastings 330ff93e3e Updated Obsidian Conflict gamedata (bug 4439, r=fyren) 2010-06-02 07:47:00 -04:00
Nicholas Hastings fe08104d18 Fixed tf2.inc incorrectly attempting to load tf2 ext on all games (bug 4197, r=fyren) 2010-05-31 16:31:10 -04:00
Scott Ehlert e518605d69 Fixed various areas where code was being compiled for Linux only, but should actually be used on OS X too (bug 4392, r=dvander). 2010-05-29 18:11:47 -04:00
Scott Ehlert 9a35085ac3 Merge. 2010-05-29 00:38:08 -05:00
Scott Ehlert b0cf41de08 Fixed potential problem when using bintools to call functions that return objects by value on OS X (bug 4392, r=dvander).
Objects are only returned in memory when their sizes are greater than 8 or are not a power of 2.
2010-05-29 00:22:21 -05:00
Nicholas Hastings 00c3dc73f3 Updated/fixed SourceForts gamedata (bug 4429, r=fyren) 2010-05-28 13:28:04 -04:00
Scott Ehlert a73cc93d21 Added version information to Mac OS X binaries (bug 4392, r=dvander). 2010-05-27 21:05:32 -05:00
Scott Ehlert 5a10299074 Added Mac OS X build support to sample extension makefiles (bug 4392, r=dvander). 2010-05-27 21:04:49 -05:00
Scott Ehlert 77d243f87f Merge. 2010-05-27 21:04:22 -05:00
Nicholas Hastings fb4f6406c9 Fixed SDKTools sm_dump_datamaps crash on improperly created entities (bug 4424, r=pred) 2010-05-26 08:30:13 -04:00
Scott Ehlert 3133b9b010 Merge. 2010-05-22 01:08:42 -05:00
Nicholas Hastings 12723167fc Added gamedata for Resistance and Liberation (bug 4418, r=fyren) 2010-05-21 14:04:19 -04:00
Nicholas Hastings 2cc22778b5 Added comment to databases.cfg to denote acceptable "host" types 2010-05-21 14:00:33 -04:00
Nicholas Hastings 790d3f12a6 Empires gamedata fixes (bug 4417, r=fyren). 2010-05-21 13:55:29 -04:00
Scott Ehlert beb1ab81e0 Updated .hgignore to ignore dylib binaries on OS X. 2010-05-19 04:31:10 -05:00
Scott Ehlert e5126b4c65 Added support for "mac" in game data files (bug 4393, r=dvander). 2010-05-16 02:27:53 -04:00
Scott Ehlert a2a4df5d06 Triggering build. 2010-05-15 20:50:24 -04:00
Scott Ehlert ac0bd9714b Triggering build. 2010-05-15 20:00:55 -04:00
David Anderson 60226d9195 Fixed windows build. 2010-05-15 13:01:23 -07:00
David Anderson 64455b9852 Moved gameconf code from core to logic (bug 4406 part 11, r=ds).
--HG--
rename : core/GameConfigs.cpp => core/logic/GameConfigs.cpp
rename : core/GameConfigs.h => core/logic/GameConfigs.h
rename : core/smn_gameconfigs.cpp => core/logic/smn_gameconfigs.cpp
2010-05-14 23:35:42 -07:00
David Anderson 96f6cdf677 Moved datapack natives from core to logic (bug 4406 part 10, r=ds).
--HG--
rename : core/smn_datapacks.cpp => core/logic/smn_datapacks.cpp
2010-05-14 21:16:35 -07:00
David Anderson c188491289 Moved handle natives from core to logic (bug 4406 part 9, r=ds).
--HG--
rename : core/smn_handles.cpp => core/logic/smn_handles.cpp
2010-05-14 21:06:06 -07:00
David Anderson e9e4d566a5 Build fix. 2010-05-14 20:56:40 -07:00
David Anderson 85bedca236 Move string natives from logic to core (bug 4406 part 8, r=fyren).
--HG--
rename : core/smn_string.cpp => core/logic/smn_string.cpp
2010-05-14 20:04:44 -07:00
David Anderson d80191df3d Move replace functions from logic to core (bug 4406 part 7, r=fyren). 2010-05-14 20:04:30 -07:00
David Anderson 9137e92c09 Move translator from logic to core (bug 4406 part 6, r=ds).
--HG--
rename : core/PhraseCollection.cpp => core/logic/PhraseCollection.cpp
rename : core/PhraseCollection.h => core/logic/PhraseCollection.h
rename : core/Translator.cpp => core/logic/Translator.cpp
rename : core/Translator.h => core/logic/Translator.h
rename : core/sm_memtable.h => core/logic/sm_memtable.h
rename : core/smn_lang.cpp => core/logic/smn_lang.cpp
2010-05-14 19:43:53 -07:00
David Anderson 721dae3892 Inline sm_memtable (bug 4406 part 5, r=ds). 2010-05-14 19:43:38 -07:00
David Anderson 1cdacf69be Move some string functions from core to logic (bug 4406 part 4, r=fyren). 2010-05-14 19:28:10 -07:00
David Anderson b5b002aa4b Move banning natives from core to logic (bug 4406 part 3, r=fyren).
--HG--
rename : core/smn_banning.cpp => core/logic/smn_banning.cpp
2010-05-14 18:22:03 -07:00
David Anderson 78f5b513c0 Move admin natives from core to logic (bug 4406 part 2, r=ds).
--HG--
rename : core/smn_admin.cpp => core/logic/smn_admin.cpp
2010-05-14 17:46:19 -07:00
David Anderson 0032fcaa66 Move memutils from core to logic (bug 4406, r=ds).
--HG--
rename : core/MemoryUtils.cpp => core/logic/MemoryUtils.cpp
rename : core/MemoryUtils.h => core/logic/MemoryUtils.h
rename : core/sm_symtable.h => core/logic/sm_symtable.h
2010-05-14 16:14:59 -07:00
Scott Ehlert 0fba0923c8 Changed MSVC compiler flag /Ot to /Ox and added /OPT:REF linker flag. 2010-05-14 02:42:08 -05:00
Scott Ehlert e0169f6696 Fixed loader on Mac OS X (bug 4392, r=dvander). 2010-05-14 01:04:17 -05:00
David Anderson 28217f10cb Added ProcessTargetString simple filter API (bug 4404, r=ds). 2010-05-13 12:28:51 -07:00
Scott Ehlert fb28f4bcd0 Fixed package name for Windows (bug 4395). 2010-05-13 04:54:31 -05:00
Scott Ehlert 8852256ab6 Appended OS names to package archives (bug 4395, r=dvander). 2010-05-13 04:23:43 -05:00
Scott Ehlert 95de453677 Compile and link fixes for Mac OS X (bug 4392, r=dvander). 2010-05-13 04:22:31 -05:00
Scott Ehlert 5ef40e15c4 Add support for Mac OS X to ResolveSymbol() and FindPattern() in IMemUtils (bug 4392, r=dvander). 2010-05-13 04:20:41 -05:00
Scott Ehlert 31f223bff5 Merge. 2010-05-13 04:19:39 -05:00
Scott Ehlert 9fce2b1d8e Only build OB-Valve binaries on Mac OS X for now (bug 4392, r=dvander). 2010-05-13 04:18:58 -05:00
David Anderson a6ceb337b2 Move timer natives into logic binary (bug 4402, r=ds).
--HG--
rename : core/smn_timers.cpp => core/logic/smn_timers.cpp
2010-05-13 01:47:12 -07:00
Scott Ehlert f4e22cb44c Backed out changeset 29e6cc6f2124 (bug 4392). 2010-05-12 04:13:56 -05:00
David Anderson ab9750f8b2 Only build OB-Valve binaries on Mac OS X right now (bug 4392, r=ds). 2010-05-11 23:48:39 -05:00
Nicholas Hastings fe8e0b0e0a Merge 2010-05-11 20:41:19 -04:00
Nicholas Hastings c2565cf3b7 Updated gamedata for ep2v cstrike(_beta) (bug 4399, r=fyren) 2010-05-11 20:40:14 -04:00
David Anderson af82971bf5 Fixed Windows build. 2010-05-11 02:07:35 -07:00
David Anderson 271b52158e Mac build fixes (bug 4392, r=me). 2010-05-11 01:46:55 -07:00
Fyren 26c404adee Mac build fixes (bug 4392, r=dvander). 2010-05-11 01:46:54 -07:00
Scott Ehlert f06af54165 Fixed compiler and linker flags for darwin (r=dvander).
The previous commit by 'me' was a fake atrocity created by dvander. :o
2010-05-11 02:36:03 -05:00
Fyren 2a77dfbcd2 Fixed buildbot scripts for darwin (r=dvander). 2010-05-11 00:16:52 -07:00
David Anderson 738fcb6563 Added pcre-7.9 build for darwin. 2010-05-11 00:10:37 -07:00
Scott Ehlert 3d4754d4ad Fixed master amb script for darwin (r=dvander). 2010-05-11 00:10:36 -07:00
Scott Ehlert b9ea1d1be4 Fixed master amb script for darwin (r=dvander). 2010-05-11 00:10:36 -07:00
Nicholas Hastings b1b0484dae Fixed TF2 natives not being marked optional when ext not required (bug 4389, r=fyren) 2010-05-10 18:18:15 -04:00
Nicholas Hastings 20b79784bf Updated Empires gamedata (bug 4390, r=fyren) 2010-05-08 21:37:21 -04:00
Nicholas Hastings 4baa3358df Updated geshi and npp sp language files for SM 1.3.2
Also fixed typo in geshi generator and added 'default' to list of reserved words.
2010-05-08 21:31:32 -04:00
Scott Ehlert 8fe7f8b8d8 Fixed SendConVarValue() on TF2, DOD:S, L4D, and L4D2 (bug 4273, r=dvander). 2010-05-04 22:53:26 -04:00
Scott Ehlert 6996a0db2b Argh, really fixed HookEntityOutput() crash on TF2 (bug 4375). 2010-04-30 11:18:45 -04:00
Scott Ehlert b89a899c82 Fixed HookEntityOutput() crash with recent updates to TF2 and L4D2 (bug 4375, r=pred, a=blocking). 2010-04-30 03:51:35 -04:00
Fyren bbbbb660b3 Triggering build 2010-04-29 20:48:17 -07:00
Scott Ehlert 6ba29219e5 Updated sample extension makefiles to compile against latest changes for L4D2 and TF2 (bug 4374, r=dvander). 2010-04-29 16:06:32 -04:00
Nicholas Hastings dd97bdcc2c Fixed SetUserCvar offset for ep2v (bug 4371, r=fyren) 2010-04-29 14:12:08 -04:00
Nicholas Hastings b63e0f08bf Backed out changeset 907677755029 2010-04-29 14:11:03 -04:00
Nicholas Hastings c5ae9d45ad Fixed SetUserCvar offset for ep2v (bug 4371, r=fyren) 2010-04-29 14:05:22 -04:00
David Anderson e906a0da8c Merge. 2010-04-29 01:28:27 -07:00
David Anderson 2edfb0aaac Fixed regression when using panels (no bug, r=me). 2010-04-29 01:28:11 -07:00
Nicholas Hastings dc116858a9 ep2v gamedata (bug 4371, r=fyren) 2010-04-29 00:09:35 -07:00
Fyren 1a938f8711 ep2v build changes (bug 4371, r=dvander) 2010-04-29 00:08:08 -07:00
David Anderson fc88cd3cb1 Check return value of GetPlayerNetInfo (bug 4315, r=fyren). 2010-04-27 23:40:04 -07:00
David Anderson 55205e631b Merge. 2010-04-27 21:07:59 -07:00
David Anderson a36fa76d21 Root menu handles in callbacks (bug 4353, r=fyren). 2010-04-27 21:03:20 -07:00
Nicholas Hastings b8d512f5e1 Fixed entity output hooks not working in Insurgency (bug 4365, r=fyren) 2010-04-24 21:10:23 -04:00
Nicholas Hastings d4263b59c6 Added obsidian to list of games which support tempents with ep2 gamedata (thread 75480, r=me). 2010-04-24 21:08:06 -04:00
Nicholas Hastings e5e1507dff Fixed functions.inc not having double-include prevention (bug 4342, r=fyren) 2010-04-24 21:06:10 -04:00
Zach Kanzler 2edf63c5fd Fixed IGamePlayer->GetUserId() returning junk (bug 3916, r=fyren) 2010-04-24 21:00:43 -04:00
Fyren 5ec4b3441e Build stuff for L4D2 DLC (bug 4361, r=SAWCE) 2010-04-23 11:39:12 -07:00
Nicholas Hastings dd1757b3c3 Updated L4D2 gamedata for The Passing update (bug 4361, r=pending) 2010-04-23 14:22:41 -04:00
Nicholas Hastings dda26545e5 Updated Insurgency gamedata for Insurgency 2010-04-19 update (bug 4356, r=fyren) 2010-04-23 10:38:16 -04:00
Nicholas Hastings 410ef8ce96 Merge 2010-04-19 11:18:46 -04:00
Nicholas Hastings ce7cb9cf64 Added Notepad++ userDefineLang.xml generator for Sourcepawn
(based on the SP GeSHi generator)
2010-04-19 11:10:26 -04:00
Nicholas Hastings 31a16375ab Enhanced Sourcepawn GeSHi generation script
* Added a few missing keywords.
* Added better preprocessor, number, and string control char highlighting.
* Added default tab width (of 4 spaces).
* Fixed parsing of some enum values.
* Changed keywords to be case sensitive.
* Changed colors to be more sane.
2010-04-19 11:08:23 -04:00
Nicholas Hastings ec7b47da22 Updated Empires gamedata for Empires 2.25a release (bug 4108, r=fyren) 2010-04-19 10:38:28 -04:00
David Anderson 0124020ba4 Added obsidian to list of games which need menu redraws (thread 123237, r=me). 2010-04-04 23:50:27 -07:00
David Anderson 28f71d18bd Added obsidian to radiotimeout game list (t=123237, r=me). 2010-04-04 23:49:28 -07:00
Nicholas Hastings fe226c1c8d Updated sourcepawn GeSHi colors slightly to appease 2.53% of the haterz. 2010-03-31 18:40:03 -04:00
Nicholas Hastings 18e20de4d6 Added GeSHi language file generator for Sourcepawn 2010-03-31 14:27:09 -04:00
Nicholas Hastings 956d345e17 Added TF2_StunPlayer native and TF2_GetPlayerConditionFlags stock to TF2 ext. (bug 4331, r=pred) 2010-03-31 08:51:25 -04:00
Nicholas Hastings ddfb958647 Added missing semicolon in plugins/include/tf2.inc. 2010-03-23 20:06:13 -04:00
Nicholas Hastings 145d0ef37d Added Gamerules SDKCall support to CSPromod gamedata (bug 4320, r=pred) 2010-03-23 19:42:19 -04:00
Nicholas Hastings 019e3956f7 Fixed bad caller crash with HookEntityOutput (bug 4311, r=fyren) 2010-03-20 11:07:45 -04:00
Nicholas Hastings a72daff4ac Added 4 new natives to TF2 ext. (bug 4166, r=pred)
Added natives for Regenerate, add/remove condition, and SetPlayerPowerPlay. Also updated TF2 test plugin.
2010-03-18 11:35:05 -04:00
Nicholas Hastings 58ce9cd37f Added missing core voting cvars to sourcemod.cfg (bug 4309, r=fyren) 2010-03-11 22:00:46 -05:00
Nicholas Hastings 687bdaff8f Added missing core voting cvars to sourcemod.cfg (bug 4224, r=pred) 2010-03-11 17:43:46 -05:00
Nicholas Hastings 2143a66ad6 Fixed incorrect DispatchSpawn signature for ZPS and added ShowMenu and Hudtext support (bug 4279, r=Fyren) 2010-03-09 20:39:56 -05:00
Nicholas Hastings 74892f1562 Re-enabled ShowMenu support for FortressForever (bug 4028, r=dvander) 2010-03-09 18:50:47 -05:00
Nicholas Hastings 4a59ac011f Fixed FireOutput signature for FortressForever (bug 4062, r=dvander) 2010-03-09 18:47:56 -05:00
Nicholas Hastings e0fd2e8f27 Fixed sm_rename on L4D2 on Windows (bug 4131, r=dvander) 2010-03-09 18:44:18 -05:00
Nicholas Hastings ba76506773 Fixed inaccurate description for sm_unban (bug 4245, r=dvander) 2010-03-09 18:41:25 -05:00
Nicholas Hastings d224827544 Fixed CSPromod SDKTools Support (bug 4255, r=dvander) 2010-03-09 18:36:45 -05:00
Nicholas Hastings 8d35b5bd11 Updated PVKII support for PVKII 2.3 (bug 4276, r=dvander) 2010-03-09 18:29:31 -05:00
Nicholas Hastings 9df28c25d7 Fixed CreateGameRulesObject sig for ZPS (bug 4285, r=dvander). 2010-03-09 18:13:21 -05:00
Matt Woodrow 5f9b2a91fd Added optional 'No Vote' option to vote menu (bug 4217, r=dvander) 2010-02-27 14:56:02 +13:00
Erik Minekus 46a46f5e49 Fixed Insurgency gamedata file (bug 4282, r=dvander). 2010-02-24 23:41:06 -08:00
Liam 4bdc495d01 Corrected a typo in the string.inc file. (bug 4207, r=fyren) 2010-02-13 01:49:39 -05:00
Liam e60d5e6aeb Updated VC2010 files. 2010-02-13 01:13:43 -05:00
UNLOZE 7c3387755d Added MSVC10 files for Visual Studio 2010 support. 2010-02-13 00:40:53 -05:00
Fyren 6f04dad428 maxClients -> MaxClients in sdktools_sound.inc (fix bug 3985, r=psychonicsux) 2010-02-10 11:07:21 -08:00
Nicholas Hastings 6ed4720df3 Added missing file for Battlegrounds support (bug 4146). 2010-02-08 20:47:51 -08:00
Nicholas Hastings ac7b454039 Added SDKTools support for CSProMod (bug 4255, r=dvander) 2010-02-08 20:25:11 -08:00
Nicholas Hastings 0af39de346 Fixed base plugins using GetMaxClients() instead of MaxClients (bug 3985, r=dvander). 2010-02-08 20:14:52 -08:00
Nicholas Hastings d484979fe8 Fixed CreateEntityByName for Insurgency (bug 4180, r=dvander). 2010-02-08 20:10:24 -08:00
Nicholas Hastings 6e87e5c05f Updated Garry's Mod offsets (bug 4230, r=dvander). 2010-02-08 20:08:14 -08:00
Nicholas Hastings 7633c8e76e Fixed nextmap errors on Garry's Mod (bug 4268, r=dvander). 2010-02-08 20:06:48 -08:00
Fyren c78e89c3c1 Compiler confused |any| tag with |String| on array arguments. 2010-02-08 20:00:06 -08:00
David Anderson 1852aaf332 Fixed GetClientCookieTime not being exported (bug 4237, r=fyren). 2010-02-08 19:58:36 -08:00
Nicholas Hastings 8b4c8f63c0 Fixed FindEntityByClassname crash in Synergy (bug 4235, r=dvander). 2010-02-08 19:57:20 -08:00
Fyren d7b64c18c2 Fixed NULL-deref in entity handling code. 2010-02-08 19:55:14 -08:00
Nicholas Hastings 09668c972e Fixed Day of Defeat offsets for 20100203 update (bug 4262, r=dvander). 2010-02-04 19:28:06 -06:00
Scott Ehlert 68a0d10443 Webternet and Updater extensions now load on Windows 2000 (bug 4234, r=dvander). 2010-01-20 15:12:57 -06:00
David Anderson 0708e7f8f6 Fixed accidental hook against garbage offset (bug 4231, r=fyren). 2010-01-20 04:03:46 -08:00
David Anderson 1235e989d4 Added PlayerRunCmd offset for DoD:s (bug 4231 mitigation, r=me). 2010-01-20 04:01:39 -08:00
Scott Ehlert 3a6808e4d8 Updated .hgignore for Explorer files beginning with a lowercase letter (argh!) 2010-01-20 02:40:55 -06:00
David Anderson dbfb034548 Mercurial queues... oh, how terrible. 2010-01-18 03:20:44 -08:00
David Anderson 94d01e9e5a Moved CRC32 from core to logic (no bug, r=me). 2010-01-18 03:08:52 -08:00
David Anderson 5e48b49b7e Updated credits for 1.3 release. 2010-01-14 03:29:31 -08:00
Greyscale 3b0785cae0 Fixed missing #endif in adminmenu.inc (bug 4216, r=dvander). 2010-01-14 00:22:45 -08:00
David Anderson bd3b46d624 Fixed command listener spew on server shutdown (bug 4198, r=fyren). 2010-01-13 21:48:51 -08:00
David Anderson 1cbe996831 Linux build fix (bug 3520 fallout). 2010-01-11 22:50:44 -08:00
Downtown1 18865c44c8 Added a new ValveCallType that allows for arbitrary |this| parameters, as well as associated features in gamedata and for reading/writing memory (bug 3520, r=dvander, sr=fyren). 2010-01-11 22:46:44 -08:00
David Anderson ead6ca73e5 Triggering build. 2010-01-11 20:09:34 -08:00
Nicholas Hastings deb3f6d9c4 Changed basechat to use %N instead of GetClientName (bug 4205, r=dvander). 2010-01-10 17:57:34 -08:00
Nicholas Hastings b1b98c5256 Fixed basechat not using color messages on hl2mp (bug 4204, r=dvander). 2010-01-10 17:51:24 -08:00
Nicholas Hastings 4dc2227f23 Fixed lack of quotes on some basechat log messages (bug 4132, r=dvander). 2010-01-10 17:50:30 -08:00
David Anderson a76f9e11fb Backed out changeset 9a52d61fe6ba (bad commit). 2010-01-10 17:49:44 -08:00
Nicholas Hastings abeb91a5e4 Fixed lack of quotes on some basechat log messages (bug 4132, r=dvander). 2010-01-10 17:47:11 -08:00
Nicholas Hastings 6d5e7cbe08 Added missing SDK define for L4D2 (bug 4209, r=dvander). 2010-01-10 17:38:03 -08:00
Nicholas Hastings c468c26ad6 Follow-up to bug 4194 (r=dvander). 2010-01-10 17:29:32 -08:00
David Anderson a0e940c5a9 Merge. 2010-01-10 17:16:08 -08:00
David Anderson 2f1de22cae Backed out changeset 292be4eb9d0c (bug 4211). 2010-01-10 17:16:02 -08:00
David Anderson 4631282709 Fixed reentrancy problems with iterators, forwards, and function removals (bug
4059, r=fyren).
2010-01-10 16:58:17 -08:00
Fyren 306ac5243a Fixed GuessSDKVersion() not working on ep2v (bug 4194, r=dvander). 2010-01-09 11:33:19 -08:00
Nicholas Hastings 956fe42a6c Fixed SetUserCvar (sm_rename) on TF/DoD Linux (bug 4196, r=dvander). 2010-01-07 01:26:01 -08:00
Nicholas Hastings 1824bdfe7e Add Insurgency to list of games that support HUD messages (bug 4136, r=dvander). 2009-12-19 20:42:32 -08:00
David Anderson 5f53284cbd Fixed build, wrong enum comparison. 2009-12-19 18:25:56 -08:00
David Anderson 7a84b71eb2 Fixed crashes from rare plugin loading errors (bug 4153, r=ds). 2009-12-19 18:19:28 -08:00
David Anderson 85382cd6c2 Fixed SourceMod crashing after flushing the profiler (bug 4149, r=ds). 2009-12-19 18:18:17 -08:00
David Anderson 02a99f1e51 Add ability to change dontBroadcast status on hooked events (bug 3886, r=ds). 2009-12-19 18:16:41 -08:00
Nicholas Hastings fe405df704 Another TF2 gamedata fix (bug 4151, r=dvander). 2009-12-19 12:57:26 -08:00
Nicholas Hastings ac5ee90c9b Battlegrounds 2 gamedata support (bug 4146, r=dvander). 2009-12-19 00:03:57 -08:00
Nicholas Hastings fb6b34e155 TF2 gamedata updates (bug 4147, r=dvander). 2009-12-18 22:01:41 -08:00
Fyren caa8932c9a Improve/fix GetEntity (bug 4092, r=pred) 2009-12-15 23:14:53 -08:00
David Anderson 75611f3bca Fixed profiler being set to NULL (bug 4143, r=fyren). 2009-12-14 23:08:15 -08:00
David Anderson f0f14d8a22 Fixed infinite loop in Windows build failure path (bug 4144, r=ds). 2009-12-14 23:07:54 -08:00
Nicholas Hastings 98ad6cd23b Fixed CreateEntityByName for Insurgency (bug 4046, r=dvander). 2009-12-14 20:31:16 -08:00
Nicholas Hastings bd80d1cd76 Updated Synergy gamedata (bug 3987, r=dvander). 2009-12-14 20:30:44 -08:00
Nicholas Hastings 5a4670ec2f Added HudText support for Zombie Master (bug 4004, r=dvander). 2009-12-14 20:30:04 -08:00
Nicholas Hastings 6fd039925a Added Neotokyo support (bug 4126, r=dvander). 2009-12-14 20:29:23 -08:00
David Anderson cd602ab5e3 Fixed basecomm description spelling (bug 4112, r=me). 2009-12-14 20:27:26 -08:00
Dog f59ead54d3 Fixed CommitSuicide offset on DoD:S (bug 4109, r=dvander). 2009-12-14 20:26:45 -08:00
Fyren 4030f1e40d Merge 2009-11-23 01:50:28 -08:00
Fyren b7ac7452f7 Fix wonky handling of path separators for "sm plugins" commands (bug 3857, r=dvander) 2009-11-23 01:47:32 -08:00
Scott Ehlert 5dd6867408 Updated .hgignore to ignore some Windows and OS X files. 2009-11-22 01:39:29 -06:00
Scott Ehlert 9d410df287 Updated sample_ext and mms_sample_ext for Orange Box Valve and Left 4 Dead 2 (bug 4118, r=pred). 2009-11-22 01:33:08 -06:00
David Anderson fe8dc36074 Use GetVSPInfo() from MM:S 1.8 legacy API (bug 4081, r=ds). 2009-11-20 15:18:58 -06:00
Fyren 0cef3fbf27 Fix leak in nominations plugin (bug 4104, r=pred) 2009-11-18 15:44:51 -08:00
Fyren b5d9b18da4 Fix rare basevotes map vote problem (bug 3905, r=dvander) 2009-11-18 15:42:21 -08:00
Scott Ehlert dc0ea197cd Added IMemoryUtils::ResolveSymbol() for resolving symbols hidden via GCC's -fvisibility=hidden (bug 4091, r=dvander,pred).
Right now, this is only used on L4D2 where it is needed.
2009-11-06 16:24:40 -06:00
David Anderson 5bf17fc5ae Clarified handle invariants in clientprefs.inc (no bug, r=me). 2009-11-04 13:52:12 -05:00
Fyren 33ca5943fa Don't call edict_t::StateChanged(ushort) on L4D2 (bug 4090, r=dvander) 2009-11-01 02:53:34 -08:00
Scott Ehlert edc6591041 Use SOURCE_ENGINE_ORANGEBOXVALVE constant from MM:S 1.8 (bug 4087, r=dvander). 2009-10-30 14:04:43 -05:00
Fyren 113ec33743 More L4D2 gamedata changes 2009-10-30 01:24:55 -07:00
Scott Ehlert 8c297832f6 Fixed Windows build, I think. 2009-10-30 00:03:54 -05:00
Fyren e767b2ff94 Typo fix 2009-10-29 20:34:00 -07:00
Scott Ehlert a1ff408c13 Merge. 2009-10-29 21:47:27 -05:00
Matt Woodrow 440184e83c New sdk uses _linux for vstdlib/tier0 2009-10-30 15:20:48 +13:00
Matt Woodrow 8ee6cad7ea Build Trigger 2009-10-30 15:10:34 +13:00
Matt Woodrow edb17b76f0 AMBuild updated to use new MM:S version 2009-10-30 14:58:17 +13:00
Fyren 31dc5f335d Updated GuessSDKVersion 2009-10-30 14:34:34 +13:00
Matt Woodrow eb68e4c627 SourceMod MSVC project files updated, windows tested and loading, gamedata fix. 2009-10-30 14:29:45 +13:00
Matt Woodrow 98e97920ae AMBuild updated for new L4D2 engine 2009-10-30 13:27:19 +13:00
Matt Woodrow 533723cd8b L4D2 gamedata updates 2009-10-30 13:27:05 +13:00
Fyren 9e69afbbd6 Inital SM fixes for l4d2 and linux makefile updates 2009-10-30 13:26:13 +13:00
Scott Ehlert 2dea76dfa1 Changed name in credits. 2009-10-29 17:35:00 -05:00
David Anderson 8a8bafb199 Use GetSourceEngineBuild() from MM:S 1.8 legacy API (bug 4083, r=ds). 2009-10-29 01:33:57 -07:00
David Anderson 5a21d8c24d Let SourceMod use OnUnlinkConCommandBase from MM:S 1.8 legacy API (bug 4080, r=ds). 2009-10-29 00:53:31 -07:00
David Anderson 5111b4799c Fix iloop race when using AddCommandListener and SourceMod unloads (bug 4077, r=pred). 2009-10-29 00:06:12 -07:00
David Anderson 528bbe0116 Build against MM:S 1.8 with core-legacy (bug 4076, r=ds). 2009-10-28 23:30:52 -07:00
David Anderson 3030ab8664 Fixed crash when activating command listeners on EP1 while inside a command callback (bug 4072, r=pred). 2009-10-28 00:50:48 -07:00
David Anderson 2698ff1a04 Added feature testing functionality (bug 4021, r=pred). 2009-10-28 00:37:34 -07:00
David Anderson 084dd1c8dd Build fix. 2009-10-28 00:31:48 -07:00
David Anderson a8392889de Fix maphistory command not returning a value (bug 4069, r=pred). 2009-10-28 00:08:15 -07:00
David Anderson 3bf5edc2b3 Added @spec target (bug 2718, r=fyren). 2009-10-27 03:41:36 -07:00
David Anderson 97be0ff22a Bumped trunk version. 2009-10-27 03:11:34 -07:00
David Anderson b43c8c018b Warn user when adminmenu_custom is going to emit duplicate entries (bug 3894, r=pred). 2009-10-27 01:43:51 -07:00
David Anderson 38a5a4b97b Increase display lengths on custom menus (bug 3677, r=pred). 2009-10-27 01:37:19 -07:00
Matt Woodrow 73d70b6953 Fixed bug in entity output hooks (bug 3988, r=fyren). 2009-10-27 00:03:59 -07:00
David Anderson 6b06733192 Added better random number generator (bug 3831, r=fyren). 2009-10-26 23:59:59 -07:00
David Anderson 359146f60b Don't pass unconnected clients into OnClientCommand (bug 3732, r=fyren). 2009-10-26 23:51:39 -07:00
Fyren 0931c6a7e1 Fix OnConfigsExecuted() executing too early on EP1 with large config files (bug 3828, r=dvander). 2009-10-26 23:44:57 -07:00
Fyren f2049c5910 Fix menu population for sm_who (bug 4030, r=pred) 2009-10-20 15:48:56 -07:00
David Anderson de76827dd8 Fixed using war mode not load_unlocking before reloading (bug 3869, r=pred). 2009-09-27 02:25:32 -04:00
David Anderson 0cae3ac5a1 Use case-insensitive game folder matches for Windows (bug 3913, r=pred). 2009-09-27 02:19:17 -04:00
David Anderson 4fc378d3e2 Target filters now run for "@me" special target (bug 4000, r=pred). 2009-09-27 02:17:23 -04:00
Scott Ehlert e3e11d233c Merge. 2009-10-06 13:37:59 -05:00
Scott Ehlert fcfd5c7419 Fixed crash when a plugin was unloaded before a client convar query had returned results (bug 4044, r=dvander). 2009-10-06 13:37:30 -05:00
Erik Minekus be8c498aea Fix help message for sm cvars (bug 3994, r=dvander). 2009-10-06 03:15:10 -07:00
TESLA-X4 5528b9ba09 HL2DM support for OnPlayerRunCmd (bug 3914, r=dvander). 2009-10-06 03:13:44 -07:00
Nicholas Hastings c60877b6f2 GoldenEye:Source supports ShowMenu (bug 3747, r=dvander). 2009-10-06 03:06:02 -07:00
Scott Ehlert 07901946d0 Fixed building of libcurl on Linux when a build clobber is done. 2009-10-06 01:52:08 -05:00
Scott Ehlert 705ea18b2a Really fixed version.rc file problem by removing and recreating build OUTPUT directory when required (bug 4042, r=dvander). 2009-10-06 01:46:06 -05:00
Scott Ehlert 3277cc3675 Fixed case where version.rc files could have incorrect version number (bug 4042, r=dvander). 2009-10-04 00:52:53 -05:00
David Anderson c09b7bed34 Updated to latest GeoLite Country database (OCT-2009). 2009-10-02 05:08:14 -07:00
Fyren 83e633534d New L4D offset for SetUserCvar (bug 4033, r=dvander). 2009-10-02 04:59:47 -07:00
David Anderson 8a2c299653 Fixed rare crash involving hudtext code and maxclient shifts (bug 4016, r=fyren). 2009-10-02 04:30:46 -07:00
David Anderson 74dc2ed1f9 Re-enabled PDB files. 2009-10-02 03:47:42 -07:00
David Anderson dc0d6a9b4a Fixed crash when reloading blocked plugins fails (bug 4038, r+a=fyren). 2009-10-02 03:33:59 -07:00
David Anderson 3f264097a7 Removed unused files. 2009-10-02 03:30:54 -07:00
Nicholas Hastings e0c7b17bd5 Updated GiveNamedItem for latest L4D update (bug 4035, r=dvander). 2009-10-02 02:35:25 -07:00
Fyren d43b027c25 Fixed crash when block-loading more than 8 plugins (bug 4034, r=dvander). 2009-10-02 02:30:01 -07:00
Eric Minekus 85963cafe7 Fixed several plugins excluding the last client from loops (bug 3984, r=dvander). 2009-10-02 02:26:11 -07:00
Fyren d4deeb4edd Puuuuuush for SDK change (bug 4032) 2009-10-01 08:48:57 -07:00
David Anderson c72bfe3685 Another forgotten-file for bug 4015. Thanks mqueues. 2009-09-26 17:19:47 -04:00
David Anderson 90137f2263 Follow-up to bug 4015: apparently hg patch doesn't commit added files. 2009-09-26 17:14:50 -04:00
David Anderson d8474cfafa Added generic command hooking mechanism, to replace Reg*Cmd which is intended for command creation (bug 4015, r=pred). 2009-09-26 17:12:23 -04:00
Matt Schubert 493a756aaa Typo; missed a quotation mark 2009-09-17 13:08:18 -04:00
Matt Schubert 95d30ba4ec Fixed the Huntsman not firing CalcIsAttackCritical (bug 3927, r=dvander) 2009-09-17 12:42:58 -04:00
Matt Woodrow dbcb3e6192 Merge 2009-09-17 19:04:15 +12:00
Matt Woodrow 4228642b53 Rockthevote 'already voted' message now displays RTV progress (bug 4011, r=Fyren) 2009-09-17 18:55:40 +12:00
Matt Woodrow acba87ae46 Added voting output (bug 1997, r=dvander) 2009-09-17 18:54:40 +12:00
David Anderson 533f17b3b0 Block plugins from registering "sm" command (bug 4013, r=pred). 2009-09-16 22:37:20 -07:00
Matt Woodrow 77de71d79d Fixed gnprintf's translation parameter reordering (bug 4010, r=dvander) 2009-09-16 13:38:04 +12:00
David Anderson caadb7fa27 Fixed invalid array access in PluginSys (bug 3933, r=pred). 2009-09-07 21:29:18 -07:00
David Anderson 1dd862f83d Build fix, bug 3818 fallout. 2009-09-07 17:15:47 -07:00
Fyren 70bb4930f6 Respect clientside mutes and add fixed client listening API (bug 3818, r=pred,dvander). 2009-09-07 17:09:28 -07:00
David Anderson 852eb5c524 Fixed BanClient() crashing if called before certain callbacks (bug 3912, r=pred). 2009-09-07 16:21:48 -07:00
Matt Woodrow 3cfc45c4e8 Fixed TR_GetEntityIndex returning -1 for world ent hits (Logical entities bcompat break) 2009-09-05 19:36:12 +12:00
David Anderson db97c2a5b1 Thanks, Python. 2009-08-30 17:27:44 -07:00
David Anderson 70993256b9 Added -lpthread to sourcemod.logic binary. 2009-08-30 17:26:03 -07:00
David Anderson a439c3be3c Added sourcemod.logic to package script. 2009-08-30 12:06:32 -07:00
David Anderson 0a060982e3 Fixed extension version reporting. 2009-08-30 01:54:45 -07:00
David Anderson 7ffcc176cd Fixed build failure in profiler. 2009-08-30 01:43:05 -07:00
David Anderson 4a9650df80 Added missing version file. 2009-08-30 01:40:39 -07:00
David Anderson f1c6f09f98 Added missing configure script. 2009-08-30 01:38:28 -07:00
David Anderson f039c0636e More build fixes. 2009-08-30 01:34:24 -07:00
David Anderson a620e1490c Build fixes. 2009-08-30 01:19:32 -07:00
David Anderson d682361cfc More changes for new build system. 2009-08-30 00:46:56 -07:00
David Anderson d3f0a14867 Imported support for new build system. 2009-08-30 00:21:42 -07:00
David Anderson 83393f299a Removed auto folders (bug 3949). 2009-08-30 00:03:58 -07:00
Matt Woodrow bf1285567e Build fix 2009-08-24 09:41:53 +12:00
DaFox e315726001 Added PointOutsideWorld native to sdktools (bug 3906, r=dvander) 2009-08-24 09:19:42 +12:00
Erik Minekus 2f3e172162 Added "motd" chat trigger to basetriggers (bug 2694, r=dvander) 2009-08-24 09:13:37 +12:00
Kornelijus Survila d6cf9bd8ae Added manual extension reloading command to root console menu (bug 3934, r=dvander) 2009-08-24 09:11:42 +12:00
Zach Kanzler 5710a35388 Added Kick, Ban and IsInKickQueue to public extension API (bug 3907, r=dvander) 2009-08-24 09:05:54 +12:00
Mr E. Unknown 1156d00538 Fixed 'list' type custom menu entries overwriting admin restrictions (bug 3783, r=pred) 2009-08-24 09:02:10 +12:00
Downtown1 5707354a18 Added sm_resetcvar command to basecommands (bug 3636, r=pred) 2009-08-24 08:55:34 +12:00
Matt Schubert 155cc4573c Fixed ForceRespawn offset for TF2 2009-08-20 03:02:43 -04:00
Matt Woodrow 3288592d30 Fixed tf2 build configs 2009-08-17 11:07:14 +12:00
Matt Woodrow 886b683739 Makefile fix 2009-08-17 10:54:57 +12:00
Matt Woodrow 95cffca5f1 Forgot makefiles patch 2009-08-17 10:53:54 +12:00
Matt Woodrow 85cb592a7e Fixed typo in the build tool 2009-08-17 10:44:35 +12:00
Matt Woodrow 13b9deb5ef Merged the build fixes (hopefully) 2009-08-17 10:42:01 +12:00
Matt Woodrow c307c692a0 Copy of new tf engine changes from 1.2 branch 2009-08-17 10:03:53 +12:00
David Anderson 008e98d980 Fixed incorrect escaping in clientprefs SQLite queries (bug 3904, r+a12=pred). 2009-08-10 22:16:58 -04:00
Fyren b11f597521 Fix SetClientViewModel (bug 3941, r=pred) 2009-08-09 15:35:49 -07:00
Matt Woodrow 944c523a49 Fixed incparser for new functag format and added a sample Crimson Editor template 2009-08-09 14:03:50 +12:00
psychonic 3c365259cc Synergy gamedata updates (bug 3315, r=dvander) 2009-07-30 17:17:48 -07:00
David Anderson 98274d4b17 Linux build of pcre-7.9 (bug 3923). 2009-07-28 12:56:16 -05:00
David Anderson 12a1cb9e97 Check-in of pcre-7.9 source code and win32 static lib (bug 3923). 2009-07-28 17:51:34 -04:00
Matt Woodrow d273750849 Mergé 2009-07-28 15:06:57 +12:00
Matt Woodrow 75c54c6738 Fixed regression with sound natives (bug 3918, r=dvander) 2009-07-28 15:05:47 +12:00
Fyren ffd72fbb4d Improve non-admin to admin chat (bug 3844, r=pred) 2009-07-27 17:02:04 -07:00
Fyren 71dc3d4826 Make Insurgency use SayText for printing to chat (bug 3738, r=dvander) 2009-07-27 16:45:30 -07:00
psychonic b7757d71bf Insurgency gamedata updates (bug 3511, r=dvander) 2009-07-27 16:17:13 -07:00
psychonic 55338e731b ZM gamedata updates (bug 3746, r=dvander) 2009-07-27 16:16:33 -07:00
psychonic 097aa3fa16 Empires gamedata updates (bug 3500, r=dvander) 2009-07-27 16:13:55 -07:00
psychonic 935d6a7cf5 ZPS gamedata updates (bug 3877, r=dvander) 2009-07-27 16:04:43 -07:00
psychonic c69d1c7fb8 AoC gamedata updates (bug 3891, r=dvander) 2009-07-27 13:30:01 -07:00
Fyren b5152c0c48 Fix sm_corecfgfile for modified sm_basepaths (bug 3856, r=dvander) 2009-07-27 13:22:55 -07:00
Matt Woodrow ed02df113f A newline again? Really? 2009-07-24 13:17:26 +12:00
Matt Woodrow 2afdcf54ab I surrender GCC! Please? 2009-07-24 13:09:06 +12:00
Matt Woodrow 764fbe7fac A merge? 2009-07-24 12:59:13 +12:00
Matt Woodrow 0c9160ec8b More build fix attempts 2009-07-24 12:54:08 +12:00
Matt Woodrow 33bed487ac Please GCC? 2009-07-24 12:43:13 +12:00
Matt Woodrow 3e36382b58 Added support for logical (non-networked) entities using entity references - See http://wiki.alliedmods.net/Entity_References_%28SourceMod%29 (bug 2459, r=dvander) 2009-07-24 12:34:31 +12:00
Matt Schubert 7ec656db09 Fix RemoveDisguise Windows signature for TF2 2009-07-09 17:51:12 -04:00
Matt Schubert cf61779b08 Backed out changeset a42b24399f60 2009-07-09 17:49:26 -04:00
Matt Schubert 71600a4f37 Fix RemoveDisguise Windows signature for TF2 (bug 3892) 2009-07-09 17:45:20 -04:00
Fyren 14320f2155 Fix PlayerRunCmd offset for TF2 2009-06-16 19:41:44 -07:00
David Anderson 1923368353 Fixed build. 2009-05-30 20:04:55 -04:00
David Anderson 752bd78de5 Fixed compiler asserting when returning a string literal (bug 3836, r=fyren). 2009-05-30 20:03:56 -04:00
David Anderson c4b17855e5 Fixed compiler erroring when tagging functions for string return (bug 3837, r=fyren). 2009-05-30 20:03:01 -04:00
David Anderson a1543f79cb Fixed compiler not handling constant chained relational operators correctly (bug 3838, r=fyren). 2009-05-30 20:02:05 -04:00
David Anderson d4798ccaa5 Fixed revote bug and inflexibilities in RedrawClientVoteMenu (bug 3834, r=fyren). 2009-05-30 19:59:55 -04:00
Fyren c2c4ed1fe5 Fix crash when unloading a plugin with live user message hooks (bug 3817, r=dvander) 2009-05-25 18:12:26 -07:00
David Anderson 614188c82b Fixed compiler using NDEBUG in debug builds (bug 3815, r=fyren). 2009-05-24 12:08:27 -04:00
David Anderson 53e98c114a Fixed Plugin_Handled acting like a Stop in usermsg hooks (bug 3685, r=fyren). 2009-05-24 12:01:18 -04:00
Fyren 73c8246204 Preliminary TF2 gamedata changes 2009-05-21 20:43:22 -07:00
Matt Woodrow 58d98f8454 Fixed crash on client disconnect 2009-05-19 15:16:25 +12:00
Fyren 7605396e84 Add L4D handling to GuessSDKVersion() (bug 3842, r=dvander) 2009-05-16 16:32:21 -07:00
"David Anderson cec339552e Moved smn_functions to logic binary.
--HG--
rename : core/smn_functions.cpp => core/logic/smn_functions.cpp
2009-05-14 11:38:50 -04:00
"David Anderson fc003db139 Updated MSVC9 files. 2009-05-14 11:28:43 -04:00
"David Anderson caf434aef2 Moved profiler and adt_trie to logic binary.
--HG--
rename : core/Profiler.cpp => core/logic/Profiler.cpp
rename : core/Profiler.h => core/logic/Profiler.h
rename : core/smn_adt_trie.cpp => core/logic/smn_adt_trie.cpp
2009-05-14 11:24:07 -04:00
David Anderson 5261873f39 Fixed Linux build. 2009-05-13 22:07:11 -04:00
David Anderson 421b58f68e Import of core modularization plan (bug 3599). 2009-05-13 21:55:50 -04:00
Fyren 850dbd62c6 Fix pred's failed l2merge merge 2009-05-13 16:24:55 -07:00
David Anderson 2af45da0a8 Merge from 1.2 branch. 2009-05-12 19:43:21 -04:00
David Anderson 685e8bac22 DOS line endings to match 1.2 branch. 2009-05-12 19:43:02 -04:00
David Anderson e2a6ae9ecc Central place to mark releases so buildbot symbols aren't scrapped by purge script (bug 3809, r=me, a12=NPOTB). 2009-05-12 19:06:57 -04:00
David Anderson eb64e66e9f Fixed crash when clientprefs saw disconnect from 64th client (bug 3821, r=pred). 2009-05-12 17:28:43 -04:00
Fyren 6a24b049cb Fixed early tv_enable causing crashes (bug 3766, r=dvander). 2009-05-12 17:27:45 -04:00
David Anderson 1112dfffb3 Merge. 2009-05-12 17:26:47 -04:00
David Anderson 3304bc2f3a Backed out changeset 97d5f4dbae0b 2009-05-12 17:26:39 -04:00
David Anderson 4d2bee192f FortressForever does not support radio menus (bug 3819, r+a12=me). 2009-05-12 12:59:11 -04:00
David Anderson 2d4fb8a463 Merge. 2009-05-12 12:37:24 -04:00
Fyren 56c5012bef Fixed early tv_enable causing crashes (bug 3766, r=dvander). 2009-05-12 12:37:12 -04:00
Fyren 47002f970d Fix bad bintools assert that will always fail in debug (r=pred) 2009-05-11 19:45:51 -07:00
Matt Woodrow f6fd395485 I dislike you GCC 2009-05-12 14:19:06 +12:00
Matt Woodrow 4f426dafef Merged, thanks Fyren 2009-05-12 13:56:00 +12:00
Matt Woodrow 7b6f2863a9 Added PlayerRunCmd hook to sdktools (bug 3289, r=dvander) 2009-05-12 13:54:06 +12:00
Fyren 834a9bc84d Some sdktools string and style changes (r=pred) 2009-05-11 18:46:19 -07:00
Matt Woodrow 7710a1fdb0 Merge from 1.2 branch 2009-05-11 11:45:08 +12:00
Matt Woodrow bd97bdd378 Fixed unhook event crash (bug 3814, r=dvander) 2009-05-11 11:32:59 +12:00
David Anderson 211c5dcfcd Fixed compiler reading uninitialized strings while processing varargs (bug 3811, r=fyren,pred, a12=blocking). 2009-05-10 11:01:19 -04:00
David Anderson 2cdf1897b9 Merge. 2009-05-09 09:24:04 -04:00
David Anderson bf8c57c669 Fixed compiler choosing whether to emit stradjust.pri on dynamic arrays based on uninitialized memory (bug 3810, r=fyren,pred, a12=blocking). 2009-05-09 09:21:14 -04:00
Fyren 7fd6b308f8 Fix Windows L4D CreateFakeClient signature (bug 3792) 2009-05-08 00:10:12 -07:00
Fyren 6908c0f1d0 Fix sdktools MSVC9 project file (and sm_slap) for EP1 games (bug 3768) 2009-05-07 20:15:32 -07:00
Fyren f74380b3e9 Fix casting problems in TextParsers breaking TrimString for non-ASCII (bug 3800, r+a12=dvander) 2009-05-03 11:23:12 -07:00
Matt Woodrow 4abdc29d9e l2merge Fyren 2009-04-24 18:20:55 +12:00
Fyren 5096aef6e7 Remove knife critical stuff and previous "fix" (bug 3791, r=pred) 2009-04-22 19:06:19 -07:00
Fyren d9f5801a68 I can in no way find fault with myself, so I blame buildbot. 2009-04-21 17:55:14 -07:00
Fyren 462e03d150 Fix medigun/CalcIsAttackCritical Windows crash (bug 3791, r=pred) 2009-04-21 02:38:35 -07:00
Fyren 6aded88e14 Fixed CommitSuicide offset for today's TF2 update 2009-04-20 21:38:12 -07:00
Fyren 74a25097b2 Fix OnClientConnect rejectmsg handling, improve doc (bug 3690, r=dvander) 2009-04-13 16:39:53 -07:00
Matt Woodrow 2c190f502f Added new playerhelpers interface 2009-04-13 10:02:55 +12:00
Matt Woodrow 0122686541 Clientprefs now loads cookies for clients on late load (bug 3735, r=dvander) 2009-04-13 09:50:46 +12:00
Fyren 187c0a9bf7 Fix GetCommandFlags for original engine games (bug 3759, r=dvander) 2009-04-07 17:24:22 -07:00
Fyren a4295d1e93 Add a warning to not edit SM's gamedata files; switched to UNIX line endings (bug 3728, r=dvander) 2009-04-07 09:59:21 -07:00
Fyren 9def5e57de Disable nextmap in Synergy and Dystopia (bug 3687, bug 3741; r=liam) 2009-04-01 05:56:51 -07:00
Fyren 3d573c08a1 Fix CommitSuicide offset (bug 3726, r=Srdog) 2009-04-01 04:35:51 -07:00
Fyren c9ff6be881 Fix CommitSuicide offset (bug 3726, r=Srdog) 2009-04-01 04:34:01 -07:00
David Anderson 40a8892cb7 Merge from sourcemod-1.2 branch. 2009-03-30 11:43:16 +02:00
David Anderson e1bb10d859 Removed SSE optimizations from msvc9 project files (bug 3756, r=ds, a12=blocking). 2009-03-30 08:31:35 +02:00
David Anderson 569f4646a0 Fixed builder not passing GCC version in some cases (bug 3750, r=ds, a12=ds). 2009-03-30 08:29:47 +02:00
David Anderson 16756e550f Handle FormatMessage failures from LoadLibrary oddities (bug 3760, r=fyren). 2009-03-29 09:01:40 -04:00
Fyren 933b77e429 Fix sm exts info help message 2009-03-25 21:01:40 -07:00
David Anderson 3ac9ecb4b7 Removed tag system (bug 3751, r=fyren, a12=blocking). 2009-03-25 03:27:32 -04:00
Fyren ccc4386285 Let vtablecheck take class names instead of just vtable symbols (also fix line endings) 2009-03-21 18:17:43 -07:00
Fyren 4364ba46e2 Switch base plugins to APL2; disable nextmap for L4D, Dystopia, Synergy (bugs 3716, 3687, 3741; r=pred) 2009-03-18 22:10:39 -07:00
Fyren d7917a6a9a Add AskPluginLoad2() to allow silent failure, deprecate AskPluginLoad() (bug 3716, r=dvander) 2009-03-18 19:20:40 -07:00
Fyren 81e30e75c4 Merge: this'll teach me to not pull first 2009-03-18 19:15:40 -07:00
Fyren 7a94343dec Fix/restore TF2_IgnitePlayer (bug 3528, r=pred) 2009-03-18 18:50:31 -07:00
Fyren 3ee6bae4ba Fix/restore TF2_IgnitePlayer (bug 3528, r=pred) 2009-03-18 18:50:20 -07:00
Fyren 9a77e6b3cc Gave OnClientAuthorized() its meds. 2009-03-18 18:34:46 -07:00
Fyren a1727cc047 vim syntax file and a perl script to generate a syntax file from the includes 2009-03-18 18:30:35 -07:00
Matt Woodrow 5b012b6509 Merge 2009-03-17 12:31:10 +13:00
Matt Woodrow c23ffa2ce5 Added GetClientCookieTime native (bug 3736, r=dvander) 2009-03-17 12:30:21 +13:00
Matt Woodrow ff68383732 Added GetClientCookieTime native (bug 3736, r=dvander) 2009-03-17 12:29:10 +13:00
Matt Woodrow bce2b2adb6 Added new playerhelpers interface 2009-03-17 12:28:37 +13:00
Matt Woodrow fa8c9a8418 Clientprefs now loads cookies for clients on late load (bug 3735, r=dvander) 2009-03-17 12:28:05 +13:00
David Anderson 2e176b8b8d Fixed auto update URL being set too late (bug 3699, r=pred). 2009-03-16 18:43:34 -04:00
Fyren f6bb6037f3 Allow spaces in compiler command line options (bug 3729, r=dvander) 2009-03-12 18:37:04 -07:00
Scott Ehlert 7fac7c8713 Pushing a build to test buildbot against mercurial 1.2. 2009-03-09 06:38:20 -05:00
David Anderson bdaef0b0dc Pushing build to test buildbot. 2009-03-09 01:21:01 -04:00
Liam 5b21fc89fc Fixed typo in code that broke buildbot. (Bug 3698 r=Liam) 2009-03-07 23:27:10 -05:00
Liam bc7b90a1b4 Removed the alive check from sm_rename. Improved mod support between various engines. (Bug 3698 r=pred) 2009-03-07 17:11:11 -05:00
Liam 134cb68396 Removed the alive check from sm_rename. Added in additional support for CSS / OB engines. 2009-03-07 16:58:14 -05:00
David Anderson c0ee2ce345 Fixed assorted updater bugs (bug 3697, r=pred, a121=blocking). 2009-03-06 17:41:35 -05:00
David Anderson a299533508 Bumping merge node so buildbot doesn't puke. 2009-03-06 14:45:03 -05:00
David Anderson d4bcbc3771 Merge from 1.2 branch. 2009-03-06 14:44:25 -05:00
Fyren 2c7555366f Fixed SetEntityHealth (bug 3693, r+a12=dvander). 2009-03-06 14:40:30 -05:00
Scott Ehlert d8264fada7 Merge from 1.2 branch. 2009-03-05 15:48:38 -06:00
Scott Ehlert 72da49415e Added -dev tag back to version.h files for manual builds. 2009-03-05 14:59:09 -06:00
David Anderson 8e744ec5f7 Re-added -dev tag, bumped version to 1.2.1. 2009-03-05 02:36:27 -05:00
David Anderson 7372b66680 Added tag sourcemod-1.2.0 for changeset 3a73bbf60f34 2009-03-05 02:35:44 -05:00
David Anderson 8dfbcf5a9f Bumped versions. 2009-03-05 02:07:44 -05:00
David Anderson 01ff2cca0c Removed -dev tag for release. 2009-03-05 02:06:59 -05:00
David Anderson e981c2b43f Updated changelog. 2009-03-05 02:05:56 -05:00
David Anderson 1f636bf7a9 Bumped trunk to 1.3.0. 2009-03-05 01:48:18 -05:00
David Anderson 68bc33ef4d Pushing build. 2009-03-05 00:01:07 -05:00
Matt Woodrow a7e447a3f5 Merge 2009-03-05 12:00:31 +13:00
Matt Woodrow 096a04b3e4 Added SourceMod to the sv_tags list and added a tags API for plugins (bug 3688, r=dvander) 2009-03-05 11:59:49 +13:00
David Anderson 86e600000d Added -lrt to webternet from suggestion in bug 3686. 2009-03-04 06:45:50 -05:00
David Anderson a0128d9b7c Fixed SetEntityHealth not compiling, darkm regression (bug 3684). 2009-03-03 09:41:55 -05:00
Matt Woodrow 65996254c6 Triggering automatic break.. uh build. 2009-03-03 11:07:50 +13:00
Fyren a85031be53 Gently disable nextmap on L4D, rather than fail load (bug 3683, r+a12=dvander). 2009-03-01 21:15:14 -05:00
Matt Woodrow 8509f0857a Build Push! 2009-03-02 14:44:33 +13:00
David Anderson b24c75b400 Moved structs.gamedata.txt out of the way.
--HG--
rename : gamedata/structs.gamedata.txt => extensions/structs/structs.gamedata.txt
2009-03-01 17:45:04 -05:00
FLOOR_MASTER d372e789a4 Performance improvements to admin-sql-prefetch (bug 3354, r+a12=dvander). 2009-03-01 16:59:12 -05:00
Fyren d9f7e4c9e0 Added more detail to certain player-oriented menu titles (bug 2740, r=liam, a12=dvander). 2009-03-01 16:51:15 -05:00
Fyren e6ea726b69 Improved docs of TIMER_HNDL_CLOSE (bug 3641, r=dvander). 2009-03-01 16:48:55 -05:00
Fyren 98c1a18e57 Improved error message for handle leakage (bug 3646, r,a12=dvander). 2009-03-01 16:43:48 -05:00
Fyren e04d2a4a10 Added case insensitivity search to ReplaceString (bug 3639, r=dvander). 2009-03-01 16:41:44 -05:00
David Anderson 96a3671bb6 Improved user message interception API (bug 3631, r=pred). 2009-03-01 16:39:25 -05:00
David Anderson 0c028ca9d0 Fixed CommitSuicide offset for Insurgency (bug 2560). 2009-03-01 16:35:01 -05:00
David Anderson 64124447d5 Fixed shutdown breakage from updater landing. 2009-03-01 03:49:59 -05:00
David Anderson 037ea592ab Fixed Linux build. 2009-03-01 01:58:42 -05:00
David Anderson 6ebbb48f9f Re-landed automating updating (bug 3530, r=pred). 2009-03-01 01:35:39 -05:00
David Anderson 2e8a53ff34 Normalized gamedata line endings to Windows. 2009-03-01 01:19:51 -05:00
David Anderson f104438802 Do binary writes instead. 2009-03-01 01:18:09 -05:00
David Anderson eb25650e26 Merge. 2009-02-28 23:15:23 -05:00
David Anderson c4cba5254c Added auto-restart functionality to the Updater extensions (bug 3530, r=pred). 2009-02-28 23:14:16 -05:00
Scott Ehlert c90dda908a Merge from 1.1 branch. 2009-02-27 00:50:12 -06:00
Scott Ehlert 6aca0a8bfc Added -dev tag back to version.h files for manual builds. 2009-02-27 00:22:59 -06:00
Matt Woodrow 864376e7ba Merging from 1.1 branch 2009-02-27 12:20:36 +13:00
Matt Woodrow 71794fe511 Updated branch for 1.1.3 development 2009-02-26 17:41:42 -05:00
Matt Woodrow c69989c56f Added tag sourcemod-1.1.2 for changeset b3ffa8a4511c 2009-02-26 17:37:57 -05:00
Scott Ehlert 2c3bf7dd23 Ran versionchanger script for consistency. 2009-02-25 23:44:18 -06:00
Scott Ehlert 5e6417eac0 Merged changes from 1.1 2009-02-25 23:17:37 -06:00
Matt Woodrow 09b24e45f9 Merge from 1.1 branch 2009-02-26 12:47:56 +13:00
Matt Woodrow fc7f9ac6e9 Fixed linux offset for SetClientInfo (bug 3652, r=Fyren) 2009-02-23 10:09:51 +13:00
Matt Woodrow 7dcc7ea99c And again with the linux fixing (bug 3657) 2009-02-23 08:58:14 +13:00
Matt Woodrow 4590015ed6 Fixed linux build 2009-02-22 14:58:05 +13:00
Matt Woodrow 79f9dc61a4 Added edict_t and CBaseHandle conversion functions to IGameHelpers (bug 2616, r=dvander) 2009-02-22 14:38:05 +13:00
Matt Woodrow 3fac7d027a Fixed SetClientInfo offset after TF2 update (bug 3652) 2009-02-21 11:29:28 +13:00
Matt Woodrow 10ba5809d2 Fixed mapchooser not checking for an existing vote with mp_fraglimit (bug 3503) 2009-02-19 20:35:41 +13:00
Matt Woodrow 792204bd06 This has to be the worst GCC error ever. 2009-02-19 19:35:45 +13:00
Matt Woodrow f19cb010a0 Upgraded clientprefs to use the client serial API (bug 3616) 2009-02-19 19:28:50 +13:00
Matt Woodrow ca3df3bd50 Added a client verification serial API (bug 3616, r=dvander) 2009-02-19 19:19:44 +13:00
Matt Woodrow db43487b5a Merging changes from 1.1 branch 2009-02-19 14:23:36 +13:00
Scott Ehlert 44a04e6167 DS fails once again. Fixed Linux build once and for all. 2009-02-18 03:25:01 -06:00
Scott Ehlert 9d6a9eb615 Ugh, fixed Linux build for real by removing stray underscores. 2009-02-18 03:13:25 -06:00
Scott Ehlert 27070af1b9 Added Dark Messiah build config to sample_ext. 2009-02-18 03:08:02 -06:00
Scott Ehlert 32d2d4107d Fixed Linux build. 2009-02-18 02:58:03 -06:00
Scott Ehlert 75ebac822d Merge. 2009-02-18 02:30:21 -06:00
Scott Ehlert bd9fab6cf5 Added support for Dark Messiah engine and game. (no bug, r=me).
The development of this feature would not be possible without the support of the following people from the game's community:
Dylan Riggs, Carl Pettengill, Ed Moreland, and Christian.
2009-02-18 02:19:22 -06:00
Matt Woodrow d75f8f11e1 Oops - FormatPath missing a param (bug 3645) 2009-02-18 19:59:14 +13:00
Matt Woodrow 47900db414 Merging changes from 1.1 branch 2009-02-18 19:14:27 +13:00
Matt Woodrow b61542242c Build Fix! 2009-02-18 15:30:43 +13:00
Matt Woodrow 13c1fd09c4 Added custom gamedata file parsing (bug 3644, r=dvander) 2009-02-18 15:08:17 +13:00
Matt Woodrow fddb69e49e Fixed MsgSentNotify callbacks not firing on intercept hook (bug3631, r=dvander) 2009-02-18 15:03:17 +13:00
David Anderson ed51d5cf84 Disallow ".." to appear in paths from the updater. 2009-02-17 16:58:17 -05:00
David Anderson 3d7b0db114 Updater uses a core.cfg specified URL now. 2009-02-17 16:39:02 -05:00
David Anderson 9e445a5adf Added API to grab arbitrary kv pairs from core.cfg. 2009-02-17 16:19:11 -05:00
David Anderson 97e25c37de Deprecated Acquire/ReleaseLock from IGameConfigManager, use thread pump in updater. 2009-02-17 15:59:51 -05:00
David Anderson 16033c1307 Deprecated sm_corecfgfile for sm_basepath (bug 2693, r=ds). 2009-02-17 14:03:20 -05:00
David Anderson 15d64b8486 Fixed documentation typos in dbi.inc (bug 3587). 2009-02-08 15:40:48 -05:00
David Anderson 5d06aa3c8c Pushing build because buildbot is delicate and needs its hand held to cross the street and put on underwear. 2009-02-08 01:06:31 -05:00
David Anderson e276223b61 Merge from sourcemod-1.1. 2009-02-08 00:02:58 -05:00
David Anderson 6530f47b2d Renamed translation file with deprecated naming scheme.
--HG--
rename : translations/plugin.playercommands.txt => translations/playercommands.phrases.txt
2009-02-07 22:32:55 -05:00
David Anderson ffd8ff099a Initial import of updater extension, currently incomplete - just getting it in the tree (bug 3530). 2009-02-02 15:41:25 -05:00
David Anderson e194f89b25 Removed UTIL_Format from webternet extension. 2009-02-01 20:38:59 -05:00
David Anderson 3bfc70aa3b Normalized line endings. 2009-02-01 20:37:50 -05:00
David Anderson 93a6a0f211 Merge. 2009-02-01 20:31:48 -05:00
David Anderson cef6a2e389 Added an SMC stream reader to ITextParser (bug 3530, r=pred). 2009-02-01 20:31:27 -05:00
mr.e.unk 4f5764e4a5 Removed RTV section from maplists.cfg. (bug 3611 r=Liam) 2009-02-01 20:22:50 -05:00
David Anderson 21770ff10f Corrected IWebternet version number. 2009-02-01 19:58:16 -05:00
David Anderson 2b97461f54 Added snprintf/vsnprintf helpers to ISourceMod, finally (bug 3530, r=pred). 2009-02-01 19:57:09 -05:00
David Anderson 0cf5f4ae2a Added form POSTing and HTTP error code handling to Webternet (bug 3530, r=pred). 2009-02-01 19:56:24 -05:00
David Anderson 7b6dcfce87 Removed md5 files from core, as they are unused. 2009-02-01 17:50:44 -05:00
David Anderson f9d472847c Merge from sourcemod-1.1. 2009-02-01 02:37:00 -05:00
David Anderson d69d97402b Fixed nits from bug 3570. 2009-02-01 02:35:19 -05:00
David Anderson 643c39690f Added client "sm", "sm credits", and "sm plugins" commands (bug 3570, r=ds,pred). 2009-02-01 02:33:31 -05:00
David Anderson 6048144310 RegConsoleCmd is now case insensitive for client-only commands (bug 3602, r=ds). 2009-02-01 02:13:17 -05:00
David Anderson a017e4820a Added the ability for extensions to invoke arbitrary natives (bug 3605, r=ds,theY4Kman). 2009-02-01 02:03:03 -05:00
David Anderson c5ec369388 Fixed STEAM_0 reference in common.phrases.txt (bug 3577). 2009-01-31 22:51:48 -05:00
Liam 52826342fc Removed sounds translations from funcommands.phrases.txt, created and added sounds.phrases.txt, modified sounds.sp to include translation files (bug 3603, r=dvander) 2009-01-31 22:39:36 -05:00
Liam 29b357a2f6 Insurgency game_start / game_newmap event fix (bug 3497, +dvander) 2009-01-31 22:21:37 -05:00
David Anderson 747ed1e59a Fixed bugs in the Knight shared files (not that these are used in SM). 2009-01-29 12:50:32 -05:00
Scott Ehlert 992c05b6aa Wow, buildbot, just wow. You built 1.1 instead of 1.2 again. 2009-01-28 02:14:41 -06:00
Scott Ehlert f4a5457941 Merged changes from sourcemod-1.1 branch. 2009-01-28 00:00:19 -06:00
Scott Ehlert 22675ba2e7 Fixed crash in GetClientInfo() native on L4D (bug 3569, r=me).
The CreateFakeClient signature (used for verification before retrieving the IServer interface pointer) changed in a recent update. The IServer pointer was therefore null and GetClientInfo() did not check for this.

The CreateFakeClient signature is also no longer hardcoded. It is modifiable in gamedata/sdktools.games/engine.*.txt.
2009-01-22 15:20:45 -06:00
Matt Woodrow 80602b011d Build fixed hopefully. 2009-01-17 13:45:51 +13:00
Matt Woodrow abea8e2195 Fixed bintools compile options 2009-01-17 13:17:55 +13:00
Liam 9075aecb18 Updated basebans.sp to support L4D and allow future expansion of the STEAM_ identifier. (bug 3567 r=dvander) 2009-01-15 12:08:33 -05:00
Liam 6e9ac875d7 Fixed the bug in sounds.sp. (Bug 3568 r=dvander) 2009-01-15 10:37:54 -05:00
Fyren 100ecb12e9 Fixed admin-sql-threaded not working on L4D (bug 3559, r=dvander). 2009-01-14 17:00:24 -05:00
David Anderson 57b4701e57 Fixed gamedata bug in SDKTools (no bug, r=me). 2009-01-14 12:20:22 -05:00
David Anderson fffc211989 Whoops, updated build tool to correctly copy new gamedata files. 2009-01-14 00:55:28 -05:00
jonasfietz 5a0528de26 Improve compile.sh to accept filenames (bug 3550, r=dvander). 2009-01-13 16:14:44 -05:00
Rothgar fb8f46ea45 Updated SDKTools definitions for Zombie Panic Source (bug 2467, r=dvander). 2009-01-13 15:58:29 -05:00
TheDOO 3653f56331 Update of Obsidian CommitSuicide offset (bug 2699, r=dvander). 2009-01-12 02:33:03 -05:00
David Anderson e31cbbfe21 New gamedata organization (bug 3546, r=ds,pred). 2009-01-12 02:28:22 -05:00
David Anderson bc3491c5bd Another build fix for Windows. 2009-01-12 01:32:53 -05:00
David Anderson 9a7c25047d Fixed windows build. 2009-01-12 01:15:29 -05:00
David Anderson 7cef8b7363 Attempt at getting webternet extension into build process. 2009-01-12 00:36:36 -05:00
David Anderson e449b8384c Webternet extension now exposes API and acts like other SM extensions. 2009-01-11 23:56:34 -05:00
David Anderson 9514c12982 Initial import of untested curl extension (bug 3560, r=pred,ds). 2009-01-11 23:48:17 -05:00
David Anderson 489d6c5a65 Imported libcurl source code. 2009-01-08 18:31:00 -05:00
David Anderson ccc59ecdaf Pre-emptive removal of gamedata updater pending rewrite. 2009-01-08 16:11:59 -05:00
David Anderson d2ce50f989 Merge from sourcemod-1.1 branch. 2009-01-08 13:39:16 -05:00
David Anderson 14e409adb4 Fixed another build issue. 2009-01-08 02:38:31 -05:00
David Anderson 4a0f639e89 Fixed build, removed stale build entries. 2009-01-08 02:19:17 -05:00
David Anderson 32c5925652 Whitespace patrol - fixed soft tabs leaking into build tool. 2009-01-08 01:54:55 -05:00
Matt Woodrow 4c91dd8621 Fixed build 2009-01-08 00:44:48 -05:00
Matt Woodrow f641aa92f5 Added Dynamic Hooking to BinTools (bug 2616 r=dvander,DS) 2009-01-08 18:17:17 +13:00
David Anderson 3bdc8583e5 Exposed IServer through SDKTools (bug 3545, r=ds). 2009-01-07 22:55:40 -05:00
David Anderson 4e37900d93 Updated build to have the sounds plugin (follow-up from bug 3498). 2009-01-07 19:28:42 -05:00
Liam db760dc29b Rewrote timer system in funcommands. Cleaned up the code. Moved sounds to a seperate plugin. Misc code optimizations. (bug 3498 r=dvander) 2009-01-07 19:21:54 -05:00
Liam f96ca17f17 Updated the game check with GetGameFolderName instead of GetGameDesc. (Bug 3473 r=dvander) 2008-12-31 23:05:36 -05:00
Liam 50580498c4 Fixed nexmap issue (Bug 2150 r=Liam) 2008-12-30 19:17:13 -05:00
Liam a21e688c96 Modified the ProcessRename function to use SetClientInfo instead of ClientCommand (Bug 2150 r=DS) 2008-12-29 23:38:28 -05:00
Scott Ehlert 4b1deee7e1 El merge. 2008-12-29 00:12:37 -06:00
Scott Ehlert bf5fefe84f Merge from sourcemod-1.1 branch. 2008-12-29 00:11:32 -06:00
Liam 004d450844 Removed the if (ident==NULL) from BindAdminCache 2008-12-29 00:31:16 -05:00
Liam 7705e88b57 Prevented blank/empty admins from being created. (Bug 3431 r=dvander) 2008-12-28 23:45:18 -05:00
David Anderson 1577fab93a Ran versionchanger.pl over trunk to get 1.2.0 into headers (bug 3521). 2008-12-28 19:59:40 -05:00
David Anderson 181fe74b09 Merge from sourcemod-1.1 branch. 2008-12-28 19:56:40 -05:00
Liam cdd78b2ec3 Added rename command to PlayerCommands. Merged rename.phrases.txt and slapslay.phrases.txt into plugin.playercommands.txt. (Bug 2150 r=dvander) 2008-12-28 18:28:57 -05:00
Liam ddc42bedf5 Modified Command_Kick to display the reason (if given) on the kick message.
Modified the translation file to use the new reason style.
2008-12-28 16:48:59 -05:00
David Anderson a7a08a7d4e Clean slate for languages.cfg (no bug). 2008-12-28 16:09:15 -05:00
David Anderson 0a33a25a7d Merge from sourcemod-1.1 branch. 2008-12-28 03:23:45 -05:00
Liam 2c9622ea52 Forced nextmap to not load on L4D (bug 3473 r=Liam) 2008-12-28 03:15:15 -05:00
David Anderson 5564c38a2f Pushing build to test buildbot. 2008-12-16 21:04:03 -06:00
David Anderson 2a853a23d7 Pushing build to test buildbot. 2008-12-16 20:46:11 -06:00
David Anderson 37da98c9bb Pushing build to test buildbot. 2008-12-16 20:43:16 -06:00
Matt Woodrow 5a5172be57 Merge 2008-12-15 00:48:54 -05:00
Matt Woodrow 88afac51f0 Merge 2008-12-12 23:24:13 -05:00
Scott Ehlert dd338d40f3 Triggering build. 2008-12-08 03:28:08 -06:00
Scott Ehlert 1cc8440900 Triggering build. 2008-12-08 00:46:54 -06:00
Scott Ehlert 47cf8f4233 Merge from 1.1 branch. 2008-12-07 21:07:14 -06:00
Scott Ehlert 4e88626d65 Merge, agh. 2008-12-07 20:54:23 -06:00
Scott Ehlert a1b91ac136 Merge from 1.1 branch. 2008-12-07 20:52:06 -06:00
Scott Ehlert 0a0fd0c64a Triggering yet another build. 2008-12-07 01:26:03 -05:00
Scott Ehlert a7c6fc12d8 Triggering a build on an off chance. 2008-12-06 23:53:55 -06:00
Scott Ehlert 48f0a49f9b Triggering a build perhaps. 2008-12-06 23:26:18 -06:00
Scott Ehlert b63d714a06 Triggering a build maybe. 2008-12-06 22:17:51 -06:00
Scott Ehlert 7bdcea5814 Merged changes from 1.1 branch. 2008-12-05 15:57:49 -06:00
Scott Ehlert f418f38589 Added L4D build config to sample extension's project files. 2008-12-05 15:56:36 -06:00
Scott Ehlert 52377b509b Triggering another build to fix bug 3478 for real. 2008-12-03 10:41:00 -06:00
Scott Ehlert 14152bb7ba Triggering build to fix bug 3478.
The structure of typedescription_t in our L4D SDK was wrong and it has been updated.
Not only does this fix sm_dump_datamaps in SDKTools, but it also fixes issues with the datamap-related natives in Core where there was a datamap within a datamap.
2008-12-03 10:34:32 -06:00
Scott Ehlert d51aaec97d Fixed a memory leak that occurred when a ConCmdIter handle was closed. (L4D engine)
Note: These handles are used by the FindFirstConCommand and FindNextConCommand natives.
2008-12-02 10:57:42 -06:00
Matt Schubert ea3fe754f4 Fixed missing slap sounds in L4D (bug 3453, r=dvander) 2008-11-30 12:53:18 -05:00
David Anderson f20603ad06 Triggered build, something funky happened.... 2008-11-29 16:58:59 -06:00
David Anderson bac975331d Merge from sourcemod-1.1. 2008-11-29 16:28:50 -06:00
Matt Schubert 4baf847062 Fixed hsay/tsay not checking for in-game players 2008-11-29 13:16:33 -05:00
Scott Ehlert 90a44ea6c8 Pushed build. 2008-11-28 23:49:37 -06:00
Scott Ehlert fef83838f9 Merged another change from 1.1 branch. 2008-11-28 23:34:18 -06:00
Scott Ehlert 1422a9abe3 Merged changes from 1.1 branch. 2008-11-28 23:32:59 -06:00
Matt Woodrow 984a2d26f4 Merge! 2008-11-25 19:14:02 +13:00
Matt Woodrow f85bb7e490 SourceMod now handles steamid's internally without the STEAM_*: part (bug 3428) 2008-11-25 19:13:08 +13:00
Scott Ehlert 843ff25de4 Moved SE_* constants from PrePreprocessorDefinitions to AdditionalOptions in MSVC project files.
-Doing this should make it a bit easier to maintain in the future.

Also added back /MP to core and sdktools.
2008-11-24 09:33:11 -06:00
Scott Ehlert 7a38e5584c OriginalFilename field in core/version.rc now has correct filename based on engine. 2008-11-24 08:37:06 -06:00
Scott Ehlert 9c1e45d97c Fixed crash when L4D server went into hibernation mode after having had an active bot and a reserved name was used by this bot
- When going into hibernation, ClientSettingsChanged is called for remaining bots
- Hook checks bot's name against reserved names in admins config and tries to kick using IClient::Disconnect
- Method of getting IClient relies on client having an INetChannel pointer
- Bots do not have an INetChannel pointer so this results in a crash
2008-11-21 14:09:50 -06:00
Scott Ehlert c2756c731f Try 2 of eliminating VPK warning.
Previous commit was more complicated then it really needed to be.
2008-11-19 02:38:28 -06:00
Scott Ehlert d6fc82f8fa Merge. 2008-11-19 02:16:45 -06:00
Scott Ehlert 2acf1b08d5 'Relatized' the path passed to FileToKeyValues() native.
This eliminates the annoying warning in L4D:
***VPK: FindFile Attempting to use full path with VPK file!
2008-11-19 02:14:43 -06:00
David Anderson 6ffd39ac77 Merge changes from 1.1 branch.
--HG--
rename : core/systems/ExtensionSys.cpp => core/ExtensionSys.cpp
rename : core/systems/PluginSys.h => core/PluginSys.h
2008-11-18 06:08:48 -08:00
Scott Ehlert 9ae456b9d1 Updated makefiles to link against binaries at l4d directory instead of l4d_demo 2008-11-18 06:00:31 -06:00
Scott Ehlert 5bbeddc134 Oops, removed something I shouldn't have 2008-11-17 22:13:32 -06:00
Scott Ehlert 373fbb6ca3 Removed debugging code from ConVarManager 2008-11-17 22:11:06 -06:00
Scott Ehlert 43f5d71724 Fixed IndexOfEdict and PEntityOfEntIndex inlines to be in line with updated edict_t structure in SDK 2008-11-14 23:08:24 -06:00
Scott Ehlert 41b61ed36f Fixed tab inconsistency in some build tool source files. 2008-11-14 16:55:09 -06:00
Scott Ehlert 31e30faace Triggering build 2008-11-14 09:58:40 -06:00
Scott Ehlert ff7a2c6b73 Added preliminary support for Left 4 Dead; some things may not yet work. 2008-11-14 09:18:30 -06:00
Scott Ehlert 7e3f9ada31 Moved IDA scripts from editor/ida to tools/ida_scripts
--HG--
rename : editor/ida/gcc_fpic.idc => tools/ida_scripts/gcc_fpic.idc
rename : editor/ida/linux_vtable_dump.idc => tools/ida_scripts/linux_vtable_dump.idc
2008-11-14 03:38:59 -06:00
David Anderson 0a956115eb Bumped version on trunk. 2008-11-12 22:47:24 -08:00
2090 changed files with 566764 additions and 16843 deletions
+11
View File
@@ -1,11 +1,15 @@
# Binaries
\.dll$
\.dylib$
\.exe$
\.so$
# Files generated by Visual Studio
\.aps$
\.ipch$
\.ncb$
\.opensdf$
\.sdf$
\.suo$
\.user$
@@ -13,3 +17,10 @@
/CrazyDebug.*
/Debug.*
/Release.*
# Files generated by Mac OS X Finder
(^|/)\.DS_Store$
# Files generated by Windows Explorer
(^|/)[dD]esktop\.ini$
(^|/)[tT]humbs\.db$
+4
View File
@@ -1,3 +1,7 @@
54539fa4e51f98d7841c853c1370dff6ccd3cdf2 sourcemod-1.0.0
e6ef5ecdf8d75740ca2685a709bf321f8873bc3b sourcemod-1.1.0
e877885fac80be71822641f7a9122cebc9812521 sourcemod-1.1.1
b3ffa8a4511c4eadaf533fc790aa6b14f7f0c6ea sourcemod-1.1.2
3a73bbf60f34befa9b66be03fa5974b394bb3411 sourcemod-1.2.0
ddd707c3454c382db5db9d28148cd19227f44759 sourcemod-1.4.0
f74e1dea2ef2c5a12b5238badc0e877106804191 sourcemod-1.4.1
+400
View File
@@ -0,0 +1,400 @@
# vim: set ts=2 sw=2 tw=99 noet ft=python:
import os
import sys
from ambuild.command import SymlinkCommand
class SM:
def __init__(self):
self.compiler = Cpp.Compiler()
#Build SDK info
self.possibleSdks = { }
self.possibleSdks['ep1'] = {'sdk': 'HL2SDK', 'ext': '1.ep1', 'def': '1',
'name': 'EPISODEONE', 'platform': ['windows', 'linux']}
self.possibleSdks['ep2'] = {'sdk': 'HL2SDKOB', 'ext': '2.ep2', 'def': '3',
'name': 'ORANGEBOX', 'platform': ['windows', 'linux']}
self.possibleSdks['ep2v'] = {'sdk': 'HL2SDKOBVALVE', 'ext': '2.ep2v', 'def': '6',
'name': 'ORANGEBOXVALVE', 'platform': ['windows', 'linux', 'darwin']}
self.possibleSdks['l4d'] = {'sdk': 'HL2SDKL4D', 'ext': '2.l4d', 'def': '7',
'name': 'LEFT4DEAD', 'platform': ['windows', 'linux', 'darwin']}
self.possibleSdks['l4d2'] = {'sdk': 'HL2SDKL4D2', 'ext': '2.l4d2', 'def': '8',
'name': 'LEFT4DEAD2', 'platform': ['windows', 'linux', 'darwin']}
self.possibleSdks['darkm'] = {'sdk': 'HL2SDK-DARKM', 'ext': '2.darkm', 'def': '2',
'name': 'DARKMESSIAH', 'platform': ['windows']}
self.possibleSdks['swarm'] = {'sdk': 'HL2SDK-SWARM', 'ext': '2.swarm', 'def': '9',
'name': 'ALIENSWARM', 'platform': ['windows']}
self.possibleSdks['bgt'] = {'sdk': 'HL2SDK-BGT', 'ext': '2.bgt', 'def': '4',
'name': 'BLOODYGOODTIME', 'platform': ['windows']}
self.possibleSdks['eye'] = {'sdk': 'HL2SDK-EYE', 'ext': '2.eye', 'def': '5',
'name': 'EYE', 'platform': ['windows']}
self.sdkInfo = { }
if AMBuild.mode == 'config':
#Detect compilers
self.compiler.DetectAll(AMBuild)
#Detect variables
envvars = { 'MMSOURCE18': 'mmsource-1.8',
'HL2SDKOBVALVE': 'hl2sdk-ob-valve',
'HL2SDKL4D': 'hl2sdk-l4d',
'HL2SDKL4D2': 'hl2sdk-l4d2',
'MYSQL5': 'mysql-5.0'
}
if AMBuild.target['platform'] != 'darwin':
envvars['HL2SDK'] = 'hl2sdk'
envvars['HL2SDKOB'] = 'hl2sdk-ob'
#Dark Messiah is Windows-only
if AMBuild.target['platform'] == 'windows':
envvars['HL2SDK-DARKM'] = 'hl2sdk-darkm'
envvars['HL2SDK-SWARM'] = 'hl2sdk-swarm'
envvars['HL2SDK-BGT'] = 'hl2sdk-bgt'
envvars['HL2SDK-EYE'] = 'hl2sdk-eye'
# Finds if a dict with `key` set to `value` is present on the dict of dicts `dictionary`
def findDictByKey(dictionary, key, value):
for index in dictionary:
elem = dictionary[index]
if elem[key] == value:
return (elem, index)
return None
for i in envvars:
if i in os.environ:
path = os.environ[i]
if not os.path.isdir(path):
raise Exception('Path for {0} was not found: {1}'.format(i, path))
elif i.startswith('HL2SDK'):
(info, sdk) = findDictByKey(self.possibleSdks, 'sdk', i)
self.sdkInfo[sdk] = info
else:
head = os.getcwd()
oldhead = None
while head != None and head != oldhead:
path = os.path.join(head, envvars[i])
if os.path.isdir(path):
break
oldhead = head
head, tail = os.path.split(head)
if i.startswith('HL2SDK'):
if head != None and head != oldhead:
(info, sdk) = findDictByKey(self.possibleSdks, 'sdk', i)
self.sdkInfo[sdk] = info
elif head == None or head == oldhead:
raise Exception('Could not find a valid path for {0}'.format(i))
AMBuild.cache.CacheVariable(i, path)
if len(self.sdkInfo) < 1:
raise Exception('At least one SDK must be available.')
AMBuild.cache.CacheVariable('sdkInfo', self.sdkInfo)
#Set up defines
cxx = self.compiler.cxx
if isinstance(cxx, Cpp.CompatGCC):
if isinstance(cxx, Cpp.GCC):
self.vendor = 'gcc'
elif isinstance(cxx, Cpp.Clang):
self.vendor = 'clang'
self.compiler.AddToListVar('CDEFINES', 'stricmp=strcasecmp')
self.compiler.AddToListVar('CDEFINES', '_stricmp=strcasecmp')
self.compiler.AddToListVar('CDEFINES', '_snprintf=snprintf')
self.compiler.AddToListVar('CDEFINES', '_vsnprintf=vsnprintf')
self.compiler.AddToListVar('CFLAGS', '-pipe')
self.compiler.AddToListVar('CFLAGS', '-fno-strict-aliasing')
if (self.vendor == 'gcc' and cxx.majorVersion >= 4) or self.vendor == 'clang':
self.compiler.AddToListVar('CFLAGS', '-fvisibility=hidden')
self.compiler.AddToListVar('CXXFLAGS', '-fvisibility-inlines-hidden')
self.compiler.AddToListVar('CFLAGS', '-Wall')
self.compiler.AddToListVar('CFLAGS', '-Werror')
self.compiler.AddToListVar('CFLAGS', '-Wno-uninitialized')
self.compiler.AddToListVar('CFLAGS', '-Wno-unused')
self.compiler.AddToListVar('CFLAGS', '-Wno-switch')
self.compiler.AddToListVar('CFLAGS', '-msse')
self.compiler.AddToListVar('CFLAGS', '-m32')
self.compiler.AddToListVar('POSTLINKFLAGS', '-m32')
self.compiler.AddToListVar('CXXFLAGS', '-fno-exceptions')
self.compiler.AddToListVar('CXXFLAGS', '-fno-rtti')
self.compiler.AddToListVar('CXXFLAGS', '-fno-threadsafe-statics')
self.compiler.AddToListVar('CXXFLAGS', '-Wno-non-virtual-dtor')
self.compiler.AddToListVar('CXXFLAGS', '-Wno-overloaded-virtual')
if (self.vendor == 'gcc' and cxx.majorVersion >= 4 and cxx.minorVersion >= 3) or \
(self.vendor == 'clang' and cxx.majorVersion >= 3):
self.compiler.AddToListVar('CXXFLAGS', '-Wno-delete-non-virtual-dtor')
self.compiler.AddToListVar('CDEFINES', 'HAVE_STDINT_H')
self.compiler.AddToListVar('CDEFINES', 'GNUC')
if self.vendor == 'gcc':
self.compiler.AddToListVar('CFLAGS', '-mfpmath=sse')
elif isinstance(cxx, Cpp.MSVC):
self.vendor = 'msvc'
if AMBuild.options.debug == '1':
self.compiler.AddToListVar('CFLAGS', '/MTd')
self.compiler.AddToListVar('POSTLINKFLAGS', '/NODEFAULTLIB:libcmt')
else:
self.compiler.AddToListVar('CFLAGS', '/MT')
self.compiler.AddToListVar('CDEFINES', '_CRT_SECURE_NO_DEPRECATE')
self.compiler.AddToListVar('CDEFINES', '_CRT_SECURE_NO_WARNINGS')
self.compiler.AddToListVar('CDEFINES', '_CRT_NONSTDC_NO_DEPRECATE')
self.compiler.AddToListVar('CXXFLAGS', '/EHsc')
self.compiler.AddToListVar('CXXFLAGS', '/GR-')
self.compiler.AddToListVar('CFLAGS', '/W3')
self.compiler.AddToListVar('CFLAGS', '/nologo')
self.compiler.AddToListVar('CFLAGS', '/Zi')
self.compiler.AddToListVar('CXXFLAGS', '/TP')
self.compiler.AddToListVar('POSTLINKFLAGS', '/DEBUG')
self.compiler.AddToListVar('POSTLINKFLAGS', '/MACHINE:X86')
self.compiler.AddToListVar('POSTLINKFLAGS', '/SUBSYSTEM:WINDOWS')
self.compiler.AddToListVar('POSTLINKFLAGS', 'kernel32.lib')
self.compiler.AddToListVar('POSTLINKFLAGS', 'user32.lib')
self.compiler.AddToListVar('POSTLINKFLAGS', 'gdi32.lib')
self.compiler.AddToListVar('POSTLINKFLAGS', 'winspool.lib')
self.compiler.AddToListVar('POSTLINKFLAGS', 'comdlg32.lib')
self.compiler.AddToListVar('POSTLINKFLAGS', 'advapi32.lib')
self.compiler.AddToListVar('POSTLINKFLAGS', 'shell32.lib')
self.compiler.AddToListVar('POSTLINKFLAGS', 'ole32.lib')
self.compiler.AddToListVar('POSTLINKFLAGS', 'oleaut32.lib')
self.compiler.AddToListVar('POSTLINKFLAGS', 'uuid.lib')
self.compiler.AddToListVar('POSTLINKFLAGS', 'odbc32.lib')
self.compiler.AddToListVar('POSTLINKFLAGS', 'odbccp32.lib')
#Optimization
if AMBuild.options.opt == '1':
self.compiler.AddToListVar('CDEFINES', 'NDEBUG')
if self.vendor == 'gcc' or self.vendor == 'clang':
self.compiler.AddToListVar('CFLAGS', '-O3')
elif self.vendor == 'msvc':
self.compiler.AddToListVar('CFLAGS', '/Ox')
self.compiler.AddToListVar('POSTLINKFLAGS', '/OPT:ICF')
self.compiler.AddToListVar('POSTLINKFLAGS', '/OPT:REF')
#Debugging
if AMBuild.options.debug == '1':
self.compiler.AddToListVar('CDEFINES', 'DEBUG')
self.compiler.AddToListVar('CDEFINES', '_DEBUG')
if self.vendor == 'gcc' or self.vendor == 'clang':
self.compiler.AddToListVar('CFLAGS', '-g3')
elif self.vendor == 'msvc':
self.compiler.AddToListVar('CFLAGS', '/Od')
self.compiler.AddToListVar('CFLAGS', '/RTC1')
#Platform-specifics
if AMBuild.target['platform'] == 'linux':
self.compiler.AddToListVar('CDEFINES', '_LINUX')
if self.vendor == 'gcc':
self.compiler.AddToListVar('POSTLINKFLAGS', '-static-libgcc')
if self.vendor == 'clang':
self.compiler.AddToListVar('POSTLINKFLAGS', '-lgcc_eh')
elif AMBuild.target['platform'] == 'darwin':
self.compiler.AddToListVar('POSTLINKFLAGS', '-mmacosx-version-min=10.5')
self.compiler.AddToListVar('POSTLINKFLAGS', ['-arch', 'i386'])
self.compiler.AddToListVar('POSTLINKFLAGS', '-lstdc++')
# For OS X dylib versioning
import re
productFile = open(os.path.join(AMBuild.sourceFolder, 'product.version'), 'r')
productContents = productFile.read()
productFile.close()
m = re.match('(\d+)\.(\d+)\.(\d+).*', productContents)
if m == None:
self.version = '1.0.0'
else:
major, minor, release = m.groups()
self.version = '{0}.{1}.{2}'.format(major, minor, release)
AMBuild.cache.CacheVariable('version', self.version)
elif AMBuild.target['platform'] == 'windows':
self.compiler.AddToListVar('CDEFINES', 'WIN32')
self.compiler.AddToListVar('CDEFINES', '_WINDOWS')
#Finish up
self.compiler.AddToListVar('CDEFINES', 'SOURCEMOD_BUILD')
self.compiler.AddToListVar('CDEFINES', 'SM_GENERATED_BUILD')
self.compiler.AddToListVar('CINCLUDES',
os.path.join(AMBuild.outputFolder, 'includes'))
self.compiler.ToConfig(AMBuild, 'compiler')
AMBuild.cache.CacheVariable('vendor', self.vendor)
self.targetMap = { }
AMBuild.cache.CacheVariable('targetMap', self.targetMap)
else:
self.sdkInfo = AMBuild.cache['sdkInfo']
self.compiler.FromConfig(AMBuild, 'compiler')
self.targetMap = AMBuild.cache['targetMap']
if AMBuild.target['platform'] == 'windows':
self.compiler.AddToListVar('RCINCLUDES', os.path.join(AMBuild.sourceFolder, 'public'))
self.compiler.AddToListVar('RCINCLUDES',
os.path.join(AMBuild.outputFolder, 'includes'))
self.mmsPath = AMBuild.cache['MMSOURCE18']
def DefaultCompiler(self):
return self.compiler.Clone()
def JobMatters(self, jobname):
file = sys._getframe().f_code.co_filename
if AMBuild.mode == 'config':
self.targetMap[jobname] = file
return True
if len(AMBuild.args) == 0:
return True
if not jobname in AMBuild.args:
return False
def DefaultExtCompiler(self, path):
compiler = self.DefaultCompiler()
compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, path))
compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, path, 'sdk'))
compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, 'public'))
compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, 'public', 'extensions'))
compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, 'public', 'sourcepawn'))
return compiler
def AutoVersion(self, folder, binary):
if AMBuild.target['platform'] == 'windows':
env = {'RCDEFINES': ['BINARY_NAME="' + binary.binaryFile + '"', 'SM_GENERATED_BUILD']}
binary.AddResourceFile(os.path.join(folder, 'version.rc' ), env)
elif AMBuild.target['platform'] == 'darwin' and isinstance(binary, Cpp.LibraryBuilder):
binary.compiler['POSTLINKFLAGS'].extend(['-compatibility_version', '1.0.0'])
binary.compiler['POSTLINKFLAGS'].extend(['-current_version', AMBuild.cache['version']])
else:
return
def PreSetupHL2Job(self, job, builder, sdk):
info = self.sdkInfo[sdk]
sdkPath = AMBuild.cache[info['sdk']]
if AMBuild.target['platform'] == 'linux':
if sdk == 'ep1':
staticLibs = os.path.join(sdkPath, 'linux_sdk')
else:
staticLibs = os.path.join(sdkPath, 'lib', 'linux')
workFolder = os.path.join(AMBuild.outputFolder, job.workFolder)
if sdk in ['ep2v', 'l4d', 'l4d2']:
for i in ['tier1_i486.a', 'mathlib_i486.a', 'libvstdlib.so', 'libtier0.so']:
link = os.path.join(workFolder, i)
target = os.path.join(staticLibs, i)
try:
os.lstat(link)
except:
job.AddCommand(SymlinkCommand(link, target))
else:
for i in ['tier1_i486.a', 'mathlib_i486.a', 'vstdlib_i486.so', 'tier0_i486.so']:
link = os.path.join(workFolder, i)
target = os.path.join(staticLibs, i)
try:
os.lstat(link)
except:
job.AddCommand(SymlinkCommand(link, target))
elif AMBuild.target['platform'] == 'darwin':
staticLibs = os.path.join(sdkPath, 'lib', 'mac')
workFolder = os.path.join(AMBuild.outputFolder, job.workFolder)
for i in ['tier1_i486.a', 'mathlib_i486.a', 'libvstdlib.dylib', 'libtier0.dylib']:
link = os.path.join(workFolder, i)
target = os.path.join(staticLibs, i)
try:
os.lstat(link)
except:
job.AddCommand(SymlinkCommand(link, target))
elif AMBuild.target['platform'] == 'windows':
libs = ['tier0', 'tier1', 'vstdlib', 'mathlib']
if sdk == 'swarm':
libs.append('interfaces')
for lib in libs:
libPath = os.path.join(sdkPath, 'lib', 'public', lib) + '.lib'
builder.RebuildIfNewer(libPath)
builder['POSTLINKFLAGS'].append(libPath)
def PostSetupHL2Job(self, job, builder, sdk):
if AMBuild.target['platform'] in ['linux', 'darwin']:
builder.AddObjectFiles(['tier1_i486.a', 'mathlib_i486.a'])
def DefaultHL2Compiler(self, path, sdk, noLink = False, oldMms = '-legacy'):
compiler = self.DefaultExtCompiler(path)
mms = 'core'
if sdk == 'ep1':
mms += oldMms
compiler['CXXINCLUDES'].append(os.path.join(self.mmsPath, mms))
compiler['CXXINCLUDES'].append(os.path.join(self.mmsPath, mms, 'sourcehook'))
info = self.possibleSdks
compiler['CDEFINES'].extend(['SE_' + info[i]['name'] + '=' + info[i]['def'] for i in info])
paths = [['public'], ['public', 'engine'], ['public', 'mathlib'], ['public', 'vstdlib'],
['public', 'tier0'], ['public', 'tier1']]
if sdk == 'ep1' or sdk == 'darkm':
paths.append(['public', 'dlls'])
paths.append(['game_shared'])
else:
paths.append(['public', 'game', 'server'])
paths.append(['public', 'toolframework'])
paths.append(['game', 'shared'])
paths.append(['common'])
info = self.sdkInfo[sdk]
sdkPath = AMBuild.cache[info['sdk']]
compiler['CDEFINES'].append('SOURCE_ENGINE=' + info['def'])
if sdk == 'swarm' and AMBuild.target['platform'] == 'windows':
compiler['CDEFINES'].extend(['COMPILER_MSVC', 'COMPILER_MSVC32'])
if sdk == 'ep1':
if AMBuild.target['platform'] == 'linux':
staticLibs = os.path.join(sdkPath, 'linux_sdk')
else:
if AMBuild.target['platform'] == 'linux':
staticLibs = os.path.join(sdkPath, 'lib', 'linux')
elif AMBuild.target['platform'] == 'darwin':
staticLibs = os.path.join(sdkPath, 'lib', 'mac')
for i in paths:
compiler['CXXINCLUDES'].append(os.path.join(sdkPath, *i))
if not noLink:
if AMBuild.target['platform'] == 'linux':
compiler['POSTLINKFLAGS'][0:0] = ['-lm']
if sdk in ['ep2v', 'l4d', 'l4d2']:
compiler['POSTLINKFLAGS'][0:0] = ['libtier0.so']
compiler['POSTLINKFLAGS'][0:0] = ['libvstdlib.so']
else:
compiler['POSTLINKFLAGS'][0:0] = ['tier0_i486.so']
compiler['POSTLINKFLAGS'][0:0] = ['vstdlib_i486.so']
elif AMBuild.target['platform'] == 'darwin':
compiler['POSTLINKFLAGS'][0:0] = ['libtier0.dylib']
compiler['POSTLINKFLAGS'][0:0] = ['libvstdlib.dylib']
return compiler
sm = SM()
globals = {
'SM': sm
}
AMBuild.Include(os.path.join('tools', 'buildbot', 'Versioning'), globals)
FileList = [
['loader', 'AMBuilder'],
['core', 'AMBuilder'],
['core', 'logic', 'AMBuilder'],
['extensions', 'bintools', 'AMBuilder'],
['extensions', 'clientprefs', 'AMBuilder'],
['extensions', 'cstrike', 'AMBuilder'],
['extensions', 'curl', 'AMBuilder'],
['extensions', 'geoip', 'AMBuilder'],
['extensions', 'mysql', 'AMBuilder'],
['extensions', 'sdktools', 'AMBuilder'],
['extensions', 'topmenus', 'AMBuilder'],
['extensions', 'updater', 'AMBuilder'],
['extensions', 'sqlite', 'AMBuilder'],
['extensions', 'regex', 'AMBuilder'],
['extensions', 'tf2', 'AMBuilder'],
['sourcepawn', 'jit', 'AMBuilder'],
['sourcepawn', 'compiler', 'AMBuilder'],
['plugins', 'AMBuilder'],
['tools', 'buildbot', 'PackageScript']
]
for parts in FileList:
AMBuild.Include(os.path.join(*parts), globals)
-1
View File
@@ -3,4 +3,3 @@ CONFIGURE YOUR IDENTITY FOR MERCURIAL!
IF YOU ARE A DEVELOPER WITH PUSH ACCESS, DO IT NOW KPLZTHX.
http://wiki.alliedmods.net/Mercurial_Tutorial#Identity
+476
View File
@@ -1,5 +1,481 @@
SourceMod Changelog
-----------------------------
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]
URL: http://wiki.alliedmods.net/SourceMod_1.3.6_Release_Notes
User Changes:
- Updated support for latest Left 4 Dead 1 (bug 4681).
Developer Changes:
- Updated TF2 custom kill defines (bug 4682).
----------------------------
SourceMod 1.3.5 [2010-10-17]
URL: http://wiki.alliedmods.net/SourceMod_1.3.5_Release_Notes
User Changes:
- Updated support for CS:S, Garry's Mod, DoD:S, TF2, HL2DM.
- Added support for Firearms: Source (bug 4537).
- Added support for Fistful of Frags (bug 3883).
- Added support for Alien Swarm (bug 4530).
- Fixed living players hearing dead players if alltalk is disabled while deadtalk is on (bug 4533, thanks Zach Callear).
- Fixed timeleft not getting reset on Game_Commencing in CS:S (bug 4557).
- Fixed PlayerRunCmd being hooked when not used (bug 3990).
- Fixed errors and missing effects caused by missing sprites on L4D2 (bug 4512).
- Fixed 'sm plugins' public command skipping plugins in recommended listing (bug 4501).
- Fixed corruption with large database.cfg files (bug 4286).
Developer Changes:
- Added TF2 object stocks (bug 4536).
- Added TF2_MakeBleed native to TF2 ext (bug 4542).
- Added support for logical entities in Synergy (bug 4534).
- Updated TF2 conditions enum and defines (bug 4526).
- Fixed potential crash with IMemUtils::FindPattern on Linux (bug 4554).
----------------------------
SourceMod 1.3.4 [2010-07-18]
URL: http://wiki.alliedmods.net/SourceMod_1.3.4_Release_Notes
User Changes:
- Support for latest TF update (bug 4506).
- Support for latest L4D2 update (bug 4509).
Developer Changes:
- Added FindFlagChar native (bug 3776).
- Added GetConVarDefault native (bug 4502).
- Added forward for TF's GetHoliday function (bug 4462).
----------------------------
SourceMod 1.3.3 [2010-06-23]
URL: http://wiki.alliedmods.net/SourceMod_1.3.3_Release_Notes
User Changes:
- Added support for CS:S on Orange Box
- Added gamedata for Resistance and Liberation (bug 4418).
- Updated gamedata for SourceForts, Empires, Obsidian Conflict, Zombie Master.
- Fixed memory corruption and leaks with some voice functionality (bug 4415).
- Fixed UI bug in sm_motd (bug 4460).
Developer Changes:
- Added new player condition (TFCond_CritCola, bug 4447).
- Fixed clientprefs deleting cookies twice in rare cases (bug 4412).
- Fixed OnClientConnected forward not firing for bots (bug 4443).
- Fixed sm_dump_datamaps crash (bug 4424).
- Fixed switch case comparisons failing with large numbers (bug 4457).
- Fixed rare crash in output hooks (bug 4422).
- Fixed bug with dynamically sized arrays being sliced (bug 4428).
- Fixed SendConVarValue() on TF2, DOD:S, L4D, and L4D2 (bug 4273).
- Fixed TF2 natives not being marked optional (bug 4389).
----------------------------
SourceMod 1.3.2 [2010-05-02]
URL: http://wiki.alliedmods.net/SourceMod_1.3.2_Release_Notes
User Changes:
- Support for recent TF, DoD, and L4D2 updates (bug 4356, bug 4361, bug 4371, bug 4374, bug 4375).
- Fixed rare crash when replicating cvars to clients (bug 4315).
- Lots of extra game support for Insurgency, ZPS, CSProMod, PVKII, and FortressForever (thanks
Nicholas "psychonic" hastings).
Developer Changes:
- Added TF functions for stunning, conditions, regeneration, and power play (bug 4166, bug 4331).
----------------------------
SourceMod 1.3.1 [2010-02-09]
URL: http://wiki.alliedmods.net/SourceMod_1.3.1_Release_Notes
User Changes:
- Added extended support for CSProMod (bug 4255).
- Fixed client disconnect crash on many third party games (bug 4231).
- Improved support for Battlegrounds 2 (bug 4146).
- Improved support for Insurgency (bug 4180).
- Improved support for Garry's Mod (bug 4230, bug 4268).
- Improved support for Synergy (bug 4235).
- Updated Day of Defeat support for 20010123 update (bug 4262).
- Fixed Webternet extension not loading on Windows 2000 (bug 4234).
Developer Changes:
- Fixed compiler complaints when using |any| tag on array arguments (bug 4274).
- Fixed GetClientCookieTime not being exported (bug 4237).
- Fixed potential crash in entity handling code (bug 4249).
----------------------------
SourceMod 1.3.0 [2010-01-15]
URL: http://wiki.alliedmods.net/SourceMod_1.3.0_Release_Notes
Major Features:
* Left 4 Dead 2 support
* Non-networked entity support
User Changes:
- Added Left 4 Dead 2 support (bug 4075).
- Added much richer voting progress feedback (bug 1997).
- Improved support for various third-party games (Nicholas "psychonic" Hastings).
- Added @spec target (bug 2718).
- Added sm_resetcvar command (bug 3636).
- Added "motd" chat trigger (bug 2694).
- Updated GeoIP to OCT-2009.
- Fixed rare map vote error (bug 3905).
- Fixed small leak in the nominations plugin (bug 4104).
- Fixed last client being excluded from some command effects (bug 3984).
- Fixed crashes in plugin [|un|re]loading (bug 4034, bug 4038, bug 4044, bug 4153).
- Special target "@me" is now filtered for certain statuses properly (bug 4000).
- Improved non-admin to admin chat (bug 3844).
- Removed "auto.*" extension folders (bug 3949).
Developer Changes:
- Added non-networked entity support (bug 2459).
- Added improved random number generator (bug 3831).
- Added GetClientCookieTime native (bug 3736).
- Added AskPluginLoad2 callback (bug 3716).
- Added PlayerRunCmd callback (bug 3289).
- Added PointOutsideWorld native (bug 3906).
- Added API for "blanket" command hooks (bug 4015).
- Added ability to test for SourceMod features (bug 4021).
- Added ability to change broadcast status on hooked events (bug 3886).
- OnClientCommand no longer receives unconnected clients (bug 3732).
- Fixed various bugs in client listening API (bug 3818).
- Fixed crash in BanClient (bug 3912).
- Fixed various crashes in self-removing callbacks (bug 4059).
- Fixed rare HUD text crash on TF (bug 4016).
- Fixed OnConfigsExecuted not running on EP1 games with large configs (bug 3828).
- Fixed entity output hooks not working (bug 3988).
- Gamedata folder matches are now case-insensitive (bug 3913).
- Blocked plugins from hooking "sm" command (bug 4013).
----------------------------
SourceMod 1.2.4 [2009-10-03]
URL: http://wiki.alliedmods.net/SourceMod_1.2.4_Release_Notes
- Updated for L4D changes (bugs 4032, 4033, 4035).
- Updated GeoLite Country database for GeoIP extension.
- Fixed crash when block-loading more than eight plugins (bug 4034).
- Fixed rare crash in hudtext code on TF (bug 4016).
- Fixed crash when reloading a blocked plugin failed (bug 4038).
- Fixed Huntsman not firing critical callback on TF (bug 3927).
- Registering the "sm" command no longer has any effect (bug 4013).
- Fixed translation bug in extension API (bug 4010).
----------------------------
SourceMod 1.2.3 [2009-08-28]
URL: http://wiki.alliedmods.net/SourceMod_1.2.3_Release_Notes
- Fix extension filename lookup. (bug 3975).
----------------------------
SourceMod 1.2.2 [2009-08-28]
URL: http://wiki.alliedmods.net/SourceMod_1.2.2_Release_Notes
- Removed auto folders. (bug 3949).
- Added PointOutsideWorld native to sdktools. (bug 3906).
- Added "motd" chat trigger to basetriggers. (bug 2694).
- Added manual extension reloading command to root console menu. (bug 3934)
- Fixed 'list' type custom menu entries overwriting admin restrictions. (bug 3783).
- Added sm_resetcvar command to basecommands. (bug 3636).
- Updated gamedata for DOD:S. (bug 3948).
- Updated gamedata for TF2. (bug 3948).
- Added new .ep2v build config for valve OB based games. (bug 3948).
- Fixed incorrect escaping in clientprefs SQLite queries. (bug 3904)
- Updated gamedata for Synergy. (bug 3315).
- Upgraded to pcre-7.9 (bug 3923).
- Switched Insurgency chat printing to SayText. (bug 3738).
- Updated gamedata for Insurgency. (bug 3511).
- Updated gamedata for ZM. (bug 3746).
- Updated gamedata for Empires. (bug 3500).
- Updated gamedata for ZPS. (bug 3877).
- Updated gamedata for AoC. (bug 3891).
- Fixed RemovePlayerDisguise signature for TF2. (bug 3892).
----------------------------
SourceMod 1.2.1 [2009-05-31]
URL: http://wiki.alliedmods.net/SourceMod_1.2.1_Release_Notes
- Updated SDKTools for latest Team Fortress update.
- Added L4D handling to GuessSDKVersion() (bug 3842).
- Updated Zombie Panic Source offsets (bug 3632).
- Fixed crash when clientprefs saw disconnect from 64th client (bug 3821).
- Fixed Plugin_Handled acting like a Stop in usermsg hooks (bug 3685).
- Fixed early tv_enable causing crashes (bug 3766).
- Fixed unhook event crash (bug 3814).
- Fixed compiler reading uninitialized strings while processing varargs (bug 3811).
- Fixed compiler choosing whether to emit stradjust.pri on dynamic arrays based on uninitialized memory (bug 3810).
- Fixed Windows L4D CreateFakeClient signature (bug 3792).
- Fixed sm_slap for EP1 games (bug 3768).
- Fixed casting problems in TextParsers breaking TrimString for non-ASCII characters (bug 3800).
- Fixed OnClientConnect rejectmsg handling, improved doc (bug 3690).
- Fixed clientprefs not loading cookies for clients on late load (bug 3735).
- Fixed GetCommandFlags on original engine games (bug 3759).
- Fixed compiler asserting when returning a string literal (bug 3836).
- Fixed compiler erroring when tagging functions for string return (bug 3837).
- Fixed compiler not handling constant chained relational operators correctly (bug 3838).
- Fixed revote bug and inflexibilities in RedrawClientVoteMenu (bug 3834).
- Fixed auto update URL being set too late (bug 3699).
- Disabled nextmap in Synergy and Dystopia (bug 3687, bug 3741).
- Removed unnecessary SSE optimizations from msvc9 project files (bug 3756).
- Removed short-lived tag system (bug 3751).
- Removed the alive check from sm_rename. (bug 3698).
- Switched FortressForever to Valve menus (bug 3819).
----------------------------
SourceMod 1.2.0 [2009-03-05]
URL: http://wiki.alliedmods.net/SourceMod_1.2.0_Release_Notes
Major Features:
* Left 4 Dead Support
* Dark Messiah Support
* New and Improved Updater
Changes:
- Added Left 4 Dead support (bug 3414).
- Added Dark Messiah game support (requires Metamod:Source 1.7.1 or higher).
- Added sm_name command (bug 2150).
- Added extension-level dynamic hooking to bintools (bug 2616).
- Added client validation API to replace passing userids asynchronously.
- Added cURL extension, available to other extensions (bug 3560).
- Added parsing of custom gamedata files (bug 3644).
- Added case insensitivity search to ReplaceString (bug 3639, Fyren).
- Added more detail to certain player-oriented menu titles (bug 2740, Fyren).
- Added sv_tags API (bug 3677).
- Greatly improved admin-sql-prefetch performance for large tables (bug 3354, FLOOR_MASTER).
- Exposed IServer address to extensions (bug 3545).
- New gamedata organization; files are now smaller and per-game (bug 3546).
- Split sound functions into a new plugin, sounds.smx.
- Fixed slap and slay on Insurgency (bug 2560).
- Fixed blank admins being created from invalid admin file lines (bug 3431).
- Fixed basetriggers not working on Insurgency (bug 3497).
- Fixed client preferences missing some clients (bug 3616).
- Improved database fallback mechanism in clientprefs (bug 3564).
- Improved timer handling in funcommands (bug 3498).
- Improved compile.sh to take filenames (bug 3550, jonasfietz).
- sm_kick now shows the kick reason when available.
- Fixed MsgPostHook (ex MsgSentNotify) callbacks not firing on intercept hook (bug 3631).
- Note: SourceMod now adds "sourcemod" to the sv_tags cvar.
----------------------------
SourceMod 1.1.2 [2009-02-26]
+1
View File
@@ -1,6 +1,7 @@
//This file unloads all plugins, re-loads a few "safe" ones, and then prevents
//any more plugins from being loaded.
sm plugins unload_all
sm plugins load_unlock
sm plugins load basebans.smx
sm plugins load basecommands.smx
sm plugins load admin-flatfile.smx
+28 -3
View File
@@ -80,21 +80,21 @@ sm_reserve_type 0
sm_reserved_slots 0
// Specifies whether or not reserved slots will be hidden (subtracted from max
// slot count). Valid values are 0 (visible) or 1 (hidden).
// slot count). Valid values are 0 (Visible) or 1 (Hidden).
// --
// Requires: reservedslots.smx
// Default: 0
sm_hide_slots 0
// Specifies whether or not non-admins can send messages to admins using
// say_team @<message>. Valid values are 0 (disabled) or 1 (enabled)
// say_team @<message>. Valid values are 0 (Disabled) or 1 (Enabled)
// --
// Requires: basechat.smx
// Default: 1
sm_chat_mode 1
// Specifies whether or not "timeleft" will automaticly be triggered every
// x seconds. Valid values are 0 (disabled) to 1800 seconds.
// x seconds. Valid values are 0 (Disabled) to 1800 seconds.
// --
// Requires: basetriggers.smx
// Default: 0
@@ -107,3 +107,28 @@ sm_timeleft_interval 0
// Requires: basetriggers.smx
// Default: 1
sm_trigger_show 1
// Specifies whether or not to display vote progress to clients in the
// "hint" box (near the bottom of the screen in most games).
// Valid values are 0 (Disabled) or 1 (Enabled).
// --
// Default: 0
sm_vote_progress_hintbox 0
// Specifies whether or not to display vote progress to clients in the
// chat area. Valid values are 0 (Disabled) or 1 (Enabled).
// --
// Default: 0
sm_vote_progress_chat 0
// Specifies whether or not to display vote progress in the server console.
// Valid values are 0 (Disabled) or 1 (Enabled).
// --
// Default: 0
sm_vote_progress_console 0
// Specifies whether or not to display vote progress to clients in the
// client console. Valid values are 0 (Disabled) or 1 (Enabled).
// --
// Default: 0
sm_vote_progress_client_console 0
+3 -15
View File
@@ -4,14 +4,6 @@
*/
"Core"
{
/**
* Relative path to SourceMod's base directory. This is relative to the game/mod directory.
* Only change this if you have installed SourceMod in a non-default location.
*
* The default value is "addons/sourcemod"
*/
"BasePath" "addons/sourcemod"
/**
* This option determines if SourceMod logging is enabled.
*
@@ -105,15 +97,11 @@
"ForceRestartAfterUpdate" "no"
/**
* Sets the server to connect to for auotmatic gamedata updates.
* URL to use for retrieving update information.
* SSL is not yet supported.
*/
"AutoUpdateServer" "smupdate.alliedmods.net"
"AutoUpdateURL" "http://update.sourcemod.net/update/"
/**
* Sets the port to connect to on the AutoUpdateServer server
*/
"AutoUpdatePort" "6500"
/**
* Whether to show debug spew.
* Currently this will log details about the gamedata updating process.
+2
View File
@@ -2,6 +2,8 @@
{
"driver_default" "mysql"
// When specifying "host", you may use an IP address, a hostname, or a socket file path
"default"
{
"driver" "default"
Binary file not shown.
-1
View File
@@ -2,4 +2,3 @@
{
"en" "English"
}
+10
View File
@@ -0,0 +1,10 @@
# vim: set ts=2 sw=2 tw=99 noet:
import sys
import ambuild.runner as runner
run = runner.Runner()
run.options.add_option('--enable-debug', action='store_const', const='1', dest='debug',
help='Enable debugging symbols')
run.options.add_option('--enable-optimize', action='store_const', const='1', dest='opt',
help='Enable optimization')
run.Configure(sys.path[0])
+78
View File
@@ -0,0 +1,78 @@
# vim: set ts=2 sw=2 tw=99 noet ft=python:
import os
for i in SM.sdkInfo:
sdk = SM.sdkInfo[i]
if AMBuild.target['platform'] not in sdk['platform']:
continue
name = 'sourcemod.' + sdk['ext']
compiler = SM.DefaultHL2Compiler('core', i)
extension = AMBuild.AddJob(name)
binary = Cpp.LibraryBuilder(name, AMBuild, extension, compiler)
SM.PreSetupHL2Job(extension, binary, i)
files = [
'AdminCache.cpp',
'ExtensionSys.cpp',
'MenuStyle_Valve.cpp',
'logic_bridge.cpp',
'smn_entities.cpp',
'sm_stringutil.cpp',
'ADTFactory.cpp',
'ForwardSys.cpp',
'MenuVoting.cpp',
'smn_events.cpp',
'smn_menus.cpp',
'sm_trie.cpp',
'CDataPack.cpp',
'frame_hooks.cpp',
'NativeInvoker.cpp',
'smn_fakenatives.cpp',
'smn_nextmap.cpp',
'sourcemm_api.cpp',
'ChatTriggers.cpp',
'NativeOwner.cpp',
'smn_filesystem.cpp',
'smn_player.cpp',
'sourcemod.cpp',
'concmd_cleaner.cpp',
'HalfLife2.cpp',
'NextMap.cpp',
'ConCmdManager.cpp',
'HandleSys.cpp',
'ConVarManager.cpp',
'LibrarySys.cpp',
'PlayerManager.cpp',
'TimerSys.cpp',
'CoreConfig.cpp',
'Logger.cpp',
'PluginInfoDatabase.cpp',
'smn_bitbuffer.cpp',
'smn_halflife.cpp',
'PluginSys.cpp',
'smn_console.cpp',
'UserMessages.cpp',
'Database.cpp',
'MenuManager.cpp',
'smn_core.cpp',
'smn_hudtext.cpp',
'smn_usermsgs.cpp',
'DebugReporter.cpp',
'MenuStyle_Base.cpp',
'ShareSys.cpp',
'smn_database.cpp',
'smn_keyvalues.cpp',
'smn_vector.cpp',
'EventManager.cpp',
'MenuStyle_Radio.cpp',
'sm_autonatives.cpp',
'sm_srvcmds.cpp',
'ConsoleDetours.cpp'
]
binary.AddSourceFiles('core', files)
SM.PostSetupHL2Job(extension, binary, i)
SM.AutoVersion('core', binary)
binary.SendToJob()
+7 -2
View File
@@ -1170,6 +1170,11 @@ bool AdminCache::GetMethodIndex(const char *name, unsigned int *_index)
bool AdminCache::BindAdminIdentity(AdminId id, const char *auth, const char *ident)
{
if (ident[0] == '\0')
{
return false;
}
AdminUser *pUser = (AdminUser *)m_pMemory->GetAddress(id);
if (!pUser || pUser->magic != USR_MAGIC_SET)
{
@@ -1714,7 +1719,7 @@ bool AdminCache::CanAdminUseCommand(int client, const char *cmd)
}
}
return g_ConCmds.CheckCommandAccess(client, cmd, bits);
return g_ConCmds.CheckClientCommandAccess(client, cmd, bits);
}
unsigned int AdminCache::SetGroupImmunityLevel(GroupId gid, unsigned int level)
@@ -1789,7 +1794,7 @@ bool AdminCache::CheckAccess(int client, const char *cmd, FlagBits flags, bool o
GetCommandOverride(cmd, Override_Command, &bits);
}
return g_ConCmds.CheckCommandAccess(client, cmd, bits) ? 1 : 0;
return g_ConCmds.CheckClientCommandAccess(client, cmd, bits) ? 1 : 0;
}
void iterator_glob_basic_override(Trie *pTrie, const char *key, void **value, void *data)
+11 -43
View File
@@ -34,14 +34,14 @@
#include "sm_stringutil.h"
#include "ConCmdManager.h"
#include "PlayerManager.h"
#include "Translator.h"
#include "HalfLife2.h"
#include "logic_bridge.h"
/* :HACKHACK: We can't SH_DECL here because ConCmdManager.cpp does.
* While the OB build only runs on MM:S 1.6.0+ (SH 5+), the older one
* can technically be compiled against any MM:S version after 1.4.2.
*/
#if defined ORANGEBOX_BUILD
#if SOURCE_ENGINE >= SE_ORANGEBOX
extern bool __SourceHook_FHRemoveConCommandDispatch(void *, bool, class fastdelegate::FastDelegate1<const CCommand &, void>);
extern int __SourceHook_FHAddConCommandDispatch(void *, ISourceHook::AddHookMode, bool, class fastdelegate::FastDelegate1<const CCommand &, void>);
#else
@@ -53,7 +53,7 @@ extern int __SourceHook_FHAddConCommandDispatch(void *, bool, class fastdelegate
#elif SH_IMPL_VERSION == 3
extern bool __SourceHook_FHAddConCommandDispatch(void *, bool, class fastdelegate::FastDelegate0<void>);
#endif //SH_IMPL_VERSION
#endif //ORANGEBOX_BUILD
#endif //SE_ORANGEBOX
ChatTriggers g_ChatTriggers;
bool g_bSupressSilentFails = false;
@@ -113,36 +113,13 @@ void ChatTriggers::OnSourceModAllInitialized()
void ChatTriggers::OnSourceModAllInitialized_Post()
{
g_pCorePhrases->AddPhraseFile("antiflood.phrases");
logicore.AddCorePhraseFile("antiflood.phrases");
}
void ChatTriggers::OnSourceModGameInitialized()
{
unsigned int total = 2;
ConCommandBase *pCmd = icvar->GetCommands();
const char *name;
while (pCmd)
{
if (pCmd->IsCommand())
{
name = pCmd->GetName();
if (!m_pSayCmd && strcmp(name, "say") == 0)
{
m_pSayCmd = (ConCommand *)pCmd;
if (--total == 0)
{
break;
}
} else if (!m_pSayTeamCmd && strcmp(name, "say_team") == 0) {
m_pSayTeamCmd = (ConCommand *)pCmd;
if (--total == 0)
{
break;
}
}
}
pCmd = const_cast<ConCommandBase *>(pCmd->GetNext());
}
m_pSayCmd = FindCommand("say");
m_pSayTeamCmd = FindCommand("say_team");
if (m_pSayCmd)
{
@@ -173,7 +150,7 @@ void ChatTriggers::OnSourceModShutdown()
g_Forwards.ReleaseForward(m_pDidFloodBlock);
}
#if defined ORANGEBOX_BUILD
#if SOURCE_ENGINE >= SE_ORANGEBOX
void ChatTriggers::OnSayCommand_Pre(const CCommand &command)
{
#else
@@ -212,17 +189,8 @@ void ChatTriggers::OnSayCommand_Pre()
{
char buffer[128];
if (!CoreTranslate(
buffer,
sizeof(buffer),
"%T",
2,
NULL,
"Flooding the server",
&client))
{
if (!logicore.CoreTranslate(buffer, sizeof(buffer), "%T", 2, NULL, "Flooding the server", &client))
UTIL_Format(buffer, sizeof(buffer), "You are flooding the server!");
}
/* :TODO: we should probably kick people who spam too much. */
@@ -267,7 +235,7 @@ void ChatTriggers::OnSayCommand_Pre()
/**
* Test if this is actually a command!
*/
if (!PreProcessTrigger(engine->PEntityOfEntIndex(client), args, is_quoted))
if (!PreProcessTrigger(PEntityOfEntIndex(client), args, is_quoted))
{
CPlayer *pPlayer;
if (is_silent
@@ -299,7 +267,7 @@ void ChatTriggers::OnSayCommand_Pre()
RETURN_META(MRES_IGNORED);
}
#if defined ORANGEBOX_BUILD
#if SOURCE_ENGINE >= SE_ORANGEBOX
void ChatTriggers::OnSayCommand_Post(const CCommand &command)
#else
void ChatTriggers::OnSayCommand_Post()
@@ -315,7 +283,7 @@ void ChatTriggers::OnSayCommand_Post()
/* Execute the cached command */
int client = g_ConCmds.GetCommandClient();
unsigned int old = SetReplyTo(SM_REPLY_CHAT);
serverpluginhelpers->ClientCommand(engine->PEntityOfEntIndex(client), m_ToExecute);
serverpluginhelpers->ClientCommand(PEntityOfEntIndex(client), m_ToExecute);
SetReplyTo(old);
}
}
+1 -1
View File
@@ -54,7 +54,7 @@ public: //SMGlobalClass
char *error,
size_t maxlength);
private: //ConCommand
#if defined ORANGEBOX_BUILD
#if SOURCE_ENGINE >= SE_ORANGEBOX
void OnSayCommand_Pre(const CCommand &command);
void OnSayCommand_Post(const CCommand &command);
#else
+81 -75
View File
@@ -34,13 +34,13 @@
#include "AdminCache.h"
#include "sm_stringutil.h"
#include "PlayerManager.h"
#include "Translator.h"
#include "HalfLife2.h"
#include "ChatTriggers.h"
#include "logic_bridge.h"
ConCmdManager g_ConCmds;
#if defined ORANGEBOX_BUILD
#if SOURCE_ENGINE >= SE_ORANGEBOX
SH_DECL_HOOK1_void(ConCommand, Dispatch, SH_NOATTRIB, false, const CCommand &);
#else
SH_DECL_HOOK0_void(ConCommand, Dispatch, SH_NOATTRIB, false);
@@ -205,7 +205,7 @@ void ConCmdManager::OnPluginDestroyed(IPlugin *plugin)
delete pList;
}
}
#if defined ORANGEBOX_BUILD
#if SOURCE_ENGINE >= SE_ORANGEBOX
void CommandCallback(const CCommand &command)
{
#else
@@ -226,49 +226,78 @@ void ConCmdManager::SetCommandClient(int client)
m_CmdClient = client + 1;
}
ConCmdInfo *ConCmdManager::FindInTrie(const char *name)
{
ConCmdInfo *pInfo;
if (!sm_trie_retrieve(m_pCmds, name, (void **)&pInfo))
return NULL;
return pInfo;
}
ConCmdList::iterator ConCmdManager::FindInList(const char *cmd)
{
List<ConCmdInfo *>::iterator iter = m_CmdList.begin();
while (iter != m_CmdList.end())
{
if (strcasecmp((*iter)->pCmd->GetName(), cmd) == 0)
break;
iter++;
}
return iter;
}
ResultType ConCmdManager::DispatchClientCommand(int client, const char *cmd, int args, ResultType type)
{
ConCmdInfo *pInfo;
if (sm_trie_retrieve(m_pCmds, cmd, (void **)&pInfo))
if ((pInfo = FindInTrie(cmd)) == NULL)
{
cell_t result = type;
cell_t tempres = result;
List<CmdHook *>::iterator iter;
CmdHook *pHook;
for (iter=pInfo->conhooks.begin();
iter!=pInfo->conhooks.end();
iter++)
ConCmdList::iterator item = FindInList(cmd);
if (item == m_CmdList.end())
return type;
pInfo = *item;
}
cell_t result = type;
cell_t tempres = result;
List<CmdHook *>::iterator iter;
CmdHook *pHook;
for (iter=pInfo->conhooks.begin();
iter!=pInfo->conhooks.end();
iter++)
{
pHook = (*iter);
if (!pHook->pf->IsRunnable())
{
pHook = (*iter);
if (!pHook->pf->IsRunnable())
continue;
}
if (pHook->pAdmin && !CheckAccess(client, cmd, pHook->pAdmin))
{
if (result < Pl_Handled)
{
continue;
result = Pl_Handled;
}
if (pHook->pAdmin && !CheckAccess(client, cmd, pHook->pAdmin))
continue;
}
pHook->pf->PushCell(client);
pHook->pf->PushCell(args);
if (pHook->pf->Execute(&tempres) == SP_ERROR_NONE)
{
if (tempres > result)
{
if (result < Pl_Handled)
{
result = Pl_Handled;
}
continue;
result = tempres;
}
pHook->pf->PushCell(client);
pHook->pf->PushCell(args);
if (pHook->pf->Execute(&tempres) == SP_ERROR_NONE)
if (result == Pl_Stop)
{
if (tempres > result)
{
result = tempres;
}
if (result == Pl_Stop)
{
break;
}
break;
}
}
type = (ResultType)result;
}
type = (ResultType)result;
return type;
}
@@ -293,35 +322,20 @@ void ConCmdManager::InternalDispatch(const CCommand &command)
*/
const char *cmd = g_HL2.CurrentCommandName();
ConCmdInfo *pInfo;
if (!sm_trie_retrieve(m_pCmds, cmd, (void **)&pInfo))
ConCmdInfo *pInfo = FindInTrie(cmd);
if (pInfo == NULL)
{
/* Unfortunately, we now have to do a slow lookup because Valve made client commands
* case-insensitive. We can't even use our sortedness.
*/
if (client == 0 && !engine->IsDedicatedServer())
{
return;
}
List<ConCmdInfo *>::iterator iter;
ConCmdList::iterator item = FindInList(cmd);
if (item == m_CmdList.end())
return;
pInfo = NULL;
iter = m_CmdList.begin();
while (iter != m_CmdList.end())
{
if (strcasecmp((*iter)->pCmd->GetName(), cmd) == 0)
{
pInfo = (*iter);
break;
}
iter++;
}
if (pInfo == NULL)
{
return;
}
pInfo = *item;
}
/* This is a hack to prevent say triggers from firing on messages that were
@@ -436,7 +450,7 @@ void ConCmdManager::InternalDispatch(const CCommand &command)
}
}
bool ConCmdManager::CheckCommandAccess(int client, const char *cmd, FlagBits cmdflags)
bool ConCmdManager::CheckClientCommandAccess(int client, const char *cmd, FlagBits cmdflags)
{
if (cmdflags == 0 || client == 0)
{
@@ -457,7 +471,11 @@ bool ConCmdManager::CheckCommandAccess(int client, const char *cmd, FlagBits cmd
return false;
}
AdminId adm = player->GetAdminId();
return CheckAdminCommandAccess(player->GetAdminId(), cmd, cmdflags);
}
bool ConCmdManager::CheckAdminCommandAccess(AdminId adm, const char *cmd, FlagBits cmdflags)
{
if (adm != INVALID_ADMIN_ID)
{
FlagBits bits = g_Admins.GetAdminFlags(adm, Access_Effective);
@@ -510,16 +528,16 @@ bool ConCmdManager::CheckCommandAccess(int client, const char *cmd, FlagBits cmd
bool ConCmdManager::CheckAccess(int client, const char *cmd, AdminCmdInfo *pAdmin)
{
if (CheckCommandAccess(client, cmd, pAdmin->eflags))
if (CheckClientCommandAccess(client, cmd, pAdmin->eflags))
{
return true;
}
edict_t *pEdict = engine->PEntityOfEntIndex(client);
edict_t *pEdict = PEntityOfEntIndex(client);
/* If we got here, the command failed... */
char buffer[128];
if (!CoreTranslate(buffer, sizeof(buffer), "%T", 2, NULL, "No Access", &client))
if (!logicore.CoreTranslate(buffer, sizeof(buffer), "%T", 2, NULL, "No Access", &client))
{
UTIL_Format(buffer, sizeof(buffer), "You do not have access to this command");
}
@@ -895,25 +913,13 @@ ConCmdInfo *ConCmdManager::AddOrFindCommand(const char *name, const char *descri
ConCmdInfo *pInfo;
if (!sm_trie_retrieve(m_pCmds, name, (void **)&pInfo))
{
ConCmdList::iterator item = FindInList(name);
if (item != m_CmdList.end())
return *item;
pInfo = new ConCmdInfo();
/* Find the commandopan */
ConCommandBase *pBase = icvar->GetCommands();
ConCommand *pCmd = NULL;
while (pBase)
{
if (strcmp(pBase->GetName(), name) == 0)
{
/* Don't want to return convar with same name */
if (!pBase->IsCommand())
{
return NULL;
}
pCmd = (ConCommand *)pBase;
break;
}
pBase = const_cast<ConCommandBase *>(pBase->GetNext());
}
ConCommand *pCmd = FindCommand(name);
if (!pCmd)
{
+13 -3
View File
@@ -92,13 +92,15 @@ struct ConCmdInfo
bool is_admin_set; /**< Whether or not admin info is set */
};
typedef List<ConCmdInfo *> ConCmdList;
class ConCmdManager :
public SMGlobalClass,
public IRootConsoleCommand,
public IPluginsListener,
public IConCommandTracker
{
#if defined ORANGEBOX_BUILD
#if SOURCE_ENGINE >= SE_ORANGEBOX
friend void CommandCallback(const CCommand &command);
#else
friend void CommandCallback();
@@ -128,7 +130,8 @@ public:
void UpdateAdminCmdFlags(const char *cmd, OverrideType type, FlagBits bits, bool remove);
bool LookForSourceModCommand(const char *cmd);
bool LookForCommandAdminFlags(const char *cmd, FlagBits *pFlags);
bool CheckCommandAccess(int client, const char *cmd, FlagBits flags);
bool CheckClientCommandAccess(int client, const char *cmd, FlagBits flags);
bool CheckAdminCommandAccess(AdminId adm, const char *cmd, FlagBits flags);
private:
void InternalDispatch(const CCommand &command);
ResultType RunAdminCommand(ConCmdInfo *pInfo, int client, int args);
@@ -139,6 +142,12 @@ private:
void RemoveConCmds(List<CmdHook *> &cmdlist);
void RemoveConCmds(List<CmdHook *> &cmdlist, IPluginContext *pContext);
bool CheckAccess(int client, const char *cmd, AdminCmdInfo *pAdmin);
// Case insensitive
ConCmdList::iterator FindInList(const char *name);
// Case sensitive
ConCmdInfo *FindInTrie(const char *name);
public:
inline int GetCommandClient()
{
@@ -151,7 +160,7 @@ public:
private:
Trie *m_pCmds; /* command lookup */
Trie *m_pCmdGrps; /* command group lookup */
List<ConCmdInfo *> m_CmdList; /* command list */
ConCmdList m_CmdList; /* command list */
int m_CmdClient; /* current client */
BaseStringTable m_Strings; /* string table */
};
@@ -159,3 +168,4 @@ private:
extern ConCmdManager g_ConCmds;
#endif // _INCLUDE_SOURCEMOD_CONCMDMANAGER_H_
+89
View File
@@ -0,0 +1,89 @@
/**
* vim: set ts=4 sw=4 tw=99 noet :
* =============================================================================
* SourceMod
* Copyright (C) 2004-2010 AlliedModders LLC. All rights reserved.
* =============================================================================
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, version 3.0, as published by the
* Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*
* As a special exception, AlliedModders LLC gives you permission to link the
* code of this program (as well as its derivative works) to "Half-Life 2," the
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
* by the Valve Corporation. You must obey the GNU General Public License in
* all respects for all other code used. Additionally, AlliedModders LLC grants
* this exception to all derivative works. AlliedModders LLC defines further
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
* or <http://www.sourcemod.net/license.php>.
*
* Version: $Id$
*/
#ifndef _INCLUDE_SOURCEMOD_CON_COMMAND_BASE_ITERATOR_H_
#define _INCLUDE_SOURCEMOD_CON_COMMAND_BASE_ITERATOR_H_
#if SOURCE_ENGINE >= SE_LEFT4DEAD
class ConCommandBaseIterator
{
public:
inline ConCommandBaseIterator() : iter(icvar)
{
iter.SetFirst();
}
inline bool IsValid()
{
return iter.IsValid();
}
inline void Next()
{
iter.Next();
}
inline ConCommandBase *Get()
{
return iter.Get();
}
private:
ICvar::Iterator iter;
};
#else
class ConCommandBaseIterator
{
public:
inline ConCommandBaseIterator()
{
iter = icvar->GetCommands();
}
inline bool IsValid()
{
return iter != NULL;
}
inline void Next()
{
iter = const_cast<ConCommandBase *>(iter->GetNext());
}
inline ConCommandBase *Get()
{
return iter;
}
private:
ConCommandBase *iter;
};
#endif
#endif /* _INCLUDE_SOURCEMOD_CON_COMMAND_BASE_ITERATOR_H_ */
+103 -30
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-2009 AlliedModders LLC. All rights reserved.
* =============================================================================
*
* This program is free software; you can redistribute it and/or modify it under
@@ -25,8 +25,6 @@
* 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 "ConVarManager.h"
@@ -41,23 +39,59 @@
ConVarManager g_ConVarManager;
#if !defined ORANGEBOX_BUILD
#if SOURCE_ENGINE <= SE_DARKMESSIAH
#define CallGlobalChangeCallbacks CallGlobalChangeCallback
#endif
#if defined ORANGEBOX_BUILD
#if SOURCE_ENGINE >= SE_ORANGEBOX
SH_DECL_HOOK3_void(ICvar, CallGlobalChangeCallbacks, SH_NOATTRIB, false, ConVar *, const char *, float);
#else
SH_DECL_HOOK2_void(ICvar, CallGlobalChangeCallbacks, SH_NOATTRIB, false, ConVar *, const char *);
#endif
#if SOURCE_ENGINE != SE_DARKMESSIAH
SH_DECL_HOOK5_void(IServerGameDLL, OnQueryCvarValueFinished, SH_NOATTRIB, 0, QueryCvarCookie_t, edict_t *, EQueryCvarValueStatus, const char *, const char *);
SH_DECL_HOOK5_void(IServerPluginCallbacks, OnQueryCvarValueFinished, SH_NOATTRIB, 0, QueryCvarCookie_t, edict_t *, EQueryCvarValueStatus, const char *, const char *);
#endif
const ParamType CONVARCHANGE_PARAMS[] = {Param_Cell, Param_String, Param_String};
typedef List<const ConVar *> ConVarList;
KTrie<ConVarInfo *> convar_cache;
class ConVarReentrancyGuard
{
ConVar *cvar;
ConVarReentrancyGuard *up;
public:
static ConVarReentrancyGuard *chain;
ConVarReentrancyGuard(ConVar *cvar)
: cvar(cvar), up(chain)
{
chain = this;
}
~ConVarReentrancyGuard()
{
assert(chain == this);
chain = up;
}
static bool IsCvarInChain(ConVar *cvar)
{
ConVarReentrancyGuard *guard = chain;
while (guard != NULL)
{
if (guard->cvar == cvar)
return true;
guard = guard->up;
}
return false;
}
};
ConVarReentrancyGuard *ConVarReentrancyGuard::chain = NULL;
ConVarManager::ConVarManager() : m_ConVarType(0), m_bIsDLLQueryHooked(false), m_bIsVSPQueryHooked(false)
{
}
@@ -84,7 +118,7 @@ void ConVarManager::OnSourceModAllInitialized()
/**
* Episode 2 has this function by default, but the older versions do not.
*/
#if !defined ORANGEBOX_BUILD
#if SOURCE_ENGINE == SE_EPISODEONE
if (g_SMAPI->GetGameDLLVersion() >= 6)
{
SH_ADD_HOOK_MEMFUNC(IServerGameDLL, OnQueryCvarValueFinished, gamedll, this, &ConVarManager::OnQueryCvarValueFinished, false);
@@ -94,6 +128,8 @@ void ConVarManager::OnSourceModAllInitialized()
SH_ADD_HOOK_STATICFUNC(ICvar, CallGlobalChangeCallbacks, icvar, OnConVarChanged, false);
g_PluginSys.AddPluginsListener(this);
/* Add the 'convars' option to the 'sm' console command */
g_RootMenu.AddRootConsoleCommand("cvars", "View convars created by a plugin", this);
}
@@ -141,6 +177,7 @@ void ConVarManager::OnSourceModShutdown()
}
convar_cache.clear();
#if SOURCE_ENGINE != SE_DARKMESSIAH
/* Unhook things */
if (m_bIsDLLQueryHooked)
{
@@ -152,12 +189,15 @@ void ConVarManager::OnSourceModShutdown()
SH_REMOVE_HOOK_MEMFUNC(IServerPluginCallbacks, OnQueryCvarValueFinished, vsp_interface, this, &ConVarManager::OnQueryCvarValueFinished, false);
m_bIsVSPQueryHooked = false;
}
#endif
SH_REMOVE_HOOK_STATICFUNC(ICvar, CallGlobalChangeCallbacks, icvar, OnConVarChanged, false);
/* Remove the 'convars' option from the 'sm' console command */
g_RootMenu.RemoveRootConsoleCommand("cvars", this);
g_PluginSys.RemovePluginsListener(this);
/* Remove the 'ConVar' handle type */
g_HandleSys.RemoveType(m_ConVarType, g_pCoreIdent);
}
@@ -176,7 +216,7 @@ void ConVarManager::OnSourceModVSPReceived()
}
/* For later MM:S versions, use the updated API, since it's cleaner. */
#if defined METAMOD_PLAPI_VERSION
#if defined METAMOD_PLAPI_VERSION || PLAPI_VERSION >= 11
int engine = g_SMAPI->GetSourceEngineBuild();
if (engine == SOURCE_ENGINE_ORIGINAL || vsp_version < 2)
{
@@ -189,8 +229,10 @@ void ConVarManager::OnSourceModVSPReceived()
}
#endif
#if SOURCE_ENGINE != SE_DARKMESSIAH
SH_ADD_HOOK_MEMFUNC(IServerPluginCallbacks, OnQueryCvarValueFinished, vsp_interface, this, &ConVarManager::OnQueryCvarValueFinished, false);
m_bIsVSPQueryHooked = true;
#endif
}
bool convar_cache_lookup(const char *name, ConVarInfo **pVar)
@@ -246,12 +288,23 @@ void ConVarManager::OnUnlinkConCommandBase(ConCommandBase *pBase, const char *na
void ConVarManager::OnPluginUnloaded(IPlugin *plugin)
{
ConVarList *pConVarList;
List<ConVarQuery>::iterator iter;
/* If plugin has a convar list, free its memory */
if (plugin->GetProperty("ConVarList", (void **)&pConVarList, true))
{
delete pConVarList;
}
/* Remove convar queries for this plugin that haven't returned results yet */
for (iter = m_ConVarQueries.begin(); iter != m_ConVarQueries.end(); iter++)
{
ConVarQuery &query = (*iter);
if (query.pCallback->GetParentRuntime() == plugin->GetRuntime())
{
m_ConVarQueries.erase(iter);
}
}
}
void ConVarManager::OnHandleDestroy(HandleType_t type, void *object)
@@ -269,8 +322,15 @@ void ConVarManager::OnRootConsoleCommand(const char *cmdname, const CCommand &co
int argcount = command.ArgC();
if (argcount >= 3)
{
bool wantReset = false;
/* Get plugin index that was passed */
const char *arg = command.Arg(2);
if (argcount >= 4 && strcmp(arg, "reset") == 0)
{
wantReset = true;
arg = command.Arg(3);
}
/* Get plugin object */
CPlugin *plugin = g_PluginSys.FindPluginByConsoleArg(arg);
@@ -295,21 +355,34 @@ void ConVarManager::OnRootConsoleCommand(const char *cmdname, const CCommand &co
return;
}
g_RootMenu.ConsolePrint("[SM] Listing %d convars for: %s", pConVarList->size(), plname);
g_RootMenu.ConsolePrint(" %-32.31s %s", "[Name]", "[Value]");
/* Iterate convar list and display each one */
if (!wantReset)
{
g_RootMenu.ConsolePrint("[SM] Listing %d convars for: %s", pConVarList->size(), plname);
g_RootMenu.ConsolePrint(" %-32.31s %s", "[Name]", "[Value]");
}
/* Iterate convar list and display/reset each one */
for (iter = pConVarList->begin(); iter != pConVarList->end(); iter++)
{
const ConVar *pConVar = (*iter);
g_RootMenu.ConsolePrint(" %-32.31s %s", pConVar->GetName(), pConVar->GetString());
/*const */ConVar *pConVar = const_cast<ConVar *>(*iter);
if (!wantReset)
{
g_RootMenu.ConsolePrint(" %-32.31s %s", pConVar->GetName(), pConVar->GetString());
} else {
pConVar->Revert();
}
}
if (wantReset)
{
g_RootMenu.ConsolePrint("[SM] Reset %d convars for: %s", pConVarList->size(), plname);
}
return;
}
/* Display usage of subcommand */
g_RootMenu.ConsolePrint("[SM] Usage: sm convars <plugin #>");
g_RootMenu.ConsolePrint("[SM] Usage: sm cvars [reset] <plugin #>");
}
Handle_t ConVarManager::CreateConVar(IPluginContext *pContext, const char *name, const char *defaultVal, const char *description, int flags, bool hasMin, float min, bool hasMax, float max)
@@ -359,17 +432,10 @@ Handle_t ConVarManager::CreateConVar(IPluginContext *pContext, const char *name,
}
}
/* To prevent creating a convar that has the same name as a console command... ugh */
ConCommandBase *pBase = icvar->GetCommands();
while (pBase)
/* Prevent creating a convar that has the same name as a console command */
if (FindCommand(name))
{
if (pBase->IsCommand() && strcmp(pBase->GetName(), name) == 0)
{
return BAD_HANDLE;
}
pBase = const_cast<ConCommandBase *>(pBase->GetNext());
return BAD_HANDLE;
}
/* Create and initialize ConVarInfo structure */
@@ -524,7 +590,8 @@ void ConVarManager::UnhookConVarChange(ConVar *pConVar, IPluginFunction *pFuncti
}
/* If the forward now has 0 functions in it... */
if (pForward->GetFunctionCount() == 0)
if (pForward->GetFunctionCount() == 0 &&
!ConVarReentrancyGuard::IsCvarInChain(pConVar))
{
/* Free this forward */
g_Forwards.ReleaseForward(pForward);
@@ -535,8 +602,9 @@ void ConVarManager::UnhookConVarChange(ConVar *pConVar, IPluginFunction *pFuncti
QueryCvarCookie_t ConVarManager::QueryClientConVar(edict_t *pPlayer, const char *name, IPluginFunction *pCallback, Handle_t hndl)
{
QueryCvarCookie_t cookie;
QueryCvarCookie_t cookie = 0;
#if SOURCE_ENGINE != SE_DARKMESSIAH
/* Call StartQueryCvarValue() in either the IVEngineServer or IServerPluginHelpers depending on situation */
if (m_bIsDLLQueryHooked)
{
@@ -553,6 +621,7 @@ QueryCvarCookie_t ConVarManager::QueryClientConVar(edict_t *pPlayer, const char
ConVarQuery query = {cookie, pCallback, hndl};
m_ConVarQueries.push_back(query);
#endif
return cookie;
}
@@ -595,7 +664,7 @@ void ConVarManager::AddConVarToPluginList(IPluginContext *pContext, const ConVar
}
}
#if defined ORANGEBOX_BUILD
#if SOURCE_ENGINE >= SE_ORANGEBOX
void ConVarManager::OnConVarChanged(ConVar *pConVar, const char *oldValue, float flOldValue)
#else
void ConVarManager::OnConVarChanged(ConVar *pConVar, const char *oldValue)
@@ -623,7 +692,7 @@ void ConVarManager::OnConVarChanged(ConVar *pConVar, const char *oldValue)
i != pInfo->changeListeners.end();
i++)
{
#if defined ORANGEBOX_BUILD
#if SOURCE_ENGINE >= SE_ORANGEBOX
(*i)->OnConVarChanged(pConVar, oldValue, flOldValue);
#else
(*i)->OnConVarChanged(pConVar, oldValue, atof(oldValue));
@@ -633,6 +702,8 @@ void ConVarManager::OnConVarChanged(ConVar *pConVar, const char *oldValue)
if (pForward != NULL)
{
ConVarReentrancyGuard guard(pConVar);
/* Now call forwards in plugins that have hooked this */
pForward->PushCell(pInfo->handle);
pForward->PushString(oldValue);
@@ -646,6 +717,7 @@ bool ConVarManager::IsQueryingSupported()
return (m_bIsDLLQueryHooked || m_bIsVSPQueryHooked);
}
#if SOURCE_ENGINE != SE_DARKMESSIAH
void ConVarManager::OnQueryCvarValueFinished(QueryCvarCookie_t cookie, edict_t *pPlayer, EQueryCvarValueStatus result, const char *cvarName, const char *cvarValue)
{
IPluginFunction *pCallback = NULL;
@@ -668,7 +740,7 @@ void ConVarManager::OnQueryCvarValueFinished(QueryCvarCookie_t cookie, edict_t *
cell_t ret;
pCallback->PushCell(cookie);
pCallback->PushCell(engine->IndexOfEdict(pPlayer));
pCallback->PushCell(IndexOfEdict(pPlayer));
pCallback->PushCell(result);
pCallback->PushString(cvarName);
@@ -687,6 +759,7 @@ void ConVarManager::OnQueryCvarValueFinished(QueryCvarCookie_t cookie, edict_t *
m_ConVarQueries.erase(iter);
}
}
#endif
HandleError ConVarManager::ReadConVarHandle(Handle_t hndl, ConVar **pVar)
{
+8 -1
View File
@@ -42,6 +42,11 @@
#include <compat_wrappers.h>
#include "concmd_cleaner.h"
#if SOURCE_ENGINE == SE_DARKMESSIAH
class EQueryCvarValueStatus;
typedef int QueryCvarCookie_t;
#endif
using namespace SourceHook;
class IConVarChangeListener
@@ -140,7 +145,7 @@ private:
/**
* Static callback that Valve's ConVar object executes when the convar's value changes.
*/
#if defined ORANGEBOX_BUILD
#if SOURCE_ENGINE >= SE_ORANGEBOX
static void OnConVarChanged(ConVar *pConVar, const char *oldValue, float flOldValue);
#else
static void OnConVarChanged(ConVar *pConVar, const char *oldValue);
@@ -149,8 +154,10 @@ private:
/**
* Callback for when StartQueryCvarValue() has finished.
*/
#if SOURCE_ENGINE != SE_DARKMESSIAH
void OnQueryCvarValueFinished(QueryCvarCookie_t cookie, edict_t *pPlayer, EQueryCvarValueStatus result,
const char *cvarName, const char *cvarValue);
#endif
private:
HandleType_t m_ConVarType;
List<ConVarInfo *> m_ConVars;
+747
View File
@@ -0,0 +1,747 @@
/**
* vim: set ts=4 sw=4 tw=99 noet :
* =============================================================================
* SourceMod
* Copyright (C) 2004-2009 AlliedModders LLC. All rights reserved.
* =============================================================================
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, version 3.0, as published by the
* Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*
* As a special exception, AlliedModders LLC gives you permission to link the
* code of this program (as well as its derivative works) to "Half-Life 2," the
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
* by the Valve Corporation. You must obey the GNU General Public License in
* all respects for all other code used. Additionally, AlliedModders LLC grants
* this exception to all derivative works. AlliedModders LLC defines further
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
* or <http://www.sourcemod.net/license.php>.
*
* Version: $Id$
*/
/**
* On SourceHook v4.3 or lower, there are no DVP hooks. Very sad, right?
* Only do this on newer versions. For the older code, we'll do an incredibly
* hacky detour.
*
* The idea of the "non-hacky" (yeah... no) code is that every unique
* ConCommand vtable gets its own DVP hook. We watch for unloading and
* loading commands to remove stale hooks from SH.
*/
#include "sourcemod.h"
#include "sourcemm_api.h"
#include "Logger.h"
#include "compat_wrappers.h"
#include "ConsoleDetours.h"
#include <IGameConfigs.h>
#include "sm_stringutil.h"
#include "ConCmdManager.h"
#include "HalfLife2.h"
#include "ConCommandBaseIterator.h"
#include "ShareSys.h"
#if defined PLATFORM_POSIX
# include <dlfcn.h>
# include <sys/mman.h>
# include <stdint.h>
# include <unistd.h>
#endif
#if SH_IMPL_VERSION >= 5
# if SOURCE_ENGINE >= SE_ORANGEBOX
SH_DECL_EXTERN1_void(ConCommand, Dispatch, SH_NOATTRIB, false, const CCommand &);
# else
SH_DECL_EXTERN0_void(ConCommand, Dispatch, SH_NOATTRIB, false);
# endif
#else
# if SH_IMPL_VERSION >= 4
extern int __SourceHook_FHVPAddConCommandDispatch(void *,bool,class fastdelegate::FastDelegate0<void>,bool);
extern int __SourceHook_FHAddConCommandDispatch(void *, bool, class fastdelegate::FastDelegate0<void>);
# else
extern bool __SourceHook_FHAddConCommandDispatch(void *, bool, class fastdelegate::FastDelegate0<void>);
# endif
extern bool __SourceHook_FHRemoveConCommandDispatch(void *, bool, class fastdelegate::FastDelegate0<void>);
#endif
#if SH_IMPL_VERSION >= 4
class GenericCommandHooker : public IConCommandLinkListener
{
struct HackInfo
{
void **vtable;
int hook;
unsigned int refcount;
};
CVector<HackInfo> vtables;
bool enabled;
SourceHook::MemFuncInfo dispatch;
inline void **GetVirtualTable(ConCommandBase *pBase)
{
return *reinterpret_cast<void***>(reinterpret_cast<char*>(pBase) +
dispatch.thisptroffs +
dispatch.vtbloffs);
}
inline bool FindVtable(void **ptr, size_t& index)
{
for (size_t i = 0; i < vtables.size(); i++)
{
if (vtables[i].vtable == ptr)
{
index = i;
return true;
}
}
return false;
}
void MakeHookable(ConCommandBase *pBase)
{
if (!pBase->IsCommand())
return;
ConCommand *cmd = (ConCommand*)pBase;
void **vtable = GetVirtualTable(cmd);
size_t index;
if (!FindVtable(vtable, index))
{
HackInfo hack;
hack.vtable = vtable;
hack.hook = SH_ADD_VPHOOK(ConCommand, Dispatch, cmd, SH_MEMBER(this, &GenericCommandHooker::Dispatch), false);
hack.refcount = 1;
vtables.push_back(hack);
}
else
{
vtables[index].refcount++;
}
}
# if SOURCE_ENGINE >= SE_ORANGEBOX
void Dispatch(const CCommand& args)
# else
void Dispatch()
# endif
{
cell_t res = ConsoleDetours::Dispatch(META_IFACEPTR(ConCommand)
# if SOURCE_ENGINE >= SE_ORANGEBOX
, args
# endif
);
if (res >= Pl_Handled)
RETURN_META(MRES_SUPERCEDE);
}
void ReparseCommandList()
{
for (size_t i = 0; i < vtables.size(); i++)
vtables[i].refcount = 0;
for (ConCommandBaseIterator iter; iter.IsValid(); iter.Next())
MakeHookable(iter.Get());
CVector<HackInfo>::iterator iter = vtables.begin();
while (iter != vtables.end())
{
if ((*iter).refcount)
{
iter++;
continue;
}
/* Damn it. This event happens AFTER the plugin has unloaded!
* There's two options. Remove the hook now and hope SH's memory
* protection will prevent a crash. Otherwise, we can wait until
* the server shuts down and more likely crash then.
*
* This situation only arises if:
* 1) Someone has used AddCommandFilter()
* 2) ... on a Dark Messiah server (mm:s new api)
* 3) ... and another MM:S plugin that uses ConCommands has unloaded.
*
* Even though the impact is really small, we'll wait until the
* server shuts down, so normal operation isn't interrupted.
*
* See bug 4018.
*/
iter = vtables.erase(iter);
}
}
void UnhookCommand(ConCommandBase *pBase)
{
if (!pBase->IsCommand())
return;
ConCommand *cmd = (ConCommand*)pBase;
void **vtable = GetVirtualTable(cmd);
size_t index;
if (!FindVtable(vtable, index))
{
g_Logger.LogError("Console detour tried to unhook command \"%s\" but it wasn't found", pBase->GetName());
return;
}
assert(vtables[index].refcount > 0);
vtables[index].refcount--;
if (vtables[index].refcount == 0)
{
SH_REMOVE_HOOK_ID(vtables[index].hook);
vtables.erase(vtables.iterAt(index));
}
}
public:
GenericCommandHooker() : enabled(false)
{
}
bool Enable()
{
SourceHook::GetFuncInfo(&ConCommand::Dispatch, dispatch);
if (dispatch.thisptroffs < 0)
{
g_Logger.LogError("Command filter could not determine ConCommand layout");
return false;
}
for (ConCommandBaseIterator iter; iter.IsValid(); iter.Next())
MakeHookable(iter.Get());
if (!vtables.size())
{
g_Logger.LogError("Command filter could not find any cvars!");
return false;
}
enabled = true;
return true;
}
void Disable()
{
for (size_t i = 0; i < vtables.size(); i++)
SH_REMOVE_HOOK_ID(vtables[i].hook);
vtables.clear();
}
virtual void OnLinkConCommand(ConCommandBase *pBase)
{
if (!enabled)
return;
MakeHookable(pBase);
}
virtual void OnUnlinkConCommand(ConCommandBase *pBase)
{
if (!enabled)
return;
if (pBase == NULL)
ReparseCommandList();
else
UnhookCommand(pBase);
}
};
/**
* END DVP HOOK VERSION
*/
#else /* SH_IMPL_VERSION >= 4 */
/**
* BEGIN ENGINE DETOUR VERSION
*/
# include <jit/jit_helpers.h>
# include <jit/x86/x86_macros.h>
class GenericCommandHooker
{
struct Patch
{
Patch() : applied(false)
{
}
bool applied;
void *base;
unsigned char search[16];
size_t search_len;
size_t offset;
size_t saveat;
int regparam;
void *detour;
};
Patch ces;
Patch cgc;
public:
static void DelayedActivation(void *inparam)
{
GenericCommandHooker *cdtrs = reinterpret_cast<GenericCommandHooker*>(inparam);
/* Safe to re-enter because the frame queue is lock+swapped. */
if ((!cdtrs->ces.applied || !cdtrs->cgc.applied) &&
g_HL2.PeekCommandStack() != NULL)
{
g_SourceMod.AddFrameAction(GenericCommandHooker::DelayedActivation, cdtrs);
return;
}
if (!cdtrs->ces.applied)
cdtrs->ApplyPatch(&cdtrs->ces);
if (!cdtrs->cgc.applied)
cdtrs->ApplyPatch(&cdtrs->cgc);
}
bool Enable()
{
const char *platform = NULL;
# if defined(PLATFORM_WINDOWS)
platform = "Windows";
# else
void *addrInBase = (void *)g_SMAPI->GetEngineFactory(false);
Dl_info info;
if (!dladdr(addrInBase, &info))
{
g_Logger.LogError("Command filter could not find engine name");
return false;
}
if (strstr(info.dli_fname, "engine_i486"))
{
platform = "Linux_486";
}
else if (strstr(info.dli_fname, "engine_i686"))
{
platform = "Linux_686";
}
else if (strstr(info.dli_fname, "engine_amd"))
{
platform = "Linux_AMD";
}
else
{
g_Logger.LogError("Command filter could not determine engine (%s)", info.dli_fname);
return false;
}
# endif
if (!PrepPatch("Cmd_ExecuteString", "CES", platform, &ces))
return false;
if (!PrepPatch("CGameClient::ExecuteString", "CGC", platform, &cgc))
return false;
if (g_HL2.PeekCommandStack() != NULL)
{
g_SourceMod.AddFrameAction(GenericCommandHooker::DelayedActivation, this);
return true;
}
ApplyPatch(&ces);
ApplyPatch(&cgc);
return true;
}
void Disable()
{
UndoPatch(&ces);
UndoPatch(&cgc);
}
private:
# if !defined PLATFORM_WINDOWS
# define PAGE_READWRITE PROT_READ|PROT_WRITE
# define PAGE_EXECUTE_READ PROT_READ|PROT_EXEC
static inline uintptr_t AddrToPage(uintptr_t address)
{
return (address & ~(uintptr_t(sysconf(_SC_PAGE_SIZE) - 1)));
}
# endif
void Protect(void *addr, size_t length, int prot)
{
# if defined PLATFORM_WINDOWS
DWORD ignore;
VirtualProtect(addr, length, prot, &ignore);
# else
uintptr_t startPage = AddrToPage(uintptr_t(addr));
length += (uintptr_t(addr) - startPage);
mprotect((void*)startPage, length, prot);
# endif
}
void UndoPatch(Patch *patch)
{
if (!patch->applied || patch->detour == NULL)
return;
g_pSourcePawn->FreePageMemory(patch->detour);
unsigned char *source = (unsigned char *)patch->base + patch->offset;
Protect(source, patch->search_len, PAGE_READWRITE);
for (size_t i = 0; i < patch->search_len; i++)
source[i] = patch->search[i];
Protect(source, patch->search_len, PAGE_EXECUTE_READ);
}
void ApplyPatch(Patch *patch)
{
assert(!patch->applied);
size_t length = 0;
void *callback = (void*)&ConsoleDetours::Dispatch;
/* Bogus assignment to make compiler is doing the right thing. */
patch->detour = callback;
/* Assemgle the detour. */
JitWriter writer;
writer.outbase = NULL;
writer.outptr = NULL;
do
{
/* Need a specific register, or value on stack? */
if (patch->regparam != -1)
IA32_Push_Reg(&writer, patch->regparam);
/* Call real function. */
IA32_Write_Jump32_Abs(&writer, IA32_Call_Imm32(&writer, 0), callback);
/* Restore stack. */
if (patch->regparam != -1)
IA32_Pop_Reg(&writer, patch->regparam);
/* Copy any saved bytes */
if (patch->saveat)
{
for (size_t i = patch->saveat; i < patch->search_len; i++)
{
writer.write_ubyte(patch->search[i]);
}
}
/* Jump back to the caller. */
unsigned char *target = (unsigned char *)patch->base + patch->offset + patch->search_len;
IA32_Jump_Imm32_Abs(&writer, target);
/* Assemble, if we can. */
if (writer.outbase == NULL)
{
length = writer.outptr - writer.outbase;
patch->detour = g_pSourcePawn->AllocatePageMemory(length);
if (patch->detour == NULL)
{
g_Logger.LogError("Ran out of memory!");
return;
}
g_pSourcePawn->SetReadWrite(patch->detour);
writer.outbase = (jitcode_t)patch->detour;
writer.outptr = writer.outbase;
}
else
{
break;
}
} while (true);
g_pSourcePawn->SetReadExecute(patch->detour);
unsigned char *source = (unsigned char *)patch->base + patch->offset;
Protect(source, 6, PAGE_READWRITE);
source[0] = 0xFF;
source[1] = 0x25;
*(void **)&source[2] = &patch->detour;
Protect(source, 6, PAGE_EXECUTE_READ);
patch->applied = true;
}
bool PrepPatch(const char *signature, const char *name, const char *platform, Patch *patch)
{
/* Get the base address of the function. */
if (!g_pGameConf->GetMemSig(signature, &patch->base) || patch->base == NULL)
{
g_Logger.LogError("Command filter could not find signature: %s", signature);
return false;
}
const char *value;
char keyname[255];
/* Get the verification bytes that will be written over. */
UTIL_Format(keyname, sizeof(keyname), "%s_Patch_%s", name, platform);
if ((value = g_pGameConf->GetKeyValue(keyname)) == NULL)
{
g_Logger.LogError("Command filter could not find key: %s", keyname);
return false;
}
patch->search_len = UTIL_DecodeHexString(patch->search, sizeof(patch->search), value);
if (patch->search_len < 6)
{
g_Logger.LogError("Error decoding %s value, or not long enough", keyname);
return false;
}
/* Get the offset into the function. */
UTIL_Format(keyname, sizeof(keyname), "%s_Offset_%s", name, platform);
if ((value = g_pGameConf->GetKeyValue(keyname)) == NULL)
{
g_Logger.LogError("Command filter could not find key: %s", keyname);
return false;
}
patch->offset = atoi(value);
if (patch->offset > 20000)
{
g_Logger.LogError("Command filter %s value is bogus", keyname);
return false;
}
/* Get the number of bytes to save from what was written over. */
patch->saveat = 0;
UTIL_Format(keyname, sizeof(keyname), "%s_Save_%s", name, platform);
if ((value = g_pGameConf->GetKeyValue(keyname)) != NULL)
{
patch->saveat = atoi(value);
if (patch->saveat >= patch->search_len)
{
g_Logger.LogError("Command filter %s value is too large", keyname);
return false;
}
}
/* Get register for parameter, if any. */
patch->regparam = -1;
UTIL_Format(keyname, sizeof(keyname), "%s_Reg_%s", name, platform);
if ((value = g_pGameConf->GetKeyValue(keyname)) != NULL)
{
patch->regparam = atoi(value);
}
/* Everything loaded from gamedata, make sure the patch will succeed. */
unsigned char *address = (unsigned char *)patch->base + patch->offset;
for (size_t i = 0; i < patch->search_len; i++)
{
if (address[i] != patch->search[i])
{
g_Logger.LogError("Command filter %s has changed (byte %x is not %x sub-offset %d)",
name, address[i], patch->search[i], i);
return false;
}
}
return true;
}
};
static bool dummy_hook_set = false;
void DummyHook()
{
if (dummy_hook_set)
{
dummy_hook_set = false;
RETURN_META(MRES_SUPERCEDE);
}
}
#endif
/**
* BEGIN THE ACTUALLY GENERIC CODE.
*/
#define FEATURECAP_COMMANDLISTENER "command listener"
static GenericCommandHooker s_GenericHooker;
ConsoleDetours g_ConsoleDetours;
ConsoleDetours::ConsoleDetours() : status(FeatureStatus_Unknown)
{
}
void ConsoleDetours::OnSourceModAllInitialized()
{
m_pForward = g_Forwards.CreateForwardEx("OnAnyCommand", ET_Hook, 3, NULL, Param_Cell,
Param_String, Param_Cell);
g_ShareSys.AddCapabilityProvider(NULL, this, FEATURECAP_COMMANDLISTENER);
}
void ConsoleDetours::OnSourceModShutdown()
{
List<Listener*>::iterator iter = m_Listeners.begin();
while (iter != m_Listeners.end())
{
Listener *listener = (*iter);
g_Forwards.ReleaseForward(listener->forward);
delete listener;
iter = m_Listeners.erase(iter);
}
g_Forwards.ReleaseForward(m_pForward);
s_GenericHooker.Disable();
}
FeatureStatus ConsoleDetours::GetFeatureStatus(FeatureType type, const char *name)
{
return GetStatus();
}
FeatureStatus ConsoleDetours::GetStatus()
{
if (status == FeatureStatus_Unknown)
{
status = s_GenericHooker.Enable() ? FeatureStatus_Available : FeatureStatus_Unavailable;
}
return status;
}
bool ConsoleDetours::AddListener(IPluginFunction *fun, const char *command)
{
if (GetStatus() != FeatureStatus_Available)
return false;
if (command == NULL)
{
m_pForward->AddFunction(fun);
}
else
{
const char *str = UTIL_ToLowerCase(command);
Listener *listener;
Listener **plistener = m_CmdLookup.retrieve(str);
if (plistener == NULL)
{
listener = new Listener;
listener->forward = g_Forwards.CreateForwardEx(NULL, ET_Hook, 3, NULL, Param_Cell,
Param_String, Param_Cell);
m_CmdLookup.insert(str, listener);
}
else
{
listener = *plistener;
}
listener->forward->AddFunction(fun);
delete [] str;
}
return true;
}
bool ConsoleDetours::RemoveListener(IPluginFunction *fun, const char *command)
{
if (command == NULL)
{
return m_pForward->RemoveFunction(fun);
}
else
{
const char *str = UTIL_ToLowerCase(command);
Listener *listener;
Listener **plistener = m_CmdLookup.retrieve(str);
delete [] str;
if (plistener == NULL)
return false;
listener = *plistener;
return listener->forward->RemoveFunction(fun);
}
}
cell_t ConsoleDetours::InternalDispatch(int client, const CCommand& args)
{
char name[255];
const char *realname = args.Arg(0);
size_t len = strlen(realname);
// Disallow command strings that are too long, for now.
if (len >= sizeof(name) - 1)
return Pl_Continue;
for (size_t i = 0; i < len; i++)
{
if (realname[i] >= 'A' && realname[i] <= 'Z')
name[i] = tolower(realname[i]);
else
name[i] = realname[i];
}
name[len] = '\0';
cell_t result = Pl_Continue;
m_pForward->PushCell(client);
m_pForward->PushString(name);
m_pForward->PushCell(args.ArgC() - 1);
m_pForward->Execute(&result, NULL);
/* Don't let plugins block this. */
if (strcmp(name, "sm") == 0)
result = Pl_Continue;
if (result >= Pl_Stop)
return result;
Listener **plistener = m_CmdLookup.retrieve(name);
if (plistener == NULL)
return result;
Listener *listener = *plistener;
if (listener->forward->GetFunctionCount() == 0)
return result;
cell_t result2 = Pl_Continue;
listener->forward->PushCell(client);
listener->forward->PushString(name);
listener->forward->PushCell(args.ArgC() - 1);
listener->forward->Execute(&result2, NULL);
if (result2 > result)
result = result2;
/* "sm" should not have flown through the above. */
assert(strcmp(name, "sm") != 0 || result == Pl_Continue);
return result;
}
#if SOURCE_ENGINE >= SE_ORANGEBOX
cell_t ConsoleDetours::Dispatch(ConCommand *pBase, const CCommand& args)
{
#else
cell_t ConsoleDetours::Dispatch(ConCommand *pBase)
{
CCommand args;
#endif
g_HL2.PushCommandStack(&args);
cell_t res = g_ConsoleDetours.InternalDispatch(g_ConCmds.GetCommandClient(), args);
g_HL2.PopCommandStack();
#if SH_IMPL_VERSION < 4
if (res >= Pl_Handled)
{
/* See bug 4020 - we can't optimize this because looking at the vtable
* is probably more expensive, since there's no SH_GET_ORIG_VFNPTR_ENTRY.
*/
SH_ADD_HOOK_STATICFUNC(ConCommand, Dispatch, pBase, DummyHook, false);
dummy_hook_set = true;
pBase->Dispatch();
SH_REMOVE_HOOK_STATICFUNC(ConCommand, Dispatch, pBase, DummyHook, false);
}
else
{
/* Make sure the command gets invoked. See bug 4019 on making this better. */
pBase->Dispatch();
}
#endif
return res;
}
+83
View File
@@ -0,0 +1,83 @@
/**
* vim: set ts=4 sw=4 tw=99 noet :
* =============================================================================
* SourceMod
* Copyright (C) 2004-2009 AlliedModders LLC. All rights reserved.
* =============================================================================
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, version 3.0, as published by the
* Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*
* As a special exception, AlliedModders LLC gives you permission to link the
* code of this program (as well as its derivative works) to "Half-Life 2," the
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
* by the Valve Corporation. You must obey the GNU General Public License in
* all respects for all other code used. Additionally, AlliedModders LLC grants
* this exception to all derivative works. AlliedModders LLC defines further
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
* or <http://www.sourcemod.net/license.php>.
*
* Version: $Id$
*/
#ifndef _INCLUDE_SOURCEMOD_CONSOLE_DETOURS_H_
#define _INCLUDE_SOURCEMOD_CONSOLE_DETOURS_H_
#include "sm_globals.h"
#include "sourcemm_api.h"
#include "ForwardSys.h"
#include <sm_trie_tpl.h>
class ConsoleDetours :
public SMGlobalClass,
public IFeatureProvider
{
friend class PlayerManager;
friend class GenericCommandHooker;
struct Listener
{
IChangeableForward *forward;
};
public:
ConsoleDetours();
public: //SMGlobalClass
void OnSourceModAllInitialized();
void OnSourceModShutdown();
public: //IFeatureProvider
FeatureStatus GetFeatureStatus(FeatureType type, const char *name);
public:
bool AddListener(IPluginFunction *fun, const char *command);
bool RemoveListener(IPluginFunction *fun, const char *command);
private:
cell_t InternalDispatch(int client, const CCommand& args);
#if SOURCE_ENGINE >= SE_ORANGEBOX
static cell_t Dispatch(ConCommand *pBase, const CCommand& args);
#else
static cell_t Dispatch(ConCommand *pBase);
#endif
public:
FeatureStatus GetStatus();
bool IsEnabled()
{
return status == FeatureStatus_Available;
}
private:
FeatureStatus status;
IChangeableForward *m_pForward;
KTrie<Listener*> m_CmdLookup;
List<Listener*> m_Listeners;
};
extern ConsoleDetours g_ConsoleDetours;
#endif /* _INCLUDE_SOURCEMOD_CONSOLE_DETOURS_H_ */
+59 -31
View File
@@ -34,7 +34,7 @@
#include "sourcemod.h"
#include "sourcemm_api.h"
#include "sm_srvcmds.h"
#include "sm_version.h"
#include <sourcemod_version.h>
#include "sm_stringutil.h"
#include "LibrarySys.h"
#include "Logger.h"
@@ -61,30 +61,35 @@ ConVar *g_ServerCfgFile = NULL;
void CheckAndFinalizeConfigs();
#if defined ORANGEBOX_BUILD
#if SOURCE_ENGINE >= SE_ORANGEBOX
SH_DECL_EXTERN1_void(ConCommand, Dispatch, SH_NOATTRIB, false, const CCommand &);
void Hook_ExecDispatchPre(const CCommand &cmd)
#elif SOURCE_ENGINE == SE_DARKMESSIAH
SH_DECL_EXTERN0_void(ConCommand, Dispatch, SH_NOATTRIB, false);
void Hook_ExecDispatchPre()
#else
extern bool __SourceHook_FHAddConCommandDispatch(void *,bool,class fastdelegate::FastDelegate0<void>);
# if SH_IMPL_VERSION >= 4
extern int __SourceHook_FHAddConCommandDispatch(void *,bool,class fastdelegate::FastDelegate0<void>);
# else
extern bool __SourceHook_FHAddConCommandDispatch(void *,bool,class fastdelegate::FastDelegate0<void>);
# endif
extern bool __SourceHook_FHRemoveConCommandDispatch(void *,bool,class fastdelegate::FastDelegate0<void>);
void Hook_ExecDispatchPre()
#endif
{
#if !defined ORANGEBOX_BUILD
#if SOURCE_ENGINE <= SE_DARKMESSIAH
CCommand cmd;
#endif
const char *arg = cmd.Arg(1);
if (!g_bServerExecd
&& arg != NULL
&& strcmp(arg, g_ServerCfgFile->GetString()) == 0)
if (!g_bServerExecd && arg != NULL && strcmp(arg, g_ServerCfgFile->GetString()) == 0)
{
g_bGotTrigger = true;
}
}
#if defined ORANGEBOX_BUILD
#if SOURCE_ENGINE >= SE_ORANGEBOX
void Hook_ExecDispatchPost(const CCommand &cmd)
#else
void Hook_ExecDispatchPost()
@@ -100,14 +105,9 @@ void Hook_ExecDispatchPost()
void CheckAndFinalizeConfigs()
{
if ((g_bServerExecd || g_ServerCfgFile == NULL)
&& g_bGotServerStart)
if ((g_bServerExecd || g_ServerCfgFile == NULL) && g_bGotServerStart)
{
#if defined ORANGEBOX_BUILD
g_PendingInternalPush = true;
#else
SM_InternalCmdTrigger();
#endif
}
}
@@ -119,6 +119,14 @@ void CoreConfig::OnSourceModAllInitialized()
g_pOnAutoConfigsBuffered = g_Forwards.CreateForward("OnAutoConfigsBuffered", ET_Ignore, 0, NULL);
}
CoreConfig::CoreConfig() : m_Strings(512)
{
}
CoreConfig::~CoreConfig()
{
}
void CoreConfig::OnSourceModShutdown()
{
g_RootMenu.RemoveRootConsoleCommand("config", this);
@@ -151,17 +159,7 @@ void CoreConfig::OnSourceModLevelChange(const char *mapName)
if (g_ServerCfgFile != NULL)
{
ConCommandBase *pBase = icvar->GetCommands();
while (pBase != NULL)
{
if (pBase->IsCommand() && strcmp(pBase->GetName(), "exec") == 0)
{
break;
}
pBase = const_cast<ConCommandBase *>(pBase->GetNext());
}
g_pExecPtr = (ConCommand *)pBase;
g_pExecPtr = FindCommand("exec");
if (g_pExecPtr != NULL)
{
SH_ADD_HOOK_STATICFUNC(ConCommand, Dispatch, g_pExecPtr, Hook_ExecDispatchPre, false);
@@ -216,14 +214,32 @@ void CoreConfig::Initialize()
/* Try to get command line value of core config convar */
const char *corecfg = icvar->GetCommandLineValue("sm_corecfgfile");
/* If sm_corecfgfile not specified on command line, use default value */
if (!corecfg)
/* If sm_corecfgfile is on the command line, use that
* If sm_corecfgfile isn't there, check sm_basepath on the command line and build the path off that
* If sm_basepath isn't there, just use the default path for the cfg
*/
if (corecfg)
{
corecfg = sm_corecfgfile.GetDefault();
g_LibSys.PathFormat(filePath, sizeof(filePath), "%s/%s", g_SourceMod.GetGamePath(), corecfg);
}
else
{
const char *basepath = icvar->GetCommandLineValue("sm_basepath");
/* Format path to config file */
if (basepath)
{
g_LibSys.PathFormat(filePath, sizeof(filePath), "%s/%s/%s", g_SourceMod.GetGamePath(), basepath, "configs/core.cfg");
}
else
{
g_LibSys.PathFormat(filePath, sizeof(filePath), "%s/%s", g_SourceMod.GetGamePath(), sm_corecfgfile.GetDefault());
}
}
/* Format path to config file */
g_LibSys.PathFormat(filePath, sizeof(filePath), "%s/%s", g_SourceMod.GetGamePath(), corecfg);
/* Reset cached key values */
m_KeyValues.clear();
m_Strings.Reset();
/* Parse config file */
if ((err=textparsers->ParseFile_SMC(filePath, this, NULL)) != SMCError_Okay)
@@ -263,9 +279,21 @@ ConfigResult CoreConfig::SetConfigOption(const char *option, const char *value,
pBase = pBase->m_pGlobalClassNext;
}
m_KeyValues.replace(option, m_Strings.AddString(value));
return ConfigResult_Ignore;
}
const char *CoreConfig::GetCoreConfigValue(const char *key)
{
int *pKey = m_KeyValues.retrieve(key);
if (pKey == NULL)
{
return NULL;
}
return m_Strings.GetString(*pKey);
}
bool SM_AreConfigsExecuted()
{
return g_bConfigsExecd;
@@ -367,7 +395,7 @@ bool SM_ExecuteConfig(CPlugin *pl, AutoConfig *cfg, bool can_create)
FILE *fp = fopen(file, "wt");
if (fp)
{
fprintf(fp, "// This file was auto-generated by SourceMod (v%s)\n", SVN_FULL_VERSION);
fprintf(fp, "// This file was auto-generated by SourceMod (v%s)\n", SM_FULL_VERSION);
fprintf(fp, "// ConVars for plugin \"%s\"\n", pl->GetFilename());
fprintf(fp, "\n\n");
+9
View File
@@ -35,6 +35,8 @@
#include "sm_globals.h"
#include <ITextParsers.h>
#include <IRootConsoleMenu.h>
#include <sm_trie_tpl.h>
#include "sm_memtable.h"
using namespace SourceMod;
@@ -43,6 +45,9 @@ class CoreConfig :
public ITextListener_SMC,
public IRootConsoleCommand
{
public:
CoreConfig();
~CoreConfig();
public: // SMGlobalClass
void OnSourceModAllInitialized();
void OnSourceModShutdown();
@@ -56,11 +61,15 @@ public:
* Initializes CoreConfig by reading from core.cfg file
*/
void Initialize();
const char *GetCoreConfigValue(const char *key);
private:
/**
* Sets configuration option by notifying SourceMod components that rely on core.cfg
*/
ConfigResult SetConfigOption(const char *option, const char *value, ConfigSource, char *Error, size_t maxlength);
private:
BaseStringTable m_Strings;
KTrie<int> m_KeyValues;
};
extern bool SM_AreConfigsExecuted();
+41 -32
View File
@@ -37,7 +37,7 @@
#include "Logger.h"
#include "ExtensionSys.h"
#include <stdlib.h>
#include "ThreadSupport.h"
#include <IThreader.h>
#define DBPARSE_LEVEL_NONE 0
#define DBPARSE_LEVEL_MAIN 1
@@ -47,7 +47,7 @@ DBManager g_DBMan;
static bool s_OneTimeThreaderErrorMsg = false;
DBManager::DBManager()
: m_StrTab(512), m_ParseLevel(0), m_ParseState(0), m_pDefault(NULL)
: m_ParseLevel(0), m_ParseState(0), m_pDefault(NULL)
{
}
@@ -104,6 +104,7 @@ void DBManager::OnSourceModShutdown()
m_pQueueLock->DestroyThis();
g_HandleSys.RemoveType(m_DatabaseType, g_pCoreIdent);
g_HandleSys.RemoveType(m_DriverType, g_pCoreIdent);
ClearConfigs();
}
unsigned int DBManager::GetInterfaceVersion()
@@ -133,13 +134,20 @@ void DBManager::OnHandleDestroy(HandleType_t type, void *object)
void DBManager::ReadSMC_ParseStart()
{
m_confs.clear();
ClearConfigs();
m_ParseLevel = 0;
m_ParseState = DBPARSE_LEVEL_NONE;
m_StrTab.Reset();
m_DefDriver.clear();
}
void DBManager::ClearConfigs()
{
List<ConfDbInfo *>::iterator iter;
for (iter=m_confs.begin(); iter!=m_confs.end(); iter++)
delete (*iter);
m_confs.clear();
}
ConfDbInfo s_CurInfo;
SMCResult DBManager::ReadSMC_NewSection(const SMCStates *states, const char *name)
{
@@ -159,7 +167,7 @@ SMCResult DBManager::ReadSMC_NewSection(const SMCStates *states, const char *nam
}
} else if (m_ParseState == DBPARSE_LEVEL_MAIN) {
s_CurInfo = ConfDbInfo();
s_CurInfo.name = m_StrTab.AddString(name);
s_CurInfo.name = name;
m_ParseState = DBPARSE_LEVEL_DATABASE;
} else if (m_ParseState == DBPARSE_LEVEL_DATABASE) {
m_ParseLevel++;
@@ -186,16 +194,16 @@ SMCResult DBManager::ReadSMC_KeyValue(const SMCStates *states, const char *key,
{
if (strcmp(value, "default") != 0)
{
s_CurInfo.driver = m_StrTab.AddString(value);
s_CurInfo.driver = value;
}
} else if (strcmp(key, "database") == 0) {
s_CurInfo.database = m_StrTab.AddString(value);
s_CurInfo.database = value;
} else if (strcmp(key, "host") == 0) {
s_CurInfo.host = m_StrTab.AddString(value);
s_CurInfo.host = value;
} else if (strcmp(key, "user") == 0) {
s_CurInfo.user = m_StrTab.AddString(value);
s_CurInfo.user = value;
} else if (strcmp(key, "pass") == 0) {
s_CurInfo.pass = m_StrTab.AddString(value);
s_CurInfo.pass = value;
} else if (strcmp(key, "timeout") == 0) {
s_CurInfo.info.maxTimeout = atoi(value);
} else if (strcmp(key, "port") == 0) {
@@ -206,13 +214,6 @@ SMCResult DBManager::ReadSMC_KeyValue(const SMCStates *states, const char *key,
return SMCResult_Continue;
}
#define ASSIGN_VAR(var) \
if (s_CurInfo.var == -1) { \
s_CurInfo.info.var = ""; \
} else { \
s_CurInfo.info.var = m_StrTab.GetString(s_CurInfo.var); \
}
SMCResult DBManager::ReadSMC_LeavingSection(const SMCStates *states)
{
if (m_ParseLevel)
@@ -223,17 +224,26 @@ SMCResult DBManager::ReadSMC_LeavingSection(const SMCStates *states)
if (m_ParseState == DBPARSE_LEVEL_DATABASE)
{
/* Set all of the info members to either a blank string
* or the string pointer from the string table.
*/
ASSIGN_VAR(driver);
ASSIGN_VAR(database);
ASSIGN_VAR(host);
ASSIGN_VAR(user);
ASSIGN_VAR(pass);
ConfDbInfo *cdb = new ConfDbInfo();
cdb->name = s_CurInfo.name;
cdb->driver = s_CurInfo.driver;
cdb->host = s_CurInfo.host;
cdb->user = s_CurInfo.user;
cdb->pass = s_CurInfo.pass;
cdb->database = s_CurInfo.database;
cdb->realDriver = s_CurInfo.realDriver;
cdb->info.maxTimeout = s_CurInfo.info.maxTimeout;
cdb->info.port = s_CurInfo.info.port;
cdb->info.driver = cdb->driver.c_str();
cdb->info.database = cdb->database.c_str();
cdb->info.host = cdb->host.c_str();
cdb->info.user = cdb->user.c_str();
cdb->info.pass = cdb->pass.c_str();
/* Save it.. */
m_confs.push_back(s_CurInfo);
m_confs.push_back(cdb);
/* Go up one level */
m_ParseState = DBPARSE_LEVEL_MAIN;
@@ -244,7 +254,6 @@ SMCResult DBManager::ReadSMC_LeavingSection(const SMCStates *states)
return SMCResult_Continue;
}
#undef ASSIGN_VAR
void DBManager::ReadSMC_ParseEnd(bool halted, bool failed)
{
@@ -333,10 +342,10 @@ void DBManager::RemoveDriver(IDBDriver *pDriver)
}
/* Make sure NOTHING references this! */
List<ConfDbInfo>::iterator iter;
List<ConfDbInfo *>::iterator iter;
for (iter=m_confs.begin(); iter!=m_confs.end(); iter++)
{
ConfDbInfo &db = (*iter);
ConfDbInfo &db = *(*iter);
if (db.realDriver == pDriver)
{
db.realDriver = NULL;
@@ -448,12 +457,12 @@ const DatabaseInfo *DBManager::FindDatabaseConf(const char *name)
ConfDbInfo *DBManager::GetDatabaseConf(const char *name)
{
List<ConfDbInfo>::iterator iter;
List<ConfDbInfo *>::iterator iter;
for (iter=m_confs.begin(); iter!=m_confs.end(); iter++)
{
ConfDbInfo &conf = (*iter);
if (strcmp(m_StrTab.GetString(conf.name), name) == 0)
ConfDbInfo &conf = *(*iter);
if (conf.name == name)
{
return &conf;
}
+9 -10
View File
@@ -47,16 +47,15 @@ using namespace SourceHook;
struct ConfDbInfo
{
ConfDbInfo() : name(-1), driver(-1), host(-1), user(-1), pass(-1),
database(-1), realDriver(NULL)
ConfDbInfo() : realDriver(NULL)
{
}
int name;
int driver;
int host;
int user;
int pass;
int database;
String name;
String driver;
String host;
String user;
String pass;
String database;
IDBDriver *realDriver;
DatabaseInfo info;
};
@@ -121,6 +120,7 @@ public:
return m_DatabaseType;
}
private:
void ClearConfigs();
void KillWorkerThread();
private:
CVector<IDBDriver *> m_drivers;
@@ -134,11 +134,10 @@ private:
IMutex *m_pQueueLock; /* Queue safety lock */
IMutex *m_pThinkLock; /* Think-queue lock */
List<ConfDbInfo> m_confs;
List<ConfDbInfo *> m_confs;
HandleType_t m_DriverType;
HandleType_t m_DatabaseType;
String m_DefDriver;
BaseStringTable m_StrTab;
char m_Filename[PLATFORM_MAX_PATH];
unsigned int m_ParseLevel;
unsigned int m_ParseState;
+7 -2
View File
@@ -56,11 +56,16 @@ void DebugReport::OnDebugSpew(const char *msg, ...)
void DebugReport::GenerateError(IPluginContext *ctx, cell_t func_idx, int err, const char *message, ...)
{
va_list ap;
char buffer[512];
va_start(ap, message);
UTIL_FormatArgs(buffer, sizeof(buffer), message, ap);
GenerateErrorVA(ctx, func_idx, err, message, ap);
va_end(ap);
}
void DebugReport::GenerateErrorVA(IPluginContext *ctx, cell_t func_idx, int err, const char *message, va_list ap)
{
char buffer[512];
UTIL_FormatArgs(buffer, sizeof(buffer), message, ap);
const char *plname = g_PluginSys.FindPluginByContext(ctx->GetContext())->GetFilename();
const char *error = g_pSourcePawn2->GetErrorString(err);
+1
View File
@@ -46,6 +46,7 @@ public: // IDebugListener
void OnDebugSpew(const char *msg, ...);
public:
void GenerateError(IPluginContext *ctx, cell_t func_idx, int err, const char *message, ...);
void GenerateErrorVA(IPluginContext *ctx, cell_t func_idx, int err, const char *message, va_list ap);
void GenerateCodeError(IPluginContext *ctx, uint32_t code_addr, int err, const char *message, ...);
private:
int _GetPluginIndex(IPluginContext *ctx);
+39 -6
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-2010 AlliedModders LLC. All rights reserved.
* =============================================================================
*
* This program is free software; you can redistribute it and/or modify it under
@@ -42,6 +42,20 @@ SH_DECL_HOOK2(IGameEventManager2, FireEvent, SH_NOATTRIB, 0, bool, IGameEvent *,
const ParamType GAMEEVENT_PARAMS[] = {Param_Cell, Param_String, Param_Cell};
typedef List<EventHook *> EventHookList;
class EventForwardFilter : public IForwardFilter
{
EventInfo *pEventInfo;
public:
EventForwardFilter(EventInfo *pEventInfo) : pEventInfo(pEventInfo)
{
}
void Preprocess(IPluginFunction *fun, FwdParamInfo *params)
{
params[2].val = pEventInfo->bDontBroadcast ? 1 : 0;
}
};
EventManager::EventManager() : m_EventType(0)
{
/* Create an event lookup trie */
@@ -147,6 +161,13 @@ 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
int EventManager::GetEventDebugID()
{
return EVENT_DEBUG_ID_INIT;
}
#endif
EventHookError EventManager::HookEvent(const char *name, IPluginFunction *pFunction, EventHookMode mode)
{
EventHook *pHook;
@@ -194,7 +215,7 @@ EventHookError EventManager::HookEvent(const char *name, IPluginFunction *pFunct
}
/* Cache the name for post hooks */
pHook->name = strdup(name);
pHook->name = sm_strdup(name);
/* Increase reference count */
pHook->refCount++;
@@ -300,7 +321,7 @@ EventHookError EventManager::UnhookEvent(const char *name, IPluginFunction *pFun
sm_trie_delete(m_EventHooks, name);
/* Free the cached name */
free(pHook->name);
delete pHook->name;
/* And finally free structure memory */
delete pHook;
@@ -327,6 +348,7 @@ EventInfo *EventManager::CreateEvent(IPluginContext *pContext, const char *name,
pInfo->pEvent = pEvent;
pInfo->pOwner = pContext->GetIdentity();
pInfo->bDontBroadcast = false;
return pInfo;
}
@@ -365,6 +387,7 @@ bool EventManager::OnFireEvent(IGameEvent *pEvent, bool bDontBroadcast)
IChangeableForward *pForward;
const char *name;
cell_t res = Pl_Continue;
bool broadcast = bDontBroadcast;
/* The engine accepts NULL without crashing, so to prevent a crash in SM we ignore these */
if (!pEvent)
@@ -390,10 +413,16 @@ bool EventManager::OnFireEvent(IGameEvent *pEvent, bool bDontBroadcast)
HandleSecurity sec(NULL, g_pCoreIdent);
Handle_t hndl = g_HandleSys.CreateHandle(m_EventType, &info, NULL, g_pCoreIdent, NULL);
info.bDontBroadcast = bDontBroadcast;
EventForwardFilter filter(&info);
pForward->PushCell(hndl);
pForward->PushString(name);
pForward->PushCell(bDontBroadcast);
pForward->Execute(&res, NULL);
pForward->Execute(&res, &filter);
broadcast = info.bDontBroadcast;
g_HandleSys.FreeHandle(hndl, &sec);
}
@@ -414,6 +443,9 @@ bool EventManager::OnFireEvent(IGameEvent *pEvent, bool bDontBroadcast)
m_EventStack.push(NULL);
}
if (broadcast != bDontBroadcast)
RETURN_META_VALUE_NEWPARAMS(MRES_IGNORED, true, &IGameEventManager2::FireEvent, (pEvent, broadcast));
RETURN_META_VALUE(MRES_IGNORED, true);
}
@@ -441,6 +473,7 @@ bool EventManager::OnFireEvent_Post(IGameEvent *pEvent, bool bDontBroadcast)
{
if (pHook->postCopy)
{
info.bDontBroadcast = bDontBroadcast;
info.pEvent = m_EventCopies.front();
info.pOwner = NULL;
hndl = g_HandleSys.CreateHandle(m_EventType, &info, NULL, g_pCoreIdent, NULL);
@@ -472,7 +505,7 @@ bool EventManager::OnFireEvent_Post(IGameEvent *pEvent, bool bDontBroadcast)
assert(pHook->pPostHook == NULL);
assert(pHook->pPreHook == NULL);
sm_trie_delete(m_EventHooks, pHook->name);
free(pHook->name);
delete pHook->name;
delete pHook;
}
}
+5 -1
View File
@@ -2,7 +2,7 @@
* vim: set ts=4 :
* =============================================================================
* SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
* Copyright (C) 2004-2010 AlliedModders LLC. All rights reserved.
* =============================================================================
*
* This program is free software; you can redistribute it and/or modify it under
@@ -53,6 +53,7 @@ struct EventInfo
}
IGameEvent *pEvent;
IdentityToken_t *pOwner;
bool bDontBroadcast;
};
struct EventHook
@@ -104,6 +105,9 @@ public: // IPluginsListener
void OnPluginUnloaded(IPlugin *plugin);
public: // IGameEventListener2
void FireGameEvent(IGameEvent *pEvent);
#if SOURCE_ENGINE >= SE_LEFT4DEAD
int GetEventDebugID();
#endif
public:
/**
* Get the 'GameEvent' handle type ID.
+219 -37
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-2010 AlliedModders LLC. All rights reserved.
* =============================================================================
*
* This program is free software; you can redistribute it and/or modify it under
@@ -49,6 +49,9 @@ void CExtension::Initialize(const char *filename, const char *path)
m_bFullyLoaded = false;
m_File.assign(filename);
m_Path.assign(path);
char real_name[PLATFORM_MAX_PATH];
g_LibSys.GetFileFromPath(real_name, sizeof(real_name), m_Path.c_str());
m_RealFile.assign(real_name);
}
CRemoteExtension::CRemoteExtension(IExtensionInterface *pAPI, const char *filename, const char *path)
@@ -57,6 +60,30 @@ CRemoteExtension::CRemoteExtension(IExtensionInterface *pAPI, const char *filena
m_pAPI = pAPI;
}
#if defined METAMOD_PLAPI_VERSION
#if SOURCE_ENGINE == SE_LEFT4DEAD
#define GAMEFIX "2.l4d"
#elif SOURCE_ENGINE == SE_LEFT4DEAD2
#define GAMEFIX "2.l4d2"
#elif SOURCE_ENGINE == SE_ALIENSWARM
#define GAMEFIX "2.swarm"
#elif SOURCE_ENGINE == SE_ORANGEBOX
#define GAMEFIX "2.ep2"
#elif SOURCE_ENGINE == SE_BLOODYGOODTIME
#define GAMEFIX "2.bgt"
#elif SOURCE_ENGINE == SE_EYE
#define GAMEFIX "2.eye"
#elif SOURCE_ENGINE == SE_ORANGEBOXVALVE
#define GAMEFIX "2.ep2v"
#elif SOURCE_ENGINE == SE_DARKMESSIAH
#define GAMEFIX "2.darkm"
#else
#define GAMEFIX "2.ep1"
#endif //(SOURCE_ENGINE == SE_LEFT4DEAD) || (SOURCE_ENGINE == SE_LEFT4DEAD2)
#else //METAMOD_PLAPI_VERSION
#define GAMEFIX "1.ep1"
#endif //METAMOD_PLAPI_VERSION
CLocalExtension::CLocalExtension(const char *filename)
{
m_PlId = 0;
@@ -64,27 +91,43 @@ CLocalExtension::CLocalExtension(const char *filename)
char path[PLATFORM_MAX_PATH];
/* Special case for new bintools binary */
if (strcmp(filename, "bintools.ext") == 0)
{
goto normal;
}
/* Zeroth, see if there is an engine specific build in the new place. */
g_SourceMod.BuildPath(Path_SM,
path,
PLATFORM_MAX_PATH,
"extensions/%s." GAMEFIX "." PLATFORM_LIB_EXT,
filename);
if (g_LibSys.IsPathFile(path))
{
goto found;
}
/* First see if there is an engine specific build! */
g_SourceMod.BuildPath(Path_SM,
path,
PLATFORM_MAX_PATH,
#if defined METAMOD_PLAPI_VERSION
#if defined ORANGEBOX_BUILD
"extensions/auto.2.ep2/%s",
#else
"extensions/auto.2.ep1/%s",
#endif //ORANGEBOX_BUILD
#else //METAMOD_PLAPI_VERSION
"extensions/auto.1.ep1/%s",
#endif //METAMOD_PLAPI_VERSION
PLATFORM_MAX_PATH,
"extensions/auto." GAMEFIX "/%s." PLATFORM_LIB_EXT,
filename);
normal:
/* Try the "normal" version */
if (!g_LibSys.IsPathFile(path))
{
g_SourceMod.BuildPath(Path_SM, path, PLATFORM_MAX_PATH, "extensions/%s", filename);
g_SourceMod.BuildPath(Path_SM,
path,
PLATFORM_MAX_PATH,
"extensions/%s." PLATFORM_LIB_EXT,
filename);
}
found:
Initialize(filename, path);
}
@@ -141,6 +184,28 @@ bool CLocalExtension::Load(char *error, size_t maxlength)
{
bool already;
m_PlId = g_pMMPlugins->Load(m_Path.c_str(), g_PLID, already, error, maxlength);
// Check the plugin didn't refuse load
Pl_Status status;
#ifndef METAMOD_PLAPI_VERSION
const char *file;
PluginId source;
#endif
if (!m_PlId || (
#ifndef METAMOD_PLAPI_VERSION
g_pMMPlugins->Query(m_PlId, file, status, source)
#else
g_pMMPlugins->Query(m_PlId, NULL, &status, NULL)
#endif
&& status < Pl_Paused))
{
m_pLib->CloseLibrary();
m_pLib = NULL;
m_pAPI = NULL;
return false;
}
}
if (!CExtension::Load(error, maxlength))
@@ -183,6 +248,23 @@ void CLocalExtension::Unload()
}
}
bool CRemoteExtension::Reload(char *error, size_t maxlength)
{
snprintf(error, maxlength, "Remote extensions do not support reloading");
return false;
}
bool CLocalExtension::Reload(char *error, size_t maxlength)
{
if (m_pLib == NULL) // FIXME: just load it instead?
return false;
m_pAPI->OnExtensionUnload();
Unload();
return Load(error, maxlength);
}
bool CRemoteExtension::IsExternal()
{
return true;
@@ -287,7 +369,12 @@ IExtensionInterface *CExtension::GetAPI()
const char *CExtension::GetFilename()
{
return m_File.c_str();
return m_RealFile.c_str();
}
const char *CExtension::GetPath() const
{
return m_Path.c_str();
}
IdentityToken_t *CExtension::GetIdentity()
@@ -490,7 +577,7 @@ void CExtensionManager::TryAutoload()
char file[PLATFORM_MAX_PATH];
len = UTIL_Format(file, sizeof(file), "%s", lfile);
strcpy(&file[len - 9], ".ext." PLATFORM_LIB_EXT);
strcpy(&file[len - 9], ".ext");
LoadAutoExtension(file);
@@ -498,13 +585,16 @@ void CExtensionManager::TryAutoload()
}
}
IExtension *CExtensionManager::LoadAutoExtension(const char *path)
IExtension *CExtensionManager::LoadAutoExtension(const char *path, bool bErrorOnMissing)
{
if (!strstr(path, "." PLATFORM_LIB_EXT))
/* Remove platform extension if it's there. Compat hack. */
const char *ext = g_LibSys.GetFileExtension(path);
if (strcmp(ext, PLATFORM_LIB_EXT) == 0)
{
char newpath[PLATFORM_MAX_PATH];
g_LibSys.PathFormat(newpath, sizeof(newpath), "%s.%s", path, PLATFORM_LIB_EXT);
return LoadAutoExtension(newpath);
char path2[PLATFORM_MAX_PATH];
UTIL_Format(path2, sizeof(path2), "%s", path);
path2[strlen(path) - strlen(PLATFORM_LIB_EXT) - 1] = '\0';
return LoadAutoExtension(path2, bErrorOnMissing);
}
IExtension *pAlready;
@@ -523,7 +613,11 @@ IExtension *CExtensionManager::LoadAutoExtension(const char *path)
if (!p->Load(error, sizeof(error)) || !p->IsLoaded())
{
g_Logger.LogError("[SM] Unable to load extension \"%s\": %s", path, error);
if (bErrorOnMissing || g_LibSys.IsPathFile(p->GetPath()))
{
g_Logger.LogError("[SM] Unable to load extension \"%s\": %s", path, error);
}
p->SetError(error);
}
@@ -542,24 +636,12 @@ IExtension *CExtensionManager::FindExtensionByFile(const char *file)
for (iter=m_Libs.begin(); iter!=m_Libs.end(); iter++)
{
pExt = (*iter);
char short_file[PLATFORM_MAX_PATH];
g_LibSys.GetFileFromPath(short_file, sizeof(short_file), pExt->GetFilename());
if (strcmp(lookup, short_file) == 0)
if (pExt->IsSameFile(lookup))
{
return pExt;
}
}
/* If we got no results, test if there was a platform extension.
* If not, add one.
*/
if (!strstr(file, "." PLATFORM_LIB_EXT))
{
char path[PLATFORM_MAX_PATH];
UTIL_Format(path, sizeof(path), "%s.%s", file, PLATFORM_LIB_EXT);
return FindExtensionByFile(path);
}
return NULL;
}
@@ -597,6 +679,16 @@ IExtension *CExtensionManager::FindExtensionByName(const char *ext)
IExtension *CExtensionManager::LoadExtension(const char *file, char *error, size_t maxlength)
{
/* Remove platform extension if it's there. Compat hack. */
const char *ext = g_LibSys.GetFileExtension(file);
if (strcmp(ext, PLATFORM_LIB_EXT) == 0)
{
char path2[PLATFORM_MAX_PATH];
UTIL_Format(path2, sizeof(path2), "%s", file);
path2[strlen(file) - strlen(PLATFORM_LIB_EXT) - 1] = '\0';
return LoadExtension(path2, error, maxlength);
}
IExtension *pAlready;
if ((pAlready=FindExtensionByFile(file)) != NULL)
{
@@ -905,11 +997,42 @@ void CExtensionManager::OnRootConsoleCommand(const char *cmdname, const CCommand
}
return;
}
else if (strcmp(cmd, "load") == 0)
{
if (argcount < 4)
{
g_RootMenu.ConsolePrint("[SM] Usage: sm exts load <file>");
return;
}
const char *filename = command.Arg(3);
char path[PLATFORM_MAX_PATH];
char error[256];
UTIL_Format(path, sizeof(path), "%s%s%s", filename, !strstr(filename, ".ext") ? ".ext" : "",
!strstr(filename, "." PLATFORM_LIB_EXT) ? "." PLATFORM_LIB_EXT : "");
if (FindExtensionByFile(path) != NULL)
{
g_RootMenu.ConsolePrint("[SM] Extension %s is already loaded.", path);
return;
}
if (LoadExtension(path, error, sizeof(error)))
{
g_RootMenu.ConsolePrint("[SM] Loaded extension %s successfully.", path);
} else
{
g_RootMenu.ConsolePrint("[SM] Extension %s failed to load: %s", path, error);
}
return;
}
else if (strcmp(cmd, "info") == 0)
{
if (argcount < 4)
{
g_RootMenu.ConsolePrint("[SM] Usage: sm info <#>");
g_RootMenu.ConsolePrint("[SM] Usage: sm exts info <#>");
return;
}
@@ -917,7 +1040,7 @@ void CExtensionManager::OnRootConsoleCommand(const char *cmdname, const CCommand
unsigned int id = atoi(sId);
if (id <= 0)
{
g_RootMenu.ConsolePrint("[SM] Usage: sm info <#>");
g_RootMenu.ConsolePrint("[SM] Usage: sm exts info <#>");
return;
}
@@ -994,7 +1117,7 @@ void CExtensionManager::OnRootConsoleCommand(const char *cmdname, const CCommand
{
if (argcount < 4)
{
g_RootMenu.ConsolePrint("[SM] Usage: sm unload <#> [code]");
g_RootMenu.ConsolePrint("[SM] Usage: sm exts unload <#> [code]");
return;
}
@@ -1107,11 +1230,57 @@ void CExtensionManager::OnRootConsoleCommand(const char *cmdname, const CCommand
return;
}
}
else if (strcmp(cmd, "reload") == 0)
{
if (argcount < 4)
{
g_RootMenu.ConsolePrint("[SM] Usage: sm exts reload <#>");
return;
}
const char *arg = command.Arg(3);
unsigned int num = atoi(arg);
CExtension *pExt = FindByOrder(num);
if (!pExt)
{
g_RootMenu.ConsolePrint("[SM] Extension number %d was not found.", num);
return;
}
if (pExt->IsLoaded())
{
char filename[PLATFORM_MAX_PATH];
char error[255];
snprintf(filename, PLATFORM_MAX_PATH, "%s", pExt->GetFilename());
if (pExt->Reload(error, sizeof(error)))
{
g_RootMenu.ConsolePrint("[SM] Extension %s is now reloaded.", filename);
}
else
{
g_RootMenu.ConsolePrint("[SM] Extension %s failed to reload: %s", filename, error);
}
return;
}
else
{
g_RootMenu.ConsolePrint("[SM] Extension %s is not loaded.", pExt->GetFilename());
return;
}
}
}
g_RootMenu.ConsolePrint("SourceMod Extensions Menu:");
g_RootMenu.DrawGenericOption("info", "Extra extension information");
g_RootMenu.DrawGenericOption("list", "List extensions");
g_RootMenu.DrawGenericOption("load", "Load an extension");
g_RootMenu.DrawGenericOption("reload", "Reload an extension");
g_RootMenu.DrawGenericOption("unload", "Unload an extension");
}
@@ -1206,3 +1375,16 @@ void CExtensionManager::CallOnCoreMapStart(edict_t *pEdictList, int edictCount,
}
}
}
bool CLocalExtension::IsSameFile(const char *file)
{
/* Only care about the shortened name. */
return strcmp(file, m_File.c_str()) == 0;
}
bool CRemoteExtension::IsSameFile(const char *file)
{
/* :TODO: this could be better, but no one uses this API anyway. */
return strcmp(file, m_Path.c_str()) == 0;
}
+9 -1
View File
@@ -66,6 +66,7 @@ public:
public: //IExtension
IExtensionInterface *GetAPI();
const char *GetFilename();
const char *GetPath() const;
IdentityToken_t *GetIdentity();
ITERATOR *FindFirstDependency(IExtension **pOwner, SMInterface **pInterface);
bool FindNextDependency(ITERATOR *iter, IExtension **pOwner, SMInterface **pInterface);
@@ -83,6 +84,8 @@ public:
virtual bool Load(char *error, size_t maxlength);
virtual bool IsLoaded() =0;
virtual void Unload() =0;
virtual bool Reload(char *error, size_t maxlength) =0;
virtual bool IsSameFile(const char* file) =0;
protected:
void Initialize(const char *filename, const char *path);
bool PerformAPICheck(char *error, size_t maxlength);
@@ -92,6 +95,7 @@ protected:
IdentityToken_t *m_pIdentToken;
IExtensionInterface *m_pAPI;
String m_File;
String m_RealFile;
String m_Path;
String m_Error;
List<IfaceInfo> m_Deps; /** Dependencies */
@@ -110,7 +114,9 @@ public:
bool Load(char *error, size_t maxlength);
bool IsLoaded();
void Unload();
bool Reload(char *error, size_t maxlength);
bool IsExternal();
bool IsSameFile(const char *file);
private:
PluginId m_PlId;
ILibrary *m_pLib;
@@ -124,7 +130,9 @@ public:
bool Load(char *error, size_t maxlength);
bool IsLoaded();
void Unload();
bool Reload(char *error, size_t maxlength);
bool IsExternal();
bool IsSameFile(const char *file);
};
class CExtensionManager :
@@ -156,7 +164,7 @@ public: //IPluginsListener
public: //IRootConsoleCommand
void OnRootConsoleCommand(const char *cmdname, const CCommand &command);
public:
IExtension *LoadAutoExtension(const char *path);
IExtension *LoadAutoExtension(const char *path, bool bErrorOnMissing=true);
void BindDependency(IExtension *pOwner, IfaceInfo *pInfo);
void AddInterface(IExtension *pOwner, SMInterface *pInterface);
void BindChildPlugin(IExtension *pParent, CPlugin *pPlugin);
+14 -8
View File
@@ -1,5 +1,5 @@
/**
* vim: set ts=4 :
* vim: set ts=4 sw=4 tw=99 noet :
* =============================================================================
* SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
@@ -255,6 +255,7 @@ CForward *CForward::CreateForward(const char *name, ExecType et, unsigned int nu
}
CForward *pForward = g_Forwards.ForwardMake();
pForward->m_IterGuard = NULL;
pForward->m_curparam = 0;
pForward->m_ExecType = et;
snprintf(pForward->m_name, FORWARDS_NAME_MAX, "%s", name ? name : "");
@@ -294,7 +295,7 @@ int CForward::Execute(cell_t *result, IForwardFilter *filter)
cell_t high_result = 0;
cell_t low_result = 0;
int err;
unsigned int failed=0, success=0;
unsigned int success=0;
unsigned int num_params = m_curparam;
FwdParamInfo temp_info[SP_MAX_EXEC_PARAMS];
FwdParamInfo *param;
@@ -304,10 +305,15 @@ int CForward::Execute(cell_t *result, IForwardFilter *filter)
memcpy(temp_info, m_params, sizeof(m_params));
m_curparam = 0;
for (iter=m_functions.begin(); iter!=m_functions.end(); iter++)
FuncIteratorGuard guard(&m_IterGuard, &iter);
while (iter != m_functions.end())
{
func = (*iter);
if (filter)
filter->Preprocess(func, temp_info);
for (unsigned int i=0; i<num_params; i++)
{
int err = SP_ERROR_PARAM;
@@ -359,11 +365,7 @@ int CForward::Execute(cell_t *result, IForwardFilter *filter)
}
/* Call the function and deal with the return value. */
if ((err=func->Execute(&cur_result)) != SP_ERROR_NONE)
{
failed++;
}
else
if ((err=func->Execute(&cur_result)) == SP_ERROR_NONE)
{
success++;
switch (m_ExecType)
@@ -403,6 +405,9 @@ int CForward::Execute(cell_t *result, IForwardFilter *filter)
}
}
}
if (!guard.Triggered())
iter++;
}
done:
@@ -682,6 +687,7 @@ bool CForward::RemoveFunction(IPluginFunction *func)
{
if ((*iter) == func)
{
m_IterGuard->FixIteratorChain(iter);
found = true;
lst->erase(iter);
break;
+53
View File
@@ -61,6 +61,58 @@ struct FwdParamInfo
ParamType pushedas;
};
class SourceMod::IForwardFilter
{
public:
virtual void Preprocess(IPluginFunction *fun, FwdParamInfo *params)
{
}
};
class FuncIteratorGuard
{
bool triggered;
FuncIteratorGuard **pprev;
FuncIter *iter;
FuncIteratorGuard *next;
public:
FuncIteratorGuard(FuncIteratorGuard **pprev, FuncIter *iter)
: triggered(false), pprev(pprev), iter(iter), next(*pprev)
{
*pprev = this;
}
~FuncIteratorGuard()
{
*pprev = next;
}
inline bool Triggered()
{
bool t = triggered;
triggered = false;
return t;
}
/**
* This should not read from |this| before the NULL check, because FwdSys
* can call (NULL)->FixIteratorChain().
*/
void FixIteratorChain(FuncIter &other)
{
FuncIteratorGuard *guard = this;
while (guard != NULL)
{
if (*guard->iter == other)
{
*(guard->iter) = ++(*(guard->iter));
guard->triggered = true;
}
guard = guard->next;
}
}
};
class CForward : public IChangeableForward
{
public: //ICallable
@@ -103,6 +155,7 @@ protected:
*/
mutable List<IPluginFunction *> m_functions;
mutable List<IPluginFunction *> m_paused;
FuncIteratorGuard *m_IterGuard;
/* Type and name information */
FwdParamInfo m_params[SP_MAX_EXEC_PARAMS];
-909
View File
@@ -1,909 +0,0 @@
/**
* vim: set ts=4 :
* =============================================================================
* SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
* =============================================================================
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, version 3.0, as published by the
* Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*
* As a special exception, AlliedModders LLC gives you permission to link the
* code of this program (as well as its derivative works) to "Half-Life 2," the
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
* by the Valve Corporation. You must obey the GNU General Public License in
* all respects for all other code used. Additionally, AlliedModders LLC grants
* this exception to all derivative works. AlliedModders LLC defines further
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
* or <http://www.sourcemod.net/license.php>.
*
* Version: $Id$
*/
#include "GameDataFetcher.h"
#include "bitbuf.h"
#ifdef PLATFORM_WINDOWS
#include <winsock2.h>
#else
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#define INVALID_SOCKET -1
#define closesocket close
#define WSAGetLastError() errno
#endif
#include "sh_vector.h"
#include "sh_string.h"
#include "sm_version.h"
#ifdef ORANGEBOX_BUILD
#include "convar_sm_ob.h"
#else
#include "convar_sm.h"
#endif
#include "sourcemm_api.h"
#include "time.h"
#include "TimerSys.h"
#include "compat_wrappers.h"
#include "sm_stringutil.h"
#include "md5.h"
#include "frame_hooks.h"
#define QUERY_MAX_LENGTH 1024
static BuildMD5ableBuffer g_MD5Builder;
static FetcherThread g_FetchThread;
static FILE *logfile = NULL;
bool g_disableGameDataUpdate = false;
/**
* Note on this. If we issue a reload and changelevel, my srcds.exe will emit
* Assertion Failed: !m_bServiceStarted
* on quit. This seems like a non-issue, because before we just terminated the
* server anyway. If anyone notices and files a bug, we can look into it further.
*/
bool g_restartAfterUpdate = false;
static bool was_level_started = false;
static int g_serverPort = 6500;
static char g_serverAddress[100] = "smupdate.alliedmods.net";
static void _ForceRestart(void *data)
{
char cmd[300];
g_Logger.LogMessage("Automatically restarting SourceMod after a successful gamedata update.");
UTIL_Format(cmd, sizeof(cmd), "meta unload %d\n", g_PLID);
engine->ServerCommand(cmd);
UTIL_Format(cmd, sizeof(cmd), "changelevel \"%s\"\n", STRING(gpGlobals->mapname));
engine->ServerCommand(cmd);
UTIL_Format(cmd, sizeof(cmd), "echo SourceMod restarted after gamedata update.\n");
engine->ServerCommand(cmd);
}
static void ForceRestart()
{
FrameAction action;
action.action = _ForceRestart;
action.data = NULL;
AddFrameAction(action);
}
void FetcherThread::RunThread(IThreadHandle *pHandle)
{
char lock_path[PLATFORM_MAX_PATH];
g_SourceMod.BuildPath(Path_SM, lock_path, sizeof(lock_path), "data/temp");
g_LibSys.CreateFolder(lock_path);
g_SourceMod.BuildPath(Path_SM, lock_path, sizeof(lock_path), "data/temp/gamedata.lock");
char log_path[PLATFORM_MAX_PATH];
g_SourceMod.BuildPath(Path_SM, log_path, sizeof(log_path), "logs/gamedata");
g_LibSys.CreateFolder(log_path);
time_t t;
GetAdjustedTime(&t);
tm *curtime = localtime(&t);
g_SourceMod.BuildPath(Path_SM,
log_path,
sizeof(log_path),
"logs/gamedata/L%04d%02d%02d.log",
curtime->tm_year + 1900,
curtime->tm_mon + 1,
curtime->tm_mday);
logfile = fopen(log_path, "at");
if (!logfile)
{
/* :( */
return;
}
//Create a blank lock file
FILE *fp = fopen(lock_path, "w");
if (fp)
{
fclose(fp);
}
char query[QUERY_MAX_LENGTH];
/* Check for updated gamedata files */
int len = BuildGameDataQuery(query, QUERY_MAX_LENGTH);
if (len == 0)
{
g_Logger.LogToFileOnly(logfile, "Could not build gamedata query!");
fclose(logfile);
unlink(lock_path);
return;
}
/* We check this late so we have the MD5 sums available. This may change in the future. */
if (g_disableGameDataUpdate)
{
g_Logger.LogToFileOnly(logfile, "Skipping gamedata fetcher (DisableAutoUpdate set)");
fclose(logfile);
unlink(lock_path);
return;
}
/* Create a new socket for this connection */
int socketDescriptor = ConnectSocket();
if (socketDescriptor == INVALID_SOCKET)
{
fclose(logfile);
unlink(lock_path);
return;
}
int sent = SendData(socketDescriptor, query, len);
IF_DEBUG_SPEW
g_Logger.LogToFileOnly(logfile, "Sent gamedata query");
ENDIF_DEBUG_SPEW
if (sent == 0)
{
IF_DEBUG_SPEW
g_Logger.LogToFileOnly(logfile, "Failed to send gamedata query data to remote host");
ENDIF_DEBUG_SPEW
closesocket(socketDescriptor);
fclose(logfile);
unlink(lock_path);
return;
}
ProcessGameDataQuery(socketDescriptor);
/* And we're done! */
closesocket(socketDescriptor);
fclose(logfile);
unlink(lock_path);
}
void FetcherThread::OnTerminate(IThreadHandle *pHandle, bool cancel)
{
g_blockGameDataLoad = false;
if (cancel)
{
return;
}
if (wasSuccess)
{
HandleUpdateStatus(updateStatus, build);
if (needsRestart)
{
if (g_restartAfterUpdate)
{
if (was_level_started)
{
ForceRestart();
}
}
else
{
g_Logger.LogMessage("Your gamedata files have been updated, please restart your server.");
}
}
}
else if (!g_disableGameDataUpdate)
{
g_Logger.LogError("An error occurred in the gamedata fetcher, see your gamedata log files for more information.");
}
}
int FetcherThread::BuildGameDataQuery(char *buffer, int maxlen)
{
char gamedata_path[PLATFORM_MAX_PATH];
g_SourceMod.BuildPath(Path_SM, gamedata_path, sizeof(gamedata_path), "gamedata");
IDirectory *dir = g_LibSys.OpenDirectory(gamedata_path);
if (dir == NULL)
{
return 0;
}
bf_write Writer = bf_write("GameDataQuery", buffer, maxlen);
Writer.WriteByte('A'); //Generic Header char
Writer.WriteByte('G'); //G for gamedata query, or green, like my hat.
short build[4] = { SVN_FILE_VERSION };
Writer.WriteBytes(&build[0], 8);
Writer.WriteByte(0); // Initialize the file counter - Index 10
while (dir->MoreFiles())
{
if (dir->IsEntryFile())
{
const char *name = dir->GetEntryName();
size_t len = strlen(name);
if (len >= 4 && strcmp(&name[len-4], ".txt") == 0)
{
MD5 md5;
SMCError err;
SMCStates states;
unsigned char raw[16];
char file[PLATFORM_MAX_PATH];
g_LibSys.PathFormat(file, sizeof(file), "%s/%s", gamedata_path, name);
g_MD5Builder.checksum = &md5;
if ((err = g_TextParser.ParseFile_SMC(file, &g_MD5Builder, &states)) == SMCError_Okay)
{
md5.raw_digest(raw);
(uint8_t)buffer[10]++; //Increment the file counter
Writer.WriteBytes(raw, 16);
FileData *data = new FileData();
data->filename = new SourceHook::String(file);
md5.hex_digest(data->checksum);
filenames.push_back(data);
IF_DEBUG_SPEW
g_Logger.LogToFileOnly(logfile, "Parsed file: %s as %s", file, data->checksum);
ENDIF_DEBUG_SPEW
}
else
{
IF_DEBUG_SPEW
const char *error = g_TextParser.GetSMCErrorString(err);
g_Logger.LogToFileOnly(logfile, "Parsing of file %s failed: %s", file, error);
ENDIF_DEBUG_SPEW
}
}
}
dir->NextEntry();
}
return Writer.GetNumBytesWritten();
}
int FetcherThread::ConnectSocket()
{
#if defined PLATFORM_WINDOWS
WSADATA wsaData;
WSAStartup(0x0101, &wsaData);
#endif
struct protoent *ptrp;
if ((ptrp = getprotobyname("tcp")) == NULL)
{
g_Logger.LogToFileOnly(logfile, "Error: Failed to find TCP protocol");
return INVALID_SOCKET;
}
int socketDescriptor = socket(AF_INET, SOCK_STREAM, ptrp->p_proto);
if (socketDescriptor == INVALID_SOCKET)
{
char error[255];
g_LibSys.GetPlatformErrorEx(WSAGetLastError(), error, sizeof(error));
g_Logger.LogToFileOnly(logfile, "Error: Failed to create socket: %s", error);
closesocket(socketDescriptor);
return INVALID_SOCKET;
}
struct hostent *he;
struct sockaddr_in local_addr;
local_addr.sin_family = AF_INET;
local_addr.sin_port = htons((u_short)g_serverPort);
he = gethostbyname(g_serverAddress);
if (!he)
{
if ((local_addr.sin_addr.s_addr = inet_addr(g_serverAddress)) == INADDR_NONE)
{
g_Logger.LogToFileOnly(logfile, "Couldn't locate address: %s", g_serverAddress);
closesocket(socketDescriptor);
return INVALID_SOCKET;
}
}
else
{
memcpy(&local_addr.sin_addr, (struct in_addr *)he->h_addr, he->h_length);
}
if (connect(socketDescriptor, (struct sockaddr *) &local_addr, sizeof(local_addr)) < 0)
{
char error[255];
g_LibSys.GetPlatformErrorEx(WSAGetLastError(), error, sizeof(error));
g_Logger.LogToFileOnly(logfile, "Couldn't connect to %s: %s", g_serverAddress, error);
closesocket(socketDescriptor);
return INVALID_SOCKET;
}
return socketDescriptor;
}
void FetcherThread::ProcessGameDataQuery(int socketDescriptor)
{
char buffer[50];
IF_DEBUG_SPEW
g_Logger.LogToFileOnly(logfile, "Waiting for reply!");
ENDIF_DEBUG_SPEW
//Read in the header bytes
int returnLen = RecvData(socketDescriptor, buffer, 12);
if (returnLen == 0)
{
char error[255];
g_LibSys.GetPlatformErrorEx(WSAGetLastError(), error, sizeof(error));
g_Logger.LogToFileOnly(logfile, "Did not receive reply: %s", error);
return;
}
IF_DEBUG_SPEW
g_Logger.LogToFileOnly(logfile, "Received Header!");
ENDIF_DEBUG_SPEW
bf_read Reader = bf_read("GameDataQuery", buffer, 12);
if (Reader.ReadByte() != 'A' || Reader.ReadByte() != 'G')
{
IF_DEBUG_SPEW
g_Logger.LogToFileOnly(logfile, "Unknown Query Response");
ENDIF_DEBUG_SPEW
return;
}
updateStatus = (UpdateStatus)Reader.ReadByte();
build[0] = Reader.ReadShort();
build[1] = Reader.ReadShort();
build[2] = Reader.ReadShort();
build[3] = Reader.ReadShort();
IF_DEBUG_SPEW
g_Logger.LogToFileOnly(logfile,
"Update Status: %i - Latest %i.%i.%i.%i",
updateStatus,
build[0],
build[1],
build[2],
build[3]);
ENDIF_DEBUG_SPEW
int changedFiles = Reader.ReadByte();
IF_DEBUG_SPEW
g_Logger.LogToFileOnly(logfile, "Files to download: %i", changedFiles);
ENDIF_DEBUG_SPEW
for (int i=0; i<changedFiles; i++)
{
//Read in the file index and byte count
returnLen = RecvData(socketDescriptor, buffer, 5);
if (returnLen == 0)
{
/* Timeout or fail? */
return;
}
Reader.StartReading(buffer, 5);
int index = Reader.ReadByte();
int tempLen = Reader.ReadUBitLong(32);
IF_DEBUG_SPEW
g_Logger.LogToFileOnly(logfile, "File index %i and length %i", index, tempLen);
ENDIF_DEBUG_SPEW
void *memPtr;
memtable->CreateMem(tempLen+1, &memPtr);
//Read the contents of our file into the memtable
returnLen = RecvData(socketDescriptor, (char *)memPtr, tempLen);
IF_DEBUG_SPEW
g_Logger.LogToFileOnly(logfile, "Received %i bytes", returnLen);
ENDIF_DEBUG_SPEW
if (returnLen == 0)
{
/* Timeout or fail? */
return;
}
((unsigned char *)memPtr)[tempLen] = '\0';
FileData *data = filenames.at(index);
const char *filename;
if (data != NULL)
{
filename = data->filename->c_str();
FILE *fp = fopen(filename, "w");
if (fp)
{
fprintf(fp, "%s", (const char *)memPtr);
fclose(fp);
}
else
{
g_Logger.LogToFileOnly(logfile, "Failed to open file \"%s\" for writing", filename);
}
}
else
{
filename = "";
}
memtable->Reset();
g_Logger.LogToFileOnly(logfile, "Updated file: %s", filename);
}
IF_DEBUG_SPEW
g_Logger.LogToFileOnly(logfile, "File Downloads Completed!");
ENDIF_DEBUG_SPEW
needsRestart = false;
if (changedFiles > 0)
{
needsRestart = true;
}
//Read changed file count
returnLen = RecvData(socketDescriptor, buffer, 1);
if (returnLen == 0)
{
char error[255];
g_LibSys.GetPlatformErrorEx(WSAGetLastError(), error, sizeof(error));
g_Logger.LogToFileOnly(logfile, "Did not receive count reply: %s", error);
return;
}
Reader.StartReading(buffer, 1);
changedFiles = Reader.ReadByte();
if (changedFiles < 1)
{
IF_DEBUG_SPEW
g_Logger.LogToFileOnly(logfile, "No unknown files. We're all done");
ENDIF_DEBUG_SPEW
return;
}
char *changedFileIndexes = new char[changedFiles];
IF_DEBUG_SPEW
g_Logger.LogToFileOnly(logfile, "%i files were unknown", changedFiles);
ENDIF_DEBUG_SPEW
returnLen = RecvData(socketDescriptor, changedFileIndexes, changedFiles);
if (returnLen == 0)
{
char error[255];
g_LibSys.GetPlatformErrorEx(WSAGetLastError(), error, sizeof(error));
g_Logger.LogToFileOnly(logfile, "Did not receive list reply: %s", error);
return;
}
Reader.StartReading(changedFileIndexes, changedFiles);
for (int i=0; i<changedFiles; i++)
{
int index = Reader.ReadByte();
char fileName[30];
FileData *data = filenames.at(index);
const char* pathname;
if (data != NULL)
{
pathname = data->filename->c_str();
}
else
{
pathname = "";
}
g_LibSys.GetFileFromPath(fileName, sizeof(fileName), pathname);
IF_DEBUG_SPEW
g_Logger.LogToFileOnly(logfile, "Unknown File %i : %s", index, fileName);
ENDIF_DEBUG_SPEW
}
delete [] changedFileIndexes;
wasSuccess = true;
}
int FetcherThread::RecvData(int socketDescriptor, char *buffer, int len)
{
fd_set fds;
struct timeval tv;
/* Create a 10 Second Timeout */
tv.tv_sec = 10;
tv.tv_usec = 0;
int bytesReceivedTotal = 0;
while (bytesReceivedTotal < len)
{
/* Add our socket to a socket set */
FD_ZERO(&fds);
FD_SET(socketDescriptor, &fds);
/* Wait max of 10 seconds for recv to become available */
select(socketDescriptor+1, &fds, NULL, NULL, &tv);
int bytesReceived = 0;
/* Is there a limit on how much we can receive? Some site said 1024 bytes, which will be well short of a file */
if (FD_ISSET(socketDescriptor, &fds))
{
bytesReceived = recv(socketDescriptor, buffer+bytesReceivedTotal, len-bytesReceivedTotal, 0);
}
if (bytesReceived == 0 || bytesReceived == -1)
{
return 0;
}
bytesReceivedTotal += bytesReceived;
}
return bytesReceivedTotal;
}
int FetcherThread::SendData(int socketDescriptor, char *buffer, int len)
{
fd_set fds;
struct timeval tv;
tv.tv_sec = 10;
tv.tv_usec = 0;
int sentBytesTotal = 0;
while (sentBytesTotal < len)
{
FD_ZERO(&fds);
FD_SET(socketDescriptor, &fds);
select(socketDescriptor+1, NULL, &fds, NULL, &tv);
int sentBytes = 0;
if (FD_ISSET(socketDescriptor, &fds))
{
sentBytes = send(socketDescriptor, buffer+sentBytesTotal, len-sentBytesTotal, 0);
}
if (sentBytes == 0 || sentBytes == -1)
{
return 0;
}
sentBytesTotal += sentBytes;
}
return sentBytesTotal;
}
void FetcherThread::HandleUpdateStatus(UpdateStatus status, short version[4])
{
switch (status)
{
case Update_Unknown:
case Update_Current:
{
break;
}
case Update_NewBuild:
{
break;
}
case Update_MinorAvailable:
{
g_Logger.LogMessage("SourceMod Update: A new release of SourceMod is now available from sourcemod.net");
g_Logger.LogMessage("Current Version: %i.%i.%i Available: %i.%i.%i", version[0], version[1], version[2], version[0], version[1], version[2]);
break;
}
case Update_MajorAvailable:
{
g_Logger.LogMessage("SourceMod Update: An major release of SourceMod is now available from sourcemod.net");
g_Logger.LogMessage("Current Version: %i.%i.%i Available: %i.%i.%i", version[0], version[1], version[2], version[0], version[1], version[2]);
break;
}
case Update_CriticalAvailable:
{
g_Logger.LogError("SourceMod Update: A critical SourceMod release is available from sourcemod.net. It is strongly recommended that you update!");
g_Logger.LogMessage("Current Version: %i.%i.%i Available: %i.%i.%i", version[0], version[1], version[2], version[0], version[1], version[2]);
break;
}
}
}
bool g_blockGameDataLoad = false;
static IThreadHandle *fetch_thread_hndl;
class InitFetch : public SMGlobalClass
{
public:
void OnSourceModAllInitialized_Post()
{
char lock_path[PLATFORM_MAX_PATH];
g_SourceMod.BuildPath(Path_SM, lock_path, sizeof(lock_path), "data/temp/gamedata.lock");
if (g_LibSys.IsPathFile(lock_path) && g_LibSys.PathExists(lock_path))
{
g_Logger.LogError("sourcemod/data/temp/gamedata.lock file detected. This is most likely due to a crash during GameData updating - Blocking GameData loading");
g_Logger.LogError("If this error persists delete the file manually");
g_blockGameDataLoad = true;
}
ThreadParams fetchThreadParams = ThreadParams();
fetchThreadParams.prio = ThreadPrio_Low;
fetch_thread_hndl = g_pThreader->MakeThread(&g_FetchThread, &fetchThreadParams);
}
void OnSourceModShutdown()
{
fetch_thread_hndl->WaitForThread();
fetch_thread_hndl->DestroyThis();
}
void OnSourceModLevelActivated()
{
was_level_started = true;
if (g_restartAfterUpdate &&
g_FetchThread.wasSuccess &&
g_FetchThread.needsRestart)
{
ForceRestart();
}
}
void OnSourceModLevelEnd()
{
was_level_started = false;
}
ConfigResult OnSourceModConfigChanged(const char *key,
const char *value,
ConfigSource source,
char *error,
size_t maxlength)
{
if (strcasecmp(key, "DisableAutoUpdate") == 0)
{
if (strcasecmp(value, "yes") == 0)
{
g_disableGameDataUpdate = true;
return ConfigResult_Accept;
}
else if (strcasecmp(value, "no") == 0)
{
g_disableGameDataUpdate = false;
return ConfigResult_Accept;
}
return ConfigResult_Reject;
}
if (strcasecmp(key, "ForceRestartAfterUpdate") == 0)
{
if (strcasecmp(value, "yes") == 0)
{
g_restartAfterUpdate = true;
return ConfigResult_Accept;
}
else if (strcasecmp(value, "no") == 0)
{
g_restartAfterUpdate = false;
return ConfigResult_Accept;
}
return ConfigResult_Reject;
}
if (strcasecmp(key, "AutoUpdateServer") == 0)
{
UTIL_Format(g_serverAddress, sizeof(g_serverAddress), "%s", value);
return ConfigResult_Accept;
}
if (strcasecmp(key, "AutoUpdatePort") == 0)
{
int port = atoi(value);
if (!port)
{
return ConfigResult_Reject;
}
g_serverPort = port;
return ConfigResult_Accept;
}
return ConfigResult_Ignore;
}
} g_InitFetch;
BuildMD5ableBuffer::BuildMD5ableBuffer()
{
stringTable = new BaseStringTable(2048);
}
BuildMD5ableBuffer::~BuildMD5ableBuffer()
{
delete stringTable;
}
void BuildMD5ableBuffer::ReadSMC_ParseStart()
{
stringTable->Reset();
}
SMCResult BuildMD5ableBuffer::ReadSMC_KeyValue(const SMCStates *states,
const char *key,
const char *value)
{
stringTable->AddString(key);
stringTable->AddString(value);
return SMCResult_Continue;
}
SMCResult BuildMD5ableBuffer::ReadSMC_NewSection(const SMCStates *states, const char *name)
{
stringTable->AddString(name);
return SMCResult_Continue;
}
void BuildMD5ableBuffer::ReadSMC_ParseEnd(bool halted, bool failed)
{
if (halted || failed)
{
return;
}
void *data = stringTable->GetMemTable()->GetAddress(0);
if (data != NULL)
{
checksum->update((unsigned char *)data, stringTable->GetMemTable()->GetActualMemUsed());
}
checksum->finalize();
}
CON_COMMAND(sm_gamedata_md5, "Checks the MD5 sum for a given gamedata file")
{
#if !defined ORANGEBOX_BUILD
CCommand args;
#endif
if (args.ArgC() < 2)
{
g_SMAPI->ConPrint("Usage: sm_gamedata_md5 <file>\n");
return;
}
const char *file = args.Arg(1);
if (!file || file[0] == '\0')
{
g_SMAPI->ConPrint("Usage: sm_gamedata_md5 <file>\n");
return;
}
SourceHook::CVector<FileData *>::iterator iter = g_FetchThread.filenames.begin();
FileData *curData;
while (iter != g_FetchThread.filenames.end())
{
curData = (*iter);
char fileName[30];
g_LibSys.GetFileFromPath(fileName, sizeof(fileName), curData->filename->c_str());
if (strcmpi(fileName, file) == 0)
{
g_SMAPI->ConPrintf("MD5 Sum: %s\n", curData->checksum);
return;
}
iter++;
}
g_SMAPI->ConPrint("File not found!\n");
}
FetcherThread::~FetcherThread()
{
SourceHook::CVector<FileData *>::iterator iter = filenames.begin();
FileData *curData;
while (iter != filenames.end())
{
curData = (*iter);
delete curData->filename;
delete curData;
iter = filenames.erase(iter);
}
}
FetcherThread::FetcherThread()
{
memtable = new BaseMemTable(4096);
wasSuccess = false;
needsRestart = false;
}
-106
View File
@@ -1,106 +0,0 @@
/**
* vim: set ts=4 :
* =============================================================================
* SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
* =============================================================================
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, version 3.0, as published by the
* Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*
* As a special exception, AlliedModders LLC gives you permission to link the
* code of this program (as well as its derivative works) to "Half-Life 2," the
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
* by the Valve Corporation. You must obey the GNU General Public License in
* all respects for all other code used. Additionally, AlliedModders LLC grants
* this exception to all derivative works. AlliedModders LLC defines further
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
* or <http://www.sourcemod.net/license.php>.
*
* Version: $Id$
*/
#ifndef _INCLUDE_SOURCEMOD_GAMEDATAFETCHER_H_
#define _INCLUDE_SOURCEMOD_GAMEDATAFETCHER_H_
#include "sourcemod.h"
#include "TextParsers.h"
#include "IThreader.h"
#include "Logger.h"
#include "LibrarySys.h"
#include "ThreadSupport.h"
#include "sm_memtable.h"
#include <sh_string.h>
#include <sh_list.h>
enum UpdateStatus
{
Update_Unknown = 0, /* Version wasn't recognised or version querying is unsupported */
Update_Current = 1, /* Server is running latest version */
Update_NewBuild = 2, /* Server is on a svn release and a newer version is available */
Update_MinorAvailable = 3, /* Server is on a release and a minor release has superceeded it */
Update_MajorAvailable = 4, /* Server is on a release and a major release has superceeded it */
Update_CriticalAvailable = 5, /* A critical update has been released (security fixes etc) */
};
class MD5;
class BuildMD5ableBuffer : public ITextListener_SMC
{
public:
BuildMD5ableBuffer();
~BuildMD5ableBuffer();
void ReadSMC_ParseStart();
SMCResult ReadSMC_KeyValue(const SMCStates *states, const char *key, const char *value);
SMCResult ReadSMC_NewSection(const SMCStates *states, const char *name);
void ReadSMC_ParseEnd(bool halted, bool failed);
public:
MD5 *checksum;
private:
BaseStringTable *stringTable;
};
struct FileData
{
SourceHook::String *filename;
char checksum[33];
};
class FetcherThread : public IThread
{
public:
FetcherThread();
~FetcherThread();
public:
void RunThread(IThreadHandle *pHandle);
void OnTerminate(IThreadHandle *pHandle, bool cancel);
private:
int BuildGameDataQuery(char *buffer, int maxlen);
void ProcessGameDataQuery(int SocketDescriptor);
int RecvData(int socketDescriptor, char *buffer, int len);
int SendData(int socketDescriptor, char *buffer, int len);
int ConnectSocket();
void HandleUpdateStatus(UpdateStatus status, short version[4]);
public:
SourceHook::CVector<FileData *> filenames;
bool needsRestart;
bool wasSuccess;
private:
UpdateStatus updateStatus;
BaseMemTable *memtable;
short build[4];
};
extern bool g_blockGameDataLoad;
#endif // _INCLUDE_SOURCEMOD_GAMEDATAFETCHER_H_
+471 -6
View File
@@ -35,12 +35,37 @@
#include "UserMessages.h"
#include "PlayerManager.h"
#include "sm_stringutil.h"
#include "GameConfigs.h"
#include <IGameConfigs.h>
#include <compat_wrappers.h>
#include <Logger.h>
#include "LibrarySys.h"
#include "logic_bridge.h"
typedef ICommandLine *(*FakeGetCommandLine)();
#if defined _WIN32
#define TIER0_NAME "tier0.dll"
#define VSTDLIB_NAME "vstdlib.dll"
#elif defined __APPLE__
#define TIER0_NAME "libtier0.dylib"
#define VSTDLIB_NAME "libvstdlib.dylib"
#elif defined __linux__
#if SOURCE_ENGINE == SE_EPISODEONE || SOURCE_ENGINE == ORANGEBOX || SOURCE_ENGINE == SE_LEFT4DEAD
#define TIER0_NAME "tier0_i486.so"
#define VSTDLIB_NAME "vstdlib_i486.so"
#else
#define TIER0_NAME "libtier0.so"
#define VSTDLIB_NAME "libvstdlib.so"
#endif
#endif
CHalfLife2 g_HL2;
ConVar *sv_lan = NULL;
static void *g_EntList = NULL;
static int entInfoOffset = -1;
namespace SourceHook
{
template<>
@@ -88,13 +113,20 @@ CHalfLife2::~CHalfLife2()
m_Maps.clear();
}
#if SOURCE_ENGINE != SE_DARKMESSIAH
CSharedEdictChangeInfo *g_pSharedChangeInfo = NULL;
#endif
#if !defined METAMOD_PLAPI_VERSION || PLAPI_VERSION < 11
bool is_original_engine = false;
#endif
void CHalfLife2::OnSourceModStartup(bool late)
{
#if SOURCE_ENGINE != SE_DARKMESSIAH
/* The Ship currently is the only known game to use an older version of the engine */
#if defined METAMOD_PLAPI_VERSION
#if defined METAMOD_PLAPI_VERSION || PLAPI_VERSION >= 11
if (g_SMAPI->GetSourceEngineBuild() == SOURCE_ENGINE_ORIGINAL)
#else
if (strcasecmp(g_SourceMod.GetGameFolderName(), "ship") == 0)
@@ -106,27 +138,161 @@ void CHalfLife2::OnSourceModStartup(bool late)
{
g_pSharedChangeInfo = engine->GetSharedEdictChangeInfo();
}
#endif
}
void CHalfLife2::OnSourceModAllInitialized()
{
m_MsgTextMsg = g_UserMsgs.GetMessageIndex("TextMsg");
m_HinTextMsg = g_UserMsgs.GetMessageIndex("HintText");
m_SayTextMsg = g_UserMsgs.GetMessageIndex("SayText");
m_VGUIMenu = g_UserMsgs.GetMessageIndex("VGUIMenu");
g_ShareSys.AddInterface(NULL, this);
}
#if !defined METAMOD_PLAPI_VERSION
void CHalfLife2::OnSourceModAllInitialized_Post()
{
InitLogicalEntData();
InitCommandLine();
}
void CHalfLife2::InitLogicalEntData()
{
char *addr = NULL;
/*
* gEntList and/or g_pEntityList
*
* First try to lookup pointer directly for platforms with symbols.
* If symbols aren't present (Windows or stripped Linux/Mac),
* attempt find via LevelShutdown + offset
*/
if (g_pGameConf->GetMemSig("gEntList", (void **)&addr))
{
#if !defined PLATFORM_WINDOWS
if (!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
}
#endif
}
if (!g_EntList)
{
if (!g_pGameConf->GetMemSig("LevelShutdown", (void **)&addr))
{
g_Logger.LogError("Logical Entities not supported by this mod (LevelShutdown) - Reverting to networkable entities only");
return;
}
if (!addr)
{
g_Logger.LogError("Failed lookup of LevelShutdown - Reverting to networkable entities only");
return;
}
int offset;
if (!g_pGameConf->GetOffset("gEntList", &offset))
{
g_Logger.LogError("Logical Entities not supported by this mod (gEntList) - Reverting to networkable entities only");
return;
}
g_EntList = *reinterpret_cast<void **>(addr + offset);
}
if (!g_EntList)
{
g_Logger.LogError("Failed lookup of gEntList - Reverting to networkable entities only");
return;
}
if (!g_pGameConf->GetOffset("EntInfo", &entInfoOffset))
{
g_Logger.LogError("Logical Entities not supported by this mod (EntInfo) - Reverting to networkable entities only");
return;
}
}
void CHalfLife2::InitCommandLine()
{
char path[PLATFORM_MAX_PATH];
char error[256];
g_SourceMod.BuildPath(Path_Game, path, sizeof(path), "../bin/" TIER0_NAME);
if (!g_LibSys.IsPathFile(path))
{
g_Logger.LogError("Could not find path for: " TIER0_NAME);
return;
}
ILibrary *lib = g_LibSys.OpenLibrary(path, error, sizeof(error));
m_pGetCommandLine = lib->GetSymbolAddress("CommandLine_Tier0");
/* '_Tier0' dropped on Alien Swarm version */
if (m_pGetCommandLine == NULL)
{
m_pGetCommandLine = lib->GetSymbolAddress("CommandLine");
}
if (m_pGetCommandLine == NULL)
{
/* We probably have a Ship engine. */
lib->CloseLibrary();
g_SourceMod.BuildPath(Path_Game, path, sizeof(path), "../bin/" VSTDLIB_NAME);
if (!g_LibSys.IsPathFile(path))
{
g_Logger.LogError("Could not find path for: " VSTDLIB_NAME);
return;
}
if ((lib = g_LibSys.OpenLibrary(path, error, sizeof(error))) == NULL)
{
g_Logger.LogError("Could not load %s: %s", path, error);
return;
}
m_pGetCommandLine = lib->GetSymbolAddress("CommandLine");
if (m_pGetCommandLine == NULL)
{
g_Logger.LogError("Could not locate any command line functionality");
}
lib->CloseLibrary();
}
}
ICommandLine *CHalfLife2::GetValveCommandLine()
{
if (!m_pGetCommandLine)
return NULL;
return ((FakeGetCommandLine)((FakeGetCommandLine *)m_pGetCommandLine))();
}
#if !defined METAMOD_PLAPI_VERSION || PLAPI_VERSION < 11
bool CHalfLife2::IsOriginalEngine()
{
return is_original_engine;
}
#endif
#if SOURCE_ENGINE != SE_DARKMESSIAH
IChangeInfoAccessor *CBaseEdict::GetChangeAccessor()
{
return engine->GetChangeAccessor( (const edict_t *)this );
}
#endif
bool UTIL_FindInSendTable(SendTable *pTable,
const char *name,
@@ -296,6 +462,7 @@ typedescription_t *CHalfLife2::FindInDataMap(datamap_t *pMap, const char *offset
void CHalfLife2::SetEdictStateChanged(edict_t *pEdict, unsigned short offset)
{
#if SOURCE_ENGINE != SE_DARKMESSIAH
if (g_pSharedChangeInfo != NULL)
{
if (offset)
@@ -308,6 +475,7 @@ void CHalfLife2::SetEdictStateChanged(edict_t *pEdict, unsigned short offset)
}
}
else
#endif
{
pEdict->m_fStateFlags |= FL_EDICT_CHANGED;
}
@@ -318,6 +486,31 @@ bool CHalfLife2::TextMsg(int client, int dest, const char *msg)
bf_write *pBitBuf = NULL;
cell_t players[] = {client};
if (dest == HUD_PRINTTALK)
{
const char *chat_saytext = g_pGameConf->GetKeyValue("ChatSayText");
/* Use SayText user message instead */
if (chat_saytext != NULL && strcmp(chat_saytext, "yes") == 0)
{
char buffer[192];
UTIL_Format(buffer, sizeof(buffer), "%s\1\n", msg);
if ((pBitBuf = g_UserMsgs.StartMessage(m_SayTextMsg, players, 1, USERMSG_RELIABLE)) == NULL)
{
return false;
}
pBitBuf->WriteByte(0);
pBitBuf->WriteString(buffer);
pBitBuf->WriteByte(1);
g_UserMsgs.EndMessage();
return true;
}
}
if ((pBitBuf = g_UserMsgs.StartMessage(m_MsgTextMsg, players, 1, USERMSG_RELIABLE)) == NULL)
{
return false;
@@ -325,6 +518,7 @@ bool CHalfLife2::TextMsg(int client, int dest, const char *msg)
pBitBuf->WriteByte(dest);
pBitBuf->WriteString(msg);
g_UserMsgs.EndMessage();
return true;
@@ -351,6 +545,26 @@ bool CHalfLife2::HintTextMsg(int client, const char *msg)
return true;
}
bool CHalfLife2::HintTextMsg(cell_t *players, int count, const char *msg)
{
bf_write *pBitBuf = NULL;
if ((pBitBuf = g_UserMsgs.StartMessage(m_HinTextMsg, players, count, USERMSG_RELIABLE)) == NULL)
{
return false;
}
const char *pre_byte = g_pGameConf->GetKeyValue("HintTextPreByte");
if (pre_byte != NULL && strcmp(pre_byte, "yes") == 0)
{
pBitBuf->WriteByte(1);
}
pBitBuf->WriteString(msg);
g_UserMsgs.EndMessage();
return true;
}
bool CHalfLife2::ShowVGUIMenu(int client, const char *name, KeyValues *data, bool show)
{
bf_write *pBitBuf = NULL;
@@ -437,7 +651,7 @@ bool CHalfLife2::IsLANServer()
bool CHalfLife2::KVLoadFromFile(KeyValues *kv, IBaseFileSystem *filesystem, const char *resourceName, const char *pathID)
{
#if defined METAMOD_PLAPI_VERSION
#if defined METAMOD_PLAPI_VERSION || PLAPI_VERSION >= 11
if (g_SMAPI->GetSourceEngineBuild() == SOURCE_ENGINE_ORIGINAL)
#else
if (strcasecmp(g_SourceMod.GetGameFolderName(), "ship") == 0)
@@ -481,7 +695,7 @@ void CHalfLife2::PushCommandStack(const CCommand *cmd)
CachedCommandInfo info;
info.args = cmd;
#if !defined ORANGEBOX_BUILD
#if SOURCE_ENGINE <= SE_DARKMESSIAH
strncopy(info.cmd, cmd->Arg(0), sizeof(info.cmd));
#endif
@@ -505,7 +719,7 @@ void CHalfLife2::PopCommandStack()
const char *CHalfLife2::CurrentCommandName()
{
#if defined ORANGEBOX_BUILD
#if SOURCE_ENGINE >= SE_ORANGEBOX
return m_CommandStack.front().args->Arg(0);
#else
return m_CommandStack.front().cmd;
@@ -539,3 +753,254 @@ void CHalfLife2::ProcessDelayedKicks()
player->Kick(info.buffer);
}
}
edict_t *CHalfLife2::EdictOfIndex(int index)
{
return ::PEntityOfEntIndex(index);
}
int CHalfLife2::IndexOfEdict(edict_t *pEnt)
{
return ::IndexOfEdict(pEnt);
}
edict_t *CHalfLife2::GetHandleEntity(CBaseHandle &hndl)
{
if (!hndl.IsValid())
{
return NULL;
}
int index = hndl.GetEntryIndex();
edict_t *pStoredEdict;
CBaseEntity *pStoredEntity;
if (!IndexToAThings(index, &pStoredEntity, &pStoredEdict))
{
return NULL;
}
if (pStoredEdict == NULL || pStoredEntity == NULL)
{
return NULL;
}
IServerEntity *pSE = pStoredEdict->GetIServerEntity();
if (pSE == NULL)
{
return NULL;
}
if (pSE->GetRefEHandle() != hndl)
{
return NULL;
}
return pStoredEdict;
}
void CHalfLife2::SetHandleEntity(CBaseHandle &hndl, edict_t *pEnt)
{
IServerEntity *pEntOther = pEnt->GetIServerEntity();
if (pEntOther == NULL)
{
return;
}
hndl.Set(pEntOther);
}
const char *CHalfLife2::GetCurrentMap()
{
return STRING(gpGlobals->mapname);
}
void CHalfLife2::ServerCommand(const char *buffer)
{
engine->ServerCommand(buffer);
}
cell_t CHalfLife2::EntityToReference(CBaseEntity *pEntity)
{
IServerUnknown *pUnknown = (IServerUnknown *)pEntity;
CBaseHandle hndl = pUnknown->GetRefEHandle();
return (hndl.ToInt() | (1<<31));
}
CBaseEntity *CHalfLife2::ReferenceToEntity(cell_t entRef)
{
CEntInfo *pInfo = NULL;
if (entRef & (1<<31))
{
/* Proper ent reference */
int hndlValue = entRef & ~(1<<31);
CBaseHandle hndl(hndlValue);
pInfo = LookupEntity(hndl.GetEntryIndex());
if (pInfo->m_SerialNumber != hndl.GetSerialNumber())
{
return NULL;
}
}
else
{
/* Old style index only */
pInfo = LookupEntity(entRef);
}
if (!pInfo)
{
return NULL;
}
IServerUnknown *pUnk = static_cast<IServerUnknown *>(pInfo->m_pEntity);
if (pUnk)
{
return pUnk->GetBaseEntity();
}
return NULL;
}
/**
* Retrieves the CEntInfo pointer from g_EntList for a given entity index
*/
CEntInfo *CHalfLife2::LookupEntity(int entIndex)
{
// Make sure that our index is within the bounds of the global ent array
if (entIndex < 0 || entIndex >= NUM_ENT_ENTRIES)
{
return NULL;
}
if (!g_EntList || entInfoOffset == -1)
{
/* Attempt to use engine interface instead */
static CEntInfo tempInfo;
tempInfo.m_pNext = NULL;
tempInfo.m_pPrev = NULL;
edict_t *pEdict = PEntityOfEntIndex(entIndex);
if (!pEdict)
{
return NULL;
}
IServerUnknown *pUnk = pEdict->GetUnknown();
if (!pUnk)
{
return NULL;
}
tempInfo.m_pEntity = pUnk;
tempInfo.m_SerialNumber = pUnk->GetRefEHandle().GetSerialNumber();
return &tempInfo;
}
CEntInfo *pArray = (CEntInfo *)(((unsigned char *)g_EntList) + entInfoOffset);
return &pArray[entIndex];
}
/**
SERIAL_MASK = 0x7fff (15 bits)
#define MAX_EDICT_BITS 11
#define NUM_ENT_ENTRY_BITS (MAX_EDICT_BITS + 1)
m_Index = iEntry | (iSerialNumber << NUM_ENT_ENTRY_BITS);
Top 5 bits of a handle are unused.
Bit 31 - Our 'reference' flag indicator
*/
cell_t CHalfLife2::IndexToReference(int entIndex)
{
CBaseEntity *pEnt = ReferenceToEntity(entIndex);
if (!pEnt)
{
return INVALID_EHANDLE_INDEX;
}
return EntityToReference(pEnt);
}
int CHalfLife2::ReferenceToIndex(cell_t entRef)
{
if ((unsigned)entRef == INVALID_EHANDLE_INDEX)
{
return INVALID_EHANDLE_INDEX;
}
if (entRef & (1<<31))
{
/* Proper ent reference */
int hndlValue = entRef & ~(1<<31);
CBaseHandle hndl(hndlValue);
CEntInfo *pInfo = LookupEntity(hndl.GetEntryIndex());
if (pInfo->m_SerialNumber != hndl.GetSerialNumber())
{
return INVALID_EHANDLE_INDEX;
}
return hndl.GetEntryIndex();
}
return entRef;
}
cell_t CHalfLife2::EntityToBCompatRef(CBaseEntity *pEntity)
{
if (pEntity == NULL)
{
return INVALID_EHANDLE_INDEX;
}
IServerUnknown *pUnknown = (IServerUnknown *)pEntity;
CBaseHandle hndl = pUnknown->GetRefEHandle();
if (hndl.GetEntryIndex() >= MAX_EDICTS)
{
return (hndl.ToInt() | (1<<31));
}
else
{
return hndl.GetEntryIndex();
}
}
cell_t CHalfLife2::ReferenceToBCompatRef(cell_t entRef)
{
if ((unsigned)entRef == INVALID_EHANDLE_INDEX)
{
return INVALID_EHANDLE_INDEX;
}
int hndlValue = entRef & ~(1<<31);
CBaseHandle hndl(hndlValue);
if (hndl.GetEntryIndex() < MAX_EDICTS)
{
return hndl.GetEntryIndex();
}
return entRef;
}
void *CHalfLife2::GetGlobalEntityList()
{
return g_EntList;
}
int CHalfLife2::GetSendPropOffset(SendProp *prop)
{
return prop->GetOffset();
}
+38 -2
View File
@@ -43,6 +43,8 @@
#include <KeyValues.h>
#include <server_class.h>
#include <datamap.h>
#include <ihandleentity.h>
#include <tier0/icommandline.h>
class CCommand;
@@ -74,7 +76,7 @@ struct DelayedFakeCliCmd
struct CachedCommandInfo
{
const CCommand *args;
#if !defined ORANGEBOX_BUILD
#if SOURCE_ENGINE <= SE_DARKMESSIAH
char cmd[300];
#endif
};
@@ -86,6 +88,15 @@ struct DelayedKickInfo
char buffer[384];
};
class CEntInfo
{
public:
IHandleEntity *m_pEntity;
int m_SerialNumber;
CEntInfo *m_pPrev;
CEntInfo *m_pNext;
};
class CHalfLife2 :
public SMGlobalClass,
public IGameHelpers
@@ -96,6 +107,7 @@ public:
public:
void OnSourceModStartup(bool late);
void OnSourceModAllInitialized();
void OnSourceModAllInitialized_Post();
/*void OnSourceModAllShutdown();*/
public: //IGameHelpers
SendProp *FindInSendTable(const char *classname, const char *offset);
@@ -106,9 +118,26 @@ public: //IGameHelpers
void SetEdictStateChanged(edict_t *pEdict, unsigned short offset);
bool TextMsg(int client, int dest, const char *msg);
bool HintTextMsg(int client, const char *msg);
bool HintTextMsg(cell_t *players, int count, const char *msg);
bool ShowVGUIMenu(int client, const char *name, KeyValues *data, bool show);
bool IsLANServer();
bool KVLoadFromFile(KeyValues *kv, IBaseFileSystem *filesystem, const char *resourceName, const char *pathID = NULL);
edict_t *EdictOfIndex(int index);
int IndexOfEdict(edict_t *pEnt);
edict_t *GetHandleEntity(CBaseHandle &hndl);
void SetHandleEntity(CBaseHandle &hndl, edict_t *pEnt);
const char *GetCurrentMap();
void ServerCommand(const char *buffer);
CBaseEntity *ReferenceToEntity(cell_t entRef);
cell_t EntityToReference(CBaseEntity *pEntity);
cell_t IndexToReference(int entIndex);
int ReferenceToIndex(cell_t entRef);
cell_t ReferenceToBCompatRef(cell_t entRef);
CEntInfo *LookupEntity(int entIndex);
cell_t EntityToBCompatRef(CBaseEntity *pEntity);
void *GetGlobalEntityList();
int GetSendPropOffset(SendProp *prop);
ICommandLine *GetValveCommandLine();
public:
void AddToFakeCliCmdQueue(int client, int userid, const char *cmd);
void ProcessFakeCliCmdQueue();
@@ -119,24 +148,31 @@ public:
const char *CurrentCommandName();
void AddDelayedKick(int client, int userid, const char *msg);
void ProcessDelayedKicks();
#if !defined METAMOD_PLAPI_VERSION
#if !defined METAMOD_PLAPI_VERSION || PLAPI_VERSION < 11
bool IsOriginalEngine();
#endif
private:
DataTableInfo *_FindServerClass(const char *classname);
private:
void InitLogicalEntData();
void InitCommandLine();
private:
Trie *m_pClasses;
List<DataTableInfo *> m_Tables;
THash<datamap_t *, DataMapTrie> m_Maps;
int m_MsgTextMsg;
int m_HinTextMsg;
int m_SayTextMsg;
int m_VGUIMenu;
Queue<DelayedFakeCliCmd *> m_CmdQueue;
CStack<DelayedFakeCliCmd *> m_FreeCmds;
CStack<CachedCommandInfo> m_CommandStack;
Queue<DelayedKickInfo> m_DelayedKicks;
void *m_pGetCommandLine;
};
extern CHalfLife2 g_HL2;
bool IndexToAThings(cell_t, CBaseEntity **pEntData, edict_t **pEdictData);
#endif //_INCLUDE_SOURCEMOD_CHALFLIFE2_H_
+44 -3
View File
@@ -620,6 +620,43 @@ HandleError HandleSystem::CloneHandle(Handle_t handle, Handle_t *newhandle, Iden
return CloneHandle(pHandle, index, newhandle, newOwner);
}
Handle_t HandleSystem::FastCloneHandle(QHandle *pHandle, unsigned int index)
{
if (pHandle->clone)
return FastCloneHandle(&m_Handles[pHandle->clone], pHandle->clone);
Handle_t hndl;
if (CloneHandle(pHandle, index, &hndl, g_pCoreIdent) != HandleError_None)
return BAD_HANDLE;
return hndl;
}
Handle_t HandleSystem::FastCloneHandle(Handle_t hndl)
{
QHandle *pHandle;
unsigned int index;
GetHandleUnchecked(hndl, pHandle, index);
return FastCloneHandle(pHandle, index);
}
void HandleSystem::GetHandleUnchecked(Handle_t hndl, QHandle *& pHandle, unsigned int &index)
{
#ifndef NDEBUG
unsigned int serial = (hndl >> 16);
#endif
index = (hndl & HANDLESYS_HANDLE_MASK);
assert(index != 0 && index <= m_HandleTail && index < HANDLESYS_MAX_HANDLES);
pHandle = &m_Handles[index];
assert(pHandle->set && pHandle->set != HandleSet_Freed);
assert(pHandle->serial == serial);
}
HandleError HandleSystem::FreeHandle(QHandle *pHandle, unsigned int index)
{
QHandleType *pType = &m_Types[pHandle->type];
@@ -950,6 +987,10 @@ bool HandleSystem::InitAccessDefaults(TypeAccess *pTypeAccess, HandleAccess *pHa
return true;
}
#define HANDLE_LOG_VERY_BAD(message, ...) \
g_Logger.LogFatal(message, ##__VA_ARGS__); \
g_Logger.LogError(message, ##__VA_ARGS__);
bool HandleSystem::TryAndFreeSomeHandles()
{
IPluginIterator *pl_iter = g_PluginSys.GetPluginIterator();
@@ -995,9 +1036,9 @@ bool HandleSystem::TryAndFreeSomeHandles()
return false;
}
g_Logger.LogFatal("[SM] MEMORY LEAK DETECTED IN PLUGIN (file \"%s\")", highest_owner->GetFilename());
g_Logger.LogFatal("[SM] Reloading plugin to free %d handles.", highest_handle_count);
g_Logger.LogFatal("[SM] Contact the author(s) of this plugin to correct this error.", highest_handle_count);
HANDLE_LOG_VERY_BAD("[SM] MEMORY LEAK DETECTED IN PLUGIN (file \"%s\")", highest_owner->GetFilename());
HANDLE_LOG_VERY_BAD("[SM] Unloading plugin to free %d handles.", highest_handle_count);
HANDLE_LOG_VERY_BAD("[SM] Contact the author(s) of this plugin to correct this error.", highest_handle_count);
highest_owner->GetBaseContext()->ThrowNativeErrorEx(SP_ERROR_MEMACCESS, "Memory leak");
+29
View File
@@ -160,6 +160,9 @@ public: //IHandleSystem
HandleError *err);
void Dump(HANDLE_REPORTER rep);
/* Bypasses security checks. */
Handle_t FastCloneHandle(Handle_t hndl);
protected:
/**
* Decodes a handle with sanity and security checking.
@@ -170,6 +173,9 @@ protected:
unsigned int *index,
bool ignoreFree=false);
Handle_t FastCloneHandle(QHandle *pHandle, unsigned int index);
void GetHandleUnchecked(Handle_t hndl, QHandle *& pHandle, unsigned int &index);
/**
* Creates a basic handle and sets its reference count to 1.
* Does not do any type or security checking.
@@ -222,4 +228,27 @@ private:
extern HandleSystem g_HandleSys;
struct AutoHandleRooter
{
public:
AutoHandleRooter(Handle_t hndl)
{
if (hndl != BAD_HANDLE)
this->hndl = g_HandleSys.FastCloneHandle(hndl);
else
this->hndl = BAD_HANDLE;
}
~AutoHandleRooter()
{
if (hndl != BAD_HANDLE)
{
HandleSecurity sec(g_pCoreIdent, g_pCoreIdent);
g_HandleSys.FreeHandle(hndl, &sec);
}
}
private:
Handle_t hndl;
};
#endif //_INCLUDE_SOURCEMOD_HANDLESYSTEM_H_
+12 -10
View File
@@ -241,7 +241,7 @@ bool LibrarySystem::IsPathDirectory(const char *path)
return true;
}
#elif defined PLATFORM_LINUX
#elif defined PLATFORM_POSIX
struct stat s;
if (stat(path, &s) != 0)
@@ -285,14 +285,16 @@ void LibrarySystem::GetPlatformErrorEx(int code, char *error, size_t maxlength)
if (error && maxlength)
{
#if defined PLATFORM_WINDOWS
FormatMessageA(
FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
(DWORD)code,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPSTR)error,
maxlength,
NULL);
if (FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
(DWORD)code,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPSTR)error,
maxlength,
NULL) == 0)
{
UTIL_Format(error, maxlength, "error code %08x", code);
}
#elif defined PLATFORM_LINUX
const char *ae = strerror_r(code, error, maxlength);
if (ae != error)
@@ -408,7 +410,7 @@ size_t LibrarySystem::GetFileFromPath(char *buffer, size_t maxlength, const char
size_t length = strlen(path);
for (size_t i = length - 1;
i >= 0 && i <= length - 1;
i <= length - 1;
i--)
{
if (path[i] == '/'
+13 -8
View File
@@ -1,8 +1,8 @@
/**
* vim: set ts=4 :
* vim: set ts=4 sw=4 :
* =============================================================================
* SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
* Copyright (C) 2004-2009 AlliedModders LLC. All rights reserved.
* =============================================================================
*
* This program is free software; you can redistribute it and/or modify it under
@@ -36,7 +36,7 @@
#include "Logger.h"
#include "LibrarySys.h"
#include "TimerSys.h"
#include "sm_version.h"
#include <sourcemod_version.h>
Logger g_Logger;
@@ -149,7 +149,7 @@ void Logger::_NewMapFile()
} 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, SVN_FULL_VERSION);
fprintf(fp, "L %s: SourceMod log file started (file \"L%02d%02d%03d.log\") (Version \"%s\")\n", date, curtime->tm_mon + 1, curtime->tm_mday, i, SM_FULL_VERSION);
fclose(fp);
}
}
@@ -356,7 +356,7 @@ void Logger::LogMessage(const char *vafmt, ...)
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, SVN_FULL_VERSION);
fprintf(fp, "L %s: SourceMod log file session started (file \"L%04d%02d%02d.log\") (Version \"%s\")\n", date, curtime->tm_year + 1900, curtime->tm_mon + 1, curtime->tm_mday, SM_FULL_VERSION);
}
va_list ap;
va_start(ap, vafmt);
@@ -378,6 +378,14 @@ print_error:
}
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)
{
@@ -408,10 +416,7 @@ void Logger::LogError(const char *vafmt, ...)
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;
}
va_list ap;
va_start(ap, vafmt);
LogToOpenFileEx(fp, vafmt, ap);
va_end(ap);
fclose(fp);
}
else
+1
View File
@@ -75,6 +75,7 @@ public:
void DisableLogging();
void LogMessage(const char *msg, ...);
void LogError(const char *msg, ...);
void LogErrorEx(const char *msg, va_list ap);
void LogFatal(const char *msg, ...);
void LogToOpenFile(FILE *fp, const char *msg, ...);
void LogToOpenFileEx(FILE *fp, const char *msg, va_list ap);
+95 -45
View File
@@ -2,38 +2,39 @@
# Makefile written by David "BAILOPAN" Anderson
SMSDK = ..
SRCDS_BASE = ~/srcds
HL2SDK_ORIG = ../../hl2sdk
HL2SDK_OB = ../../hl2sdk-ob
MMSOURCE17 = ../../mmsource-1.7
HL2SDK_OB_VALVE = ../../hl2sdk-ob-valve
HL2SDK_L4D = ../../hl2sdk-l4d
HL2SDK_L4D2 = ../../hl2sdk-l4d2
MMSOURCE = ../../mmsource-central
#####################################
### EDIT BELOW FOR OTHER PROJECTS ###
#####################################
OBJECTS = AdminCache.cpp CDataPack.cpp ConCmdManager.cpp ConVarManager.cpp CoreConfig.cpp \
Database.cpp DebugReporter.cpp EventManager.cpp GameConfigs.cpp HalfLife2.cpp Logger.cpp \
MemoryUtils.cpp PlayerManager.cpp TextParsers.cpp TimerSys.cpp Translator.cpp UserMessages.cpp \
sm_autonatives.cpp sm_memtable.cpp sm_srvcmds.cpp sm_stringutil.cpp sm_trie.cpp \
Database.cpp DebugReporter.cpp EventManager.cpp HalfLife2.cpp Logger.cpp \
PlayerManager.cpp TimerSys.cpp UserMessages.cpp \
sm_autonatives.cpp sm_srvcmds.cpp sm_stringutil.cpp sm_trie.cpp \
sourcemm_api.cpp sourcemod.cpp MenuStyle_Base.cpp MenuStyle_Valve.cpp MenuManager.cpp \
MenuStyle_Radio.cpp ChatTriggers.cpp ADTFactory.cpp MenuVoting.cpp sm_crc32.cpp \
frame_hooks.cpp concmd_cleaner.cpp Profiler.cpp PhraseCollection.cpp NextMap.cpp \
NativeOwner.cpp GameDataFetcher.cpp md5.cpp
OBJECTS += smn_admin.cpp smn_bitbuffer.cpp smn_console.cpp smn_core.cpp \
smn_datapacks.cpp smn_entities.cpp smn_events.cpp smn_fakenatives.cpp \
smn_filesystem.cpp smn_float.cpp smn_functions.cpp smn_gameconfigs.cpp smn_halflife.cpp \
smn_handles.cpp smn_keyvalues.cpp smn_banning.cpp smn_maplists.cpp \
smn_lang.cpp smn_player.cpp smn_string.cpp smn_sorting.cpp smn_textparse.cpp smn_timers.cpp \
smn_usermsgs.cpp smn_menus.cpp smn_database.cpp smn_vector.cpp smn_adt_array.cpp \
smn_adt_trie.cpp smn_hudtext.cpp smn_adt_stack.cpp smn_nextmap.cpp
MenuStyle_Radio.cpp ChatTriggers.cpp ADTFactory.cpp MenuVoting.cpp \
frame_hooks.cpp concmd_cleaner.cpp NextMap.cpp \
NativeOwner.cpp logic_bridge.cpp ConsoleDetours.cpp
OBJECTS += smn_bitbuffer.cpp smn_console.cpp smn_core.cpp \
smn_entities.cpp smn_events.cpp smn_fakenatives.cpp \
smn_filesystem.cpp smn_halflife.cpp \
smn_keyvalues.cpp smn_player.cpp \
smn_usermsgs.cpp smn_menus.cpp smn_vector.cpp \
smn_hudtext.cpp smn_nextmap.cpp
OBJECTS += ExtensionSys.cpp \
ForwardSys.cpp \
HandleSys.cpp \
LibrarySys.cpp \
PluginInfoDatabase.cpp \
PluginSys.cpp \
ShareSys.cpp
OBJECTS += thread/ThreadWorker.cpp thread/BaseWorker.cpp thread/PosixThreads.cpp ThreadSupport.cpp
ShareSys.cpp \
NativeInvoker.cpp
##############################################
### CONFIGURE ANY OTHER FLAGS/OPTIONS HERE ###
@@ -46,30 +47,81 @@ CPP_GCC4_FLAGS = -fvisibility-inlines-hidden
CPP = gcc
override ENGSET = false
ifeq "$(ENGINE)" "original"
HL2SDK = $(HL2SDK_ORIG)
HL2PUB = $(HL2SDK_ORIG)/public
HL2LIB = $(HL2SDK_ORIG)/linux_sdk
METAMOD = $(MMSOURCE17)/core-legacy
INCLUDE += -I$(HL2SDK)/public/dlls
SRCDS = $(SRCDS_BASE)
BINARY = sourcemod.1.ep1.so
override ENGSET = true
endif
ifeq "$(ENGINE)" "orangebox"
HL2SDK = $(HL2SDK_OB)
HL2PUB = $(HL2SDK_OB)/public
HL2LIB = $(HL2SDK_OB)/lib/linux
CFLAGS += -DORANGEBOX_BUILD
METAMOD = $(MMSOURCE17)/core
INCLUDE += -I$(HL2SDK)/public/game/server
SRCDS = $(SRCDS_BASE)/orangebox
BINARY = sourcemod.2.ep2.so
ifneq (,$(filter original orangebox orangeboxvalve left4dead left4dead2,$(ENGINE)))
override ENGSET = true
endif
LINK += $(HL2LIB)/tier1_i486.a $(HL2LIB)/mathlib_i486.a vstdlib_i486.so \
tier0_i486.so -lpthread -static-libgcc
ifeq "$(ENGINE)" "original"
HL2SDK = $(HL2SDK_ORIG)
HL2LIB = $(HL2SDK)/linux_sdk
CFLAGS += -DSOURCE_ENGINE=1
METAMOD = $(MMSOURCE)/core-legacy
INCLUDE += -I$(HL2SDK)/public/dlls
BINARY = sourcemod.1.ep1.so
endif
ifeq "$(ENGINE)" "orangebox"
HL2SDK = $(HL2SDK_OB)
HL2LIB = $(HL2SDK)/lib/linux
CFLAGS += -DSOURCE_ENGINE=3
METAMOD = $(MMSOURCE)/core
INCLUDE += -I$(HL2SDK)/public/game/server
BINARY = sourcemod.2.ep2.so
endif
ifeq "$(ENGINE)" "orangeboxvalve"
HL2SDK = $(HL2SDK_OB_VALVE)
HL2LIB = $(HL2SDK)/lib/linux
CFLAGS += -DSOURCE_ENGINE=6
METAMOD = $(MMSOURCE)/core
INCLUDE += -I$(HL2SDK)/public/game/server
#-I$(HL2SDK)/common
BINARY = sourcemod.2.ep2v.so
endif
ifeq "$(ENGINE)" "left4dead"
HL2SDK = $(HL2SDK_L4D)
HL2LIB = $(HL2SDK)/lib/linux
CFLAGS += -DSOURCE_ENGINE=7
METAMOD = $(MMSOURCE)/core
INCLUDE += -I$(HL2SDK)/public/game/server
BINARY = sourcemod.2.l4d.so
endif
ifeq "$(ENGINE)" "left4dead2"
HL2SDK = $(HL2SDK_L4D2)
HL2LIB = $(HL2SDK)/lib/linux
CFLAGS += -DSOURCE_ENGINE=8
METAMOD = $(MMSOURCE)/core
INCLUDE += -I$(HL2SDK)/public/game/server
BINARY = sourcemod.2.l4d2.so
endif
HL2PUB = $(HL2SDK)/public
OS := $(shell uname -s)
ifeq "$(OS)" "Darwin"
LIB_EXT = dylib
HL2LIB = $(HL2SDK)/lib/mac
else
LIB_EXT = so
ifeq "$(ENGINE)" "original"
HL2LIB = $(HL2SDK)/linux_sdk
else
HL2LIB = $(HL2SDK)/lib/linux
endif
endif
ifneq (,$(filter original orangebox left4dead,$(ENGINE)))
LIB_SUFFIX = _i486.$(LIB_EXT)
else
LIB_PREFIX = lib
LIB_SUFFIX = .$(LIB_EXT)
endif
CFLAGS += -DSE_EPISODEONE=1 -DSE_DARKMESSIAH=2 -DSE_ORANGEBOX=3 -DSE_BLOODYGOODTIME=4 -DSE_EYE=5 \
-DSE_ORANGEBOXVALVE=6 -DSE_LEFT4DEAD=7 -DSE_LEFT4DEAD2=8 -DSE_ALIENSWARM=9
LINK += $(HL2LIB)/tier1_i486.a $(HL2LIB)/mathlib_i486.a $(LIB_PREFIX)vstdlib$(LIB_SUFFIX) \
$(LIB_PREFIX)tier0$(LIB_SUFFIX) -static-libgcc
INCLUDE += -I. -I.. -I$(HL2PUB) -I$(HL2PUB)/engine -I$(HL2PUB)/mathlib -I$(HL2PUB)/vstdlib \
-I$(HL2PUB)/tier0 -I$(HL2PUB)/tier1 -I$(METAMOD) -I$(METAMOD)/sourcehook \
@@ -108,15 +160,15 @@ $(BIN_DIR)/%.o: %.c
$(CPP) $(INCLUDE) $(CFLAGS) -o $@ -c $<
all: check
mkdir -p $(BIN_DIR)/systems
mkdir -p $(BIN_DIR)/thread
ln -sf $(SRCDS)/bin/vstdlib_i486.so vstdlib_i486.so;
ln -sf $(SRCDS)/bin/tier0_i486.so tier0_i486.so;
mkdir -p $(BIN_DIR)
ln -sf $(HL2LIB)/$(LIB_PREFIX)vstdlib$(LIB_SUFFIX)
ln -sf $(HL2LIB)/$(LIB_PREFIX)tier0$(LIB_SUFFIX)
$(MAKE) -f Makefile sourcemod
check:
if [ "$(ENGSET)" = "false" ]; then \
echo "You must supply ENGINE=orangebox or ENGINE=original"; \
echo "You must supply one of the following values for ENGINE:"; \
echo "left4dead2, left4dead, orangeboxvalve, orangebox, or original"; \
exit 1; \
fi
@@ -130,6 +182,4 @@ default: all
clean: check
rm -rf $(BIN_DIR)/*.o
rm -rf $(BIN_DIR)/systems/*.o
rm -rf $(BIN_DIR)/thread/*.o
rm -rf $(BIN_DIR)/$(BINARY)
-220
View File
@@ -1,220 +0,0 @@
/**
* vim: set ts=4 :
* =============================================================================
* SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
* =============================================================================
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, version 3.0, as published by the
* Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*
* As a special exception, AlliedModders LLC gives you permission to link the
* code of this program (as well as its derivative works) to "Half-Life 2," the
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
* by the Valve Corporation. You must obey the GNU General Public License in
* all respects for all other code used. Additionally, AlliedModders LLC grants
* this exception to all derivative works. AlliedModders LLC defines further
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
* or <http://www.sourcemod.net/license.php>.
*
* Version: $Id$
*/
#include "MemoryUtils.h"
#include "ShareSys.h"
#ifdef PLATFORM_LINUX
#include <string.h>
#include <elf.h>
#endif
MemoryUtils g_MemUtils;
#if 0
MemoryUtils::MemoryUtils()
{
#ifdef PLATFORM_WINDOWS
SYSTEM_INFO info;
GetSystemInfo(&info);
m_PageSize = info.dwPageSize;
#elif defined PLATFORM_POSIX
m_PageSize = sysconf(_SC_PAGE_SIZE);
#endif
}
#endif
void MemoryUtils::OnSourceModAllInitialized()
{
g_ShareSys.AddInterface(NULL, this);
}
void *MemoryUtils::FindPattern(const void *libPtr, const char *pattern, size_t len)
{
DynLibInfo lib;
bool found;
char *ptr, *end;
memset(&lib, 0, sizeof(DynLibInfo));
if (!GetLibraryInfo(libPtr, lib))
{
return NULL;
}
ptr = reinterpret_cast<char *>(lib.baseAddress);
end = ptr + lib.memorySize;
while (ptr < end)
{
found = true;
for (register size_t i = 0; i < len; i++)
{
if (pattern[i] != '\x2A' && pattern[i] != ptr[i])
{
found = false;
break;
}
}
if (found)
return ptr;
ptr++;
}
return NULL;
}
bool MemoryUtils::GetLibraryInfo(const void *libPtr, DynLibInfo &lib)
{
unsigned long baseAddr;
if (libPtr == NULL)
{
return false;
}
#ifdef PLATFORM_WINDOWS
MEMORY_BASIC_INFORMATION info;
IMAGE_DOS_HEADER *dos;
IMAGE_NT_HEADERS *pe;
IMAGE_FILE_HEADER *file;
IMAGE_OPTIONAL_HEADER *opt;
if (!VirtualQuery(libPtr, &info, sizeof(MEMORY_BASIC_INFORMATION)))
{
return false;
}
baseAddr = reinterpret_cast<unsigned long>(info.AllocationBase);
/* All this is for our insane sanity checks :o */
dos = reinterpret_cast<IMAGE_DOS_HEADER *>(baseAddr);
pe = reinterpret_cast<IMAGE_NT_HEADERS *>(baseAddr + dos->e_lfanew);
file = &pe->FileHeader;
opt = &pe->OptionalHeader;
/* Check PE magic and signature */
if (dos->e_magic != IMAGE_DOS_SIGNATURE || pe->Signature != IMAGE_NT_SIGNATURE || opt->Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC)
{
return false;
}
/* Check architecture, which is 32-bit/x86 right now
* Should change this for 64-bit if Valve gets their act together
*/
if (file->Machine != IMAGE_FILE_MACHINE_I386)
{
return false;
}
/* For our purposes, this must be a dynamic library */
if ((file->Characteristics & IMAGE_FILE_DLL) == 0)
{
return false;
}
/* Finally, we can do this */
lib.memorySize = opt->SizeOfImage;
#elif defined PLATFORM_LINUX
Dl_info info;
Elf32_Ehdr *file;
Elf32_Phdr *phdr;
uint16_t phdrCount;
if (!dladdr(libPtr, &info))
{
return false;
}
if (!info.dli_fbase || !info.dli_fname)
{
return false;
}
/* This is for our insane sanity checks :o */
baseAddr = reinterpret_cast<unsigned long>(info.dli_fbase);
file = reinterpret_cast<Elf32_Ehdr *>(baseAddr);
/* Check ELF magic */
if (memcmp(ELFMAG, file->e_ident, SELFMAG) != 0)
{
return false;
}
/* Check ELF version */
if (file->e_ident[EI_VERSION] != EV_CURRENT)
{
return false;
}
/* Check ELF architecture, which is 32-bit/x86 right now
* Should change this for 64-bit if Valve gets their act together
*/
if (file->e_ident[EI_CLASS] != ELFCLASS32 || file->e_machine != EM_386 || file->e_ident[EI_DATA] != ELFDATA2LSB)
{
return false;
}
/* For our purposes, this must be a dynamic library/shared object */
if (file->e_type != ET_DYN)
{
return false;
}
phdrCount = file->e_phnum;
phdr = reinterpret_cast<Elf32_Phdr *>(baseAddr + file->e_phoff);
/* Add up the memory sizes of segments marked as PT_LOAD as those are the only ones that should be in memory */
for (uint16_t i = 0; i < phdrCount; i++)
{
Elf32_Phdr &hdr = phdr[i];
if (hdr.p_type == PT_LOAD)
{
lib.memorySize += hdr.p_memsz;
}
}
#endif
lib.baseAddress = reinterpret_cast<void *>(baseAddr);
return true;
}
+32 -6
View File
@@ -41,7 +41,7 @@
#include "ShareSys.h"
#include "HandleSys.h"
#include "sourcemm_api.h"
#include "Translator.h"
#include "logic_bridge.h"
MenuManager g_Menus;
VoteMenuHandler s_VoteHandler;
@@ -231,6 +231,7 @@ IMenuPanel *MenuManager::RenderMenu(int client, menu_states_t &md, ItemOrder ord
unsigned int pgn = menu->GetPagination();
unsigned int maxItems = style->GetMaxPageItems();
bool exitButton = (menu->GetMenuOptionFlags() & MENUFLAG_BUTTON_EXIT) == MENUFLAG_BUTTON_EXIT;
bool novoteButton = (menu->GetMenuOptionFlags() & MENUFLAG_BUTTON_NOVOTE) == MENUFLAG_BUTTON_NOVOTE;
if (pgn != MENU_NO_PAGINATION)
{
@@ -241,6 +242,11 @@ IMenuPanel *MenuManager::RenderMenu(int client, menu_states_t &md, ItemOrder ord
maxItems--;
}
if (novoteButton)
{
maxItems--;
}
/* This is very not allowed! */
if (maxItems < 2)
{
@@ -436,6 +442,20 @@ skip_search:
/* Draw the item according to the order */
menu_slots_t *slots = md.slots;
unsigned int position = 0; /* Keep track of the last position */
if (novoteButton)
{
char text[50];
if (!logicore.CoreTranslate(text, sizeof(text), "%T", 2, NULL, "No Vote", &client))
{
UTIL_Format(text, sizeof(text), "No Vote");
}
ItemDrawInfo dr(text, 0);
position = panel->DrawItem(dr);
slots[position].type = ItemSel_Exit;
position++;
}
if (order == ItemOrder_Ascending)
{
md.item_on_page = drawItems[0].position;
@@ -586,7 +606,7 @@ skip_search:
{
if (exitBackButton)
{
if (!CoreTranslate(text, sizeof(text), "%T", 2, NULL, "Back", &client))
if (!logicore.CoreTranslate(text, sizeof(text), "%T", 2, NULL, "Back", &client))
{
UTIL_Format(text, sizeof(text), "Back");
}
@@ -596,7 +616,7 @@ skip_search:
}
else
{
if (!CoreTranslate(text, sizeof(text), "%T", 2, NULL, "Previous", &client))
if (!logicore.CoreTranslate(text, sizeof(text), "%T", 2, NULL, "Previous", &client))
{
UTIL_Format(text, sizeof(text), "Previous");
}
@@ -617,7 +637,7 @@ skip_search:
/* NEXT */
if (displayNext || canDrawDisabled)
{
if (!CoreTranslate(text, sizeof(text), "%T", 2, NULL, "Next", &client))
if (!logicore.CoreTranslate(text, sizeof(text), "%T", 2, NULL, "Next", &client))
{
UTIL_Format(text, sizeof(text), "Next");
}
@@ -648,7 +668,7 @@ skip_search:
/* EXIT */
if (exitButton)
{
if (!CoreTranslate(text, sizeof(text), "%T", 2, NULL, "Exit", &client))
if (!logicore.CoreTranslate(text, sizeof(text), "%T", 2, NULL, "Exit", &client))
{
UTIL_Format(text, sizeof(text), "Exit");
}
@@ -798,5 +818,11 @@ bool MenuManager::IsClientInVotePool(int client)
bool MenuManager::RedrawClientVoteMenu(int client)
{
return s_VoteHandler.RedrawToClient(client);
return RedrawClientVoteMenu2(client, true);
}
bool MenuManager::RedrawClientVoteMenu2(int client, bool revote)
{
return s_VoteHandler.RedrawToClient(client, revote);
}
+1
View File
@@ -91,6 +91,7 @@ public:
unsigned int GetRemainingVoteDelay();
bool IsClientInVotePool(int client);
bool RedrawClientVoteMenu(int client);
bool RedrawClientVoteMenu2(int client, bool revote);
public: //IHandleTypeDispatch
void OnHandleDestroy(HandleType_t type, void *object);
bool GetHandleApproxSize(HandleType_t type, void *object, unsigned int *pSize);
+4 -1
View File
@@ -314,7 +314,7 @@ void BaseMenuStyle::ClientPressedKey(int client, unsigned int key_press)
if (sound != NULL)
{
edict_t *pEdict = engine->PEntityOfEntIndex(client);
edict_t *pEdict = PEntityOfEntIndex(client);
if (pEdict)
{
ICollideable *pCollideable = pEdict->GetCollideable();
@@ -377,6 +377,9 @@ void BaseMenuStyle::ClientPressedKey(int client, unsigned int key_press)
RemoveClientFromWatch(client);
}
Handle_t hndl = menu ? menu->GetHandle() : BAD_HANDLE;
AutoHandleRooter ahr(hndl);
if (cancel)
{
mh->OnMenuCancel(menu, client, reason);
+2 -1
View File
@@ -32,11 +32,12 @@
#include "MenuStyle_Radio.h"
#include "sm_stringutil.h"
#include "UserMessages.h"
#include "GameConfigs.h"
#include <IGameConfigs.h>
#include "PlayerManager.h"
#if defined MENU_DEBUG
#include "Logger.h"
#endif
#include "logic_bridge.h"
extern const char *g_RadioNumTable[];
CRadioStyle g_RadioMenuStyle;
+2 -3
View File
@@ -32,7 +32,6 @@
#include "sm_stringutil.h"
#include "PlayerManager.h"
#include "MenuStyle_Valve.h"
#include "Translator.h"
#include "PlayerManager.h"
#include "ConCmdManager.h"
@@ -88,7 +87,7 @@ void ValveMenuStyle::HookCreateMessage(edict_t *pEdict,
return;
}
int client = engine->IndexOfEdict(pEdict);
int client = IndexOfEdict(pEdict);
if (client < 1 || client > 256)
{
return;
@@ -325,7 +324,7 @@ void CValveMenuDisplay::SendRawDisplay(int client, int priority, unsigned int ti
m_pKv->SetInt("time", time ? time : 200);
SH_CALL(g_pSPHCC, &IServerPluginHelpers::CreateMessage)(
engine->PEntityOfEntIndex(client),
PEntityOfEntIndex(client),
DIALOG_MENU,
m_pKv,
vsp_interface);
+222 -12
View File
@@ -1,8 +1,8 @@
/**
* vim: set ts=4 :
* vim: set ts=4 sw=4 :
* =============================================================================
* SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
* Copyright (C) 2004-2009 AlliedModders LLC. All rights reserved.
* =============================================================================
*
* This program is free software; you can redistribute it and/or modify it under
@@ -34,10 +34,57 @@
#include "MenuVoting.h"
#include "PlayerManager.h"
#include "sourcemm_api.h"
#include <sourcemod.h>
#include <Logger.h>
#include <HalfLife2.h>
#include <mathlib.h>
#include <const.h>
#include <ITranslator.h>
#include "logic_bridge.h"
float g_next_vote = 0.0f;
#if defined ORANGEBOX_BUILD
#define VOTE_NOT_VOTING -2
#define VOTE_PENDING -1
ConVar sm_vote_hintbox("sm_vote_progress_hintbox",
"0",
0,
"Show current vote progress in a hint box",
true,
0.0,
true,
1.0);
ConVar sm_vote_chat("sm_vote_progress_chat",
"0",
0,
"Show current vote progress as chat messages",
true,
0.0,
true,
1.0);
ConVar sm_vote_console("sm_vote_progress_console",
"0",
0,
"Show current vote progress as console messages",
true,
0.0,
true,
1.0);
ConVar sm_vote_client_console("sm_vote_progress_client_console",
"0",
0,
"Show current vote progress as console messages to clients",
true,
0.0,
true,
1.0);
#if SOURCE_ENGINE >= SE_ORANGEBOX
void OnVoteDelayChange(IConVar *cvar, const char *value, float flOldValue);
#else
void OnVoteDelayChange(ConVar *cvar, const char *value);
@@ -52,7 +99,7 @@ ConVar sm_vote_delay("sm_vote_delay",
0.0,
OnVoteDelayChange);
#if defined ORANGEBOX_BUILD
#if SOURCE_ENGINE >= SE_ORANGEBOX
void OnVoteDelayChange(IConVar *cvar, const char *value, float flOldValue)
#else
void OnVoteDelayChange(ConVar *cvar, const char *value)
@@ -117,7 +164,7 @@ void VoteMenuHandler::OnClientDisconnected(int client)
* newly connected client is not allowed to vote.
*/
int item;
if ((item = m_ClientVotes[client]) >= -1)
if ((item = m_ClientVotes[client]) >= VOTE_PENDING)
{
if (item >= 0)
{
@@ -125,7 +172,7 @@ void VoteMenuHandler::OnClientDisconnected(int client)
assert(m_Votes[item] > 0);
m_Votes[item]--;
}
m_ClientVotes[client] = -2;
m_ClientVotes[client] = VOTE_NOT_VOTING;
}
}
@@ -189,13 +236,13 @@ bool VoteMenuHandler::IsClientInVotePool(int client)
return false;
}
return (m_ClientVotes[client] > -2);
return (m_ClientVotes[client] > VOTE_NOT_VOTING);
}
bool VoteMenuHandler::GetClientVoteChoice(int client, unsigned int *pItem)
{
if (!IsClientInVotePool(client)
|| m_ClientVotes[client] == -1)
|| m_ClientVotes[client] == VOTE_PENDING)
{
return false;
}
@@ -205,7 +252,7 @@ bool VoteMenuHandler::GetClientVoteChoice(int client, unsigned int *pItem)
return true;
}
bool VoteMenuHandler::RedrawToClient(int client)
bool VoteMenuHandler::RedrawToClient(int client, bool revotes)
{
unsigned int time_limit;
@@ -214,6 +261,20 @@ bool VoteMenuHandler::RedrawToClient(int client)
return false;
}
if (m_ClientVotes[client] >= 0)
{
if ((m_VoteFlags & VOTEFLAG_NO_REVOTES) == VOTEFLAG_NO_REVOTES || !revotes)
{
return false;
}
assert((unsigned)m_ClientVotes[client] < m_Items);
assert(m_Votes[m_ClientVotes[client]] > 0);
m_Votes[m_ClientVotes[client]]--;
m_ClientVotes[client] = VOTE_PENDING;
m_Revoting[client] = true;
m_NumVotes--;
}
if (m_nMenuTime == MENU_TIME_FOREVER)
{
time_limit = m_nMenuTime;
@@ -247,7 +308,8 @@ bool VoteMenuHandler::InitializeVoting(IBaseMenu *menu,
/* Mark all clients as not voting */
for (int i=1; i<=gpGlobals->maxClients; i++)
{
m_ClientVotes[i] = -2;
m_ClientVotes[i] = VOTE_NOT_VOTING;
m_Revoting[i] = false;
}
m_Items = menu->GetItemCount();
@@ -291,6 +353,8 @@ void VoteMenuHandler::StartVoting()
m_pHandler->OnMenuVoteStart(m_pCurMenu);
m_displayTimer = g_Timers.CreateTimer(this, 1.0, NULL, TIMER_FLAG_REPEAT|TIMER_FLAG_NO_MAPCHANGE);
/* By now we know how many clients were set.
* If there are none, we should end IMMEDIATELY.
*/
@@ -298,6 +362,8 @@ void VoteMenuHandler::StartVoting()
{
EndVoting();
}
m_TotalClients = m_Clients;
}
void VoteMenuHandler::DecrementPlayerCount()
@@ -334,6 +400,11 @@ void VoteMenuHandler::EndVoting()
g_next_vote = gpGlobals->curtime + fVoteDelay;
}
if (m_displayTimer)
{
g_Timers.KillTimer(m_displayTimer);
}
if (m_bCancelled)
{
/* If we were cancelled, don't bother tabulating anything.
@@ -380,7 +451,7 @@ void VoteMenuHandler::EndVoting()
/* Build the client list */
for (int i=1; i<=gpGlobals->maxClients; i++)
{
if (m_ClientVotes[i] >= -1)
if (m_ClientVotes[i] >= VOTE_PENDING)
{
client_vote[vote.num_clients].client = i;
client_vote[vote.num_clients].item = m_ClientVotes[i];
@@ -424,7 +495,7 @@ void VoteMenuHandler::OnMenuCancel(IBaseMenu *menu, int client, MenuCancelReason
void VoteMenuHandler::OnMenuDisplay(IBaseMenu *menu, int client, IMenuPanel *display)
{
m_ClientVotes[client] = -1;
m_ClientVotes[client] = VOTE_PENDING;
m_pHandler->OnMenuDisplay(menu, client, display);
}
@@ -446,6 +517,58 @@ void VoteMenuHandler::OnMenuSelect(IBaseMenu *menu, int client, unsigned int ite
m_ClientVotes[client] = item;
m_Votes[item]++;
m_NumVotes++;
if (sm_vote_chat.GetBool() || sm_vote_console.GetBool())
{
static char buffer[1024];
ItemDrawInfo dr;
menu->GetItemInfo(item, &dr);
if (sm_vote_console.GetBool())
{
int target = SOURCEMOD_SERVER_LANGUAGE;
logicore.CoreTranslate(buffer, sizeof(buffer), "[SM] %T", 4, NULL, "Voted For",
&target, g_Players.GetPlayerByIndex(client)->GetName(), dr.display);
Engine_LogPrintWrapper(buffer);
}
if (sm_vote_chat.GetBool() || sm_vote_client_console.GetBool())
{
int maxclients = g_Players.GetMaxClients();
for (int i=1; i<=maxclients; i++)
{
CPlayer *pPlayer = g_Players.GetPlayerByIndex(i);
assert(pPlayer);
if (pPlayer->IsInGame() && !pPlayer->IsFakeClient())
{
if (m_Revoting[client])
{
logicore.CoreTranslate(buffer, sizeof(buffer), "[SM] %T", 4, NULL, "Changed Vote",
&i, g_Players.GetPlayerByIndex(client)->GetName(), dr.display);
}
else
{
logicore.CoreTranslate(buffer, sizeof(buffer), "[SM] %T", 4, NULL, "Voted For",
&i, g_Players.GetPlayerByIndex(client)->GetName(), dr.display);
}
if (sm_vote_chat.GetBool())
{
g_HL2.TextMsg(i, HUD_PRINTTALK, buffer);
}
if (sm_vote_client_console.GetBool())
{
engine->ClientPrintf(pPlayer->GetEdict(), buffer);
}
}
}
}
}
BuildVoteLeaders();
DrawHintProgress();
}
m_pHandler->OnMenuSelect(menu, client, item);
@@ -468,6 +591,9 @@ void VoteMenuHandler::InternalReset()
m_NumVotes = 0;
m_bCancelled = false;
m_pHandler = NULL;
m_leaderList[0] = '\0';
m_displayTimer = NULL;
m_TotalClients = 0;
}
void VoteMenuHandler::CancelVoting()
@@ -489,3 +615,87 @@ bool VoteMenuHandler::IsCancelling()
{
return m_bCancelled;
}
void VoteMenuHandler::DrawHintProgress()
{
if (!sm_vote_hintbox.GetBool())
{
return;
}
static char buffer[1024];
float timeRemaining = (m_fStartTime + m_nMenuTime) - gpGlobals->curtime;
if (timeRemaining < 0)
{
timeRemaining = 0.0;
}
int iTimeRemaining = RoundFloatToInt(timeRemaining);
int maxclients = g_Players.GetMaxClients();
for (int i=1; i<=maxclients; i++)
{
if (g_Players.GetPlayerByIndex(i)->IsInGame())
{
logicore.CoreTranslate(buffer, sizeof(buffer), "%T%s", 6, NULL, "Vote Count",
&i, &m_NumVotes, &m_TotalClients, &iTimeRemaining, &m_leaderList);
g_HL2.HintTextMsg(i, buffer);
}
}
}
void VoteMenuHandler::BuildVoteLeaders()
{
if (m_NumVotes == 0 || !sm_vote_hintbox.GetBool())
{
return;
}
menu_vote_result_t vote;
menu_vote_result_t::menu_item_vote_t item_vote[256];
memset(&vote, 0, sizeof(vote));
/* Build the item list */
for (unsigned int i=0; i<m_Items; i++)
{
if (m_Votes[i] > 0)
{
item_vote[vote.num_items].count = m_Votes[i];
item_vote[vote.num_items].item = i;
vote.num_votes += m_Votes[i];
vote.num_items++;
}
}
vote.item_list = item_vote;
assert(vote.num_votes);
/* Sort the item list descending */
qsort(item_vote,
vote.num_items,
sizeof(menu_vote_result_t::menu_item_vote_t),
SortVoteItems);
/* Take the top 3 (if applicable) and draw them */
int len = 0;
for (unsigned int i=0; i<vote.num_items && i<3; i++)
{
int curItem = vote.item_list[i].item;
ItemDrawInfo dr;
m_pCurMenu->GetItemInfo(curItem, &dr);
len += g_SourceMod.Format(m_leaderList + len, sizeof(m_leaderList) - len, "\n%i. %s: (%i)", i+1, dr.display, vote.item_list[i].count);
}
}
SourceMod::ResultType VoteMenuHandler::OnTimer(ITimer *pTimer, void *pData)
{
DrawHintProgress();
return Pl_Continue;
}
void VoteMenuHandler::OnTimerEnd(ITimer *pTimer, void *pData)
{
m_displayTimer = NULL;
}
+14 -2
View File
@@ -36,6 +36,7 @@
#include <IPlayerHelpers.h>
#include <sh_vector.h>
#include "sm_globals.h"
#include <TimerSys.h>
using namespace SourceHook;
using namespace SourceMod;
@@ -43,7 +44,8 @@ using namespace SourceMod;
class VoteMenuHandler :
public IMenuHandler,
public SMGlobalClass,
public IClientListener
public IClientListener,
public ITimedEvent
{
public: //SMGlobalClass
void OnSourceModAllInitialized();
@@ -61,6 +63,9 @@ public: //IMenuHandler
void OnMenuEnd(IBaseMenu *menu, MenuEndReason reason);
void OnMenuDrawItem(IBaseMenu *menu, int client, unsigned int item, unsigned int &style);
unsigned int OnMenuDisplayItem(IBaseMenu *menu, int client, IMenuPanel *panel, unsigned int item, const ItemDrawInfo &dr);
public: //ITimedEvent
ResultType OnTimer(ITimer *pTimer, void *pData);
void OnTimerEnd(ITimer *pTimer, void *pData);
public:
bool StartVote(IBaseMenu *menu,
unsigned int num_clients,
@@ -74,7 +79,7 @@ public:
unsigned int GetRemainingVoteDelay();
bool IsClientInVotePool(int client);
bool GetClientVoteChoice(int client, unsigned int *pItem);
bool RedrawToClient(int client);
bool RedrawToClient(int client, bool revote);
private:
void Reset(IMenuHandler *mh);
void DecrementPlayerCount();
@@ -85,9 +90,12 @@ private:
unsigned int time,
unsigned int flags);
void StartVoting();
void DrawHintProgress();
void BuildVoteLeaders();
private:
IMenuHandler *m_pHandler;
unsigned int m_Clients;
unsigned int m_TotalClients;
unsigned int m_Items;
CVector<unsigned int> m_Votes;
IBaseMenu *m_pCurMenu;
@@ -99,6 +107,10 @@ private:
float m_fStartTime;
unsigned int m_nMenuTime;
int m_ClientVotes[256+1];
bool m_Revoting[256+1];
char m_leaderList[1024];
ITimer *m_displayTimer;
};
#endif //_INCLUDE_SOURCEMOD_MENUVOTING_H_
+379
View File
@@ -0,0 +1,379 @@
/**
* vim: set ts=4 :
* =============================================================================
* SourcePawn
* Copyright (C) 2004-2009 AlliedModders LLC. All rights reserved.
* =============================================================================
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, version 3.0, as published by the
* Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*
* As a special exception, AlliedModders LLC gives you permission to link the
* code of this program (as well as its derivative works) to "Half-Life 2," the
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
* by the Valve Corporation. You must obey the GNU General Public License in
* all respects for all other code used. Additionally, AlliedModders LLC grants
* this exception to all derivative works. AlliedModders LLC defines further
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
* or <http://www.sourcemod.net/license.php>.
*
* Version: $Id$
*/
#include "NativeInvoker.h"
#include "ShareSys.h"
NativeInterface g_NInvoke;
NativeInvoker::NativeInvoker()
{
}
NativeInvoker::~NativeInvoker()
{
}
const char *NativeInterface::GetInterfaceName()
{
return SMINTERFACE_NINVOKE_NAME;
}
unsigned int NativeInterface::GetInterfaceVersion()
{
return SMINTERFACE_NINVOKE_VERSION;
}
void NativeInterface::OnSourceModAllInitialized()
{
g_ShareSys.AddInterface(NULL, &g_NInvoke);
}
IPluginRuntime *NativeInterface::CreateRuntime(const char *name, size_t bytes)
{
return g_pSourcePawn2->CreateEmptyRuntime(name, bytes);
}
INativeInvoker *NativeInterface::CreateInvoker()
{
return new NativeInvoker();
}
bool NativeInvoker::Start(IPluginContext *pContext, const char *name)
{
NativeEntry *entry;
entry = g_ShareSys.FindNative(name);
if (entry == NULL)
{
return false;
}
native = NULL;
if (entry->replacement.owner != NULL)
{
native = entry->replacement.func;
}
else if (entry->owner != NULL)
{
native = entry->func;
}
if (native == NULL)
{
return false;
}
this->pContext = pContext;
m_curparam = 0;
m_errorstate = SP_ERROR_NONE;
return true;
}
cell_t NativeInvoker::PushCell(cell_t cell)
{
if (m_curparam >= SP_MAX_EXEC_PARAMS)
{
return SetError(SP_ERROR_PARAMS_MAX);
}
m_info[m_curparam].marked = false;
m_params[m_curparam] = cell;
m_curparam++;
return SP_ERROR_NONE;
}
int NativeInvoker::PushCellByRef(cell_t *cell, int flags)
{
return PushArray(cell, 1, flags);
}
int NativeInvoker::PushFloat(float number)
{
cell_t val = *(cell_t *)&number;
return PushCell(val);
}
int NativeInvoker::PushFloatByRef(float *number, int flags)
{
return PushCellByRef((cell_t *)number, flags);
}
int NativeInvoker::PushArray(cell_t *inarray, unsigned int cells, int copyback)
{
if (m_curparam >= SP_MAX_EXEC_PARAMS)
{
return SetError(SP_ERROR_PARAMS_MAX);
}
ParamInfo *info = &m_info[m_curparam];
info->flags = inarray ? copyback : 0;
info->marked = true;
info->size = cells;
info->str.is_sz = false;
info->orig_addr = inarray;
m_curparam++;
return SP_ERROR_NONE;
}
int NativeInvoker::PushString(const char *string)
{
return _PushString(string, SM_PARAM_STRING_COPY, 0, strlen(string)+1);
}
int NativeInvoker::PushStringEx(char *buffer, size_t length, int sz_flags, int cp_flags)
{
return _PushString(buffer, sz_flags, cp_flags, length);
}
int NativeInvoker::_PushString(const char *string, int sz_flags, int cp_flags, size_t len)
{
if (m_curparam >= SP_MAX_EXEC_PARAMS)
{
return SetError(SP_ERROR_PARAMS_MAX);
}
ParamInfo *info = &m_info[m_curparam];
info->marked = true;
info->orig_addr = (cell_t *)string;
info->flags = cp_flags;
info->size = len;
info->str.sz_flags = sz_flags;
info->str.is_sz = true;
m_curparam++;
return SP_ERROR_NONE;
}
void NativeInvoker::Cancel()
{
if (pContext == NULL)
{
return;
}
m_errorstate = SP_ERROR_NONE;
m_curparam = 0;
pContext = NULL;
native = NULL;
}
int NativeInvoker::SetError(int err)
{
m_errorstate = err;
return err;
}
int NativeInvoker::Invoke(cell_t *result)
{
int err = SP_ERROR_NONE;
if (pContext == NULL)
{
return SP_ERROR_INVALID_NATIVE;
}
if (m_errorstate != SP_ERROR_NONE)
{
err = m_errorstate;
Cancel();
return err;
}
cell_t tresult;
if (result == NULL)
{
result = &tresult;
}
//This is for re-entrancy!
IPluginContext *ctx = pContext;
cell_t _temp_params[SP_MAX_EXEC_PARAMS + 1];
cell_t *temp_params = &_temp_params[1];
ParamInfo temp_info[SP_MAX_EXEC_PARAMS];
unsigned int numparams = m_curparam;
unsigned int i;
bool docopies = true;
if (numparams)
{
//Save the info locally, then reset it for re-entrant calls.
memcpy(temp_info, m_info, numparams * sizeof(ParamInfo));
}
m_curparam = 0;
pContext = NULL;
/* Initialize 0th parameter */
_temp_params[0] = numparams;
/* Browse the parameters and build arrays */
for (i = 0; i < numparams; i++)
{
/* Is this marked as an array? */
if (temp_info[i].marked)
{
if (!temp_info[i].str.is_sz)
{
/* Allocate a normal/generic array */
if ((err = ctx->HeapAlloc(temp_info[i].size,
&temp_info[i].local_addr,
&temp_info[i].phys_addr))
!= SP_ERROR_NONE)
{
break;
}
if (temp_info[i].orig_addr)
{
memcpy(temp_info[i].phys_addr, temp_info[i].orig_addr, sizeof(cell_t) * temp_info[i].size);
}
}
else
{
/* Calculate cells required for the string */
size_t cells = (temp_info[i].size + sizeof(cell_t) - 1) / sizeof(cell_t);
/* Allocate the buffer */
if ((err = ctx->HeapAlloc(cells,
&temp_info[i].local_addr,
&temp_info[i].phys_addr))
!= SP_ERROR_NONE)
{
break;
}
/* Copy original string if necessary */
if ((temp_info[i].str.sz_flags & SM_PARAM_STRING_COPY) && (temp_info[i].orig_addr != NULL))
{
/* Cut off UTF-8 properly */
if (temp_info[i].str.sz_flags & SM_PARAM_STRING_UTF8)
{
if ((err = ctx->StringToLocalUTF8(temp_info[i].local_addr,
temp_info[i].size,
(const char *)temp_info[i].orig_addr,
NULL))
!= SP_ERROR_NONE)
{
break;
}
}
/* Copy a binary blob */
else if (temp_info[i].str.sz_flags & SM_PARAM_STRING_BINARY)
{
memmove(temp_info[i].phys_addr, temp_info[i].orig_addr, temp_info[i].size);
}
/* Copy ASCII characters */
else
{
if ((err = ctx->StringToLocal(temp_info[i].local_addr,
temp_info[i].size,
(const char *)temp_info[i].orig_addr))
!= SP_ERROR_NONE)
{
break;
}
}
}
} /* End array/string calculation */
/* Update the pushed parameter with the byref local address */
temp_params[i] = temp_info[i].local_addr;
}
else
{
/* Just copy the value normally */
temp_params[i] = m_params[i];
}
}
/* Make the call if we can */
if (err == SP_ERROR_NONE)
{
*result = native(ctx, _temp_params);
if (ctx->GetLastNativeError() != SP_ERROR_NONE)
{
docopies = false;
ctx->ClearLastNativeError();
}
}
else
{
docopies = false;
}
/* i should be equal to the last valid parameter + 1 */
while (i--)
{
if (!temp_info[i].marked)
{
continue;
}
if (docopies && (temp_info[i].flags & SM_PARAM_COPYBACK))
{
if (temp_info[i].orig_addr)
{
if (temp_info[i].str.is_sz)
{
memcpy(temp_info[i].orig_addr, temp_info[i].phys_addr, temp_info[i].size);
}
else
{
if (temp_info[i].size == 1)
{
*temp_info[i].orig_addr = *(temp_info[i].phys_addr);
}
else
{
memcpy(temp_info[i].orig_addr,
temp_info[i].phys_addr,
temp_info[i].size * sizeof(cell_t));
}
}
}
}
if ((err = ctx->HeapPop(temp_info[i].local_addr)) != SP_ERROR_NONE)
{
return err;
}
}
return err;
}
+98
View File
@@ -0,0 +1,98 @@
/**
* vim: set ts=4 :
* =============================================================================
* SourceMod
* Copyright (C) 2004-2009 AlliedModders LLC. All rights reserved.
* =============================================================================
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, version 3.0, as published by the
* Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*
* As a special exception, AlliedModders LLC gives you permission to link the
* code of this program (as well as its derivative works) to "Half-Life 2," the
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
* by the Valve Corporation. You must obey the GNU General Public License in
* all respects for all other code used. Additionally, AlliedModders LLC grants
* this exception to all derivative works. AlliedModders LLC defines further
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
* or <http://www.sourcemod.net/license.php>.
*
* Version: $Id$
*/
#ifndef _INCLUDE_SOURCEMOD_NATIVE_INVOKER_H_
#define _INCLUDE_SOURCEMOD_NATIVE_INVOKER_H_
#include "sm_globals.h"
#include <INativeInvoker.h>
struct ParamInfo
{
int flags; /* Copy-back flags */
bool marked; /* Whether this is marked as being used */
cell_t local_addr; /* Local address to free */
cell_t *phys_addr; /* Physical address of our copy */
cell_t *orig_addr; /* Original address to copy back to */
ucell_t size; /* Size of array in bytes */
struct
{
bool is_sz; /* is a string */
int sz_flags; /* has sz flags */
} str;
};
class NativeInvoker : public INativeInvoker
{
public:
NativeInvoker();
~NativeInvoker();
public: /* ICallable */
int PushCell(cell_t cell);
int PushCellByRef(cell_t *cell, int flags=SM_PARAM_COPYBACK);
int PushFloat(float number);
int PushFloatByRef(float *number, int flags=SM_PARAM_COPYBACK);
int PushArray(cell_t *inarray, unsigned int cells, int flags=0);
int PushString(const char *string);
int PushStringEx(char *buffer, size_t length, int sz_flags, int cp_flags);
void Cancel();
public: /* INativeInvoker */
bool Start(IPluginContext *pContext, const char *name);
int Invoke(cell_t *result);
private:
int _PushString(const char *string, int sz_flags, int cp_flags, size_t len);
int SetError(int err);
private:
IPluginContext *pContext;
SPVM_NATIVE_FUNC native;
cell_t m_params[SP_MAX_EXEC_PARAMS];
ParamInfo m_info[SP_MAX_EXEC_PARAMS];
unsigned int m_curparam;
int m_errorstate;
};
class NativeInterface :
public INativeInterface,
public SMGlobalClass
{
public: /* SMGlobalClass */
void OnSourceModAllInitialized();
public: /* SMInterface */
unsigned int GetInterfaceVersion();
const char *GetInterfaceName();
public: /* INativeInvoker */
IPluginRuntime *CreateRuntime(const char *name, size_t bytes);
INativeInvoker *CreateInvoker();
};
extern NativeInterface g_NInvoke;
#endif /* _INCLUDE_SOURCEMOD_NATIVE_INVOKER_H_ */
+26 -25
View File
@@ -38,12 +38,22 @@
NextMapManager g_NextMap;
#if SOURCE_ENGINE != SE_DARKMESSIAH
SH_DECL_HOOK2_void(IVEngineServer, ChangeLevel, SH_NOATTRIB, 0, const char *, const char *);
#if defined ORANGEBOX_BUILD
SH_DECL_EXTERN1_void(ConCommand, Dispatch, SH_NOATTRIB, false, const CCommand &);
#else
extern bool __SourceHook_FHAddConCommandDispatch(void *,bool,class fastdelegate::FastDelegate0<void>);
SH_DECL_HOOK4_void(IVEngineServer, ChangeLevel, SH_NOATTRIB, 0, const char *, const char *, const char *, bool);
#endif
#if SOURCE_ENGINE >= SE_ORANGEBOX
SH_DECL_EXTERN1_void(ConCommand, Dispatch, SH_NOATTRIB, false, const CCommand &);
#elif SOURCE_ENGINE == SE_DARKMESSIAH
SH_DECL_EXTERN0_void(ConCommand, Dispatch, SH_NOATTRIB, false);
#else
# if SH_IMPL_VERSION >= 4
extern int __SourceHook_FHAddConCommandDispatch(void *,bool,class fastdelegate::FastDelegate0<void>);
# else
extern bool __SourceHook_FHAddConCommandDispatch(void *,bool,class fastdelegate::FastDelegate0<void>);
#endif
extern bool __SourceHook_FHRemoveConCommandDispatch(void *,bool,class fastdelegate::FastDelegate0<void>);
#endif
@@ -55,30 +65,13 @@ bool g_forcedChange = false;
void NextMapManager::OnSourceModAllInitialized_Post()
{
#if defined ORANGEBOX_BUILD
#if SOURCE_ENGINE >= SE_ORANGEBOX
SH_ADD_HOOK(IVEngineServer, ChangeLevel, engine, SH_MEMBER(this, &NextMapManager::HookChangeLevel), false);
#else
SH_ADD_HOOK_MEMFUNC(IVEngineServer, ChangeLevel, engine, this, &NextMapManager::HookChangeLevel, false);
#endif
ConCommandBase *pBase = icvar->GetCommands();
ConCommand *pCmd = NULL;
while (pBase)
{
if (strcmp(pBase->GetName(), "changelevel") == 0)
{
/* Don't want to return convar with same name */
if (!pBase->IsCommand())
{
break;
}
pCmd = (ConCommand *)pBase;
break;
}
pBase = const_cast<ConCommandBase *>(pBase->GetNext());
}
ConCommand *pCmd = FindCommand("changelevel");
if (pCmd != NULL)
{
SH_ADD_HOOK_STATICFUNC(ConCommand, Dispatch, pCmd, CmdChangeLevelCallback, false);
@@ -88,7 +81,7 @@ void NextMapManager::OnSourceModAllInitialized_Post()
void NextMapManager::OnSourceModShutdown()
{
#if defined ORANGEBOX_BUILD
#if SOURCE_ENGINE >= SE_ORANGEBOX
SH_REMOVE_HOOK(IVEngineServer, ChangeLevel, engine, SH_MEMBER(this, &NextMapManager::HookChangeLevel), false);
#else
SH_REMOVE_HOOK_MEMFUNC(IVEngineServer, ChangeLevel, engine, this, &NextMapManager::HookChangeLevel, false);
@@ -126,7 +119,11 @@ bool NextMapManager::SetNextMap(const char *map)
return true;
}
#if SOURCE_ENGINE != SE_DARKMESSIAH
void NextMapManager::HookChangeLevel(const char *map, const char *unknown)
#else
void NextMapManager::HookChangeLevel(const char *map, const char *unknown, const char *video, bool bLongLoading)
#endif
{
if (g_forcedChange)
{
@@ -146,7 +143,11 @@ void NextMapManager::HookChangeLevel(const char *map, const char *unknown)
UTIL_Format(m_tempChangeInfo.m_mapName, sizeof(m_tempChangeInfo.m_mapName), newmap);
UTIL_Format(m_tempChangeInfo.m_changeReason, sizeof(m_tempChangeInfo.m_changeReason), "Normal level change");
#if SOURCE_ENGINE != SE_DARKMESSIAH
RETURN_META_NEWPARAMS(MRES_IGNORED, &IVEngineServer::ChangeLevel, (newmap, unknown));
#else
RETURN_META_NEWPARAMS(MRES_IGNORED, &IVEngineServer::ChangeLevel, (newmap, unknown, video, bLongLoading));
#endif
}
void NextMapManager::OnSourceModLevelChange( const char *mapName )
@@ -203,7 +204,7 @@ NextMapManager::NextMapManager()
m_mapHistory = SourceHook::List<MapChangeData *>();
}
#if defined ORANGEBOX_BUILD
#if SOURCE_ENGINE >= SE_ORANGEBOX
void CmdChangeLevelCallback(const CCommand &command)
{
#else
+6 -2
View File
@@ -58,7 +58,7 @@ struct MapChangeData
time_t startTime;
};
#if defined ORANGEBOX_BUILD
#if SOURCE_ENGINE >= SE_ORANGEBOX
void CmdChangeLevelCallback(const CCommand &command);
#else
void CmdChangeLevelCallback();
@@ -69,7 +69,7 @@ class NextMapManager : public SMGlobalClass
public:
NextMapManager();
#if defined ORANGEBOX_BUILD
#if SOURCE_ENGINE >= SE_ORANGEBOX
friend void CmdChangeLevelCallback(const CCommand &command);
#else
friend void CmdChangeLevelCallback();
@@ -84,7 +84,11 @@ public:
void ForceChangeLevel(const char *mapName, const char* changeReason);
#if SOURCE_ENGINE != SE_DARKMESSIAH
void HookChangeLevel(const char *map, const char *unknown);
#else
void HookChangeLevel(const char *map, const char *unknown, const char *video, bool bLongLoading);
#endif
public:
SourceHook::List<MapChangeData *> m_mapHistory;
+299 -94
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-2009 AlliedModders LLC. All rights reserved.
* =============================================================================
*
* This program is free software; you can redistribute it and/or modify it under
@@ -39,21 +39,23 @@
#include "sm_stringutil.h"
#include "CoreConfig.h"
#include "TimerSys.h"
#include "Translator.h"
#include "Logger.h"
#include "ChatTriggers.h"
#include "HalfLife2.h"
#include <inetchannel.h>
#include <iclient.h>
#include "GameConfigs.h"
#include <IGameConfigs.h>
#include "ExtensionSys.h"
#include <sourcemod_version.h>
#include "ConsoleDetours.h"
#include "logic_bridge.h"
PlayerManager g_Players;
bool g_OnMapStarted = false;
IForward *PreAdminCheck = NULL;
IForward *PostAdminCheck = NULL;
IForward *PostAdminFilter = NULL;
IForward *OnClientConnected = NULL;
const unsigned int *g_NumPlayersToAuth = NULL;
int lifestate_offset = -1;
List<ICommandTargetProcessor *> target_processors;
@@ -61,7 +63,7 @@ List<ICommandTargetProcessor *> target_processors;
SH_DECL_HOOK5(IServerGameClients, ClientConnect, SH_NOATTRIB, 0, bool, edict_t *, const char *, const char *, char *, int);
SH_DECL_HOOK2_void(IServerGameClients, ClientPutInServer, SH_NOATTRIB, 0, edict_t *, const char *);
SH_DECL_HOOK1_void(IServerGameClients, ClientDisconnect, SH_NOATTRIB, 0, edict_t *);
#if defined ORANGEBOX_BUILD
#if SOURCE_ENGINE >= SE_ORANGEBOX
SH_DECL_HOOK2_void(IServerGameClients, ClientCommand, SH_NOATTRIB, 0, edict_t *, const CCommand &);
#else
SH_DECL_HOOK1_void(IServerGameClients, ClientCommand, SH_NOATTRIB, 0, edict_t *);
@@ -69,15 +71,23 @@ SH_DECL_HOOK1_void(IServerGameClients, ClientCommand, SH_NOATTRIB, 0, edict_t *)
SH_DECL_HOOK1_void(IServerGameClients, ClientSettingsChanged, SH_NOATTRIB, 0, edict_t *);
SH_DECL_HOOK3_void(IServerGameDLL, ServerActivate, SH_NOATTRIB, 0, edict_t *, int, int);
#if defined ORANGEBOX_BUILD
#if SOURCE_ENGINE >= SE_ORANGEBOX
SH_DECL_EXTERN1_void(ConCommand, Dispatch, SH_NOATTRIB, false, const CCommand &);
#elif SOURCE_ENGINE == SE_DARKMESSIAH
SH_DECL_EXTERN0_void(ConCommand, Dispatch, SH_NOATTRIB, false);
#else
extern bool __SourceHook_FHAddConCommandDispatch(void *,bool,class fastdelegate::FastDelegate0<void>);
# if SH_IMPL_VERSION >= 4
extern int __SourceHook_FHAddConCommandDispatch(void *,bool,class fastdelegate::FastDelegate0<void>);
# else
extern bool __SourceHook_FHAddConCommandDispatch(void *,bool,class fastdelegate::FastDelegate0<void>);
# endif
extern bool __SourceHook_FHRemoveConCommandDispatch(void *,bool,class fastdelegate::FastDelegate0<void>);
#endif
ConCommand *maxplayersCmd = NULL;
unsigned int g_PlayerSerialCount = 0;
class KickPlayerTimer : public ITimedEvent
{
public:
@@ -103,6 +113,9 @@ PlayerManager::PlayerManager()
m_FirstPass = false;
m_maxClients = 0;
m_SourceTVUserId = -1;
m_ReplayUserId = -1;
m_UserIdLookUp = new int[USHRT_MAX+1];
memset(m_UserIdLookUp, 0, sizeof(int) * (USHRT_MAX+1));
}
@@ -132,6 +145,7 @@ void PlayerManager::OnSourceModAllInitialized()
ParamType p2[] = {Param_Cell};
m_clconnect = g_Forwards.CreateForward("OnClientConnect", ET_LowEvent, 3, p1);
m_clconnect_post = g_Forwards.CreateForward("OnClientConnected", ET_Ignore, 1, p2);
m_clputinserver = g_Forwards.CreateForward("OnClientPutInServer", ET_Ignore, 1, p2);
m_cldisconnect = g_Forwards.CreateForward("OnClientDisconnect", ET_Ignore, 1, p2);
m_cldisconnect_post = g_Forwards.CreateForward("OnClientDisconnect_Post", ET_Ignore, 1, p2);
@@ -140,7 +154,6 @@ void PlayerManager::OnSourceModAllInitialized()
m_clauth = g_Forwards.CreateForward("OnClientAuthorized", ET_Ignore, 2, NULL, Param_Cell, Param_String);
m_onActivate = g_Forwards.CreateForward("OnServerLoad", ET_Ignore, 0, NULL);
m_onActivate2 = g_Forwards.CreateForward("OnMapStart", ET_Ignore, 0, NULL);
OnClientConnected = g_Forwards.CreateForward("OnClientConnected", ET_Ignore, 1, p2);
PreAdminCheck = g_Forwards.CreateForward("OnClientPreAdminCheck", ET_Event, 1, p1);
PostAdminCheck = g_Forwards.CreateForward("OnClientPostAdminCheck", ET_Ignore, 1, p1);
@@ -149,26 +162,7 @@ void PlayerManager::OnSourceModAllInitialized()
m_bIsListenServer = !engine->IsDedicatedServer();
m_ListenClient = 0;
g_ConVarManager.AddConVarChangeListener("tv_enable", this);
ConCommandBase *pBase = icvar->GetCommands();
ConCommand *pCmd = NULL;
while (pBase)
{
if (strcmp(pBase->GetName(), "maxplayers") == 0)
{
/* Don't want to return convar with same name */
if (!pBase->IsCommand())
{
break;
}
pCmd = (ConCommand *)pBase;
break;
}
pBase = const_cast<ConCommandBase *>(pBase->GetNext());
}
ConCommand *pCmd = FindCommand("maxplayers");
if (pCmd != NULL)
{
SH_ADD_HOOK_STATICFUNC(ConCommand, Dispatch, pCmd, CmdMaxplayersCallback, true);
@@ -179,6 +173,7 @@ void PlayerManager::OnSourceModAllInitialized()
void PlayerManager::OnSourceModShutdown()
{
SH_REMOVE_HOOK_MEMFUNC(IServerGameClients, ClientConnect, serverClients, this, &PlayerManager::OnClientConnect, false);
SH_REMOVE_HOOK_MEMFUNC(IServerGameClients, ClientConnect, serverClients, this, &PlayerManager::OnClientConnect_Post, true);
SH_REMOVE_HOOK_MEMFUNC(IServerGameClients, ClientPutInServer, serverClients, this, &PlayerManager::OnClientPutInServer, true);
SH_REMOVE_HOOK_MEMFUNC(IServerGameClients, ClientDisconnect, serverClients, this, &PlayerManager::OnClientDisconnect, false);
SH_REMOVE_HOOK_MEMFUNC(IServerGameClients, ClientDisconnect, serverClients, this, &PlayerManager::OnClientDisconnect_Post, true);
@@ -188,6 +183,7 @@ void PlayerManager::OnSourceModShutdown()
/* Release forwards */
g_Forwards.ReleaseForward(m_clconnect);
g_Forwards.ReleaseForward(m_clconnect_post);
g_Forwards.ReleaseForward(m_clputinserver);
g_Forwards.ReleaseForward(m_cldisconnect);
g_Forwards.ReleaseForward(m_cldisconnect_post);
@@ -196,7 +192,6 @@ void PlayerManager::OnSourceModShutdown()
g_Forwards.ReleaseForward(m_clauth);
g_Forwards.ReleaseForward(m_onActivate);
g_Forwards.ReleaseForward(m_onActivate2);
g_Forwards.ReleaseForward(OnClientConnected);
g_Forwards.ReleaseForward(PreAdminCheck);
g_Forwards.ReleaseForward(PostAdminCheck);
@@ -204,8 +199,6 @@ void PlayerManager::OnSourceModShutdown()
delete [] m_Players;
g_ConVarManager.RemoveConVarChangeListener("tv_enable", this);
if (maxplayersCmd != NULL)
{
SH_REMOVE_HOOK_STATICFUNC(ConCommand, Dispatch, maxplayersCmd, CmdMaxplayersCallback, true);
@@ -242,10 +235,26 @@ ConfigResult PlayerManager::OnSourceModConfigChanged(const char *key,
void PlayerManager::OnServerActivate(edict_t *pEdictList, int edictCount, int clientMax)
{
static ConVar *tv_enable = icvar->FindVar("tv_enable");
#if SOURCE_ENGINE == SE_ORANGEBOXVALVE
static ConVar *replay_enable = icvar->FindVar("replay_enable");
#endif
// clientMax will not necessarily be correct here (such as on late SourceTV enable)
m_maxClients = gpGlobals->maxClients;
ICommandLine *commandLine = g_HL2.GetValveCommandLine();
m_bIsSourceTVActive = (tv_enable && tv_enable->GetBool() && (!commandLine || commandLine->FindParm("-nohltv") == 0));
m_bIsReplayActive = false;
#if SOURCE_ENGINE == SE_ORANGEBOXVALVE
m_bIsReplayActive = (replay_enable && replay_enable->GetBool());
#endif
m_PlayersSinceActive = 0;
if (!m_FirstPass)
{
/* Initialize all players */
m_maxClients = clientMax;
m_PlayerCount = 0;
m_Players = new CPlayer[ABSOLUTE_PLAYER_LIMIT + 1];
m_AuthQueue = new unsigned int[ABSOLUTE_PLAYER_LIMIT + 1];
@@ -254,10 +263,13 @@ void PlayerManager::OnServerActivate(edict_t *pEdictList, int edictCount, int cl
memset(m_AuthQueue, 0, sizeof(unsigned int) * (ABSOLUTE_PLAYER_LIMIT + 1));
g_NumPlayersToAuth = &m_AuthQueue[0];
g_PluginSys.SyncMaxClients(clientMax);
}
g_Extensions.CallOnCoreMapStart(pEdictList, edictCount, clientMax);
g_PluginSys.SyncMaxClients(m_maxClients);
g_OnMapStarted = true;
g_Extensions.CallOnCoreMapStart(pEdictList, edictCount, m_maxClients);
m_onActivate->Execute(NULL);
m_onActivate2->Execute(NULL);
@@ -266,12 +278,10 @@ void PlayerManager::OnServerActivate(edict_t *pEdictList, int edictCount, int cl
{
if ((*iter)->GetClientListenerVersion() >= 5)
{
(*iter)->OnServerActivated(clientMax);
(*iter)->OnServerActivated(m_maxClients);
}
}
g_OnMapStarted = true;
SMGlobalClass *cls = SMGlobalClass::head;
while (cls)
{
@@ -415,9 +425,25 @@ void PlayerManager::RunAuthChecks()
bool PlayerManager::OnClientConnect(edict_t *pEntity, const char *pszName, const char *pszAddress, char *reject, int maxrejectlen)
{
int client = engine->IndexOfEdict(pEntity);
int client = IndexOfEdict(pEntity);
CPlayer *pPlayer = &m_Players[client];
++m_PlayersSinceActive;
pPlayer->Initialize(pszName, pszAddress, pEntity);
/* Get the client's language */
if (m_QueryLang)
{
const char *name;
if (!pPlayer->IsFakeClient() && (name=engine->GetClientConVarValue(client, "cl_language")))
{
unsigned int langid;
pPlayer->m_LangId = (translator->GetLanguageByName(name, &langid)) ? langid : translator->GetServerLanguage();
} else {
pPlayer->m_LangId = translator->GetServerLanguage();
}
}
List<IClientListener *>::iterator iter;
IClientListener *pListener = NULL;
for (iter=m_hooks.begin(); iter!=m_hooks.end(); iter++)
@@ -431,9 +457,8 @@ bool PlayerManager::OnClientConnect(edict_t *pEntity, const char *pszName, const
cell_t res = 1;
pPlayer->Initialize(pszName, pszAddress, pEntity);
m_clconnect->PushCell(client);
m_clconnect->PushStringEx(reject, maxrejectlen, SM_PARAM_STRING_UTF8, SM_PARAM_COPYBACK);
m_clconnect->PushStringEx(reject, maxrejectlen, SM_PARAM_STRING_UTF8 | SM_PARAM_STRING_COPY, SM_PARAM_COPYBACK);
m_clconnect->PushCell(maxrejectlen);
m_clconnect->Execute(&res);
@@ -459,7 +484,7 @@ bool PlayerManager::OnClientConnect(edict_t *pEntity, const char *pszName, const
bool PlayerManager::OnClientConnect_Post(edict_t *pEntity, const char *pszName, const char *pszAddress, char *reject, int maxrejectlen)
{
int client = engine->IndexOfEdict(pEntity);
int client = IndexOfEdict(pEntity);
bool orig_value = META_RESULT_ORIG_RET(bool);
CPlayer *pPlayer = &m_Players[client];
@@ -473,7 +498,7 @@ bool PlayerManager::OnClientConnect_Post(edict_t *pEntity, const char *pszName,
pListener->OnClientConnected(client);
if (!pPlayer->IsConnected())
{
break;
return true;
}
}
@@ -485,8 +510,8 @@ bool PlayerManager::OnClientConnect_Post(edict_t *pEntity, const char *pszName,
}
cell_t res;
OnClientConnected->PushCell(client);
OnClientConnected->Execute(&res, NULL);
m_clconnect_post->PushCell(client);
m_clconnect_post->Execute(&res, NULL);
}
else
{
@@ -499,7 +524,7 @@ bool PlayerManager::OnClientConnect_Post(edict_t *pEntity, const char *pszName,
void PlayerManager::OnClientPutInServer(edict_t *pEntity, const char *playername)
{
cell_t res;
int client = engine->IndexOfEdict(pEntity);
int client = IndexOfEdict(pEntity);
CPlayer *pPlayer = &m_Players[client];
/* If they're not connected, they're a bot */
@@ -510,6 +535,40 @@ void PlayerManager::OnClientPutInServer(edict_t *pEntity, const char *playername
const char *authid = engine->GetPlayerNetworkIDString(pEntity);
pPlayer->Authorize(authid);
pPlayer->m_bFakeClient = true;
/*
* While we're already filtered to just bots, we'll do other checks to
* make sure that the requisite services are enabled and that the bots
* have joined at the expected time.
*
* Checking playerinfo's IsHLTV and IsReplay would be better and less
* error-prone but will always show false until later in the frame,
* after PutInServer and Activate, and we want it now!
*/
// This doesn't actually get incremented until OnClientConnect. Fake it to check.
int newCount = m_PlayersSinceActive + 1;
int userId = engine->GetPlayerUserId(pEntity);
#if SOURCE_ENGINE == SE_ORANGEBOXVALVE
if (m_bIsReplayActive && newCount == 1
&& (m_ReplayUserId == userId || strcmp(playername, "Replay") == 0))
{
pPlayer->m_bIsReplay = true;
m_ReplayUserId = userId;
}
#endif
if (m_bIsSourceTVActive
&& ((!m_bIsReplayActive && newCount == 1)
|| (m_bIsReplayActive && newCount == 2))
&& (m_SourceTVUserId == userId || strcmp(playername, "SourceTV") == 0)
)
{
pPlayer->m_bIsSourceTV = true;
m_SourceTVUserId = userId;
}
if (!OnClientConnect(pEntity, playername, "127.0.0.1", error, sizeof(error)))
{
/* :TODO: kick the bot if it's rejected */
@@ -527,6 +586,11 @@ void PlayerManager::OnClientPutInServer(edict_t *pEntity, const char *playername
return;
}
}
cell_t res;
m_clconnect_post->PushCell(client);
m_clconnect_post->Execute(&res, NULL);
/* Now do authorization */
for (iter=m_hooks.begin(); iter!=m_hooks.end(); iter++)
{
@@ -548,19 +612,6 @@ void PlayerManager::OnClientPutInServer(edict_t *pEntity, const char *playername
pPlayer->m_Info = playerinfo->GetPlayerInfo(pEntity);
}
/* Get the client's language */
if (m_QueryLang)
{
const char *name;
if (!pPlayer->IsFakeClient() && (name=engine->GetClientConVarValue(client, "cl_language")))
{
unsigned int langid;
pPlayer->m_LangId = (g_Translator.GetLanguageByName(name, &langid)) ? langid : g_Translator.GetServerLanguage();
} else {
pPlayer->m_LangId = g_Translator.GetServerLanguage();
}
}
pPlayer->Connect();
m_PlayerCount++;
@@ -597,7 +648,7 @@ void PlayerManager::OnSourceModLevelEnd()
void PlayerManager::OnClientDisconnect(edict_t *pEntity)
{
cell_t res;
int client = engine->IndexOfEdict(pEntity);
int client = IndexOfEdict(pEntity);
CPlayer *pPlayer = &m_Players[client];
if (pPlayer->IsConnected())
@@ -635,7 +686,7 @@ void PlayerManager::OnClientDisconnect(edict_t *pEntity)
void PlayerManager::OnClientDisconnect_Post(edict_t *pEntity)
{
cell_t res;
int client = engine->IndexOfEdict(pEntity);
int client = IndexOfEdict(pEntity);
m_cldisconnect_post->PushCell(client);
m_cldisconnect_post->Execute(&res, NULL);
@@ -649,7 +700,28 @@ void PlayerManager::OnClientDisconnect_Post(edict_t *pEntity)
}
}
#if defined ORANGEBOX_BUILD
void ClientConsolePrint(edict_t *e, const char *fmt, ...)
{
char buffer[512];
va_list ap;
va_start(ap, fmt);
size_t len = vsnprintf(buffer, sizeof(buffer), fmt, ap);
va_end(ap);
if (len >= sizeof(buffer) - 1)
{
buffer[sizeof(buffer) - 2] = '\n';
buffer[sizeof(buffer) - 1] = '\0';
} else {
buffer[len++] = '\n';
buffer[len] = '\0';
}
engine->ClientPrintf(e, buffer);
}
#if SOURCE_ENGINE >= SE_ORANGEBOX
void PlayerManager::OnClientCommand(edict_t *pEntity, const CCommand &args)
{
#else
@@ -657,7 +729,7 @@ void PlayerManager::OnClientCommand(edict_t *pEntity)
{
CCommand args;
#endif
int client = engine->IndexOfEdict(pEntity);
int client = IndexOfEdict(pEntity);
cell_t res = Pl_Continue;
CPlayer *pPlayer = &m_Players[client];
@@ -666,6 +738,39 @@ void PlayerManager::OnClientCommand(edict_t *pEntity)
return;
}
if (strcmp(args.Arg(0), "sm") == 0)
{
if (args.ArgC() > 1 && strcmp(args.Arg(1), "plugins") == 0)
{
g_PluginSys.ListPluginsToClient(pPlayer, args);
RETURN_META(MRES_SUPERCEDE);
}
else if (args.ArgC() > 1 && strcmp(args.Arg(1), "credits") == 0)
{
ClientConsolePrint(pEntity,
"SourceMod would not be possible without:");
ClientConsolePrint(pEntity,
" David \"BAILOPAN\" Anderson, Borja \"faluco\" Ferrer");
ClientConsolePrint(pEntity,
" Scott \"DS\" Ehlert, Matt \"pRED\" Woodrow");
ClientConsolePrint(pEntity,
" Michael \"ferret\" McKoy, Pavol \"PM OnoTo\" Marko");
ClientConsolePrint(pEntity,
"SourceMod is open source under the GNU General Public License.");
RETURN_META(MRES_SUPERCEDE);
}
ClientConsolePrint(pEntity,
"SourceMod %s, by AlliedModders LLC", SM_FULL_VERSION);
ClientConsolePrint(pEntity,
"To see running plugins, type \"sm plugins\"");
ClientConsolePrint(pEntity,
"To see credits, type \"sm credits\"");
ClientConsolePrint(pEntity,
"Visit http://www.sourcemod.net/");
RETURN_META(MRES_SUPERCEDE);
}
g_HL2.PushCommandStack(&args);
int argcount = args.ArgC() - 1;
@@ -683,10 +788,27 @@ void PlayerManager::OnClientCommand(edict_t *pEntity)
}
}
if (g_ConsoleDetours.IsEnabled())
{
cell_t res2 = g_ConsoleDetours.InternalDispatch(client, args);
if (res2 >= Pl_Stop)
{
g_HL2.PopCommandStack();
RETURN_META(MRES_SUPERCEDE);
}
else if (res2 > res)
{
res = res2;
}
}
cell_t res2 = Pl_Continue;
m_clcommand->PushCell(client);
m_clcommand->PushCell(argcount);
m_clcommand->Execute(&res2, NULL);
if (pPlayer->IsInGame())
{
m_clcommand->PushCell(client);
m_clcommand->PushCell(argcount);
m_clcommand->Execute(&res2, NULL);
}
if (res2 > res)
{
@@ -712,7 +834,7 @@ void PlayerManager::OnClientCommand(edict_t *pEntity)
void PlayerManager::OnClientSettingsChanged(edict_t *pEntity)
{
cell_t res;
int client = engine->IndexOfEdict(pEntity);
int client = IndexOfEdict(pEntity);
CPlayer *pPlayer = &m_Players[client];
if (!pPlayer->IsConnected())
@@ -720,9 +842,14 @@ void PlayerManager::OnClientSettingsChanged(edict_t *pEntity)
return;
}
m_clinfochanged->PushCell(engine->IndexOfEdict(pEntity));
m_clinfochanged->PushCell(client);
m_clinfochanged->Execute(&res, NULL);
if (pPlayer->IsFakeClient())
{
return;
}
IPlayerInfo *info = pPlayer->GetPlayerInfo();
const char *new_name = info ? info->GetName() : engine->GetClientConVarValue(client, "name");
const char *old_name = pPlayer->m_Name.c_str();
@@ -762,6 +889,17 @@ void PlayerManager::OnClientSettingsChanged(edict_t *pEntity)
}
}
}
/* Notify Extensions */
List<IClientListener *>::iterator iter;
IClientListener *pListener = NULL;
for (iter=m_hooks.begin(); iter!=m_hooks.end(); iter++)
{
pListener = (*iter);
if (pListener->GetClientListenerVersion() >= 13)
{
pListener->OnClientSettingsChanged(client);
}
}
}
int PlayerManager::GetMaxClients()
@@ -840,7 +978,7 @@ void PlayerManager::RemoveClientListener(IClientListener *listener)
IGamePlayer *PlayerManager::GetGamePlayer(edict_t *pEdict)
{
int index = engine->IndexOfEdict(pEdict);
int index = IndexOfEdict(pEdict);
return GetGamePlayer(index);
}
@@ -1106,10 +1244,18 @@ void PlayerManager::ProcessCommandTarget(cmd_target_info_t *info)
if (strcmp(info->pattern, "@me") == 0 && info->admin != 0)
{
info->targets[0] = info->admin;
info->num_targets = 1;
strncopy(info->target_name, pAdmin->GetName(), info->target_name_maxlength);
info->target_name_style = COMMAND_TARGETNAME_RAW;
info->reason = FilterCommandTarget(pAdmin, pAdmin, info->flags);
if (info->reason == COMMAND_TARGET_VALID)
{
info->targets[0] = info->admin;
info->num_targets = 1;
strncopy(info->target_name, pAdmin->GetName(), info->target_name_maxlength);
info->target_name_style = COMMAND_TARGETNAME_RAW;
}
else
{
info->num_targets = 0;
}
return;
}
@@ -1223,7 +1369,7 @@ void PlayerManager::ProcessCommandTarget(cmd_target_info_t *info)
continue;
}
if (stristr(pTarget->GetName(), info->pattern) != NULL)
if (logicore.stristr(pTarget->GetName(), info->pattern) != NULL)
{
if (found_client)
{
@@ -1261,18 +1407,6 @@ void PlayerManager::ProcessCommandTarget(cmd_target_info_t *info)
}
}
void PlayerManager::OnConVarChanged( ConVar *pConVar, const char *oldValue, float flOldValue )
{
if (pConVar->GetBool() && !atoi(oldValue))
{
MaxPlayersChanged(gpGlobals->maxClients + 1);
}
else
{
MaxPlayersChanged();
}
}
void PlayerManager::OnSourceModMaxPlayersChanged( int newvalue )
{
m_maxClients = newvalue;
@@ -1280,6 +1414,11 @@ void PlayerManager::OnSourceModMaxPlayersChanged( int newvalue )
void PlayerManager::MaxPlayersChanged( int newvalue /*= -1*/ )
{
if (!m_FirstPass)
{
return;
}
if (newvalue == -1)
{
newvalue = gpGlobals->maxClients;
@@ -1311,7 +1450,29 @@ void PlayerManager::MaxPlayersChanged( int newvalue /*= -1*/ )
}
}
#if defined ORANGEBOX_BUILD
int PlayerManager::GetClientFromSerial(unsigned int serial)
{
serial_t s;
s.value = serial;
int client = s.bits.index;
IGamePlayer *pPlayer = GetGamePlayer(client);
if (!pPlayer)
{
return 0;
}
if (serial == pPlayer->GetSerial())
{
return client;
}
return 0;
}
#if SOURCE_ENGINE >= SE_ORANGEBOX
void CmdMaxplayersCallback(const CCommand &command)
{
#else
@@ -1337,10 +1498,14 @@ CPlayer::CPlayer()
m_TempAdmin = false;
m_Info = NULL;
m_bAdminCheckSignalled = false;
m_UserId = -1;
m_bIsInKickQueue = false;
m_LastPassword.clear();
m_LangId = SOURCEMOD_LANGUAGE_ENGLISH;
m_bFakeClient = false;
m_bIsSourceTV = false;
m_bIsReplay = false;
m_Serial.value = -1;
}
void CPlayer::Initialize(const char *name, const char *ip, edict_t *pEntity)
@@ -1349,8 +1514,11 @@ void CPlayer::Initialize(const char *name, const char *ip, edict_t *pEntity)
m_Name.assign(name);
m_Ip.assign(ip);
m_pEdict = pEntity;
m_iIndex = engine->IndexOfEdict(pEntity);
m_LangId = g_Translator.GetServerLanguage();
m_iIndex = IndexOfEdict(pEntity);
m_LangId = translator->GetServerLanguage();
m_Serial.bits.index = m_iIndex;
m_Serial.bits.serial = g_PlayerSerialCount++;
char ip2[24], *ptr;
strncopy(ip2, ip, sizeof(ip2));
@@ -1371,7 +1539,7 @@ void CPlayer::Connect()
m_IsInGame = true;
const char *var = g_Players.GetPassInfoVar();
int client = engine->IndexOfEdict(m_pEdict);
int client = IndexOfEdict(m_pEdict);
if (var[0] != '\0')
{
const char *pass = engine->GetClientConVarValue(client, var);
@@ -1409,6 +1577,9 @@ void CPlayer::Disconnect()
m_UserId = -1;
m_bIsInKickQueue = false;
m_bFakeClient = false;
m_bIsSourceTV = false;
m_bIsReplay = false;
m_Serial.value = -1;
}
void CPlayer::SetName(const char *name)
@@ -1476,6 +1647,16 @@ bool CPlayer::IsFakeClient()
return m_bFakeClient;
}
bool CPlayer::IsSourceTV() const
{
return m_bIsSourceTV;
}
bool CPlayer::IsReplay() const
{
return m_bIsReplay;
}
void CPlayer::SetAdminId(AdminId id, bool temporary)
{
if (!m_IsConnected)
@@ -1511,8 +1692,22 @@ void CPlayer::Kick(const char *str)
{
MarkAsBeingKicked();
INetChannel *pNetChan = static_cast<INetChannel *>(engine->GetPlayerNetInfo(m_iIndex));
IClient *pClient = static_cast<IClient *>(pNetChan->GetMsgHandler());
pClient->Disconnect("%s", str);
if (pNetChan == NULL)
{
/* What does this even mean? Hell if I know. */
int userid = GetUserId();
if (userid > 0)
{
char buffer[255];
UTIL_Format(buffer, sizeof(buffer), "kickid %d %s\n", userid, str);
engine->ServerCommand(buffer);
}
}
else
{
IClient *pClient = static_cast<IClient *>(pNetChan->GetMsgHandler());
pClient->Disconnect("%s", str);
}
}
void CPlayer::Authorize_Post()
@@ -1618,7 +1813,7 @@ void CPlayer::DoBasicAdminChecks()
/* First check the name */
AdminId id;
int client = engine->IndexOfEdict(m_pEdict);
int client = IndexOfEdict(m_pEdict);
if ((id = g_Admins.FindAdminByIdentity("name", GetName())) != INVALID_ADMIN_ID)
{
@@ -1654,6 +1849,11 @@ unsigned int CPlayer::GetLanguageId()
return m_LangId;
}
void CPlayer::SetLanguageId(unsigned int id)
{
m_LangId = id;
}
int CPlayer::GetUserId()
{
if (m_UserId == -1)
@@ -1715,3 +1915,8 @@ int CPlayer::GetLifeState()
return PLAYER_LIFE_DEAD;
}
}
unsigned int CPlayer::GetSerial()
{
return m_Serial.value;
}
+30 -7
View File
@@ -51,6 +51,16 @@ using namespace SourceHook;
#define MIN_API_FOR_ADMINCALLS 7
union serial_t
{
uint32_t value;
struct
{
uint8_t index;
uint32_t serial : 24;
} bits;
};
class CPlayer : public IGamePlayer
{
friend class PlayerManager;
@@ -66,17 +76,21 @@ public:
bool IsConnected();
bool IsAuthorized();
bool IsFakeClient();
bool IsSourceTV() const;
bool IsReplay() const;
void SetAdminId(AdminId id, bool temporary);
AdminId GetAdminId();
void Kick(const char *str);
bool IsInKickQueue();
IPlayerInfo *GetPlayerInfo();
unsigned int GetLanguageId();
void SetLanguageId(unsigned int id);
int GetUserId();
bool RunAdminCacheChecks();
void NotifyPostAdminChecks();
unsigned int GetSerial();
public:
void DoBasicAdminChecks();
bool IsInKickQueue();
void MarkAsBeingKicked();
int GetLifeState();
private:
@@ -107,12 +121,14 @@ private:
unsigned int m_LangId;
int m_UserId;
bool m_bFakeClient;
bool m_bIsSourceTV;
bool m_bIsReplay;
serial_t m_Serial;
};
class PlayerManager :
public SMGlobalClass,
public IPlayerManager,
public IConVarChangeListener
public IPlayerManager
{
friend class CPlayer;
public:
@@ -135,7 +151,7 @@ public:
void OnClientPutInServer(edict_t *pEntity, char const *playername);
void OnClientDisconnect(edict_t *pEntity);
void OnClientDisconnect_Post(edict_t *pEntity);
#if defined ORANGEBOX_BUILD
#if SOURCE_ENGINE >= SE_ORANGEBOX
void OnClientCommand(edict_t *pEntity, const CCommand &args);
#else
void OnClientCommand(edict_t *pEntity);
@@ -156,8 +172,7 @@ public: //IPlayerManager
void RegisterCommandTargetProcessor(ICommandTargetProcessor *pHandler);
void UnregisterCommandTargetProcessor(ICommandTargetProcessor *pHandler);
void ProcessCommandTarget(cmd_target_info_t *info);
public: // IConVarChangeListener
void OnConVarChanged(ConVar *pConVar, const char *oldValue, float flOldValue);
int GetClientFromSerial(unsigned int serial);
public:
inline int MaxClients()
{
@@ -184,6 +199,7 @@ private:
private:
List<IClientListener *> m_hooks;
IForward *m_clconnect;
IForward *m_clconnect_post;
IForward *m_cldisconnect;
IForward *m_cldisconnect_post;
IForward *m_clputinserver;
@@ -196,20 +212,27 @@ private:
int *m_UserIdLookUp;
int m_maxClients;
int m_PlayerCount;
int m_PlayersSinceActive;
bool m_FirstPass;
unsigned int *m_AuthQueue;
String m_PassInfoVar;
bool m_QueryLang;
bool m_bIsListenServer;
int m_ListenClient;
bool m_bIsSourceTVActive;
bool m_bIsReplayActive;
int m_SourceTVUserId;
int m_ReplayUserId;
};
#if defined ORANGEBOX_BUILD
#if SOURCE_ENGINE >= SE_ORANGEBOX
void CmdMaxplayersCallback(const CCommand &command);
#else
void CmdMaxplayersCallback();
#endif
extern void ClientConsolePrint(edict_t *e, const char *fmt, ...);
extern PlayerManager g_Players;
extern bool g_OnMapStarted;
extern const unsigned int *g_NumPlayersToAuth;
+1 -1
View File
@@ -276,7 +276,7 @@ SMCResult CPluginInfoDatabase::ReadSMC_LeavingSection(const SMCStates *states)
{
m_infodb_size *= 2;
}
int newidx = memtab->CreateMem(m_infodb_size, (void **)&table);
int newidx = memtab->CreateMem(m_infodb_size * sizeof(int), (void **)&table);
if (m_infodb != -1)
{
void *oldtable = (int *)memtab->GetAddress(m_infodb);
+169 -48
View File
@@ -37,7 +37,6 @@
#include "ForwardSys.h"
#include "sourcemm_api.h"
#include "sourcemod.h"
#include "TextParsers.h"
#include "Logger.h"
#include "ExtensionSys.h"
#include "sm_srvcmds.h"
@@ -45,7 +44,7 @@
#include "ConCmdManager.h"
#include "PlayerManager.h"
#include "CoreConfig.h"
#include "Translator.h"
#include "logic_bridge.h"
CPluginManager g_PluginSys;
HandleType_t g_PluginType = 0;
@@ -57,17 +56,18 @@ CPlugin::CPlugin(const char *file)
m_type = PluginType_Private;
m_status = Plugin_Uncompiled;
m_bSilentlyFailed = false;
m_serial = ++MySerial;
m_pRuntime = NULL;
m_errormsg[256] = '\0';
snprintf(m_filename, sizeof(m_filename), "%s", file);
m_errormsg[sizeof(m_errormsg) - 1] = '\0';
UTIL_Format(m_filename, sizeof(m_filename), "%s", file);
m_handle = 0;
m_ident = NULL;
m_pProps = sm_trie_create();
m_FakeNativesMissing = false;
m_LibraryMissing = false;
m_bGotAllLoaded = false;
m_pPhrases = g_Translator.CreatePhraseCollection();
m_pPhrases = translator->CreatePhraseCollection();
m_MaxClientsVar = NULL;
}
@@ -164,7 +164,7 @@ CPlugin *CPlugin::CreatePlugin(const char *file, char *error, size_t maxlength)
{
if (error)
{
snprintf(error, maxlength, "Unable to open file");
UTIL_Format(error, maxlength, "Unable to open file");
}
pPlugin->m_status = Plugin_BadLoad;
return pPlugin;
@@ -210,7 +210,7 @@ void CPlugin::SetErrorState(PluginStatus status, const char *error_fmt, ...)
va_list ap;
va_start(ap, error_fmt);
vsnprintf(m_errormsg, sizeof(m_errormsg), error_fmt, ap);
UTIL_FormatArgs(m_errormsg, sizeof(m_errormsg), error_fmt, ap);
va_end(ap);
if (m_pRuntime != NULL)
@@ -273,13 +273,13 @@ bool CPlugin::UpdateInfo()
base->GetPubvarAddrs(idx, &local_addr, (cell_t **)&info);
m_FileVersion = info->version;
if (m_FileVersion >= 3)
if (m_FileVersion >= 4)
{
base->LocalToString(info->date, (char **)&pDate);
base->LocalToString(info->time, (char **)&pTime);
UTIL_Format(m_DateTime, sizeof(m_DateTime), "%s %s", pDate, pTime);
}
if (m_FileVersion > 4)
if (m_FileVersion > 5)
{
base->LocalToString(info->filevers, (char **)&pFileVers);
SetErrorState(Plugin_Failed, "Newer SourceMod required (%s or higher)", pFileVers);
@@ -372,7 +372,7 @@ void CPlugin::Call_OnAllPluginsLoaded()
pFunction->Execute(&result);
}
if (g_OnMapStarted)
if (g_SourceMod.IsMapRunning())
{
if ((pFunction = m_pRuntime->GetFunctionByName("OnMapStart")) != NULL)
{
@@ -386,22 +386,27 @@ void CPlugin::Call_OnAllPluginsLoaded()
}
}
bool CPlugin::Call_AskPluginLoad(char *error, size_t maxlength)
APLRes CPlugin::Call_AskPluginLoad(char *error, size_t maxlength)
{
if (m_status != Plugin_Created)
{
return false;
return APLRes_Failure;
}
m_status = Plugin_Loaded;
int err;
cell_t result;
IPluginFunction *pFunction = m_pRuntime->GetFunctionByName("AskPluginLoad");
bool haveNewAPL = false;
IPluginFunction *pFunction = m_pRuntime->GetFunctionByName("AskPluginLoad2");
if (!pFunction)
if (pFunction)
{
return true;
haveNewAPL = true;
}
else if (!(pFunction = m_pRuntime->GetFunctionByName("AskPluginLoad")))
{
return APLRes_Success;
}
pFunction->PushCell(m_handle);
@@ -410,15 +415,21 @@ bool CPlugin::Call_AskPluginLoad(char *error, size_t maxlength)
pFunction->PushCell(maxlength);
if ((err=pFunction->Execute(&result)) != SP_ERROR_NONE)
{
return false;
return APLRes_Failure;
}
if (!result || m_status != Plugin_Loaded)
if (haveNewAPL)
{
return false;
return (APLRes)result;
}
else if (result)
{
return APLRes_Success;
}
else
{
return APLRes_Failure;
}
return true;
}
void *CPlugin::GetPluginStructure()
@@ -470,6 +481,11 @@ PluginStatus CPlugin::GetStatus()
return m_status;
}
bool CPlugin::IsSilentlyFailed()
{
return m_bSilentlyFailed;
}
bool CPlugin::IsDebugging()
{
if (m_pRuntime == NULL)
@@ -480,6 +496,11 @@ bool CPlugin::IsDebugging()
return true;
}
void CPlugin::SetSilentlyFailed(bool sf)
{
m_bSilentlyFailed = sf;
}
void CPlugin::LibraryActions(bool dropping)
{
List<String>::iterator iter;
@@ -851,7 +872,7 @@ void CPluginManager::LoadPluginsFromDir(const char *basedir, const char *localpa
if (localpath == NULL)
{
/* If no path yet, don't add a former slash */
snprintf(new_local, sizeof(new_local), "%s", dir->GetEntryName());
UTIL_Format(new_local, sizeof(new_local), "%s", dir->GetEntryName());
} else {
g_LibSys.PathFormat(new_local, sizeof(new_local), "%s/%s", localpath, dir->GetEntryName());
}
@@ -866,7 +887,7 @@ void CPluginManager::LoadPluginsFromDir(const char *basedir, const char *localpa
char plugin[PLATFORM_MAX_PATH];
if (localpath == NULL)
{
snprintf(plugin, sizeof(plugin), "%s", name);
UTIL_Format(plugin, sizeof(plugin), "%s", name);
} else {
g_LibSys.PathFormat(plugin, sizeof(plugin), "%s/%s", localpath, name);
}
@@ -965,7 +986,7 @@ LoadRes CPluginManager::_LoadPlugin(CPlugin **_plugin, const char *path, bool de
{
if (error)
{
snprintf(error, maxlength, "Unable to set JIT option (key \"%s\") (value \"%s\")", key, val);
UTIL_Format(error, maxlength, "Unable to set JIT option (key \"%s\") (value \"%s\")", key, val);
}
co->Abort();
co = NULL;
@@ -984,7 +1005,7 @@ LoadRes CPluginManager::_LoadPlugin(CPlugin **_plugin, const char *path, bool de
pPlugin->m_pRuntime = g_pSourcePawn2->LoadPlugin(co, fullpath, &err);
if (pPlugin->m_pRuntime == NULL)
{
snprintf(error,
UTIL_Format(error,
maxlength,
"Unable to load plugin (error %d: %s)",
err,
@@ -1004,20 +1025,31 @@ LoadRes CPluginManager::_LoadPlugin(CPlugin **_plugin, const char *path, bool de
}
}
LoadRes loadFailure = LoadRes_Failure;
/* Get the status */
if (pPlugin->GetStatus() == Plugin_Created)
{
/* First native pass - add anything from Core */
g_ShareSys.BindNativesToPlugin(pPlugin, true);
pPlugin->InitIdentity();
if (pPlugin->Call_AskPluginLoad(error, maxlength))
APLRes result = pPlugin->Call_AskPluginLoad(error, maxlength);
switch (result)
{
case APLRes_Success:
/* Autoload any modules */
LoadOrRequireExtensions(pPlugin, 1, error, maxlength);
}
else
{
break;
case APLRes_Failure:
pPlugin->SetErrorState(Plugin_Failed, "%s", error);
loadFailure = LoadRes_Failure;
break;
case APLRes_SilentFailure:
pPlugin->SetErrorState(Plugin_Failed, "%s", error);
loadFailure = LoadRes_SilentFailure;
pPlugin->SetSilentlyFailed(true);
break;
default:
assert(false);
}
}
@@ -1030,7 +1062,7 @@ LoadRes CPluginManager::_LoadPlugin(CPlugin **_plugin, const char *path, bool de
*_plugin = pPlugin;
}
return (pPlugin->GetStatus() == Plugin_Loaded) ? LoadRes_Successful : LoadRes_Failure;
return (pPlugin->GetStatus() == Plugin_Loaded) ? LoadRes_Successful : loadFailure;
}
IPlugin *CPluginManager::LoadPlugin(const char *path, bool debug, PluginType type, char error[], size_t maxlength, bool *wasloaded)
@@ -1053,13 +1085,16 @@ IPlugin *CPluginManager::LoadPlugin(const char *path, bool debug, PluginType typ
if (res == LoadRes_NeverLoad)
{
if (m_LoadingLocked)
if (error)
{
UTIL_Format(error, maxlength, "There is a global plugin loading lock in effect");
}
else
{
UTIL_Format(error, maxlength, "This plugin is blocked from loading (see plugin_settings.cfg)");
if (m_LoadingLocked)
{
UTIL_Format(error, maxlength, "There is a global plugin loading lock in effect");
}
else
{
UTIL_Format(error, maxlength, "This plugin is blocked from loading (see plugin_settings.cfg)");
}
}
return NULL;
}
@@ -1090,12 +1125,12 @@ void CPluginManager::LoadAutoPlugin(const char *plugin)
{
g_Logger.LogError("[SM] Failed to load plugin \"%s\": %s", plugin, error);
pl->SetErrorState(
pl->GetStatus() == Plugin_BadLoad ? Plugin_BadLoad : Plugin_Failed,
pl->GetStatus() <= Plugin_Created ? Plugin_BadLoad : pl->GetStatus(),
"%s",
error);
}
if (res == LoadRes_Successful || res == LoadRes_Failure)
if (res == LoadRes_Successful || res == LoadRes_Failure || res == LoadRes_SilentFailure)
{
AddPlugin(pl);
}
@@ -1189,7 +1224,7 @@ bool CPluginManager::FindOrRequirePluginDeps(CPlugin *pPlugin, char *error, size
{
if (error)
{
snprintf(error, maxlength, "Fatal error during initializing plugin load");
UTIL_Format(error, maxlength, "Fatal error during initializing plugin load");
}
return false;
}
@@ -1222,7 +1257,7 @@ bool CPluginManager::FindOrRequirePluginDeps(CPlugin *pPlugin, char *error, size
{
if (error)
{
snprintf(error, maxlength, "Could not find required plugin \"%s\"", name);
UTIL_Format(error, maxlength, "Could not find required plugin \"%s\"", name);
}
return false;
}
@@ -1273,7 +1308,8 @@ bool CPluginManager::LoadOrRequireExtensions(CPlugin *pPlugin, unsigned int pass
if (ext->autoload)
{
g_LibSys.PathFormat(path, PLATFORM_MAX_PATH, "%s", file);
g_Extensions.LoadAutoExtension(path);
bool bErrorOnMissing = ext->required ? true : false;
g_Extensions.LoadAutoExtension(path, bErrorOnMissing);
}
}
else if (pass == 2)
@@ -1293,7 +1329,7 @@ bool CPluginManager::LoadOrRequireExtensions(CPlugin *pPlugin, unsigned int pass
{
if (error)
{
snprintf(error, maxlength, "Required extension \"%s\" file(\"%s\") not running", name, file);
UTIL_Format(error, maxlength, "Required extension \"%s\" file(\"%s\") not running", name, file);
}
return false;
}
@@ -1361,7 +1397,7 @@ bool CPluginManager::RunSecondPass(CPlugin *pPlugin, char *error, size_t maxleng
{
if (error)
{
snprintf(error, maxlength, "Native \"%s\" was not found", native->name);
UTIL_Format(error, maxlength, "Native \"%s\" was not found", native->name);
}
return false;
}
@@ -1951,7 +1987,7 @@ void CPluginManager::OnRootConsoleCommand(const char *cmdname, const CCommand &c
assert(pl->GetStatus() != Plugin_Created);
int len = 0;
const sm_plugininfo_t *info = pl->GetPublicInfo();
if (pl->GetStatus() != Plugin_Running)
if (pl->GetStatus() != Plugin_Running && !pl->IsSilentlyFailed())
{
len += UTIL_Format(buffer, sizeof(buffer), " %02d <%s>", id, GetStatusText(pl->GetStatus()));
@@ -1967,6 +2003,8 @@ void CPluginManager::OnRootConsoleCommand(const char *cmdname, const CCommand &c
}
if (pl->GetStatus() < Plugin_Created)
{
if (pl->IsSilentlyFailed())
len += UTIL_Format(&buffer[len], sizeof(buffer)-len, " Disabled:");
len += UTIL_Format(&buffer[len], sizeof(buffer)-len, " \"%s\"", (IS_STR_FILLED(info->name)) ? info->name : pl->GetFilename());
if (IS_STR_FILLED(info->version))
{
@@ -2015,7 +2053,7 @@ void CPluginManager::OnRootConsoleCommand(const char *cmdname, const CCommand &c
char pluginfile[256];
const char *ext = g_LibSys.GetFileExtension(filename) ? "" : ".smx";
UTIL_Format(pluginfile, sizeof(pluginfile), "%s%s", filename, ext);
g_SourceMod.BuildPath(Path_None, pluginfile, sizeof(pluginfile), "%s%s", filename, ext);
IPlugin *pl = LoadPlugin(pluginfile, false, PluginType_MapUpdated, error, sizeof(error), &wasloaded);
@@ -2062,7 +2100,7 @@ void CPluginManager::OnRootConsoleCommand(const char *cmdname, const CCommand &c
{
char pluginfile[256];
const char *ext = g_LibSys.GetFileExtension(arg) ? "" : ".smx";
UTIL_Format(pluginfile, sizeof(pluginfile), "%s%s", arg, ext);
g_SourceMod.BuildPath(Path_None, pluginfile, sizeof(pluginfile), "%s%s", arg, ext);
if (!sm_trie_retrieve(m_LoadLookup, pluginfile, (void **)&pl))
{
@@ -2152,7 +2190,7 @@ void CPluginManager::OnRootConsoleCommand(const char *cmdname, const CCommand &c
{
char pluginfile[256];
const char *ext = g_LibSys.GetFileExtension(arg) ? "" : ".smx";
UTIL_Format(pluginfile, sizeof(pluginfile), "%s%s", arg, ext);
g_SourceMod.BuildPath(Path_None, pluginfile, sizeof(pluginfile), "%s%s", arg, ext);
if (!sm_trie_retrieve(m_LoadLookup, pluginfile, (void **)&pl))
{
@@ -2273,7 +2311,7 @@ void CPluginManager::OnRootConsoleCommand(const char *cmdname, const CCommand &c
{
char pluginfile[256];
const char *ext = g_LibSys.GetFileExtension(arg) ? "" : ".smx";
UTIL_Format(pluginfile, sizeof(pluginfile), "%s%s", arg, ext);
g_SourceMod.BuildPath(Path_None, pluginfile, sizeof(pluginfile), "%s%s", arg, ext);
if (!sm_trie_retrieve(m_LoadLookup, pluginfile, (void **)&pl))
{
@@ -2284,7 +2322,10 @@ void CPluginManager::OnRootConsoleCommand(const char *cmdname, const CCommand &c
char name[PLATFORM_MAX_PATH];
const sm_plugininfo_t *info = pl->GetPublicInfo();
strcpy(name, (IS_STR_FILLED(info->name)) ? info->name : pl->GetFilename());
if (pl->GetStatus() <= Plugin_Paused)
strcpy(name, (IS_STR_FILLED(info->name)) ? info->name : pl->GetFilename());
else
strcpy(name, pl->GetFilename());
if (ReloadPlugin(pl))
{
@@ -2624,3 +2665,83 @@ void CPluginManager::SyncMaxClients(int max_clients)
(*iter)->SyncMaxClients(max_clients);
}
}
void CPluginManager::ListPluginsToClient(CPlayer *player, const CCommand &args)
{
char buffer[256];
unsigned int id = 0;
int plnum = GetPluginCount();
edict_t *e = player->GetEdict();
unsigned int start = 0;
if (!plnum)
{
ClientConsolePrint(e, "[SM] No plugins found.");
return;
}
if (args.ArgC() > 2)
{
start = atoi(args.Arg(2));
}
CPlugin *pl;
SourceHook::List<CPlugin *>::iterator iter;
SourceHook::List<CPlugin *> m_FailList;
for (iter = m_plugins.begin();
iter != m_plugins.end();
iter++)
{
pl = (*iter);
if (pl->GetStatus() != Plugin_Running)
{
continue;
}
/* Count valid plugins */
id++;
if (id < start)
{
continue;
}
if (id - start > 10)
{
break;
}
size_t len;
const sm_plugininfo_t *info = pl->GetPublicInfo();
len = UTIL_Format(buffer, sizeof(buffer), " \"%s\"", (IS_STR_FILLED(info->name)) ? info->name : pl->GetFilename());
if (IS_STR_FILLED(info->version))
{
len += UTIL_Format(&buffer[len], sizeof(buffer)-len, " (%s)", info->version);
}
if (IS_STR_FILLED(info->author))
{
UTIL_Format(&buffer[len], sizeof(buffer)-len, " by %s", info->author);
}
else
{
UTIL_Format(&buffer[len], sizeof(buffer)-len, " %s", pl->m_filename);
}
ClientConsolePrint(e, "%s", buffer);
}
/* See if we can get more plugins */
while (iter != m_plugins.end())
{
if ((*iter)->GetStatus() == Plugin_Running)
{
break;
}
}
/* Do we actually have more plugins? */
if (iter != m_plugins.end())
{
ClientConsolePrint(e, "To see more, type \"sm plugins %d\"", id);
}
}
+23 -3
View File
@@ -2,7 +2,7 @@
* vim: set ts=4 :
* =============================================================================
* SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
* Copyright (C) 2004-2010 AlliedModders LLC. All rights reserved.
* =============================================================================
*
* This program is free software; you can redistribute it and/or modify it under
@@ -47,7 +47,11 @@
#include "sm_trie.h"
#include "sourcemod.h"
#include <IRootConsoleMenu.h>
#if defined ORANGEBOX_BUILD
#if SOURCE_ENGINE == SE_ALIENSWARM
#include "convar_sm_swarm.h"
#elif (SOURCE_ENGINE == SE_LEFT4DEAD) || (SOURCE_ENGINE == SE_LEFT4DEAD2)
#include "convar_sm_l4d.h"
#elif (SOURCE_ENGINE == SE_ORANGEBOX) || (SOURCE_ENGINE == SE_BLOODYGOODTIME) || (SOURCE_ENGINE == SE_EYE) || (SOURCE_ENGINE == SE_ORANGEBOXVALVE)
#include "convar_sm_ob.h"
#else
#include "convar_sm.h"
@@ -56,6 +60,8 @@
#include "NativeOwner.h"
#include "ShareSys.h"
class CPlayer;
using namespace SourceHook;
/**
@@ -113,9 +119,17 @@ enum LoadRes
LoadRes_Successful,
LoadRes_AlreadyLoaded,
LoadRes_Failure,
LoadRes_SilentFailure,
LoadRes_NeverLoad
};
enum APLRes
{
APLRes_Success,
APLRes_Failure,
APLRes_SilentFailure
};
struct AutoConfig
{
String autocfg;
@@ -142,6 +156,8 @@ public:
const char *GetFilename();
bool IsDebugging();
PluginStatus GetStatus();
bool IsSilentlyFailed();
void SetSilentlyFailed(bool sf);
const sm_plugininfo_t *GetPublicInfo();
bool SetPauseState(bool paused);
unsigned int GetSerial();
@@ -179,7 +195,7 @@ public:
*
* If the error buffer is NULL, the error message is cached locally.
*/
bool Call_AskPluginLoad(char *error, size_t maxlength);
APLRes Call_AskPluginLoad(char *error, size_t maxlength);
/**
* Calls the OnPluginStart function.
@@ -243,6 +259,7 @@ private:
PluginType m_type;
char m_filename[PLATFORM_MAX_PATH];
PluginStatus m_status;
bool m_bSilentlyFailed;
unsigned int m_serial;
sm_plugininfo_t m_info;
char m_errormsg[256];
@@ -395,6 +412,8 @@ public:
CPlugin *FindPluginByConsoleArg(const char *arg);
void SyncMaxClients(int max_clients);
void ListPluginsToClient(CPlayer *player, const CCommand &args);
private:
LoadRes _LoadPlugin(CPlugin **pPlugin, const char *path, bool debug, PluginType type, char error[], size_t maxlength);
@@ -456,3 +475,4 @@ private:
extern CPluginManager g_PluginSys;
#endif //_INCLUDE_SOURCEMOD_PLUGINSYSTEM_H_
+82
View File
@@ -527,3 +527,85 @@ NativeEntry *ShareSystem::AddFakeNative(IPluginFunction *pFunc, const char *name
return pEntry;
}
void ShareSystem::AddCapabilityProvider(IExtension *myself, IFeatureProvider *provider,
const char *name)
{
if (m_caps.retrieve(name) != NULL)
return;
Capability cap;
cap.ext = myself;
cap.provider = provider;
m_caps.insert(name, cap);
}
void ShareSystem::DropCapabilityProvider(IExtension *myself, IFeatureProvider *provider,
const char *name)
{
Capability *pCap = m_caps.retrieve(name);
if (pCap == NULL)
return;
if (pCap->ext != myself || pCap->provider != provider)
return;
m_caps.remove(name);
}
FeatureStatus ShareSystem::TestFeature(IPluginRuntime *pRuntime, FeatureType feature,
const char *name)
{
switch (feature)
{
case FeatureType_Native:
return TestNative(pRuntime, name);
case FeatureType_Capability:
return TestCap(name);
default:
break;
}
return FeatureStatus_Unknown;
}
FeatureStatus ShareSystem::TestNative(IPluginRuntime *pRuntime, const char *name)
{
uint32_t index;
if (pRuntime->FindNativeByName(name, &index) == SP_ERROR_NONE)
{
sp_native_t *native;
if (pRuntime->GetNativeByIndex(index, &native) == SP_ERROR_NONE)
{
if (native->status == SP_NATIVE_BOUND)
return FeatureStatus_Available;
else
return FeatureStatus_Unknown;
}
}
NativeEntry *entry = FindNative(name);
if (entry == NULL)
return FeatureStatus_Unknown;
if ((entry->replacement.owner != NULL || entry->owner != NULL) &&
(entry->replacement.func != NULL || entry->func != NULL))
{
return FeatureStatus_Available;
}
else
{
return FeatureStatus_Unavailable;
}
}
FeatureStatus ShareSystem::TestCap(const char *name)
{
Capability *cap = m_caps.retrieve(name);
if (cap == NULL)
return FeatureStatus_Unknown;
return cap->provider->GetFeatureStatus(FeatureType_Capability, name);
}
+16 -2
View File
@@ -87,7 +87,13 @@ struct NativeEntry
FakeNative *fake;
};
class ShareSystem :
struct Capability
{
IExtension *ext;
IFeatureProvider *provider;
};
class ShareSystem :
public IShareSys,
public SMGlobalClass,
public IHandleTypeDispatch
@@ -110,6 +116,10 @@ public: //IShareSys
void AddDependency(IExtension *myself, const char *filename, bool require, bool autoload);
void RegisterLibrary(IExtension *myself, const char *name);
void OverrideNatives(IExtension *myself, const sp_nativeinfo_t *natives);
void AddCapabilityProvider(IExtension *myself, IFeatureProvider *provider,
const char *name);
void DropCapabilityProvider(IExtension *myself, IFeatureProvider *provider,
const char *name);
public: //SMGlobalClass
/* Pre-empt in case anything tries to register idents early */
void Initialize();
@@ -119,6 +129,9 @@ public: //IHandleTypeDispatch
public:
IdentityToken_t *CreateCoreIdentity();
void RemoveInterfaces(IExtension *pExtension);
FeatureStatus TestFeature(IPluginRuntime *pRuntime, FeatureType feature, const char *name);
FeatureStatus TestNative(IPluginRuntime *pRuntime, const char *name);
FeatureStatus TestCap(const char *name);
public:
inline IdentityToken_t *GetIdentRoot()
{
@@ -128,10 +141,10 @@ public:
void BindNativesToPlugin(CPlugin *pPlugin, bool bCoreOnly);
void BindNativeToPlugin(CPlugin *pPlugin, NativeEntry *pEntry);
NativeEntry *AddFakeNative(IPluginFunction *pFunc, const char *name, SPVM_FAKENATIVE_FUNC func);
NativeEntry *FindNative(const char *name);
private:
NativeEntry *AddNativeToCache(CNativeOwner *pOwner, const sp_nativeinfo_t *ntv);
void ClearNativeFromCache(CNativeOwner *pOwner, const char *name);
NativeEntry *FindNative(const char *name);
void BindNativeToPlugin(CPlugin *pPlugin,
sp_native_t *ntv,
uint32_t index,
@@ -143,6 +156,7 @@ private:
HandleType_t m_IfaceType;
IdentityType_t m_CoreType;
KTrie<NativeEntry *> m_NtvCache;
KTrie<Capability> m_caps;
};
extern ShareSystem g_ShareSys;
+1 -1
View File
@@ -78,11 +78,11 @@ public: //ITimerSystem
float GetTickedTime();
void NotifyOfGameStart(float offset /* = 0.0f */);
bool GetMapTimeLeft(float *pTime);
IMapTimer *GetMapTimer();
public:
void RunFrame();
void RemoveMapChangeTimers();
void GameFrame(bool simulating);
IMapTimer *GetMapTimer();
private:
List<ITimer *> m_SingleTimers;
List<ITimer *> m_LoopTimers;
+73 -14
View File
@@ -2,7 +2,7 @@
* vim: set ts=4 :
* =============================================================================
* SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
* Copyright (C) 2004-2010 AlliedModders LLC. All rights reserved.
* =============================================================================
*
* This program is free software; you can redistribute it and/or modify it under
@@ -34,7 +34,11 @@
UserMessages g_UserMsgs;
#if SOURCE_ENGINE >= SE_LEFT4DEAD
SH_DECL_HOOK3(IVEngineServer, UserMessageBegin, SH_NOATTRIB, 0, bf_write *, IRecipientFilter *, int, const char *);
#else
SH_DECL_HOOK2(IVEngineServer, UserMessageBegin, SH_NOATTRIB, 0, bf_write *, IRecipientFilter *, int);
#endif
SH_DECL_HOOK0_void(IVEngineServer, MessageEnd, SH_NOATTRIB, 0);
UserMessages::UserMessages() : m_InterceptBuffer(m_pBase, 2500)
@@ -164,9 +168,17 @@ bf_write *UserMessages::StartMessage(int msg_id, const cell_t players[], unsigne
if (m_CurFlags & USERMSG_BLOCKHOOKS)
{
#if SOURCE_ENGINE >= SE_LEFT4DEAD
buffer = ENGINE_CALL(UserMessageBegin)(static_cast<IRecipientFilter *>(&m_CellRecFilter), msg_id, g_SMAPI->GetUserMessage(msg_id));
#else
buffer = ENGINE_CALL(UserMessageBegin)(static_cast<IRecipientFilter *>(&m_CellRecFilter), msg_id);
#endif
} else {
#if SOURCE_ENGINE >= SE_LEFT4DEAD
buffer = engine->UserMessageBegin(static_cast<IRecipientFilter *>(&m_CellRecFilter), msg_id, g_SMAPI->GetUserMessage(msg_id));
#else
buffer = engine->UserMessageBegin(static_cast<IRecipientFilter *>(&m_CellRecFilter), msg_id);
#endif
}
return buffer;
@@ -193,7 +205,31 @@ bool UserMessages::EndMessage()
return true;
}
bool UserMessages::HookUserMessage2(int msg_id,
IUserMessageListener *pListener,
bool intercept)
{
return InternalHook(msg_id, pListener, intercept, true);
}
bool UserMessages::UnhookUserMessage2(int msg_id,
IUserMessageListener *pListener,
bool intercept)
{
return InternalUnhook(msg_id, pListener, intercept, true);
}
bool UserMessages::HookUserMessage(int msg_id, IUserMessageListener *pListener, bool intercept)
{
return InternalHook(msg_id, pListener, intercept, false);
}
bool UserMessages::UnhookUserMessage(int msg_id, IUserMessageListener *pListener, bool intercept)
{
return InternalUnhook(msg_id, pListener, intercept, false);
}
bool UserMessages::InternalHook(int msg_id, IUserMessageListener *pListener, bool intercept, bool isNew)
{
if (msg_id < 0 || msg_id >= 255)
{
@@ -212,6 +248,7 @@ bool UserMessages::HookUserMessage(int msg_id, IUserMessageListener *pListener,
pInfo->Callback = pListener;
pInfo->IsHooked = false;
pInfo->KillMe = false;
pInfo->IsNew = isNew;
if (!m_HookCount++)
{
@@ -231,8 +268,8 @@ bool UserMessages::HookUserMessage(int msg_id, IUserMessageListener *pListener,
return true;
}
bool UserMessages::UnhookUserMessage(int msg_id, IUserMessageListener *pListener, bool intercept)
{
bool UserMessages::InternalUnhook(int msg_id, IUserMessageListener *pListener, bool intercept, bool isNew)
{
MsgList *pList;
MsgIter iter;
ListenerInfo *pInfo;
@@ -247,7 +284,7 @@ bool UserMessages::UnhookUserMessage(int msg_id, IUserMessageListener *pListener
for (iter=pList->begin(); iter!=pList->end(); iter++)
{
pInfo = (*iter);
if (pInfo->Callback == pListener)
if (pInfo->Callback == pListener && pInfo->IsNew == isNew)
{
if (pInfo->IsHooked)
{
@@ -279,7 +316,11 @@ void UserMessages::_DecRefCounter()
}
}
#if SOURCE_ENGINE >= SE_LEFT4DEAD
bf_write *UserMessages::OnStartMessage_Pre(IRecipientFilter *filter, int msg_type, const char *msg_name)
#else
bf_write *UserMessages::OnStartMessage_Pre(IRecipientFilter *filter, int msg_type)
#endif
{
bool is_intercept_empty = m_msgIntercepts[msg_type].empty();
bool is_hook_empty = m_msgHooks[msg_type].empty();
@@ -305,7 +346,11 @@ bf_write *UserMessages::OnStartMessage_Pre(IRecipientFilter *filter, int msg_typ
RETURN_META_VALUE(MRES_IGNORED, NULL);
}
#if SOURCE_ENGINE >= SE_LEFT4DEAD
bf_write *UserMessages::OnStartMessage_Post(IRecipientFilter *filter, int msg_type, const char *msg_name)
#else
bf_write *UserMessages::OnStartMessage_Post(IRecipientFilter *filter, int msg_type)
#endif
{
if (!m_InHook)
{
@@ -319,7 +364,7 @@ bf_write *UserMessages::OnStartMessage_Post(IRecipientFilter *filter, int msg_ty
void UserMessages::OnMessageEnd_Post()
{
if (!m_InHook || m_BlockEndPost)
if (!m_InHook)
{
RETURN_META(MRES_IGNORED);
}
@@ -328,12 +373,22 @@ void UserMessages::OnMessageEnd_Post()
MsgIter iter;
ListenerInfo *pInfo;
m_InHook = false;
pList = &m_msgIntercepts[m_CurId];
for (iter=pList->begin(); iter!=pList->end(); )
{
pInfo = (*iter);
if (m_BlockEndPost && !pInfo->IsNew)
{
continue;
}
pInfo->IsHooked = true;
pInfo->Callback->OnUserMessageSent(m_CurId);
if (pInfo->IsNew)
{
pInfo->Callback->OnPostUserMessage(m_CurId, !m_BlockEndPost);
}
if (pInfo->KillMe)
{
@@ -347,14 +402,20 @@ void UserMessages::OnMessageEnd_Post()
iter++;
}
m_InHook = false;
pList = &m_msgHooks[m_CurId];
for (iter=pList->begin(); iter!=pList->end(); )
{
pInfo = (*iter);
if (m_BlockEndPost && !pInfo->IsNew)
{
continue;
}
pInfo->IsHooked = true;
pInfo->Callback->OnUserMessageSent(m_CurId);
if (pInfo->IsNew)
{
pInfo->Callback->OnPostUserMessage(m_CurId, !m_BlockEndPost);
}
if (pInfo->KillMe)
{
@@ -435,16 +496,15 @@ void UserMessages::OnMessageEnd_Pre()
iter++;
}
if (handled)
{
goto supercede;
}
if (intercepted)
if (!handled && intercepted)
{
bf_write *engine_bfw;
#if SOURCE_ENGINE >= SE_LEFT4DEAD
engine_bfw = ENGINE_CALL(UserMessageBegin)(m_CurRecFilter, m_CurId, g_SMAPI->GetUserMessage(m_CurId));
#else
engine_bfw = ENGINE_CALL(UserMessageBegin)(m_CurRecFilter, m_CurId);
#endif
m_ReadBuffer.StartReading(m_InterceptBuffer.GetBasePointer(), m_InterceptBuffer.GetNumBytesWritten());
engine_bfw->WriteBitsFromBuffer(&m_ReadBuffer, m_InterceptBuffer.GetNumBitsWritten());
ENGINE_CALL(MessageEnd)();
@@ -471,7 +531,6 @@ void UserMessages::OnMessageEnd_Pre()
RETURN_META((intercepted) ? MRES_SUPERCEDE : MRES_IGNORED);
supercede:
m_InHook = false;
m_BlockEndPost = true;
RETURN_META(MRES_SUPERCEDE);
}
+15 -1
View File
@@ -2,7 +2,7 @@
* vim: set ts=4 :
* =============================================================================
* SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
* Copyright (C) 2004-2010 AlliedModders LLC. All rights reserved.
* =============================================================================
*
* This program is free software; you can redistribute it and/or modify it under
@@ -48,6 +48,7 @@ struct ListenerInfo
IUserMessageListener *Callback;
bool IsHooked;
bool KillMe;
bool IsNew;
};
typedef List<ListenerInfo *> MsgList;
@@ -71,12 +72,25 @@ public: //IUserMessages
bool UnhookUserMessage(int msg_id, IUserMessageListener *pListener, bool intercept=false);
bf_write *StartMessage(int msg_id, const cell_t players[], unsigned int playersNum, int flags);
bool EndMessage();
bool HookUserMessage2(int msg_id,
IUserMessageListener *pListener,
bool intercept=false);
bool UnhookUserMessage2(int msg_id,
IUserMessageListener *pListener,
bool intercept=false);
public:
#if SOURCE_ENGINE >= SE_LEFT4DEAD
bf_write *OnStartMessage_Pre(IRecipientFilter *filter, int msg_type, const char *msg_name);
bf_write *OnStartMessage_Post(IRecipientFilter *filter, int msg_type, const char *msg_name);
#else
bf_write *OnStartMessage_Pre(IRecipientFilter *filter, int msg_type);
bf_write *OnStartMessage_Post(IRecipientFilter *filter, int msg_type);
#endif
void OnMessageEnd_Pre();
void OnMessageEnd_Post();
private:
bool InternalHook(int msg_id, IUserMessageListener *pListener, bool intercept, bool isNew);
bool InternalUnhook(int msg_id, IUserMessageListener *pListener, bool intercept, bool isNew);
void _DecRefCounter();
private:
List<ListenerInfo *> m_msgHooks[255];
+34 -20
View File
@@ -35,9 +35,13 @@
#include "concmd_cleaner.h"
#include "sm_stringutil.h"
#include "sourcemm_api.h"
#include "compat_wrappers.h"
#if defined ORANGEBOX_BUILD
#if SOURCE_ENGINE >= SE_ORANGEBOX
SH_DECL_HOOK1_void(ICvar, UnregisterConCommand, SH_NOATTRIB, 0, ConCommandBase *);
SH_DECL_HOOK1_void(ICvar, RegisterConCommand, SH_NOATTRIB, 0, ConCommandBase *);
#else
SH_DECL_HOOK1_void(ICvar, RegisterConCommandBase, SH_NOATTRIB, 0, ConCommandBase *);
#endif
using namespace SourceHook;
@@ -50,29 +54,55 @@ struct ConCommandInfo
};
List<ConCommandInfo *> tracked_bases;
IConCommandLinkListener *IConCommandLinkListener::head = NULL;
ConCommandBase *FindConCommandBase(const char *name);
class ConCommandCleaner : public SMGlobalClass
{
public:
#if defined ORANGEBOX_BUILD
void OnSourceModAllInitialized()
{
#if SOURCE_ENGINE >= SE_ORANGEBOX
SH_ADD_HOOK_MEMFUNC(ICvar, UnregisterConCommand, icvar, this, &ConCommandCleaner::UnlinkConCommandBase, false);
SH_ADD_HOOK_MEMFUNC(ICvar, RegisterConCommand, icvar, this, &ConCommandCleaner::LinkConCommandBase, false);
#else
SH_ADD_HOOK_MEMFUNC(ICvar, RegisterConCommandBase, icvar, this, &ConCommandCleaner::LinkConCommandBase, false);
#endif
}
void OnSourceModShutdown()
{
#if SOURCE_ENGINE >= SE_ORANGEBOX
SH_REMOVE_HOOK_MEMFUNC(ICvar, UnregisterConCommand, icvar, this, &ConCommandCleaner::UnlinkConCommandBase, false);
}
SH_REMOVE_HOOK_MEMFUNC(ICvar, RegisterConCommand, icvar, this, &ConCommandCleaner::LinkConCommandBase, false);
#else
SH_REMOVE_HOOK_MEMFUNC(ICvar, RegisterConCommandBase, icvar, this, &ConCommandCleaner::LinkConCommandBase, false);
#endif
}
void LinkConCommandBase(ConCommandBase *pBase)
{
IConCommandLinkListener *listener = IConCommandLinkListener::head;
while (listener)
{
listener->OnLinkConCommand(pBase);
listener = listener->next;
}
}
void UnlinkConCommandBase(ConCommandBase *pBase)
{
ConCommandInfo *pInfo;
List<ConCommandInfo *>::iterator iter = tracked_bases.begin();
IConCommandLinkListener *listener = IConCommandLinkListener::head;
while (listener)
{
listener->OnUnlinkConCommand(pBase);
listener = listener->next;
}
if (pBase)
{
while (iter != tracked_bases.end())
@@ -95,7 +125,7 @@ public:
while (iter != tracked_bases.end())
{
/* This is just god-awful! */
if (FindConCommandBase((*iter)->name) != (*iter)->pBase)
if (FindCommandBase((*iter)->name) != (*iter)->pBase)
{
pInfo = (*iter);
iter = tracked_bases.erase(iter);
@@ -143,22 +173,6 @@ public:
}
} s_ConCmdTracker;
ConCommandBase *FindConCommandBase(const char *name)
{
const ConCommandBase *pBase = icvar->GetCommands();
while (pBase != NULL)
{
if (strcmp(pBase->GetName(), name) == 0)
{
return const_cast<ConCommandBase *>(pBase);
}
pBase = pBase->GetNext();
}
return NULL;
}
void TrackConCommandBase(ConCommandBase *pBase, IConCommandTracker *me)
{
s_ConCmdTracker.AddTarget(pBase, me);
+22 -1
View File
@@ -38,9 +38,30 @@ public:
virtual void OnUnlinkConCommandBase(ConCommandBase *pBase, const char *name, bool is_read_safe) = 0;
};
ConCommandBase *FindConCommandBase(const char *name);
void TrackConCommandBase(ConCommandBase *pBase, IConCommandTracker *me);
void UntrackConCommandBase(ConCommandBase *pBase, IConCommandTracker *me);
void Global_OnUnlinkConCommandBase(ConCommandBase *pBase);
class IConCommandLinkListener
{
friend class ConCommandCleaner;
static IConCommandLinkListener *head;
IConCommandLinkListener *next;
public:
IConCommandLinkListener()
{
next = head;
head = this;
}
virtual void OnLinkConCommand(ConCommandBase *pBase)
{
}
virtual void OnUnlinkConCommand(ConCommandBase *pBase)
{
}
};
#endif //_INCLUDE_CONCMD_TRACKER_H_
+718
View File
@@ -0,0 +1,718 @@
//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
// $Workfile: $
// $Date: $
//
//-----------------------------------------------------------------------------
// $NoKeywords: $
//===========================================================================//
#ifndef CONVAR_H
#define CONVAR_H
#if _WIN32
#pragma once
#endif
#include "tier0/dbg.h"
#include "tier1/iconvar.h"
#include "tier1/utlvector.h"
#include "tier1/utlstring.h"
#include "icvar.h"
#ifdef _WIN32
#define FORCEINLINE_CVAR FORCEINLINE
#elif defined _LINUX || defined __APPLE__
#define FORCEINLINE_CVAR inline
#else
#error "implement me"
#endif
//-----------------------------------------------------------------------------
// Forward declarations
//-----------------------------------------------------------------------------
class ConVar;
class CCommand;
class ConCommand;
class ConCommandBase;
struct characterset_t;
//-----------------------------------------------------------------------------
// Any executable that wants to use ConVars need to implement one of
// these to hook up access to console variables.
//-----------------------------------------------------------------------------
class IConCommandBaseAccessor
{
public:
// Flags is a combination of FCVAR flags in cvar.h.
// hOut is filled in with a handle to the variable.
virtual bool RegisterConCommandBase( ConCommandBase *pVar ) = 0;
};
//-----------------------------------------------------------------------------
// Helper method for console development
//-----------------------------------------------------------------------------
#if defined( _X360 ) && !defined( _RETAIL )
void ConVar_PublishToVXConsole();
#endif
//-----------------------------------------------------------------------------
// Called when a ConCommand needs to execute
//-----------------------------------------------------------------------------
typedef void ( *FnCommandCallbackV1_t )( void );
typedef void ( *FnCommandCallback_t )( const CCommand &command );
#define COMMAND_COMPLETION_MAXITEMS 64
#define COMMAND_COMPLETION_ITEM_LENGTH 64
//-----------------------------------------------------------------------------
// Returns 0 to COMMAND_COMPLETION_MAXITEMS worth of completion strings
//-----------------------------------------------------------------------------
typedef int ( *FnCommandCompletionCallback )( const char *partial, char commands[ COMMAND_COMPLETION_MAXITEMS ][ COMMAND_COMPLETION_ITEM_LENGTH ] );
//-----------------------------------------------------------------------------
// Interface version
//-----------------------------------------------------------------------------
class ICommandCallback
{
public:
virtual void CommandCallback( const CCommand &command ) = 0;
};
class ICommandCompletionCallback
{
public:
virtual int CommandCompletionCallback( const char *pPartial, CUtlVector< CUtlString > &commands ) = 0;
};
//-----------------------------------------------------------------------------
// Purpose: The base console invoked command/cvar interface
//-----------------------------------------------------------------------------
class ConCommandBase
{
friend class CCvar;
friend class ConVar;
friend class ConCommand;
friend void ConVar_Register( int nCVarFlag, IConCommandBaseAccessor *pAccessor );
friend void ConVar_PublishToVXConsole();
// FIXME: Remove when ConVar changes are done
friend class CDefaultCvar;
public:
ConCommandBase( void );
ConCommandBase( const char *pName, const char *pHelpString = 0,
int flags = 0 );
virtual ~ConCommandBase( void );
virtual bool IsCommand( void ) const;
// Check flag
virtual bool IsFlagSet( int flag ) const;
// Set flag
virtual void AddFlags( int flags );
// Remove flag
virtual void RemoveFlags( int flags );
// Get flags
virtual int GetFlags( void ) const;
// Return name of cvar
virtual const char *GetName( void ) const;
// Return help text for cvar
virtual const char *GetHelpText( void ) const;
// Deal with next pointer
const ConCommandBase *GetNext( void ) const;
ConCommandBase *GetNext( void );
inline void SetNext(ConCommandBase *pBase)
{
m_pNext = pBase;
}
virtual bool IsRegistered( void ) const;
// Returns the DLL identifier
virtual CVarDLLIdentifier_t GetDLLIdentifier() const;
protected:
virtual void Create( const char *pName, const char *pHelpString = 0,
int flags = 0 );
// Used internally by OneTimeInit to initialize/shutdown
virtual void Init();
void Shutdown();
// Internal copy routine ( uses new operator from correct module )
char *CopyString( const char *from );
private:
// Next ConVar in chain
// Prior to register, it points to the next convar in the DLL.
// Once registered, though, m_pNext is reset to point to the next
// convar in the global list
ConCommandBase *m_pNext;
// Has the cvar been added to the global list?
bool m_bRegistered;
// Static data
const char *m_pszName;
const char *m_pszHelpString;
// ConVar flags
int m_nFlags;
protected:
// ConVars add themselves to this list for the executable.
// Then ConVar_Register runs through all the console variables
// and registers them into a global list stored in vstdlib.dll
static ConCommandBase *s_pConCommandBases;
// ConVars in this executable use this 'global' to access values.
static IConCommandBaseAccessor *s_pAccessor;
public:
inline void SetFlags(int flags)
{
m_nFlags = flags;
}
};
//-----------------------------------------------------------------------------
// Command tokenizer
//-----------------------------------------------------------------------------
class CCommand
{
public:
CCommand();
CCommand( int nArgC, const char **ppArgV );
bool Tokenize( const char *pCommand, characterset_t *pBreakSet = NULL );
void Reset();
int ArgC() const;
const char **ArgV() const;
const char *ArgS() const; // All args that occur after the 0th arg, in string form
const char *GetCommandString() const; // The entire command in string form, including the 0th arg
const char *operator[]( int nIndex ) const; // Gets at arguments
const char *Arg( int nIndex ) const; // Gets at arguments
// Helper functions to parse arguments to commands.
const char* FindArg( const char *pName ) const;
int FindArgInt( const char *pName, int nDefaultVal ) const;
static int MaxCommandLength();
static characterset_t* DefaultBreakSet();
private:
enum
{
COMMAND_MAX_ARGC = 64,
COMMAND_MAX_LENGTH = 512,
};
int m_nArgc;
int m_nArgv0Size;
char m_pArgSBuffer[ COMMAND_MAX_LENGTH ];
char m_pArgvBuffer[ COMMAND_MAX_LENGTH ];
const char* m_ppArgv[ COMMAND_MAX_ARGC ];
};
inline int CCommand::MaxCommandLength()
{
return COMMAND_MAX_LENGTH - 1;
}
inline int CCommand::ArgC() const
{
return m_nArgc;
}
inline const char **CCommand::ArgV() const
{
return m_nArgc ? (const char**)m_ppArgv : NULL;
}
inline const char *CCommand::ArgS() const
{
return m_nArgv0Size ? &m_pArgSBuffer[m_nArgv0Size] : "";
}
inline const char *CCommand::GetCommandString() const
{
return m_nArgc ? m_pArgSBuffer : "";
}
inline const char *CCommand::Arg( int nIndex ) const
{
// FIXME: Many command handlers appear to not be particularly careful
// about checking for valid argc range. For now, we're going to
// do the extra check and return an empty string if it's out of range
if ( nIndex < 0 || nIndex >= m_nArgc )
return "";
return m_ppArgv[nIndex];
}
inline const char *CCommand::operator[]( int nIndex ) const
{
return Arg( nIndex );
}
//-----------------------------------------------------------------------------
// Purpose: The console invoked command
//-----------------------------------------------------------------------------
class ConCommand : public ConCommandBase
{
friend class CCvar;
public:
typedef ConCommandBase BaseClass;
ConCommand( const char *pName, FnCommandCallbackV1_t callback,
const char *pHelpString = 0, int flags = 0, FnCommandCompletionCallback completionFunc = 0 );
ConCommand( const char *pName, FnCommandCallback_t callback,
const char *pHelpString = 0, int flags = 0, FnCommandCompletionCallback completionFunc = 0 );
ConCommand( const char *pName, ICommandCallback *pCallback,
const char *pHelpString = 0, int flags = 0, ICommandCompletionCallback *pCommandCompletionCallback = 0 );
virtual ~ConCommand( void );
virtual bool IsCommand( void ) const;
virtual int AutoCompleteSuggest( const char *partial, CUtlVector< CUtlString > &commands );
virtual bool CanAutoComplete( void );
// Invoke the function
virtual void Dispatch( const CCommand &command );
private:
// NOTE: To maintain backward compat, we have to be very careful:
// All public virtual methods must appear in the same order always
// since engine code will be calling into this code, which *does not match*
// in the mod code; it's using slightly different, but compatible versions
// of this class. Also: Be very careful about adding new fields to this class.
// Those fields will not exist in the version of this class that is instanced
// in mod code.
// Call this function when executing the command
union
{
FnCommandCallbackV1_t m_fnCommandCallbackV1;
FnCommandCallback_t m_fnCommandCallback;
ICommandCallback *m_pCommandCallback;
};
union
{
FnCommandCompletionCallback m_fnCompletionCallback;
ICommandCompletionCallback *m_pCommandCompletionCallback;
};
bool m_bHasCompletionCallback : 1;
bool m_bUsingNewCommandCallback : 1;
bool m_bUsingCommandCallbackInterface : 1;
public:
inline FnCommandCallback_t GetCallback() const
{
return m_fnCommandCallback;
}
};
//-----------------------------------------------------------------------------
// Purpose: A console variable
//-----------------------------------------------------------------------------
class ConVar : public ConCommandBase, public IConVar
{
friend class CCvar;
friend class ConVarRef;
public:
typedef ConCommandBase BaseClass;
ConVar( const char *pName, const char *pDefaultValue, int flags = 0);
ConVar( const char *pName, const char *pDefaultValue, int flags,
const char *pHelpString );
ConVar( const char *pName, const char *pDefaultValue, int flags,
const char *pHelpString, bool bMin, float fMin, bool bMax, float fMax );
ConVar( const char *pName, const char *pDefaultValue, int flags,
const char *pHelpString, FnChangeCallback_t callback );
ConVar( const char *pName, const char *pDefaultValue, int flags,
const char *pHelpString, bool bMin, float fMin, bool bMax, float fMax,
FnChangeCallback_t callback );
virtual ~ConVar( void );
virtual bool IsCommand( void ) const;
virtual bool IsFlagSet( int flag ) const;
virtual void AddFlags( int flags );
virtual int GetFlags( void ) const;
virtual const char *GetName( void ) const;
virtual const char* GetHelpText( void ) const;
virtual bool IsRegistered( void ) const;
// Install a change callback (there shouldn't already be one....)
void InstallChangeCallback( FnChangeCallback_t callback );
// Retrieve value
FORCEINLINE_CVAR float GetFloat( void ) const;
FORCEINLINE_CVAR int GetInt( void ) const;
FORCEINLINE_CVAR bool GetBool() const { return !!GetInt(); }
FORCEINLINE_CVAR char const *GetString( void ) const;
// Used internally by OneTimeInit to initialize.
virtual void Init();
virtual const char *GetBaseName( void ) const;
virtual int GetSplitScreenPlayerSlot ( void ) const;
// Any function that allocates/frees memory needs to be virtual or else you'll have crashes
// from alloc/free across dll/exe boundaries.
// These just call into the IConCommandBaseAccessor to check flags and set the var (which ends up calling InternalSetValue).
virtual void SetValue( const char *value );
virtual void SetValue( float value );
virtual void SetValue( int value );
#if SOURCE_ENGINE >= SE_LEFT4DEAD2
virtual void SetValue( Color value );
#endif
// Reset to default value
void Revert( void );
// True if it has a min/max setting
bool GetMin( float& minVal ) const;
bool GetMax( float& maxVal ) const;
const char *GetDefault( void ) const;
private:
// Called by CCvar when the value of a var is changing.
virtual void InternalSetValue(const char *value);
// For CVARs marked FCVAR_NEVER_AS_STRING
virtual void InternalSetFloatValue( float fNewValue );
virtual void InternalSetIntValue( int nValue );
#if SOURCE_ENGINE >= SE_LEFT4DEAD2
virtual void InternalSetColorValue( Color value );
#endif
virtual bool ClampValue( float& value );
virtual void ChangeStringValue( const char *tempVal, float flOldValue );
virtual void Create( const char *pName, const char *pDefaultValue, int flags = 0,
const char *pHelpString = 0, bool bMin = false, float fMin = 0.0,
bool bMax = false, float fMax = false, FnChangeCallback_t callback = 0 );
private:
// This either points to "this" or it points to the original declaration of a ConVar.
// This allows ConVars to exist in separate modules, and they all use the first one to be declared.
// m_pParent->m_pParent must equal m_pParent (ie: m_pParent must be the root, or original, ConVar).
ConVar *m_pParent;
// Static data
const char *m_pszDefaultValue;
// Value
// Dynamically allocated
char *m_pszString;
int m_StringLength;
// Values
float m_fValue;
int m_nValue;
// Min/Max values
bool m_bHasMin;
float m_fMinVal;
bool m_bHasMax;
float m_fMaxVal;
// Call this function when ConVar changes
FnChangeCallback_t m_fnChangeCallback;
public:
inline FnChangeCallback_t GetCallback() const
{
return m_fnChangeCallback;
}
inline void SetMin(bool set, float min=0.0)
{
m_bHasMin = set;
m_fMinVal = min;
}
inline void SetMax(bool set, float max=0.0)
{
m_bHasMax = set;
m_fMaxVal = max;
}
};
//-----------------------------------------------------------------------------
// Purpose: Return ConVar value as a float
// Output : float
//-----------------------------------------------------------------------------
FORCEINLINE_CVAR float ConVar::GetFloat( void ) const
{
return m_pParent->m_fValue;
}
//-----------------------------------------------------------------------------
// Purpose: Return ConVar value as an int
// Output : int
//-----------------------------------------------------------------------------
FORCEINLINE_CVAR int ConVar::GetInt( void ) const
{
return m_pParent->m_nValue;
}
//-----------------------------------------------------------------------------
// Purpose: Return ConVar value as a string, return "" for bogus string pointer, etc.
// Output : const char *
//-----------------------------------------------------------------------------
FORCEINLINE_CVAR const char *ConVar::GetString( void ) const
{
if ( m_nFlags & FCVAR_NEVER_AS_STRING )
return "FCVAR_NEVER_AS_STRING";
return ( m_pParent->m_pszString ) ? m_pParent->m_pszString : "";
}
//-----------------------------------------------------------------------------
// Used to read/write convars that already exist (replaces the FindVar method)
//-----------------------------------------------------------------------------
class ConVarRef
{
public:
ConVarRef( const char *pName );
ConVarRef( const char *pName, bool bIgnoreMissing );
ConVarRef( IConVar *pConVar );
void Init( const char *pName, bool bIgnoreMissing );
bool IsValid() const;
bool IsFlagSet( int nFlags ) const;
IConVar *GetLinkedConVar();
// Get/Set value
float GetFloat( void ) const;
int GetInt( void ) const;
bool GetBool() const { return !!GetInt(); }
const char *GetString( void ) const;
void SetValue( const char *pValue );
void SetValue( float flValue );
void SetValue( int nValue );
void SetValue( bool bValue );
const char *GetName() const;
const char *GetDefault() const;
private:
// High-speed method to read convar data
IConVar *m_pConVar;
ConVar *m_pConVarState;
};
//-----------------------------------------------------------------------------
// Did we find an existing convar of that name?
//-----------------------------------------------------------------------------
FORCEINLINE_CVAR bool ConVarRef::IsFlagSet( int nFlags ) const
{
return ( m_pConVar->IsFlagSet( nFlags ) != 0 );
}
FORCEINLINE_CVAR IConVar *ConVarRef::GetLinkedConVar()
{
return m_pConVar;
}
FORCEINLINE_CVAR const char *ConVarRef::GetName() const
{
return m_pConVar->GetName();
}
//-----------------------------------------------------------------------------
// Purpose: Return ConVar value as a float
//-----------------------------------------------------------------------------
FORCEINLINE_CVAR float ConVarRef::GetFloat( void ) const
{
return m_pConVarState->m_fValue;
}
//-----------------------------------------------------------------------------
// Purpose: Return ConVar value as an int
//-----------------------------------------------------------------------------
FORCEINLINE_CVAR int ConVarRef::GetInt( void ) const
{
return m_pConVarState->m_nValue;
}
//-----------------------------------------------------------------------------
// Purpose: Return ConVar value as a string, return "" for bogus string pointer, etc.
//-----------------------------------------------------------------------------
FORCEINLINE_CVAR const char *ConVarRef::GetString( void ) const
{
Assert( !IsFlagSet( FCVAR_NEVER_AS_STRING ) );
return m_pConVarState->m_pszString;
}
FORCEINLINE_CVAR void ConVarRef::SetValue( const char *pValue )
{
m_pConVar->SetValue( pValue );
}
FORCEINLINE_CVAR void ConVarRef::SetValue( float flValue )
{
m_pConVar->SetValue( flValue );
}
FORCEINLINE_CVAR void ConVarRef::SetValue( int nValue )
{
m_pConVar->SetValue( nValue );
}
FORCEINLINE_CVAR void ConVarRef::SetValue( bool bValue )
{
m_pConVar->SetValue( bValue ? 1 : 0 );
}
FORCEINLINE_CVAR const char *ConVarRef::GetDefault() const
{
return m_pConVarState->m_pszDefaultValue;
}
//-----------------------------------------------------------------------------
// Called by the framework to register ConCommands with the ICVar
//-----------------------------------------------------------------------------
void ConVar_Register( int nCVarFlag = 0, IConCommandBaseAccessor *pAccessor = NULL );
void ConVar_Unregister( );
//-----------------------------------------------------------------------------
// Utility methods
//-----------------------------------------------------------------------------
void ConVar_PrintFlags( const ConCommandBase *var );
void ConVar_PrintDescription( const ConCommandBase *pVar );
//-----------------------------------------------------------------------------
// Purpose: Utility class to quickly allow ConCommands to call member methods
//-----------------------------------------------------------------------------
#ifdef _MSC_VER
#pragma warning (disable : 4355 )
#endif
template< class T >
class CConCommandMemberAccessor : public ConCommand, public ICommandCallback, public ICommandCompletionCallback
{
typedef ConCommand BaseClass;
typedef void ( T::*FnMemberCommandCallback_t )( const CCommand &command );
typedef int ( T::*FnMemberCommandCompletionCallback_t )( const char *pPartial, CUtlVector< CUtlString > &commands );
public:
CConCommandMemberAccessor( T* pOwner, const char *pName, FnMemberCommandCallback_t callback, const char *pHelpString = 0,
int flags = 0, FnMemberCommandCompletionCallback_t completionFunc = 0 ) :
BaseClass( pName, this, pHelpString, flags, ( completionFunc != 0 ) ? this : NULL )
{
m_pOwner = pOwner;
m_Func = callback;
m_CompletionFunc = completionFunc;
}
~CConCommandMemberAccessor()
{
Shutdown();
}
void SetOwner( T* pOwner )
{
m_pOwner = pOwner;
}
virtual void CommandCallback( const CCommand &command )
{
Assert( m_pOwner && m_Func );
(m_pOwner->*m_Func)( command );
}
virtual int CommandCompletionCallback( const char *pPartial, CUtlVector< CUtlString > &commands )
{
Assert( m_pOwner && m_CompletionFunc );
return (m_pOwner->*m_CompletionFunc)( pPartial, commands );
}
private:
T* m_pOwner;
FnMemberCommandCallback_t m_Func;
FnMemberCommandCompletionCallback_t m_CompletionFunc;
};
#ifdef _MSC_VER
#pragma warning ( default : 4355 )
#endif
//-----------------------------------------------------------------------------
// Purpose: Utility macros to quicky generate a simple console command
//-----------------------------------------------------------------------------
#define CON_COMMAND( name, description ) \
static void name( const CCommand &args ); \
static ConCommand name##_command( #name, name, description ); \
static void name( const CCommand &args )
#define CON_COMMAND_F( name, description, flags ) \
static void name( const CCommand &args ); \
static ConCommand name##_command( #name, name, description, flags ); \
static void name( const CCommand &args )
#define CON_COMMAND_F_COMPLETION( name, description, flags, completion ) \
static void name( const CCommand &args ); \
static ConCommand name##_command( #name, name, description, flags, completion ); \
static void name( const CCommand &args )
#define CON_COMMAND_EXTERN( name, _funcname, description ) \
void _funcname( const CCommand &args ); \
static ConCommand name##_command( #name, _funcname, description ); \
void _funcname( const CCommand &args )
#define CON_COMMAND_EXTERN_F( name, _funcname, description, flags ) \
void _funcname( const CCommand &args ); \
static ConCommand name##_command( #name, _funcname, description, flags ); \
void _funcname( const CCommand &args )
#define CON_COMMAND_MEMBER_F( _thisclass, name, _funcname, description, flags ) \
void _funcname( const CCommand &args ); \
friend class CCommandMemberInitializer_##_funcname; \
class CCommandMemberInitializer_##_funcname \
{ \
public: \
CCommandMemberInitializer_##_funcname() : m_ConCommandAccessor( NULL, name, &_thisclass::_funcname, description, flags ) \
{ \
m_ConCommandAccessor.SetOwner( GET_OUTER( _thisclass, m_##_funcname##_register ) ); \
} \
private: \
CConCommandMemberAccessor< _thisclass > m_ConCommandAccessor; \
}; \
\
CCommandMemberInitializer_##_funcname m_##_funcname##_register; \
#endif // CONVAR_H
+1 -1
View File
@@ -24,7 +24,7 @@
#ifdef _WIN32
#define FORCEINLINE_CVAR FORCEINLINE
#elif _LINUX
#elif defined _LINUX || defined __APPLE__
#define FORCEINLINE_CVAR inline
#else
#error "implement me"
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -37,7 +37,7 @@
#include "PlayerManager.h"
#include "CoreConfig.h"
#include <sm_queue.h>
#include "ThreadSupport.h"
#include <IThreader.h>
static IMutex *frame_mutex;
static Queue<FrameAction> *frame_queue;
+6 -1
View File
@@ -32,10 +32,15 @@
#ifndef _INCLUDE_SOURCEMOD_FRAME_HOOKS_H_
#define _INCLUDE_SOURCEMOD_FRAME_HOOKS_H_
typedef void (*FRAMEACTION)(void *data);
#include <ISourceMod.h>
using namespace SourceMod;
struct FrameAction
{
FrameAction(FRAMEACTION a, void *d) : data(d), action(a)
{
}
void *data;
FRAMEACTION action;
};
+59
View File
@@ -0,0 +1,59 @@
# vim: set ts=2 sw=2 tw=99 noet ft=python:
import os
compiler = SM.DefaultCompiler()
base = AMBuild.sourceFolder
compiler['CXXINCLUDES'].append(os.path.join(SM.mmsPath, 'core', 'sourcehook'))
compiler['CXXINCLUDES'].append(os.path.join(base, 'core', 'logic'))
compiler['CXXINCLUDES'].append(os.path.join(base, 'public'))
compiler['CXXINCLUDES'].append(os.path.join(base, 'public', 'sourcepawn'))
compiler['CDEFINES'].append('SM_DEFAULT_THREADER')
compiler['CDEFINES'].append('SM_LOGIC')
if AMBuild.target['platform'] == 'linux':
compiler['POSTLINKFLAGS'].append('-lpthread')
if AMBuild.target['platform'] == 'darwin':
compiler['POSTLINKFLAGS'].extend(['-framework', 'CoreServices'])
extension = AMBuild.AddJob('sourcemod.logic')
binary = Cpp.LibraryBuilder('sourcemod.logic', AMBuild, extension, compiler)
files = [
'common_logic.cpp',
'smn_adt_array.cpp',
'smn_sorting.cpp',
'smn_maplists.cpp',
'smn_adt_stack.cpp',
'thread/ThreadWorker.cpp',
'thread/BaseWorker.cpp',
'ThreadSupport.cpp',
'smn_float.cpp',
'TextParsers.cpp',
'smn_textparse.cpp',
'smn_adt_trie.cpp',
'Profiler.cpp',
'smn_functions.cpp',
'smn_timers.cpp',
'smn_players.cpp',
'MemoryUtils.cpp',
'smn_admin.cpp',
'smn_banning.cpp',
'stringutil.cpp',
'Translator.cpp',
'PhraseCollection.cpp',
'smn_lang.cpp',
'smn_string.cpp',
'smn_handles.cpp',
'smn_datapacks.cpp',
'smn_gameconfigs.cpp',
'GameConfigs.cpp',
'sm_crc32.cpp',
'smn_profiler.cpp'
]
if AMBuild.target['platform'] == 'windows':
files.append('thread/WinThreads.cpp')
else:
files.append('thread/PosixThreads.cpp')
binary.AddSourceFiles('core/logic', files)
SM.AutoVersion('core/logic', binary)
binary.SendToJob()
+92
View File
@@ -0,0 +1,92 @@
/**
* vim: set ts=4 sw=4 tw=99 noet :
* =============================================================================
* SourceMod
* Copyright (C) 2004-2009 AlliedModders LLC. All rights reserved.
* =============================================================================
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, version 3.0, as published by the
* Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*
* As a special exception, AlliedModders LLC gives you permission to link the
* code of this program (as well as its derivative works) to "Half-Life 2," the
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
* by the Valve Corporation. You must obey the GNU General Public License in
* all respects for all other code used. Additionally, AlliedModders LLC grants
* this exception to all derivative works. AlliedModders LLC defines further
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
* or <http://www.sourcemod.net/license.php>.
*
* Version: $Id$
*/
#ifndef _INCLUDE_SOURCEMOD_AUTO_HANDLE_ROOTER_H_
#define _INCLUDE_SOURCEMOD_AUTO_HANDLE_ROOTER_H_
#include "common_logic.h"
#include <IHandleSys.h>
class AutoHandleRooter
{
public:
AutoHandleRooter(Handle_t hndl)
{
if (hndl != BAD_HANDLE)
this->hndl = handlesys->FastCloneHandle(hndl);
else
this->hndl = BAD_HANDLE;
}
~AutoHandleRooter()
{
if (hndl != BAD_HANDLE)
{
HandleSecurity sec(g_pCoreIdent, g_pCoreIdent);
handlesys->FreeHandle(hndl, &sec);
}
}
Handle_t getHandle()
{
return hndl;
}
private:
Handle_t hndl;
};
class AutoHandleCloner
{
Handle_t original;
HandleSecurity sec;
AutoHandleRooter ahr;
public:
AutoHandleCloner(Handle_t original, HandleSecurity sec)
: original(original), sec(sec), ahr(original)
{
}
~AutoHandleCloner()
{
if (original != BAD_HANDLE)
{
handlesys->FreeHandle(original, &sec);
}
}
Handle_t getClone()
{
return ahr.getHandle();
}
};
#endif /* _INCLUDE_SOURCEMOD_AUTO_HANDLE_ROOTER_H_ */
@@ -29,6 +29,9 @@
* Version: $Id$
*/
#ifndef _INCLUDE_SOURCEMOD_CELLARRAY_H_
#define _INCLUDE_SOURCEMOD_CELLARRAY_H_
#include <stdlib.h>
#include <string.h>
@@ -204,3 +207,6 @@ private:
size_t m_AllocSize;
size_t m_Size;
};
#endif /* _INCLUDE_SOURCEMOD_CELLARRAY_H_ */
File diff suppressed because it is too large Load Diff
@@ -32,13 +32,12 @@
#ifndef _INCLUDE_SOURCEMOD_CGAMECONFIGS_H_
#define _INCLUDE_SOURCEMOD_CGAMECONFIGS_H_
#include "common_logic.h"
#include <IGameConfigs.h>
#include <ITextParsers.h>
#include <sh_list.h>
#include "sm_trie.h"
#include "sm_globals.h"
#include "sm_memtable.h"
#include "sm_trie_tpl.h"
#include <sm_trie_tpl.h>
using namespace SourceMod;
using namespace SourceHook;
@@ -55,6 +54,7 @@ public:
~CGameConfig();
public:
bool Reparse(char *error, size_t maxlength);
bool EnterFile(const char *file, char *error, size_t maxlength);
public: //ITextListener_SMC
SMCResult ReadSMC_NewSection(const SMCStates *states, const char *name);
SMCResult ReadSMC_KeyValue(const SMCStates *states, const char *key, const char *value);
@@ -64,16 +64,18 @@ public: //IGameConfig
bool GetOffset(const char *key, int *value);
SendProp *GetSendProp(const char *key);
bool GetMemSig(const char *key, void **addr);
bool GetAddress(const char *key, void **addr);
public:
void IncRefCount();
unsigned int DecRefCount();
private:
BaseStringTable *m_pStrings;
char *m_pFile;
Trie *m_pOffsets;
Trie *m_pProps;
Trie *m_pKeys;
Trie *m_pSigs;
char m_File[PLATFORM_MAX_PATH];
char m_CurFile[PLATFORM_MAX_PATH];
KTrie<int> m_Offsets;
KTrie<SendProp *> m_Props;
KTrie<int> m_Keys;
KTrie<void *> m_Sigs;
unsigned int m_RefCount;
/* Parse states */
int m_ParseState;
@@ -83,10 +85,32 @@ private:
char m_offset[64];
char m_Game[256];
bool bShouldBeReadingDefault;
bool had_game;
bool matched_game;
bool had_engine;
bool matched_engine;
/* Custom Sections */
unsigned int m_CustomLevel;
ITextListener_SMC *m_CustomHandler;
/* Support for reading Addresses */
struct AddressConf
{
char signatureName[64];
int readCount;
int read[8];
AddressConf(char *sigName, unsigned sigLength, unsigned readCount, int *read);
AddressConf() {}
};
char m_Address[64];
char m_AddressSignature[64];
int m_AddressReadCount;
int m_AddressRead[8];
KTrie<AddressConf> *m_pAddresses;
};
class GameConfigManager :
@@ -104,13 +128,15 @@ public: //IGameConfigManager
HandleError *err);
void AddUserConfigHook(const char *sectionname, ITextListener_SMC *listener);
void RemoveUserConfigHook(const char *sectionname, ITextListener_SMC *listener);
void AcquireLock();
void ReleaseLock();
public: //SMGlobalClass
void OnSourceModStartup(bool late);
void OnSourceModAllInitialized();
void OnSourceModAllShutdown();
private:
List<CGameConfig *> m_cfgs;
Trie *m_pLookup;
KTrie<CGameConfig *> m_Lookup;
public:
KTrie<ITextListener_SMC *> m_customHandlers;
};
+107
View File
@@ -0,0 +1,107 @@
# (C)2004-2008 SourceMod Development Team
# Makefile written by David "BAILOPAN" Anderson
SMSDK = ../..
MMSOURCE17 = ../../../mmsource-1.7
#####################################
### EDIT BELOW FOR OTHER PROJECTS ###
#####################################
BINARY = sourcemod.logic.so
OBJECTS = \
common_logic.cpp \
smn_adt_array.cpp \
smn_sorting.cpp \
smn_maplists.cpp \
smn_adt_stack.cpp \
thread/ThreadWorker.cpp \
thread/BaseWorker.cpp \
thread/PosixThreads.cpp \
ThreadSupport.cpp \
smn_float.cpp \
TextParsers.cpp \
smn_textparse.cpp \
smn_adt_trie.cpp \
Profiler.cpp \
smn_functions.cpp \
sm_crc32.cpp \
smn_timers.cpp \
MemoryUtils.cpp \
smn_admin.cpp \
smn_banning.cpp \
stringutil.cpp \
Translator.cpp \
PhraseCollection.cpp \
smn_lang.cpp \
smn_string.cpp \
smn_handles.cpp \
smn_datapacks.cpp \
smn_gameconfigs.cpp \
GameConfigs.cpp \
smn_players.cpp
##############################################
### CONFIGURE ANY OTHER FLAGS/OPTIONS HERE ###
##############################################
C_OPT_FLAGS = -DNDEBUG -O3 -funroll-loops -pipe -fno-strict-aliasing
C_DEBUG_FLAGS = -D_DEBUG -DDEBUG -g -ggdb3
C_GCC4_FLAGS = -fvisibility=hidden
CPP_GCC4_FLAGS = -fvisibility-inlines-hidden
CPP = gcc
LINK += -lpthread -static-libgcc
INCLUDE += -I. -I$(MMSOURCE17)/core/sourcehook -I$(SMSDK)/public -I$(SMSDK)/public/sourcepawn
CFLAGS += -D_LINUX -Dstricmp=strcasecmp -D_stricmp=strcasecmp -D_strnicmp=strncasecmp -Dstrnicmp=strncasecmp \
-D_snprintf=snprintf -D_vsnprintf=vsnprintf -D_alloca=alloca -Dstrcmpi=strcasecmp -Wall -Werror \
-Wno-uninitialized -mfpmath=sse -msse -DSOURCEMOD_BUILD -DHAVE_STDINT_H -DSM_DEFAULT_THREADER -m32 \
-DSM_LOGIC
CPPFLAGS += -Wno-non-virtual-dtor -fno-exceptions -fno-rtti
################################################
### DO NOT EDIT BELOW HERE FOR MOST PROJECTS ###
################################################
ifeq "$(DEBUG)" "true"
BIN_DIR = Debug
CFLAGS += $(C_DEBUG_FLAGS)
else
BIN_DIR = Release
CFLAGS += $(C_OPT_FLAGS)
endif
GCC_VERSION := $(shell $(CPP) -dumpversion >&1 | cut -b1)
ifeq "$(GCC_VERSION)" "4"
CFLAGS += $(C_GCC4_FLAGS)
CPPFLAGS += $(CPP_GCC4_FLAGS)
endif
OBJ_LINUX := $(OBJECTS:%.cpp=$(BIN_DIR)/%.o)
OBJ_LINUX := $(OBJ_LINUX:%.c=$(BIN_DIR)/%.o)
$(BIN_DIR)/%.o: %.cpp
$(CPP) $(INCLUDE) $(CFLAGS) $(CPPFLAGS) -o $@ -c $<
$(BIN_DIR)/%.o: %.c
$(CPP) $(INCLUDE) $(CFLAGS) -o $@ -c $<
all:
mkdir -p $(BIN_DIR)/thread
$(MAKE) -f Makefile sourcemod
sourcemod: $(OBJ_LINUX)
$(CPP) $(INCLUDE) $(OBJ_LINUX) $(LINK) -m32 -shared -ldl -lm -o $(BIN_DIR)/$(BINARY)
debug:
$(MAKE) -f Makefile all DEBUG=true
default: all
clean:
rm -rf $(BIN_DIR)/*.o
rm -rf $(BIN_DIR)/thread/*.o
rm -rf $(BIN_DIR)/$(BINARY)
+612
View File
@@ -0,0 +1,612 @@
/**
* vim: set ts=4 sw=4 tw=99 noet :
* =============================================================================
* SourceMod
* Copyright (C) 2004-2011 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 "MemoryUtils.h"
#ifdef PLATFORM_LINUX
#include <fcntl.h>
#include <link.h>
#include <sys/mman.h>
#define PAGE_SIZE 4096
#define PAGE_ALIGN_UP(x) ((x + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))
#endif
#ifdef PLATFORM_APPLE
#include <AvailabilityMacros.h>
#include <mach/task.h>
#include <mach-o/dyld_images.h>
#include <mach-o/loader.h>
#include <mach-o/nlist.h>
/* Define things from 10.6 SDK for older SDKs */
#ifndef MAC_OS_X_VERSION_10_6
struct task_dyld_info
{
mach_vm_address_t all_image_info_addr;
mach_vm_size_t all_image_info_size;
};
typedef struct task_dyld_info task_dyld_info_data_t;
#define TASK_DYLD_INFO 17
#define TASK_DYLD_INFO_COUNT (sizeof(task_dyld_info_data_t) / sizeof(natural_t))
#endif // MAC_OS_X_VERSION_10_6
#endif // PLATFORM_APPLE
MemoryUtils g_MemUtils;
MemoryUtils::MemoryUtils()
{
#ifdef PLATFORM_APPLE
Gestalt(gestaltSystemVersionMajor, &m_OSXMajor);
Gestalt(gestaltSystemVersionMinor, &m_OSXMinor);
/* Get pointer to struct that describes all loaded mach-o images in process */
if ((m_OSXMajor == 10 && m_OSXMinor >= 6) || m_OSXMajor > 10)
{
task_dyld_info_data_t dyld_info;
mach_msg_type_number_t count = TASK_DYLD_INFO_COUNT;
task_info(mach_task_self(), TASK_DYLD_INFO, (task_info_t)&dyld_info, &count);
m_ImageList = (struct dyld_all_image_infos *)dyld_info.all_image_info_addr;
}
else
{
struct nlist list[2];
memset(list, 0, sizeof(list));
list[0].n_un.n_name = (char *)"_dyld_all_image_infos";
nlist("/usr/lib/dyld", list);
m_ImageList = (struct dyld_all_image_infos *)list[0].n_value;
}
#endif
}
MemoryUtils::~MemoryUtils()
{
#if defined PLATFORM_LINUX || defined PLATFORM_APPLE
for (size_t i = 0; i < m_SymTables.size(); i++)
{
delete m_SymTables[i];
}
m_SymTables.clear();
#endif
}
void MemoryUtils::OnSourceModAllInitialized()
{
sharesys->AddInterface(NULL, this);
}
void *MemoryUtils::FindPattern(const void *libPtr, const char *pattern, size_t len)
{
DynLibInfo lib;
bool found;
char *ptr, *end;
memset(&lib, 0, sizeof(DynLibInfo));
if (!GetLibraryInfo(libPtr, lib))
{
return NULL;
}
ptr = reinterpret_cast<char *>(lib.baseAddress);
end = ptr + lib.memorySize;
while (ptr < end)
{
found = true;
for (register size_t i = 0; i < len; i++)
{
if (pattern[i] != '\x2A' && pattern[i] != ptr[i])
{
found = false;
break;
}
}
if (found)
return ptr;
ptr++;
}
return NULL;
}
void *MemoryUtils::ResolveSymbol(void *handle, const char *symbol)
{
#ifdef PLATFORM_WINDOWS
return GetProcAddress((HMODULE)handle, symbol);
#elif defined PLATFORM_LINUX
struct link_map *dlmap;
struct stat dlstat;
int dlfile;
uintptr_t map_base;
Elf32_Ehdr *file_hdr;
Elf32_Shdr *sections, *shstrtab_hdr, *symtab_hdr, *strtab_hdr;
Elf32_Sym *symtab;
const char *shstrtab, *strtab;
uint16_t section_count;
uint32_t symbol_count;
LibSymbolTable *libtable;
SymbolTable *table;
Symbol *symbol_entry;
dlmap = (struct link_map *)handle;
symtab_hdr = NULL;
strtab_hdr = NULL;
table = NULL;
/* See if we already have a symbol table for this library */
for (size_t i = 0; i < m_SymTables.size(); i++)
{
libtable = m_SymTables[i];
if (libtable->lib_base == dlmap->l_addr)
{
table = &libtable->table;
break;
}
}
/* If we don't have a symbol table for this library, then create one */
if (table == NULL)
{
libtable = new LibSymbolTable();
libtable->table.Initialize();
libtable->lib_base = dlmap->l_addr;
libtable->last_pos = 0;
table = &libtable->table;
m_SymTables.push_back(libtable);
}
/* See if the symbol is already cached in our table */
symbol_entry = table->FindSymbol(symbol, strlen(symbol));
if (symbol_entry != NULL)
{
return symbol_entry->address;
}
/* If symbol isn't in our table, then we have open the actual library */
dlfile = open(dlmap->l_name, O_RDONLY);
if (dlfile == -1 || fstat(dlfile, &dlstat) == -1)
{
close(dlfile);
return NULL;
}
/* Map library file into memory */
file_hdr = (Elf32_Ehdr *)mmap(NULL, dlstat.st_size, PROT_READ, MAP_PRIVATE, dlfile, 0);
map_base = (uintptr_t)file_hdr;
if (file_hdr == MAP_FAILED)
{
close(dlfile);
return NULL;
}
close(dlfile);
if (file_hdr->e_shoff == 0 || file_hdr->e_shstrndx == SHN_UNDEF)
{
munmap(file_hdr, dlstat.st_size);
return NULL;
}
sections = (Elf32_Shdr *)(map_base + file_hdr->e_shoff);
section_count = file_hdr->e_shnum;
/* Get ELF section header string table */
shstrtab_hdr = &sections[file_hdr->e_shstrndx];
shstrtab = (const char *)(map_base + shstrtab_hdr->sh_offset);
/* Iterate sections while looking for ELF symbol table and string table */
for (uint16_t i = 0; i < section_count; i++)
{
Elf32_Shdr &hdr = sections[i];
const char *section_name = shstrtab + hdr.sh_name;
if (strcmp(section_name, ".symtab") == 0)
{
symtab_hdr = &hdr;
}
else if (strcmp(section_name, ".strtab") == 0)
{
strtab_hdr = &hdr;
}
}
/* Uh oh, we don't have a symbol table or a string table */
if (symtab_hdr == NULL || strtab_hdr == NULL)
{
munmap(file_hdr, dlstat.st_size);
return NULL;
}
symtab = (Elf32_Sym *)(map_base + symtab_hdr->sh_offset);
strtab = (const char *)(map_base + strtab_hdr->sh_offset);
symbol_count = symtab_hdr->sh_size / symtab_hdr->sh_entsize;
/* Iterate symbol table starting from the position we were at last time */
for (uint32_t i = libtable->last_pos; i < symbol_count; i++)
{
Elf32_Sym &sym = symtab[i];
unsigned char sym_type = ELF32_ST_TYPE(sym.st_info);
const char *sym_name = strtab + sym.st_name;
Symbol *cur_sym;
/* Skip symbols that are undefined or do not refer to functions or objects */
if (sym.st_shndx == SHN_UNDEF || (sym_type != STT_FUNC && sym_type != STT_OBJECT))
{
continue;
}
/* Caching symbols as we go along */
cur_sym = table->InternSymbol(sym_name, strlen(sym_name), (void *)(dlmap->l_addr + sym.st_value));
if (strcmp(symbol, sym_name) == 0)
{
symbol_entry = cur_sym;
libtable->last_pos = ++i;
break;
}
}
munmap(file_hdr, dlstat.st_size);
return symbol_entry ? symbol_entry->address : NULL;
#elif defined PLATFORM_APPLE
uintptr_t dlbase, linkedit_addr;
uint32_t image_count;
struct mach_header *file_hdr;
struct load_command *loadcmds;
struct segment_command *linkedit_hdr;
struct symtab_command *symtab_hdr;
struct nlist *symtab;
const char *strtab;
uint32_t loadcmd_count;
uint32_t symbol_count;
LibSymbolTable *libtable;
SymbolTable *table;
Symbol *symbol_entry;
dlbase = 0;
image_count = m_ImageList->infoArrayCount;
linkedit_hdr = NULL;
symtab_hdr = NULL;
table = NULL;
/* Loop through mach-o images in process.
* We can skip index 0 since that is just the executable.
*/
for (uint32_t i = 1; i < image_count; i++)
{
const struct dyld_image_info &info = m_ImageList->infoArray[i];
/* "Load" each one until we get a matching handle */
void *h = dlopen(info.imageFilePath, RTLD_NOLOAD);
if (h == handle)
{
dlbase = (uintptr_t)info.imageLoadAddress;
dlclose(h);
break;
}
dlclose(h);
}
if (!dlbase)
{
/* Uh oh, we couldn't find a matching handle */
return NULL;
}
/* See if we already have a symbol table for this library */
for (size_t i = 0; i < m_SymTables.size(); i++)
{
libtable = m_SymTables[i];
if (libtable->lib_base == dlbase)
{
table = &libtable->table;
break;
}
}
/* If we don't have a symbol table for this library, then create one */
if (table == NULL)
{
libtable = new LibSymbolTable();
libtable->table.Initialize();
libtable->lib_base = dlbase;
libtable->last_pos = 0;
table = &libtable->table;
m_SymTables.push_back(libtable);
}
/* See if the symbol is already cached in our table */
symbol_entry = table->FindSymbol(symbol, strlen(symbol));
if (symbol_entry != NULL)
{
return symbol_entry->address;
}
/* If symbol isn't in our table, then we have to locate it in memory */
file_hdr = (struct mach_header *)dlbase;
loadcmds = (struct load_command *)(dlbase + sizeof(struct mach_header));
loadcmd_count = file_hdr->ncmds;
/* Loop through load commands until we find the ones for the symbol table */
for (uint32_t i = 0; i < loadcmd_count; i++)
{
if (loadcmds->cmd == LC_SEGMENT && !linkedit_hdr)
{
struct segment_command *seg = (struct segment_command *)loadcmds;
if (strcmp(seg->segname, "__LINKEDIT") == 0)
{
linkedit_hdr = seg;
if (symtab_hdr)
{
break;
}
}
}
else if (loadcmds->cmd == LC_SYMTAB)
{
symtab_hdr = (struct symtab_command *)loadcmds;
if (linkedit_hdr)
{
break;
}
}
/* Load commands are not of a fixed size which is why we add the size */
loadcmds = (struct load_command *)((uintptr_t)loadcmds + loadcmds->cmdsize);
}
if (!linkedit_hdr || !symtab_hdr || !symtab_hdr->symoff || !symtab_hdr->stroff)
{
/* Uh oh, no symbol table */
return NULL;
}
linkedit_addr = dlbase + linkedit_hdr->vmaddr;
symtab = (struct nlist *)(linkedit_addr + symtab_hdr->symoff - linkedit_hdr->fileoff);
strtab = (const char *)(linkedit_addr + symtab_hdr->stroff - linkedit_hdr->fileoff);
symbol_count = symtab_hdr->nsyms;
/* Iterate symbol table starting from the position we were at last time */
for (uint32_t i = libtable->last_pos; i < symbol_count; i++)
{
struct nlist &sym = symtab[i];
/* Ignore the prepended underscore on all symbols, so +1 here */
const char *sym_name = strtab + sym.n_un.n_strx + 1;
Symbol *cur_sym;
/* Skip symbols that are undefined */
if (sym.n_sect == NO_SECT)
{
continue;
}
/* Caching symbols as we go along */
cur_sym = table->InternSymbol(sym_name, strlen(sym_name), (void *)(dlbase + sym.n_value));
if (strcmp(symbol, sym_name) == 0)
{
symbol_entry = cur_sym;
libtable->last_pos = ++i;
break;
}
}
return symbol_entry ? symbol_entry->address : NULL;
#endif
}
bool MemoryUtils::GetLibraryInfo(const void *libPtr, DynLibInfo &lib)
{
uintptr_t baseAddr;
if (libPtr == NULL)
{
return false;
}
#ifdef PLATFORM_WINDOWS
MEMORY_BASIC_INFORMATION info;
IMAGE_DOS_HEADER *dos;
IMAGE_NT_HEADERS *pe;
IMAGE_FILE_HEADER *file;
IMAGE_OPTIONAL_HEADER *opt;
if (!VirtualQuery(libPtr, &info, sizeof(MEMORY_BASIC_INFORMATION)))
{
return false;
}
baseAddr = reinterpret_cast<uintptr_t>(info.AllocationBase);
/* All this is for our insane sanity checks :o */
dos = reinterpret_cast<IMAGE_DOS_HEADER *>(baseAddr);
pe = reinterpret_cast<IMAGE_NT_HEADERS *>(baseAddr + dos->e_lfanew);
file = &pe->FileHeader;
opt = &pe->OptionalHeader;
/* Check PE magic and signature */
if (dos->e_magic != IMAGE_DOS_SIGNATURE || pe->Signature != IMAGE_NT_SIGNATURE || opt->Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC)
{
return false;
}
/* Check architecture, which is 32-bit/x86 right now
* Should change this for 64-bit if Valve gets their act together
*/
if (file->Machine != IMAGE_FILE_MACHINE_I386)
{
return false;
}
/* For our purposes, this must be a dynamic library */
if ((file->Characteristics & IMAGE_FILE_DLL) == 0)
{
return false;
}
/* Finally, we can do this */
lib.memorySize = opt->SizeOfImage;
#elif defined PLATFORM_LINUX
Dl_info info;
Elf32_Ehdr *file;
Elf32_Phdr *phdr;
uint16_t phdrCount;
if (!dladdr(libPtr, &info))
{
return false;
}
if (!info.dli_fbase || !info.dli_fname)
{
return false;
}
/* This is for our insane sanity checks :o */
baseAddr = reinterpret_cast<uintptr_t>(info.dli_fbase);
file = reinterpret_cast<Elf32_Ehdr *>(baseAddr);
/* Check ELF magic */
if (memcmp(ELFMAG, file->e_ident, SELFMAG) != 0)
{
return false;
}
/* Check ELF version */
if (file->e_ident[EI_VERSION] != EV_CURRENT)
{
return false;
}
/* Check ELF architecture, which is 32-bit/x86 right now
* Should change this for 64-bit if Valve gets their act together
*/
if (file->e_ident[EI_CLASS] != ELFCLASS32 || file->e_machine != EM_386 || file->e_ident[EI_DATA] != ELFDATA2LSB)
{
return false;
}
/* For our purposes, this must be a dynamic library/shared object */
if (file->e_type != ET_DYN)
{
return false;
}
phdrCount = file->e_phnum;
phdr = reinterpret_cast<Elf32_Phdr *>(baseAddr + file->e_phoff);
for (uint16_t i = 0; i < phdrCount; i++)
{
Elf32_Phdr &hdr = phdr[i];
/* We only really care about the segment with executable code */
if (hdr.p_type == PT_LOAD && hdr.p_flags == (PF_X|PF_R))
{
/* From glibc, elf/dl-load.c:
* c->mapend = ((ph->p_vaddr + ph->p_filesz + GLRO(dl_pagesize) - 1)
* & ~(GLRO(dl_pagesize) - 1));
*
* In glibc, the segment file size is aligned up to the nearest page size and
* added to the virtual address of the segment. We just want the size here.
*/
lib.memorySize = PAGE_ALIGN_UP(hdr.p_filesz);
break;
}
}
#elif defined PLATFORM_APPLE
Dl_info info;
struct mach_header *file;
struct segment_command *seg;
uint32_t cmd_count;
if (!dladdr(libPtr, &info))
{
return false;
}
if (!info.dli_fbase || !info.dli_fname)
{
return false;
}
/* This is for our insane sanity checks :o */
baseAddr = (uintptr_t)info.dli_fbase;
file = (struct mach_header *)baseAddr;
/* Check Mach-O magic */
if (file->magic != MH_MAGIC)
{
return false;
}
/* Check architecture (32-bit/x86) */
if (file->cputype != CPU_TYPE_I386 || file->cpusubtype != CPU_SUBTYPE_I386_ALL)
{
return false;
}
/* For our purposes, this must be a dynamic library */
if (file->filetype != MH_DYLIB)
{
return false;
}
cmd_count = file->ncmds;
seg = (struct segment_command *)(baseAddr + sizeof(struct mach_header));
/* Add up memory sizes of mapped segments */
for (uint32_t i = 0; i < cmd_count; i++)
{
if (seg->cmd == LC_SEGMENT)
{
lib.memorySize += seg->vmsize;
}
seg = (struct segment_command *)((uintptr_t)seg + seg->cmdsize);
}
#endif
lib.baseAddress = reinterpret_cast<void *>(baseAddr);
return true;
}
@@ -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-2011 AlliedModders LLC. All rights reserved.
* =============================================================================
*
* This program is free software; you can redistribute it and/or modify it under
@@ -25,34 +25,64 @@
* 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_MEMORYUTILS_H_
#define _INCLUDE_SOURCEMOD_MEMORYUTILS_H_
#include "common_logic.h"
#include <IMemoryUtils.h>
#include "sm_globals.h"
#if defined PLATFORM_LINUX || defined PLATFORM_APPLE
#include <sh_vector.h>
#include "sm_symtable.h"
using namespace SourceHook;
#endif
using namespace SourceMod;
#ifdef PLATFORM_APPLE
#include <CoreServices/CoreServices.h>
#endif
struct DynLibInfo
{
void *baseAddress;
size_t memorySize;
};
#if defined PLATFORM_LINUX || defined PLATFORM_APPLE
struct LibSymbolTable
{
SymbolTable table;
uintptr_t lib_base;
uint32_t last_pos;
};
#endif
class MemoryUtils :
public IMemoryUtils,
public SMGlobalClass
{
public:
MemoryUtils();
~MemoryUtils();
public: // SMGlobalClass
void OnSourceModAllInitialized();
public: // IMemoryUtils
void *FindPattern(const void *libPtr, const char *pattern, size_t len);
private:
void *ResolveSymbol(void *handle, const char *symbol);
public:
bool GetLibraryInfo(const void *libPtr, DynLibInfo &lib);
#if defined PLATFORM_LINUX || defined PLATFORM_APPLE
private:
CVector<LibSymbolTable *> m_SymTables;
#ifdef PLATFORM_APPLE
struct dyld_all_image_infos *m_ImageList;
SInt32 m_OSXMajor;
SInt32 m_OSXMinor;
#endif
#endif
};
extern MemoryUtils g_MemUtils;
+399
View File
@@ -0,0 +1,399 @@
// MersenneTwister.h
// Mersenne Twister random number generator -- a C++ class MTRand
// Based on code by Makoto Matsumoto, Takuji Nishimura, and Shawn Cokus
// Richard J. Wagner v1.0 15 May 2003 [email protected]
// The Mersenne Twister is an algorithm for generating random numbers. It
// was designed with consideration of the flaws in various other generators.
// The period, 2^19937-1, and the order of equidistribution, 623 dimensions,
// are far greater. The generator is also fast; it avoids multiplication and
// division, and it benefits from caches and pipelines. For more information
// see the inventors' web page at http://www.math.keio.ac.jp/~matumoto/emt.html
// Reference
// M. Matsumoto and T. Nishimura, "Mersenne Twister: A 623-Dimensionally
// Equidistributed Uniform Pseudo-Random Number Generator", ACM Transactions on
// Modeling and Computer Simulation, Vol. 8, No. 1, January 1998, pp 3-30.
// Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
// Copyright (C) 2000 - 2003, Richard J. Wagner
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. The names of its contributors may not be used to endorse or promote
// products derived from this software without specific prior written
// permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// The original code included the following notice:
//
// When you use this, send an email to: [email protected]
// with an appropriate reference to your work.
//
// It would be nice to CC: [email protected] and [email protected]
// when you write.
#ifndef MERSENNETWISTER_H
#define MERSENNETWISTER_H
// Not thread safe (unless auto-initialization is avoided and each thread has
// its own MTRand object)
#include <limits.h>
#include <stdio.h>
#include <time.h>
#include <math.h>
class MTRand {
// Data
public:
typedef unsigned long uint32; // unsigned integer type, at least 32 bits
enum { N = 624 }; // length of state vector
enum { SAVE = N + 1 }; // length of array for save()
protected:
enum { M = 397 }; // period parameter
uint32 state[N]; // internal state
uint32 *pNext; // next value to get from state
int left; // number of values left before reload needed
//Methods
public:
MTRand( const uint32& oneSeed ); // initialize with a simple uint32
MTRand( uint32 *const bigSeed, uint32 const seedLength = N ); // or an array
MTRand(); // auto-initialize with /dev/urandom or time() and clock()
// Do NOT use for CRYPTOGRAPHY without securely hashing several returned
// values together, otherwise the generator state can be learned after
// reading 624 consecutive values.
// Access to 32-bit random numbers
double rand(); // real number in [0,1]
double rand( const double& n ); // real number in [0,n]
double randExc(); // real number in [0,1)
double randExc( const double& n ); // real number in [0,n)
double randDblExc(); // real number in (0,1)
double randDblExc( const double& n ); // real number in (0,n)
uint32 randInt(); // integer in [0,2^32-1]
uint32 randInt( const uint32& n ); // integer in [0,n] for n < 2^32
double operator()() { return rand(); } // same as rand()
// Access to 53-bit random numbers (capacity of IEEE double precision)
double rand53(); // real number in [0,1)
// Access to nonuniform random number distributions
double randNorm( const double& mean = 0.0, const double& variance = 0.0 );
// Re-seeding functions with same behavior as initializers
void seed( const uint32 oneSeed );
void seed( uint32 *const bigSeed, const uint32 seedLength = N );
void seed();
// Saving and loading generator state
void save( uint32* saveArray ) const; // to array of size SAVE
void load( uint32 *const loadArray ); // from such array
protected:
void initialize( const uint32 oneSeed );
void reload();
uint32 hiBit( const uint32& u ) const { return u & 0x80000000UL; }
uint32 loBit( const uint32& u ) const { return u & 0x00000001UL; }
uint32 loBits( const uint32& u ) const { return u & 0x7fffffffUL; }
uint32 mixBits( const uint32& u, const uint32& v ) const
{ return hiBit(u) | loBits(v); }
uint32 twist( const uint32& m, const uint32& s0, const uint32& s1 ) const
{ return m ^ (mixBits(s0,s1)>>1) ^ (-loBit(s1) & 0x9908b0dfUL); }
static uint32 hash( time_t t, clock_t c );
};
inline MTRand::MTRand( const uint32& oneSeed )
{ seed(oneSeed); }
inline MTRand::MTRand( uint32 *const bigSeed, const uint32 seedLength )
{ seed(bigSeed,seedLength); }
inline MTRand::MTRand()
{ seed(); }
inline double MTRand::rand()
{ return double(randInt()) * (1.0/4294967295.0); }
inline double MTRand::rand( const double& n )
{ return rand() * n; }
inline double MTRand::randExc()
{ return double(randInt()) * (1.0/4294967296.0); }
inline double MTRand::randExc( const double& n )
{ return randExc() * n; }
inline double MTRand::randDblExc()
{ return ( double(randInt()) + 0.5 ) * (1.0/4294967296.0); }
inline double MTRand::randDblExc( const double& n )
{ return randDblExc() * n; }
inline double MTRand::rand53()
{
uint32 a = randInt() >> 5, b = randInt() >> 6;
return ( a * 67108864.0 + b ) * (1.0/9007199254740992.0); // by Isaku Wada
}
inline double MTRand::randNorm( const double& mean, const double& variance )
{
// Return a real number from a normal (Gaussian) distribution with given
// mean and variance by Box-Muller method
double r = sqrt( -2.0 * log( 1.0-randDblExc()) ) * variance;
double phi = 2.0 * 3.14159265358979323846264338328 * randExc();
return mean + r * cos(phi);
}
inline MTRand::uint32 MTRand::randInt()
{
// Pull a 32-bit integer from the generator state
// Every other access function simply transforms the numbers extracted here
if( left == 0 ) reload();
--left;
register uint32 s1;
s1 = *pNext++;
s1 ^= (s1 >> 11);
s1 ^= (s1 << 7) & 0x9d2c5680UL;
s1 ^= (s1 << 15) & 0xefc60000UL;
return ( s1 ^ (s1 >> 18) );
}
inline MTRand::uint32 MTRand::randInt( const uint32& n )
{
// Find which bits are used in n
// Optimized by Magnus Jonsson ([email protected])
uint32 used = n;
used |= used >> 1;
used |= used >> 2;
used |= used >> 4;
used |= used >> 8;
used |= used >> 16;
// Draw numbers until one is found in [0,n]
uint32 i;
do
i = randInt() & used; // toss unused bits to shorten search
while( i > n );
return i;
}
inline void MTRand::seed( const uint32 oneSeed )
{
// Seed the generator with a simple uint32
initialize(oneSeed);
reload();
}
inline void MTRand::seed( uint32 *const bigSeed, const uint32 seedLength )
{
// Seed the generator with an array of uint32's
// There are 2^19937-1 possible initial states. This function allows
// all of those to be accessed by providing at least 19937 bits (with a
// default seed length of N = 624 uint32's). Any bits above the lower 32
// in each element are discarded.
// Just call seed() if you want to get array from /dev/urandom
initialize(19650218UL);
register int i = 1;
register uint32 j = 0;
register int k = ( N > seedLength ? N : seedLength );
for( ; k; --k )
{
state[i] =
state[i] ^ ( (state[i-1] ^ (state[i-1] >> 30)) * 1664525UL );
state[i] += ( bigSeed[j] & 0xffffffffUL ) + j;
state[i] &= 0xffffffffUL;
++i; ++j;
if( i >= N ) { state[0] = state[N-1]; i = 1; }
if( j >= seedLength ) j = 0;
}
for( k = N - 1; k; --k )
{
state[i] =
state[i] ^ ( (state[i-1] ^ (state[i-1] >> 30)) * 1566083941UL );
state[i] -= i;
state[i] &= 0xffffffffUL;
++i;
if( i >= N ) { state[0] = state[N-1]; i = 1; }
}
state[0] = 0x80000000UL; // MSB is 1, assuring non-zero initial array
reload();
}
inline void MTRand::seed()
{
// Seed the generator with an array from /dev/urandom if available
// Otherwise use a hash of time() and clock() values
// First try getting an array from /dev/urandom
FILE* urandom = fopen( "/dev/urandom", "rb" );
if( urandom )
{
uint32 bigSeed[N];
register uint32 *s = bigSeed;
register int i = N;
register bool success = true;
while( success && i-- )
success = fread( s++, sizeof(uint32), 1, urandom );
fclose(urandom);
if( success ) { seed( bigSeed, N ); return; }
}
// Was not successful, so use time() and clock() instead
seed( hash( time(NULL), clock() ) );
}
inline void MTRand::initialize( const uint32 seed )
{
// Initialize generator state with seed
// See Knuth TAOCP Vol 2, 3rd Ed, p.106 for multiplier.
// In previous versions, most significant bits (MSBs) of the seed affect
// only MSBs of the state array. Modified 9 Jan 2002 by Makoto Matsumoto.
register uint32 *s = state;
register uint32 *r = state;
register int i = 1;
*s++ = seed & 0xffffffffUL;
for( ; i < N; ++i )
{
*s++ = ( 1812433253UL * ( *r ^ (*r >> 30) ) + i ) & 0xffffffffUL;
r++;
}
}
inline void MTRand::reload()
{
// Generate N new values in state
// Made clearer and faster by Matthew Bellew ([email protected])
register uint32 *p = state;
register int i;
for( i = N - M; i--; ++p )
*p = twist( p[M], p[0], p[1] );
for( i = M; --i; ++p )
*p = twist( p[M-N], p[0], p[1] );
*p = twist( p[M-N], p[0], state[0] );
left = N, pNext = state;
}
inline MTRand::uint32 MTRand::hash( time_t t, clock_t c )
{
// Get a uint32 from t and c
// Better than uint32(x) in case x is floating point in [0,1]
// Based on code by Lawrence Kirby ([email protected])
static uint32 differ = 0; // guarantee time-based seeds will change
uint32 h1 = 0;
unsigned char *p = (unsigned char *) &t;
for( size_t i = 0; i < sizeof(t); ++i )
{
h1 *= UCHAR_MAX + 2U;
h1 += p[i];
}
uint32 h2 = 0;
p = (unsigned char *) &c;
for( size_t j = 0; j < sizeof(c); ++j )
{
h2 *= UCHAR_MAX + 2U;
h2 += p[j];
}
return ( h1 + differ++ ) ^ h2;
}
inline void MTRand::save( uint32* saveArray ) const
{
register uint32 *sa = saveArray;
register const uint32 *s = state;
register int i = N;
for( ; i--; *sa++ = *s++ ) {}
*sa = left;
}
inline void MTRand::load( uint32 *const loadArray )
{
register uint32 *s = state;
register uint32 *la = loadArray;
register int i = N;
for( ; i--; *s++ = *la++ ) {}
left = *la;
pNext = &state[N-left];
}
#endif // MERSENNETWISTER_H
// Change log:
//
// v0.1 - First release on 15 May 2000
// - Based on code by Makoto Matsumoto, Takuji Nishimura, and Shawn Cokus
// - Translated from C to C++
// - Made completely ANSI compliant
// - Designed convenient interface for initialization, seeding, and
// obtaining numbers in default or user-defined ranges
// - Added automatic seeding from /dev/urandom or time() and clock()
// - Provided functions for saving and loading generator state
//
// v0.2 - Fixed bug which reloaded generator one step too late
//
// v0.3 - Switched to clearer, faster reload() code from Matthew Bellew
//
// v0.4 - Removed trailing newline in saved generator format to be consistent
// with output format of built-in types
//
// v0.5 - Improved portability by replacing static const int's with enum's and
// clarifying return values in seed(); suggested by Eric Heimburg
// - Removed MAXINT constant; use 0xffffffffUL instead
//
// v0.6 - Eliminated seed overflow when uint32 is larger than 32 bits
// - Changed integer [0,n] generator to give better uniformity
//
// v0.7 - Fixed operator precedence ambiguity in reload()
// - Added access for real numbers in (0,1) and (0,n)
//
// v0.8 - Included time.h header to properly support time_t and clock_t
//
// v1.0 - Revised seeding to match 26 Jan 2002 update of Nishimura and Matsumoto
// - Allowed for seeding with arrays of any length
// - Added access for real numbers in [0,1) with 53-bit resolution
// - Added access for real numbers from normal (Gaussian) distributions
// - Increased overall speed by optimizing twist()
// - Doubled speed of integer [0,n] generation
// - Fixed out-of-range number generation on 64-bit machines
// - Improved portability by substituting literal constants for long enum's
// - Changed license from GNU LGPL to BSD
@@ -29,9 +29,9 @@
* Version: $Id$
*/
#include "common_logic.h"
#include "PhraseCollection.h"
#include "Translator.h"
#include "sm_stringutil.h"
CPhraseCollection::CPhraseCollection()
{
@@ -54,7 +54,7 @@ IPhraseFile *CPhraseCollection::AddPhraseFile(const char *filename)
char full_name[PLATFORM_MAX_PATH];
/* No compat shim here. The user should have read the doc. */
UTIL_Format(full_name, sizeof(full_name), "%s.txt", filename);
smcore.Format(full_name, sizeof(full_name), "%s.txt", filename);
fid = g_Translator.FindOrAddPhraseFile(full_name);
pFile = g_Translator.GetFileByIndex(fid);
@@ -113,7 +113,7 @@ bool CPhraseCollection::FormatString(char *buffer,
unsigned int arg;
arg = 0;
if (!gnprintf(buffer, maxlength, format, this, params, numparams, arg, pOutLength, pFailPhrase))
if (!smcore.gnprintf(buffer, maxlength, format, this, params, numparams, arg, pOutLength, pFailPhrase))
{
return false;
}
+51 -20
View File
@@ -30,13 +30,13 @@
*/
#include "Profiler.h"
#include "PluginSys.h"
#include "sm_stringutil.h"
#include "Logger.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;
@@ -314,43 +314,74 @@ void ProfileEngine::Clear()
void ProfileEngine::OnSourceModAllInitialized()
{
g_RootMenu.AddRootConsoleCommand("profiler", "Profiler commands", this);
rootmenu->AddRootConsoleCommand2("profiler", "Profiler commands", this);
}
void ProfileEngine::OnSourceModShutdown()
{
g_RootMenu.RemoveRootConsoleCommand("profiler", this);
rootmenu->RemoveRootConsoleCommand("profiler", this);
}
void ProfileEngine::OnRootConsoleCommand(const char *cmdname, const CCommand &command)
void ProfileEngine::OnRootConsoleCommand2(const char *cmdname, const ICommandArgs *command)
{
if (command.ArgC() >= 3)
if (command->ArgC() >= 3)
{
if (strcmp(command.Arg(2), "flush") == 0)
if (strcmp(command->Arg(2), "flush") == 0)
{
FILE *fp;
char path[256];
g_SourceMod.BuildPath(Path_SM, path, sizeof(path), "logs/profile_%d.xml", (int)time(NULL));
g_pSM->BuildPath(Path_SM, path, sizeof(path), "logs/profile_%d.xml", (int)time(NULL));
if ((fp = fopen(path, "wt")) == NULL)
{
g_RootMenu.ConsolePrint("Failed, could not open file for writing: %s", path);
rootmenu->ConsolePrint("Failed, could not open file for writing: %s", path);
return;
}
GenerateReport(fp);
fclose(fp);
Clear();
g_RootMenu.ConsolePrint("Profiler report generated as: %s\n", path);
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;
}
}
g_RootMenu.ConsolePrint("Profiler commands:");
g_RootMenu.DrawGenericOption("flush", "Flushes statistics to disk and starts over");
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)
@@ -388,8 +419,8 @@ void ProfileEngine::WriteReport(FILE *fp, ProfileReport *report, const char *nam
ar = report->GetReport(i);
strncopy(new_name, ar->atom_name, sizeof(new_name));
UTIL_ReplaceAll(new_name, sizeof(new_name), "<", "&lt;");
UTIL_ReplaceAll(new_name, sizeof(new_name), ">", "&gt;");
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,
@@ -438,20 +469,20 @@ void ProfileReport::SaveAtom(const prof_atom_t &atom)
if (atom.atom_type == SP_PROF_NATIVES)
{
strncopy(full_name, atom.name, sizeof(full_name));
smcore.strncopy(full_name, atom.name, sizeof(full_name));
}
else
{
CPlugin *pl;
IPlugin *pl;
const char *file;
file = "unknown";
if ((pl = g_PluginSys.GetPluginByCtx(atom.ctx)) != NULL)
if ((pl = pluginsys->FindPluginByContext(atom.ctx)) != NULL)
{
file = pl->GetFilename();
}
UTIL_Format(full_name, sizeof(full_name), "%s!%s", file, atom.name);
smcore.Format(full_name, sizeof(full_name), "%s!%s", file, atom.name);
}
atom_time = CalcAtomTime(atom);
@@ -460,7 +491,7 @@ void ProfileReport::SaveAtom(const prof_atom_t &atom)
{
report = new prof_atom_report_t;
strncopy(report->atom_name, full_name, sizeof(report->atom_name));
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;
+4 -4
View File
@@ -38,8 +38,8 @@
#include <sh_vector.h>
#include <sh_stack.h>
#include <stdio.h>
#include "sm_globals.h"
#include "sm_srvcmds.h"
#include "common_logic.h"
#include <IRootConsoleMenu.h>
using namespace SourcePawn;
using namespace SourceHook;
@@ -103,7 +103,7 @@ public: //SMGlobalClass
void OnSourceModAllInitialized();
void OnSourceModShutdown();
public: //IRootConsoleCommand
void OnRootConsoleCommand(const char *cmdname, const CCommand &command);
void OnRootConsoleCommand2(const char *cmdname, const ICommandArgs *command);
public: //IProfiler
void OnNativeBegin(IPluginContext *pContext, sp_native_t *native);
void OnNativeEnd() ;
@@ -126,6 +126,6 @@ private:
prof_point_t m_ProfStart;
};
extern ProfileEngine g_Profiler;
extern IProfiler *sm_profiler;
#endif //_INCLUDE_SOURCEMOD_PLUGIN_PROFILER_H_
File diff suppressed because it is too large Load Diff
@@ -33,7 +33,7 @@
#define _INCLUDE_SOURCEMOD_TEXTPARSERS_H_
#include <ITextParsers.h>
#include "sm_globals.h"
#include "common_logic.h"
using namespace SourceMod;
@@ -70,14 +70,18 @@ public:
char *buffer,
size_t maxsize);
SMCError ParseSMCStream(const char *stream,
size_t length,
ITextListener_SMC *smc_listener,
SMCStates *states,
char *buffer,
size_t maxsize);
unsigned int GetUTF8CharBytes(const char *stream);
const char *GetSMCErrorString(SMCError err);
bool IsWhitespace(const char *stream);
private:
SMCError ParseString_SMC(const char *stream,
ITextListener_SMC *smc,
SMCStates *states);
SMCError ParseStream_SMC(void *stream,
STREAMREADER srdr,
ITextListener_SMC *smc,
@@ -1,8 +1,8 @@
/**
* vim: set ts=4 :
* vim: set ts=4 sw=4 :
* =============================================================================
* SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
* Copyright (C) 2004-2009 AlliedModders LLC. All rights reserved.
* =============================================================================
*
* This program is free software; you can redistribute it and/or modify it under
@@ -28,10 +28,9 @@
*
* Version: $Id$
*/
#include <sm_platform.h>
#include "ThreadSupport.h"
#include "sm_globals.h"
#include "ShareSys.h"
#include "common_logic.h"
#if defined PLATFORM_POSIX
#include "thread/PosixThreads.h"
@@ -47,6 +46,7 @@ class RegThreadStuff : public SMGlobalClass
public:
void OnSourceModAllInitialized()
{
g_ShareSys.AddInterface(NULL, g_pThreader);
sharesys->AddInterface(NULL, g_pThreader);
}
} s_RegThreadStuff;
+110 -107
View File
@@ -29,22 +29,24 @@
* Version: $Id$
*/
#include "common_logic.h"
#include <stdarg.h>
#include <stdlib.h>
#include <ctype.h>
#include <sm_platform.h>
#include "Translator.h"
#include "Logger.h"
#include "LibrarySys.h"
#include "sm_stringutil.h"
#include "sourcemod.h"
#include "PlayerManager.h"
#include <IPlayerHelpers.h>
#include <ISourceMod.h>
#include <ILibrarySys.h>
#include "PhraseCollection.h"
#include "ShareSys.h"
#include "stringutil.h"
Translator g_Translator;
IPhraseCollection *g_pCorePhrases = NULL;
unsigned int g_pCorePhraseID = 0;
using namespace SourceMod;
struct trans_t
{
int stridx;
@@ -67,15 +69,10 @@ CPhraseFile::CPhraseFile(Translator *pTranslator, const char *file)
m_LangCount = pTranslator->GetLanguageCount();
m_File.assign(file);
m_pTranslator = pTranslator;
m_pPhraseLookup = NULL;
}
CPhraseFile::~CPhraseFile()
{
if (m_pPhraseLookup)
{
sm_trie_destroy(m_pPhraseLookup);
}
}
void CPhraseFile::ParseError(const char *message, ...)
@@ -99,20 +96,16 @@ void CPhraseFile::ParseWarning(const char *message, ...)
if (!m_FileLogged)
{
g_Logger.LogError("[SM] Warning(s) encountered in translation file \"%s\"", m_File.c_str());
smcore.LogError("[SM] Warning(s) encountered in translation file \"%s\"", m_File.c_str());
m_FileLogged = true;
}
g_Logger.LogError("[SM] %s", buffer);
smcore.LogError("[SM] %s", buffer);
}
void CPhraseFile::ReparseFile()
{
if (m_pPhraseLookup)
{
sm_trie_destroy(m_pPhraseLookup);
}
m_pPhraseLookup = sm_trie_create();
m_PhraseLookup.clear();
m_LangCount = m_pTranslator->GetLanguageCount();
@@ -123,19 +116,19 @@ void CPhraseFile::ReparseFile()
SMCError err;
char path[PLATFORM_MAX_PATH];
g_SourceMod.BuildPath(Path_SM, path, PLATFORM_MAX_PATH, "translations/%s", m_File.c_str());
g_pSM->BuildPath(Path_SM, path, PLATFORM_MAX_PATH, "translations/%s", m_File.c_str());
//backwards compatibility shim
/* :HACKHACK: Change .cfg/.txt and vice versa for compatibility */
if (!g_LibSys.PathExists(path))
if (!libsys->PathExists(path))
{
if (m_File.compare("common.cfg") == 0)
{
UTIL_ReplaceAll(path, sizeof(path), "common.cfg", "common.phrases.txt");
UTIL_ReplaceAll(path, sizeof(path), "common.cfg", "common.phrases.txt", true);
} else if (strstr(path, ".cfg")) {
UTIL_ReplaceAll(path, sizeof(path), ".cfg", ".txt");
UTIL_ReplaceAll(path, sizeof(path), ".cfg", ".txt", true);
} else if (strstr(path, ".txt")) {
UTIL_ReplaceAll(path, sizeof(path), ".txt", ".cfg");
UTIL_ReplaceAll(path, sizeof(path), ".txt", ".cfg", true);
}
}
@@ -149,8 +142,8 @@ void CPhraseFile::ReparseFile()
msg = m_ParseError.c_str();
}
g_Logger.LogError("[SM] Fatal error encountered parsing translation file \"%s\"", m_File.c_str());
g_Logger.LogError("[SM] Error (line %d, column %d): %s", states.line, states.col, msg);
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);
}
const char *code;
@@ -161,7 +154,7 @@ void CPhraseFile::ReparseFile()
continue;
}
g_SourceMod.BuildPath(Path_SM,
g_pSM->BuildPath(Path_SM,
path,
PLATFORM_MAX_PATH,
"translations/%s/%s",
@@ -169,7 +162,7 @@ void CPhraseFile::ReparseFile()
m_File.c_str());
/* Speculatively load these. */
if (!g_LibSys.PathExists(path))
if (!libsys->PathExists(path))
{
continue;
}
@@ -182,10 +175,10 @@ void CPhraseFile::ReparseFile()
msg = m_ParseError.c_str();
}
g_Logger.LogError("[SM] Fatal error encountered parsing translation file \"%s/%s\"",
smcore.LogError("[SM] Fatal error encountered parsing translation file \"%s/%s\"",
code,
m_File.c_str());
g_Logger.LogError("[SM] Error (line %d, column %d): %s",
smcore.LogError("[SM] Error (line %d, column %d): %s",
states.line,
states.col,
msg);
@@ -217,17 +210,17 @@ SMCResult CPhraseFile::ReadSMC_NewSection(const SMCStates *states, const char *n
m_ParseState = PPS_InPhrase;
recognized = true;
void *value;
if (sm_trie_retrieve(m_pPhraseLookup, name, &value))
int *pvalue;
if ((pvalue = m_PhraseLookup.retrieve(name)) != NULL)
{
m_CurPhrase = reinterpret_cast<int>(value);
m_CurPhrase = *pvalue;
}
else
{
phrase_t *pPhrase;
m_CurPhrase = m_pMemory->CreateMem(sizeof(phrase_t), (void **)&pPhrase);
sm_trie_insert(m_pPhraseLookup, name, reinterpret_cast<void *>(m_CurPhrase));
m_PhraseLookup.insert(name, m_CurPhrase);
/* Initialize new phrase */
trans_t *pTrans;
@@ -639,9 +632,7 @@ SMCResult CPhraseFile::ReadSMC_LeavingSection(const SMCStates *states)
if (m_ParseState == PPS_InPhrase)
{
if (m_CurPhrase == -1 && m_LastPhraseString.size())
{
sm_trie_delete(m_pPhraseLookup, m_LastPhraseString.c_str());
}
m_PhraseLookup.remove(m_LastPhraseString.c_str());
m_CurPhrase = -1;
m_ParseState = PPS_Phrases;
m_LastPhraseString.assign("");
@@ -658,9 +649,7 @@ void CPhraseFile::ReadSMC_ParseEnd(bool halted, bool failed)
{
/* Check to see if we have any dangling phrases that weren't completed, and scrap them */
if ((halted || failed) && m_LastPhraseString.size())
{
sm_trie_delete(m_pPhraseLookup, m_LastPhraseString.c_str());
}
m_PhraseLookup.remove(m_LastPhraseString.c_str());
}
TransError CPhraseFile::GetTranslation(const char *szPhrase, unsigned int lang_id, Translation *pTrans)
@@ -670,13 +659,11 @@ TransError CPhraseFile::GetTranslation(const char *szPhrase, unsigned int lang_i
return Trans_BadLanguage;
}
void *object;
if (!sm_trie_retrieve(m_pPhraseLookup, szPhrase, &object))
{
int *pvalue;
if ((pvalue = m_PhraseLookup.retrieve(szPhrase)) == NULL)
return Trans_BadPhrase;
}
phrase_t *pPhrase = (phrase_t *)m_pMemory->GetAddress(reinterpret_cast<int>(object));
phrase_t *pPhrase = (phrase_t *)m_pMemory->GetAddress(*pvalue);
trans_t *trans = (trans_t *)m_pMemory->GetAddress(pPhrase->trans_tbl);
trans = &trans[lang_id];
@@ -705,7 +692,6 @@ const char *CPhraseFile::GetFilename()
Translator::Translator() : m_ServerLang(SOURCEMOD_LANGUAGE_ENGLISH)
{
m_pStringTab = new BaseStringTable(2048);
m_pLCodeLookup = sm_trie_create();
strncopy(m_InitialLang, "en", sizeof(m_InitialLang));
}
@@ -721,8 +707,6 @@ Translator::~Translator()
delete m_Languages[i];
}
sm_trie_destroy(m_pLCodeLookup);
delete m_pStringTab;
}
@@ -739,13 +723,13 @@ ConfigResult Translator::OnSourceModConfigChanged(const char *key,
unsigned int index;
if (!GetLanguageByCode(value, &index))
{
UTIL_Format(error, maxlength, "Language code \"%s\" is not registered", value);
smcore.Format(error, maxlength, "Language code \"%s\" is not registered", value);
return ConfigResult_Reject;
}
m_ServerLang = index;
} else {
strncopy(m_InitialLang, value, sizeof(m_InitialLang));
smcore.strncopy(m_InitialLang, value, sizeof(m_InitialLang));
}
return ConfigResult_Accept;
@@ -758,7 +742,7 @@ void Translator::OnSourceModLevelChange(const char *mapName)
{
/* Refresh language stuff */
char path[PLATFORM_MAX_PATH];
g_SourceMod.BuildPath(Path_SM, path, sizeof(path), "configs/languages.cfg");
g_pSM->BuildPath(Path_SM, path, sizeof(path), "configs/languages.cfg");
RebuildLanguageDatabase(path);
}
@@ -766,10 +750,16 @@ void Translator::OnSourceModAllInitialized()
{
AddLanguage("en", "English");
const char* lang = smcore.GetCoreConfigValue("ServerLang");
if (lang)
{
strncpy(m_InitialLang, lang, sizeof(m_InitialLang));
}
g_pCorePhrases = CreatePhraseCollection();
g_pCorePhrases->AddPhraseFile("core.phrases");
g_ShareSys.AddInterface(NULL, this);
sharesys->AddInterface(NULL, this);
}
void Translator::OnSourceModShutdown()
@@ -779,43 +769,38 @@ void Translator::OnSourceModShutdown()
bool Translator::GetLanguageByCode(const char *code, unsigned int *index)
{
void *_index;
unsigned int *pindex;
if (!sm_trie_retrieve(m_pLCodeLookup, code, &_index))
{
if ((pindex = m_LCodeLookup.retrieve(code)) == NULL)
return false;
}
if (index)
{
*index = reinterpret_cast<unsigned int>(_index);
}
*index = *pindex;
return true;
}
bool Translator::GetLanguageByName(const char *name, unsigned int *index)
{
CVector<Language *>::iterator iter;
unsigned int id = 0;
for (iter=m_Languages.begin(); iter!=m_Languages.end(); iter++, id++)
char lower[256];
size_t len = strlen(name);
if (len > 255) len = 255;
for (size_t i = 0; i < len; i++)
{
if (strcasecmp(m_pStringTab->GetString((*iter)->m_FullName), name) == 0)
{
break;
}
if (name[i] >= 'A' && name[i] <= 'Z')
lower[i] = tolower(name[i]);
else
lower[i] = name[i];
}
lower[len] = '\0';
if (iter == m_Languages.end())
{
unsigned int *pIndex;
if ((pIndex = m_LAliases.retrieve(lower)) == NULL)
return false;
}
if (index)
{
*index = id;
}
*index = *pIndex;
return true;
}
@@ -853,8 +838,8 @@ unsigned int Translator::FindOrAddPhraseFile(const char *phrase_file)
void Translator::RebuildLanguageDatabase(const char *lang_header_file)
{
/* Erase everything we have */
sm_trie_destroy(m_pLCodeLookup);
m_pLCodeLookup = sm_trie_create();
m_LCodeLookup.clear();
m_LAliases.clear();
m_pStringTab->Reset();
for (size_t i=0; i<m_Languages.size(); i++)
@@ -874,25 +859,27 @@ void Translator::RebuildLanguageDatabase(const char *lang_header_file)
str_err = m_CustomError.c_str();
}
g_Logger.LogError("[SM] Failed to parse language header file: \"%s\"", lang_header_file);
g_Logger.LogError("[SM] Parse error (line %d, column %d): %s", states.line, states.col, str_err);
smcore.LogError("[SM] Failed to parse language header file: \"%s\"", lang_header_file);
smcore.LogError("[SM] Parse error (line %d, column %d): %s", states.line, states.col, str_err);
}
void *serverLang;
unsigned int *pServerLang;
if (!sm_trie_retrieve(m_pLCodeLookup, m_InitialLang, &serverLang))
if ((pServerLang = m_LCodeLookup.retrieve(m_InitialLang)) == NULL)
{
g_Logger.LogError("Server language was set to bad language \"%s\" -- reverting to English", m_InitialLang);
smcore.LogError("Server language was set to bad language \"%s\" -- reverting to English", m_InitialLang);
strncopy(m_InitialLang, "en", sizeof(m_InitialLang));
smcore.strncopy(m_InitialLang, "en", sizeof(m_InitialLang));
m_ServerLang = SOURCEMOD_LANGUAGE_ENGLISH;
}
m_ServerLang = reinterpret_cast<unsigned int>(serverLang);
else
{
m_ServerLang = *pServerLang;
}
if (!m_Languages.size())
{
g_Logger.LogError("[SM] Fatal error, no languages found! Translation will not work.");
smcore.LogError("[SM] Fatal error, no languages found! Translation will not work.");
}
for (size_t i=0; i<m_Files.size(); i++)
@@ -919,7 +906,7 @@ SMCResult Translator::ReadSMC_NewSection(const SMCStates *states, const char *na
if (!m_InLanguageSection)
{
g_Logger.LogError("[SM] Warning: Unrecognized section \"%s\" in languages.cfg", name);
smcore.LogError("[SM] Warning: Unrecognized section \"%s\" in languages.cfg", name);
}
return SMCResult_Continue;
@@ -938,8 +925,8 @@ SMCResult Translator::ReadSMC_KeyValue(const SMCStates *states, const char *key,
if (len < 2 || len > 3)
{
g_Logger.LogError("[SM] Warning encountered parsing languages.cfg file.");
g_Logger.LogError("[SM] Invalid language code \"%s\" is being ignored.", key);
smcore.LogError("[SM] Warning encountered parsing languages.cfg file.");
smcore.LogError("[SM] Invalid language code \"%s\" is being ignored.", key);
}
AddLanguage(key, value);
@@ -949,20 +936,40 @@ SMCResult Translator::ReadSMC_KeyValue(const SMCStates *states, const char *key,
bool Translator::AddLanguage(const char *langcode, const char *description)
{
if (sm_trie_retrieve(m_pLCodeLookup, langcode, NULL))
char lower[256];
size_t len = strlen(description);
if (len > 255) len = 255;
for (size_t i = 0; i < len; i++)
{
return false;
if (description[i] >= 'A' && description[i] <= 'Z')
lower[i] = tolower(description[i]);
else
lower[i] = description[i];
}
lower[len] = '\0';
Language *pLanguage = new Language;
unsigned int idx = m_Languages.size();
if (m_LAliases.retrieve(lower))
return false;
UTIL_Format(pLanguage->m_code2, sizeof(pLanguage->m_code2), "%s", langcode);
pLanguage->m_FullName = m_pStringTab->AddString(description);
unsigned int idx;
if (unsigned int *pIdx = m_LCodeLookup.retrieve(langcode))
{
idx = *pIdx;
}
else
{
Language *pLanguage = new Language;
idx = m_Languages.size();
sm_trie_insert(m_pLCodeLookup, langcode, reinterpret_cast<void *>(idx));
smcore.Format(pLanguage->m_code2, sizeof(pLanguage->m_code2), "%s", langcode);
pLanguage->m_CanonicalName = m_pStringTab->AddString(lower);
m_Languages.push_back(pLanguage);
m_LCodeLookup.insert(langcode, idx);
m_Languages.push_back(pLanguage);
}
m_LAliases.insert(lower, idx);
return true;
}
@@ -984,7 +991,7 @@ unsigned int Translator::GetServerLanguage()
unsigned int Translator::GetClientLanguage(int client)
{
CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
IGamePlayer *pPlayer = playerhelpers->GetGamePlayer(client);
return pPlayer->GetLanguageId();
}
@@ -1002,7 +1009,7 @@ bool Translator::GetLanguageInfo(unsigned int number, const char **code, const c
}
if (name)
{
*name = m_pStringTab->GetString(l->m_FullName);
*name = m_pStringTab->GetString(l->m_CanonicalName);
}
return true;
@@ -1025,20 +1032,16 @@ IPhraseCollection *Translator::CreatePhraseCollection()
int Translator::SetGlobalTarget(int index)
{
return g_SourceMod.SetGlobalTarget(index);
return g_pSM->SetGlobalTarget(index);
}
int Translator::GetGlobalTarget() const
{
return g_SourceMod.GetGlobalTarget();
return g_pSM->GetGlobalTarget();
}
bool CoreTranslate(char *buffer,
size_t maxlength,
const char *format,
unsigned int numparams,
size_t *pOutLength,
...)
bool CoreTranslate(char *buffer, size_t maxlength, const char *format, unsigned int numparams,
size_t *pOutLength, ...)
{
va_list ap;
unsigned int i;
@@ -1068,11 +1071,11 @@ bool CoreTranslate(char *buffer,
{
if (fail_phrase != NULL)
{
g_Logger.LogError("[SM] Could not find core phrase: %s", fail_phrase);
smcore.LogError("[SM] Could not find core phrase: %s", fail_phrase);
}
else
{
g_Logger.LogError("[SM] Unknown fatal error while translating a core phrase.");
smcore.LogError("[SM] Unknown fatal error while translating a core phrase.");
}
return false;
@@ -1093,7 +1096,7 @@ bool Translator::FormatString(char *buffer,
unsigned int arg;
arg = 0;
if (!gnprintf(buffer, maxlength, format, pPhrases, params, numparams, arg, pOutLength, pFailPhrase))
if (!smcore.gnprintf(buffer, maxlength, format, pPhrases, params, numparams, arg, pOutLength, pFailPhrase))
{
return false;
}
@@ -32,17 +32,14 @@
#ifndef _INCLUDE_SOURCEMOD_TRANSLATOR_H_
#define _INCLUDE_SOURCEMOD_TRANSLATOR_H_
#include "sm_trie.h"
#include "common_logic.h"
#include <sm_trie_tpl.h>
#include <sh_string.h>
#include <sh_vector.h>
#include "sm_globals.h"
#include "sm_memtable.h"
#include "ITextParsers.h"
#include <ITranslator.h>
#define MAX_TRANSLATE_PARAMS 32
#define CORELANG_ENGLISH 0
/* :TODO: write a templatized version of tries? */
using namespace SourceHook;
@@ -58,7 +55,7 @@ enum PhraseParseState
struct Language
{
char m_code2[4];
int m_FullName;
int m_CanonicalName;
};
class CPhraseFile :
@@ -82,7 +79,7 @@ private:
void ParseError(const char *message, ...);
void ParseWarning(const char *message, ...);
private:
Trie *m_pPhraseLookup;
KTrie<int> m_PhraseLookup;
String m_File;
Translator *m_pTranslator;
PhraseParseState m_ParseState;
@@ -155,7 +152,8 @@ private:
CVector<Language *> m_Languages;
CVector<CPhraseFile *> m_Files;
BaseStringTable *m_pStringTab;
Trie *m_pLCodeLookup;
KTrie<unsigned int> m_LCodeLookup;
KTrie<unsigned int> m_LAliases;
bool m_InLanguageSection;
String m_CustomError;
unsigned int m_ServerLang;
@@ -175,3 +173,4 @@ extern unsigned int g_pCorePhraseID;
extern Translator g_Translator;
#endif //_INCLUDE_SOURCEMOD_TRANSLATOR_H_
+157
View File
@@ -0,0 +1,157 @@
/**
* vim: set ts=4 sw=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 <new>
#include <stdlib.h>
#include <sm_platform.h>
#include <string.h>
#include "common_logic.h"
#include "TextParsers.h"
#include "Profiler.h"
#include "sm_crc32.h"
#include "MemoryUtils.h"
#include "stringutil.h"
#include "ThreadSupport.h"
#include "Translator.h"
#include "GameConfigs.h"
sm_core_t smcore;
IHandleSys *handlesys;
IdentityToken_t *g_pCoreIdent;
SMGlobalClass *SMGlobalClass::head = NULL;
ISourceMod *g_pSM;
ILibrarySys *libsys;
ITextParsers *textparser = &g_TextParser;
IVEngineServer *engine;
IShareSys *sharesys;
IRootConsole *rootmenu;
IPluginManager *pluginsys;
IForwardManager *forwardsys;
ITimerSystem *timersys;
ServerGlobals serverGlobals;
IPlayerManager *playerhelpers;
IAdminSystem *adminsys;
IGameHelpers *gamehelpers;
static void AddCorePhraseFile(const char *filename)
{
g_pCorePhrases->AddPhraseFile("antiflood.phrases");
}
static IGameConfig *GetCoreGameConfig()
{
return g_pGameConf;
}
static sm_logic_t logic =
{
NULL,
g_pThreader,
sm_profiler,
&g_Translator,
stristr,
CoreTranslate,
AddCorePhraseFile,
UTIL_ReplaceAll,
UTIL_ReplaceEx,
UTIL_DecodeHexString,
GetCoreGameConfig
};
static void logic_init(const sm_core_t* core, sm_logic_t* _logic)
{
logic.head = SMGlobalClass::head;
memcpy(&smcore, core, sizeof(sm_core_t));
memcpy(_logic, &logic, sizeof(sm_logic_t));
memcpy(&serverGlobals, core->serverGlobals, sizeof(ServerGlobals));
handlesys = core->handlesys;
libsys = core->libsys;
engine = core->engine;
g_pCoreIdent = core->core_ident;
g_pSM = core->sm;
sharesys = core->sharesys;
rootmenu = core->rootmenu;
pluginsys = core->pluginsys;
forwardsys = core->forwardsys;
timersys = core->timersys;
playerhelpers = core->playerhelpers;
adminsys = core->adminsys;
gamehelpers = core->gamehelpers;
}
PLATFORM_EXTERN_C ITextParsers *get_textparsers()
{
return &g_TextParser;
}
PLATFORM_EXTERN_C LogicInitFunction logic_load(uint32_t magic)
{
if (magic != SM_LOGIC_MAGIC)
{
return NULL;
}
return logic_init;
}
void CoreNativesToAdd::OnSourceModAllInitialized()
{
smcore.AddNatives(m_NativeList);
}
/* Overload a few things to prevent libstdc++ linking */
#if defined __linux__ || defined __APPLE__
extern "C" void __cxa_pure_virtual(void)
{
}
void *operator new(size_t size)
{
return malloc(size);
}
void *operator new[](size_t size)
{
return malloc(size);
}
void operator delete(void *ptr)
{
free(ptr);
}
void operator delete[](void * ptr)
{
free(ptr);
}
#endif
+57
View File
@@ -0,0 +1,57 @@
/**
* vim: set ts=4 :
* =============================================================================
* SourceMod
* Copyright (C) 2004-2009 AlliedModders LLC. All rights reserved.
* =============================================================================
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, version 3.0, as published by the
* Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*
* As a special exception, AlliedModders LLC gives you permission to link the
* code of this program (as well as its derivative works) to "Half-Life 2," the
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
* by the Valve Corporation. You must obey the GNU General Public License in
* all respects for all other code used. Additionally, AlliedModders LLC grants
* this exception to all derivative works. AlliedModders LLC defines further
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
* or <http://www.sourcemod.net/license.php>.
*
* Version: $Id$
*/
#ifndef _INCLUDE_SOURCEMOD_COMMON_LOGIC_H_
#define _INCLUDE_SOURCEMOD_COMMON_LOGIC_H_
#include <IHandleSys.h>
#include "../sm_globals.h"
#include "intercom.h"
extern sm_core_t smcore;
extern IHandleSys *handlesys;
extern ISourceMod *g_pSM;
extern ILibrarySys *libsys;
extern ITextParsers *textparser;
extern IVEngineServer *engine;
extern IShareSys *sharesys;
extern IRootConsole *rootmenu;
extern IPluginManager *pluginsys;
extern IForwardManager *forwardsys;
extern ITimerSystem *timersys;
extern ServerGlobals serverGlobals;
extern IPlayerManager *playerhelpers;
extern IAdminSystem *adminsys;
extern IGameHelpers *gamehelpers;
#endif /* _INCLUDE_SOURCEMOD_COMMON_LOGIC_H_ */
+146
View File
@@ -0,0 +1,146 @@
/**
* vim: set ts=4 :
* =============================================================================
* SourceMod
* Copyright (C) 2004-2009 AlliedModders LLC. All rights reserved.
* =============================================================================
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, version 3.0, as published by the
* Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*
* As a special exception, AlliedModders LLC gives you permission to link the
* code of this program (as well as its derivative works) to "Half-Life 2," the
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
* by the Valve Corporation. You must obey the GNU General Public License in
* all respects for all other code used. Additionally, AlliedModders LLC grants
* this exception to all derivative works. AlliedModders LLC defines further
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
* or <http://www.sourcemod.net/license.php>.
*
* Version: $Id$
*/
#include <sp_vm_api.h>
#include <IHandleSys.h>
#include <IShareSys.h>
#ifndef _INCLUDE_SOURCEMOD_INTERCOM_H_
#define _INCLUDE_SOURCEMOD_INTERCOM_H_
using namespace SourceMod;
/**
* Add 1 to the RHS of this expression to bump the intercom file
* This is to prevent mismatching core/logic binaries
*/
#define SM_LOGIC_MAGIC (0x0F47C0DE - 17)
#if defined SM_LOGIC
class IVEngineServer
#else
class IVEngineServer_Logic
#endif
{
public:
virtual bool IsMapValid(const char *map) = 0;
virtual void ServerCommand(const char *cmd) = 0;
};
namespace SourceMod
{
class ISourceMod;
class ILibrarySys;
class ITextParsers;
class IThreader;
class IRootConsole;
class IPluginManager;
class IForwardManager;
class ITimerSystem;
class IPlayerManager;
class IAdminSystem;
class IGameHelpers;
class IPhraseCollection;
class ITranslator;
class IGameConfig;
}
class IVEngineServer;
class ConVar;
struct ServerGlobals
{
const double *universalTime;
float *interval_per_tick;
float *frametime;
};
struct sm_core_t
{
/* Objects */
IHandleSys *handlesys;
IdentityToken_t *core_ident;
ISourceMod *sm;
ILibrarySys *libsys;
IVEngineServer *engine;
IShareSys *sharesys;
IRootConsole *rootmenu;
IPluginManager *pluginsys;
IForwardManager *forwardsys;
ITimerSystem *timersys;
IPlayerManager *playerhelpers;
IAdminSystem *adminsys;
IGameHelpers *gamehelpers;
/* Functions */
void (*AddNatives)(sp_nativeinfo_t* nlist);
ConVar * (*FindConVar)(const char*);
unsigned int (*strncopy)(char*, const char*, size_t);
char * (*TrimWhitespace)(char *, size_t &);
void (*LogError)(const char*, ...);
const char * (*GetCvarString)(ConVar*);
size_t (*Format)(char*, size_t, const char*, ...);
void (*GenerateError)(IPluginContext *, cell_t, int, const char *, ...);
bool (*gnprintf)(char *, size_t, const char *, IPhraseCollection *, void **,
unsigned int, unsigned int &, size_t *, const char **);
size_t (*atcprintf)(char *, size_t, const char *, IPluginContext *, const cell_t *, int *);
bool (*GetGameName)(char *buffer, size_t maxlength);
const char * (*GetGameDescription)();
const char * (*GetSourceEngineName)();
bool (*SymbolsAreHidden)();
const char * (*GetCoreConfigValue)(const char*);
/* Data */
ServerGlobals *serverGlobals;
void * serverFactory;
void * engineFactory;
void * matchmakingDSFactory;
};
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 *, ...);
void (*AddCorePhraseFile)(const char *filename);
unsigned int (*ReplaceAll)(char*, size_t, const char *, const char *, bool);
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)();
};
typedef void (*LogicInitFunction)(const sm_core_t *core, sm_logic_t *logic);
typedef LogicInitFunction (*LogicLoadFunction)(uint32_t magic);
typedef ITextParsers *(*GetITextParsers)();
#endif /* _INCLUDE_SOURCEMOD_INTERCOM_H_ */
+19
View File
@@ -0,0 +1,19 @@
Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "logic", "logic.vcxproj", "{6EF06E6E-0ED5-4E2D-A8F3-01DD1EC25BA7}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{6EF06E6E-0ED5-4E2D-A8F3-01DD1EC25BA7}.Debug|Win32.ActiveCfg = Debug|Win32
{6EF06E6E-0ED5-4E2D-A8F3-01DD1EC25BA7}.Debug|Win32.Build.0 = Debug|Win32
{6EF06E6E-0ED5-4E2D-A8F3-01DD1EC25BA7}.Release|Win32.ActiveCfg = Release|Win32
{6EF06E6E-0ED5-4E2D-A8F3-01DD1EC25BA7}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
+159
View File
@@ -0,0 +1,159 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{6EF06E6E-0ED5-4E2D-A8F3-01DD1EC25BA7}</ProjectGuid>
<RootNamespace>jitx86</RootNamespace>
<Keyword>Win32Proj</Keyword>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..;$(MMSOURCE18)\core\sourcehook;..\..\..\public;..\..\..\public\sourcepawn;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;JITX86_EXPORTS;_CRT_SECURE_NO_DEPRECATE;SM_DEFAULT_THREADER;SM_LOGIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
</ClCompile>
<Link>
<OutputFile>$(OutDir)sourcemod.logic.dll</OutputFile>
<IgnoreSpecificDefaultLibraries>LIBC;LIBCD;LIBCMT;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<DataExecutionPrevention>
</DataExecutionPrevention>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<AdditionalIncludeDirectories>..;$(MMSOURCE17)\core\sourcehook;..\..\..\public;..\..\..\public\sourcepawn;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;JITX86_EXPORTS;_CRT_SECURE_NO_DEPRECATE;SM_LOGIC;SM_DEFAULT_THREADER;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<EnableEnhancedInstructionSet>NotSet</EnableEnhancedInstructionSet>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<OutputFile>$(OutDir)sourcemod.logic.dll</OutputFile>
<IgnoreSpecificDefaultLibraries>LIBC;LIBCD;LIBCMTD;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<DataExecutionPrevention>
</DataExecutionPrevention>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\common_logic.cpp" />
<ClCompile Include="..\GameConfigs.cpp" />
<ClCompile Include="..\MemoryUtils.cpp" />
<ClCompile Include="..\PhraseCollection.cpp" />
<ClCompile Include="..\Profiler.cpp" />
<ClCompile Include="..\sm_crc32.cpp" />
<ClCompile Include="..\smn_admin.cpp" />
<ClCompile Include="..\smn_adt_array.cpp" />
<ClCompile Include="..\smn_adt_stack.cpp" />
<ClCompile Include="..\smn_adt_trie.cpp" />
<ClCompile Include="..\smn_banning.cpp" />
<ClCompile Include="..\smn_datapacks.cpp" />
<ClCompile Include="..\smn_float.cpp" />
<ClCompile Include="..\smn_functions.cpp" />
<ClCompile Include="..\smn_gameconfigs.cpp" />
<ClCompile Include="..\smn_handles.cpp" />
<ClCompile Include="..\smn_lang.cpp" />
<ClCompile Include="..\smn_maplists.cpp" />
<ClCompile Include="..\smn_players.cpp" />
<ClCompile Include="..\smn_sorting.cpp" />
<ClCompile Include="..\smn_string.cpp" />
<ClCompile Include="..\smn_textparse.cpp" />
<ClCompile Include="..\smn_timers.cpp" />
<ClCompile Include="..\stringutil.cpp" />
<ClCompile Include="..\TextParsers.cpp" />
<ClCompile Include="..\ThreadSupport.cpp" />
<ClCompile Include="..\Translator.cpp" />
<ClCompile Include="..\thread\BaseWorker.cpp" />
<ClCompile Include="..\thread\ThreadWorker.cpp" />
<ClCompile Include="..\thread\WinThreads.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\AutoHandleRooter.h" />
<ClInclude Include="..\CellArray.h" />
<ClInclude Include="..\common_logic.h" />
<ClInclude Include="..\GameConfigs.h" />
<ClInclude Include="..\intercom.h" />
<ClInclude Include="..\MemoryUtils.h" />
<ClInclude Include="..\MersenneTwister.h" />
<ClInclude Include="..\PhraseCollection.h" />
<ClInclude Include="..\Profiler.h" />
<ClInclude Include="..\sm_crc32.h" />
<ClInclude Include="..\sm_memtable.h" />
<ClInclude Include="..\sm_symtable.h" />
<ClInclude Include="..\stringutil.h" />
<ClInclude Include="..\svn_version.h" />
<ClInclude Include="..\TextParsers.h" />
<ClInclude Include="..\ThreadSupport.h" />
<ClInclude Include="..\thread\BaseWorker.h" />
<ClInclude Include="..\thread\ThreadWorker.h" />
<ClInclude Include="..\thread\WinThreads.h" />
<ClInclude Include="..\Translator.h" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\version.rc" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
+188
View File
@@ -0,0 +1,188 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions>
</Filter>
<Filter Include="Threads">
<UniqueIdentifier>{67c1ebce-c1f8-4d2c-9ef4-33f0ef6343e9}</UniqueIdentifier>
</Filter>
<Filter Include="Threads\Header Files">
<UniqueIdentifier>{c6e2ebb3-4869-4453-9b83-e49f70cb8a05}</UniqueIdentifier>
</Filter>
<Filter Include="Threads\Source Files">
<UniqueIdentifier>{e6d8a9af-1c1b-4f0c-ae06-a9ebd5cd32e4}</UniqueIdentifier>
</Filter>
<Filter Include="Natives">
<UniqueIdentifier>{126462f2-e517-4854-8a94-759e56787536}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\common_logic.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\GameConfigs.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\MemoryUtils.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\PhraseCollection.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\Profiler.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\sm_crc32.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\stringutil.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\TextParsers.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\ThreadSupport.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\Translator.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\thread\BaseWorker.cpp">
<Filter>Threads\Source Files</Filter>
</ClCompile>
<ClCompile Include="..\thread\ThreadWorker.cpp">
<Filter>Threads\Source Files</Filter>
</ClCompile>
<ClCompile Include="..\thread\WinThreads.cpp">
<Filter>Threads\Source Files</Filter>
</ClCompile>
<ClCompile Include="..\smn_admin.cpp">
<Filter>Natives</Filter>
</ClCompile>
<ClCompile Include="..\smn_timers.cpp">
<Filter>Natives</Filter>
</ClCompile>
<ClCompile Include="..\smn_adt_array.cpp">
<Filter>Natives</Filter>
</ClCompile>
<ClCompile Include="..\smn_adt_stack.cpp">
<Filter>Natives</Filter>
</ClCompile>
<ClCompile Include="..\smn_adt_trie.cpp">
<Filter>Natives</Filter>
</ClCompile>
<ClCompile Include="..\smn_banning.cpp">
<Filter>Natives</Filter>
</ClCompile>
<ClCompile Include="..\smn_datapacks.cpp">
<Filter>Natives</Filter>
</ClCompile>
<ClCompile Include="..\smn_float.cpp">
<Filter>Natives</Filter>
</ClCompile>
<ClCompile Include="..\smn_functions.cpp">
<Filter>Natives</Filter>
</ClCompile>
<ClCompile Include="..\smn_gameconfigs.cpp">
<Filter>Natives</Filter>
</ClCompile>
<ClCompile Include="..\smn_handles.cpp">
<Filter>Natives</Filter>
</ClCompile>
<ClCompile Include="..\smn_lang.cpp">
<Filter>Natives</Filter>
</ClCompile>
<ClCompile Include="..\smn_maplists.cpp">
<Filter>Natives</Filter>
</ClCompile>
<ClCompile Include="..\smn_players.cpp">
<Filter>Natives</Filter>
</ClCompile>
<ClCompile Include="..\smn_sorting.cpp">
<Filter>Natives</Filter>
</ClCompile>
<ClCompile Include="..\smn_string.cpp">
<Filter>Natives</Filter>
</ClCompile>
<ClCompile Include="..\smn_textparse.cpp">
<Filter>Natives</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\CellArray.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\common_logic.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\intercom.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\Profiler.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\svn_version.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\TextParsers.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\ThreadSupport.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\thread\BaseWorker.h">
<Filter>Threads\Header Files</Filter>
</ClInclude>
<ClInclude Include="..\thread\ThreadWorker.h">
<Filter>Threads\Header Files</Filter>
</ClInclude>
<ClInclude Include="..\thread\WinThreads.h">
<Filter>Threads\Header Files</Filter>
</ClInclude>
<ClInclude Include="..\AutoHandleRooter.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\GameConfigs.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\MemoryUtils.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\MersenneTwister.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\PhraseCollection.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\sm_crc32.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\sm_memtable.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\sm_symtable.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\stringutil.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\Translator.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\version.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
</Project>
+20
View File
@@ -0,0 +1,20 @@
Microsoft Visual Studio Solution File, Format Version 10.00
# Visual Studio 2008
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "logic", "logic.vcproj", "{6EF06E6E-0ED5-4E2D-A8F3-01DD1EC25BA7}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{6EF06E6E-0ED5-4E2D-A8F3-01DD1EC25BA7}.Debug|Win32.ActiveCfg = Debug|Win32
{6EF06E6E-0ED5-4E2D-A8F3-01DD1EC25BA7}.Debug|Win32.Build.0 = Debug|Win32
{6EF06E6E-0ED5-4E2D-A8F3-01DD1EC25BA7}.Release|Win32.ActiveCfg = Release|Win32
{6EF06E6E-0ED5-4E2D-A8F3-01DD1EC25BA7}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

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