Compare commits

..
Author SHA1 Message Date
BotoX f8f48e6219 Add CapabilityProvider for MultiTargetFilter client param 2019-09-10 11:22:05 +02:00
BotoX b68e032cc2 Added client id to MultiTargetFilter forward. 2019-09-10 11:22:05 +02:00
BotoX d93f6984cc cstrike: Fix wrong timeleft calculation (#1072)
* Fix wrong timeleft calculation

* reorder function calls
2019-09-02 15:33:28 -07:00
42 207584818f Add RequestFrameCallback optional data param (#1068) 2019-09-02 14:00:22 -07:00
Asher Baker 7a42d6b564 Fix build with latest hl2sdk-csgo 2019-09-02 21:45:04 +01:00
David Anderson 94b3ca08a2 Update SourcePawn & amtl submodules (#1067) 2019-09-01 13:24:39 -07:00
RumbleFrog ab5f00b65b Correct FrameIterator retval regression (#1066) 2019-08-26 19:26:51 -07:00
JoinedSenses b8fd7db58d Create menu if multiple nom matches found (#983)
This change checks the nomination against the map arraylist. If the nomination matches multiple results, those results are then added to a menu to allow the client to select available maps. The maps added to the menu go against the same checks as the normal nomination menu and wont allow nomination of disabled maps.

Example image of /nominate jump_b
https://i.imgur.com/ZdzB0gk.png

If reply source is console, menus wont be generated and it will attempt to nominate as normal.
2019-08-01 13:48:10 +01:00
hydrogen-mvm 22635d8d35 Add File.Flush methodmap (#1056)
This allows us to do FileHandle.Flush() instead of FlushFile(FileHandle) and maintain consistency in always using methodmaps for file I/O operations.
2019-07-31 22:18:07 +00:00
hydrogen-mvm fb9b284bcf Correct malformed Regex documentation (#1055) 2019-07-31 10:48:46 -07:00
David Anderson 5868ffd04e Merge pull request #1050 from alliedmodders/update-sp-093edef
Update SourcePawn to 093edef
2019-07-24 09:38:43 -07:00
Asher Baker 8ce99e0540 Link pthread library for Linux binaries 2019-07-24 14:47:13 +01:00
Asher Baker efb02755bc Update SourcePawn to 093edef 2019-07-24 13:51:15 +01:00
Asher Baker fcafd0784c Workaround CS:GO Stringtable bug (#1046)
The cause of the infamous "Index error writing string table baseline"
error appears to be a timing issue between the engine's network message
processing, the stringtable encoding, and command processing when adding
stringtable entries in OnConfigsExecuted.

When the first client connects the map is re-loaded which causes a full
refresh, the game's stringtable entries are added at tick 65, the client
connection is registered at tick 66, and stringtable entries added in
OnConfigsExecuted are registered as being added in tick 67. The engine
later calls WriteBaselines with the client's signon tick, and neglects
to encode the SM added entries as it considers them from the future.

To avoid this, always pass INT_MAX as the current tick when encoding
the baseline, so all stringtable entries are included regardless of when
they were added. Tested on both Windows and Linux.
2019-07-19 09:13:34 +01:00
42 199802150b Update TF2_IgnitePlayer to support setting duration of fire (#1038)
Related to #713
2019-07-05 22:37:25 +01:00
MartLegion e47c1a840a Pad plugin ID based on the total plugin count (#1027)
Closes #994
2019-06-17 01:06:03 +01:00
Nicholas Hastings 14227c04b8 Fix matchmaking_ds bin not being found for gamedata (#1006). (#1028) 2019-06-01 14:30:22 -04:00
Batfoxkid cf0a49881e TFCond Descriptions (#1005)
This is mainly for API (https://sm.alliedmods.net/new-api/tf2/TFCond) to show description of the condition.
2019-06-01 15:43:06 +01:00
JoinedSenses 527a998740 Fix whitespace regression from #1012 (#1026) 2019-05-30 20:11:43 -07:00
JoinedSenses 352f078b07 Add Cookie methodmap (#1012) 2019-05-30 18:27:14 -07:00
JoinedSenses 4f3c3175e6 Create GlobalForward & PrivateForward methodmaps (#1004) 2019-05-29 14:17:42 -07:00
JoinedSenses 81dc80fbd1 Correct Plugin API Documentation Formatting (#1019) 2019-05-28 18:38:58 -07:00
Headline 28036966a6 Fix Miscellaneous Regressions and UBs (#1022) 2019-05-28 18:04:08 -07:00
Headline 2164f5191e Fix GCC 9 Builds (#1024) 2019-05-28 17:57:40 -07:00
Asher Baker 216ba8b4e9 Create FUNDING.yml 2019-05-27 17:15:04 +01:00
Bara 9c55eed549 Add Shield and Bumpmine to cstrike.inc (#991) 2019-05-24 06:03:42 -07:00
Amine B f9ce25a7fe PassType typo fixup (#1018)
* PassType typo fixup

Just some little observations, I will look up for more in other files whenever I can

* Update natives.cpp

* Update outputnatives.cpp
2019-05-15 07:22:34 -04:00
Nicholas Hastings 7e418933e7 Re-add missing GetEconItemView param (fixes #1001). (#1017) 2019-05-14 20:55:44 -04:00
Nicholas Hastings 05b3fc0fb9 Re-add float cast on TF2_AddCondition param (fixes #1013). (#1016)
Broken by ArgScuffer
2019-05-14 19:22:43 -04:00
Bruno Ronning d7990596f9 Update CS:GO "Reload" offset. (#1011) 2019-05-14 18:56:14 -04:00
Kyle Sanderson 86f974f242 NPOTB: Enable cstrike builds w/ Travis-CI. (#1014)
Travis-CI seems to have finally improved their environment so we should be okay to test this unique code-path now with CI.
2019-05-14 11:38:20 -07:00
Loïc 6addc5c8dd Fix wrong formatting to "Vote Delay Minutes" when delay above 60s (#1009)
Fixes #1007
2019-05-13 00:20:47 +01:00
David Anderson 15a7faeafd Merge pull request #1008 from alliedmodders/update-sp
Update SourcePawn to 4cba235.
2019-05-11 14:13:28 -07:00
David Anderson 626963fc49 Update SourcePawn to 4cba235. 2019-05-11 13:53:09 -07:00
JoinedSenses 2e72fc115d Fix malformed documentation indentation in Array.FindValue (#1002)
Modified indention for uniformity
2019-05-09 16:56:17 -07:00
JoinedSenses 26462f2848 Add Sort and SortCustom to ArrayList methodmap (#1003) 2019-05-09 18:44:31 +01:00
Michael Flaherty 9cd2a74271 Fix ArgBuffer String Serialization (#999) 2019-05-04 01:46:55 -07:00
iNilo e1648ba8f9 Add missing semicolon to profiler.inc (#996) 2019-05-03 02:11:03 -07:00
Michael Flaherty dae6d13f06 Fix CSS Builds (#992) 2019-05-01 17:29:55 -04:00
PerfectLaugh ccf1d7abbd Remove unneeded paramter in CS_DropWeapon (#988)
Updated in 4/30/2019 csgo update
2019-05-01 11:38:02 -04:00
Nick Hastings b92381505a Update Linux CSWeaponDropBB signature. 2019-05-01 11:35:13 -04:00
Nicholas Hastings 5ba6b1426b Revert "Update CS:GO CSWeaponDrop Signature (#985)" (#990)
This reverts commit fc7453a6c7.
2019-05-01 11:31:26 -04:00
Anthony fc7453a6c7 Update CS:GO CSWeaponDrop Signature (#985) 2019-04-30 23:36:39 -07:00
404UNF ae00144e84 Add new custom kill identifier for TF2 (#972) 2019-04-22 22:53:31 +01:00
Playa 59baaf1123 Fix param order in CancelClientMenu documentation (#982) 2019-04-22 20:33:27 +01:00
Michael Flaherty e2eac382c0 Add templated helper class to promote type-safety (#965) 2019-04-12 12:10:37 -07:00
Michael Flaherty dd81d7c78f Incorperate Licensing Into Project Tree (#961) 2019-04-12 12:10:13 -07:00
peace-maker e3f4d239f1 IBinTools: Block loading incompatible interface versions (#979)
In #705 SourceMod received support for x64 binaries. The `IBinTools` interface was updated to call functions in 64bit binaries. The `PassInfo` struct's size was increased and the `Create(V)Call()` functions signatures changed, thus making the interface incompatible for consumers which were compiled against an earlier version.

`SMInterface::IsVersionCompatible` wasn't adjusted to that fact, so extensions compiled against pre SM 1.10 could request an `IBinTools` interface pointer, but crash when they try to use it.

This change makes requests to older interface versions invalid, thus letting `RequestInterface` return `NULL` for older extensions. It doesn't fix the backwards incompatibility, but at least makes the problem more blatant, so extensions can handle it themselves.
2019-04-11 14:51:38 -07:00
⭐ B3none 8f0527487f SQL-Admin-Manager: style clean-up (#974)
* Switched to sizeof instead of hard-coding for loop size

* Switched back to pre-increment.

* Dynamically pad variables
2019-04-06 11:47:21 -07:00
Nicholas Hastings 318b36cdcf Trigger build for hl2sdk-csgo update. 2019-03-28 20:00:20 -04:00
TheRandomLabs f4b9dfb2e7 Fix misspelling of "runoff" in mapchooser (#973) 2019-03-23 18:21:54 -07:00
David Anderson 2e11d3400e Fix MSVC2015 build. 2019-03-16 17:25:36 -07:00
David Anderson 364cd094d9 Trigger a build. 2019-03-16 16:57:22 -07:00
David Anderson 2af7600057 Switch to MSVC2015 builders. 2019-03-16 16:21:57 -07:00
komashchenko 8031e42bda pb: Add natives to work with 64 bit values (#943)
* Add natives to work with 64 bit Protobuf values

* Fix linux build

* FIX alignment requirements

* FIX alignment requirements V2

* Remove legacy API

* Inattention
2019-03-04 09:06:43 -08:00
Ҝờţأķ 7f9ceaac06 basevotes: Fix buffer size for workshop obtained levels. (#956) 2019-03-03 15:00:24 -08:00
David Anderson ae0a03d438 Merge pull request #964 from Bara/patch-5
Add missing semicolon
2019-02-19 21:49:07 -08:00
Bara d105ce778d Add missing semicolon
Otherwise you'll get this error:
regex.inc(182) : error 001: expected token: ";", but found "<newline>"

[Example with latest sourcemod (1.10.6383) version](https://travis-ci.org/Bara/TroubleinTerroristTown/jobs/495529570#L640)
2019-02-19 17:21:17 +01:00
David Anderson 653e9325fc Merge pull request #963 from alliedmodders/update-sp
Update SourcePawn.
2019-02-18 12:53:21 -08:00
David Anderson 5d7d7c122e Update SourcePawn. 2019-02-17 21:21:43 -08:00
Ross Bemrose 45fb26d282 Change MultiTargetFilter to a typeset that allows ArrayList as its second argument. (#955) 2019-02-03 13:27:26 -08:00
Asher Baker c501c837d0 Ignore SM site certificate when downloading GeoIP
Build servers don't have a root for it, and the address is internal
2019-01-19 12:34:23 +00:00
Asher Baker 590f71436f Get GeoIP data from SM site for now 2019-01-19 12:18:36 +00:00
Michael Flaherty b7e252dfd6 Prevent FrameIterator OOB Errors (#949) 2019-01-13 13:36:35 -08:00
Nicholas Hastings a2246af121 Unify map lookup logic across tf2esque engines. (fixes #927) (#931) 2019-01-07 18:17:28 -05:00
Bara 3e454db2d8 Add snowball to CSWeaponID (#936) 2019-01-05 14:56:07 -05:00
OkyHp b88e0d7875 Add getter for Event.BroadcastDisabled (#946)
In a pre-hook, the hook param is not reliable if multiple plugins have hooked the same event.
2019-01-03 19:42:42 +00:00
Nick Hastings 821251b176 Fix BfRead.BytesLeft not being able to be optional. (fixes #945). 2019-01-01 15:34:26 -05:00
Deathreus 1b3599c189 Bump non-critical versioning to 1.10 (#939) 2018-12-27 21:02:14 -05:00
Nicholas Hastings 5e7596dea6 Upgrade SQLite from v3.22.0 to v3.26.0. (#935) 2018-12-19 17:26:29 -05:00
David Anderson ab7519530e Merge pull request #934 from alliedmodders/enum-structs
Inauguration of SourcePawn enum structs
2018-12-16 22:43:43 -08:00
David Anderson faa10f52a8 Move dynamicmenu.sp enum structs to transitional syntax. 2018-12-16 18:49:36 -08:00
David Anderson 53df09fbb7 Fix dynamicmenu.sp indentation. 2018-12-16 18:41:55 -08:00
Michael Flaherty c8f3035cb0 Introduce enum structs to core sm plugins 2018-12-15 13:51:03 -08:00
David Anderson f465985370 Update SourcePawn and AMTL to master.
This brings in enum struct support.
2018-12-15 12:17:11 -08:00
David Anderson 470486ba7e Don't double-format in ReplyToCommand. (#932) 2018-12-12 23:30:27 -08:00
Nick Hastings 9a4fe1c475 Fix signed/unsigned compare on Windows. 2018-12-12 20:02:23 -05:00
Ruben Gonzalez dd61223c0b Add new CSGO weapon id's/itemdefs. (#929) 2018-12-12 11:35:36 -08:00
Nick Hastings c196082988 Typo fix for CS:GO POSIX Extinguish gamedata. 2018-12-08 09:05:10 -05:00
Nick Hastings 9e58476631 Update CS:GO contribution score offset. 2018-12-07 07:24:30 -05:00
Nick Hastings 4bebdc18a2 Hmm... 2018-12-06 20:31:29 -05:00
Nick Hastings a01529b210 Add new GiveNamedItem param for CS:GO. 2018-12-06 20:18:21 -05:00
Nick Hastings 0b35c84bf0 Update CS:GO SDKTools and SDKHooks offsets. 2018-12-06 19:23:32 -05:00
Ruben Gonzalez 846a99e57f Merge branch 'master' of github.com:alliedmodders/sourcemod 2018-12-06 18:49:15 -05:00
Ruben Gonzalez c28f957fb3 Update csgo gamedata part 1 2018-12-06 18:47:44 -05:00
peace-maker f0aec6b0b6 Fix typo in fallback to "default" maplists section (#923)
When lookup of a more specialized entry in the maplists.cfg failed, it wouldn't fallback to the "default" section, but just try to parse the same section again.
2018-11-13 16:32:18 +00:00
Ruben Gonzalez d79c5e0dfa Switch CS:GO Clantag set/get to use netprops + offset over sig + offset. (#922)
* Switch CS:GO Clantag set/get to use netprops + offset over sig+offset.

* Make sure the new functions are defined before using them...

* Fix offset name

* Fix incorrectly dereferencing.
2018-11-09 07:13:17 -05:00
Kyle Sanderson cb8d92edeb SDKHooks: Reset global hookid when unhooking in SH. (#916)
Fixes https://github.com/alliedmodders/sourcemod/issues/912
2018-10-28 11:06:57 -07:00
Asher Baker db9925493a Update game.empires.txt 2018-10-14 13:06:30 +01:00
peace-maker 1b795a70b0 Add GameData methodmap (#766) 2018-10-11 20:27:56 -07:00
Kruzya ccfd2ffe38 Added sm_reload_databases (#773)
Added command sm_reload_databases for refreshing "registered" Databases Configurations cache.

Closes #772
2018-10-11 17:36:52 +01:00
Asher Baker c1d235a59c Use natural sorting for map lists (Fixes #892) (#907)
This produces consistently better results, especially for games such as L4D(2).
2018-10-11 15:20:10 +01:00
Asher Baker b5320a4f8a Add a note about FormatTime platform dependence (#908)
This has been another constant source of confusion since the C99 ones were added to the strftime documentation we link.

It'd be nice to have a consistent implementation inside SM in the future.
2018-10-11 11:07:07 +01:00
Asher Baker a1271ec3a8 Handle NULLs in SDKCall string return (Fixes #874) (#906)
`SDKCall` has existing semantics that a `-1` retval indicates null, so use that and writes an empty string to the buffer.

Consumers can tell the difference between `""` and `NULL` by checking if the return value is `0` or `-1`.
2018-10-11 00:18:03 +01:00
Asher Baker a659896f8a Revert "Use natural sorting for map lists (Fixes #892)"
This reverts commit a4e169aa8f.
2018-10-11 00:04:46 +01:00
Asher Baker a4e169aa8f Use natural sorting for map lists (Fixes #892) 2018-10-11 00:03:34 +01:00
Asher Baker 7dd733cf46 Improve CreateNative failure message (#903)
This confuses everyone.
2018-10-10 13:35:17 +01:00
Ruben Gonzalez 6eb319f46e Update CS:GO gamedata. (#904) 2018-10-09 20:18:53 -04:00
SlidyBat 3add38f665 Add additional TraceRay natives (#885)
* More TR natives

* Fix small typo

* Fix another typo

* Fix TR_AllSolid description

* Change Disp to Displacement

* Reorder params in TR_GetSurfaceName

* Fix TR_GetSurfaceName

* Another fix for TR_GetSurfaceName -_-

* Change if block to switch

* Make handle first param in TR_GetSurfaceName

* Reorder TR_GetStartPosition params

* Make TranslatePartitionFlags static

* Change tabs used for formatting to spaces

* Change inline comment style to be consistent with rest of file
2018-10-07 14:15:54 -07:00
Michael Flaherty 34e91fbd81 Restore SQL_CheckConfig Behavior (#873)
* Change lookup strategy for SQL_CheckConfig

* Ensure db conf lookup failures default to ..default

* Revert "Ensure db conf lookup failures default to ..default"

This reverts commit 03dc703daeeeadaa134e2160bf2c7cd812402758.
2018-10-07 14:08:11 -07:00
Michael Flaherty a9ca1a2fd6 NPOTB: Clarify preprocessor logic (#900) 2018-10-05 04:22:29 -07:00
Michael Flaherty a21c7564c1 [NMRiH] Gamedata update (Fixes #898) (#899) 2018-10-05 07:09:19 -04:00
Asher Baker 1ca4517f46 Revert "Remove arch loops from build scripts. (#889)"
This reverts commit 7ed329c11f.
2018-10-04 17:59:40 +00:00
Michael Flaherty 22b43e3869 Fix regression in vstk size (#894)
* Fix regression in vstk size

* Fix macro comment mistake

* More macro comment removals
2018-10-04 08:08:29 -04:00
Michael Flaherty fc14e37d0f Fix CS_TerminateRound calls & detour (#893) 2018-10-03 22:50:31 -04:00
David Anderson 7ed329c11f Remove arch loops from build scripts. (#889)
This simplifies non-sdk build scripts by removing their loops over SM.archs. Instead the top-level
build script will re-evaluate them for each architecture.
2018-09-30 09:59:28 -07:00
Michael Flaherty 6ad6abd319 Update sourcepawn submodule 2018-09-29 21:12:40 -07:00
SlidyBat bece74491d NPOTB: Update sample extension params to be sourcehook-friendly (#886) 2018-09-22 21:55:05 -07:00
Michael Flaherty 990a02dbe0 Fix grammar error in File docs (#883) 2018-09-22 12:27:05 -07:00
Ruben Gonzalez 75193e9ee9 Add new weapons to CSWeaponID enum. (#869) 2018-09-12 10:13:39 -04:00
JoinedSenses a5b22498ce Update to sm_ban, sm_kick, & sm_map in chat with no args to display menu (#838)
This change makes it so /kick, /ban, and /map open the already created methods for displaying their menus when there are no args.

The reason for the feature is to take advantage of menus that already exist and to make the commands easier to use.

The client == 0 check prevents them from opening if it was ran via rcon, sm_rcon, or server command. Client auth is also checked because its a registered admin command.

Usage params will display if client == 0 and args < min

For example, a moderator wants to change a map, instead of running through the admin menu, they can instead type just /map to display available maps and choose one.

If a mod wants to quickly ban or kick someone without having to either run through the admin menu or type it out, they could then type the corresponding commands with no args to open the menus.
2018-09-04 00:41:22 +01:00
Maxim Telezhenko 398522712e Add missing MarkNativeAsOptional for SetAuthIdCookie native (#879) 2018-09-01 00:19:48 +01:00
Asher Baker caf0914289 Remove MAPLIST_FLAG_NO_DEFAULT misuses (#870)
These two base plugins are using the MAPLIST_FLAG_NO_DEFAULT when they shouldn't, which causes much user (and SM developer) confusion as it is completely counter to the documentation.
2018-08-19 12:41:53 +01:00
Michael Flaherty 17700e45b0 Fix SetClanTag CS:GO Windows Signature (#868) 2018-08-15 17:56:04 -07:00
Asher Baker ba8b42ef1b Burninate IDataPack (#864)
This doesn't break any extensions NOT using IDataPack, and we do not know of any that are.

* The extension storage utility of this interface has been broken for the last 9 months, with ISourceMod::CreateDataPack being disabled.
* The plugin interop utility of this interface (its stated purpose) has been broken for the last 11+ years, with ISourceMod::GetDataPackHandleType being disabled.

I imagine it only survived the first cleanup 11 years ago because CSS:DM was using it internally, which it has now been migrated away from.

Compiled all the included extensions without changes (API compat), and loaded extensions build pre-change without issue (ABI compat).
2018-08-13 23:03:48 +01:00
SlidyBat 144fb907f1 Add new Traceray natives (#754) 2018-08-13 23:02:12 +01:00
Asher Baker e7c6b23439 Update blacklist.plugins.txt 2018-08-12 22:32:59 +01:00
Michael Flaherty a65c215217 Fix DataPack Overwrite Regression (#862)
Some tests passed with the implementation prior to this commit, but those were edge cases. Good older behavior is now fully restored
2018-08-11 13:31:33 +01:00
peace-maker 7e3b1c395b Mark new methodmap natives as optional (#867)
The `TopMenu` methodmap natives weren't marked as optional if the extension was optional like the other normal natives.

The `Regex` natives weren't marked as optional at all before if the regex extension was included optionally.

This makes the error message cleaner in case topmenus aren't loaded.
```
adminmenu.smx (Admin Menu): Required extension "TopMenus" file("topmenus.ext") not running
basebans.smx (Basic Ban Commands): Native "TopMenu.Display" was not found
```
2018-08-06 20:11:01 +01:00
Nick Hastings 3511d2a44d Trigger build against hl2sdk-tf2 update. 2018-08-02 17:29:09 -04:00
ddhoward beaf812909 Deprecate FormatUserLogText (#856)
Allow client index 0, too. (Console)
2018-07-31 19:19:18 -07:00
Michael Flaherty 7068c3e865 Fix LogStackTrace Anomaly (#863) 2018-07-31 04:17:36 -07:00
Kyle Sanderson 255b9323cc Flip sm_debug_connect to "1" (#860) 2018-07-27 22:02:31 -07:00
hydrogen-mvm d14c94c353 Add missing return value documentation (#854) 2018-07-26 18:33:22 -07:00
Michael Flaherty 11abe77eed Allow any returns in native callbacks (#857) 2018-07-25 21:46:44 -07:00
hydrogen-mvm 7d8dfb09d8 Fix English style in CONTRIBUTING.md (#855) 2018-07-21 23:17:35 -06:00
Kyle Sanderson 3baa703256 NPOTB: Fix clang-3.9 failures with Travis-CI (#851)
fix clang-3.9 failures, maybe; hopefully. I forget why this was broken.
2018-07-17 13:07:55 -07:00
Kyle Sanderson 2b3159f418 NPOTB: Add Discord and IRC Server to README.md 2018-07-17 10:43:23 -07:00
Kyle Sanderson 72acca4b9e Fix DataPack memory leak regression from #848. (#850)
* Fix memory leak regression from https://github.com/alliedmodders/sourcemod/pull/848.
2018-07-16 08:34:49 -07:00
Michael Flaherty 32d12ea4a6 Preserve old DataPack behavior when overwriting data (#848)
* Match old DataPack behavior when overwriting data

* Make RemoveItem more flexible

* Ditch implied RemoveItem behavior & asher fixes

* KyleS nits - but fixed before he says them

* Add back implicit behavior

* Update CDataPack.cpp

Committing to the spec.

* Update CDataPack.h

* fixup removing last item if explicitly requested

* Fix logic for accepting pack pos, rather than index

* Fixup IsReadable

* headache is over now
2018-07-14 17:00:17 -07:00
Ruben Gonzalez e4862dade8 Update CS:GO mac64/linux64 gamedata. 2018-07-13 19:44:40 -04:00
Ruben Gonzalez ed908b6545 Fix CS:GO weaponPrice offset. 2018-07-13 07:47:53 -04:00
KliPPy a81b52a787 Add move semantics for StringHashMap (#589)
* Move semantics for StringHashMap

* style

* Update sm_stringhashmap.h
2018-07-12 11:25:22 -07:00
komashchenko 52cdbb4fc1 Fix sm_help erroring out if invoked during the connection process (#723)
* Fix "Exception reported: Client 12 is not in game"

* Fix

* Update adminhelp.sp
2018-07-12 11:18:57 -07:00
Kyle Sanderson d0bf26135c Collection of plugin cleanups (#777)
* Fix rockthevote not clearing g_Voted on fakeclients.

* remove g_RTVAllowed in rockthevote as it's unused.

* Fix basebans using the wrong forward for configs.

* Prevent sm_addban from banning an immune steam adminid.

* Sprinkle in IsChatTrigger checks to plugins with plaintext chat hooks.

* fixup g_Voted[client] in OnClientDisconnect
2018-07-12 11:16:18 -07:00
Nick Hastings 4f2bb62ff9 Enable radio menus for IOSoccer. 2018-07-10 20:19:36 -04:00
Michael Flaherty 28f1ea82b6 Add base CommandIterator implementation (#819)
* Add base CommandIterator implementation

* Add check for invalid pos & finalize pr
2018-07-10 17:39:31 -04:00
Michael Flaherty aaac0b9eb2 Individualize NameHashSet Hashing & Revisit #709 (#740)
* Make mac/win lookups lowercase'd

* Revert #709 & 81042cc

* Adjust HashPolicy implementation across sourcemod

Basically, in order to implement our own (actual) hash policy in
`PluginSys.h`, we needed to remove the blanket implementation of `hash`
that was used before. Now, each policy must implement `hash` along with
`matches` in order to be used with `NameHashSet`. While this does force
us to change every implementation of policies across the entirety of
sourcemod, it allows core to use flexible implementations of `hash`.

* Remove logic duplication

* Improve lowercase checks
2018-07-10 17:38:40 -04:00
Alfred Llagas daee19d502 Changed "entiy" to "entity" in IsEntNetworkable (#847)
* Changed "entiy" to "entity" in IsEntNetworkable

* Update entity.inc
2018-07-08 11:11:35 -04:00
Mattia 70145dfd74 Make SQL_QuoteString deprecated (#792)
* Make SQL_QuoteString deprecated

* Fix message
2018-07-08 11:06:06 -04:00
Michael Flaherty c09b32010f Add Profiler methodmap (#814)
* Add profiler methodmap

* No tag mismatches here

thanks pm

* Lets fix some documentation while we're here.

* Use proper methodmap documentation style

Across sm we use `//` for methodmap docs, so lets just keep this consistent
2018-07-08 11:05:29 -04:00
Mattia 85a1d3e78a "sound" folder instead "sounds" (#790)
The folder is actually "sound" and not "sounds"
2018-07-08 11:04:20 -04:00
Nick Hastings a9c9da1066 Update SDKTools sound functionality for hl2sdk-csgo changes. 2018-07-07 08:57:00 -04:00
Nick Hastings 2860f31cb0 Trigger build for hl2sdk-csgo update. 2018-07-06 20:54:36 -04:00
Ruben Gonzalez 54cf1337c1 Merge branch 'master' of github.com:alliedmodders/sourcemod 2018-07-06 19:18:44 -04:00
Ruben Gonzalez dcde5927b1 Update SetClanTag signature 2018-07-06 19:18:14 -04:00
Nick Hastings c458d1e600 Trigger build for hl2sdk-csgo update. 2018-07-06 19:08:58 -04:00
Mr. Silence aae7161273 Updated some offsets and all signatures for ZPS. (#839)
Signed-off-by: Mr.Silence <[email protected]>
2018-06-27 17:15:27 -04:00
Nick Hastings 6287774d69 Update SDKTools gamedata for IOSoccer (fixes #833). 2018-06-22 16:30:22 -04:00
voed dc4d597fb9 Add link to SourceMod plugin API reference in project readme (#830) 2018-06-22 08:08:00 -06:00
Michael Flaherty 9ceb1af4fe Add LogStackTrace native (#685) 2018-06-19 23:18:37 -07:00
Michael Flaherty b9b6832a11 Streamline ConfDb loading proceedure (#791)
* Create DatabaseConfBuilder & remove locking
* Remove all refcounting

This is part 1/n in regards to this PR's rework
* Move db conf lookup out of RunThreadPart
* Return default configuration for failed lookups
* RefPtr members & stop leaks
* fix uint comparison warning
2018-06-19 09:35:37 -07:00
Nick Hastings 53c63def07 Use env vars to find MySQL src on Linux, macOS. 2018-06-07 20:40:14 -04:00
Asher Baker 4f70185aef Fix amtl submodule pin 2018-06-05 19:06:04 +01:00
peace-maker 6fcb411fe4 MySQL: Support multiple result sets in prepared queries (#825)
Prepared statements can return multiple result sets since MySQL 5.5. That can happen when calling stored procedures using `CALL x();`.

This change removes the previous caching of result bindings, since the number of fields in a result can differ from result set to result set. This could potentially have a negative impact on prepared statements always only returning one result set, since the result binding buffers are recreated everytime the statement is executed instead of once. That difference should be negligible.

Fixes #823.
2018-06-05 18:33:33 +01:00
peace-maker 9cc518e408 Fix MySQL extension build using vs2015 (#824)
MySQL defines its own timespec_t. Official mysql builds are built using VS2013, so you still need to compile the client library yourself to be able to link it, but this change makes the dbi extension compatible with future versions already.
2018-06-05 09:29:11 -04:00
Nick Hastings ddebc2a075 Fix oops with SetConVarBounds. 2018-06-03 12:36:58 -04:00
David Anderson fe6abb0c48 Merge pull request #822 from alliedmodders/update-sourcepawn
Update SourcePawn.
2018-05-31 23:32:51 -07:00
David Anderson 90e66cbeef Update SourcePawn. 2018-05-31 23:13:36 -07:00
David Anderson 487e01e4ed Merge pull request #821 from alliedmodders/update-amtl
Update AMTL.
2018-05-31 21:44:09 -07:00
David Anderson 25b3d8f354 Update AMTL. 2018-05-31 21:23:59 -07:00
Ruben Gonzalez d430bd2f5c Fix CompileRegex not actually setting a valid error code. (#775)
Fix CompileRegex not actually setting a valid error code.
2018-05-28 13:59:43 -04:00
Ruben Gonzalez e2767a3c80 Remove goto from ExtensionSys.cpp (#729) 2018-05-25 09:49:10 -04:00
RumbleFrog 7f552e4d75 Deprecate GetMaxClients (#818) 2018-05-23 12:58:36 +01:00
Nick Hastings cbcda61135 Swap _XKEYCHECK_H for _ALLOW_KEYWORD_MACROS, in case it moves to a
different header.
2018-05-21 19:54:12 -04:00
jason-e 2904c87b62 Send ShowActivity messages to TV clients (#813)
`ShowActivity` and related functions are used to inform all clients about the usage of admin commands (such as bans or mutes). These messages are not sent to any fake clients, however they _should_ be sent to SourceTV/GOTV fake clients because messages they receive are actually visible to broadcast viewers and in demos recorded with `tv_record`. 

Player chat messages as well as SM functions like `PrintToChat`/`PrintToChatAll` broadcast to TV clients, but `ShowActivity` does not.
2018-05-09 09:13:49 +01:00
Nick Hastings cfdedce362 Missed converting a GetFlags instance. 2018-05-06 13:18:04 -04:00
Nick Hastings 467d57059a Out with the old ConVar accessibility hacks, in with the new. 2018-05-06 12:59:33 -04:00
Nick Hastings c993712438 Update BM:S gamedata. 2018-05-06 12:17:47 -04:00
Nick Hastings a69d18ae1c Fix warning/error on newer Clang versions from abort not being defined. 2018-05-06 10:28:24 -04:00
Nick Hastings 95dae67d5b Fix wrong matchmaking_ds bin path being used in some instances. 2018-05-06 10:26:43 -04:00
Nick Hastings f6a64da672 Update Insurgency FireOutput gamedata. 2018-05-05 11:35:06 -04:00
Nick Hastings 11b23a6d07 Update ConVar hacks for BMS.
This is also to trigger an MM:S build for hl2sdk changes in multiple branches.
2018-05-05 11:01:55 -04:00
Spirrwell 82f1c5a20b Update Function Offsets For PVKII (#808)
* Update Function Offsets For PVKII

-Updates offsets
-Removes "Reload" as no corresponding function actually exists

* Offset Fixes

-Re-add "Reload" as it's defined for CBaseCombatWeapon
-Fix Linux\Mac offsets for GroundEntChanged
2018-05-01 20:28:54 -04:00
404 7e080d259e Update helpers.inc (#805)
Update GetClientAuthString to GetClientAuthId
2018-04-28 11:18:12 +01:00
Kyle Sanderson 1ab6ab1e5c NPOTB: Add basic issue template for new GH issues. 2018-04-05 22:20:49 -07:00
Nick Hastings b0e7bab980 Merge branch 'master' of https://github.com/alliedmodders/sourcemod 2018-03-28 21:11:14 -04:00
Nick Hastings 9b8d28de56 Allow -1/null for attacker and inflictor for OTD (bug 6494). 2018-03-28 21:10:32 -04:00
Michael Flaherty 5611ec54a2 Migrate extensions to common AMTL string funcs (#785) 2018-03-25 13:00:53 -07:00
Hexah 6c7e29cbdb Documentation fixes from methodmap implementation (#788)
* There is no "menu" param

* No "menu" param on GetTitle()

* Misspell "Replies"
2018-03-25 12:58:11 -07:00
Michael Flaherty 118d6dc9b1 Improve error message for EmitSound (#787)
Improve some error messages in sdktools.
2018-03-20 19:42:43 -06:00
Nicholas Hastings 08fe840bfd Probably fix Windows build. 2018-03-20 17:25:48 -04:00
Nicholas Hastings 4637cf9221 Use MySQL 5.5 for MySQL extension. (#786) 2018-03-20 17:12:30 -04:00
Joël Troch 4fd68939d3 [ZPS] Update gamedata and engine migration (#782)
* Migrate ZPS from EP2 to SDK 2013 engine

* Update ZPS gamedata (for version 3.0.7-Hotfix3)
2018-03-19 19:19:01 -04:00
peace-maker be6a930e82 Update SQLite to version 3.22.0 (#783)
This includes numerous bug fixes, optimizations and new features from releases over the past 5 years.

http://sqlite.org/chronology.html
2018-03-19 19:09:12 -04:00
Michael Flaherty 956f264b85 Replace ke::SafeSprintf with ke::SafeStrcpy (#784) 2018-03-19 20:12:51 +00:00
Nicholas Hastings 0a91b1f5b1 Increase MAX_NAME_LENGTH to match CS:GO MAX_PLAYER_NAME_LENGTH. 2018-02-25 10:51:18 -05:00
Nicholas Hastings a17b47a2dc Add Protobuf.HasField native. 2018-02-25 10:49:37 -05:00
Michael Flaherty 2a8c390498 Un-const string retrievals (#769) 2018-02-20 18:38:17 +00:00
Asher Baker 41ffe975fd Update blacklist.plugins.txt 2018-02-15 22:35:56 +00:00
Ruben Gonzalez 5ac3390656 Add new regex natives. (#767)
Add new regex natives to get multiple/all matches.
2018-02-15 15:31:24 -05:00
peace-maker f9faf9e48c Allow different values per platform in "Keys" gamedata section (#765)
This adds support for platform specific custom key values in the `Keys` section in game config files. Now you can have different values for the same key per platform.

Previously you could only add general key values in gamedata files that were the same on all platforms like
```
"Keys"
{
	"key"	"value"
}
```

This patch allows you to set the value per platform in a subsection like
```
"Keys"
{
	"key"
	{
		"windows"	"value1"
		"linux"	"value2"
		"mac"	"value3"
	}
}
```

Looking up the `key` will return the value matching the host platform.
2018-02-06 14:40:51 +00:00
Michael Flaherty e57dce76e1 Add support for msvc 1912 (Fixes #761) (#764)
* Add support for msvc 1912

* Default new msvc versions to VS 2017

* Use 2015 lib with 2017
2018-02-04 17:06:22 -05:00
Michael Flaherty 64a6972757 Fix description for CharToLower and CharToUpper v2 (#750) 2018-02-02 23:30:12 +00:00
StrangeThings 1293d15f72 Remove the @brief tag in sdktools_hooks.inc (#759) 2018-02-02 23:28:20 +00:00
Michael Flaherty 12fca79006 Prevent use of primitive float operation functions (#763)
Apparently people use the float natives for actual float arithmetic; they're not really intended to be used directly.

* Prevent use of primitive float operation functions
* Deprecate float operation functs
* Alias Float natives to internal names
* Add clarifying note
* Remove use of internal FloatDiv native
2018-02-02 23:27:38 +00:00
thewavelength 55b8371fa8 Add VS Preview 2017 as valid compiler (msvc-1911) (#678) 2018-01-28 11:39:23 +00:00
peace-maker a8080c0bbb Fix description of nominations convars (#758) 2018-01-27 12:00:04 +00:00
JRiipinen 8c61fdc99d Add more TF2 specific DMG_ definitions (#756)
* Add more TF2 DMG_ definitions

* Guard them all

* Inline doccomments
2018-01-26 14:06:54 +00:00
Nicholas Hastings 9374620b8b Add RemoveEntity native. (bug 5714) (#745) 2018-01-07 13:52:36 -05:00
Ruben Gonzalez 5a35760215 Merge pull request #744 from alliedmodders/show-required-exts
Address issue #737
2017-12-31 11:06:35 -05:00
Alex 6b257de75a Add internationalization to basechat and fix CS:GO colours (#674)
* Added translation more to basechat

Also fixed colors, because it didn't work without `\x01` at begin of string.

* Fixed cs:go colors, thanks Bara20

* Added 'space' at the start of string.

* Added check for Engine_CSGO, to remove offset on other games

* forgot one row
2017-12-30 12:25:32 -08:00
Ruben Gonzalez 40356fc9db Address issue #737 2017-12-30 14:08:56 -05:00
Kyle Sanderson de108cca44 Simplify Logger internals (Fixes Issue #663). (#691)
* Simplify Logger internals (Issue #663).

* Avoid reformatting strings on every call.
2017-12-29 19:56:25 -08:00
Kyle Sanderson 5f5a6b3a16 Migrate CDataPack from a Compact Cassette tape. (#688)
* Migrate CDataPack from a Cassette Tape.

Tested-By: Headline22.

* Remove last IsReadable param pass.

* populate len still if CDataPack::ReadString is unreadable or the wrong type.

* Fyren Fixes(TM)(R)(C).

* Deprecate IDataPack.
2017-12-29 19:56:02 -08:00
Nicholas Hastings 29b1926432 A couple of fixups to last commit (NPOTB). 2017-12-29 04:55:56 -08:00
Nicholas Hastings e0a154faa0 Add TF2 NextBot symbol data from Pelipoka to GDC (NPOTB). 2017-12-29 04:38:47 -08:00
Byte 1706fdfed9 Fix typo and update CSGOBadList (#738)
* Fix typo

* Update CSGOBadList
2017-12-28 18:43:49 -05:00
Byte 945df342d8 Fix typo in SwitchTeam Linux Signature (#743) 2017-12-28 17:39:30 -05:00
Scott Ehlert bfb11c7712 Remove extra CS:GO Mac offset for GetItemInLoadout 2017-12-20 04:17:29 -06:00
Scott Ehlert fa7d8757dc Rebuild 64-bit Linux libpcre with -Wa,-mrelax-relocations=no 2017-12-20 03:50:12 -06:00
Scott Ehlert 3c7978153b Rebuild 64-bit Linux libpcre with -fPIC. 2017-12-20 03:15:57 -06:00
Scott Ehlert 7cb3d4d8ff Fix Linux and macOS builds. 2017-12-20 02:13:56 -06:00
Scott Ehlert 870e118150 Fix BreakpadSymbols script for 64-bit builds. 2017-12-20 02:07:30 -06:00
Scott Ehlert e27f8fba1a Hopefully fix Windows build. 2017-12-20 02:04:05 -06:00
Scott Ehlert ce1a4dcac0 64-bit support for CSGO on Linux and macOS (#705) 2017-12-20 01:56:23 -06:00
Scott Ehlert 057a5790e2 Update CS:GO TerminateRound signature for Linux. 2017-12-19 23:23:29 -06:00
Nicholas Hastings 87858ef264 Test build. 2017-12-18 21:00:04 -05:00
Nicholas Hastings 98fea02eaa Roll version. >_> 2017-12-18 20:39:57 -05:00
303 changed files with 152851 additions and 49572 deletions
+7 -7
View File
@@ -7,17 +7,17 @@ Please consider the following guidelines when reporting an issue.
#### Not for general support
This is not the right place to get help with using or installing SourceMod, or for issues with specific, third-party SourceMod plugins or extensions.
For help with SourceMod, please consult the [AlliedModders forums](https://forums.alliedmods.net/forumdisplay.php?f=52). Similary, for assistance with, or to report issues with third-party SourceMod plugins or extension, you should post in the existing thread for the plugin or extension at the [AlliedModders forums](https://forums.alliedmods.net/forumdisplay.php?f=52).
For help with SourceMod, please consult the [AlliedModders forums](https://forums.alliedmods.net/forumdisplay.php?f=52). Similarly, for assistance with, or to report issues with, third-party SourceMod plugins or extensions, you should post in the existing thread for that plugin or extension on the [AlliedModders forums](https://forums.alliedmods.net/forumdisplay.php?f=52).
#### Details, details, details
Provide as much detail as possible when reporting an issue.
For bugs or other undesired behavior, answers to the follow questions are a great start.
For bugs or other undesired behavior, answers to the following questions are a great start:
* What is the issue?
* What behavior are you expecting instead?
* On what operating system is the game server running?
* What game is the game server running?
* What exact (full x.y.z.a version number) version of Metamod:Source and SourceMod are installed on the game server?
* What exact version (full x.y.z.a version number) of Metamod:Source and SourceMod are installed on the game server?
* What is the specific, shortest path to reproducing this issue? If this issue can be reproduced with plugin code, please try to shorten it to the minimum required to trigger the problem.
If this is a feature request, the following are helpful. Generally, not all will apply, but whatever you can answer ahead of time will shorten back and forth conversation.
@@ -29,18 +29,18 @@ If this is a feature request, the following are helpful. Generally, not all will
Please report any security bugs to [[email protected]](mailto:[email protected]) rather than to this public issue tracker.
#### We're only human
Please keep in mind that we maintain the project in our spare time, at no cost. There is no SLA, and you are not owed a response or fix.
Please keep in mind that we maintain this project in our spare time, at no cost. There is no SLA, and you are not owed a response or a fix.
#### Conduct
Please refer to the [AlliedModders forum rules.](https://forums.alliedmods.net/misc.php?do=showrules)
## Pull Requests
Firstly, thank you for considering to contribute changes to the project!
Firstly, thank you for considering contributing changes to the project!
However, if this is anything more than a small fix such an a gamedata update, a glaring code flaw, or a simple typo in a file like this one, please file an issue first so that it can be discussed, unless you have already spoken to multiple members of the development team about it on IRC or the AlliedModders forums.
However, if this is anything more than a small fix such as a gamedata update, a glaring code flaw, or a simple typo in a file like this one, please file an issue first so that it can be discussed, unless you have already spoken to multiple members of the development team about it on IRC or the AlliedModders forums.
We don't like to have to reject pull requests, so we want to avoid those scenarios. We wouldn't want you to feel that you wasted your time writing something only for us to have it then be shot down.
We don't like to have to reject pull requests, so we want to avoid those scenarios. We wouldn't want you to feel like you wasted your time writing something only for us to shoot it down.
#### Rejection
*Copied from Phabricator's [Contributing Code guidelines](https://secure.phabricator.com/book/phabcontrib/article/contributing_code/#rejecting-patches), as we largely feel the same way about this.*
+8
View File
@@ -0,0 +1,8 @@
# These are supported funding model platforms
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
custom: https://www.sourcemod.net/donate.php
+26
View File
@@ -0,0 +1,26 @@
# Help us help you
- [ ] I have checked that my issue [doesn't exist yet](https://github.com/alliedmodders/sourcemod/issues).
- [ ] I have tried my absolute best to reduce the problem-space and have provided the absolute smallest test-case possible.
- [ ] I can always reproduce the issue with the provided description below.
# Environment
* Operating System version:
* Game/AppID (with version if applicable):
* Current SourceMod version:
* Current SourceMod snapshot:
* Current Metamod: Source snapshot:
- [ ] I have updated SourceMod to the [latest version](https://www.sourcemod.net/downloads.php) and it still happens.
- [ ] I have updated SourceMod to the [latest snapshot](https://www.sourcemod.net/downloads.php?branch=dev) and it still happens.
- [ ] I have updated SourceMM to the [latest snapshot](https://sourcemm.net/downloads.php?branch=dev) and it still happens.
# Description
# Problematic Code (or Steps to Reproduce)
```
// TODO(you): code here to reproduce the problem
```
# Logs
* Please attach in separate files: game output, library logs, kernel logs, and any other supporting information.
* In case of a crash, please attach minidump or dump analyze output.
+1 -1
View File
@@ -3,4 +3,4 @@
url = https://github.com/alliedmodders/amtl
[submodule "sourcepawn"]
path = sourcepawn
url = https://github.com/BotoX/sourcepawn.git
url = https://github.com/alliedmodders/sourcepawn
+3 -1
View File
@@ -9,6 +9,7 @@ addons:
apt:
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty-3.9
- llvm-toolchain-trusty-4.0
- llvm-toolchain-trusty-5.0
packages:
@@ -23,6 +24,7 @@ addons:
# - clang-5.0
# - g++-6
# - g++-6-multilib
- clang-3.9
- g++-4.8-multilib
- g++-4.8
- g++-4.9-multilib
@@ -112,5 +114,5 @@ script:
- mkdir build && cd build
- PATH="~/.local/bin:$PATH"
- eval "${MATRIX_EVAL}"
- python ../configure.py --enable-optimize --sdks=episode1,tf2,l4d2,csgo,dota
- python ../configure.py --enable-optimize --sdks=episode1,css,tf2,l4d2,csgo,dota
- ambuild
+133 -46
View File
@@ -11,10 +11,29 @@ class SDK(object):
self.platform = platform
self.name = dir
self.path = None # Actual path
self.platformSpec = platform
# By default, nothing supports x64.
if type(platform) is list:
self.platformSpec = {p: ['x86'] for p in platform}
else:
self.platformSpec = platform
def shouldBuild(self, target, archs):
if target.platform not in self.platformSpec:
return False
if not len([i for i in self.platformSpec[target.platform] if i in archs]):
return False
return True
WinOnly = ['windows']
WinLinux = ['windows', 'linux']
WinLinuxMac = ['windows', 'linux', 'mac']
CSGO = {
'windows': ['x86'],
'linux': ['x86', 'x64'],
'mac': ['x64']
}
PossibleSDKs = {
'episode1': SDK('HL2SDK', '2.ep1', '1', 'EPISODEONE', WinLinux, 'episode1'),
@@ -31,7 +50,7 @@ PossibleSDKs = {
'swarm': SDK('HL2SDK-SWARM', '2.swarm', '16', 'ALIENSWARM', WinOnly, 'swarm'),
'bgt': SDK('HL2SDK-BGT', '2.bgt', '4', 'BLOODYGOODTIME', WinOnly, 'bgt'),
'eye': SDK('HL2SDK-EYE', '2.eye', '5', 'EYE', WinOnly, 'eye'),
'csgo': SDK('HL2SDKCSGO', '2.csgo', '21', 'CSGO', WinLinux, 'csgo'),
'csgo': SDK('HL2SDKCSGO', '2.csgo', '21', 'CSGO', CSGO, 'csgo'),
'portal2': SDK('HL2SDKPORTAL2', '2.portal2', '17', 'PORTAL2', [], 'portal2'),
'blade': SDK('HL2SDKBLADE', '2.blade', '18', 'BLADE', WinLinux, 'blade'),
'insurgency': SDK('HL2SDKINSURGENCY', '2.insurgency', '19', 'INSURGENCY', WinLinuxMac, 'insurgency'),
@@ -60,6 +79,28 @@ def ResolveEnvPath(env, folder):
def Normalize(path):
return os.path.abspath(os.path.normpath(path))
def SetArchFlags(compiler, arch, platform):
if compiler.behavior == 'gcc':
if arch == 'x86':
compiler.cflags += ['-m32']
compiler.linkflags += ['-m32']
if platform == 'mac':
compiler.linkflags += ['-arch', 'i386']
elif arch == 'x64':
compiler.cflags += ['-m64', '-fPIC']
compiler.linkflags += ['-m64']
if platform == 'mac':
compiler.linkflags += ['-arch', 'x86_64']
elif compiler.like('msvc'):
if builder.target.arch == 'x86':
compiler.linkflags += ['/MACHINE:X86']
elif builder.target.arch == 'x64':
compiler.linkflags += ['/MACHINE:X64']
def AppendArchSuffix(binary, name, arch):
if arch == 'x64':
binary.localFolder = name + '.x64'
class SMConfig(object):
def __init__(self):
@@ -68,10 +109,12 @@ class SMConfig(object):
self.extensions = []
self.generated_headers = None
self.mms_root = None
self.mysql_root = None
self.mysql_root = {}
self.spcomp = None
self.spcomp_bins = None
self.smx_files = {}
self.versionlib = None
self.archs = builder.target.arch.replace('x86_64', 'x64').split(',')
def use_auto_versioning(self):
if builder.backend != 'amb2':
@@ -105,7 +148,7 @@ class SMConfig(object):
for sdk_name in PossibleSDKs:
sdk = PossibleSDKs[sdk_name]
if builder.target.platform in sdk.platform:
if sdk.shouldBuild(builder.target, self.archs):
if builder.options.hl2sdk_root:
sdk_path = os.path.join(builder.options.hl2sdk_root, sdk.folder)
else:
@@ -118,8 +161,9 @@ class SMConfig(object):
sdk.path = Normalize(sdk_path)
self.sdks[sdk_name] = sdk
if len(self.sdks) < 1:
raise Exception('At least one SDK must be available.')
if len(self.sdks) < 1 and len(sdk_list):
raise Exception('No SDKs were found that build on {0}-{1}, nothing to do.'.format(
builder.target.platform, builder.target.arch))
if builder.options.mms_path:
self.mms_root = builder.options.mms_path
@@ -136,20 +180,39 @@ class SMConfig(object):
if builder.options.hasMySql:
if builder.options.mysql_path:
self.mysql_root = builder.options.mysql_path
self.mysql_root['x86'] = builder.options.mysql_path
else:
for i in range(7):
self.mysql_root = ResolveEnvPath('MYSQL5', 'mysql-5.' + str(i))
if self.mysql_root:
for i in range(10):
self.mysql_root['x86'] = ResolveEnvPath('MYSQL55', 'mysql-5.' + str(i))
if self.mysql_root['x86']:
break
if not self.mysql_root or not os.path.isdir(self.mysql_root):
if not self.mysql_root['x86'] or not os.path.isdir(self.mysql_root['x86']):
raise Exception('Could not find a path to MySQL!')
self.mysql_root = Normalize(self.mysql_root)
self.mysql_root['x86'] = Normalize(self.mysql_root['x86'])
# For now, ignore 64-bit MySQL on Windows
if 'x64' in self.archs and builder.target.platform != 'windows':
if builder.options.mysql64_path:
self.mysql_root['x64'] = builder.options.mysql64_path
else:
for i in range(10):
self.mysql_root['x64'] = ResolveEnvPath('MYSQL55_64', 'mysql-5.' + str(i) + '-x86_64')
if self.mysql_root['x64']:
break
if not self.mysql_root['x64'] or not os.path.isdir(self.mysql_root['x64']):
raise Exception('Could not find a path to 64-bit MySQL!')
self.mysql_root['x64'] = Normalize(self.mysql_root['x64'])
def configure(self):
builder.AddConfigureFile('pushbuild.txt')
if not set(self.archs).issubset(['x86', 'x64']):
raise Exception('Unknown target architecture: {0}'.format(builder.target.arch))
cxx = builder.DetectCxx()
if cxx.like('msvc') and len(self.archs) > 1:
raise Exception('Building multiple archs with MSVC is not currently supported')
if cxx.like('gcc'):
self.configure_gcc(cxx)
@@ -200,12 +263,11 @@ class SMConfig(object):
'-pipe',
'-fno-strict-aliasing',
'-Wall',
# '-Werror',
'-Werror',
'-Wno-unused',
'-Wno-switch',
'-Wno-array-bounds',
'-msse',
'-m32',
'-fvisibility=hidden',
]
cxx.cxxflags += [
@@ -216,7 +278,6 @@ class SMConfig(object):
'-Wno-overloaded-virtual',
'-fvisibility-inlines-hidden',
]
cxx.linkflags += ['-m32']
have_gcc = cxx.family == 'gcc'
have_clang = cxx.family == 'clang'
@@ -234,7 +295,8 @@ class SMConfig(object):
cxx.cxxflags += ['-Wno-delete-non-virtual-dtor']
if cxx.version >= 'gcc-4.8':
cxx.cflags += ['-Wno-unused-result']
if cxx.version >= 'gcc-9.0':
cxx.cxxflags += ['-Wno-class-memaccess', '-Wno-packed-not-aligned']
if have_clang:
cxx.cxxflags += ['-Wno-implicit-exception-spec-mismatch']
if cxx.version >= 'apple-clang-5.1' or cxx.version >= 'clang-3.4':
@@ -271,7 +333,6 @@ class SMConfig(object):
'/TP',
]
cxx.linkflags += [
'/MACHINE:X86',
'kernel32.lib',
'user32.lib',
'gdi32.lib',
@@ -310,7 +371,6 @@ class SMConfig(object):
cxx.cflags += ['-mmacosx-version-min=10.5']
cxx.linkflags += [
'-mmacosx-version-min=10.5',
'-arch', 'i386',
'-lstdc++',
'-stdlib=libstdc++',
]
@@ -319,7 +379,7 @@ class SMConfig(object):
def configure_windows(self, cxx):
cxx.defines += ['WIN32', '_WINDOWS']
def AddVersioning(self, binary):
def AddVersioning(self, binary, arch):
if builder.target.platform == 'windows':
binary.sources += ['version.rc']
binary.compiler.rcdefines += [
@@ -335,45 +395,51 @@ class SMConfig(object):
'-current_version', self.productVersion
]
if self.use_auto_versioning():
binary.compiler.linkflags += [self.versionlib]
binary.compiler.linkflags += [self.versionlib[arch]]
binary.compiler.sourcedeps += SM.generated_headers
return binary
def LibraryBuilder(self, compiler, name):
def LibraryBuilder(self, compiler, name, arch):
binary = compiler.Library(name)
self.AddVersioning(binary)
AppendArchSuffix(binary, name, arch)
self.AddVersioning(binary, arch)
if binary.compiler.like('msvc'):
binary.compiler.linkflags += ['/SUBSYSTEM:WINDOWS']
return binary
def ProgramBuilder(self, compiler, name):
def ProgramBuilder(self, compiler, name, arch):
binary = compiler.Program(name)
self.AddVersioning(binary)
AppendArchSuffix(binary, name, arch)
self.AddVersioning(binary, arch)
if '-static-libgcc' in binary.compiler.linkflags:
binary.compiler.linkflags.remove('-static-libgcc')
if '-lgcc_eh' in binary.compiler.linkflags:
binary.compiler.linkflags.remove('-lgcc_eh')
if binary.compiler.like('gcc'):
binary.compiler.linkflags += ['-lstdc++']
binary.compiler.linkflags += ['-lstdc++', '-lpthread']
if binary.compiler.like('msvc'):
binary.compiler.linkflags += ['/SUBSYSTEM:CONSOLE']
return binary
def StaticLibraryBuilder(self, compiler, name):
def StaticLibraryBuilder(self, compiler, name, arch):
binary = compiler.StaticLibrary(name)
AppendArchSuffix(binary, name, arch)
return binary;
def Library(self, context, name):
def Library(self, context, name, arch):
compiler = context.cxx.clone()
return self.LibraryBuilder(compiler, name)
SetArchFlags(compiler, arch, builder.target.platform)
return self.LibraryBuilder(compiler, name, arch)
def Program(self, context, name):
def Program(self, context, name, arch):
compiler = context.cxx.clone()
return self.ProgramBuilder(compiler, name)
SetArchFlags(compiler, arch, builder.target.platform)
return self.ProgramBuilder(compiler, name, arch)
def StaticLibrary(self, context, name):
def StaticLibrary(self, context, name, arch):
compiler = context.cxx.clone()
return self.StaticLibraryBuilder(compiler, name)
SetArchFlags(compiler, arch, builder.target.platform)
return self.StaticLibraryBuilder(compiler, name, arch)
def ConfigureForExtension(self, context, compiler):
compiler.cxxincludes += [
@@ -386,13 +452,15 @@ class SMConfig(object):
]
return compiler
def ExtLibrary(self, context, name):
binary = self.Library(context, name)
def ExtLibrary(self, context, name, arch):
binary = self.Library(context, name, arch)
self.ConfigureForExtension(context, binary.compiler)
return binary
def ConfigureForHL2(self, binary, sdk):
def ConfigureForHL2(self, binary, sdk, arch):
compiler = binary.compiler
SetArchFlags(compiler, arch, builder.target.platform)
compiler.cxxincludes += [
os.path.join(self.mms_root, 'core'),
@@ -435,6 +503,9 @@ class SMConfig(object):
else:
compiler.defines += ['COMPILER_GCC']
if arch == 'x64':
compiler.defines += ['X64BITS', 'PLATFORM_64BITS']
# For everything after Swarm, this needs to be defined for entity networking
# to work properly with sendprop value changes.
if sdk.name in ['blade', 'insurgency', 'doi', 'csgo']:
@@ -446,6 +517,7 @@ class SMConfig(object):
if sdk.name == 'csgo' and builder.target.platform == 'linux':
compiler.linkflags += ['-lstdc++']
compiler.defines += ['_GLIBCXX_USE_CXX11_ABI=0']
for path in paths:
compiler.cxxincludes += [os.path.join(sdk.path, *path)]
@@ -455,16 +527,20 @@ class SMConfig(object):
lib_folder = os.path.join(sdk.path, 'linux_sdk')
elif sdk.name in ['sdk2013', 'bms']:
lib_folder = os.path.join(sdk.path, 'lib', 'public', 'linux32')
elif arch == 'x64':
lib_folder = os.path.join(sdk.path, 'lib', 'linux64')
else:
lib_folder = os.path.join(sdk.path, 'lib', 'linux')
elif builder.target.platform == 'mac':
if sdk.name in ['sdk2013', 'bms']:
lib_folder = os.path.join(sdk.path, 'lib', 'public', 'osx32')
elif arch == 'x64':
lib_folder = os.path.join(sdk.path, 'lib', 'osx64')
else:
lib_folder = os.path.join(sdk.path, 'lib', 'mac')
if builder.target.platform in ['linux', 'mac']:
if sdk.name in ['sdk2013', 'bms']:
if sdk.name in ['sdk2013', 'bms'] or arch == 'x64':
compiler.postlink += [
compiler.Dep(os.path.join(lib_folder, 'tier1.a')),
compiler.Dep(os.path.join(lib_folder, 'mathlib.a'))
@@ -476,12 +552,17 @@ class SMConfig(object):
]
if sdk.name in ['blade', 'insurgency', 'doi', 'csgo']:
compiler.postlink += [compiler.Dep(os.path.join(lib_folder, 'interfaces_i486.a'))]
if arch == 'x64':
compiler.postlink += [compiler.Dep(os.path.join(lib_folder, 'interfaces.a'))]
else:
compiler.postlink += [compiler.Dep(os.path.join(lib_folder, 'interfaces_i486.a'))]
dynamic_libs = []
if builder.target.platform == 'linux':
if sdk.name in ['css', 'hl2dm', 'dods', 'tf2', 'sdk2013', 'bms', 'nucleardawn', 'l4d2', 'insurgency', 'doi']:
dynamic_libs = ['libtier0_srv.so', 'libvstdlib_srv.so']
elif arch == 'x64' and sdk.name == 'csgo':
dynamic_libs = ['libtier0_client.so', 'libvstdlib_client.so']
elif sdk.name in ['l4d', 'blade', 'insurgency', 'doi', 'csgo']:
dynamic_libs = ['libtier0.so', 'libvstdlib.so']
else:
@@ -512,20 +593,21 @@ class SMConfig(object):
return binary
def HL2Library(self, context, name, sdk):
binary = self.Library(context, name)
def HL2Library(self, context, name, sdk, arch):
binary = self.Library(context, name, arch)
self.ConfigureForExtension(context, binary.compiler)
return self.ConfigureForHL2(binary, sdk)
return self.ConfigureForHL2(binary, sdk, arch)
def HL2Project(self, context, name):
project = context.cxx.LibraryProject(name)
self.ConfigureForExtension(context, project.compiler)
return project
def HL2Config(self, project, name, sdk):
def HL2Config(self, project, name, sdk, arch):
binary = project.Configure(name, '{0} - {1}'.format(self.tag, sdk.name))
self.AddVersioning(binary)
return self.ConfigureForHL2(binary, sdk)
AppendArchSuffix(binary, name, arch)
self.AddVersioning(binary, arch)
return self.ConfigureForHL2(binary, sdk, arch)
SM = SMConfig()
SM.detectProductVersion()
@@ -548,10 +630,15 @@ SP = builder.Build('sourcepawn/AMBuildScript', {
'external_amtl': os.path.join(builder.sourcePath, 'public', 'amtl'),
'external_build': ['core'],
})
SM.spcomp = SP.spcomp
SM.binaries += [
SP.libsourcepawn
]
if len(SP.spcomp) > 1:
SM.spcomp = SP.spcomp['x86']
else:
SM.spcomp = SP.spcomp[list(SP.spcomp.keys())[0]]
SM.spcomp_bins = list(SP.spcomp.values())
for arch in SM.archs:
SM.binaries += [
SP.libsourcepawn[arch]
]
BuildScripts = [
'loader/AMBuilder',
+10
View File
@@ -14,4 +14,14 @@ Development
- [Issue tracker](https://github.com/alliedmodders/sourcemod/issues): Issues that require back and forth communication
- [Building SourceMod](https://wiki.alliedmods.net/Building_SourceMod): Instructions on how to build SourceMod itself using [AMBuild](https://github.com/alliedmodders/ambuild)
- [SourcePawn scripting](https://wiki.alliedmods.net/Category:SourceMod_Scripting): SourcePawn examples and introduction to the language
- [SourceMod plugin API](https://sm.alliedmods.net/new-api): Online SourceMod plugin API reference generated from the include files
- [SourceMod extension development](https://wiki.alliedmods.net/Category:SourceMod_Development): C++ examples and introduction to various extension interfaces
Contact
-------
- Connect with us on [GameSurge](https://gamesurge.net) IRC in #sourcemod
- Alternatively feel free to join our [Discord](https://discord.gg/HgZctSS) server
License
-------
SourceMod is licensed under the GNU General Public License version 3. Special exceptions are outlined in the LICENSE.txt file inside of the licenses folder.
+1 -1
View File
@@ -35,7 +35,7 @@ namespace SourceMod {
// Add 1 to the RHS of this expression to bump the intercom file
// This is to prevent mismatching core/logic binaries
static const uint32_t SM_LOGIC_MAGIC = 0x0F47C0DE - 55;
static const uint32_t SM_LOGIC_MAGIC = 0x0F47C0DE - 57;
} // namespace SourceMod
+2 -3
View File
@@ -50,7 +50,6 @@ class IProviderCallbacks;
class IExtensionSys;
class ITextParsers;
class ILogger;
class IDataPack;
class ICellArray;
struct sm_logic_t
@@ -70,10 +69,10 @@ struct sm_logic_t
void (*GenerateError)(IPluginContext *, cell_t, int, const char *, ...);
void (*AddNatives)(sp_nativeinfo_t *natives);
void (*RegisterProfiler)(IProfilingTool *tool);
IDataPack * (*CreateDataPack)();
void (*FreeDataPack)(IDataPack *pack);
ICellArray * (*CreateCellArray)(size_t blocksize);
void (*FreeCellArray)(ICellArray *arr);
void * (*FromPseudoAddress)(uint32_t pseudoAddr);
uint32_t (*ToPseudoAddress)(void *addr);
IScriptManager *scripts;
IShareSys *sharesys;
IExtensionSys *extsys;
+2
View File
@@ -22,6 +22,8 @@ parser.options.add_option('--hl2sdk-root', type=str, dest='hl2sdk_root', default
help='Root search folder for HL2SDKs')
parser.options.add_option('--mysql-path', type=str, dest='mysql_path', default=None,
help='Path to MySQL 5')
parser.options.add_option('--mysql64-path', type=str, dest='mysql64_path', default=None,
help='Path to 64-bit MySQL 5')
parser.options.add_option('--mms-path', type=str, dest='mms_path', default=None,
help='Path to Metamod:Source')
parser.options.add_option('--enable-debug', action='store_const', const='1', dest='debug',
+54 -45
View File
@@ -1,4 +1,4 @@
# vim: set sts=2 ts=8 sw=2 tw=99 et ft=python:
# vim: set sts=2 ts=8 sw=2 tw=99 et ft=python:
import os
project = SM.HL2Project(builder, 'sourcemod')
@@ -44,61 +44,70 @@ project.sources += [
for sdk_name in SM.sdks:
sdk = SM.sdks[sdk_name]
binary_name = 'sourcemod.' + sdk.ext
for arch in SM.archs:
if not arch in sdk.platformSpec[builder.target.platform]:
continue
binary = SM.HL2Config(project, binary_name, sdk)
compiler = binary.compiler
binary_name = 'sourcemod.' + sdk.ext
compiler.cxxincludes += [
builder.sourcePath
]
binary = SM.HL2Config(project, binary_name, sdk, arch)
compiler = binary.compiler
if sdk.name == 'csgo':
compiler.cxxincludes += [
os.path.join(sdk.path, 'common', 'protobuf-2.5.0', 'src'),
os.path.join(sdk.path, 'public', 'engine', 'protobuf'),
os.path.join(sdk.path, 'public', 'game', 'shared', 'csgo', 'protobuf')
builder.sourcePath
]
if compiler.like('msvc'):
compiler.defines += ['_XKEYCHECK_H']
if sdk.name == 'csgo':
compiler.cxxincludes += [
os.path.join(sdk.path, 'common', 'protobuf-2.5.0', 'src'),
os.path.join(sdk.path, 'public', 'engine', 'protobuf'),
os.path.join(sdk.path, 'public', 'game', 'shared', 'csgo', 'protobuf')
]
if builder.target.platform == 'linux':
compiler.postlink += ['-lpthread', '-lrt']
if sdk.name == 'csgo':
if compiler.like('msvc'):
compiler.defines += ['_ALLOW_KEYWORD_MACROS']
if builder.target.platform == 'linux':
lib_path = os.path.join(sdk.path, 'lib', 'linux32', 'release', 'libprotobuf.a')
compiler.linkflags += ['-Wl,--exclude-libs=libprotobuf.a']
elif builder.target.platform == 'mac':
lib_path = os.path.join(sdk.path, 'lib', 'osx32', 'release', 'libprotobuf.a')
elif builder.target.platform == 'windows':
msvc_ver = compiler.version
vs_year = ''
if msvc_ver == 1800:
vs_year = '2013'
elif 1900 <= msvc_ver < 2000:
vs_year = '2015'
else:
raise Exception('Cannot find libprotobuf for MSVC version "' + str(compiler.version) + '"')
compiler.postlink += ['-lpthread', '-lrt']
if 'DEBUG' in compiler.defines:
lib_path = os.path.join(sdk.path, 'lib', 'win32', 'debug', 'vs' + vs_year, 'libprotobuf.lib')
else:
lib_path = os.path.join(sdk.path, 'lib', 'win32', 'release', 'vs' + vs_year, 'libprotobuf.lib')
compiler.linkflags.insert(0, binary.Dep(lib_path))
if sdk.name == 'csgo':
if builder.target.platform == 'linux':
if arch == 'x86':
lib_path = os.path.join(sdk.path, 'lib', 'linux32', 'release', 'libprotobuf.a')
elif arch == 'x64':
lib_path = os.path.join(sdk.path, 'lib', 'linux64', 'release', 'libprotobuf.a')
compiler.linkflags += ['-Wl,--exclude-libs=libprotobuf.a']
elif builder.target.platform == 'mac':
if arch == 'x86':
lib_path = os.path.join(sdk.path, 'lib', 'osx32', 'release', 'libprotobuf.a')
elif arch == 'x64':
lib_path = os.path.join(sdk.path, 'lib', 'osx64', 'release', 'libprotobuf.a')
elif builder.target.platform == 'windows':
msvc_ver = compiler.version
vs_year = ''
if msvc_ver == 1800:
vs_year = '2013'
elif 1900 <= msvc_ver < 2000:
vs_year = '2015'
else:
raise Exception('Cannot find libprotobuf for MSVC version "' + str(compiler.version) + '"')
if 'DEBUG' in compiler.defines:
lib_path = os.path.join(sdk.path, 'lib', 'win32', 'debug', 'vs' + vs_year, 'libprotobuf.lib')
else:
lib_path = os.path.join(sdk.path, 'lib', 'win32', 'release', 'vs' + vs_year, 'libprotobuf.lib')
compiler.linkflags.insert(0, binary.Dep(lib_path))
if sdk.name == 'csgo':
binary.sources += ['smn_protobuf.cpp']
else:
binary.sources += ['smn_bitbuffer.cpp']
if sdk.name == 'csgo':
binary.sources += ['smn_protobuf.cpp']
else:
binary.sources += ['smn_bitbuffer.cpp']
if sdk.name == 'csgo':
binary.sources += [
os.path.join(sdk.path, 'public', 'engine', 'protobuf', 'netmessages.pb.cc'),
os.path.join(sdk.path, 'public', 'game', 'shared', 'csgo', 'protobuf', 'cstrike15_usermessages.pb.cc'),
os.path.join(sdk.path, 'public', 'game', 'shared', 'csgo', 'protobuf', 'cstrike15_usermessage_helpers.cpp'),
]
if sdk.name == 'csgo':
binary.sources += [
os.path.join(sdk.path, 'public', 'engine', 'protobuf', 'netmessages.pb.cc'),
os.path.join(sdk.path, 'public', 'game', 'shared', 'csgo', 'protobuf', 'cstrike15_usermessages.pb.cc'),
os.path.join(sdk.path, 'public', 'game', 'shared', 'csgo', 'protobuf', 'cstrike15_usermessage_helpers.cpp'),
]
SM.binaries += builder.Add(project)
+9 -6
View File
@@ -317,7 +317,7 @@ bool ConCmdManager::CheckAccess(int client, const char *cmd, AdminCmdInfo *pAdmi
char buffer[128];
if (!logicore.CoreTranslate(buffer, sizeof(buffer), "%T", 2, NULL, "No Access", &client))
{
ke::SafeSprintf(buffer, sizeof(buffer), "You do not have access to this command");
ke::SafeStrcpy(buffer, sizeof(buffer), "You do not have access to this command");
}
unsigned int replyto = g_ChatTriggers.GetReplyTo();
@@ -342,9 +342,10 @@ bool ConCmdManager::AddAdminCommand(IPluginFunction *pFunction,
const char *group,
int adminflags,
const char *description,
int flags)
int flags,
IPlugin *pPlugin)
{
ConCmdInfo *pInfo = AddOrFindCommand(name, description, flags);
ConCmdInfo *pInfo = AddOrFindCommand(name, description, flags, pPlugin);
if (!pInfo)
return false;
@@ -388,10 +389,11 @@ bool ConCmdManager::AddAdminCommand(IPluginFunction *pFunction,
bool ConCmdManager::AddServerCommand(IPluginFunction *pFunction,
const char *name,
const char *description,
int flags)
int flags,
IPlugin *pPlugin)
{
ConCmdInfo *pInfo = AddOrFindCommand(name, description, flags);
ConCmdInfo *pInfo = AddOrFindCommand(name, description, flags, pPlugin);
if (!pInfo)
return false;
@@ -555,7 +557,7 @@ bool ConCmdManager::LookForCommandAdminFlags(const char *cmd, FlagBits *pFlags)
return true;
}
ConCmdInfo *ConCmdManager::AddOrFindCommand(const char *name, const char *description, int flags)
ConCmdInfo *ConCmdManager::AddOrFindCommand(const char *name, const char *description, int flags, IPlugin *pPlugin)
{
ConCmdInfo *pInfo;
if (!m_Cmds.retrieve(name, &pInfo))
@@ -580,6 +582,7 @@ ConCmdInfo *ConCmdManager::AddOrFindCommand(const char *name, const char *descri
char *new_name = sm_strdup(name);
char *new_help = sm_strdup(description);
pCmd = new ConCommand(new_name, CommandCallback, new_help, flags);
pInfo->pPlugin = pPlugin;
pInfo->sourceMod = true;
}
else
+8 -4
View File
@@ -41,6 +41,7 @@
#include <IAdminSystem.h>
#include "concmd_cleaner.h"
#include "GameHooks.h"
#include <am-autoptr.h>
#include <sm_stringhashmap.h>
#include <am-utility.h>
#include <am-inlinelist.h>
@@ -98,8 +99,9 @@ struct ConCmdInfo
{
ConCmdInfo()
{
pPlugin = nullptr;
sourceMod = false;
pCmd = NULL;
pCmd = nullptr;
eflags = 0;
}
bool sourceMod; /**< Determines whether or not concmd was created by a SourceMod plugin */
@@ -107,6 +109,7 @@ struct ConCmdInfo
CmdHookList hooks; /**< Hook list */
FlagBits eflags; /**< Effective admin flags */
ke::RefPtr<CommandHook> sh_hook; /**< SourceHook hook, if any. */
IPlugin *pPlugin; /**< Owning plugin handle. */
};
typedef List<ConCmdInfo *> ConCmdList;
@@ -131,13 +134,14 @@ public: //IRootConsoleCommand
public: //IConCommandTracker
void OnUnlinkConCommandBase(ConCommandBase *pBase, const char *name) override;
public:
bool AddServerCommand(IPluginFunction *pFunction, const char *name, const char *description, int flags);
bool AddServerCommand(IPluginFunction *pFunction, const char *name, const char *description, int flags, IPlugin *pPlugin);
bool AddAdminCommand(IPluginFunction *pFunction,
const char *name,
const char *group,
int adminflags,
const char *description,
int flags);
int flags,
IPlugin *pPlugin);
ResultType DispatchClientCommand(int client, const char *cmd, int args, ResultType type);
void UpdateAdminCmdFlags(const char *cmd, OverrideType type, FlagBits bits, bool remove);
bool LookForSourceModCommand(const char *cmd);
@@ -145,7 +149,7 @@ public:
private:
bool InternalDispatch(int client, const ICommandArgs *args);
ResultType RunAdminCommand(ConCmdInfo *pInfo, int client, int args);
ConCmdInfo *AddOrFindCommand(const char *name, const char *description, int flags);
ConCmdInfo *AddOrFindCommand(const char *name, const char *description, int flags, IPlugin *pPlugin);
void AddToCmdList(ConCmdInfo *info);
void RemoveConCmd(ConCmdInfo *info, const char *cmd, bool untrack);
bool CheckAccess(int client, const char *cmd, AdminCmdInfo *pAdmin);
+2 -2
View File
@@ -364,8 +364,8 @@ void EventManager::FireEvent(EventInfo *pInfo, bool bDontBroadcast)
void EventManager::FireEventToClient(EventInfo *pInfo, IClient *pClient)
{
// The IClient vtable is +4 from the IGameEventListener2 (CBaseClient) vtable due to multiple inheritance.
IGameEventListener2 *pGameClient = (IGameEventListener2 *)((intptr_t)pClient - 4);
// The IClient vtable is +sizeof(void *) from the IGameEventListener2 (CBaseClient) vtable due to multiple inheritance.
IGameEventListener2 *pGameClient = (IGameEventListener2 *)((intptr_t)pClient - sizeof(void *));
pGameClient->FireGameEvent(pInfo->pEvent);
}
+30 -17
View File
@@ -50,8 +50,8 @@
typedef ICommandLine *(*FakeGetCommandLine)();
#define TIER0_NAME SOURCE_BIN_PREFIX "tier0" SOURCE_BIN_SUFFIX SOURCE_BIN_EXT
#define VSTDLIB_NAME SOURCE_BIN_PREFIX "vstdlib" SOURCE_BIN_SUFFIX SOURCE_BIN_EXT
#define TIER0_NAME FORMAT_SOURCE_BIN_NAME("tier0")
#define VSTDLIB_NAME FORMAT_SOURCE_BIN_NAME("vstdlib")
CHalfLife2 g_HL2;
ConVar *sv_lan = NULL;
@@ -139,6 +139,7 @@ void CHalfLife2::OnSourceModAllInitialized_Post()
m_CSGOBadList.add("m_flFallbackWear");
m_CSGOBadList.add("m_nFallbackStatTrak");
m_CSGOBadList.add("m_iCompetitiveRanking");
m_CSGOBadList.add("m_iCompetitiveRankType");
m_CSGOBadList.add("m_nActiveCoinRank");
m_CSGOBadList.add("m_nMusicID");
#endif
@@ -162,7 +163,7 @@ ConfigResult CHalfLife2::OnSourceModConfigChanged(const char *key, const char *v
}
else
{
ke::SafeSprintf(error, maxlength, "Invalid value: must be \"yes\" or \"no\"");
ke::SafeStrcpy(error, maxlength, "Invalid value: must be \"yes\" or \"no\"");
return ConfigResult_Reject;
}
#endif
@@ -227,7 +228,12 @@ void CHalfLife2::InitLogicalEntData()
return;
}
#ifdef PLATFORM_X86
g_EntList = *reinterpret_cast<void **>(addr + offset);
#elif defined PLATFORM_X64
int32_t varOffset = *reinterpret_cast<int32_t *>(addr + offset);
g_EntList = reinterpret_cast<void *>(addr + offset + sizeof(int32_t) + varOffset);
#endif
}
}
@@ -827,7 +833,7 @@ void CHalfLife2::AddDelayedKick(int client, int userid, const char *msg)
kick.client = client;
kick.userid = userid;
ke::SafeSprintf(kick.buffer, sizeof(kick.buffer), "%s", msg);
ke::SafeStrcpy(kick.buffer, sizeof(kick.buffer), msg);
m_DelayedKicks.push(kick);
}
@@ -1194,7 +1200,7 @@ bool IsWindowsReservedDeviceName(const char *pMapname)
};
size_t reservedCount = sizeof(reservedDeviceNames) / sizeof(reservedDeviceNames[0]);
for (int i = 0; i < reservedCount; ++i)
for (size_t i = 0; i < reservedCount; ++i)
{
if (CheckReservedFilename(pMapname, reservedDeviceNames[i]))
{
@@ -1260,19 +1266,26 @@ SMFindMapResult CHalfLife2::FindMap(const char *pMapName, char *pFoundMap, size_
return SMFindMapResult::FuzzyMatch;
}
#elif SOURCE_ENGINE == SE_TF2 || SOURCE_ENGINE == SE_BMS
static char szTemp[PLATFORM_MAX_PATH];
if (pFoundMap == NULL)
#elif SOURCE_ENGINE == SE_TF2 || SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_HL2DM \
|| SOURCE_ENGINE == SE_SDK2013 || SOURCE_ENGINE == SE_BMS
static IVEngineServer *engine23 = (IVEngineServer *)(g_SMAPI->GetEngineFactory()("VEngineServer023", nullptr));
if (engine23)
{
ke::SafeStrcpy(szTemp, SM_ARRAYSIZE(szTemp), pMapName);
pFoundMap = szTemp;
nMapNameMax = 0;
}
static char szTemp[PLATFORM_MAX_PATH];
if (pFoundMap == NULL)
{
ke::SafeStrcpy(szTemp, SM_ARRAYSIZE(szTemp), pMapName);
pFoundMap = szTemp;
nMapNameMax = 0;
}
return static_cast<SMFindMapResult>(engine->FindMap(pFoundMap, static_cast<int>(nMapNameMax)));
#elif SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_SDK2013
static IVEngineServer *engine21 = (IVEngineServer *)(g_SMAPI->GetEngineFactory()("VEngineServer021", nullptr));
return engine21->IsMapValid(pMapName) == 0 ? SMFindMapResult::NotFound : SMFindMapResult::Found;
return static_cast<SMFindMapResult>(engine->FindMap(pFoundMap, static_cast<int>(nMapNameMax)));
}
else
{
static IVEngineServer *engine21 = (IVEngineServer *)(g_SMAPI->GetEngineFactory()("VEngineServer021", nullptr));
return engine21->IsMapValid(pMapName) == 0 ? SMFindMapResult::NotFound : SMFindMapResult::Found;
}
#else
return engine->IsMapValid(pMapName) == 0 ? SMFindMapResult::NotFound : SMFindMapResult::Found;
#endif
@@ -1339,7 +1352,7 @@ string_t CHalfLife2::AllocPooledString(const char *pszValue)
bool CHalfLife2::GetServerSteam3Id(char *pszOut, size_t len) const
{
CSteamID sid(GetServerSteamId64());
CSteamID sid((uint64)GetServerSteamId64());
switch (sid.GetEAccountType())
{
+5 -2
View File
@@ -70,8 +70,8 @@ using namespace SourceMod;
#define SOURCE_BIN_EXT ".dylib"
#elif defined __linux__
#if SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_TF2 \
|| SOURCE_ENGINE == SE_SDK2013 || SOURCE_ENGINE == SE_LEFT4DEAD2 || SOURCE_ENGINE == SE_NUCLEARDAWN \
|| SOURCE_ENGINE == SE_BMS || SOURCE_ENGINE == SE_INSURGENCY || SOURCE_ENGINE == SE_DOI
|| SOURCE_ENGINE == SE_SDK2013 || SOURCE_ENGINE == SE_LEFT4DEAD2 || SOURCE_ENGINE == SE_NUCLEARDAWN \
|| SOURCE_ENGINE == SE_BMS || SOURCE_ENGINE == SE_INSURGENCY || SOURCE_ENGINE == SE_DOI
#define SOURCE_BIN_PREFIX "lib"
#define SOURCE_BIN_SUFFIX "_srv"
#elif SOURCE_ENGINE >= SE_LEFT4DEAD
@@ -84,6 +84,9 @@ using namespace SourceMod;
#define SOURCE_BIN_EXT ".so"
#endif
#define FORMAT_SOURCE_BIN_NAME(basename) \
(SOURCE_BIN_PREFIX basename SOURCE_BIN_SUFFIX SOURCE_BIN_EXT)
struct DataTableInfo
{
struct SendPropPolicy
+3 -3
View File
@@ -308,7 +308,7 @@ IMenuPanel *MenuManager::RenderMenu(int client, menu_states_t &md, ItemOrder ord
{
ItemDrawInfo &dr = drawItems[foundItems].draw;
/* Is the item valid? */
if (menu->GetItemInfo(i, &dr, client) != NULL)
if (menu->GetItemInfo(i, &dr) != NULL)
{
/* Ask the user to change the style, if necessary */
mh->OnMenuDrawItem(menu, client, i, dr.style);
@@ -398,7 +398,7 @@ IMenuPanel *MenuManager::RenderMenu(int client, menu_states_t &md, ItemOrder ord
}
while (++lastItem < totalItems)
{
if (menu->GetItemInfo(lastItem, &dr, client) != NULL)
if (menu->GetItemInfo(lastItem, &dr) != NULL)
{
mh->OnMenuDrawItem(menu, client, lastItem, dr.style);
if (IsSlotItem(panel, dr.style))
@@ -420,7 +420,7 @@ IMenuPanel *MenuManager::RenderMenu(int client, menu_states_t &md, ItemOrder ord
lastItem--;
while (lastItem != 0)
{
if (menu->GetItemInfo(lastItem, &dr, client) != NULL)
if (menu->GetItemInfo(lastItem, &dr) != NULL)
{
mh->OnMenuDrawItem(menu, client, lastItem, dr.style);
if (IsSlotItem(panel, dr.style))
+3 -64
View File
@@ -633,7 +633,7 @@ bool CBaseMenu::AppendItem(const char *info, const ItemDrawInfo &draw)
return false;
}
CItem item(m_items.length());
CItem item;
item.info = info;
if (draw.display)
@@ -655,7 +655,7 @@ bool CBaseMenu::InsertItem(unsigned int position, const char *info, const ItemDr
if (position >= m_items.length())
return false;
CItem item(position);
CItem item;
item.info = info;
if (draw.display)
item.display = new ke::AString(draw.display);
@@ -679,16 +679,11 @@ void CBaseMenu::RemoveAllItems()
m_items.clear();
}
const char *CBaseMenu::GetItemInfo(unsigned int position, ItemDrawInfo *draw/* =NULL */, int client/* =0 */)
const char *CBaseMenu::GetItemInfo(unsigned int position, ItemDrawInfo *draw/* =NULL */)
{
if (position >= m_items.length())
return NULL;
if (client > 0 && position < m_RandomMaps[client].length())
{
position = m_RandomMaps[client][position];
}
if (draw)
{
draw->display = m_items[position].display->chars();
@@ -698,62 +693,6 @@ const char *CBaseMenu::GetItemInfo(unsigned int position, ItemDrawInfo *draw/* =
return m_items[position].info.chars();
}
void CBaseMenu::ShufflePerClient(int start, int stop)
{
// limit map len to 255 items since it's using uint8
int length = MIN(GetItemCount(), 255);
if (stop >= 0)
length = MIN(length, stop);
for (int i = 1; i < SM_MAXPLAYERS + 1; i++)
{
// populate per-client map ...
m_RandomMaps[i].resize(length);
for (int j = 0; j < length; j++)
m_RandomMaps[i][j] = j;
// ... and random shuffle it
for (int j = length - 1; j > start; j--)
{
int x = rand() % (j - start + 1) + start;
uint8_t tmp = m_RandomMaps[i][x];
m_RandomMaps[i][x] = m_RandomMaps[i][j];
m_RandomMaps[i][j] = tmp;
}
}
}
void CBaseMenu::SetClientMapping(int client, int *array, int length)
{
length = MIN(length, 255);
m_RandomMaps[client].resize(length);
for (int i = 0; i < length; i++)
{
m_RandomMaps[client][i] = array[i];
}
}
bool CBaseMenu::IsPerClientShuffled()
{
for (int i = 1; i < SM_MAXPLAYERS + 1; i++)
{
if(m_RandomMaps[i].length() > 0)
return true;
}
return false;
}
unsigned int CBaseMenu::GetRealItemIndex(int client, unsigned int position)
{
if (client > 0 && position < m_RandomMaps[client].length())
{
position = m_RandomMaps[client][position];
return m_items[position].index;
}
return position;
}
unsigned int CBaseMenu::GetItemCount()
{
return m_items.length();
+3 -11
View File
@@ -34,6 +34,7 @@
#include <IMenuManager.h>
#include <IPlayerHelpers.h>
#include <am-autoptr.h>
#include <am-string.h>
#include <am-vector.h>
#include "sm_fastlink.h"
@@ -43,9 +44,8 @@ using namespace SourceMod;
class CItem
{
public:
CItem(unsigned int index)
CItem()
{
this->index = index;
style = 0;
access = 0;
}
@@ -53,13 +53,11 @@ public:
: info(ke::Move(other.info)),
display(ke::Move(other.display))
{
index = other.index;
style = other.style;
access = other.access;
}
CItem & operator =(CItem &&other)
{
index = other.index;
info = ke::Move(other.info);
display = ke::Move(other.display);
style = other.style;
@@ -68,7 +66,6 @@ public:
}
public:
unsigned int index;
ke::AString info;
ke::AutoPtr<ke::AString> display;
unsigned int style;
@@ -141,7 +138,7 @@ public:
virtual bool InsertItem(unsigned int position, const char *info, const ItemDrawInfo &draw);
virtual bool RemoveItem(unsigned int position);
virtual void RemoveAllItems();
virtual const char *GetItemInfo(unsigned int position, ItemDrawInfo *draw=NULL, int client=0);
virtual const char *GetItemInfo(unsigned int position, ItemDrawInfo *draw=NULL);
virtual unsigned int GetItemCount();
virtual bool SetPagination(unsigned int itemsPerPage);
virtual unsigned int GetPagination();
@@ -155,10 +152,6 @@ public:
virtual unsigned int GetMenuOptionFlags();
virtual void SetMenuOptionFlags(unsigned int flags);
virtual IMenuHandler *GetHandler();
virtual void ShufflePerClient(int start, int stop);
virtual void SetClientMapping(int client, int *array, int length);
virtual bool IsPerClientShuffled();
virtual unsigned int GetRealItemIndex(int client, unsigned int position);
unsigned int GetBaseMemUsage();
private:
void InternalDelete();
@@ -175,7 +168,6 @@ protected:
Handle_t m_hHandle;
IMenuHandler *m_pHandler;
unsigned int m_nFlags;
ke::Vector<uint8_t> m_RandomMaps[SM_MAXPLAYERS+1];
};
#endif //_INCLUDE_MENUSTYLE_BASE_H
+1 -2
View File
@@ -458,9 +458,8 @@ void CRadioMenuPlayer::Radio_Init(int keys, const char *title, const char *text)
}
else
{
display_len = ke::SafeSprintf(display_pkt,
display_len = ke::SafeStrcpy(display_pkt,
sizeof(display_pkt),
"%s",
text);
}
display_keys = keys;
+3 -4
View File
@@ -514,16 +514,15 @@ void VoteMenuHandler::OnMenuSelect(IBaseMenu *menu, int client, unsigned int ite
/* Check by our item count, NOT the vote array size */
if (item < m_Items)
{
unsigned int index = menu->GetRealItemIndex(client, item);
m_ClientVotes[client] = index;
m_Votes[index]++;
m_ClientVotes[client] = item;
m_Votes[item]++;
m_NumVotes++;
if (sm_vote_chat.GetBool() || sm_vote_console.GetBool() || sm_vote_client_console.GetBool())
{
static char buffer[1024];
ItemDrawInfo dr;
menu->GetItemInfo(item, &dr, client);
menu->GetItemInfo(item, &dr);
if (sm_vote_console.GetBool())
{
+7 -7
View File
@@ -138,8 +138,8 @@ void NextMapManager::HookChangeLevel(const char *map, const char *unknown, const
logger->LogMessage("[SM] Changed map to \"%s\"", newmap);
ke::SafeSprintf(m_tempChangeInfo.m_mapName, sizeof(m_tempChangeInfo.m_mapName), newmap);
ke::SafeSprintf(m_tempChangeInfo.m_changeReason, sizeof(m_tempChangeInfo.m_changeReason), "Normal level change");
ke::SafeStrcpy(m_tempChangeInfo.m_mapName, sizeof(m_tempChangeInfo.m_mapName), newmap);
ke::SafeStrcpy(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));
@@ -184,14 +184,14 @@ void NextMapManager::OnSourceModLevelChange( const char *mapName )
m_tempChangeInfo.m_mapName[0] ='\0';
m_tempChangeInfo.m_changeReason[0] = '\0';
m_tempChangeInfo.startTime = time(NULL);
ke::SafeSprintf(lastMap, sizeof(lastMap), "%s", mapName);
ke::SafeStrcpy(lastMap, sizeof(lastMap), mapName);
}
void NextMapManager::ForceChangeLevel( const char *mapName, const char* changeReason )
{
/* Store the mapname and reason */
ke::SafeSprintf(m_tempChangeInfo.m_mapName, sizeof(m_tempChangeInfo.m_mapName), "%s", mapName);
ke::SafeSprintf(m_tempChangeInfo.m_changeReason, sizeof(m_tempChangeInfo.m_changeReason), "%s", changeReason);
ke::SafeStrcpy(m_tempChangeInfo.m_mapName, sizeof(m_tempChangeInfo.m_mapName), mapName);
ke::SafeStrcpy(m_tempChangeInfo.m_changeReason, sizeof(m_tempChangeInfo.m_changeReason), changeReason);
/* Change level and skip our hook */
g_forcedChange = true;
@@ -221,7 +221,7 @@ void CmdChangeLevelCallback()
if (g_NextMap.m_tempChangeInfo.m_mapName[0] == '\0')
{
ke::SafeSprintf(g_NextMap.m_tempChangeInfo.m_mapName, sizeof(g_NextMap.m_tempChangeInfo.m_mapName), command.Arg(1));
ke::SafeSprintf(g_NextMap.m_tempChangeInfo.m_changeReason, sizeof(g_NextMap.m_tempChangeInfo.m_changeReason), "changelevel Command");
ke::SafeStrcpy(g_NextMap.m_tempChangeInfo.m_mapName, sizeof(g_NextMap.m_tempChangeInfo.m_mapName), command.Arg(1));
ke::SafeStrcpy(g_NextMap.m_tempChangeInfo.m_changeReason, sizeof(g_NextMap.m_tempChangeInfo.m_changeReason), "changelevel Command");
}
}
+8 -106
View File
@@ -30,7 +30,6 @@
*/
#include "PlayerManager.h"
#include "sourcemod.h"
#include "IAdminSystem.h"
#include "ConCmdManager.h"
#include "MenuStyle_Valve.h"
@@ -64,7 +63,7 @@ const unsigned int *g_NumPlayersToAuth = NULL;
int lifestate_offset = -1;
List<ICommandTargetProcessor *> target_processors;
ConVar sm_debug_connect("sm_debug_connect", "0", 0, "Log Debug information about potential connection issues.");
ConVar sm_debug_connect("sm_debug_connect", "1", 0, "Log Debug information about potential connection issues.");
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 *);
@@ -93,12 +92,6 @@ SH_DECL_EXTERN1_void(ConCommand, Dispatch, SH_NOATTRIB, false, const CCommand &)
#else
SH_DECL_EXTERN0_void(ConCommand, Dispatch, SH_NOATTRIB, false);
#endif
SH_DECL_HOOK2_void(IVEngineServer, ClientPrintf, SH_NOATTRIB, 0, edict_t *, const char *);
static void PrintfBuffer_FrameAction(void *data)
{
g_Players.OnPrintfFrameAction(reinterpret_cast<unsigned int>(data));
}
ConCommand *maxplayersCmd = NULL;
@@ -109,7 +102,7 @@ class KickPlayerTimer : public ITimedEvent
public:
ResultType OnTimer(ITimer *pTimer, void *pData)
{
int userid = (int)pData;
int userid = (int)(intptr_t)pData;
int client = g_Players.GetClientOfUserId(userid);
if (client)
{
@@ -179,7 +172,6 @@ void PlayerManager::OnSourceModAllInitialized()
#elif SOURCE_ENGINE > SE_EYE // 2013/orangebox, but not original orangebox.
SH_ADD_HOOK(IServerGameDLL, SetServerHibernation, gamedll, SH_MEMBER(this, &PlayerManager::OnServerHibernationUpdate), true);
#endif
SH_ADD_HOOK(IVEngineServer, ClientPrintf, engine, SH_MEMBER(this, &PlayerManager::OnClientPrintf), false);
sharesys->AddInterface(NULL, this);
@@ -233,7 +225,6 @@ void PlayerManager::OnSourceModShutdown()
#elif SOURCE_ENGINE > SE_EYE // 2013/orangebox, but not original orangebox.
SH_REMOVE_HOOK(IServerGameDLL, SetServerHibernation, gamedll, SH_MEMBER(this, &PlayerManager::OnServerHibernationUpdate), true);
#endif
SH_REMOVE_HOOK(IVEngineServer, ClientPrintf, engine, SH_MEMBER(this, &PlayerManager::OnClientPrintf), false);
/* Release forwards */
forwardsys->ReleaseForward(m_clconnect);
@@ -281,7 +272,7 @@ ConfigResult PlayerManager::OnSourceModConfigChanged(const char *key,
} else if (strcasecmp(value, "off") == 0) {
m_QueryLang = false;
} else {
ke::SafeSprintf(error, maxlength, "Invalid value: must be \"on\" or \"off\"");
ke::SafeStrcpy(error, maxlength, "Invalid value: must be \"on\" or \"off\"");
return ConfigResult_Reject;
}
return ConfigResult_Accept;
@@ -292,7 +283,7 @@ ConfigResult PlayerManager::OnSourceModConfigChanged(const char *key,
} else if ( strcasecmp(value, "no") == 0) {
m_bAuthstringValidation = false;
} else {
ke::SafeSprintf(error, maxlength, "Invalid value: must be \"yes\" or \"no\"");
ke::SafeStrcpy(error, maxlength, "Invalid value: must be \"yes\" or \"no\"");
return ConfigResult_Reject;
}
return ConfigResult_Accept;
@@ -855,88 +846,6 @@ void PlayerManager::OnClientDisconnect_Post(edict_t *pEntity)
}
}
void PlayerManager::OnClientPrintf(edict_t *pEdict, const char *szMsg)
{
int client = IndexOfEdict(pEdict);
CPlayer &player = m_Players[client];
if (!player.IsConnected())
RETURN_META(MRES_IGNORED);
INetChannel *pNetChan = static_cast<INetChannel *>(engine->GetPlayerNetInfo(client));
if (pNetChan == NULL)
RETURN_META(MRES_IGNORED);
size_t nMsgLen = strlen(szMsg);
#if SOURCE_ENGINE == SE_EPISODEONE
static const int nNumBitsWritten = 0;
#else
int nNumBitsWritten = pNetChan->GetNumBitsWritten(false); // SVC_Print uses unreliable netchan
#endif
// if the msg is bigger than allowed then just let it fail
if (nMsgLen + 1 >= SVC_Print_BufferSize) // +1 for NETMSG_TYPE_BITS
RETURN_META(MRES_IGNORED);
// enqueue msgs if we'd overflow the SVC_Print buffer (+7 as ceil)
if (!player.m_PrintfBuffer.empty() || (nNumBitsWritten + NETMSG_TYPE_BITS + 7) / 8 + nMsgLen >= SVC_Print_BufferSize)
{
// Don't send any more messages for this player until the buffer is empty.
// Queue up a gameframe hook to empty the buffer (if we haven't already)
if (player.m_PrintfBuffer.empty())
g_SourceMod.AddFrameAction(PrintfBuffer_FrameAction, (void *)(uintptr_t)player.GetSerial());
player.m_PrintfBuffer.append(szMsg);
RETURN_META(MRES_SUPERCEDE);
}
RETURN_META(MRES_IGNORED);
}
void PlayerManager::OnPrintfFrameAction(unsigned int serial)
{
int client = GetClientFromSerial(serial);
CPlayer &player = m_Players[client];
if (!player.IsConnected())
{
player.ClearNetchannelQueue();
return;
}
INetChannel *pNetChan = static_cast<INetChannel *>(engine->GetPlayerNetInfo(client));
if (pNetChan == NULL)
{
player.ClearNetchannelQueue();
return;
}
while (!player.m_PrintfBuffer.empty())
{
#if SOURCE_ENGINE == SE_EPISODEONE
static const int nNumBitsWritten = 0;
#else
int nNumBitsWritten = pNetChan->GetNumBitsWritten(false); // SVC_Print uses unreliable netchan
#endif
ke::AString &string = player.m_PrintfBuffer.front();
// stop if we'd overflow the SVC_Print buffer (+7 as ceil)
if ((nNumBitsWritten + NETMSG_TYPE_BITS + 7) / 8 + string.length() >= SVC_Print_BufferSize)
break;
SH_CALL(engine, &IVEngineServer::ClientPrintf)(player.m_pEdict, string.chars());
player.m_PrintfBuffer.popFront();
}
if (!player.m_PrintfBuffer.empty())
{
// continue processing it on the next gameframe as buffer is not empty
g_SourceMod.AddFrameAction(PrintfBuffer_FrameAction, (void *)(uintptr_t)player.GetSerial());
}
}
void ClientConsolePrint(edict_t *e, const char *fmt, ...)
{
char buffer[512];
@@ -2141,18 +2050,18 @@ void CPlayer::UpdateAuthIds()
}
char szAuthBuffer[64];
snprintf(szAuthBuffer, sizeof(szAuthBuffer), "STEAM_%u:%u:%u", steam2universe, m_SteamId.GetAccountID() & 1, m_SteamId.GetAccountID() >> 1);
ke::SafeSprintf(szAuthBuffer, sizeof(szAuthBuffer), "STEAM_%u:%u:%u", steam2universe, m_SteamId.GetAccountID() & 1, m_SteamId.GetAccountID() >> 1);
m_Steam2Id = szAuthBuffer;
// TODO: make sure all hl2sdks' steamclientpublic.h have k_unSteamUserDesktopInstance.
if (m_SteamId.GetUnAccountInstance() == 1 /* k_unSteamUserDesktopInstance */)
{
snprintf(szAuthBuffer, sizeof(szAuthBuffer), "[U:%u:%u]", m_SteamId.GetEUniverse(), m_SteamId.GetAccountID());
ke::SafeSprintf(szAuthBuffer, sizeof(szAuthBuffer), "[U:%u:%u]", m_SteamId.GetEUniverse(), m_SteamId.GetAccountID());
}
else
{
snprintf(szAuthBuffer, sizeof(szAuthBuffer), "[U:%u:%u:%u]", m_SteamId.GetEUniverse(), m_SteamId.GetAccountID(), m_SteamId.GetUnAccountInstance());
ke::SafeSprintf(szAuthBuffer, sizeof(szAuthBuffer), "[U:%u:%u:%u]", m_SteamId.GetEUniverse(), m_SteamId.GetAccountID(), m_SteamId.GetUnAccountInstance());
}
m_Steam3Id = szAuthBuffer;
@@ -2236,13 +2145,6 @@ void CPlayer::Disconnect()
#if SOURCE_ENGINE == SE_CSGO
m_LanguageCookie = InvalidQueryCvarCookie;
#endif
ClearNetchannelQueue();
}
void CPlayer::ClearNetchannelQueue(void)
{
while (!m_PrintfBuffer.empty())
m_PrintfBuffer.popFront();
}
void CPlayer::SetName(const char *name)
@@ -2578,7 +2480,7 @@ void CPlayer::DoBasicAdminChecks()
if (!g_Players.CheckSetAdminName(client, this, id))
{
int userid = engine->GetPlayerUserId(m_pEdict);
g_Timers.CreateTimer(&s_KickPlayerTimer, 0.1f, (void *)userid, 0);
g_Timers.CreateTimer(&s_KickPlayerTimer, 0.1f, (void *)(intptr_t)userid, 0);
}
return;
}
-8
View File
@@ -43,7 +43,6 @@
#include <sh_list.h>
#include <sh_vector.h>
#include <am-string.h>
#include <am-deque.h>
#include "ConVarManager.h"
#include <steam/steamclientpublic.h>
@@ -124,7 +123,6 @@ private:
bool IsAuthStringValidated();
bool SetEngineString();
bool SetCSteamID();
void ClearNetchannelQueue(void);
private:
bool m_IsConnected = false;
bool m_IsInGame = false;
@@ -154,7 +152,6 @@ private:
#if SOURCE_ENGINE == SE_CSGO
QueryCvarCookie_t m_LanguageCookie = InvalidQueryCvarCookie;
#endif
ke::Deque<ke::AString> m_PrintfBuffer;
};
class PlayerManager :
@@ -193,8 +190,6 @@ public:
void OnClientSettingsChanged(edict_t *pEntity);
//void OnClientSettingsChanged_Pre(edict_t *pEntity);
void OnServerHibernationUpdate(bool bHibernating);
void OnClientPrintf(edict_t *pEdict, const char *szMsg);
void OnPrintfFrameAction(unsigned int serial);
public: //IPlayerManager
void AddClientListener(IClientListener *listener);
void RemoveClientListener(IClientListener *listener);
@@ -272,9 +267,6 @@ private:
int m_SourceTVUserId;
int m_ReplayUserId;
bool m_bInCCKVHook;
private:
static const int NETMSG_TYPE_BITS = 5; // SVC_Print overhead for netmsg type
static const int SVC_Print_BufferSize = 2048 - 1; // -1 for terminating \0
};
#if SOURCE_ENGINE >= SE_ORANGEBOX
+91
View File
@@ -118,6 +118,13 @@ public:
return msg;
}
inline bool HasField(const char *pszFieldName)
{
GETCHECK_FIELD();
CHECK_FIELD_NOT_REPEATED();
return msg->GetReflection()->HasField(*msg, field);
}
inline bool GetInt32(const char *pszFieldName, int32 *out)
{
GETCHECK_FIELD();
@@ -341,6 +348,20 @@ public:
return true;
}
inline bool GetInt64OrUnsigned(const char *pszFieldName, int64 *out)
{
GETCHECK_FIELD();
CHECK_FIELD_TYPE2(INT64, UINT64);
CHECK_FIELD_NOT_REPEATED();
if (fieldType == protobuf::FieldDescriptor::CPPTYPE_UINT64)
*out = (int64)msg->GetReflection()->GetUInt64(*msg, field);
else
*out = msg->GetReflection()->GetInt64(*msg, field);
return true;
}
inline bool SetInt32OrUnsignedOrEnum(const char *pszFieldName, int32 value)
{
@@ -367,6 +388,24 @@ public:
return true;
}
inline bool SetInt64OrUnsigned(const char *pszFieldName, int64 value)
{
GETCHECK_FIELD();
CHECK_FIELD_TYPE2(INT64, UINT64);
CHECK_FIELD_NOT_REPEATED();
if (fieldType == protobuf::FieldDescriptor::CPPTYPE_UINT64)
{
msg->GetReflection()->SetUInt64(msg, field, (uint64)value);
}
else
{
msg->GetReflection()->SetInt64(msg, field, value);
}
return true;
}
inline bool GetRepeatedInt32OrUnsignedOrEnum(const char *pszFieldName, int index, int32 *out)
{
@@ -384,6 +423,21 @@ public:
return true;
}
inline bool GetRepeatedInt64OrUnsigned(const char *pszFieldName, int index, int64 *out)
{
GETCHECK_FIELD();
CHECK_FIELD_TYPE2(INT64, UINT64);
CHECK_FIELD_REPEATED();
CHECK_REPEATED_ELEMENT(index);
if (fieldType == protobuf::FieldDescriptor::CPPTYPE_UINT64)
*out = (int64)msg->GetReflection()->GetRepeatedUInt64(*msg, field, index);
else
*out = msg->GetReflection()->GetRepeatedInt64(*msg, field, index);
return true;
}
inline bool SetRepeatedInt32OrUnsignedOrEnum(const char *pszFieldName, int index, int32 value)
{
@@ -411,6 +465,25 @@ public:
return true;
}
inline bool SetRepeatedInt64OrUnsigned(const char *pszFieldName, int index, int64 value)
{
GETCHECK_FIELD();
CHECK_FIELD_TYPE2(INT64, UINT64);
CHECK_FIELD_REPEATED();
CHECK_REPEATED_ELEMENT(index);
if (fieldType == protobuf::FieldDescriptor::CPPTYPE_UINT64)
{
msg->GetReflection()->SetRepeatedUInt64(msg, field, index, (uint64)value);
}
else
{
msg->GetReflection()->SetRepeatedInt64(msg, field, index, value);
}
return true;
}
inline bool AddInt32OrUnsignedOrEnum(const char *pszFieldName, int32 value)
{
@@ -437,6 +510,24 @@ public:
return true;
}
inline bool AddInt64OrUnsigned(const char *pszFieldName, int64 value)
{
GETCHECK_FIELD();
CHECK_FIELD_TYPE2(INT64, UINT64);
CHECK_FIELD_REPEATED();
if (fieldType == protobuf::FieldDescriptor::CPPTYPE_UINT64)
{
msg->GetReflection()->AddUInt64(msg, field, (uint64)value);
}
else
{
msg->GetReflection()->AddInt64(msg, field, value);
}
return true;
}
inline bool GetBool(const char *pszFieldName, bool *out)
{
+90 -86
View File
@@ -1,94 +1,98 @@
# vim: set sts=2 ts=8 sw=2 tw=99 et ft=python:
import os
binary = SM.Library(builder, 'sourcemod.logic')
binary.compiler.cxxincludes += [
builder.sourcePath,
os.path.join(builder.sourcePath, 'core', 'logic'),
os.path.join(builder.sourcePath, 'public'),
os.path.join(builder.sourcePath, 'sourcepawn', 'include'),
os.path.join(builder.sourcePath, 'public', 'amtl', 'amtl'),
os.path.join(builder.sourcePath, 'public', 'amtl'),
os.path.join(SM.mms_root, 'core', 'sourcehook')
]
binary.compiler.defines += [
'SM_DEFAULT_THREADER',
'SM_LOGIC'
]
for arch in SM.archs:
binary = SM.Library(builder, 'sourcemod.logic', arch)
binary.compiler.cxxincludes += [
builder.sourcePath,
os.path.join(builder.sourcePath, 'core', 'logic'),
os.path.join(builder.sourcePath, 'public'),
os.path.join(builder.sourcePath, 'sourcepawn', 'include'),
os.path.join(builder.sourcePath, 'public', 'amtl', 'amtl'),
os.path.join(builder.sourcePath, 'public', 'amtl'),
os.path.join(SM.mms_root, 'core', 'sourcehook')
]
binary.compiler.defines += [
'SM_DEFAULT_THREADER',
'SM_LOGIC'
]
if builder.target.platform == 'linux':
binary.compiler.postlink += ['-lpthread', '-lrt']
elif builder.target.platform == 'mac':
binary.compiler.cflags += ['-Wno-deprecated-declarations']
binary.compiler.postlink += ['-framework', 'CoreServices']
if builder.target.platform == 'linux':
binary.compiler.postlink += ['-lpthread', '-lrt']
elif builder.target.platform == 'mac':
binary.compiler.cflags += ['-Wno-deprecated-declarations']
binary.compiler.postlink += ['-framework', 'CoreServices']
if binary.compiler.family == 'gcc' or binary.compiler.family == 'clang':
binary.compiler.cxxflags += ['-fno-rtti']
elif binary.compiler.family == 'msvc':
binary.compiler.cxxflags += ['/GR-']
if binary.compiler.family == 'gcc' or binary.compiler.family == 'clang':
binary.compiler.cxxflags += ['-fno-rtti']
elif binary.compiler.family == 'msvc':
binary.compiler.cxxflags += ['/GR-']
binary.sources += [
'common_logic.cpp',
'smn_adt_array.cpp',
'smn_sorting.cpp',
'smn_maplists.cpp',
'ADTFactory.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',
'smn_functions.cpp',
'smn_timers.cpp',
'smn_players.cpp',
'MemoryUtils.cpp',
'smn_admin.cpp',
'smn_banning.cpp',
'smn_filesystem.cpp',
'stringutil.cpp',
'Translator.cpp',
'PhraseCollection.cpp',
'smn_lang.cpp',
'smn_string.cpp',
'smn_handles.cpp',
'smn_datapacks.cpp',
'smn_gameconfigs.cpp',
'smn_fakenatives.cpp',
'GameConfigs.cpp',
'sm_crc32.cpp',
'smn_profiler.cpp',
'ShareSys.cpp',
'PluginSys.cpp',
'HandleSys.cpp',
'NativeOwner.cpp',
'ExtensionSys.cpp',
'DebugReporter.cpp',
'Database.cpp',
'smn_database.cpp',
'ForwardSys.cpp',
'AdminCache.cpp',
'sm_trie.cpp',
'smn_console.cpp',
'ProfileTools.cpp',
'Logger.cpp',
'smn_core.cpp',
'smn_menus.cpp',
'sprintf.cpp',
'LibrarySys.cpp',
'RootConsoleMenu.cpp',
'CDataPack.cpp',
'frame_tasks.cpp',
'smn_halflife.cpp',
'FrameIterator.cpp',
'NativeInvoker.cpp',
]
if builder.target.platform == 'windows':
binary.sources += ['thread/WinThreads.cpp']
else:
binary.sources += ['thread/PosixThreads.cpp']
binary.sources += [
'common_logic.cpp',
'smn_adt_array.cpp',
'smn_sorting.cpp',
'smn_maplists.cpp',
'ADTFactory.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',
'smn_functions.cpp',
'smn_timers.cpp',
'smn_players.cpp',
'MemoryUtils.cpp',
'smn_admin.cpp',
'smn_banning.cpp',
'smn_filesystem.cpp',
'stringutil.cpp',
'Translator.cpp',
'PhraseCollection.cpp',
'smn_lang.cpp',
'smn_string.cpp',
'smn_handles.cpp',
'smn_datapacks.cpp',
'smn_gameconfigs.cpp',
'smn_fakenatives.cpp',
'GameConfigs.cpp',
'sm_crc32.cpp',
'smn_profiler.cpp',
'ShareSys.cpp',
'PluginSys.cpp',
'HandleSys.cpp',
'NativeOwner.cpp',
'ExtensionSys.cpp',
'DebugReporter.cpp',
'Database.cpp',
'smn_database.cpp',
'ForwardSys.cpp',
'AdminCache.cpp',
'sm_trie.cpp',
'smn_console.cpp',
'ProfileTools.cpp',
'Logger.cpp',
'smn_core.cpp',
'smn_menus.cpp',
'sprintf.cpp',
'LibrarySys.cpp',
'RootConsoleMenu.cpp',
'CDataPack.cpp',
'frame_tasks.cpp',
'smn_halflife.cpp',
'FrameIterator.cpp',
'DatabaseConfBuilder.cpp',
]
if arch == 'x64':
binary.sources += ['PseudoAddrManager.cpp']
SM.binaries += [builder.Add(binary)]
if builder.target.platform == 'windows':
binary.sources += ['thread/WinThreads.cpp']
else:
binary.sources += ['thread/PosixThreads.cpp']
SM.binaries += [builder.Add(binary)]
+3 -3
View File
@@ -1090,14 +1090,14 @@ bool AdminCache::GetUnifiedSteamIdentity(const char *ident, char *out, size_t ma
else if (len >= 11 && !strncmp(ident, "STEAM_", 6) && ident[8] != '_')
{
// non-bot/lan Steam2 Id, strip off the STEAM_* part
snprintf(out, maxlen, "%s", &ident[8]);
ke::SafeStrcpy(out, maxlen, &ident[8]);
return true;
}
else if (len >= 7 && !strncmp(ident, "[U:", 3) && ident[len-1] == ']')
{
// Steam3 Id, replicate the Steam2 Post-"STEAM_" part
uint32_t accountId = strtoul(&ident[5], nullptr, 10);
snprintf(out, maxlen, "%u:%u", accountId & 1, accountId >> 1);
ke::SafeSprintf(out, maxlen, "%u:%u", accountId & 1, accountId >> 1);
return true;
}
else
@@ -1124,7 +1124,7 @@ bool AdminCache::GetUnifiedSteamIdentity(const char *ident, char *out, size_t ma
&& accountType == k_EAccountTypeIndividual && accountInstance <= k_unSteamUserWebInstance
)
{
snprintf(out, maxlen, "%u:%u", accountId & 1, accountId >> 1);
ke::SafeSprintf(out, maxlen, "%u:%u", accountId & 1, accountId >> 1);
return true;
}
}
+132 -245
View File
@@ -33,27 +33,20 @@
#include <string.h>
#include "CDataPack.h"
#include <amtl/am-autoptr.h>
#include <amtl/am-vector.h>
using namespace ke;
#define DATAPACK_INITIAL_SIZE 64
CDataPack::CDataPack()
{
m_pBase = (char *)malloc(DATAPACK_INITIAL_SIZE);
m_capacity = DATAPACK_INITIAL_SIZE;
Initialize();
}
CDataPack::~CDataPack()
{
free(m_pBase);
Initialize();
}
static Vector<AutoPtr<CDataPack>> sDataPackCache;
static ke::Vector<ke::AutoPtr<CDataPack>> sDataPackCache;
IDataPack * CDataPack::New()
CDataPack *CDataPack::New()
{
if (sDataPackCache.empty())
return new CDataPack();
@@ -65,293 +58,187 @@ IDataPack * CDataPack::New()
}
void
CDataPack::Free(IDataPack *pack)
CDataPack::Free(CDataPack *pack)
{
sDataPackCache.append(static_cast<CDataPack *>(pack));
}
void CDataPack::Initialize()
{
m_curptr = m_pBase;
m_size = 0;
}
void CDataPack::CheckSize(size_t typesize)
{
if (m_curptr - m_pBase + typesize <= m_capacity)
{
return;
}
size_t pos = m_curptr - m_pBase;
do
{
m_capacity *= 2;
} while (pos + typesize > m_capacity);
m_pBase = (char *)realloc(m_pBase, m_capacity);
m_curptr = m_pBase + pos;
} while (this->RemoveItem());
elements.clear();
position = 0;
}
void CDataPack::ResetSize()
{
m_size = 0;
Initialize();
}
size_t CDataPack::CreateMemory(size_t size, void **addr)
{
CheckSize(sizeof(char) + sizeof(size_t) + size);
size_t pos = m_curptr - m_pBase;
InternalPack val;
val.type = CDataPackType::Raw;
val.pData.vval = new uint8_t[size + sizeof(size)];
reinterpret_cast<size_t *>(val.pData.vval)[0] = size;
elements.insert(position, val);
*(char *)m_curptr = Raw;
m_curptr += sizeof(char);
*(size_t *)m_curptr = size;
m_curptr += sizeof(size_t);
if (addr)
{
*addr = m_curptr;
}
m_curptr += size;
m_size += sizeof(char) + sizeof(size_t) + size;
return pos;
return position++;
}
void CDataPack::PackCell(cell_t cell)
{
CheckSize(sizeof(char) + sizeof(size_t) + sizeof(cell_t));
*(char *)m_curptr = Cell;
m_curptr += sizeof(char);
*(size_t *)m_curptr = sizeof(cell_t);
m_curptr += sizeof(size_t);
*(cell_t *)m_curptr = cell;
m_curptr += sizeof(cell_t);
m_size += sizeof(char) + sizeof(size_t) + sizeof(cell_t);
InternalPack val;
val.type = CDataPackType::Cell;
val.pData.cval = cell;
elements.insert(position++, val);
}
void CDataPack::PackFloat(float val)
void CDataPack::PackFunction(cell_t function)
{
CheckSize(sizeof(char) + sizeof(size_t) + sizeof(float));
InternalPack val;
val.type = CDataPackType::Function;
val.pData.cval = function;
elements.insert(position++, val);
}
*(char *)m_curptr = Float;
m_curptr += sizeof(char);
*(size_t *)m_curptr = sizeof(float);
m_curptr += sizeof(size_t);
*(float *)m_curptr = val;
m_curptr += sizeof(float);
m_size += sizeof(char) + sizeof(size_t) + sizeof(float);
void CDataPack::PackFloat(float floatval)
{
InternalPack val;
val.type = CDataPackType::Float;
val.pData.fval = floatval;
elements.insert(position++, val);
}
void CDataPack::PackString(const char *string)
{
size_t len = strlen(string);
size_t maxsize = sizeof(char) + sizeof(size_t) + len + 1;
CheckSize(maxsize);
*(char *)m_curptr = String;
m_curptr += sizeof(char);
// Pack the string length first for buffer overrun checking.
*(size_t *)m_curptr = len;
m_curptr += sizeof(size_t);
// Now pack the string.
memcpy(m_curptr, string, len);
m_curptr[len] = '\0';
m_curptr += len + 1;
m_size += maxsize;
InternalPack val;
val.type = CDataPackType::String;
ke::AString *sval = new ke::AString(string);
val.pData.sval = sval;
elements.insert(position++, val);
}
void CDataPack::Reset() const
{
m_curptr = m_pBase;
position = 0;
}
size_t CDataPack::GetPosition() const
{
return static_cast<size_t>(m_curptr - m_pBase);
return position;
}
bool CDataPack::SetPosition(size_t pos) const
{
if (pos > m_size)
{
if (pos > elements.length())
return false;
}
m_curptr = m_pBase + pos;
position = pos;
return true;
}
cell_t CDataPack::ReadCell() const
{
if (!IsReadable(sizeof(char) + sizeof(size_t) + sizeof(cell_t)))
{
if (!IsReadable() || elements[position].type != CDataPackType::Cell)
return 0;
}
if (*reinterpret_cast<char *>(m_curptr) != Cell)
{
return 0;
}
m_curptr += sizeof(char);
if (*reinterpret_cast<size_t *>(m_curptr) != sizeof(cell_t))
{
return 0;
}
m_curptr += sizeof(size_t);
cell_t val = *reinterpret_cast<cell_t *>(m_curptr);
m_curptr += sizeof(cell_t);
return val;
}
float CDataPack::ReadFloat() const
{
if (!IsReadable(sizeof(char) + sizeof(size_t) + sizeof(float)))
{
return 0;
}
if (*reinterpret_cast<char *>(m_curptr) != Float)
{
return 0;
}
m_curptr += sizeof(char);
if (*reinterpret_cast<size_t *>(m_curptr) != sizeof(float))
{
return 0;
}
m_curptr += sizeof(size_t);
float val = *reinterpret_cast<float *>(m_curptr);
m_curptr += sizeof(float);
return val;
}
bool CDataPack::IsReadable(size_t bytes) const
{
return (bytes + (m_curptr - m_pBase) > m_size) ? false : true;
}
const char *CDataPack::ReadString(size_t *len) const
{
if (!IsReadable(sizeof(char) + sizeof(size_t)))
{
return NULL;
}
if (*reinterpret_cast<char *>(m_curptr) != String)
{
return NULL;
}
m_curptr += sizeof(char);
size_t real_len = *(size_t *)m_curptr;
m_curptr += sizeof(size_t);
char *str = (char *)m_curptr;
if ((strlen(str) != real_len) || !(IsReadable(real_len+1)))
{
return NULL;
}
if (len)
{
*len = real_len;
}
m_curptr += real_len + 1;
return str;
}
void *CDataPack::GetMemory() const
{
return m_curptr;
}
void *CDataPack::ReadMemory(size_t *size) const
{
if (!IsReadable(sizeof(size_t)))
{
return NULL;
}
if (*reinterpret_cast<char *>(m_curptr) != Raw)
{
return NULL;
}
m_curptr += sizeof(char);
size_t bytecount = *(size_t *)m_curptr;
m_curptr += sizeof(size_t);
if (!IsReadable(bytecount))
{
return NULL;
}
void *ptr = m_curptr;
if (size)
{
*size = bytecount;
}
m_curptr += bytecount;
return ptr;
}
void CDataPack::PackFunction(cell_t function)
{
CheckSize(sizeof(char) + sizeof(size_t) + sizeof(cell_t));
*(char *)m_curptr = Function;
m_curptr += sizeof(char);
*(size_t *)m_curptr = sizeof(cell_t);
m_curptr += sizeof(size_t);
*(cell_t *)m_curptr = function;
m_curptr += sizeof(cell_t);
m_size += sizeof(char) + sizeof(size_t) + sizeof(cell_t);
return elements[position++].pData.cval;
}
cell_t CDataPack::ReadFunction() const
{
if (!IsReadable(sizeof(char) + sizeof(size_t) + sizeof(cell_t)))
{
if (!IsReadable() || elements[position].type != CDataPackType::Function)
return 0;
}
if (*reinterpret_cast<char *>(m_curptr) != Function)
{
return 0;
}
m_curptr += sizeof(char);
if (*reinterpret_cast<size_t *>(m_curptr) != sizeof(cell_t))
{
return 0;
}
m_curptr += sizeof(size_t);
cell_t val = *reinterpret_cast<cell_t *>(m_curptr);
m_curptr += sizeof(cell_t);
return val;
return elements[position++].pData.cval;
}
float CDataPack::ReadFloat() const
{
if (!IsReadable() || elements[position].type != CDataPackType::Float)
return 0;
return elements[position++].pData.fval;
}
bool CDataPack::IsReadable(size_t bytes) const
{
return (position < elements.length());
}
const char *CDataPack::ReadString(size_t *len) const
{
if (!IsReadable() || elements[position].type != CDataPackType::String)
{
if (len)
*len = 0;
return nullptr;
}
const ke::AString &val = *elements[position++].pData.sval;
if (len)
*len = val.length();
return val.chars();
}
void *CDataPack::ReadMemory(size_t *size) const
{
void *ptr = nullptr;
if (!IsReadable() || elements[position].type != CDataPackType::Raw)
return ptr;
size_t *val = reinterpret_cast<size_t *>(elements[position].pData.vval);
ptr = &(val[1]);
++position;
if (size)
*size = val[0]; /* Egor!!!! */
return ptr;
}
bool CDataPack::RemoveItem(size_t pos)
{
if (!elements.length())
{
return false;
}
if (pos == static_cast<size_t>(-1))
{
pos = position;
}
if (pos >= elements.length())
{
return false;
}
if (pos < position) // we're deleting under us, step back
{
--position;
}
switch (elements[pos].type)
{
case CDataPackType::Raw:
{
delete elements[pos].pData.vval;
break;
}
case CDataPackType::String:
{
delete elements[pos].pData.sval;
break;
}
}
elements.remove(pos);
return true;
}
+134 -23
View File
@@ -32,54 +32,165 @@
#ifndef _INCLUDE_SOURCEMOD_CDATAPACK_H_
#define _INCLUDE_SOURCEMOD_CDATAPACK_H_
#include <IDataPack.h>
#include <ISourceMod.h>
#include <amtl/am-vector.h>
#include <amtl/am-string.h>
using namespace SourceMod;
class CDataPack : public IDataPack
enum CDataPackType {
Raw,
Cell,
Float,
String,
Function
};
class CDataPack
{
public:
CDataPack();
~CDataPack();
static IDataPack *New();
static void Free(IDataPack *pack);
public: //IDataReader
static CDataPack *New();
static void Free(CDataPack *pack);
public: // Originally IDataReader
/**
* @brief Resets the position in the data stream to the beginning.
*/
void Reset() const;
/**
* @brief Retrieves the current stream position.
*
* @return Index into the stream.
*/
size_t GetPosition() const;
/**
* @brief Sets the current stream position.
*
* @param pos Index to set the stream at.
* @return True if succeeded, false if out of bounds.
*/
bool SetPosition(size_t pos) const;
/**
* @brief Reads one cell from the data stream.
*
* @return A cell read from the current position.
*/
cell_t ReadCell() const;
/**
* @brief Reads one float from the data stream.
*
* @return A float read from the current position.
*/
float ReadFloat() const;
bool IsReadable(size_t bytes) const;
/**
* @brief Returns whether or not a specified number of bytes from the current stream
* position to the end can be read.
*
* @param bytes Number of bytes to simulate reading.
* @return True if can be read, false otherwise.
*/
bool IsReadable(size_t bytes = 0) const;
/**
* @brief Reads a string from the data stream.
*
* @param len Optional pointer to store the string length.
* @return Pointer to the string, or NULL if out of bounds.
*/
const char *ReadString(size_t *len) const;
void *GetMemory() const;
/**
* @brief Reads the current position as a generic data type.
*
* @param size Optional pointer to store the size of the data type.
* @return Pointer to the data, or NULL if out of bounds.
*/
void *ReadMemory(size_t *size) const;
/**
* @brief Reads a function pointer from the data stream.
*
* @return A function pointer read from the current position.
*/
cell_t ReadFunction() const;
public: //IDataPack
public: // Originally IDataPack
/**
* @brief Resets the used size of the stream back to zero.
*/
void ResetSize();
/**
* @brief Packs one cell into the data stream.
*
* @param cell Cell value to write.
*/
void PackCell(cell_t cell);
/**
* @brief Packs one float into the data stream.
*
* @param val Float value to write.
*/
void PackFloat(float val);
/**
* @brief Packs one string into the data stream.
* The length is recorded as well for buffer overrun protection.
*
* @param string String to write.
*/
void PackString(const char *string);
/**
* @brief Creates a generic block of memory in the stream.
*
* Note that the pointer it returns can be invalidated on further
* writing, since the stream size may grow. You may need to double back
* and fetch the pointer again.
*
* @param size Size of the memory to create in the stream.
* @param addr Optional pointer to store the relocated memory address.
* @return Current position of the stream beforehand.
*/
size_t CreateMemory(size_t size, void **addr);
/**
* @brief Packs one function pointer into the data stream.
*
* @param function The function pointer to write.
*/
void PackFunction(cell_t function);
public:
void Initialize();
inline size_t GetCapacity() const { return m_capacity; }
private:
void CheckSize(size_t sizetype);
private:
char *m_pBase;
mutable char *m_curptr;
size_t m_capacity;
size_t m_size;
inline size_t GetCapacity() const { return this->elements.length(); };
inline CDataPackType GetCurrentType(void) const { return this->elements[this->position].type; };
bool RemoveItem(size_t pos = -1);
enum DataPackType {
Raw,
Cell,
Float,
String,
Function
};
private:
typedef union {
cell_t cval;
float fval;
uint8_t *vval;
ke::AString *sval;
} InternalPackValue;
typedef struct {
InternalPackValue pData;
CDataPackType type;
} InternalPack;
ke::Vector<InternalPack> elements;
mutable size_t position;
};
#endif //_INCLUDE_SOURCEMOD_CDATAPACK_H_
+9 -3
View File
@@ -227,11 +227,17 @@ private:
/* finally, allocate the new block */
if (m_Data)
{
m_Data = (cell_t *)realloc(m_Data, sizeof(cell_t) * m_BlockSize * m_AllocSize);
cell_t *data = static_cast<cell_t*>(realloc(m_Data, sizeof(cell_t) * m_BlockSize * m_AllocSize));
if (!data) // allocation failure
{
return false;
}
m_Data = data;
} else {
m_Data = (cell_t *)malloc(sizeof(cell_t) * m_BlockSize * m_AllocSize);
m_Data = static_cast<cell_t*>(malloc(sizeof(cell_t) * m_BlockSize * m_AllocSize));
}
return (m_Data != NULL);
return (m_Data != nullptr);
}
private:
cell_t *m_Data;
+43 -191
View File
@@ -37,6 +37,7 @@
#include <stdlib.h>
#include <IThreader.h>
#include <bridge/include/ILogger.h>
#include <bridge/include/CoreProvider.h>
#define DBPARSE_LEVEL_NONE 0
#define DBPARSE_LEVEL_MAIN 1
@@ -47,8 +48,6 @@ static bool s_OneTimeThreaderErrorMsg = false;
DBManager::DBManager()
: m_Terminate(false),
m_ParseLevel(0),
m_ParseState(0),
m_pDefault(NULL)
{
}
@@ -65,38 +64,29 @@ void DBManager::OnSourceModAllInitialized()
g_HandleSys.InitAccessDefaults(NULL, &sec);
sec.access[HandleAccess_Delete] |= HANDLE_RESTRICT_IDENTITY;
sec.access[HandleAccess_Clone] |= HANDLE_RESTRICT_IDENTITY;
m_DriverType = g_HandleSys.CreateType("IDriver", this, 0, NULL, &sec, g_pCoreIdent, NULL);
m_DatabaseType = g_HandleSys.CreateType("IDatabase", this, 0, NULL, NULL, g_pCoreIdent, NULL);
g_ShareSys.AddInterface(NULL, this);
g_pSM->BuildPath(Path_SM, m_Filename, sizeof(m_Filename), "configs/databases.cfg");
g_PluginSys.AddPluginsListener(this);
m_Builder.SetPath(m_Filename);
g_PluginSys.AddPluginsListener(this);
g_pSM->AddGameFrameHook(&FrameHook);
auto sm_reload_databases = [this] (int client, const ICommandArgs *args) -> bool {
m_Builder.StartParse();
return true;
};
bridge->DefineCommand("sm_reload_databases", "Reparse database configurations file", sm_reload_databases);
}
void DBManager::OnSourceModLevelChange(const char *mapName)
{
SMCError err;
SMCStates states = {0, 0};
/* We lock and don't give up the lock until we're done.
* This way the thread's search won't be searching through a
* potentially empty/corrupt list, which would be very bad.
*/
ke::AutoLock lock(&m_ConfigLock);
if ((err = textparsers->ParseFile_SMC(m_Filename, this, &states)) != SMCError_Okay)
{
logger->LogError("[SM] Detected parse error(s) in file \"%s\"", m_Filename);
if (err != SMCError_Custom)
{
const char *txt = textparsers->GetSMCErrorString(err);
logger->LogError("[SM] Line %d: %s", states.line, txt);
}
}
m_Builder.StartParse();
}
void DBManager::OnSourceModShutdown()
@@ -106,7 +96,6 @@ void DBManager::OnSourceModShutdown()
g_PluginSys.RemovePluginsListener(this);
g_HandleSys.RemoveType(m_DatabaseType, g_pCoreIdent);
g_HandleSys.RemoveType(m_DriverType, g_pCoreIdent);
ClearConfigs();
}
unsigned int DBManager::GetInterfaceVersion()
@@ -134,136 +123,10 @@ void DBManager::OnHandleDestroy(HandleType_t type, void *object)
}
}
void DBManager::ReadSMC_ParseStart()
{
ClearConfigs();
m_ParseLevel = 0;
m_ParseState = DBPARSE_LEVEL_NONE;
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)
{
if (m_ParseLevel)
{
m_ParseLevel++;
return SMCResult_Continue;
}
if (m_ParseState == DBPARSE_LEVEL_NONE)
{
if (strcmp(name, "Databases") == 0)
{
m_ParseState = DBPARSE_LEVEL_MAIN;
} else {
m_ParseLevel++;
}
} else if (m_ParseState == DBPARSE_LEVEL_MAIN) {
s_CurInfo = ConfDbInfo();
s_CurInfo.name = name;
m_ParseState = DBPARSE_LEVEL_DATABASE;
} else if (m_ParseState == DBPARSE_LEVEL_DATABASE) {
m_ParseLevel++;
}
return SMCResult_Continue;
}
SMCResult DBManager::ReadSMC_KeyValue(const SMCStates *states, const char *key, const char *value)
{
if (m_ParseLevel)
{
return SMCResult_Continue;
}
if (m_ParseState == DBPARSE_LEVEL_MAIN)
{
if (strcmp(key, "driver_default") == 0)
{
m_DefDriver.assign(value);
}
} else if (m_ParseState == DBPARSE_LEVEL_DATABASE) {
if (strcmp(key, "driver") == 0)
{
if (strcmp(value, "default") != 0)
{
s_CurInfo.driver = value;
}
} else if (strcmp(key, "database") == 0) {
s_CurInfo.database = value;
} else if (strcmp(key, "host") == 0) {
s_CurInfo.host = value;
} else if (strcmp(key, "user") == 0) {
s_CurInfo.user = value;
} else if (strcmp(key, "pass") == 0) {
s_CurInfo.pass = value;
} else if (strcmp(key, "timeout") == 0) {
s_CurInfo.info.maxTimeout = atoi(value);
} else if (strcmp(key, "port") == 0) {
s_CurInfo.info.port = atoi(value);
}
}
return SMCResult_Continue;
}
SMCResult DBManager::ReadSMC_LeavingSection(const SMCStates *states)
{
if (m_ParseLevel)
{
m_ParseLevel--;
return SMCResult_Continue;
}
if (m_ParseState == DBPARSE_LEVEL_DATABASE)
{
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(cdb);
/* Go up one level */
m_ParseState = DBPARSE_LEVEL_MAIN;
} else if (m_ParseState == DBPARSE_LEVEL_MAIN) {
m_ParseState = DBPARSE_LEVEL_NONE;
return SMCResult_Halt;
}
return SMCResult_Continue;
}
void DBManager::ReadSMC_ParseEnd(bool halted, bool failed)
{
}
bool DBManager::Connect(const char *name, IDBDriver **pdr, IDatabase **pdb, bool persistent, char *error, size_t maxlength)
{
ConfDbInfo *pInfo = GetDatabaseConf(name);
ConfDbInfoList *list = m_Builder.GetConfigList();
ke::RefPtr<ConfDbInfo> pInfo = list->GetDatabaseConf(name);
if (!pInfo)
{
@@ -282,11 +145,12 @@ bool DBManager::Connect(const char *name, IDBDriver **pdr, IDatabase **pdb, bool
/* Try to assign a real driver pointer */
if (pInfo->info.driver[0] == '\0')
{
if (!m_pDefault && m_DefDriver.size() > 0)
ke::AString defaultDriver = list->GetDefaultDriver();
if (!m_pDefault && defaultDriver.length() > 0)
{
m_pDefault = FindOrLoadDriver(m_DefDriver.c_str());
m_pDefault = FindOrLoadDriver(defaultDriver.chars());
}
dname = m_DefDriver.size() ? m_DefDriver.c_str() : "default";
dname = defaultDriver.length() ? defaultDriver.chars() : "default";
pInfo->realDriver = m_pDefault;
} else {
pInfo->realDriver = FindOrLoadDriver(pInfo->info.driver);
@@ -310,7 +174,6 @@ bool DBManager::Connect(const char *name, IDBDriver **pdr, IDatabase **pdb, bool
*pdb = NULL;
g_pSM->Format(error, maxlength, "Driver \"%s\" not found", dname);
return false;
}
@@ -323,7 +186,7 @@ void DBManager::AddDriver(IDBDriver *pDriver)
*/
KillWorkerThread();
m_drivers.push_back(pDriver);
m_drivers.push_back(pDriver);
}
void DBManager::RemoveDriver(IDBDriver *pDriver)
@@ -343,17 +206,17 @@ void DBManager::RemoveDriver(IDBDriver *pDriver)
}
}
/* Make sure NOTHING references this! */
List<ConfDbInfo *>::iterator iter;
for (iter=m_confs.begin(); iter!=m_confs.end(); iter++)
ConfDbInfoList *list = m_Builder.GetConfigList();
for (size_t i = 0; i < list->length(); i++)
{
ConfDbInfo &db = *(*iter);
if (db.realDriver == pDriver)
ke::RefPtr<ConfDbInfo> current = list->at(i);
if (current->realDriver == pDriver)
{
db.realDriver = NULL;
current->realDriver = NULL;
}
}
/* Someone unloaded the default driver? Silly.. */
if (pDriver == m_pDefault)
{
@@ -389,9 +252,11 @@ void DBManager::RemoveDriver(IDBDriver *pDriver)
IDBDriver *DBManager::GetDefaultDriver()
{
if (!m_pDefault && m_DefDriver.size() > 0)
ConfDbInfoList *list = m_Builder.GetConfigList();
ke::AString defaultDriver = list->GetDefaultDriver();
if (!m_pDefault && defaultDriver.length() > 0)
{
m_pDefault = FindOrLoadDriver(m_DefDriver.c_str());
m_pDefault = FindOrLoadDriver(defaultDriver.chars());
}
return m_pDefault;
@@ -454,10 +319,16 @@ IDBDriver *DBManager::GetDriver(unsigned int index)
const DatabaseInfo *DBManager::FindDatabaseConf(const char *name)
{
ConfDbInfo *info = GetDatabaseConf(name);
ConfDbInfoList *list = m_Builder.GetConfigList();
ke::RefPtr<ConfDbInfo> info = list->GetDatabaseConf(name);
if (!info)
{
return NULL;
// couldn't find requested conf, return default if exists
info = list->GetDefaultConfiguration();
if (!info)
{
return NULL;
}
}
return &info->info;
@@ -465,18 +336,9 @@ const DatabaseInfo *DBManager::FindDatabaseConf(const char *name)
ConfDbInfo *DBManager::GetDatabaseConf(const char *name)
{
List<ConfDbInfo *>::iterator iter;
for (iter=m_confs.begin(); iter!=m_confs.end(); iter++)
{
ConfDbInfo &conf = *(*iter);
if (conf.name == name)
{
return &conf;
}
}
return NULL;
ConfDbInfoList *list = m_Builder.GetConfigList();
ke::RefPtr<ConfDbInfo> info(list->GetDatabaseConf(name));
return info;
}
IDBDriver *DBManager::FindOrLoadDriver(const char *name)
@@ -729,23 +591,13 @@ void DBManager::OnPluginWillUnload(IPlugin *plugin)
}
}
void DBManager::LockConfig()
ke::AString DBManager::GetDefaultDriverName()
{
m_ConfigLock.Lock();
}
void DBManager::UnlockConfig()
{
m_ConfigLock.Unlock();
}
const char *DBManager::GetDefaultDriverName()
{
return m_DefDriver.c_str();
ConfDbInfoList *list = m_Builder.GetConfigList();
return list->GetDefaultDriver();
}
void DBManager::AddDependency(IExtension *myself, IDBDriver *driver)
{
g_Extensions.AddRawDependency(myself, driver->GetIdentity(), driver);
}
+6 -33
View File
@@ -32,39 +32,24 @@
#ifndef _INCLUDE_DATABASE_MANAGER_H_
#define _INCLUDE_DATABASE_MANAGER_H_
#include <IDBDriver.h>
#include "common_logic.h"
#include <sh_vector.h>
#include <sh_string.h>
#include <am-string.h>
#include <sh_list.h>
#include <ITextParsers.h>
#include <IThreader.h>
#include <IPluginSys.h>
#include <am-thread-utils.h>
#include "sm_simple_prioqueue.h"
#include <am-refcounting.h>
#include "DatabaseConfBuilder.h"
using namespace SourceHook;
struct ConfDbInfo
{
ConfDbInfo() : realDriver(NULL)
{
}
String name;
String driver;
String host;
String user;
String pass;
String database;
IDBDriver *realDriver;
DatabaseInfo info;
};
class DBManager :
public IDBManager,
public SMGlobalClass,
public IHandleTypeDispatch,
public ITextListener_SMC,
public IPluginsListener
{
public:
@@ -83,6 +68,7 @@ public: //IDBManager
void AddDriver(IDBDriver *pDrivera);
void RemoveDriver(IDBDriver *pDriver);
const DatabaseInfo *FindDatabaseConf(const char *name);
ConfDbInfo *GetDatabaseConf(const char *name);
bool Connect(const char *name, IDBDriver **pdr, IDatabase **pdb, bool persistent, char *error, size_t maxlength);
unsigned int GetDriverCount();
IDBDriver *GetDriver(unsigned int index);
@@ -90,25 +76,16 @@ public: //IDBManager
HandleError ReadHandle(Handle_t hndl, DBHandleType type, void **ptr);
HandleError ReleaseHandle(Handle_t hndl, DBHandleType type, IdentityToken_t *token);
void AddDependency(IExtension *myself, IDBDriver *driver);
public: //ITextListener_SMC
void ReadSMC_ParseStart();
SMCResult ReadSMC_NewSection(const SMCStates *states, const char *name);
SMCResult ReadSMC_KeyValue(const SMCStates *states, const char *key, const char *value);
SMCResult ReadSMC_LeavingSection(const SMCStates *states);
void ReadSMC_ParseEnd(bool halted, bool failed);
public: //ke::IRunnable
void Run();
void ThreadMain();
public: //IPluginsListener
void OnPluginWillUnload(IPlugin *plugin);
public:
ConfDbInfo *GetDatabaseConf(const char *name);
IDBDriver *FindOrLoadDriver(const char *name);
IDBDriver *GetDefaultDriver();
const char *GetDefaultDriverName();
ke::AString GetDefaultDriverName();
bool AddToThreadQueue(IDBThreadOperation *op, PrioQueueLevel prio);
void LockConfig();
void UnlockConfig();
void RunFrame();
inline HandleType_t GetDatabaseType()
{
@@ -126,17 +103,13 @@ private:
CVector<bool> m_drSafety; /* which drivers are safe? */
ke::AutoPtr<ke::Thread> m_Worker;
ke::ConditionVariable m_QueueEvent;
ke::Mutex m_ConfigLock;
ke::Mutex m_ThinkLock;
bool m_Terminate;
List<ConfDbInfo *> m_confs;
DatabaseConfBuilder m_Builder;
HandleType_t m_DriverType;
HandleType_t m_DatabaseType;
String m_DefDriver;
char m_Filename[PLATFORM_MAX_PATH];
unsigned int m_ParseLevel;
unsigned int m_ParseState;
IDBDriver *m_pDefault;
};
+184
View File
@@ -0,0 +1,184 @@
/**
* vim: set ts=4 sw=4 tw=99 noet :
* =============================================================================
* SourceMod
* Copyright (C) 2004-2018 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 "DatabaseConfBuilder.h"
#include <bridge/include/ILogger.h>
#define DBPARSE_LEVEL_NONE 0
#define DBPARSE_LEVEL_MAIN 1
#define DBPARSE_LEVEL_DATABASE 2
DatabaseConfBuilder::DatabaseConfBuilder()
: m_ParseList(nullptr),
m_InfoList(new ConfDbInfoList())
{
}
void DatabaseConfBuilder::SetPath(char *str)
{
m_Filename = str;
}
DatabaseConfBuilder::~DatabaseConfBuilder()
{
}
ConfDbInfoList *DatabaseConfBuilder::GetConfigList()
{
return m_InfoList;
}
void DatabaseConfBuilder::StartParse()
{
SMCError err;
SMCStates states = {0, 0};
if ((err = textparsers->ParseFile_SMC(m_Filename.chars(), this, &states)) != SMCError_Okay)
{
logger->LogError("[SM] Detected parse error(s) in file \"%s\"", m_Filename.chars());
if (err != SMCError_Custom)
{
const char *txt = textparsers->GetSMCErrorString(err);
logger->LogError("[SM] Line %d: %s", states.line, txt);
}
}
}
void DatabaseConfBuilder::ReadSMC_ParseStart()
{
m_ParseLevel = 0;
m_ParseState = DBPARSE_LEVEL_NONE;
m_ParseList = new ConfDbInfoList();
}
SMCResult DatabaseConfBuilder::ReadSMC_NewSection(const SMCStates *states, const char *name)
{
if (m_ParseLevel)
{
m_ParseLevel++;
return SMCResult_Continue;
}
if (m_ParseState == DBPARSE_LEVEL_NONE)
{
if (strcmp(name, "Databases") == 0)
{
m_ParseState = DBPARSE_LEVEL_MAIN;
} else {
m_ParseLevel++;
}
} else if (m_ParseState == DBPARSE_LEVEL_MAIN) {
m_ParseCurrent = new ConfDbInfo();
m_ParseCurrent->name = name;
m_ParseState = DBPARSE_LEVEL_DATABASE;
} else if (m_ParseState == DBPARSE_LEVEL_DATABASE) {
m_ParseLevel++;
}
return SMCResult_Continue;
}
SMCResult DatabaseConfBuilder::ReadSMC_KeyValue(const SMCStates *states, const char *key, const char *value)
{
if (m_ParseLevel)
{
return SMCResult_Continue;
}
if (m_ParseState == DBPARSE_LEVEL_MAIN)
{
if (strcmp(key, "driver_default") == 0)
{
m_ParseList->SetDefaultDriver(value);
}
} else if (m_ParseState == DBPARSE_LEVEL_DATABASE) {
if (strcmp(key, "driver") == 0)
{
if (strcmp(value, "default") != 0)
{
m_ParseCurrent->driver = value;
}
} else if (strcmp(key, "database") == 0) {
m_ParseCurrent->database = value;
} else if (strcmp(key, "host") == 0) {
m_ParseCurrent->host = value;
} else if (strcmp(key, "user") == 0) {
m_ParseCurrent->user = value;
} else if (strcmp(key, "pass") == 0) {
m_ParseCurrent->pass = value;
} else if (strcmp(key, "timeout") == 0) {
m_ParseCurrent->info.maxTimeout = atoi(value);
} else if (strcmp(key, "port") == 0) {
m_ParseCurrent->info.port = atoi(value);
}
}
return SMCResult_Continue;
}
SMCResult DatabaseConfBuilder::ReadSMC_LeavingSection(const SMCStates *states)
{
if (m_ParseLevel)
{
m_ParseLevel--;
return SMCResult_Continue;
}
if (m_ParseState == DBPARSE_LEVEL_DATABASE)
{
m_ParseCurrent->info.driver = m_ParseCurrent->driver.chars();
m_ParseCurrent->info.database = m_ParseCurrent->database.chars();
m_ParseCurrent->info.host = m_ParseCurrent->host.chars();
m_ParseCurrent->info.user = m_ParseCurrent->user.chars();
m_ParseCurrent->info.pass = m_ParseCurrent->pass.chars();
/* Save it.. */
m_ParseCurrent->AddRef();
m_ParseList->append(m_ParseCurrent);
m_ParseCurrent = nullptr;
/* Go up one level */
m_ParseState = DBPARSE_LEVEL_MAIN;
} else if (m_ParseState == DBPARSE_LEVEL_MAIN) {
m_ParseState = DBPARSE_LEVEL_NONE;
return SMCResult_Halt;
}
return SMCResult_Continue;
}
void DatabaseConfBuilder::ReadSMC_ParseEnd(bool halted, bool failed)
{
m_InfoList->ReleaseMembers();
delete m_InfoList;
m_InfoList = m_ParseList;
m_ParseList = nullptr;
}
+129
View File
@@ -0,0 +1,129 @@
/**
* vim: set ts=4 sw=4 tw=99 noet :
* =============================================================================
* SourceMod
* Copyright (C) 2004-2018 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_DATABASE_CONF_BUILDER_H_
#define _INCLUDE_DATABASE_CONF_BUILDER_H_
#include <IDBDriver.h>
#include <ITextParsers.h>
#include "common_logic.h"
#include <am-vector.h>
#include <am-string.h>
#include <am-refcounting-threadsafe.h>
class ConfDbInfo : public ke::RefcountedThreadsafe<ConfDbInfo>
{
public:
ConfDbInfo() : realDriver(NULL)
{
}
ke::AString name;
ke::AString driver;
ke::AString host;
ke::AString user;
ke::AString pass;
ke::AString database;
IDBDriver *realDriver;
DatabaseInfo info;
};
class ConfDbInfoList : public ke::Vector<ConfDbInfo *>
{
/* Allow internal usage of ConfDbInfoList */
friend class DBManager;
friend class DatabaseConfBuilder;
private:
ke::AString& GetDefaultDriver() {
return m_DefDriver;
}
ConfDbInfo *GetDatabaseConf(const char *name) {
for (size_t i = 0; i < this->length(); i++)
{
ConfDbInfo *current = this->at(i);
/* If we run into the default configuration, then we'll save it
* for the next call to GetDefaultConfiguration */
if (strcmp(current->name.chars(), "default") == 0)
{
m_DefaultConfig = current;
}
if (strcmp(current->name.chars(), name) == 0)
{
return current;
}
}
return nullptr;
}
ConfDbInfo *GetDefaultConfiguration() {
return m_DefaultConfig;
}
void SetDefaultDriver(const char *input) {
m_DefDriver = ke::AString(input);
}
void ReleaseMembers() {
for (size_t i = 0; i < this->length(); i++) {
ConfDbInfo *current = this->at(i);
current->Release();
}
}
private:
ConfDbInfo *m_DefaultConfig;
ke::AString m_DefDriver;
};
class DatabaseConfBuilder : public ITextListener_SMC
{
public:
DatabaseConfBuilder();
~DatabaseConfBuilder();
void StartParse();
void SetPath(char* path);
ConfDbInfoList *GetConfigList();
public: //ITextListener_SMC
void ReadSMC_ParseStart();
SMCResult ReadSMC_NewSection(const SMCStates *states, const char *name);
SMCResult ReadSMC_KeyValue(const SMCStates *states, const char *key, const char *value);
SMCResult ReadSMC_LeavingSection(const SMCStates *states);
void ReadSMC_ParseEnd(bool halted, bool failed);
private:
unsigned int m_ParseLevel;
unsigned int m_ParseState;
ConfDbInfo *m_ParseCurrent;
ConfDbInfoList *m_ParseList;
private:
ke::AString m_Filename;
ConfDbInfoList *m_InfoList;
};
#endif //_INCLUDE_DATABASE_CONF_BUILDER_H_
+29 -11
View File
@@ -29,11 +29,11 @@
* Version: $Id$
*/
#include <ISourceMod.h>
#include <IPluginSys.h>
#include <stdarg.h>
#include "DebugReporter.h"
#include "Logger.h"
#include <am-string.h>
DebugReport g_DbgReporter;
@@ -194,35 +194,53 @@ void DebugReport::ReportError(const IErrorReport &report, IFrameIterator &iter)
g_Logger.LogError("[SM] Blaming: %s", blame);
}
if (!iter.Done())
ke::Vector<ke::AString> arr = GetStackTrace(&iter);
for (size_t i = 0; i < arr.length(); i++)
{
g_Logger.LogError("[SM] Call stack trace:");
g_Logger.LogError("%s", arr[i].chars());
}
}
for (int index = 0; !iter.Done(); iter.Next(), index++)
ke::Vector<ke::AString> DebugReport::GetStackTrace(IFrameIterator *iter)
{
char temp[3072];
ke::Vector<ke::AString> trace;
iter->Reset();
if (!iter->Done())
{
trace.append("[SM] Call stack trace:");
for (int index = 0; !iter->Done(); iter->Next(), index++)
{
const char *fn = iter.FunctionName();
const char *fn = iter->FunctionName();
if (!fn)
{
fn = "<unknown function>";
}
if (iter.IsNativeFrame())
if (iter->IsNativeFrame())
{
g_Logger.LogError("[SM] [%d] %s", index, fn);
g_pSM->Format(temp, sizeof(temp), "[SM] [%d] %s", index, fn);
trace.append(temp);
continue;
}
if (iter.IsScriptedFrame())
if (iter->IsScriptedFrame())
{
const char *file = iter.FilePath();
const char *file = iter->FilePath();
if (!file)
{
file = "<unknown>";
}
g_Logger.LogError("[SM] [%d] Line %d, %s::%s",
g_pSM->Format(temp, sizeof(temp), "[SM] [%d] Line %d, %s::%s",
index,
iter.LineNumber(),
iter->LineNumber(),
file,
fn);
trace.append(temp);
}
}
}
return trace;
}
+3
View File
@@ -34,6 +34,8 @@
#include "sp_vm_api.h"
#include "common_logic.h"
#include <am-vector.h>
#include <am-string.h>
class DebugReport :
public SMGlobalClass,
@@ -48,6 +50,7 @@ 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, ...);
ke::Vector<ke::AString> GetStackTrace(IFrameIterator *iter);
private:
int _GetPluginIndex(IPluginContext *ctx);
};
+69 -119
View File
@@ -73,73 +73,68 @@ CLocalExtension::CLocalExtension(const char *filename, bool bRequired)
/* 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_pSM->BuildPath(Path_SM,
path,
PLATFORM_MAX_PATH,
"extensions/%s.%s." PLATFORM_LIB_EXT,
filename,
bridge->gamesuffix);
if (libsys->IsPathFile(path))
{
goto found;
}
/* COMPAT HACK: One-halfth, if ep2v, see if there is an engine specific build in the new place with old naming */
if (strcmp(bridge->gamesuffix, "2.tf2") == 0
|| strcmp(bridge->gamesuffix, "2.dods") == 0
|| strcmp(bridge->gamesuffix, "2.hl2dm") == 0
)
{
g_pSM->BuildPath(Path_SM,
path,
PLATFORM_MAX_PATH,
"extensions/%s.2.ep2v." PLATFORM_LIB_EXT,
filename);
if (libsys->IsPathFile(path))
{
goto found;
}
}
else if (strcmp(bridge->gamesuffix, "2.nd") == 0)
{
g_pSM->BuildPath(Path_SM,
path,
PLATFORM_MAX_PATH,
"extensions/%s.2.l4d2." PLATFORM_LIB_EXT,
filename);
if (libsys->IsPathFile(path))
{
goto found;
}
}
/* First see if there is an engine specific build! */
g_pSM->BuildPath(Path_SM,
path,
PLATFORM_MAX_PATH,
"extensions/auto.%s/%s." PLATFORM_LIB_EXT,
filename,
bridge->gamesuffix);
/* Try the "normal" version */
if (!libsys->IsPathFile(path))
{
normal:
g_pSM->BuildPath(Path_SM,
path,
PLATFORM_MAX_PATH,
"extensions/%s." PLATFORM_LIB_EXT,
filename);
}
else
{
/* Zeroth, see if there is an engine specific build in the new place. */
g_pSM->BuildPath(Path_SM,
path,
PLATFORM_MAX_PATH,
"extensions/%s.%s." PLATFORM_LIB_EXT,
filename,
bridge->gamesuffix);
found:
if (!libsys->IsPathFile(path))
{
/* COMPAT HACK: One-halfth, if ep2v, see if there is an engine specific build in the new place with old naming */
if (strcmp(bridge->gamesuffix, "2.tf2") == 0
|| strcmp(bridge->gamesuffix, "2.dods") == 0
|| strcmp(bridge->gamesuffix, "2.hl2dm") == 0
)
{
g_pSM->BuildPath(Path_SM,
path,
PLATFORM_MAX_PATH,
"extensions/%s.2.ep2v." PLATFORM_LIB_EXT,
filename);
}
else if (strcmp(bridge->gamesuffix, "2.nd") == 0)
{
g_pSM->BuildPath(Path_SM,
path,
PLATFORM_MAX_PATH,
"extensions/%s.2.l4d2." PLATFORM_LIB_EXT,
filename);
}
//Try further
if (!libsys->IsPathFile(path))
{
/* First see if there is an engine specific build! */
g_pSM->BuildPath(Path_SM,
path,
PLATFORM_MAX_PATH,
"extensions/auto.%s/%s." PLATFORM_LIB_EXT,
filename,
bridge->gamesuffix);
/* Try the "normal" version */
if (!libsys->IsPathFile(path))
{
g_pSM->BuildPath(Path_SM,
path,
PLATFORM_MAX_PATH,
"extensions/%s." PLATFORM_LIB_EXT,
filename);
}
}
}
}
Initialize(filename, path, bRequired);
}
@@ -176,7 +171,7 @@ bool CLocalExtension::Load(char *error, size_t maxlength)
{
m_pLib->CloseLibrary();
m_pLib = NULL;
snprintf(error, maxlength, "Unable to find extension entry point");
ke::SafeStrcpy(error, maxlength, "Unable to find extension entry point");
return false;
}
@@ -246,7 +241,7 @@ void CLocalExtension::Unload()
bool CRemoteExtension::Reload(char *error, size_t maxlength)
{
snprintf(error, maxlength, "Remote extensions do not support reloading");
ke::SafeStrcpy(error, maxlength, "Remote extensions do not support reloading");
return false;
}
@@ -280,13 +275,13 @@ bool CExtension::PerformAPICheck(char *error, size_t maxlength)
{
if (!m_pAPI)
{
snprintf(error, maxlength, "No IExtensionInterface instance provided");
ke::SafeStrcpy(error, maxlength, "No IExtensionInterface instance provided");
return false;
}
if (m_pAPI->GetExtensionVersion() > SMINTERFACE_EXTENSIONAPI_VERSION)
{
snprintf(error, maxlength, "Extension version is too new to load (%d, max is %d)", m_pAPI->GetExtensionVersion(), SMINTERFACE_EXTENSIONAPI_VERSION);
ke::SafeSprintf(error, maxlength, "Extension version is too new to load (%d, max is %d)", m_pAPI->GetExtensionVersion(), SMINTERFACE_EXTENSIONAPI_VERSION);
return false;
}
@@ -421,65 +416,20 @@ void CExtension::AddChildDependent(CExtension *pOther, SMInterface *iface)
m_ChildDeps.push_back(info);
}
// note: dependency iteration deprecated since 1.10
ITERATOR *CExtension::FindFirstDependency(IExtension **pOwner, SMInterface **pInterface)
{
List<IfaceInfo>::iterator iter = m_Deps.begin();
if (iter == m_Deps.end())
{
return NULL;
}
if (pOwner)
{
*pOwner = (*iter).owner;
}
if (pInterface)
{
*pInterface = (*iter).iface;
}
List<IfaceInfo>::iterator *pIter = new List<IfaceInfo>::iterator(iter);
return (ITERATOR *)pIter;
return nullptr;
}
bool CExtension::FindNextDependency(ITERATOR *iter, IExtension **pOwner, SMInterface **pInterface)
{
List<IfaceInfo>::iterator *pIter = (List<IfaceInfo>::iterator *)iter;
List<IfaceInfo>::iterator _iter;
if (_iter == m_Deps.end())
{
return false;
}
_iter++;
if (pOwner)
{
*pOwner = (*_iter).owner;
}
if (pInterface)
{
*pInterface = (*_iter).iface;
}
*pIter = _iter;
if (_iter == m_Deps.end())
{
return false;
}
return true;
return false;
}
void CExtension::FreeDependencyIterator(ITERATOR *iter)
{
List<IfaceInfo>::iterator *pIter = (List<IfaceInfo>::iterator *)iter;
delete pIter;
}
void CExtension::AddInterface(SMInterface *pInterface)
@@ -493,7 +443,7 @@ bool CExtension::IsRunning(char *error, size_t maxlength)
{
if (error)
{
snprintf(error, maxlength, "%s", m_Error.c_str());
ke::SafeStrcpy(error, maxlength, m_Error.c_str());
}
return false;
}
@@ -575,7 +525,7 @@ void CExtensionManager::TryAutoload()
}
char file[PLATFORM_MAX_PATH];
len = ke::SafeSprintf(file, sizeof(file), "%s", lfile);
len = ke::SafeStrcpy(file, sizeof(file), lfile);
strcpy(&file[len - 9], ".ext");
LoadAutoExtension(file);
@@ -591,7 +541,7 @@ IExtension *CExtensionManager::LoadAutoExtension(const char *path, bool bErrorOn
if (strcmp(ext, PLATFORM_LIB_EXT) == 0)
{
char path2[PLATFORM_MAX_PATH];
ke::SafeSprintf(path2, sizeof(path2), "%s", path);
ke::SafeStrcpy(path2, sizeof(path2), path);
path2[strlen(path) - strlen(PLATFORM_LIB_EXT) - 1] = '\0';
return LoadAutoExtension(path2, bErrorOnMissing);
}
@@ -683,7 +633,7 @@ IExtension *CExtensionManager::LoadExtension(const char *file, char *error, size
if (strcmp(ext, PLATFORM_LIB_EXT) == 0)
{
char path2[PLATFORM_MAX_PATH];
ke::SafeSprintf(path2, sizeof(path2), "%s", file);
ke::SafeStrcpy(path2, sizeof(path2), file);
path2[strlen(file) - strlen(PLATFORM_LIB_EXT) - 1] = '\0';
return LoadExtension(path2, error, maxlength);
}
@@ -1136,7 +1086,7 @@ void CExtensionManager::OnRootConsoleCommand(const char *cmdname, const ICommand
if (pExt->unload_code == (unsigned)atoi(unload))
{
char filename[PLATFORM_MAX_PATH];
snprintf(filename, PLATFORM_MAX_PATH, "%s", pExt->GetFilename());
ke::SafeStrcpy(filename, PLATFORM_MAX_PATH, pExt->GetFilename());
UnloadExtension(pExt);
rootmenu->ConsolePrint("[SM] Extension %s is now unloaded.", filename);
}
@@ -1151,7 +1101,7 @@ void CExtensionManager::OnRootConsoleCommand(const char *cmdname, const ICommand
|| (!pExt->m_ChildDeps.size() && !pExt->m_Dependents.size()))
{
char filename[PLATFORM_MAX_PATH];
snprintf(filename, PLATFORM_MAX_PATH, "%s", pExt->GetFilename());
ke::SafeStrcpy(filename, PLATFORM_MAX_PATH, pExt->GetFilename());
UnloadExtension(pExt);
rootmenu->ConsolePrint("[SM] Extension %s is now unloaded.", filename);
return;
@@ -1252,7 +1202,7 @@ void CExtensionManager::OnRootConsoleCommand(const char *cmdname, const ICommand
char filename[PLATFORM_MAX_PATH];
char error[255];
snprintf(filename, PLATFORM_MAX_PATH, "%s", pExt->GetFilename());
ke::SafeStrcpy(filename, PLATFORM_MAX_PATH, pExt->GetFilename());
if (pExt->Reload(error, sizeof(error)))
{
+43 -16
View File
@@ -66,26 +66,33 @@ static const char *g_pParseEngine = NULL;
#define PSTATE_GAMEDEFS_OFFSETS 3
#define PSTATE_GAMEDEFS_OFFSETS_OFFSET 4
#define PSTATE_GAMEDEFS_KEYS 5
#define PSTATE_GAMEDEFS_SUPPORTED 6
#define PSTATE_GAMEDEFS_SIGNATURES 7
#define PSTATE_GAMEDEFS_SIGNATURES_SIG 8
#define PSTATE_GAMEDEFS_CRC 9
#define PSTATE_GAMEDEFS_CRC_BINARY 10
#define PSTATE_GAMEDEFS_CUSTOM 11
#define PSTATE_GAMEDEFS_ADDRESSES 12
#define PSTATE_GAMEDEFS_ADDRESSES_ADDRESS 13
#define PSTATE_GAMEDEFS_ADDRESSES_ADDRESS_READ 14
#define PSTATE_GAMEDEFS_KEYS_PLATFORM 6
#define PSTATE_GAMEDEFS_SUPPORTED 7
#define PSTATE_GAMEDEFS_SIGNATURES 8
#define PSTATE_GAMEDEFS_SIGNATURES_SIG 9
#define PSTATE_GAMEDEFS_CRC 10
#define PSTATE_GAMEDEFS_CRC_BINARY 11
#define PSTATE_GAMEDEFS_CUSTOM 12
#define PSTATE_GAMEDEFS_ADDRESSES 13
#define PSTATE_GAMEDEFS_ADDRESSES_ADDRESS 14
#define PSTATE_GAMEDEFS_ADDRESSES_ADDRESS_READ 15
#if defined PLATFORM_X86
#define PLATFORM_ARCH_SUFFIX ""
#elif defined PLATFORM_X64
#define PLATFORM_ARCH_SUFFIX "64"
#endif
#if defined PLATFORM_WINDOWS
#define PLATFORM_NAME "windows"
#define PLATFORM_NAME "windows" PLATFORM_ARCH_SUFFIX
#define PLATFORM_SERVER_BINARY "server.dll"
#elif defined PLATFORM_LINUX
#define PLATFORM_NAME "linux"
#define PLATFORM_COMPAT_ALT "mac" /* Alternate platform name if game data is missing for primary one */
#define PLATFORM_NAME "linux" PLATFORM_ARCH_SUFFIX
#define PLATFORM_COMPAT_ALT "mac" PLATFORM_ARCH_SUFFIX /* Alternate platform name if game data is missing for primary one */
#define PLATFORM_SERVER_BINARY "server_i486.so"
#elif defined PLATFORM_APPLE
#define PLATFORM_NAME "mac"
#define PLATFORM_COMPAT_ALT "linux"
#define PLATFORM_NAME "mac" PLATFORM_ARCH_SUFFIX
#define PLATFORM_COMPAT_ALT "linux" PLATFORM_ARCH_SUFFIX
#define PLATFORM_SERVER_BINARY "server.dylib"
#endif
@@ -252,6 +259,13 @@ SMCResult CGameConfig::ReadSMC_NewSection(const SMCStates *states, const char *n
}
break;
}
case PSTATE_GAMEDEFS_KEYS:
{
strncopy(m_Key, name, sizeof(m_Key));
m_ParseState = PSTATE_GAMEDEFS_KEYS_PLATFORM;
matched_platform = false;
break;
}
case PSTATE_GAMEDEFS_OFFSETS:
{
m_Prop[0] = '\0';
@@ -338,7 +352,8 @@ SMCResult CGameConfig::ReadSMC_NewSection(const SMCStates *states, const char *n
}
else
{
if (strcmp(name, "linux") != 0 && strcmp(name, "windows") != 0 && strcmp(name, "mac") != 0)
if (strcmp(name, "linux") != 0 && strcmp(name, "windows") != 0 && strcmp(name, "mac") != 0 &&
strcmp(name, "linux64") != 0 && strcmp(name, "windows64") != 0 && strcmp(name, "mac64") != 0)
{
logger->LogError("[SM] Error while parsing Address section for \"%s\" (%s):", m_Address, m_CurFile);
logger->LogError("[SM] Unrecognized platform \"%s\"", name);
@@ -349,7 +364,7 @@ SMCResult CGameConfig::ReadSMC_NewSection(const SMCStates *states, const char *n
}
/* No sub-sections allowed:
case PSTATE_GAMEDEFS_OFFSETS_OFFSET:
case PSTATE_GAMEDEFS_KEYS:
case PSTATE_GAMEDEFS_KEYS_PLATFORM:
case PSTATE_GAMEDEFS_SUPPORTED:
case PSTATE_GAMEDEFS_SIGNATURES_SIG:
case PSTATE_GAMEDEFS_CRC_BINARY:
@@ -386,6 +401,13 @@ SMCResult CGameConfig::ReadSMC_KeyValue(const SMCStates *states, const char *key
} else if (m_ParseState == PSTATE_GAMEDEFS_KEYS) {
ke::AString vstr(value);
m_Keys.replace(key, ke::Move(vstr));
}
else if (m_ParseState == PSTATE_GAMEDEFS_KEYS_PLATFORM) {
if (IsPlatformCompatible(key, &matched_platform))
{
ke::AString vstr(value);
m_Keys.replace(m_Key, ke::Move(vstr));
}
} else if (m_ParseState == PSTATE_GAMEDEFS_SUPPORTED) {
if (strcmp(key, "game") == 0)
{
@@ -499,6 +521,11 @@ SMCResult CGameConfig::ReadSMC_LeavingSection(const SMCStates *states)
m_ParseState = PSTATE_GAMEDEFS;
break;
}
case PSTATE_GAMEDEFS_KEYS_PLATFORM:
{
m_ParseState = PSTATE_GAMEDEFS_KEYS;
break;
}
case PSTATE_GAMEDEFS_OFFSETS_OFFSET:
{
/* Parse the offset... */
+1
View File
@@ -90,6 +90,7 @@ private:
char m_Prop[64];
char m_offset[64];
char m_Game[256];
char m_Key[64];
bool bShouldBeReadingDefault;
bool had_game;
bool matched_game;
+1
View File
@@ -35,6 +35,7 @@
#include <IHandleSys.h>
#include <stdio.h>
#include <sm_namehashset.h>
#include <amtl/am-autoptr.h>
#include <amtl/am-string.h>
#include <amtl/am-function.h>
#include "common_logic.h"
+11 -7
View File
@@ -66,7 +66,7 @@ CDirectory::CDirectory(const char *path)
{
#if defined PLATFORM_WINDOWS
char newpath[PLATFORM_MAX_PATH];
snprintf(newpath, sizeof(newpath), "%s\\*.*", path);
ke::SafeSprintf(newpath, sizeof(newpath), "%s\\*.*", path);
m_dir = FindFirstFileA(newpath, &m_fd);
if (!IsValid())
{
@@ -78,7 +78,7 @@ CDirectory::CDirectory(const char *path)
{
/* :TODO: we need to read past "." and ".."! */
ep = readdir(m_dir);
snprintf(m_origpath, PLATFORM_MAX_PATH, "%s", path);
ke::SafeStrcpy(m_origpath, PLATFORM_MAX_PATH, path);
} else {
ep = NULL;
}
@@ -125,7 +125,9 @@ bool CDirectory::IsEntryDirectory()
return ((m_fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY);
#elif defined PLATFORM_POSIX
char temppath[PLATFORM_MAX_PATH];
snprintf(temppath, sizeof(temppath), "%s/%s", m_origpath, GetEntryName());
int ret = ke::SafeSprintf(temppath, sizeof(temppath), "%s/%s", m_origpath, GetEntryName());
if (static_cast<size_t>(ret) >= sizeof(temppath))
return false;
return ke::file::IsDirectory(temppath);
#endif
}
@@ -136,7 +138,9 @@ bool CDirectory::IsEntryFile()
return !(m_fd.dwFileAttributes & (FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_DEVICE));
#elif defined PLATFORM_POSIX
char temppath[PLATFORM_MAX_PATH];
snprintf(temppath, sizeof(temppath), "%s/%s", m_origpath, GetEntryName());
int ret = ke::SafeSprintf(temppath, sizeof(temppath), "%s/%s", m_origpath, GetEntryName());
if (static_cast<size_t>(ret) >= sizeof(temppath))
return false;
return ke::file::IsFile(temppath);
#endif
}
@@ -226,7 +230,7 @@ void LibrarySystem::GetPlatformErrorEx(int code, char *error, size_t maxlength)
const char *ae = strerror_r(code, error, maxlength);
if (ae != error)
{
ke::SafeSprintf(error, maxlength, "%s", ae);
ke::SafeStrcpy(error, maxlength, ae);
}
#elif defined PLATFORM_POSIX
strerror_r(code, error, maxlength);
@@ -305,12 +309,12 @@ size_t LibrarySystem::GetFileFromPath(char *buffer, size_t maxlength, const char
#endif
)
{
return ke::SafeSprintf(buffer, maxlength, "%s", &path[i+1]);
return ke::SafeStrcpy(buffer, maxlength, &path[i+1]);
}
}
/* We scanned and found no path separator */
return ke::SafeSprintf(buffer, maxlength, "%s", path);
return ke::SafeStrcpy(buffer, maxlength, path);
}
bool LibrarySystem::FileTime(const char *path, FileTimeType type, time_t *pTime)
+188 -288
View File
@@ -40,10 +40,6 @@
Logger g_Logger;
/**
* :TODO: This should be creating the log folder if it doesn't exist
*/
ConfigResult Logger::OnSourceModConfigChanged(const char *key,
const char *value,
ConfigSource source,
@@ -60,7 +56,7 @@ ConfigResult Logger::OnSourceModConfigChanged(const char *key,
} else if (strcasecmp(value, "off") == 0) {
state = false;
} else {
ke::SafeSprintf(error, maxlength, "Invalid value: must be \"on\" or \"off\"");
ke::SafeStrcpy(error, maxlength, "Invalid value: must be \"on\" or \"off\"");
return ConfigResult_Reject;
}
@@ -68,7 +64,7 @@ ConfigResult Logger::OnSourceModConfigChanged(const char *key,
{
state ? EnableLogging() : DisableLogging();
} else {
m_InitialState = state;
m_Active = state;
}
return ConfigResult_Accept;
@@ -81,7 +77,7 @@ ConfigResult Logger::OnSourceModConfigChanged(const char *key,
} else if (strcasecmp(value, "game") == 0) {
m_Mode = LoggingMode_Game;
} else {
ke::SafeSprintf(error, maxlength, "Invalid value: must be [daily|map|game]");
ke::SafeStrcpy(error, maxlength, "Invalid value: must be [daily|map|game]");
return ConfigResult_Reject;
}
@@ -93,7 +89,12 @@ ConfigResult Logger::OnSourceModConfigChanged(const char *key,
void Logger::OnSourceModStartup(bool late)
{
InitLogger(m_Mode);
char buff[PLATFORM_MAX_PATH];
g_pSM->BuildPath(Path_SM, buff, sizeof(buff), "logs");
if (!libsys->IsPathDirectory(buff))
{
libsys->CreateFolder(buff);
}
}
void Logger::OnSourceModAllShutdown()
@@ -103,127 +104,7 @@ void Logger::OnSourceModAllShutdown()
void Logger::OnSourceModLevelChange(const char *mapName)
{
MapChange(mapName);
}
void Logger::_NewMapFile()
{
if (!m_Active)
{
return;
}
/* Append "Log file closed" to previous log file */
_CloseFile();
char _filename[256];
int i = 0;
time_t t = g_pSM->GetAdjustedTime();
tm *curtime = localtime(&t);
while (true)
{
g_pSM->BuildPath(Path_SM, _filename, sizeof(_filename), "logs/L%02d%02d%03d.log", curtime->tm_mon + 1, curtime->tm_mday, i);
FILE *fp = fopen(_filename, "r");
if (!fp)
{
break;
}
fclose(fp);
i++;
}
m_NrmFileName.assign(_filename);
FILE *fp = fopen(m_NrmFileName.c_str(), "w");
if (!fp)
{
char error[255];
libsys->GetPlatformError(error, sizeof(error));
LogFatal("[SM] Unexpected fatal logging error (file \"%s\")", m_NrmFileName.c_str());
LogFatal("[SM] Platform returned error: \"%s\"", error);
LogFatal("[SM] Logging has been disabled.");
m_Active = false;
return;
} else {
char date[32];
strftime(date, sizeof(date), "%m/%d/%Y - %H:%M:%S", curtime);
fprintf(fp, "L %s: SourceMod log file started (file \"L%02d%02d%03d.log\") (Version \"%s\")\n", date, curtime->tm_mon + 1, curtime->tm_mday, i, SOURCEMOD_VERSION);
fclose(fp);
}
}
void Logger::_CloseFile()
{
if (!m_Active)
{
return;
}
FILE *fp = NULL;
if (!m_NrmFileName.empty())
{
fp = fopen(m_NrmFileName.c_str(), "r+");
if (fp)
{
fseek(fp, 0, SEEK_END);
LogMessage("Log file closed.");
fclose(fp);
}
m_NrmFileName.clear();
}
if (!m_ErrMapStart)
{
return;
}
fp = fopen(m_ErrFileName.c_str(), "r+");
if (fp)
{
fseek(fp, 0, SEEK_END);
LogError("Error log file session closed.");
fclose(fp);
}
m_ErrFileName.clear();
}
void Logger::InitLogger(LoggingMode mode)
{
m_Mode = mode;
m_Active = m_InitialState;
time_t t = g_pSM->GetAdjustedTime();
tm *curtime = localtime(&t);
m_NrmCurDay = curtime->tm_mday;
m_ErrCurDay = curtime->tm_mday;
char _filename[256];
g_pSM->BuildPath(Path_SM, _filename, sizeof(_filename), "logs/errors_%04d%02d%02d.log", curtime->tm_year + 1900, curtime->tm_mon + 1, curtime->tm_mday);
m_ErrFileName.assign(_filename);
switch (m_Mode)
{
case LoggingMode_PerMap:
{
if (!m_Active)
{
m_DelayedStart = true;
}
break;
}
case LoggingMode_Daily:
{
g_pSM->BuildPath(Path_SM, _filename, sizeof(_filename), "logs/L%04d%02d%02d.log", curtime->tm_year + 1900, curtime->tm_mon + 1, curtime->tm_mday);
m_NrmFileName.assign(_filename);
m_DailyPrintHdr = true;
break;
}
default:
{
/* do nothing... */
break;
}
}
_MapChange(mapName);
}
void Logger::CloseLogger()
@@ -231,6 +112,13 @@ void Logger::CloseLogger()
_CloseFile();
}
void Logger::_CloseFile()
{
_CloseNormal();
_CloseError();
_CloseFatal();
}
void Logger::LogToOpenFile(FILE *fp, const char *msg, ...)
{
if (!m_Active)
@@ -259,11 +147,6 @@ void Logger::LogToFileOnly(FILE *fp, const char *msg, ...)
void Logger::LogToOpenFileEx(FILE *fp, const char *msg, va_list ap)
{
if (!m_Active)
{
return;
}
static ConVar *sv_logecho = bridge->FindConVar("sv_logecho");
char buffer[3072];
@@ -282,15 +165,12 @@ void Logger::LogToOpenFileEx(FILE *fp, const char *msg, va_list ap)
ke::SafeSprintf(conBuffer, sizeof(conBuffer), "L %s: %s\n", date, buffer);
bridge->ConPrint(conBuffer);
}
fflush(fp);
}
void Logger::LogToFileOnlyEx(FILE *fp, const char *msg, va_list ap)
{
if (!m_Active)
{
return;
}
char buffer[3072];
ke::SafeVsprintf(buffer, sizeof(buffer), msg, ap);
@@ -298,8 +178,8 @@ void Logger::LogToFileOnlyEx(FILE *fp, const char *msg, va_list ap)
time_t t = g_pSM->GetAdjustedTime();
tm *curtime = localtime(&t);
strftime(date, sizeof(date), "%m/%d/%Y - %H:%M:%S", curtime);
fprintf(fp, "L %s: %s\n", date, buffer);
fflush(fp);
}
@@ -324,63 +204,14 @@ void Logger::LogMessageEx(const char *vafmt, va_list ap)
return;
}
if (m_DelayedStart)
FILE *pFile = _OpenNormal();
if (!pFile)
{
m_DelayedStart = false;
_NewMapFile();
return;
}
time_t t = g_pSM->GetAdjustedTime();
tm *curtime = localtime(&t);
FILE *fp = NULL;
if (m_Mode == LoggingMode_PerMap)
{
fp = fopen(m_NrmFileName.c_str(), "a+");
if (!fp)
{
_NewMapFile();
fp = fopen(m_NrmFileName.c_str(), "a+");
if (!fp)
{
goto print_error;
}
}
} else {
if (m_NrmCurDay != curtime->tm_mday)
{
char _filename[256];
g_pSM->BuildPath(Path_SM, _filename, sizeof(_filename), "logs/L%04d%02d%02d.log", curtime->tm_year + 1900, curtime->tm_mon + 1, curtime->tm_mday);
m_NrmFileName.assign(_filename);
m_NrmCurDay = curtime->tm_mday;
m_DailyPrintHdr = true;
}
fp = fopen(m_NrmFileName.c_str(), "a+");
}
if (fp)
{
if (m_DailyPrintHdr)
{
char date[32];
m_DailyPrintHdr = false;
strftime(date, sizeof(date), "%m/%d/%Y - %H:%M:%S", curtime);
fprintf(fp, "L %s: SourceMod log file session started (file \"L%04d%02d%02d.log\") (Version \"%s\")\n", date, curtime->tm_year + 1900, curtime->tm_mon + 1, curtime->tm_mday, SOURCEMOD_VERSION);
}
LogToOpenFileEx(fp, vafmt, ap);
fclose(fp);
} else {
goto print_error;
}
return;
print_error:
char error[255];
libsys->GetPlatformError(error, sizeof(error));
LogFatal("[SM] Unexpected fatal logging error (file \"%s\")", m_NrmFileName.c_str());
LogFatal("[SM] Platform returned error: \"%s\"", error);
LogFatal("[SM] Logging has been disabled.");
m_Active = false;
LogToOpenFileEx(pFile, vafmt, ap);
fclose(pFile);
}
void Logger::LogError(const char *vafmt, ...)
@@ -398,72 +229,20 @@ void Logger::LogErrorEx(const char *vafmt, va_list ap)
return;
}
time_t t = g_pSM->GetAdjustedTime();
tm *curtime = localtime(&t);
if (curtime->tm_mday != m_ErrCurDay)
FILE *pFile = _OpenError();
if (!pFile)
{
char _filename[256];
g_pSM->BuildPath(Path_SM, _filename, sizeof(_filename), "logs/errors_%04d%02d%02d.log", curtime->tm_year + 1900, curtime->tm_mon + 1, curtime->tm_mday);
m_ErrFileName.assign(_filename);
m_ErrCurDay = curtime->tm_mday;
m_ErrMapStart = false;
}
FILE *fp = fopen(m_ErrFileName.c_str(), "a+");
if (fp)
{
if (!m_ErrMapStart)
{
char date[32];
strftime(date, sizeof(date), "%m/%d/%Y - %H:%M:%S", curtime);
fprintf(fp, "L %s: SourceMod error session started\n", date);
fprintf(fp, "L %s: Info (map \"%s\") (file \"errors_%04d%02d%02d.log\")\n", date, m_CurMapName.c_str(), curtime->tm_year + 1900, curtime->tm_mon + 1, curtime->tm_mday);
m_ErrMapStart = true;
}
LogToOpenFileEx(fp, vafmt, ap);
fclose(fp);
}
else
{
char error[255];
libsys->GetPlatformError(error, sizeof(error));
LogFatal("[SM] Unexpected fatal logging error (file \"%s\")", m_NrmFileName.c_str());
LogFatal("[SM] Platform returned error: \"%s\"", error);
LogFatal("[SM] Logging has been disabled.");
m_Active = false;
return;
}
LogToOpenFileEx(pFile, vafmt, ap);
fclose(pFile);
}
void Logger::MapChange(const char *mapname)
void Logger::_MapChange(const char *mapname)
{
m_CurMapName.assign(mapname);
switch (m_Mode)
{
case LoggingMode_Daily:
{
LogMessage("-------- Mapchange to %s --------", mapname);
break;
}
case LoggingMode_PerMap:
{
_NewMapFile();
break;
}
default:
{
/* Do nothing... */
break;
}
}
if (m_ErrMapStart)
{
LogError("Error log file session closed.");
}
m_ErrMapStart = false;
m_CurrentMapName = mapname;
_UpdateFiles(true);
}
void Logger::_PrintToGameLog(const char *fmt, va_list ap)
@@ -480,30 +259,6 @@ void Logger::_PrintToGameLog(const char *fmt, va_list ap)
bridge->LogToGame(msg);
}
const char *Logger::GetLogFileName(LogType type) const
{
switch (type)
{
case LogType_Normal:
{
return m_NrmFileName.c_str();
}
case LogType_Error:
{
return m_ErrFileName.c_str();
}
default:
{
return "";
}
}
}
LoggingMode Logger::GetLoggingMode() const
{
return m_Mode;
}
void Logger::EnableLogging()
{
if (m_Active)
@@ -539,16 +294,161 @@ void Logger::LogFatalEx(const char *msg, va_list ap)
* It's already implemented twice which is bad.
*/
char path[PLATFORM_MAX_PATH];
g_pSM->BuildPath(Path_Game, path, sizeof(path), "sourcemod_fatal.log");
FILE *fp = fopen(path, "at");
if (fp)
FILE *pFile = _OpenFatal();
if (!pFile)
{
m_Active = true;
LogToOpenFileEx(fp, msg, ap);
m_Active = false;
fclose(fp);
return;
}
LogToOpenFileEx(pFile, msg, ap);
fclose(pFile);
}
void Logger::_UpdateFiles(bool bLevelChange)
{
time_t t = g_pSM->GetAdjustedTime();
tm *curtime = localtime(&t);
if (!bLevelChange && curtime->tm_mday == m_Day)
{
return;
}
m_Day = curtime->tm_mday;
char buff[PLATFORM_MAX_PATH];
ke::SafeSprintf(buff, sizeof(buff), "%04d%02d%02d", curtime->tm_year + 1900, curtime->tm_mon + 1, curtime->tm_mday);
ke::AString currentDate(buff);
if (m_Mode == LoggingMode_PerMap)
{
if (bLevelChange)
{
for (size_t iter = 0; iter < static_cast<size_t>(-1); ++iter)
{
g_pSM->BuildPath(Path_SM, buff, sizeof(buff), "logs/L%s%u.log", currentDate.chars(), iter);
if (!libsys->IsPathFile(buff))
{
break;
}
}
}
else
{
ke::SafeStrcpy(buff, sizeof(buff), m_NormalFileName.chars());
}
}
else
{
g_pSM->BuildPath(Path_SM, buff, sizeof(buff), "logs/L%s.log", currentDate.chars());
}
if (m_NormalFileName.compare(buff))
{
_CloseNormal();
m_NormalFileName = buff;
}
else
{
if (bLevelChange)
{
LogMessage("-------- Mapchange to %s --------", m_CurrentMapName.chars());
}
}
g_pSM->BuildPath(Path_SM, buff, sizeof(buff), "logs/errors_%s.log", currentDate.chars());
if (bLevelChange || m_ErrorFileName.compare(buff))
{
_CloseError();
m_ErrorFileName = buff;
}
}
FILE *Logger::_OpenNormal()
{
_UpdateFiles();
FILE *pFile = fopen(m_NormalFileName.chars(), "a+");
if (pFile == NULL)
{
_LogFatalOpen(m_NormalFileName);
return pFile;
}
if (!m_DamagedNormalFile)
{
time_t t = g_pSM->GetAdjustedTime();
tm *curtime = localtime(&t);
char date[32];
strftime(date, sizeof(date), "%m/%d/%Y - %H:%M:%S", curtime);
fprintf(pFile, "L %s: SourceMod log file session started (file \"%s\") (Version \"%s\")\n", date, m_NormalFileName.chars(), SOURCEMOD_VERSION);
m_DamagedNormalFile = true;
}
return pFile;
}
FILE *Logger::_OpenError()
{
_UpdateFiles();
FILE *pFile = fopen(m_ErrorFileName.chars(), "a+");
if (pFile == NULL)
{
_LogFatalOpen(m_ErrorFileName);
return pFile;
}
if (!m_DamagedErrorFile)
{
time_t t = g_pSM->GetAdjustedTime();
tm *curtime = localtime(&t);
char date[32];
strftime(date, sizeof(date), "%m/%d/%Y - %H:%M:%S", curtime);
fprintf(pFile, "L %s: SourceMod error session started\n", date);
fprintf(pFile, "L %s: Info (map \"%s\") (file \"%s\")\n", date, m_CurrentMapName.chars(), m_ErrorFileName.chars());
m_DamagedErrorFile = true;
}
return pFile;
}
FILE *Logger::_OpenFatal()
{
char path[PLATFORM_MAX_PATH];
g_pSM->BuildPath(Path_Game, path, sizeof(path), "sourcemod_fatal.log");
return fopen(path, "at");
}
void Logger::_LogFatalOpen(ke::AString &str)
{
char error[255];
libsys->GetPlatformError(error, sizeof(error));
LogFatal("[SM] Unexpected fatal logging error (file \"%s\")", str.chars());
LogFatal("[SM] Platform returned error: \"%s\"", error);
}
void Logger::_CloseNormal()
{
if (m_DamagedNormalFile)
{
LogMessage("Log file closed.");
m_DamagedNormalFile = false;
}
}
void Logger::_CloseError()
{
if (m_DamagedErrorFile)
{
LogError("Error log file session closed.");
m_DamagedErrorFile = false;
}
}
void Logger::_CloseFatal()
{
}
+22 -20
View File
@@ -34,11 +34,9 @@
#include "common_logic.h"
#include <stdio.h>
#include <sh_string.h>
#include <amtl/am-string.h>
#include <bridge/include/ILogger.h>
using namespace SourceHook;
enum LogType
{
LogType_Normal,
@@ -55,9 +53,7 @@ enum LoggingMode
class Logger : public SMGlobalClass, public ILogger
{
public:
Logger() : m_Mode(LoggingMode_Daily), m_ErrMapStart(false),
m_Active(false), m_DelayedStart(false), m_DailyPrintHdr(false),
m_InitialState(true)
Logger() : m_Day(-1), m_Mode(LoggingMode_Daily), m_Active(true), m_DamagedNormalFile(false), m_DamagedErrorFile(false)
{
}
public: //SMGlobalClass
@@ -70,7 +66,6 @@ public: //SMGlobalClass
void OnSourceModAllShutdown();
void OnSourceModLevelChange(const char *mapName);
public:
void InitLogger(LoggingMode mode);
void CloseLogger();
void EnableLogging();
void DisableLogging();
@@ -85,25 +80,32 @@ public:
/* This version does not print to console, and is thus thread-safe */
void LogToFileOnly(FILE *fp, const char *msg, ...);
void LogToFileOnlyEx(FILE *fp, const char *msg, va_list ap);
void MapChange(const char *mapname);
const char *GetLogFileName(LogType type) const;
LoggingMode GetLoggingMode() const;
private:
void _MapChange(const char *mapname);
void _CloseFile();
void _NewMapFile();
void _CloseNormal();
void _CloseError();
void _CloseFatal();
FILE *_OpenNormal();
FILE *_OpenError();
FILE *_OpenFatal();
void _LogFatalOpen(ke::AString &str);
void _PrintToGameLog(const char *fmt, va_list ap);
void _UpdateFiles(bool bLevelChange = false);
private:
String m_NrmFileName;
String m_ErrFileName;
String m_CurMapName;
ke::AString m_NormalFileName;
ke::AString m_ErrorFileName;
ke::AString m_CurrentMapName;
int m_Day;
LoggingMode m_Mode;
int m_NrmCurDay;
int m_ErrCurDay;
bool m_ErrMapStart;
bool m_Active;
bool m_DelayedStart;
bool m_DailyPrintHdr;
bool m_InitialState;
bool m_DamagedNormalFile;
bool m_DamagedErrorFile;
};
extern Logger g_Logger;
+112 -76
View File
@@ -43,18 +43,6 @@
#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;
@@ -63,25 +51,10 @@ 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;
}
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;
#endif
}
@@ -147,13 +120,25 @@ void *MemoryUtils::ResolveSymbol(void *handle, const char *symbol)
#elif defined PLATFORM_LINUX
#ifdef PLATFORM_X86
typedef Elf32_Ehdr ElfHeader;
typedef Elf32_Shdr ElfSHeader;
typedef Elf32_Sym ElfSymbol;
#define ELF_SYM_TYPE ELF32_ST_TYPE
#else
typedef Elf64_Ehdr ElfHeader;
typedef Elf64_Shdr ElfSHeader;
typedef Elf64_Sym ElfSymbol;
#define ELF_SYM_TYPE ELF64_ST_TYPE
#endif
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;
ElfHeader *file_hdr;
ElfSHeader *sections, *shstrtab_hdr, *symtab_hdr, *strtab_hdr;
ElfSymbol *symtab;
const char *shstrtab, *strtab;
uint16_t section_count;
uint32_t symbol_count;
@@ -204,7 +189,7 @@ void *MemoryUtils::ResolveSymbol(void *handle, const char *symbol)
}
/* Map library file into memory */
file_hdr = (Elf32_Ehdr *)mmap(NULL, dlstat.st_size, PROT_READ, MAP_PRIVATE, dlfile, 0);
file_hdr = (ElfHeader *)mmap(NULL, dlstat.st_size, PROT_READ, MAP_PRIVATE, dlfile, 0);
map_base = (uintptr_t)file_hdr;
if (file_hdr == MAP_FAILED)
{
@@ -219,7 +204,7 @@ void *MemoryUtils::ResolveSymbol(void *handle, const char *symbol)
return NULL;
}
sections = (Elf32_Shdr *)(map_base + file_hdr->e_shoff);
sections = (ElfSHeader *)(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];
@@ -228,7 +213,7 @@ void *MemoryUtils::ResolveSymbol(void *handle, const char *symbol)
/* 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];
ElfSHeader &hdr = sections[i];
const char *section_name = shstrtab + hdr.sh_name;
if (strcmp(section_name, ".symtab") == 0)
@@ -248,15 +233,15 @@ void *MemoryUtils::ResolveSymbol(void *handle, const char *symbol)
return NULL;
}
symtab = (Elf32_Sym *)(map_base + symtab_hdr->sh_offset);
symtab = (ElfSymbol *)(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);
ElfSymbol &sym = symtab[i];
unsigned char sym_type = ELF_SYM_TYPE(sym.st_info);
const char *sym_name = strtab + sym.st_name;
Symbol *cur_sym;
@@ -280,14 +265,29 @@ void *MemoryUtils::ResolveSymbol(void *handle, const char *symbol)
return symbol_entry ? symbol_entry->address : NULL;
#elif defined PLATFORM_APPLE
#ifdef PLATFORM_X86
typedef struct mach_header MachHeader;
typedef struct segment_command MachSegment;
typedef struct nlist MachSymbol;
const uint32_t MACH_LOADCMD_SEGMENT = LC_SEGMENT;
#else
typedef struct mach_header_64 MachHeader;
typedef struct segment_command_64 MachSegment;
typedef struct nlist_64 MachSymbol;
const uint32_t MACH_LOADCMD_SEGMENT = LC_SEGMENT_64;
#endif
typedef struct load_command MachLoadCmd;
typedef struct symtab_command MachSymHeader;
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;
MachHeader *file_hdr;
MachLoadCmd *loadcmds;
MachSegment *linkedit_hdr;
MachSymHeader *symtab_hdr;
MachSymbol *symtab;
const char *strtab;
uint32_t loadcmd_count;
uint32_t symbol_count;
@@ -357,16 +357,16 @@ void *MemoryUtils::ResolveSymbol(void *handle, const char *symbol)
/* 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));
file_hdr = (MachHeader *)dlbase;
loadcmds = (MachLoadCmd *)(dlbase + sizeof(MachHeader));
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)
if (loadcmds->cmd == MACH_LOADCMD_SEGMENT && !linkedit_hdr)
{
struct segment_command *seg = (struct segment_command *)loadcmds;
MachSegment *seg = (MachSegment *)loadcmds;
if (strcmp(seg->segname, "__LINKEDIT") == 0)
{
linkedit_hdr = seg;
@@ -378,7 +378,7 @@ void *MemoryUtils::ResolveSymbol(void *handle, const char *symbol)
}
else if (loadcmds->cmd == LC_SYMTAB)
{
symtab_hdr = (struct symtab_command *)loadcmds;
symtab_hdr = (MachSymHeader *)loadcmds;
if (linkedit_hdr)
{
break;
@@ -386,7 +386,7 @@ void *MemoryUtils::ResolveSymbol(void *handle, const char *symbol)
}
/* Load commands are not of a fixed size which is why we add the size */
loadcmds = (struct load_command *)((uintptr_t)loadcmds + loadcmds->cmdsize);
loadcmds = (MachLoadCmd *)((uintptr_t)loadcmds + loadcmds->cmdsize);
}
if (!linkedit_hdr || !symtab_hdr || !symtab_hdr->symoff || !symtab_hdr->stroff)
@@ -396,14 +396,14 @@ void *MemoryUtils::ResolveSymbol(void *handle, const char *symbol)
}
linkedit_addr = dlbase + linkedit_hdr->vmaddr;
symtab = (struct nlist *)(linkedit_addr + symtab_hdr->symoff - linkedit_hdr->fileoff);
symtab = (MachSymbol *)(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];
MachSymbol &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;
@@ -440,6 +440,12 @@ bool MemoryUtils::GetLibraryInfo(const void *libPtr, DynLibInfo &lib)
#ifdef PLATFORM_WINDOWS
#ifdef PLATFORM_X86
const WORD PE_FILE_MACHINE = IMAGE_FILE_MACHINE_I386;
#else
const WORD PE_FILE_MACHINE = IMAGE_FILE_MACHINE_AMD64;
#endif
MEMORY_BASIC_INFORMATION info;
IMAGE_DOS_HEADER *dos;
IMAGE_NT_HEADERS *pe;
@@ -465,10 +471,8 @@ bool MemoryUtils::GetLibraryInfo(const void *libPtr, DynLibInfo &lib)
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)
/* Check architecture */
if (file->Machine != PE_FILE_MACHINE)
{
return false;
}
@@ -484,9 +488,21 @@ bool MemoryUtils::GetLibraryInfo(const void *libPtr, DynLibInfo &lib)
#elif defined PLATFORM_LINUX
#ifdef PLATFORM_X86
typedef Elf32_Ehdr ElfHeader;
typedef Elf32_Phdr ElfPHeader;
const unsigned char ELF_CLASS = ELFCLASS32;
const uint16_t ELF_MACHINE = EM_386;
#else
typedef Elf64_Ehdr ElfHeader;
typedef Elf64_Phdr ElfPHeader;
const unsigned char ELF_CLASS = ELFCLASS64;
const uint16_t ELF_MACHINE = EM_X86_64;
#endif
Dl_info info;
Elf32_Ehdr *file;
Elf32_Phdr *phdr;
ElfHeader *file;
ElfPHeader *phdr;
uint16_t phdrCount;
if (!dladdr(libPtr, &info))
@@ -501,7 +517,7 @@ bool MemoryUtils::GetLibraryInfo(const void *libPtr, DynLibInfo &lib)
/* This is for our insane sanity checks :o */
baseAddr = reinterpret_cast<uintptr_t>(info.dli_fbase);
file = reinterpret_cast<Elf32_Ehdr *>(baseAddr);
file = reinterpret_cast<ElfHeader *>(baseAddr);
/* Check ELF magic */
if (memcmp(ELFMAG, file->e_ident, SELFMAG) != 0)
@@ -514,11 +530,15 @@ bool MemoryUtils::GetLibraryInfo(const void *libPtr, DynLibInfo &lib)
{
return false;
}
/* Check ELF endianness */
if (file->e_ident[EI_DATA] != ELFDATA2LSB)
{
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)
/* Check ELF architecture */
if (file->e_ident[EI_CLASS] != ELF_CLASS || file->e_machine != ELF_MACHINE)
{
return false;
}
@@ -530,11 +550,11 @@ bool MemoryUtils::GetLibraryInfo(const void *libPtr, DynLibInfo &lib)
}
phdrCount = file->e_phnum;
phdr = reinterpret_cast<Elf32_Phdr *>(baseAddr + file->e_phoff);
phdr = reinterpret_cast<ElfPHeader *>(baseAddr + file->e_phoff);
for (uint16_t i = 0; i < phdrCount; i++)
{
Elf32_Phdr &hdr = phdr[i];
ElfPHeader &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))
@@ -553,9 +573,25 @@ bool MemoryUtils::GetLibraryInfo(const void *libPtr, DynLibInfo &lib)
#elif defined PLATFORM_APPLE
#ifdef PLATFORM_X86
typedef struct mach_header MachHeader;
typedef struct segment_command MachSegment;
const uint32_t MACH_MAGIC = MH_MAGIC;
const uint32_t MACH_LOADCMD_SEGMENT = LC_SEGMENT;
const cpu_type_t MACH_CPU_TYPE = CPU_TYPE_I386;
const cpu_subtype_t MACH_CPU_SUBTYPE = CPU_SUBTYPE_I386_ALL;
#else
typedef struct mach_header_64 MachHeader;
typedef struct segment_command_64 MachSegment;
const uint32_t MACH_MAGIC = MH_MAGIC_64;
const uint32_t MACH_LOADCMD_SEGMENT = LC_SEGMENT_64;
const cpu_type_t MACH_CPU_TYPE = CPU_TYPE_X86_64;
const cpu_subtype_t MACH_CPU_SUBTYPE = CPU_SUBTYPE_X86_64_ALL;
#endif
Dl_info info;
struct mach_header *file;
struct segment_command *seg;
MachHeader *file;
MachSegment *seg;
uint32_t cmd_count;
if (!dladdr(libPtr, &info))
@@ -570,16 +606,16 @@ bool MemoryUtils::GetLibraryInfo(const void *libPtr, DynLibInfo &lib)
/* This is for our insane sanity checks :o */
baseAddr = (uintptr_t)info.dli_fbase;
file = (struct mach_header *)baseAddr;
file = (MachHeader *)baseAddr;
/* Check Mach-O magic */
if (file->magic != MH_MAGIC)
if (file->magic != MACH_MAGIC)
{
return false;
}
/* Check architecture (32-bit/x86) */
if (file->cputype != CPU_TYPE_I386 || file->cpusubtype != CPU_SUBTYPE_I386_ALL)
/* Check architecture */
if (file->cputype != MACH_CPU_TYPE || file->cpusubtype != MACH_CPU_SUBTYPE)
{
return false;
}
@@ -591,17 +627,17 @@ bool MemoryUtils::GetLibraryInfo(const void *libPtr, DynLibInfo &lib)
}
cmd_count = file->ncmds;
seg = (struct segment_command *)(baseAddr + sizeof(struct mach_header));
seg = (MachSegment *)(baseAddr + sizeof(MachHeader));
/* Add up memory sizes of mapped segments */
for (uint32_t i = 0; i < cmd_count; i++)
{
if (seg->cmd == LC_SEGMENT)
if (seg->cmd == MACH_LOADCMD_SEGMENT)
{
lib.memorySize += seg->vmsize;
}
seg = (struct segment_command *)((uintptr_t)seg + seg->cmdsize);
seg = (MachSegment *)((uintptr_t)seg + seg->cmdsize);
}
#endif
+1
View File
@@ -33,6 +33,7 @@
#include <IShareSys.h>
#include <IHandleSys.h>
#include <am-autoptr.h>
#include <am-string.h>
#include <am-utility.h>
#include <am-refcounting.h>
-321
View File
@@ -1,321 +0,0 @@
// vim: set sts=2 ts=8 sw=2 tw=99 et:
//
// Copyright (C) 2006-2015 AlliedModders LLC
//
// This file is part of SourcePawn. SourcePawn is free software: you can
// redistribute it and/or modify it under the terms of the GNU General Public
// License as published by the Free Software Foundation, either version 3 of
// the License, or (at your option) any later version.
//
// You should have received a copy of the GNU General Public License along with
// SourcePawn. If not, see http://www.gnu.org/licenses/.
//
#include <stdio.h>
#include <string.h>
#include "NativeInvoker.h"
/********************
* FUNCTION CALLING *
********************/
NativeInvoker::NativeInvoker(IPluginContext *pContext, const ke::RefPtr<Native> &native)
: context_(pContext),
m_curparam(0),
m_errorstate(SP_ERROR_NONE),
native_(native)
{
}
NativeInvoker::~NativeInvoker()
{
Cancel();
}
bool
NativeInvoker::IsRunnable()
{
return true;
}
IPluginContext *
NativeInvoker::GetParentContext()
{
return context_;
}
int 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 = sp::FloatCellUnion(number).cell;
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 (!m_curparam)
return;
m_errorstate = SP_ERROR_NONE;
m_curparam = 0;
}
int
NativeInvoker::Execute(cell_t *result, cell_t buffer, cell_t size)
{
context_->ClearLastNativeError();
// For backward compatibility, we have to clear the exception state.
// Otherwise code like this:
//
// static cell_t native(cx, params) {
// for (auto callback : callbacks) {
// callback->Execute();
// }
// }
//
// Could unintentionally leak a pending exception back to the caller,
// which wouldn't have happened before the Great Exception Refactoring.
SourcePawn::ExceptionHandler eh(context_);
eh.Debug(!size);
if (!Invoke(result)) {
if(size)
context_->StringToLocalUTF8(buffer, size, eh.Message(), NULL);
int Err = context_->GetLastNativeError();
context_->ClearLastNativeError();
return Err;
}
return SP_ERROR_NONE;
}
bool
NativeInvoker::Invoke(cell_t *result)
{
if (!IsRunnable()) {
Cancel();
context_->ReportErrorNumber(SP_ERROR_NOT_RUNNABLE);
return false;
}
if (int err = m_errorstate) {
Cancel();
context_->ReportErrorNumber(err);
return false;
}
//This is for re-entrancy!
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;
if (numparams)
{
//Save the info locally, then reset it for re-entrant calls.
memcpy(temp_info, m_info, numparams * sizeof(ParamInfo));
}
m_curparam = 0;
/* Initialize 0th parameter */
_temp_params[0] = numparams;
/* Browse the parameters and build arrays */
bool ok = true;
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 */
int err = context_->HeapAlloc(
temp_info[i].size,
&(temp_info[i].local_addr),
&(temp_info[i].phys_addr));
if (err != SP_ERROR_NONE) {
context_->ReportErrorNumber(err);
ok = false;
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 */
int err = context_->HeapAlloc(
cells,
&(temp_info[i].local_addr),
&(temp_info[i].phys_addr));
if (err != SP_ERROR_NONE) {
context_->ReportErrorNumber(err);
ok = false;
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) {
context_->StringToLocalUTF8(
temp_info[i].local_addr,
temp_info[i].size,
(const char *)temp_info[i].orig_addr,
NULL);
}
/* 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
{
context_->StringToLocal(
temp_info[i].local_addr,
temp_info[i].size,
(const char *)temp_info[i].orig_addr);
}
}
} /* 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 (ok)
{
*result = native_->func()(context_, _temp_params);
}
/* i should be equal to the last valid parameter + 1 */
bool docopies = ok;
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 (int err = context_->HeapPop(temp_info[i].local_addr))
context_->ReportErrorNumber(err);
}
return context_->GetLastNativeError() == SP_ERROR_NONE;
}
int
NativeInvoker::SetError(int err)
{
m_errorstate = err;
return err;
}
int NativeInvoker::CallFunction(const cell_t *params, unsigned int num_params, cell_t *result) { return 0; }
funcid_t NativeInvoker::GetFunctionID() { return 0; }
int NativeInvoker::Execute2(IPluginContext *ctx, cell_t *result) { return 0; }
int NativeInvoker::CallFunction2(IPluginContext *ctx, const cell_t *params, unsigned int num_params, cell_t *result) { return 0; }
IPluginRuntime *NativeInvoker::GetParentRuntime() { return NULL; }
-79
View File
@@ -1,79 +0,0 @@
// vim: set sts=2 ts=8 sw=2 tw=99 et:
//
// Copyright (C) 2006-2015 AlliedModders LLC
//
// This file is part of SourcePawn. SourcePawn is free software: you can
// redistribute it and/or modify it under the terms of the GNU General Public
// License as published by the Free Software Foundation, either version 3 of
// the License, or (at your option) any later version.
//
// You should have received a copy of the GNU General Public License along with
// SourcePawn. If not, see http://www.gnu.org/licenses/.
//
#ifndef _INCLUDE_SOURCEMOD_NATIVE_INVOKER_H_
#define _INCLUDE_SOURCEMOD_NATIVE_INVOKER_H_
#include <sp_vm_api.h>
#include <amtl/am-autoptr.h>
#include <amtl/am-refcounting.h>
#include "Native.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 IPluginFunction
{
public:
NativeInvoker(IPluginContext *pContext, const ke::RefPtr<Native> &native);
virtual ~NativeInvoker();
public:
int PushCell(cell_t cell);
int PushCellByRef(cell_t *cell, int flags);
int PushFloat(float number);
int PushFloatByRef(float *number, int flags);
int PushArray(cell_t *inarray, unsigned int cells, int copyback);
int PushString(const char *string);
int PushStringEx(char *buffer, size_t length, int sz_flags, int cp_flags);
int Execute(cell_t *result, cell_t buffer=0, cell_t size=0);
void Cancel();
int CallFunction(const cell_t *params, unsigned int num_params, cell_t *result);
IPluginContext *GetParentContext();
bool Invoke(cell_t *result);
bool IsRunnable();
funcid_t GetFunctionID();
int Execute2(IPluginContext *ctx, cell_t *result);
int CallFunction2(IPluginContext *ctx,
const cell_t *params,
unsigned int num_params,
cell_t *result);
IPluginRuntime *GetParentRuntime();
const char *DebugName() {
return native_->name();
}
private:
int _PushString(const char *string, int sz_flags, int cp_flags, size_t len);
int SetError(int err);
private:
IPluginContext *context_;
cell_t m_params[SP_MAX_EXEC_PARAMS];
ParamInfo m_info[SP_MAX_EXEC_PARAMS];
unsigned int m_curparam;
int m_errorstate;
ke::RefPtr<Native> native_;
};
#endif //_INCLUDE_SOURCEMOD_NATIVE_INVOKER_H_
+19 -16
View File
@@ -75,7 +75,7 @@ CPlugin::CPlugin(const char *file)
m_serial = ++MySerial;
m_errormsg[0] = '\0';
m_DateTime[0] = '\0';
ke::SafeSprintf(m_filename, sizeof(m_filename), "%s", file);
ke::SafeStrcpy(m_filename, sizeof(m_filename), file);
memset(&m_info, 0, sizeof(m_info));
@@ -905,7 +905,7 @@ void CPluginManager::LoadPluginsFromDir(const char *basedir, const char *localpa
if (localpath == NULL)
{
/* If no path yet, don't add a former slash */
ke::SafeSprintf(new_local, sizeof(new_local), "%s", dir->GetEntryName());
ke::SafeStrcpy(new_local, sizeof(new_local), dir->GetEntryName());
} else {
libsys->PathFormat(new_local, sizeof(new_local), "%s/%s", localpath, dir->GetEntryName());
}
@@ -920,7 +920,7 @@ void CPluginManager::LoadPluginsFromDir(const char *basedir, const char *localpa
char plugin[PLATFORM_MAX_PATH];
if (localpath == NULL)
{
ke::SafeSprintf(plugin, sizeof(plugin), "%s", name);
ke::SafeStrcpy(plugin, sizeof(plugin), name);
} else {
libsys->PathFormat(plugin, sizeof(plugin), "%s/%s", localpath, name);
}
@@ -994,9 +994,9 @@ IPlugin *CPluginManager::LoadPlugin(const char *path, bool debug, PluginType typ
if (res == LoadRes_NeverLoad) {
if (m_LoadingLocked)
ke::SafeSprintf(error, maxlength, "There is a global plugin loading lock in effect");
ke::SafeStrcpy(error, maxlength, "There is a global plugin loading lock in effect");
else
ke::SafeSprintf(error, maxlength, "This plugin is blocked from loading (see plugin_settings.cfg)");
ke::SafeStrcpy(error, maxlength, "This plugin is blocked from loading (see plugin_settings.cfg)");
return NULL;
}
@@ -1277,7 +1277,7 @@ bool CPluginManager::MalwareCheckPass(CPlugin *pPlugin)
unsigned char *pCodeHash = pPlugin->GetRuntime()->GetCodeHash();
char codeHashBuf[40];
ke::SafeSprintf(codeHashBuf, 40, "plugin_");
ke::SafeStrcpy(codeHashBuf, sizeof(codeHashBuf), "plugin_");
for (int i = 0; i < 16; i++)
ke::SafeSprintf(codeHashBuf + 7 + (i * 2), 3, "%02x", pCodeHash[i]);
@@ -1607,7 +1607,7 @@ ConfigResult CPluginManager::OnSourceModConfigChanged(const char *key,
} else if (strcasecmp(value, "no") == 0) {
m_bBlockBadPlugins = false;
} else {
ke::SafeSprintf(error, maxlength, "Invalid value: must be \"yes\" or \"no\"");
ke::SafeStrcpy(error, maxlength, "Invalid value: must be \"yes\" or \"no\"");
return ConfigResult_Reject;
}
return ConfigResult_Accept;
@@ -1701,6 +1701,9 @@ void CPluginManager::OnRootConsoleCommand(const char *cmdname, const ICommandArg
char buffer[256];
unsigned int id = 1;
int plnum = GetPluginCount();
char plstr[10];
ke::SafeSprintf(plstr, sizeof(plstr), "%d", plnum);
int plpadding = strlen(plstr);
if (!plnum)
{
@@ -1709,7 +1712,7 @@ void CPluginManager::OnRootConsoleCommand(const char *cmdname, const ICommandArg
}
else
{
rootmenu->ConsolePrint("[SM] Listing %d plugin%s:", GetPluginCount(), (plnum > 1) ? "s" : "");
rootmenu->ConsolePrint("[SM] Listing %d plugin%s:", plnum, (plnum > 1) ? "s" : "");
}
ke::LinkedList<CPlugin *> fail_list;
@@ -1721,19 +1724,19 @@ void CPluginManager::OnRootConsoleCommand(const char *cmdname, const ICommandArg
const sm_plugininfo_t *info = pl->GetPublicInfo();
if (pl->GetStatus() != Plugin_Running && !pl->IsSilentlyFailed())
{
len += ke::SafeSprintf(buffer, sizeof(buffer), " %02d <%s>", id, GetStatusText(pl->GetDisplayStatus()));
len += ke::SafeSprintf(buffer, sizeof(buffer), " %0*d <%s>", plpadding, id, GetStatusText(pl->GetDisplayStatus()));
/* Plugin has failed to load. */
fail_list.append(pl);
}
else
{
len += ke::SafeSprintf(buffer, sizeof(buffer), " %02d", id);
len += ke::SafeSprintf(buffer, sizeof(buffer), " %0*d", plpadding, id);
}
if (pl->GetStatus() < Plugin_Created || pl->GetStatus() == Plugin_Evicted)
{
if (pl->IsSilentlyFailed())
len += ke::SafeSprintf(&buffer[len], sizeof(buffer)-len, " Disabled:");
len += ke::SafeStrcpy(&buffer[len], sizeof(buffer)-len, " Disabled:");
len += ke::SafeSprintf(&buffer[len], sizeof(buffer)-len, " \"%s\"", (IS_STR_FILLED(info->name)) ? info->name : pl->GetFilename());
if (IS_STR_FILLED(info->version))
{
@@ -1842,11 +1845,11 @@ void CPluginManager::OnRootConsoleCommand(const char *cmdname, const ICommandArg
if (pl->GetStatus() < Plugin_Created)
{
const sm_plugininfo_t *info = pl->GetPublicInfo();
ke::SafeSprintf(name, sizeof(name), (IS_STR_FILLED(info->name)) ? info->name : pl->GetFilename());
ke::SafeStrcpy(name, sizeof(name), (IS_STR_FILLED(info->name)) ? info->name : pl->GetFilename());
}
else
{
ke::SafeSprintf(name, sizeof(name), "%s", pl->GetFilename());
ke::SafeStrcpy(name, sizeof(name), pl->GetFilename());
}
if (UnloadPlugin(pl))
@@ -1958,11 +1961,11 @@ void CPluginManager::OnRootConsoleCommand(const char *cmdname, const ICommandArg
if (IPluginRuntime *runtime = pl->GetRuntime()) {
unsigned char *pCodeHash = runtime->GetCodeHash();
unsigned char *pDataHash = runtime->GetDataHash();
char combinedHash[33];
for (int i = 0; i < 16; i++)
ke::SafeSprintf(combinedHash + (i * 2), 3, "%02x", pCodeHash[i] ^ pDataHash[i]);
rootmenu->ConsolePrint(" Hash: %s", combinedHash);
}
} else {
@@ -2090,7 +2093,7 @@ void CPluginManager::ReloadPluginImpl(int id, const char filename[], PluginType
char error[128];
bool wasloaded;
IPlugin *newpl = LoadPlugin(filename, true, ptype, error, sizeof(error), &wasloaded);
if (!newpl)
if (!newpl)
{
rootmenu->ConsolePrint("[SM] Plugin %s failed to reload: %s.", filename, error);
return;
+8 -29
View File
@@ -55,9 +55,6 @@
#include <bridge/include/IScriptManager.h>
#include <am-function.h>
#include <ReentrantList.h>
#ifdef PLATFORM_APPLE
#include <cctype>
#endif
class CPlayer;
@@ -487,17 +484,10 @@ private:
{
/* For windows & mac, we convert the path to lower-case in order to avoid duplicate plugin loading */
#if defined PLATFORM_WINDOWS || defined PLATFORM_APPLE
const char *original = key.chars();
char *copy = strdup(original);
ke::AString original(key.chars());
ke::AString lower = original.lowercase();
for (size_t i = 0; copy[i]; ++i)
{
copy[i] = tolower(copy[i]);
}
uint32_t hash = detail::CharsAndLength(copy).hash();
free(copy);
return hash;
return detail::CharsAndLength(lower.chars()).hash();
#else
return key.hash();
#endif
@@ -505,25 +495,14 @@ private:
static inline bool matches(const char *file, const CPlugin *plugin)
{
const char *pluginFile = const_cast<CPlugin*>(plugin)->GetFilename();
const char *pluginFileChars = const_cast<CPlugin*>(plugin)->GetFilename();
#if defined PLATFORM_WINDOWS || defined PLATFORM_APPLE
size_t fileLen = strlen(file);
if (fileLen != strlen(pluginFile))
{
return false;
}
ke::AString pluginFile = ke::AString(pluginFileChars).lowercase();
ke::AString input = ke::AString(file).lowercase();
for (size_t i = 0; i < fileLen; ++i)
{
if (tolower(file[i]) != tolower(pluginFile[i]))
{
return false;
}
}
return true;
return pluginFile == input;
#else
return strcmp(pluginFile, file) == 0;
return strcmp(pluginFileChars, file) == 0;
#endif
}
};
+169
View File
@@ -0,0 +1,169 @@
/**
* vim: set ts=4 :
* =============================================================================
* SourceMod
* Copyright (C) 2004-2017 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 "PseudoAddrManager.h"
#ifdef PLATFORM_APPLE
#include <mach/mach.h>
#include <mach/vm_region.h>
#endif
#ifdef PLATFORM_LINUX
#include <inttypes.h>
#endif
PseudoAddressManager::PseudoAddressManager() : m_NumEntries(0)
{
}
// A pseudo address consists of a table index in the upper 6 bits and an offset in the
// lower 26 bits. The table consists of memory allocation base addresses.
void *PseudoAddressManager::FromPseudoAddress(uint32_t paddr)
{
#ifdef PLATFORM_X64
uint8_t index = paddr >> PSEUDO_OFFSET_BITS;
uint32_t offset = paddr & ((1 << PSEUDO_OFFSET_BITS) - 1);
if (index >= m_NumEntries)
return nullptr;
return reinterpret_cast<void *>(uintptr_t(m_AllocBases[index]) + offset);
#else
return nullptr;
#endif
}
uint32_t PseudoAddressManager::ToPseudoAddress(void *addr)
{
#ifdef PLATFORM_X64
uint8_t index = 0;
uint32_t offset = 0;
bool hasEntry = false;
void *base = GetAllocationBase(addr);
if (base) {
for (int i = 0; i < m_NumEntries; i++) {
if (m_AllocBases[i] == base) {
index = i;
hasEntry = true;
break;
}
}
} else {
return 0;
}
if (!hasEntry) {
index = m_NumEntries;
if (m_NumEntries < SM_ARRAYSIZE(m_AllocBases))
m_AllocBases[m_NumEntries++] = base;
else
return 0; // Table is full
}
ptrdiff_t diff = uintptr_t(addr) - uintptr_t(base);
// Ensure difference fits in 26 bits
if (diff > (UINT32_MAX >> PSEUDO_INDEX_BITS))
return 0;
return (index << PSEUDO_OFFSET_BITS) | diff;
#else
return 0;
#endif
}
void *PseudoAddressManager::GetAllocationBase(void *ptr)
{
#if defined PLATFORM_WINDOWS
MEMORY_BASIC_INFORMATION info;
if (!VirtualQuery(ptr, &info, sizeof(MEMORY_BASIC_INFORMATION)))
return nullptr;
return info.AllocationBase;
#elif defined PLATFORM_APPLE
#ifdef PLATFORM_X86
typedef vm_region_info_t mach_vm_region_info_t;
typedef vm_region_basic_info_data_t mach_vm_region_basic_info_data_t;
const vm_region_flavor_t MACH_VM_REGION_BASIC_INFO = VM_REGION_BASIC_INFO;
const mach_msg_type_number_t MACH_VM_REGION_BASIC_INFO_COUNT = VM_REGION_BASIC_INFO_COUNT;
#define mach_vm_region vm_region
#elif defined PLATFORM_X64
typedef vm_region_info_64_t mach_vm_region_info_t ;
typedef vm_region_basic_info_data_64_t mach_vm_region_basic_info_data_t;
const vm_region_flavor_t MACH_VM_REGION_BASIC_INFO = VM_REGION_BASIC_INFO_64;
const mach_msg_type_number_t MACH_VM_REGION_BASIC_INFO_COUNT = VM_REGION_BASIC_INFO_COUNT_64;
#define mach_vm_region vm_region_64
#endif
vm_size_t size;
vm_address_t vmaddr = reinterpret_cast<vm_address_t>(ptr);
mach_vm_region_basic_info_data_t info;
memory_object_name_t obj;
vm_region_flavor_t flavor = MACH_VM_REGION_BASIC_INFO;
mach_msg_type_number_t count = MACH_VM_REGION_BASIC_INFO_COUNT;
kern_return_t kr = mach_vm_region(mach_task_self(), &vmaddr, &size, flavor,
reinterpret_cast<mach_vm_region_info_t>(&info),
&count, &obj);
if (kr != KERN_SUCCESS)
return nullptr;
return reinterpret_cast<void *>(vmaddr);
#elif defined PLATFORM_LINUX
uintptr_t addr = reinterpret_cast<uintptr_t>(ptr);
// Format:
// lower upper prot stuff path
// 08048000-0804c000 r-xp 00000000 03:03 1010107 /bin/cat
FILE *fp = fopen("/proc/self/maps", "r");
if (fp) {
uintptr_t lower, upper;
while (fscanf(fp, "%" PRIxPTR "-%" PRIxPTR, &lower, &upper) != EOF) {
if (addr >= lower && addr <= upper) {
fclose(fp);
return reinterpret_cast<void *>(lower);
}
// Read to end of line
int c;
while ((c = fgetc(fp)) != '\n') {
if (c == EOF)
break;
}
if (c == EOF)
break;
}
fclose(fp);
}
return nullptr;
#endif
}
+51
View File
@@ -0,0 +1,51 @@
/**
* vim: set ts=4 :
* =============================================================================
* SourceMod
* Copyright (C) 2004-2017 AlliedModders LLC. All rights reserved.
* =============================================================================
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, version 3.0, as published by the
* Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*
* As a special exception, AlliedModders LLC gives you permission to link the
* code of this program (as well as its derivative works) to "Half-Life 2," the
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
* by the Valve Corporation. You must obey the GNU General Public License in
* all respects for all other code used. Additionally, AlliedModders LLC grants
* this exception to all derivative works. AlliedModders LLC defines further
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
* or <http://www.sourcemod.net/license.php>.
*/
#ifndef _INCLUDE_SOURCEMOD_PSEUDOADDRESSMANAGER_H_
#define _INCLUDE_SOURCEMOD_PSEUDOADDRESSMANAGER_H_
#include "common_logic.h"
class PseudoAddressManager
{
public:
PseudoAddressManager();
public:
void *FromPseudoAddress(uint32_t paddr);
uint32_t ToPseudoAddress(void *addr);
private:
void *GetAllocationBase(void *ptr);
private:
static constexpr uint8_t PSEUDO_OFFSET_BITS = 26;
static constexpr uint8_t PSEUDO_INDEX_BITS = sizeof(uint32_t) * 8 - PSEUDO_OFFSET_BITS;
void *m_AllocBases[1 << PSEUDO_INDEX_BITS];
uint8_t m_NumEntries;
};
#endif // _INCLUDE_SOURCEMOD_PSEUDOADDRESSMANAGER_H_
+2 -2
View File
@@ -166,7 +166,7 @@ void RootConsoleMenu::DrawGenericOption(const char *cmd, const char *text)
{
buffer[len++] = ' ';
}
len += snprintf(&buffer[len], sizeof(buffer) - len, " - %s", text);
len += ke::SafeSprintf(&buffer[len], sizeof(buffer) - len, " - %s", text);
ConsolePrint("%s", buffer);
}
}
@@ -256,7 +256,7 @@ static bool sm_dump_handles(int client, const ICommandArgs *args)
auto write_handles_to_game = [] (const char *str) -> void
{
char buffer[1024];
size_t len = ke::SafeSprintf(buffer, sizeof(buffer)-2, "%s", str);
size_t len = ke::SafeStrcpy(buffer, sizeof(buffer)-2, str);
buffer[len] = '\n';
buffer[len+1] = '\0';
+4 -6
View File
@@ -162,18 +162,16 @@ bool ShareSystem::RequestInterface(const char *iface_name,
SMInterface **pIface)
{
/* See if the interface exists */
List<IfaceInfo>::iterator iter;
SMInterface *iface;
IExtension *iface_owner;
IExtension *iface_owner = nullptr;
bool found = false;
for (iter=m_Interfaces.begin(); iter!=m_Interfaces.end(); iter++)
for (auto iter = m_Interfaces.begin(); iter!=m_Interfaces.end(); iter++)
{
IfaceInfo &info = (*iter);
IfaceInfo &info = *iter;
iface = info.iface;
if (strcmp(iface->GetInterfaceName(), iface_name) == 0)
{
if (iface->GetInterfaceVersion() == iface_vers
|| iface->IsVersionCompatible(iface_vers))
if (iface->GetInterfaceVersion() == iface_vers || iface->IsVersionCompatible(iface_vers))
{
iface_owner = info.owner;
found = true;
+2 -2
View File
@@ -144,7 +144,7 @@ SMCError TextParsers::ParseSMCFile(const char *file,
fclose(fp);
errstr = GetSMCErrorString(result);
ke::SafeSprintf(buffer, maxsize, "%s", errstr != NULL ? errstr : "Unknown error");
ke::SafeStrcpy(buffer, maxsize, errstr != NULL ? errstr : "Unknown error");
return result;
}
@@ -195,7 +195,7 @@ SMCError TextParsers::ParseSMCStream(const char *stream,
result = ParseStream_SMC(&rs, RawStreamReader, smc_listener, states);
const char *errstr = GetSMCErrorString(result);
ke::SafeSprintf(buffer, maxsize, "%s", errstr != NULL ? errstr : "Unknown error");
ke::SafeStrcpy(buffer, maxsize, errstr != NULL ? errstr : "Unknown error");
return result;
}
+1 -1
View File
@@ -940,7 +940,7 @@ bool Translator::AddLanguage(const char *langcode, const char *description)
Language *pLanguage = new Language;
idx = m_Languages.size();
ke::SafeSprintf(pLanguage->m_code2, sizeof(pLanguage->m_code2), "%s", langcode);
ke::SafeStrcpy(pLanguage->m_code2, sizeof(pLanguage->m_code2), langcode);
pLanguage->m_CanonicalName = m_pStringTab->AddString(lower);
m_LCodeLookup.insert(langcode, idx);
+23 -3
View File
@@ -55,7 +55,6 @@
#include "sprintf.h"
#include "LibrarySys.h"
#include "RootConsoleMenu.h"
#include "CDataPack.h"
#include "CellArray.h"
#include <bridge/include/BridgeAPI.h>
#include <bridge/include/IProviderCallbacks.h>
@@ -86,6 +85,9 @@ IScriptManager *scripts = &g_PluginSys;
IExtensionSys *extsys = &g_Extensions;
ILogger *logger = &g_Logger;
CNativeOwner g_CoreNatives;
#ifdef PLATFORM_X64
PseudoAddressManager pseudoAddr;
#endif
static void AddCorePhraseFile(const char *filename)
{
@@ -115,6 +117,24 @@ static void RegisterProfiler(IProfilingTool *tool)
g_ProfileToolManager.RegisterTool(tool);
}
static void *FromPseudoAddress(uint32_t paddr)
{
#ifdef PLATFORM_X64
return pseudoAddr.FromPseudoAddress(paddr);
#else
return nullptr;
#endif
}
static uint32_t ToPseudoAddress(void *addr)
{
#ifdef PLATFORM_X64
return pseudoAddr.ToPseudoAddress(addr);
#else
return 0;
#endif
}
// Defined in smn_filesystem.cpp.
extern bool OnLogPrint(const char *msg);
@@ -146,10 +166,10 @@ static sm_logic_t logic =
GenerateError,
AddNatives,
RegisterProfiler,
CDataPack::New,
CDataPack::Free,
CellArray::New,
CellArray::Free,
FromPseudoAddress,
ToPseudoAddress,
&g_PluginSys,
&g_ShareSys,
&g_Extensions,
+5
View File
@@ -33,6 +33,9 @@
#define _INCLUDE_SOURCEMOD_COMMON_LOGIC_H_
#include "../sm_globals.h"
#ifdef PLATFORM_X64
#include "PseudoAddrManager.h"
#endif
namespace SourceMod {
class CoreProvider;
@@ -57,6 +60,7 @@ class IVEngineServerBridge;
#endif
} // namespace SourceMod
struct ServerGlobals;
class PseudoAddressManager;
extern SourceMod::CoreProvider *bridge;
extern SourceMod::IHandleSys *handlesys;
@@ -76,6 +80,7 @@ extern SourceMod::IScriptManager *scripts;
extern SourceMod::IExtensionSys *extsys;
extern SourceMod::ILogger *logger;
extern SourceMod::IMenuManager *menus;
extern PseudoAddressManager pseudoAddr;
#if defined SM_LOGIC
extern SourceMod::IVEngineServerBridge *engine;
+1
View File
@@ -31,6 +31,7 @@
#include <stdlib.h>
#include "common_logic.h"
#include <am-autoptr.h>
#include <am-moveable.h>
#include <am-refcounting.h>
#include <sm_stringhashmap.h>
+29
View File
@@ -708,7 +708,11 @@ enum NumberType
static cell_t LoadFromAddress(IPluginContext *pContext, const cell_t *params)
{
#ifdef PLATFORM_X86
void *addr = reinterpret_cast<void*>(params[1]);
#else
void *addr = pseudoAddr.FromPseudoAddress(params[1]);
#endif
if (addr == NULL)
{
@@ -736,7 +740,11 @@ static cell_t LoadFromAddress(IPluginContext *pContext, const cell_t *params)
static cell_t StoreToAddress(IPluginContext *pContext, const cell_t *params)
{
#ifdef PLATFORM_X86
void *addr = reinterpret_cast<void*>(params[1]);
#else
void *addr = pseudoAddr.FromPseudoAddress(params[1]);
#endif
if (addr == NULL)
{
@@ -929,6 +937,26 @@ static cell_t FrameIterator_GetFilePath(IPluginContext *pContext, const cell_t *
return 0;
}
static cell_t LogStackTrace(IPluginContext *pContext, const cell_t *params)
{
char buffer[512];
g_pSM->FormatString(buffer, sizeof(buffer), pContext, params, 1);
IFrameIterator *it = pContext->CreateFrameIterator();
ke::Vector<ke::AString> arr = g_DbgReporter.GetStackTrace(it);
pContext->DestroyFrameIterator(it);
IPlugin *pPlugin = scripts->FindPluginByContext(pContext->GetContext());
g_Logger.LogError("[SM] Stack trace requested: %s", buffer);
g_Logger.LogError("[SM] Called from: %s", pPlugin->GetFilename());
for (size_t i = 0; i < arr.length(); ++i)
{
g_Logger.LogError("%s", arr[i].chars());
}
return 0;
}
REGISTER_NATIVES(coreNatives)
{
{"ThrowError", ThrowError},
@@ -959,6 +987,7 @@ REGISTER_NATIVES(coreNatives)
{"StoreToAddress", StoreToAddress},
{"IsNullVector", IsNullVector},
{"IsNullString", IsNullString},
{"LogStackTrace", LogStackTrace},
{"FrameIterator.FrameIterator", FrameIterator_Create},
{"FrameIterator.Next", FrameIterator_Next},
+11 -9
View File
@@ -314,6 +314,12 @@ public:
error[0] = '\0';
strncopy(dbname, _dbname, sizeof(dbname));
me = scripts->FindPluginByContext(m_pFunction->GetParentContext()->GetContext());
m_pInfo = g_DBMan.GetDatabaseConf(dbname);
if (!m_pInfo)
{
g_pSM->Format(error, sizeof(error), "Could not find database config \"%s\"", dbname);
}
}
IdentityToken_t *GetOwner()
{
@@ -325,15 +331,10 @@ public:
}
void RunThreadPart()
{
g_DBMan.LockConfig();
const DatabaseInfo *pInfo = g_DBMan.FindDatabaseConf(dbname);
if (!pInfo)
if (m_pInfo)
{
g_pSM->Format(error, sizeof(error), "Could not find database config \"%s\"", dbname);
} else {
m_pDatabase = m_pDriver->Connect(pInfo, false, error, sizeof(error));
m_pDatabase = m_pDriver->Connect(&m_pInfo->info, false, error, sizeof(error));
}
g_DBMan.UnlockConfig();
}
void CancelThinkPart()
{
@@ -383,6 +384,7 @@ public:
delete this;
}
private:
ke::RefPtr<ConfDbInfo> m_pInfo;
IPlugin *me;
IPluginFunction *m_pFunction;
IDBDriver *m_pDriver;
@@ -453,7 +455,7 @@ static cell_t ConnectToDbAsync(IPluginContext *pContext, const cell_t *params, A
g_pSM->Format(error,
sizeof(error),
"Could not find driver \"%s\"",
pInfo->driver[0] == '\0' ? g_DBMan.GetDefaultDriverName() : pInfo->driver);
pInfo->driver[0] == '\0' ? g_DBMan.GetDefaultDriverName().chars() : pInfo->driver);
} else if (!driver->IsThreadSafe()) {
g_pSM->Format(error,
sizeof(error),
@@ -1423,7 +1425,7 @@ static cell_t SQL_CheckConfig(IPluginContext *pContext, const cell_t *params)
char *name;
pContext->LocalToString(params[1], &name);
return (g_DBMan.FindDatabaseConf(name) != NULL) ? 1 : 0;
return (g_DBMan.GetDatabaseConf(name) != nullptr) ? 1 : 0;
}
static cell_t SQL_ConnectCustom(IPluginContext *pContext, const cell_t *params)
+84 -37
View File
@@ -61,7 +61,7 @@ public:
}
void OnHandleDestroy(HandleType_t type, void *object)
{
CDataPack::Free(reinterpret_cast<IDataPack *>(object));
CDataPack::Free(reinterpret_cast<CDataPack *>(object));
}
bool GetHandleApproxSize(HandleType_t type, void *object, unsigned int *pSize)
{
@@ -73,7 +73,7 @@ public:
static cell_t smn_CreateDataPack(IPluginContext *pContext, const cell_t *params)
{
IDataPack *pDataPack = CDataPack::New();
CDataPack *pDataPack = CDataPack::New();
if (!pDataPack)
{
@@ -88,7 +88,7 @@ static cell_t smn_WritePackCell(IPluginContext *pContext, const cell_t *params)
Handle_t hndl = static_cast<Handle_t>(params[1]);
HandleError herr;
HandleSecurity sec;
IDataPack *pDataPack;
CDataPack *pDataPack;
sec.pOwner = pContext->GetIdentity();
sec.pIdentity = g_pCoreIdent;
@@ -96,7 +96,13 @@ static cell_t smn_WritePackCell(IPluginContext *pContext, const cell_t *params)
if ((herr=handlesys->ReadHandle(hndl, g_DataPackType, &sec, (void **)&pDataPack))
!= HandleError_None)
{
return pContext->ThrowNativeError("Invalid data pack handle %x (error %d)", hndl, herr);
return pContext->ThrowNativeError("Invalid data pack handle %x (error %d).", hndl, herr);
}
bool insert = (params[0] >= 3) ? params[3] : false;
if (!insert)
{
pDataPack->RemoveItem();
}
pDataPack->PackCell(params[2]);
@@ -109,7 +115,7 @@ static cell_t smn_WritePackFloat(IPluginContext *pContext, const cell_t *params)
Handle_t hndl = static_cast<Handle_t>(params[1]);
HandleError herr;
HandleSecurity sec;
IDataPack *pDataPack;
CDataPack *pDataPack;
sec.pOwner = pContext->GetIdentity();
sec.pIdentity = g_pCoreIdent;
@@ -117,7 +123,13 @@ static cell_t smn_WritePackFloat(IPluginContext *pContext, const cell_t *params)
if ((herr=handlesys->ReadHandle(hndl, g_DataPackType, &sec, (void **)&pDataPack))
!= HandleError_None)
{
return pContext->ThrowNativeError("Invalid data pack handle %x (error %d)", hndl, herr);
return pContext->ThrowNativeError("Invalid data pack handle %x (error %d).", hndl, herr);
}
bool insert = (params[0] >= 3) ? params[3] : false;
if (!insert)
{
pDataPack->RemoveItem();
}
pDataPack->PackFloat(sp_ctof(params[2]));
@@ -130,7 +142,7 @@ static cell_t smn_WritePackString(IPluginContext *pContext, const cell_t *params
Handle_t hndl = static_cast<Handle_t>(params[1]);
HandleError herr;
HandleSecurity sec;
IDataPack *pDataPack;
CDataPack *pDataPack;
sec.pOwner = pContext->GetIdentity();
sec.pIdentity = g_pCoreIdent;
@@ -138,7 +150,13 @@ static cell_t smn_WritePackString(IPluginContext *pContext, const cell_t *params
if ((herr=handlesys->ReadHandle(hndl, g_DataPackType, &sec, (void **)&pDataPack))
!= HandleError_None)
{
return pContext->ThrowNativeError("Invalid data pack handle %x (error %d)", hndl, herr);
return pContext->ThrowNativeError("Invalid data pack handle %x (error %d).", hndl, herr);
}
bool insert = (params[0] >= 3) ? params[3] : false;
if (!insert)
{
pDataPack->RemoveItem();
}
char *str;
@@ -153,7 +171,7 @@ static cell_t smn_WritePackFunction(IPluginContext *pContext, const cell_t *para
Handle_t hndl = static_cast<Handle_t>(params[1]);
HandleError herr;
HandleSecurity sec;
IDataPack *pDataPack;
CDataPack *pDataPack;
sec.pOwner = pContext->GetIdentity();
sec.pIdentity = g_pCoreIdent;
@@ -161,7 +179,13 @@ static cell_t smn_WritePackFunction(IPluginContext *pContext, const cell_t *para
if ((herr = handlesys->ReadHandle(hndl, g_DataPackType, &sec, (void **)&pDataPack))
!= HandleError_None)
{
return pContext->ThrowNativeError("Invalid data pack handle %x (error %d)", hndl, herr);
return pContext->ThrowNativeError("Invalid data pack handle %x (error %d).", hndl, herr);
}
bool insert = (params[0] >= 3) ? params[3] : false;
if (!insert)
{
pDataPack->RemoveItem();
}
pDataPack->PackFunction(params[2]);
@@ -174,7 +198,7 @@ static cell_t smn_ReadPackCell(IPluginContext *pContext, const cell_t *params)
Handle_t hndl = static_cast<Handle_t>(params[1]);
HandleError herr;
HandleSecurity sec;
IDataPack *pDataPack;
CDataPack *pDataPack;
sec.pOwner = pContext->GetIdentity();
sec.pIdentity = g_pCoreIdent;
@@ -182,12 +206,17 @@ static cell_t smn_ReadPackCell(IPluginContext *pContext, const cell_t *params)
if ((herr=handlesys->ReadHandle(hndl, g_DataPackType, &sec, (void **)&pDataPack))
!= HandleError_None)
{
return pContext->ThrowNativeError("Invalid data pack handle %x (error %d)", hndl, herr);
return pContext->ThrowNativeError("Invalid data pack handle %x (error %d).", hndl, herr);
}
if (!pDataPack->IsReadable(sizeof(char) + sizeof(size_t) + sizeof(cell_t)))
if (!pDataPack->IsReadable())
{
return pContext->ThrowNativeError("DataPack operation is out of bounds.");
return pContext->ThrowNativeError("Data pack operation is out of bounds.");
}
if (pDataPack->GetCurrentType() != CDataPackType::Cell)
{
return pContext->ThrowNativeError("Invalid data pack type (got %d / expected %d).", pDataPack->GetCurrentType(), CDataPackType::Cell);
}
return pDataPack->ReadCell();
@@ -198,7 +227,7 @@ static cell_t smn_ReadPackFloat(IPluginContext *pContext, const cell_t *params)
Handle_t hndl = static_cast<Handle_t>(params[1]);
HandleError herr;
HandleSecurity sec;
IDataPack *pDataPack;
CDataPack *pDataPack;
sec.pOwner = pContext->GetIdentity();
sec.pIdentity = g_pCoreIdent;
@@ -206,12 +235,17 @@ static cell_t smn_ReadPackFloat(IPluginContext *pContext, const cell_t *params)
if ((herr=handlesys->ReadHandle(hndl, g_DataPackType, &sec, (void **)&pDataPack))
!= HandleError_None)
{
return pContext->ThrowNativeError("Invalid data pack handle %x (error %d)", hndl, herr);
return pContext->ThrowNativeError("Invalid data pack handle %x (error %d).", hndl, herr);
}
if (!pDataPack->IsReadable(sizeof(char) + sizeof(size_t) + sizeof(float)))
if (!pDataPack->IsReadable())
{
return pContext->ThrowNativeError("DataPack operation is out of bounds.");
return pContext->ThrowNativeError("Data pack operation is out of bounds.");
}
if (pDataPack->GetCurrentType() != CDataPackType::Float)
{
return pContext->ThrowNativeError("Invalid data pack type (got %d / expected %d).", pDataPack->GetCurrentType(), CDataPackType::Float);
}
return sp_ftoc(pDataPack->ReadFloat());
@@ -222,7 +256,7 @@ static cell_t smn_ReadPackString(IPluginContext *pContext, const cell_t *params)
Handle_t hndl = static_cast<Handle_t>(params[1]);
HandleError herr;
HandleSecurity sec;
IDataPack *pDataPack;
CDataPack *pDataPack;
sec.pOwner = pContext->GetIdentity();
sec.pIdentity = g_pCoreIdent;
@@ -230,15 +264,20 @@ static cell_t smn_ReadPackString(IPluginContext *pContext, const cell_t *params)
if ((herr=handlesys->ReadHandle(hndl, g_DataPackType, &sec, (void **)&pDataPack))
!= HandleError_None)
{
return pContext->ThrowNativeError("Invalid data pack handle %x (error %d)", hndl, herr);
return pContext->ThrowNativeError("Invalid data pack handle %x (error %d).", hndl, herr);
}
const char *str;
if (!(str=pDataPack->ReadString(NULL)))
if (!pDataPack->IsReadable())
{
return pContext->ThrowNativeError("DataPack operation is out of bounds.");
return pContext->ThrowNativeError("Data pack operation is out of bounds.");
}
if (pDataPack->GetCurrentType() != CDataPackType::String)
{
return pContext->ThrowNativeError("Invalid data pack type (got %d / expected %d).", pDataPack->GetCurrentType(), CDataPackType::String);
}
const char *str = pDataPack->ReadString(NULL);
pContext->StringToLocal(params[2], params[3], str);
return 1;
@@ -249,7 +288,7 @@ static cell_t smn_ReadPackFunction(IPluginContext *pContext, const cell_t *param
Handle_t hndl = static_cast<Handle_t>(params[1]);
HandleError herr;
HandleSecurity sec;
IDataPack *pDataPack;
CDataPack *pDataPack;
sec.pOwner = pContext->GetIdentity();
sec.pIdentity = g_pCoreIdent;
@@ -257,12 +296,17 @@ static cell_t smn_ReadPackFunction(IPluginContext *pContext, const cell_t *param
if ((herr = handlesys->ReadHandle(hndl, g_DataPackType, &sec, (void **)&pDataPack))
!= HandleError_None)
{
return pContext->ThrowNativeError("Invalid data pack handle %x (error %d)", hndl, herr);
return pContext->ThrowNativeError("Invalid data pack handle %x (error %d).", hndl, herr);
}
if (!pDataPack->IsReadable(sizeof(char) + sizeof(size_t) + sizeof(cell_t)))
if (!pDataPack->IsReadable())
{
return pContext->ThrowNativeError("DataPack operation is out of bounds.");
return pContext->ThrowNativeError("Data pack operation is out of bounds.");
}
if (pDataPack->GetCurrentType() != CDataPackType::Function)
{
return pContext->ThrowNativeError("Invalid data pack type (got %d / expected %d).", pDataPack->GetCurrentType(), CDataPackType::Function);
}
return pDataPack->ReadFunction();
@@ -273,7 +317,7 @@ static cell_t smn_ResetPack(IPluginContext *pContext, const cell_t *params)
Handle_t hndl = static_cast<Handle_t>(params[1]);
HandleError herr;
HandleSecurity sec;
IDataPack *pDataPack;
CDataPack *pDataPack;
sec.pOwner = pContext->GetIdentity();
sec.pIdentity = g_pCoreIdent;
@@ -281,14 +325,17 @@ static cell_t smn_ResetPack(IPluginContext *pContext, const cell_t *params)
if ((herr=handlesys->ReadHandle(hndl, g_DataPackType, &sec, (void **)&pDataPack))
!= HandleError_None)
{
return pContext->ThrowNativeError("Invalid data pack handle %x (error %d)", hndl, herr);
return pContext->ThrowNativeError("Invalid data pack handle %x (error %d).", hndl, herr);
}
pDataPack->Reset();
if (params[2])
{
pDataPack->ResetSize();
}
else
{
pDataPack->Reset();
}
return 1;
}
@@ -298,7 +345,7 @@ static cell_t smn_GetPackPosition(IPluginContext *pContext, const cell_t *params
Handle_t hndl = static_cast<Handle_t>(params[1]);
HandleError herr;
HandleSecurity sec;
IDataPack *pDataPack;
CDataPack *pDataPack;
sec.pOwner = pContext->GetIdentity();
sec.pIdentity = g_pCoreIdent;
@@ -306,7 +353,7 @@ static cell_t smn_GetPackPosition(IPluginContext *pContext, const cell_t *params
if ((herr=handlesys->ReadHandle(hndl, g_DataPackType, &sec, (void **)&pDataPack))
!= HandleError_None)
{
return pContext->ThrowNativeError("Invalid data pack handle %x (error %d)", hndl, herr);
return pContext->ThrowNativeError("Invalid data pack handle %x (error %d).", hndl, herr);
}
return static_cast<cell_t>(pDataPack->GetPosition());
@@ -317,7 +364,7 @@ static cell_t smn_SetPackPosition(IPluginContext *pContext, const cell_t *params
Handle_t hndl = static_cast<Handle_t>(params[1]);
HandleError herr;
HandleSecurity sec;
IDataPack *pDataPack;
CDataPack *pDataPack;
sec.pOwner = pContext->GetIdentity();
sec.pIdentity = g_pCoreIdent;
@@ -325,12 +372,12 @@ static cell_t smn_SetPackPosition(IPluginContext *pContext, const cell_t *params
if ((herr=handlesys->ReadHandle(hndl, g_DataPackType, &sec, (void **)&pDataPack))
!= HandleError_None)
{
return pContext->ThrowNativeError("Invalid data pack handle %x (error %d)", hndl, herr);
return pContext->ThrowNativeError("Invalid data pack handle %x (error %d).", hndl, herr);
}
if (!pDataPack->SetPosition(params[2]))
{
return pContext->ThrowNativeError("Invalid DataPack position, %d is out of bounds", params[2]);
return pContext->ThrowNativeError("Invalid data pack position, %d is out of bounds (%d)", params[2], pDataPack->GetCapacity());
}
return 1;
@@ -341,7 +388,7 @@ static cell_t smn_IsPackReadable(IPluginContext *pContext, const cell_t *params)
Handle_t hndl = static_cast<Handle_t>(params[1]);
HandleError herr;
HandleSecurity sec;
IDataPack *pDataPack;
CDataPack *pDataPack;
sec.pOwner = pContext->GetIdentity();
sec.pIdentity = g_pCoreIdent;
@@ -349,7 +396,7 @@ static cell_t smn_IsPackReadable(IPluginContext *pContext, const cell_t *params)
if ((herr=handlesys->ReadHandle(hndl, g_DataPackType, &sec, (void **)&pDataPack))
!= HandleError_None)
{
return pContext->ThrowNativeError("Invalid data pack handle %x (error %d)", hndl, herr);
return pContext->ThrowNativeError("Invalid data pack handle %x (error %d).", hndl, herr);
}
return pDataPack->IsReadable(params[2]) ? 1 : 0;
+2 -2
View File
@@ -113,14 +113,14 @@ static cell_t CreateNative(IPluginContext *pContext, const cell_t *params)
IPluginFunction *pFunction = pContext->GetFunctionById(params[2]);
if (!pFunction)
{
return pContext->ThrowNativeError("Function %x is not a valid function", params[2]);
return pContext->ThrowNativeError("Failed to create native \"%s\", function %x is not a valid function", name, params[2]);
}
pPlugin = g_PluginSys.GetPluginByCtx(pContext->GetContext());
if (!pPlugin->AddFakeNative(pFunction, name, FakeNativeRouter))
{
return pContext->ThrowNativeError("Fatal error creating dynamic native!");
return pContext->ThrowNativeError("Failed to create native \"%s\", name is probably already in use", name);
}
return 1;
+2 -1
View File
@@ -321,7 +321,7 @@ static cell_t sm_OpenDirectory(IPluginContext *pContext, const cell_t *params)
{
size_t len = strlen(path);
char wildcardedPath[PLATFORM_MAX_PATH];
snprintf(wildcardedPath, sizeof(wildcardedPath), "%s%s*", path, (path[len-1] != '/' && path[len-1] != '\\') ? "/" : "");
ke::SafeSprintf(wildcardedPath, sizeof(wildcardedPath), "%s%s*", path, (path[len-1] != '/' && path[len-1] != '\\') ? "/" : "");
char *pathID;
if ((err=pContext->LocalToStringNULL(params[3], &pathID)) != SP_ERROR_NONE)
@@ -1195,6 +1195,7 @@ REGISTER_NATIVES(filesystem)
{"File.WriteLine", sm_WriteFileLine},
{"File.EndOfFile", sm_IsEndOfFile},
{"File.Seek", sm_FileSeek},
{"File.Flush", sm_FlushFile},
{"File.Position.get", sm_FilePosition},
{"File.ReadInt8", File_ReadTyped<int8_t>},
{"File.ReadUint8", File_ReadTyped<uint8_t>},
+32 -85
View File
@@ -35,8 +35,6 @@
#include <IForwardSys.h>
#include <ISourceMod.h>
#include <amtl/am-autoptr.h>
#include "ShareSys.h"
#include "NativeInvoker.h"
HandleType_t g_GlobalFwdType = 0;
HandleType_t g_PrivateFwdType = 0;
@@ -45,7 +43,6 @@ static bool s_CallStarted = false;
static ICallable *s_pCallable = NULL;
static IPluginFunction *s_pFunction = NULL;
static IForward *s_pForward = NULL;
static NativeInvoker *s_pInvoker = NULL;
class ForwardNativeHelpers :
public SMGlobalClass,
@@ -105,9 +102,6 @@ inline void ResetCall()
s_pFunction = NULL;
s_pForward = NULL;
s_pCallable = NULL;
if(s_pInvoker)
delete s_pInvoker;
s_pInvoker = NULL;
}
static cell_t sm_GetFunctionByName(IPluginContext *pContext, const cell_t *params)
@@ -372,27 +366,6 @@ static cell_t sm_CallStartForward(IPluginContext *pContext, const cell_t *params
return 1;
}
static cell_t sm_CallStartNative(IPluginContext *pContext, const cell_t *params)
{
ResetCall();
char *name;
pContext->LocalToString(params[1], &name);
ke::RefPtr<Native> pNative = g_ShareSys.FindNative(name);
if (!pNative)
return 0;//pContext->ThrowNativeError("Invalid native \"%s\"", name);
s_pInvoker = new NativeInvoker(pContext, pNative);
s_pCallable = static_cast<ICallable *>(s_pInvoker);
s_CallStarted = true;
return 1;
}
static cell_t sm_CallPushCell(IPluginContext *pContext, const cell_t *params)
{
int err;
@@ -683,39 +656,6 @@ static cell_t sm_CallFinish(IPluginContext *pContext, const cell_t *params)
IForward *pForward = s_pForward;
ResetCall();
err = pForward->Execute(result, NULL);
} else if (s_pInvoker) {
err = s_pInvoker->Execute(result);
ResetCall();
}
return err;
}
static cell_t sm_CallFinishEx(IPluginContext *pContext, const cell_t *params)
{
int err = SP_ERROR_NOT_RUNNABLE;
cell_t *result;
if (!s_CallStarted)
{
return pContext->ThrowNativeError("Cannot finish call when there is no call in progress");
}
pContext->LocalToPhysAddr(params[1], &result);
// Note: Execute() swallows exceptions, so this is okay.
if (s_pFunction)
{
IPluginFunction *pFunction = s_pFunction;
ResetCall();
err = pFunction->Execute(result, params[2], params[3]);
} else if (s_pForward) {
IForward *pForward = s_pForward;
ResetCall();
err = pForward->Execute(result, NULL);
} else if (s_pInvoker) {
err = s_pInvoker->Execute(result, params[2], params[3]);
ResetCall();
}
return err;
@@ -793,29 +733,36 @@ static cell_t sm_AddFrameAction(IPluginContext *pContext, const cell_t *params)
REGISTER_NATIVES(functionNatives)
{
{"GetFunctionByName", sm_GetFunctionByName},
{"CreateGlobalForward", sm_CreateGlobalForward},
{"CreateForward", sm_CreateForward},
{"GetForwardFunctionCount", sm_GetForwardFunctionCount},
{"AddToForward", sm_AddToForward},
{"RemoveFromForward", sm_RemoveFromForward},
{"RemoveAllFromForward", sm_RemoveAllFromForward},
{"Call_StartFunction", sm_CallStartFunction},
{"Call_StartForward", sm_CallStartForward},
{"Call_StartNative", sm_CallStartNative},
{"Call_PushCell", sm_CallPushCell},
{"Call_PushCellRef", sm_CallPushCellRef},
{"Call_PushFloat", sm_CallPushFloat},
{"Call_PushFloatRef", sm_CallPushFloatRef},
{"Call_PushArray", sm_CallPushArray},
{"Call_PushArrayEx", sm_CallPushArrayEx},
{"Call_PushString", sm_CallPushString},
{"Call_PushStringEx", sm_CallPushStringEx},
{"Call_PushNullVector", sm_CallPushNullVector},
{"Call_PushNullString", sm_CallPushNullString},
{"Call_Finish", sm_CallFinish},
{"Call_FinishEx", sm_CallFinishEx},
{"Call_Cancel", sm_CallCancel},
{"RequestFrame", sm_AddFrameAction},
{NULL, NULL},
{"GetFunctionByName", sm_GetFunctionByName},
{"CreateGlobalForward", sm_CreateGlobalForward},
{"CreateForward", sm_CreateForward},
{"GetForwardFunctionCount", sm_GetForwardFunctionCount},
{"AddToForward", sm_AddToForward},
{"RemoveFromForward", sm_RemoveFromForward},
{"RemoveAllFromForward", sm_RemoveAllFromForward},
{"Call_StartFunction", sm_CallStartFunction},
{"Call_StartForward", sm_CallStartForward},
{"Call_PushCell", sm_CallPushCell},
{"Call_PushCellRef", sm_CallPushCellRef},
{"Call_PushFloat", sm_CallPushFloat},
{"Call_PushFloatRef", sm_CallPushFloatRef},
{"Call_PushArray", sm_CallPushArray},
{"Call_PushArrayEx", sm_CallPushArrayEx},
{"Call_PushString", sm_CallPushString},
{"Call_PushStringEx", sm_CallPushStringEx},
{"Call_PushNullVector", sm_CallPushNullVector},
{"Call_PushNullString", sm_CallPushNullString},
{"Call_Finish", sm_CallFinish},
{"Call_Cancel", sm_CallCancel},
{"RequestFrame", sm_AddFrameAction},
{"GlobalForward.GlobalForward", sm_CreateGlobalForward},
{"GlobalForward.FunctionCount.get", sm_GetForwardFunctionCount},
{"PrivateForward.PrivateForward", sm_CreateForward},
{"PrivateForward.AddFunction", sm_AddToForward},
{"PrivateForward.RemoveFunction", sm_RemoveFromForward},
{"PrivateForward.RemoveAllFunctions", sm_RemoveAllFromForward},
{NULL, NULL},
};
+14 -1
View File
@@ -67,7 +67,10 @@ static cell_t smn_LoadGameConfigFile(IPluginContext *pCtx, const cell_t *params)
return pCtx->ThrowNativeError("Unable to open %s: %s", filename, error);
}
return handlesys->CreateHandle(g_GameConfigsType, gc, pCtx->GetIdentity(), g_pCoreIdent, NULL);
Handle_t hndl = handlesys->CreateHandle(g_GameConfigsType, gc, pCtx->GetIdentity(), g_pCoreIdent, NULL);
if (hndl == BAD_HANDLE)
g_GameConfigs.CloseGameConfigFile(gc);
return hndl;
}
static cell_t smn_GameConfGetOffset(IPluginContext *pCtx, const cell_t *params)
@@ -152,7 +155,11 @@ static cell_t smn_GameConfGetAddress(IPluginContext *pCtx, const cell_t *params)
if (!gc->GetAddress(key, &val))
return 0;
#ifdef PLATFORM_X86
return (cell_t)val;
#else
return pseudoAddr.ToPseudoAddress(val);
#endif
}
static GameConfigsNatives s_GameConfigsNatives;
@@ -163,5 +170,11 @@ REGISTER_NATIVES(gameconfignatives)
{"GameConfGetOffset", smn_GameConfGetOffset},
{"GameConfGetKeyValue", smn_GameConfGetKeyValue},
{"GameConfGetAddress", smn_GameConfGetAddress},
// Transitional syntax support.
{"GameData.GameData", smn_LoadGameConfigFile},
{"GameData.GetOffset", smn_GameConfGetOffset},
{"GameData.GetKeyValue", smn_GameConfGetKeyValue},
{"GameData.GetAddress", smn_GameConfGetAddress},
{NULL, NULL}
};
+1 -1
View File
@@ -68,7 +68,7 @@ static cell_t sm_LoadTranslations(IPluginContext *pCtx, const cell_t *params)
IPlugin *pl = pluginsys->FindPluginByContext(pCtx->GetContext());
pCtx->LocalToString(params[1], &filename);
ke::SafeSprintf(buffer, sizeof(buffer), "%s", filename);
ke::SafeStrcpy(buffer, sizeof(buffer), filename);
/* Make sure there is no extension */
if ((ext = strstr(buffer, ".txt")) != NULL
+102 -2
View File
@@ -321,9 +321,109 @@ public:
delete m_pCurMapList;
m_pCurMapList = NULL;
}
static bool alphanum_isdigit(const char c)
{
return c >= '0' && c <= '9';
}
static int alphanum_impl(const char *l, const char *r)
{
/**
* http://www.davekoelle.com/files/alphanum.hpp
*
* compare l and r with strcmp() semantics, but using
* the "Alphanum Algorithm". This function is designed to read
* through the l and r strings only one time, for
* maximum performance. It does not allocate memory for
* substrings.
*
* Released under the MIT License - https://opensource.org/licenses/MIT
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
enum mode_t { STRING, NUMBER } mode = STRING;
while (*l && *r)
{
if (mode == STRING)
{
char l_char, r_char;
while ((l_char = *l) && (r_char = *r))
{
// check if this are digit characters
const bool l_digit = alphanum_isdigit(l_char), r_digit = alphanum_isdigit(r_char);
// if both characters are digits, we continue in NUMBER mode
if (l_digit && r_digit)
{
mode = NUMBER;
break;
}
// if only the left character is a digit, we have a result
if (l_digit) return -1;
// if only the right character is a digit, we have a result
if (r_digit) return +1;
// compute the difference of both characters
const int diff = l_char - r_char;
// if they differ we have a result
if (diff != 0) return diff;
// otherwise process the next characters
++l;
++r;
}
}
else // mode == NUMBER
{
// get the left number
unsigned long l_int = 0;
while (*l && alphanum_isdigit(*l))
{
// TODO: this can overflow
l_int = l_int * 10 + *l - '0';
++l;
}
// get the right number
unsigned long r_int = 0;
while (*r && alphanum_isdigit(*r))
{
// TODO: this can overflow
r_int = r_int * 10 + *r - '0';
++r;
}
// if the difference is not equal to zero, we have a comparison result
const long diff = l_int - r_int;
if (diff != 0)
return diff;
// otherwise we process the next substring in STRING mode
mode = STRING;
}
}
if (*r) return -1;
if (*l) return +1;
return 0;
}
static int sort_maps_in_adt_array(const void *str1, const void *str2)
{
return strcmp((char *)str1, (char *)str2);
return alphanum_impl(static_cast<const char *>(str1), static_cast<const char *>(str2));
}
ICellArray *UpdateMapList(ICellArray *pUseArray, const char *name, int *pSerial, unsigned int flags)
{
@@ -341,7 +441,7 @@ public:
*/
if (strcmp(name, "default") != 0)
{
success = GetMapList(&pNewArray, name, &change_serial);
success = GetMapList(&pNewArray, "default", &change_serial);
}
/* If either of the last two conditions failed, try again if we can. */
if (!success && strcmp(name, "mapcyclefile") != 0)
+1 -62
View File
@@ -816,14 +816,8 @@ static cell_t GetMenuItem(IPluginContext *pContext, const cell_t *params)
ItemDrawInfo dr;
const char *info;
cell_t client = (params[0] >= 8) ? params[8] : 0;
if(!client && menu->IsPerClientShuffled())
{
return pContext->ThrowNativeError("This menu has been per-client random shuffled. "
"You have to call GetMenuItem with a client index!");
}
if ((info=menu->GetItemInfo(params[2], &dr, client)) == NULL)
if ((info=menu->GetItemInfo(params[2], &dr)) == NULL)
{
return 0;
}
@@ -838,57 +832,6 @@ static cell_t GetMenuItem(IPluginContext *pContext, const cell_t *params)
return 1;
}
static cell_t MenuShufflePerClient(IPluginContext *pContext, const cell_t *params)
{
Handle_t hndl = (Handle_t)params[1];
HandleError err;
IBaseMenu *menu;
if ((err = ReadMenuHandle(params[1], &menu)) != HandleError_None)
{
return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
}
int start = params[2];
int stop = params[3];
if (stop > 0 && !(stop >= start))
{
return pContext->ThrowNativeError("Stop must be -1 or >= start!");
}
menu->ShufflePerClient(start, stop);
return 1;
}
static cell_t MenuSetClientMapping(IPluginContext *pContext, const cell_t *params)
{
Handle_t hndl = (Handle_t)params[1];
HandleError err;
IBaseMenu *menu;
if ((err = ReadMenuHandle(params[1], &menu)) != HandleError_None)
{
return pContext->ThrowNativeError("Menu handle %x is invalid (error %d)", hndl, err);
}
int client = params[2];
if (client < 1 || client > SM_MAXPLAYERS)
{
return pContext->ThrowNativeError("Invalid client index!");
}
cell_t *array;
pContext->LocalToPhysAddr(params[3], &array);
int length = params[4];
menu->SetClientMapping(client, array, length);
return 1;
}
static cell_t SetMenuPagination(IPluginContext *pContext, const cell_t *params)
{
Handle_t hndl = (Handle_t)params[1];
@@ -1702,8 +1645,6 @@ REGISTER_NATIVES(menuNatives)
{"SetPanelKeys", SetPanelKeys},
{"SetVoteResultCallback", SetVoteResultCallback},
{"VoteMenu", VoteMenu},
{"MenuShufflePerClient", MenuShufflePerClient},
{"MenuSetClientMapping", MenuSetClientMapping},
{"SetMenuNoVoteButton", SetMenuNoVoteButton},
// Transitional syntax support.
@@ -1732,8 +1673,6 @@ REGISTER_NATIVES(menuNatives)
{"Menu.ToPanel", CreatePanelFromMenu},
{"Menu.Cancel", CancelMenu},
{"Menu.DisplayVote", VoteMenu},
{"Menu.ShufflePerClient", MenuShufflePerClient},
{"Menu.SetClientMapping", MenuSetClientMapping},
{"Menu.Pagination.get", GetMenuPagination},
{"Menu.Pagination.set", SetMenuPagination},
{"Menu.OptionFlags.get", GetMenuOptionFlags},
+28 -32
View File
@@ -64,10 +64,13 @@ static const int kActivityAdmins = 4; // Show admin activity to admins anonymo
static const int kActivityAdminsNames = 8; // If 4 is specified, admin names will be shown.
static const int kActivityRootNames = 16; // Always show admin names to root users.
#define FEATURECAP_MULTITARGETFILTER_CLIENTPARAM "SourceMod MultiTargetFilter ClientParam"
class PlayerLogicHelpers :
public SMGlobalClass,
public IPluginsListener,
public ICommandTargetProcessor
public ICommandTargetProcessor,
public IFeatureProvider
{
struct SimpleMultiTargetFilter
{
@@ -186,6 +189,7 @@ public: //SMGlobalClass
void OnSourceModAllInitialized()
{
pluginsys->AddPluginsListener(this);
sharesys->AddCapabilityProvider(NULL, this, FEATURECAP_MULTITARGETFILTER_CLIENTPARAM);
}
void OnSourceModShutdown()
@@ -195,6 +199,7 @@ public: //SMGlobalClass
playerhelpers->UnregisterCommandTargetProcessor(this);
filterEnabled = false;
}
sharesys->DropCapabilityProvider(NULL, this, FEATURECAP_MULTITARGETFILTER_CLIENTPARAM);
}
public: //IPluginsListener
@@ -212,6 +217,13 @@ public: //IPluginsListener
}
}
}
public: //IFeatureProvider
FeatureStatus GetFeatureStatus(FeatureType type, const char *name)
{
return FeatureStatus_Available;
}
} s_PlayerLogicHelpers;
static cell_t
@@ -398,7 +410,7 @@ static cell_t SteamIdToLocal(IPluginContext *pCtx, int index, AuthIdType authTyp
}
char szAuth[64];
snprintf(szAuth, sizeof(szAuth), "%" PRIu64, steamId);
ke::SafeSprintf(szAuth, sizeof(szAuth), "%" PRIu64, steamId);
pCtx->StringToLocal(local_addr, bytes, szAuth);
}
@@ -1124,7 +1136,6 @@ static cell_t _ShowActivity(IPluginContext *pContext,
{
IGamePlayer *pPlayer = playerhelpers->GetGamePlayer(i);
if (!pPlayer->IsInGame()
|| pPlayer->IsFakeClient()
|| (display_in_chat && i == client))
{
continue;
@@ -1251,7 +1262,6 @@ static cell_t _ShowActivity2(IPluginContext *pContext,
{
IGamePlayer *pPlayer = playerhelpers->GetGamePlayer(i);
if (!pPlayer->IsInGame()
|| pPlayer->IsFakeClient()
|| i == client)
{
continue;
@@ -1461,23 +1471,24 @@ static cell_t IsClientInKickQueue(IPluginContext *pContext, const cell_t *params
return pPlayer->IsInKickQueue() ? 1 : 0;
}
cmd_target_info_t g_ProcessTargetString_info;
static cell_t ProcessTargetString(IPluginContext *pContext, const cell_t *params)
{
pContext->LocalToString(params[1], (char **) &g_ProcessTargetString_info.pattern);
g_ProcessTargetString_info.admin = params[2];
pContext->LocalToPhysAddr(params[3], &g_ProcessTargetString_info.targets);
g_ProcessTargetString_info.max_targets = params[4];
g_ProcessTargetString_info.flags = params[5];
pContext->LocalToString(params[6], &g_ProcessTargetString_info.target_name);
g_ProcessTargetString_info.target_name_maxlength = params[7];
cmd_target_info_t info;
pContext->LocalToString(params[1], (char **) &info.pattern);
info.admin = params[2];
pContext->LocalToPhysAddr(params[3], &info.targets);
info.max_targets = params[4];
info.flags = params[5];
pContext->LocalToString(params[6], &info.target_name);
info.target_name_maxlength = params[7];
cell_t *tn_is_ml;
pContext->LocalToPhysAddr(params[8], &tn_is_ml);
playerhelpers->ProcessCommandTarget(&g_ProcessTargetString_info);
playerhelpers->ProcessCommandTarget(&info);
if (g_ProcessTargetString_info.target_name_style == COMMAND_TARGETNAME_ML)
if (info.target_name_style == COMMAND_TARGETNAME_ML)
{
*tn_is_ml = 1;
}
@@ -1486,30 +1497,16 @@ static cell_t ProcessTargetString(IPluginContext *pContext, const cell_t *params
*tn_is_ml = 0;
}
if (g_ProcessTargetString_info.num_targets == 0)
if (info.num_targets == 0)
{
return g_ProcessTargetString_info.reason;
return info.reason;
}
else
{
return g_ProcessTargetString_info.num_targets;
return info.num_targets;
}
}
static cell_t GetLastProcessTargetString(IPluginContext *pContext, const cell_t *params)
{
cell_t *admin, *flags;
pContext->StringToLocalUTF8(params[1], params[2], g_ProcessTargetString_info.pattern, NULL);
pContext->LocalToPhysAddr(params[3], &admin);
pContext->LocalToPhysAddr(params[4], &flags);
*admin = g_ProcessTargetString_info.admin;
*flags = g_ProcessTargetString_info.flags;
return 0;
}
static cell_t FormatActivitySource(IPluginContext *pContext, const cell_t *params)
{
int value;
@@ -1661,7 +1658,6 @@ REGISTER_NATIVES(playernatives)
{ "NotifyPostAdminCheck", NotifyPostAdminCheck },
{ "IsClientInKickQueue", IsClientInKickQueue },
{ "ProcessTargetString", ProcessTargetString },
{ "GetLastProcessTargetString", GetLastProcessTargetString },
{ "FormatActivitySource", FormatActivitySource },
{ "GetClientSerial", sm_GetClientSerial },
{ "GetClientFromSerial", sm_GetClientFromSerial },
+5
View File
@@ -223,6 +223,11 @@ REGISTER_NATIVES(profilerNatives)
{"EnterProfilingEvent", EnterProfilingEvent},
{"LeaveProfilingEvent", LeaveProfilingEvent},
{"IsProfilingActive", IsProfilingActive},
{"Profiler.Profiler", CreateProfiler},
{"Profiler.Time.get", GetProfilerTime},
{"Profiler.Start", StartProfiling},
{"Profiler.Stop", StopProfiling},
{NULL, NULL},
};
+12 -8
View File
@@ -584,12 +584,16 @@ static cell_t sm_SortADTArrayCustom(IPluginContext *pContext, const cell_t *para
REGISTER_NATIVES(sortNatives)
{
{"SortIntegers", sm_SortIntegers},
{"SortFloats", sm_SortFloats},
{"SortStrings", sm_SortStrings},
{"SortCustom1D", sm_SortCustom1D},
{"SortCustom2D", sm_SortCustom2D},
{"SortADTArray", sm_SortADTArray},
{"SortADTArrayCustom", sm_SortADTArrayCustom},
{NULL, NULL},
{"SortIntegers", sm_SortIntegers},
{"SortFloats", sm_SortFloats},
{"SortStrings", sm_SortStrings},
{"SortCustom1D", sm_SortCustom1D},
{"SortCustom2D", sm_SortCustom2D},
{"SortADTArray", sm_SortADTArray},
{"SortADTArrayCustom", sm_SortADTArrayCustom},
{"ArrayList.Sort", sm_SortADTArray},
{"ArrayList.SortCustom", sm_SortADTArrayCustom},
{NULL, NULL},
};
+3 -9
View File
@@ -1171,18 +1171,12 @@ reswitch:
int userid;
if (!bridge->DescribePlayer(*value, &name, &auth, &userid))
return pCtx->ThrowNativeError("Client index %d is invalid (arg %d)", *value, arg);
ke::SafeSprintf(buffer,
sizeof(buffer),
"%s<%d><%s><>",
name,
userid,
auth);
ke::SafeSprintf(buffer, sizeof(buffer), "%s<%d><%s><>", name, userid, auth);
}
else
{
ke::SafeSprintf(buffer,
sizeof(buffer),
"Console<0><Console><Console>");
ke::SafeStrcpy(buffer, sizeof(buffer), "Console<0><Console><Console>");
}
if (!AddString(&buf_p, llen, buffer, width, prec, flags))
return pCtx->ThrowNativeError("Escaped string would be truncated (arg %d)", arg);
+10 -2
View File
@@ -381,7 +381,11 @@ public:
{
if (len > max_size)
{
buffer = (char *)realloc(buffer, len);
auto *newbuffer = static_cast<char *>(realloc(buffer, len));
if (!newbuffer)
return nullptr;
buffer = newbuffer;
max_size = len;
}
return buffer;
@@ -420,7 +424,11 @@ cell_t InternalFormat(IPluginContext *pCtx, const cell_t *params, int start)
{
if (maxlen > sizeof(g_formatbuf))
{
__copy_buf = g_extrabuf.GetWithSize(maxlen);
char *tmpbuff = g_extrabuf.GetWithSize(maxlen);
if (!tmpbuff)
return pCtx->ThrowNativeError("Unable to allocate buffer with a size of \"%u\"", maxlen);
__copy_buf = tmpbuff;
}
else
{
+4 -12
View File
@@ -52,8 +52,6 @@
#include <bridge/include/IPlayerInfoBridge.h>
#include <bridge/include/IFileSystemBridge.h>
#define MATCHMAKINGDS_NAME "matchmaking_ds" SOURCE_BIN_SUFFIX SOURCE_BIN_EXT
sm_logic_t logicore;
IThreader *g_pThreader = nullptr;
@@ -629,13 +627,7 @@ void CoreProviderImpl::InitializeBridge()
this->serverFactory = (void *)g_SMAPI->GetServerFactory(false);
this->listeners = SMGlobalClass::head;
char path[PLATFORM_MAX_PATH];
ke::path::Format(path, sizeof(path),
"%s/bin/" MATCHMAKINGDS_NAME,
g_SMAPI->GetBaseDir());
if (ke::RefPtr<ke::SharedLib> mmlib = ke::SharedLib::Open(path, NULL, 0)) {
if (ke::RefPtr<ke::SharedLib> mmlib = ke::SharedLib::Open(FORMAT_SOURCE_BIN_NAME("matchmaking_ds"), NULL, 0)) {
this->matchmakingDSFactory =
mmlib->get<decltype(sCoreProviderImpl.matchmakingDSFactory)>("CreateInterface");
}
@@ -668,7 +660,7 @@ bool CoreProviderImpl::LoadBridge(char *error, size_t maxlength)
/* Now it's time to load the logic binary */
g_SMAPI->PathFormat(file,
sizeof(file),
"%s/bin/sourcemod.logic." PLATFORM_LIB_EXT,
"%s/bin/" PLATFORM_ARCH_FOLDER "sourcemod.logic." PLATFORM_LIB_EXT,
g_SourceMod.GetSourceModPath());
char myerror[255];
@@ -681,7 +673,7 @@ bool CoreProviderImpl::LoadBridge(char *error, size_t maxlength)
LogicLoadFunction llf = logic_->get<decltype(llf)>("logic_load");
if (!llf) {
logic_ = nullptr;
ke::SafeSprintf(error, maxlength, "could not find logic_load function");
ke::SafeStrcpy(error, maxlength, "could not find logic_load function");
return false;
}
@@ -690,7 +682,7 @@ bool CoreProviderImpl::LoadBridge(char *error, size_t maxlength)
logic_init_ = llf(SM_LOGIC_MAGIC);
if (!logic_init_) {
ke::SafeSprintf(error, maxlength, "component version mismatch");
ke::SafeStrcpy(error, maxlength, "component version mismatch");
return false;
}
return true;
+147 -15
View File
@@ -712,7 +712,8 @@ static cell_t sm_RegServerCmd(IPluginContext *pContext, const cell_t *params)
return pContext->ThrowNativeError("Invalid function id (%X)", params[2]);
}
if (!g_ConCmds.AddServerCommand(pFunction, name, help, params[4]))
IPlugin *pPlugin = scripts->FindPluginByContext(pContext->GetContext());
if (!g_ConCmds.AddServerCommand(pFunction, name, help, params[4], pPlugin))
{
return pContext->ThrowNativeError("Command \"%s\" could not be created. A convar with the same name already exists.", name);
}
@@ -742,7 +743,7 @@ static cell_t sm_RegConsoleCmd(IPluginContext *pContext, const cell_t *params)
IPlugin *pPlugin = scripts->FindPluginByContext(pContext->GetContext());
const char *group = pPlugin->GetFilename();
if (!g_ConCmds.AddAdminCommand(pFunction, name, group, 0, help, params[4]))
if (!g_ConCmds.AddAdminCommand(pFunction, name, group, 0, help, params[4], pPlugin))
{
return pContext->ThrowNativeError("Command \"%s\" could not be created. A convar with the same name already exists.", name);
}
@@ -769,9 +770,9 @@ static cell_t sm_RegAdminCmd(IPluginContext *pContext, const cell_t *params)
pContext->LocalToString(params[5], (char **)&group);
pFunction = pContext->GetFunctionById(params[2]);
IPlugin *pPlugin = scripts->FindPluginByContext(pContext->GetContext());
if (group[0] == '\0')
{
IPlugin *pPlugin = scripts->FindPluginByContext(pContext->GetContext());
group = pPlugin->GetFilename();
}
@@ -780,7 +781,7 @@ static cell_t sm_RegAdminCmd(IPluginContext *pContext, const cell_t *params)
return pContext->ThrowNativeError("Invalid function id (%X)", params[2]);
}
if (!g_ConCmds.AddAdminCommand(pFunction, name, group, flags, help, cmdflags))
if (!g_ConCmds.AddAdminCommand(pFunction, name, group, flags, help, cmdflags, pPlugin))
{
return pContext->ThrowNativeError("Command \"%s\" could not be created. A convar with the same name already exists.", name);
}
@@ -788,16 +789,6 @@ static cell_t sm_RegAdminCmd(IPluginContext *pContext, const cell_t *params)
return 1;
}
static cell_t sm_IsCommandCallback(IPluginContext *pContext, const cell_t *params)
{
const ICommandArgs *pCmd = g_HL2.PeekCommandStack();
if (!pCmd)
return 0;
return 1;
}
static cell_t sm_GetCmdArgs(IPluginContext *pContext, const cell_t *params)
{
const ICommandArgs *pCmd = g_HL2.PeekCommandStack();
@@ -1317,6 +1308,141 @@ static cell_t FakeClientCommandKeyValues(IPluginContext *pContext, const cell_t
#endif
}
static cell_t sm_CommandIterator(IPluginContext *pContext, const cell_t *params)
{
GlobCmdIter *iter = new GlobCmdIter;
iter->started = false;
Handle_t hndl = handlesys->CreateHandle(hCmdIterType, iter, pContext->GetIdentity(), g_pCoreIdent, NULL);
if (hndl == BAD_HANDLE)
{
delete iter;
}
return hndl;
}
static cell_t sm_CommandIteratorNext(IPluginContext *pContext, const cell_t *params)
{
GlobCmdIter *iter;
HandleError err;
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
if ((err = handlesys->ReadHandle(params[1], hCmdIterType, &sec, (void **)&iter))
!= HandleError_None)
{
return pContext->ThrowNativeError("Invalid CommandIterator Handle %x", params[1]);
}
const List<ConCmdInfo *> &cmds = g_ConCmds.GetCommandList();
if (!iter->started)
{
iter->iter = cmds.begin();
iter->started = true;
}
else
{
iter->iter++;
}
// iterate further, skip non-sourcemod cmds
while (iter->iter != cmds.end() && !(*(iter->iter))->sourceMod)
{
iter->iter++;
}
return iter->iter != cmds.end();
}
static cell_t sm_CommandIteratorFlags(IPluginContext *pContext, const cell_t *params)
{
GlobCmdIter *iter;
HandleError err;
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
if ((err = handlesys->ReadHandle(params[1], hCmdIterType, &sec, (void **)&iter))
!= HandleError_None)
{
return pContext->ThrowNativeError("Invalid CommandIterator Handle %x", params[1]);
}
const List<ConCmdInfo *> &cmds = g_ConCmds.GetCommandList();
if (!iter->started || iter->iter == cmds.end())
{
return pContext->ThrowNativeError("Invalid CommandIterator position");
}
ConCmdInfo *pInfo = (*(iter->iter));
return pInfo->eflags;
}
static cell_t sm_CommandIteratorGetDesc(IPluginContext *pContext, const cell_t *params)
{
GlobCmdIter *iter;
HandleError err;
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
if ((err = handlesys->ReadHandle(params[1], hCmdIterType, &sec, (void **)&iter))
!= HandleError_None)
{
return pContext->ThrowNativeError("Invalid CommandIterator Handle %x", params[1]);
}
const List<ConCmdInfo *> &cmds = g_ConCmds.GetCommandList();
if (!iter->started || iter->iter == cmds.end())
{
return pContext->ThrowNativeError("Invalid CommandIterator position");
}
ConCmdInfo *pInfo = (*(iter->iter));
pContext->StringToLocalUTF8(params[2], params[3], pInfo->pCmd->GetHelpText(), NULL);
return 1;
}
static cell_t sm_CommandIteratorGetName(IPluginContext *pContext, const cell_t *params)
{
GlobCmdIter *iter;
HandleError err;
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
if ((err = handlesys->ReadHandle(params[1], hCmdIterType, &sec, (void **)&iter))
!= HandleError_None)
{
return pContext->ThrowNativeError("Invalid CommandIterator Handle %x", params[1]);
}
const List<ConCmdInfo *> &cmds = g_ConCmds.GetCommandList();
if (!iter->started || iter->iter == cmds.end())
{
return pContext->ThrowNativeError("Invalid CommandIterator position");
}
ConCmdInfo *pInfo = (*(iter->iter));
pContext->StringToLocalUTF8(params[2], params[3], pInfo->pCmd->GetName(), NULL);
return 1;
}
static cell_t sm_CommandIteratorPlugin(IPluginContext *pContext, const cell_t *params)
{
GlobCmdIter *iter;
HandleError err;
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
if ((err = handlesys->ReadHandle(params[1], hCmdIterType, &sec, (void **)&iter))
!= HandleError_None)
{
return pContext->ThrowNativeError("Invalid CommandIterator Handle %x", params[1]);
}
const List<ConCmdInfo *> &cmds = g_ConCmds.GetCommandList();
if (!iter->started || iter->iter == cmds.end())
{
return pContext->ThrowNativeError("Invalid CommandIterator position");
}
ConCmdInfo *pInfo = (*(iter->iter));
return pInfo->pPlugin->GetMyHandle();
}
REGISTER_NATIVES(consoleNatives)
{
{"CreateConVar", sm_CreateConVar},
@@ -1341,7 +1467,6 @@ REGISTER_NATIVES(consoleNatives)
{"GetConVarDefault", GetConVarDefault},
{"RegServerCmd", sm_RegServerCmd},
{"RegConsoleCmd", sm_RegConsoleCmd},
{"IsCommandCallback", sm_IsCommandCallback},
{"GetCmdArgString", sm_GetCmdArgString},
{"GetCmdArgs", sm_GetCmdArgs},
{"GetCmdArg", sm_GetCmdArg},
@@ -1383,5 +1508,12 @@ REGISTER_NATIVES(consoleNatives)
{"ConVar.AddChangeHook", sm_HookConVarChange},
{"ConVar.RemoveChangeHook", sm_UnhookConVarChange},
{"CommandIterator.CommandIterator", sm_CommandIterator},
{"CommandIterator.Next", sm_CommandIteratorNext},
{"CommandIterator.GetDescription", sm_CommandIteratorGetDesc},
{"CommandIterator.GetName", sm_CommandIteratorGetName},
{"CommandIterator.Flags.get", sm_CommandIteratorFlags},
{"CommandIterator.Plugin.get", sm_CommandIteratorPlugin},
{NULL, NULL}
};
+7 -2
View File
@@ -2595,7 +2595,7 @@ static cell_t GetEntityFlags(IPluginContext *pContext, const cell_t *params)
for (int32_t i = 0; i < 32; i++)
{
int32_t flag = (1<<i);
int32_t flag = (1U<<i);
if ((actual_flags & flag) == flag)
{
sm_flags |= SDKEntFlagToSMEntFlag(flag);
@@ -2641,7 +2641,7 @@ static cell_t SetEntityFlags(IPluginContext *pContext, const cell_t *params)
for (int32_t i = 0; i < 32; i++)
{
int32_t flag = (1<<i);
int32_t flag = (1U<<i);
if ((sm_flags & flag) == flag)
{
actual_flags |= SMEntFlagToSDKEntFlag(flag);
@@ -2660,7 +2660,12 @@ static cell_t GetEntityAddress(IPluginContext *pContext, const cell_t *params)
{
return pContext->ThrowNativeError("Entity %d (%d) is invalid", g_HL2.ReferenceToIndex(params[1]), params[1]);
}
#ifdef PLATFORM_X86
return reinterpret_cast<cell_t>(pEntity);
#else
return g_SourceMod.ToPseudoAddress(pEntity);
#endif
}
REGISTER_NATIVES(entityNatives)
+17
View File
@@ -438,6 +438,22 @@ static cell_t sm_SetEventBroadcast(IPluginContext *pContext, const cell_t *param
return 1;
}
static cell_t sm_GetEventBroadcast(IPluginContext *pContext, const cell_t *params)
{
Handle_t hndl = static_cast<Handle_t>(params[1]);
HandleError err;
EventInfo *pInfo;
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
if ((err=handlesys->ReadHandle(hndl, g_EventManager.GetHandleType(), &sec, (void **)&pInfo))
!= HandleError_None)
{
return pContext->ThrowNativeError("Invalid game event handle %x (error %d)", hndl, err);
}
return pInfo->bDontBroadcast;
}
REGISTER_NATIVES(gameEventNatives)
{
{"HookEvent", sm_HookEvent},
@@ -471,6 +487,7 @@ REGISTER_NATIVES(gameEventNatives)
{"Event.SetFloat", sm_SetEventFloat},
{"Event.SetString", sm_SetEventString},
{"Event.BroadcastDisabled.set", sm_SetEventBroadcast},
{"Event.BroadcastDisabled.get", sm_GetEventBroadcast},
{NULL, NULL}
};
+1 -1
View File
@@ -1104,7 +1104,7 @@ static cell_t smn_KvGetSectionSymbol(IPluginContext *pCtx, const cell_t *params)
static cell_t KeyValues_Import(IPluginContext *pContext, const cell_t *params)
{
// This version takes (dest, src). The original is (src, dest).
cell_t new_params[3] = {
const cell_t new_params[3] = {
2,
params[2],
params[1],
-22
View File
@@ -356,27 +356,6 @@ static cell_t GetAvgPackets(IPluginContext *pContext, const cell_t *params)
return sp_ftoc(value);
}
static cell_t sm_GetClientIClient(IPluginContext *pContext, const cell_t *params)
{
int client = params[1];
CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
if (!pPlayer)
{
return pContext->ThrowNativeError("Client index %d is invalid", client);
}
else if (!pPlayer->IsConnected())
{
return pContext->ThrowNativeError("Client %d is not connected", client);
}
else if (pPlayer->IsFakeClient())
{
return pContext->ThrowNativeError("Client %d is a bot", client);
}
return (cell_t)pPlayer->GetIClient();
}
static cell_t RunAdminCacheChecks(IPluginContext *pContext, const cell_t *params)
{
int client = params[1];
@@ -413,7 +392,6 @@ REGISTER_NATIVES(playernatives)
{"GetClientAvgChoke", GetAvgChoke},
{"GetClientAvgData", GetAvgData},
{"GetClientAvgPackets", GetAvgPackets},
{"GetClientIClient", sm_GetClientIClient },
{"RunAdminCacheChecks", RunAdminCacheChecks},
{NULL, NULL}
};
+92
View File
@@ -82,6 +82,38 @@ static cell_t smn_PbReadInt(IPluginContext *pCtx, const cell_t *params)
return ret;
}
static cell_t smn_PbReadInt64(IPluginContext *pCtx, const cell_t *params)
{
GET_MSG_FROM_HANDLE_OR_ERR();
GET_FIELD_NAME_OR_ERR();
cell_t *ret;
pCtx->LocalToPhysAddr(params[3], &ret);
int64 temp;
((cell_t *)&temp)[0] = ret[0];
((cell_t *)&temp)[1] = ret[1];
if (params[4] < 0)
{
if (!msg->GetInt64OrUnsigned(strField, &temp))
{
return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
}
}
else
{
if (!msg->GetRepeatedInt64OrUnsigned(strField, params[4], &temp))
{
return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, params[4], msg->GetProtobufMessage()->GetTypeName().c_str());
}
}
ret[0] = ((cell_t *)&temp)[0];
ret[1] = ((cell_t *)&temp)[1];
return 1;
}
static cell_t smn_PbReadFloat(IPluginContext *pCtx, const cell_t *params)
{
GET_MSG_FROM_HANDLE_OR_ERR();
@@ -304,6 +336,14 @@ static cell_t smn_PbGetRepeatedFieldCount(IPluginContext *pCtx, const cell_t *pa
return cnt;
}
static cell_t smn_PbHasField(IPluginContext *pCtx, const cell_t *params)
{
GET_MSG_FROM_HANDLE_OR_ERR();
GET_FIELD_NAME_OR_ERR();
return msg->HasField(strField) ? 1 : 0;
}
static cell_t smn_PbSetInt(IPluginContext *pCtx, const cell_t *params)
{
GET_MSG_FROM_HANDLE_OR_ERR();
@@ -328,6 +368,35 @@ static cell_t smn_PbSetInt(IPluginContext *pCtx, const cell_t *params)
return 1;
}
static cell_t smn_PbSetInt64(IPluginContext *pCtx, const cell_t *params)
{
GET_MSG_FROM_HANDLE_OR_ERR();
GET_FIELD_NAME_OR_ERR();
cell_t *value;
pCtx->LocalToPhysAddr(params[3], &value);
int64 temp;
((cell_t *)&temp)[0] = value[0];
((cell_t *)&temp)[1] = value[1];
if (params[4] < 0)
{
if (!msg->SetInt64OrUnsigned(strField, temp))
{
return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
}
}
else
{
if (!msg->SetRepeatedInt64OrUnsigned(strField, params[4], temp))
{
return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, params[4], msg->GetProtobufMessage()->GetTypeName().c_str());
}
}
return 1;
}
static cell_t smn_PbSetFloat(IPluginContext *pCtx, const cell_t *params)
{
GET_MSG_FROM_HANDLE_OR_ERR();
@@ -545,6 +614,25 @@ static cell_t smn_PbAddInt(IPluginContext *pCtx, const cell_t *params)
return 1;
}
static cell_t smn_PbAddInt64(IPluginContext *pCtx, const cell_t *params)
{
GET_MSG_FROM_HANDLE_OR_ERR();
GET_FIELD_NAME_OR_ERR();
cell_t *value;
pCtx->LocalToPhysAddr(params[3], &value);
int64 temp;
((cell_t *)&temp)[0] = value[0];
((cell_t *)&temp)[1] = value[1];
if (!msg->AddInt64OrUnsigned(strField, temp))
{
return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
}
return 1;
}
static cell_t smn_PbAddFloat(IPluginContext *pCtx, const cell_t *params)
{
GET_MSG_FROM_HANDLE_OR_ERR();
@@ -770,6 +858,7 @@ REGISTER_NATIVES(protobufnatives)
// Transitional syntax.
{"Protobuf.ReadInt", smn_PbReadInt},
{"Protobuf.ReadInt64", smn_PbReadInt64},
{"Protobuf.ReadFloat", smn_PbReadFloat},
{"Protobuf.ReadBool", smn_PbReadBool},
{"Protobuf.ReadString", smn_PbReadString},
@@ -778,7 +867,9 @@ REGISTER_NATIVES(protobufnatives)
{"Protobuf.ReadVector", smn_PbReadVector},
{"Protobuf.ReadVector2D", smn_PbReadVector2D},
{"Protobuf.GetRepeatedFieldCount", smn_PbGetRepeatedFieldCount},
{"Protobuf.HasField", smn_PbHasField},
{"Protobuf.SetInt", smn_PbSetInt},
{"Protobuf.SetInt64", smn_PbSetInt64},
{"Protobuf.SetFloat", smn_PbSetFloat},
{"Protobuf.SetBool", smn_PbSetBool},
{"Protobuf.SetString", smn_PbSetString},
@@ -787,6 +878,7 @@ REGISTER_NATIVES(protobufnatives)
{"Protobuf.SetVector", smn_PbSetVector},
{"Protobuf.SetVector2D", smn_PbSetVector2D},
{"Protobuf.AddInt", smn_PbAddInt},
{"Protobuf.AddInt64", smn_PbAddInt64},
{"Protobuf.AddFloat", smn_PbAddFloat},
{"Protobuf.AddBool", smn_PbAddBool},
{"Protobuf.AddString", smn_PbAddString},
+1 -1
View File
@@ -110,7 +110,7 @@ bool SourceMod_Core::Load(PluginId id, ISmmAPI *ismm, char *error, size_t maxlen
{
if (error)
{
snprintf(error, maxlen, "Unable to find interface %s", MMIFACE_PLMANAGER);
ke::SafeSprintf(error, maxlen, "Unable to find interface %s", MMIFACE_PLMANAGER);
}
return false;
}
+20 -10
View File
@@ -107,7 +107,7 @@ ConfigResult SourceModBase::OnSourceModConfigChanged(const char *key,
{
if (source == ConfigSource_Console)
{
ke::SafeSprintf(error, maxlength, "Cannot be set at runtime");
ke::SafeStrcpy(error, maxlength, "Cannot be set at runtime");
return ConfigResult_Reject;
}
@@ -185,7 +185,7 @@ bool SourceModBase::InitializeSourceMod(char *error, size_t maxlength, bool late
/* Attempt to load the JIT! */
char file[PLATFORM_MAX_PATH];
char myerror[255];
g_SMAPI->PathFormat(file, sizeof(file), "%s/bin/sourcepawn.jit.x86.%s",
g_SMAPI->PathFormat(file, sizeof(file), "%s/bin/" PLATFORM_ARCH_FOLDER "sourcepawn.jit.x86.%s",
GetSourceModPath(),
PLATFORM_LIB_EXT
);
@@ -195,7 +195,7 @@ bool SourceModBase::InitializeSourceMod(char *error, size_t maxlength, bool late
{
if (error && maxlength)
{
ke::SafeSprintf(error, maxlength, "%s (failed to load bin/sourcepawn.jit.x86.%s)",
ke::SafeSprintf(error, maxlength, "%s (failed to load bin/" PLATFORM_ARCH_FOLDER "sourcepawn.jit.x86.%s)",
myerror,
PLATFORM_LIB_EXT);
}
@@ -207,7 +207,7 @@ bool SourceModBase::InitializeSourceMod(char *error, size_t maxlength, bool late
if (!factoryFn) {
if (error && maxlength)
snprintf(error, maxlength, "SourcePawn library is out of date");
ke::SafeStrcpy(error, maxlength, "SourcePawn library is out of date");
ShutdownJIT();
return false;
}
@@ -215,7 +215,7 @@ bool SourceModBase::InitializeSourceMod(char *error, size_t maxlength, bool late
ISourcePawnFactory *factory = factoryFn(SOURCEPAWN_API_VERSION);
if (!factory) {
if (error && maxlength)
snprintf(error, maxlength, "SourcePawn library is out of date");
ke::SafeStrcpy(error, maxlength, "SourcePawn library is out of date");
ShutdownJIT();
return false;
}
@@ -223,7 +223,7 @@ bool SourceModBase::InitializeSourceMod(char *error, size_t maxlength, bool late
g_pPawnEnv = factory->NewEnvironment();
if (!g_pPawnEnv) {
if (error && maxlength)
snprintf(error, maxlength, "Could not create a SourcePawn environment!");
ke::SafeStrcpy(error, maxlength, "Could not create a SourcePawn environment!");
ShutdownJIT();
return false;
}
@@ -617,14 +617,14 @@ unsigned int SourceModBase::GetGlobalTarget() const
return m_target;
}
IDataPack *SourceModBase::CreateDataPack()
void *SourceModBase::CreateDataPack()
{
return logicore.CreateDataPack();
return nullptr;
}
void SourceModBase::FreeDataPack(IDataPack *pack)
void SourceModBase::FreeDataPack(void *pack)
{
logicore.FreeDataPack(pack);
return;
}
Handle_t SourceModBase::GetDataPackHandleType(bool readonly)
@@ -745,6 +745,16 @@ bool SourceModBase::IsMapRunning()
return g_OnMapStarted;
}
void *SourceModBase::FromPseudoAddress(uint32_t pseudoAddr)
{
return logicore.FromPseudoAddress(pseudoAddr);
}
uint32_t SourceModBase::ToPseudoAddress(void *addr)
{
return logicore.ToPseudoAddress(addr);
}
class ConVarRegistrar :
public IConCommandBaseAccessor,
public SMGlobalClass
+4 -2
View File
@@ -113,8 +113,8 @@ public: // ISourceMod
void LogMessage(IExtension *pExt, const char *format, ...);
void LogError(IExtension *pExt, const char *format, ...);
size_t FormatString(char *buffer, size_t maxlength, IPluginContext *pContext, const cell_t *params, unsigned int param);
IDataPack *CreateDataPack();
void FreeDataPack(IDataPack *pack);
void *CreateDataPack();
void FreeDataPack(void *pack);
HandleType_t GetDataPackHandleType(bool readonly=false);
KeyValues *ReadKeyValuesHandle(Handle_t hndl, HandleError *err=NULL, bool root=false);
const char *GetGameFolderName() const;
@@ -135,6 +135,8 @@ public: // ISourceMod
int GetPluginId();
int GetShApiVersion();
bool IsMapRunning();
void *FromPseudoAddress(uint32_t pseudoAddr);
uint32_t ToPseudoAddress(void *addr);
private:
void ShutdownServices();
private:
+24 -21
View File
@@ -1,27 +1,30 @@
# vim: set sts=2 ts=8 sw=2 tw=99 et ft=python:
import os
binary = SM.ExtLibrary(builder, 'bintools.ext')
binary.compiler.defines += ['HOOKING_ENABLED']
binary.compiler.cxxincludes += [
os.path.join(SM.mms_root, 'core', 'sourcehook'),
os.path.join(builder.sourcePath, 'public', 'jit'),
os.path.join(builder.sourcePath, 'public', 'jit', 'x86'),
]
if binary.compiler.family == 'gcc' or binary.compiler.family == 'clang':
binary.compiler.cxxflags += ['-fno-rtti']
elif binary.compiler.family == 'msvc':
binary.compiler.cxxflags += ['/GR-']
for arch in SM.archs:
binary = SM.ExtLibrary(builder, 'bintools.ext', arch)
binary.compiler.defines += ['HOOKING_ENABLED']
binary.compiler.cxxincludes += [
os.path.join(SM.mms_root, 'core', 'sourcehook'),
os.path.join(builder.sourcePath, 'public', 'jit'),
os.path.join(builder.sourcePath, 'public', 'jit', 'x86'),
]
if binary.compiler.family == 'gcc' or binary.compiler.family == 'clang':
binary.compiler.cxxflags += ['-fno-rtti']
elif binary.compiler.family == 'msvc':
binary.compiler.cxxflags += ['/GR-']
binary.sources += [
'extension.cpp',
'CallMaker.cpp',
'CallWrapper.cpp',
'HookWrapper.cpp',
'jit_call.cpp',
'jit_hook.cpp',
'../../public/smsdk_ext.cpp'
]
binary.sources += [
'extension.cpp',
'CallMaker.cpp',
'CallWrapper.cpp',
'../../public/smsdk_ext.cpp'
]
if arch == 'x64':
binary.sources += ['jit_call_x64.cpp']
else:
binary.sources += ['jit_call.cpp']
SM.extensions += [builder.Add(binary)]
SM.extensions += [builder.Add(binary)]
+57 -4
View File
@@ -82,7 +82,8 @@ ICallWrapper *CallMaker::CreateCall(void *address,
CallConvention cv,
const PassInfo *retInfo,
const PassInfo paramInfo[],
unsigned int numParams)
unsigned int numParams,
unsigned int fnFlags)
{
SourceHook::CProtoInfoBuilder protoInfo(GetSHCallConvention(cv));
@@ -103,7 +104,11 @@ ICallWrapper *CallMaker::CreateCall(void *address,
NULL, NULL, NULL, NULL);
}
#if defined PLATFORM_X64
return g_CallMaker2.CreateCall(address, &(*protoInfo), retInfo, paramInfo, fnFlags);
#else
return g_CallMaker2.CreateCall(address, &(*protoInfo));
#endif
}
ICallWrapper *CallMaker::CreateVCall(unsigned int vtblIdx,
@@ -111,7 +116,8 @@ ICallWrapper *CallMaker::CreateVCall(unsigned int vtblIdx,
unsigned int thisOffs,
const PassInfo *retInfo,
const PassInfo paramInfo[],
unsigned int numParams)
unsigned int numParams,
unsigned int fnFlags)
{
SourceHook::MemFuncInfo info;
info.isVirtual = true;
@@ -138,12 +144,16 @@ ICallWrapper *CallMaker::CreateVCall(unsigned int vtblIdx,
NULL, NULL, NULL, NULL);
}
#if defined PLATFORM_X64
return g_CallMaker2.CreateVirtualCall(&(*protoInfo), &info, retInfo, paramInfo, fnFlags);
#else
return g_CallMaker2.CreateVirtualCall(&(*protoInfo), &info);
#endif
}
ICallWrapper *CallMaker2::CreateCall(void *address, const SourceHook::ProtoInfo *protoInfo)
{
#ifdef PLATFORM_X86
CallWrapper *pWrapper = new CallWrapper(protoInfo);
pWrapper->SetCalleeAddr(address);
@@ -151,11 +161,15 @@ ICallWrapper *CallMaker2::CreateCall(void *address, const SourceHook::ProtoInfo
pWrapper->SetCodeBaseAddr(addr);
return pWrapper;
#else
return nullptr;
#endif
}
ICallWrapper *CallMaker2::CreateVirtualCall(const SourceHook::ProtoInfo *protoInfo,
const SourceHook::MemFuncInfo *info)
{
#ifdef PLATFORM_X86
CallWrapper *pWrapper = new CallWrapper(protoInfo);
pWrapper->SetMemFuncInfo(info);
@@ -163,9 +177,48 @@ ICallWrapper *CallMaker2::CreateVirtualCall(const SourceHook::ProtoInfo *protoIn
pWrapper->SetCodeBaseAddr(addr);
return pWrapper;
#else
return nullptr;
#endif
}
#if defined HOOKING_ENABLED
ICallWrapper *CallMaker2::CreateCall(void *address, const SourceHook::ProtoInfo *protoInfo,
const PassInfo *retInfo, const PassInfo paramInfo[],
unsigned int fnFlags)
{
#ifdef PLATFORM_X64
CallWrapper *pWrapper = new CallWrapper(protoInfo, retInfo, paramInfo, fnFlags);
pWrapper->SetCalleeAddr(address);
void *addr = JIT_CallCompile(pWrapper, FuncAddr_Direct);
pWrapper->SetCodeBaseAddr(addr);
return pWrapper;
#else
return nullptr;
#endif
}
ICallWrapper *CallMaker2::CreateVirtualCall(const SourceHook::ProtoInfo *protoInfo,
const SourceHook::MemFuncInfo *info,
const PassInfo *retInfo,
const PassInfo paramInfo[],
unsigned int fnFlags)
{
#ifdef PLATFORM_X64
CallWrapper *pWrapper = new CallWrapper(protoInfo, retInfo, paramInfo, fnFlags);
pWrapper->SetMemFuncInfo(info);
void *addr = JIT_CallCompile(pWrapper, FuncAddr_VTable);
pWrapper->SetCodeBaseAddr(addr);
return pWrapper;
#else
return nullptr;
#endif
}
#if 0
IHookWrapper *CallMaker2::CreateVirtualHook(SourceHook::ISourceHook *pSH,
const SourceHook::ProtoInfo *protoInfo,
const SourceHook::MemFuncInfo *info,
+10 -7
View File
@@ -34,7 +34,6 @@
#include "CallWrapper.h"
#include "HookWrapper.h"
using namespace SourceMod;
@@ -45,26 +44,30 @@ public: //IBinTools
CallConvention cv,
const PassInfo *retInfo,
const PassInfo paramInfo[],
unsigned int numParams);
unsigned int numParams,
unsigned int fnFlags);
ICallWrapper *CreateVCall(unsigned int vtblIdx,
unsigned int vtblOffs,
unsigned int thisOffs,
const PassInfo *retInfo,
const PassInfo paramInfo[],
unsigned int numParams);
unsigned int numParams,
unsigned int fnFlags);
};
class CallMaker2
#if defined HOOKING_ENABLED
: public IBinTools2
#endif
{
public: //IBinTools2
virtual ICallWrapper *CreateCall(void *address,
const SourceHook::ProtoInfo *protoInfo);
virtual ICallWrapper *CreateVirtualCall(const SourceHook::ProtoInfo *protoInfo,
const SourceHook::MemFuncInfo *info);
#if defined HOOKING_ENABLED
ICallWrapper *CreateCall(void *address, const SourceHook::ProtoInfo *protoInfo,
const PassInfo *retInfo, const PassInfo paramInfo[], unsigned int fnFlags);
ICallWrapper *CreateVirtualCall(const SourceHook::ProtoInfo *protoInfo,
const SourceHook::MemFuncInfo *info, const PassInfo *retInfo,
const PassInfo paramInfo[], unsigned int fnFlags);
#if 0
virtual IHookWrapper *CreateVirtualHook(SourceHook::ISourceHook *pSH,
const SourceHook::ProtoInfo *protoInfo,
const SourceHook::MemFuncInfo *info,
+22 -1
View File
@@ -33,7 +33,7 @@
#include "CallWrapper.h"
#include "CallMaker.h"
CallWrapper::CallWrapper(const SourceHook::ProtoInfo *protoInfo)
CallWrapper::CallWrapper(const SourceHook::ProtoInfo *protoInfo) : m_FnFlags(0)
{
m_AddrCodeBase = NULL;
m_AddrCallee = NULL;
@@ -77,6 +77,22 @@ CallWrapper::CallWrapper(const SourceHook::ProtoInfo *protoInfo)
}
}
CallWrapper::CallWrapper(const SourceHook::ProtoInfo *protoInfo, const PassInfo *retInfo,
const PassInfo paramInfo[], unsigned int fnFlags) : CallWrapper(protoInfo)
{
m_RetParam->fields = retInfo->fields;
m_RetParam->numFields = retInfo->numFields;
unsigned int argnum = protoInfo->numOfParams;
for (unsigned int i = 0; i < argnum; i++)
{
m_Params[i].info.fields = paramInfo[i].fields;
m_Params[i].info.numFields = paramInfo[i].numFields;
}
m_FnFlags = fnFlags;
}
CallWrapper::~CallWrapper()
{
delete [] m_Params;
@@ -184,3 +200,8 @@ unsigned int CallWrapper::GetParamOffset(unsigned int num)
return m_Params[num].offset;
}
unsigned int CallWrapper::GetFunctionFlags()
{
return m_FnFlags;
}
+4
View File
@@ -47,6 +47,8 @@ class CallWrapper : public ICallWrapper
{
public:
CallWrapper(const SourceHook::ProtoInfo *protoInfo);
CallWrapper(const SourceHook::ProtoInfo *protoInfo, const PassInfo *retInfo,
const PassInfo paramInfo[], unsigned int fnFlags);
~CallWrapper();
public: //ICallWrapper
CallConvention GetCallConvention();
@@ -59,6 +61,7 @@ public: //ICallWrapper
SourceHook::ProtoInfo::CallConvention GetSHCallConvention();
const SourceHook::PassInfo *GetSHParamInfo(unsigned int num);
unsigned int GetParamOffset(unsigned int num);
unsigned int GetFunctionFlags();
public:
void SetCalleeAddr(void *addr);
void SetCodeBaseAddr(void *addr);
@@ -74,6 +77,7 @@ private:
void *m_AddrCallee;
void *m_AddrCodeBase;
SourceHook::MemFuncInfo m_FuncInfo;
unsigned int m_FnFlags;
};
#endif //_INCLUDE_SOURCEMOD_CALLWRAPPER_H_
-6
View File
@@ -50,12 +50,6 @@ bool BinTools::SDK_OnLoad(char *error, size_t maxlength, bool late)
g_SPEngine = g_pSM->GetScriptingEngine();
g_pShareSys->AddInterface(myself, &g_CallMaker);
/* IBinTools2 is only compatible with SH v5 */
if (g_pSM->GetShApiVersion() >= 5)
{
g_pShareSys->AddInterface(myself, &g_CallMaker2);
}
return true;
}
File diff suppressed because it is too large Load Diff
+3 -2
View File
@@ -34,11 +34,12 @@
#include <jit_helpers.h>
#include <x86_macros.h>
#include <sm_platform.h>
#include "CallWrapper.h"
#include "HookWrapper.h"
void *JIT_CallCompile(CallWrapper *pWrapper, FuncAddrMethod method);
#if defined HOOKING_ENABLED
#if 0
void *JIT_HookCompile(HookWrapper *pWrapper);
void JIT_FreeHook(void *addr);
#endif
+1 -1
View File
@@ -214,7 +214,7 @@ inline void Write_Push_Params(JitWriter *jit,
IA32_Push_Reg(jit, kREG_EBX);
//push <pWrapper>
IA32_Push_Imm32(jit, (jit_int32_t)pWrapper);
IA32_Push_Imm32(jit, (jit_int32_t)(intptr_t)pWrapper);
}
inline void Write_Call_Handler(JitWriter *jit, void *addr)
+656
View File
@@ -0,0 +1,656 @@
/**
* vim: set ts=4 :
* =============================================================================
* SourceMod BinTools Extension
* Copyright (C) 2004-2017 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 <jit_helpers.h>
#include <x86_macros.h>
// 64-bit registers
const jit_uint8_t kREG_RAX = kREG_EAX;
const jit_uint8_t kREG_RCX = kREG_ECX;
const jit_uint8_t kREG_RDX = kREG_EDX;
const jit_uint8_t kREG_RBX = kREG_EBX;
const jit_uint8_t kREG_RSP = kREG_ESP;
const jit_uint8_t kREG_RBP = kREG_EBP;
const jit_uint8_t kREG_RSI = kREG_ESI;
const jit_uint8_t kREG_RDI = kREG_EDI;
const jit_uint8_t kREG_R8 = 8;
const jit_uint8_t kREG_R9 = 9;
const jit_uint8_t kREG_R10 = 10;
const jit_uint8_t kREG_R11 = 11;
const jit_uint8_t kREG_R12 = 12;
const jit_uint8_t kREG_R13 = 13;
const jit_uint8_t kREG_R14 = 14;
const jit_uint8_t kREG_R15 = 15;
const jit_uint8_t kREG_XMM0 = 0;
const jit_uint8_t kREG_XMM1 = 1;
const jit_uint8_t kREG_XMM2 = 2;
const jit_uint8_t kREG_XMM3 = 3;
const jit_uint8_t kREG_XMM4 = 4;
const jit_uint8_t kREG_XMM5 = 5;
const jit_uint8_t kREG_XMM6 = 6;
const jit_uint8_t kREG_XMM7 = 7;
const jit_uint8_t kREG_XMM8 = 8;
const jit_uint8_t kREG_XMM9 = 9;
const jit_uint8_t kREG_XMM10 = 10;
const jit_uint8_t kREG_XMM11 = 11;
const jit_uint8_t kREG_XMM12 = 12;
const jit_uint8_t kREG_XMM13 = 13;
const jit_uint8_t kREG_XMM14 = 14;
const jit_uint8_t kREG_XMM15 = 15;
#define X64_REX_PREFIX 0x40
#define IA32_MOV_REG8_IMM8 0xB0
inline jit_uint8_t x64_rex(bool w, jit_uint8_t r, jit_uint8_t x, jit_uint8_t b)
{
return (X64_REX_PREFIX | ((jit_uint8_t)w << 3) | ((r>>3) << 2) | ((x>>3) << 1) | (b >> 3));
}
inline void X64_Push_Reg(JitWriter *jit, jit_uint8_t reg)
{
if (reg >= kREG_R8)
jit->write_ubyte(x64_rex(false, 0, 0, reg));
IA32_Push_Reg(jit, reg & 7);
}
inline void X64_Mov_Reg_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode)
{
jit->write_ubyte(x64_rex(true, dest, 0, src));
IA32_Mov_Reg_Rm(jit, dest & 7, src & 7, mode);
}
inline void X64_Mov_Reg_Rm_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp)
{
jit->write_ubyte(x64_rex(true, dest, 0, src));
IA32_Mov_Reg_Rm_Disp8(jit, dest & 7, src & 7, disp);
}
inline void X64_Mov_Reg_Rm_Disp32(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int32_t disp)
{
jit->write_ubyte(x64_rex(true, dest, 0, src));
IA32_Mov_Reg_Rm_Disp32(jit, dest & 7, src & 7, disp);
}
inline void X64_Mov_Reg32_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode)
{
if (src>= kREG_R8 || dest >= kREG_R8)
jit->write_ubyte(x64_rex(false, dest, 0, src));
IA32_Mov_Reg_Rm(jit, dest & 7, src & 7, mode);
}
inline void X64_Mov_Reg32_Rm_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp)
{
if (src>= kREG_R8 || dest >= kREG_R8)
jit->write_ubyte(x64_rex(false, dest, 0, src));
IA32_Mov_Reg_Rm_Disp8(jit, dest & 7, src & 7, disp);
}
inline void X64_Mov_Reg32_Rm_Disp32(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int32_t disp)
{
if (src>= kREG_R8 || dest >= kREG_R8)
jit->write_ubyte(x64_rex(false, dest, 0, src));
IA32_Mov_Reg_Rm_Disp32(jit, dest & 7, src & 7, disp);
}
inline void X64_And_Rm_Imm8(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode, jit_int8_t value)
{
jit->write_ubyte(x64_rex(true, 0, 0, reg));
IA32_And_Rm_Imm8(jit, reg & 7, mode, value);
}
inline void X64_Sub_Rm_Imm8(JitWriter *jit, jit_uint8_t reg, jit_int8_t val, jit_uint8_t mode)
{
jit->write_ubyte(x64_rex(true, 5, 0, reg));
IA32_Sub_Rm_Imm8(jit, reg & 7, val, mode);
}
inline void X64_Sub_Rm_Imm32(JitWriter *jit, jit_uint8_t reg, jit_int32_t val, jit_uint8_t mode)
{
jit->write_ubyte(x64_rex(true, 5, 0, reg));
IA32_Sub_Rm_Imm32(jit, reg & 7, val, mode);
}
inline void X64_Pop_Reg(JitWriter *jit, jit_uint8_t reg)
{
if (reg >= kREG_R8)
jit->write_ubyte(x64_rex(false, 0, 0, reg));
IA32_Pop_Reg(jit, reg & 7);
}
inline void X64_Return(JitWriter *jit)
{
IA32_Return(jit);
}
inline void X64_Movzx_Reg64_Rm8_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp)
{
jit->write_ubyte(x64_rex(true, dest, 0, src));
IA32_Movzx_Reg32_Rm8_Disp8(jit, dest & 7, src & 7, disp);
}
inline void X64_Movzx_Reg64_Rm8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode)
{
jit->write_ubyte(x64_rex(true, dest, 0, src));
IA32_Movzx_Reg32_Rm8(jit, dest & 7, src & 7, mode);
}
inline void X64_Movzx_Reg64_Rm8_Disp32(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int32_t disp)
{
jit->write_ubyte(x64_rex(true, dest, 0, src));
IA32_Movzx_Reg32_Rm8_Disp32(jit, dest & 7, src & 7, disp);
}
inline void X64_Mov_RmRSP_Reg(JitWriter *jit, jit_uint8_t src)
{
jit->write_ubyte(x64_rex(true, kREG_RSP, 0, src));
jit->write_ubyte(IA32_MOV_RM_REG);
jit->write_ubyte(ia32_modrm(MOD_MEM_REG, src & 7, kREG_RSP));
jit->write_ubyte(ia32_sib(NOSCALE, kREG_NOIDX, kREG_RSP));
}
inline void X64_Mov_RmRSP_Disp8_Reg(JitWriter *jit, jit_uint8_t src, jit_int8_t disp)
{
jit->write_ubyte(x64_rex(true, src, 0, kREG_RSP));
jit->write_ubyte(IA32_MOV_RM_REG);
jit->write_ubyte(ia32_modrm(MOD_DISP8, src & 7, kREG_RSP));
jit->write_ubyte(ia32_sib(NOSCALE, kREG_NOIDX, kREG_RSP));
jit->write_byte(disp);
}
inline void X64_Mov_RmRSP_Disp32_Reg(JitWriter *jit, jit_uint8_t src, jit_int8_t disp)
{
jit->write_ubyte(x64_rex(true, src, 0, kREG_RSP));
jit->write_ubyte(IA32_MOV_RM_REG);
jit->write_ubyte(ia32_modrm(MOD_DISP32, src & 7, kREG_RSP));
jit->write_ubyte(ia32_sib(NOSCALE, kREG_NOIDX, kREG_RSP));
jit->write_byte(disp);
}
inline void X64_Movzx_Reg64_Rm16(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode)
{
jit->write_ubyte(x64_rex(true, dest, 0, src));
IA32_Movzx_Reg32_Rm16(jit, dest & 7, src & 7, mode);
}
inline void X64_Movzx_Reg64_Rm16_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp)
{
jit->write_ubyte(x64_rex(true, dest, 0, src));
IA32_Movzx_Reg32_Rm16_Disp8(jit, dest & 7, src & 7, disp);
}
inline void X64_Movzx_Reg64_Rm16_Disp32(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int32_t disp)
{
jit->write_ubyte(x64_rex(true, dest, 0, src));
IA32_Movzx_Reg32_Rm16_Disp32(jit, dest & 7, src & 7, disp);
}
inline void X64_Lea_DispRegImm8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src_base, jit_int8_t val)
{
jit->write_ubyte(x64_rex(true, dest, 0, src_base));
IA32_Lea_DispRegImm8(jit, dest & 7, src_base & 7, val);
}
inline void X64_Lea_DispRegImm32(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src_base, jit_int32_t val)
{
jit->write_ubyte(x64_rex(true, dest, 0, src_base));
IA32_Lea_DispRegImm32(jit, dest & 7, src_base & 7, val);
}
inline void X64_Add_Rm_Imm8(JitWriter *jit, jit_uint8_t reg, jit_int8_t value, jit_uint8_t mode)
{
jit->write_ubyte(x64_rex(true, 0, 0, reg));
IA32_Add_Rm_Imm8(jit, reg & 7, value, mode);
}
inline void X64_Add_Rm_Imm32(JitWriter *jit, jit_uint8_t reg, jit_int32_t value, jit_uint8_t mode)
{
jit->write_ubyte(x64_rex(true, 0, 0, reg));
IA32_Add_Rm_Imm32(jit, reg & 7, value, mode);
}
inline void X64_Movaps_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src)
{
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
jit->write_ubyte(x64_rex(false, dest, 0, src));
jit->write_ubyte(0x0F);
jit->write_ubyte(0x28);
jit->write_ubyte(ia32_modrm(MOD_MEM_REG, dest & 7, src & 7));
}
inline void X64_Movups_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src)
{
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
jit->write_ubyte(x64_rex(false, dest, 0, src));
jit->write_ubyte(0x0F);
jit->write_ubyte(0x10);
jit->write_ubyte(ia32_modrm(MOD_MEM_REG, dest & 7, src & 7));
}
inline void X64_Movaps_Rm_Reg(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src)
{
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
jit->write_ubyte(x64_rex(false, src, 0, dest));
jit->write_ubyte(0x0F);
jit->write_ubyte(0x29);
jit->write_ubyte(ia32_modrm(MOD_MEM_REG, src & 7, dest & 7));
jit->write_ubyte(ia32_sib(NOSCALE, kREG_NOIDX, dest & 7));
}
inline void X64_Movapd_Rm_Reg(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src)
{
jit->write_ubyte(0x66);
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
jit->write_ubyte(x64_rex(false, src, 0, dest));
jit->write_ubyte(0x0F);
jit->write_ubyte(0x29);
jit->write_ubyte(ia32_modrm(MOD_MEM_REG, src & 7, dest & 7));
jit->write_ubyte(ia32_sib(NOSCALE, kREG_NOIDX, dest & 7));
}
inline void X64_Movups_Rm_Reg(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src)
{
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
jit->write_ubyte(x64_rex(false, src, 0, dest));
jit->write_ubyte(0x0F);
jit->write_ubyte(0x11);
jit->write_ubyte(ia32_modrm(MOD_MEM_REG, src & 7, dest & 7));
}
inline void X64_Movupd_Rm_Reg(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src)
{
jit->write_ubyte(0x66);
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
jit->write_ubyte(x64_rex(false, src, 0, dest));
jit->write_ubyte(0x0F);
jit->write_ubyte(0x11);
jit->write_ubyte(ia32_modrm(MOD_MEM_REG, src & 7, dest & 7));
}
inline void X64_Movupd_Rm_Disp8_Reg(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp)
{
jit->write_ubyte(0x66);
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
jit->write_ubyte(x64_rex(false, src, 0, dest));
jit->write_ubyte(0x0F);
jit->write_ubyte(0x11);
jit->write_ubyte(ia32_modrm(MOD_DISP8, src & 7, dest & 7));
jit->write_byte(disp);
}
inline void X64_Movaps_Rm_Disp8_Reg(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp)
{
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
jit->write_ubyte(x64_rex(false, src, 0, dest));
jit->write_ubyte(0x0F);
jit->write_ubyte(0x29);
jit->write_ubyte(ia32_modrm(MOD_DISP8, src & 7, dest & 7));
jit->write_byte(disp);
}
inline void X64_Movups_Rm_Disp8_Reg(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp)
{
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
jit->write_ubyte(x64_rex(false, src, 0, dest));
jit->write_ubyte(0x0F);
jit->write_ubyte(0x11);
jit->write_ubyte(ia32_modrm(MOD_DISP8, src & 7, dest & 7));
jit->write_byte(disp);
}
inline void X64_Movaps_Rm_Disp32_Reg(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int32_t disp)
{
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
jit->write_ubyte(x64_rex(false, src, 0, dest));
jit->write_ubyte(0x0F);
jit->write_ubyte(0x29);
jit->write_ubyte(ia32_modrm(MOD_DISP32, src & 7, dest & 7));
jit->write_byte(disp);
}
inline void X64_Movups_Rm_Disp32_Reg(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int32_t disp)
{
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
jit->write_ubyte(x64_rex(false, src, 0, dest));
jit->write_ubyte(0x0F);
jit->write_ubyte(0x11);
jit->write_ubyte(ia32_modrm(MOD_DISP32, src & 7, dest & 7));
jit->write_byte(disp);
}
inline void X64_Movlps_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src)
{
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
jit->write_ubyte(x64_rex(false, dest, 0, src));
jit->write_ubyte(0x0F);
jit->write_ubyte(0x12);
jit->write_ubyte(ia32_modrm(MOD_MEM_REG, dest & 7, src & 7));
}
inline void X64_Movhps_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src)
{
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
jit->write_ubyte(x64_rex(false, dest, 0, src));
jit->write_ubyte(0x0F);
jit->write_ubyte(0x16);
jit->write_ubyte(ia32_modrm(MOD_MEM_REG, dest & 7, src & 7));
}
inline void X64_Movaps_Rm_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp)
{
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
jit->write_ubyte(x64_rex(false, dest, 0, src));
jit->write_ubyte(0x0F);
jit->write_ubyte(0x28);
jit->write_ubyte(ia32_modrm(MOD_DISP8, dest & 7, src & 7));
jit->write_byte(disp);
}
inline void X64_Movups_Rm_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp)
{
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
jit->write_ubyte(x64_rex(false, dest, 0, src));
jit->write_ubyte(0x0F);
jit->write_ubyte(0x10);
jit->write_ubyte(ia32_modrm(MOD_DISP8, dest & 7, src & 7));
jit->write_byte(disp);
}
inline void X64_Movlps_Rm_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp)
{
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
jit->write_ubyte(x64_rex(false, dest, 0, src));
jit->write_ubyte(0x0F);
jit->write_ubyte(0x12);
jit->write_ubyte(ia32_modrm(MOD_DISP8, dest & 7, src & 7));
jit->write_byte(disp);
}
inline void X64_Movhps_Rm_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp)
{
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
jit->write_ubyte(x64_rex(false, dest, 0, src));
jit->write_ubyte(0x0F);
jit->write_ubyte(0x16);
jit->write_ubyte(ia32_modrm(MOD_DISP8, dest & 7, src & 7));
jit->write_byte(disp);
}
inline void X64_Movaps_Rm_Disp32(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int32_t disp)
{
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
jit->write_ubyte(x64_rex(false, dest, 0, src));
jit->write_ubyte(0x0F);
jit->write_ubyte(0x28);
jit->write_ubyte(ia32_modrm(MOD_DISP32, dest & 7, src & 7));
jit->write_byte(disp);
}
inline void X64_Movups_Rm_Disp32(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int32_t disp)
{
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
jit->write_ubyte(x64_rex(false, dest, 0, src));
jit->write_ubyte(0x0F);
jit->write_ubyte(0x10);
jit->write_ubyte(ia32_modrm(MOD_DISP32, dest & 7, src & 7));
jit->write_byte(disp);
}
inline void X64_Movapd_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src)
{
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
jit->write_ubyte(x64_rex(false, dest, 0, src));
jit->write_ubyte(0x66);
jit->write_ubyte(0x0F);
jit->write_ubyte(0x28);
jit->write_ubyte(ia32_modrm(MOD_MEM_REG, dest & 7, src & 7));
}
inline void X64_Movupd_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src)
{
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
jit->write_ubyte(x64_rex(false, dest, 0, src));
jit->write_ubyte(0x66);
jit->write_ubyte(0x0F);
jit->write_ubyte(0x10);
jit->write_ubyte(ia32_modrm(MOD_MEM_REG, dest & 7, src & 7));
}
inline void X64_Movapd_Rm_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp)
{
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
jit->write_ubyte(x64_rex(false, dest, 0, src));
jit->write_ubyte(0x66);
jit->write_ubyte(0x0F);
jit->write_ubyte(0x28);
jit->write_ubyte(ia32_modrm(MOD_DISP8, dest & 7, src & 7));
jit->write_byte(disp);
}
inline void X64_Movupd_Rm_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp)
{
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
jit->write_ubyte(x64_rex(false, dest, 0, src));
jit->write_ubyte(0x66);
jit->write_ubyte(0x0F);
jit->write_ubyte(0x10);
jit->write_ubyte(ia32_modrm(MOD_DISP8, dest & 7, src & 7));
jit->write_byte(disp);
}
inline void X64_Movapd_Rm_Disp32(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int32_t disp)
{
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
jit->write_ubyte(x64_rex(false, dest, 0, src));
jit->write_ubyte(0x66);
jit->write_ubyte(0x0F);
jit->write_ubyte(0x28);
jit->write_ubyte(ia32_modrm(MOD_DISP32, dest & 7, src & 7));
jit->write_byte(disp);
}
inline void X64_Movupd_Rm_Disp32(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int32_t disp)
{
if (dest >= kREG_XMM8 || src >= kREG_XMM8)
jit->write_ubyte(x64_rex(false, dest, 0, src));
jit->write_ubyte(0x66);
jit->write_ubyte(0x0F);
jit->write_ubyte(0x10);
jit->write_ubyte(ia32_modrm(MOD_DISP32, dest & 7, src & 7));
jit->write_byte(disp);
}
inline void X64_Cld(JitWriter *jit)
{
IA32_Cld(jit);
}
inline void X64_Rep(JitWriter *jit)
{
IA32_Rep(jit);
}
inline void X64_Movsq(JitWriter *jit)
{
jit->write_ubyte(x64_rex(true, 0, 0, 0));
jit->write_ubyte(IA32_MOVSD);
}
inline void X64_Movsb(JitWriter *jit)
{
jit->write_ubyte(IA32_MOVSB);
}
inline void X64_Lea_Reg_DispRegMultImm8(JitWriter *jit,
jit_uint8_t dest,
jit_uint8_t src_base,
jit_uint8_t src_index,
jit_uint8_t scale,
jit_int8_t val)
{
jit->write_ubyte(x64_rex(true, dest, 0, src_index));
IA32_Lea_Reg_DispRegMultImm8(jit, dest & 7, src_base, src_index & 7, scale, val);
}
inline void X64_Lea_Reg_DispRegMultImm32(JitWriter *jit,
jit_uint8_t dest,
jit_uint8_t src_base,
jit_uint8_t src_index,
jit_uint8_t scale,
jit_int32_t val)
{
jit->write_ubyte(x64_rex(true, dest, 0, src_index));
jit->write_ubyte(IA32_LEA_REG_MEM);
jit->write_ubyte(ia32_modrm(MOD_DISP32, dest & 7, kREG_SIB));
jit->write_ubyte(ia32_sib(scale, src_index & 7, src_base));
jit->write_int32(val);
}
inline jitoffs_t X64_Mov_Reg_Imm32(JitWriter *jit, jit_uint8_t dest, jit_int32_t num)
{
jitoffs_t offs;
jit->write_ubyte(x64_rex(true, 0, 0, dest));
jit->write_ubyte(0xC7);
jit->write_ubyte(ia32_modrm(MOD_REG, 0, dest & 7));
offs = jit->get_outputpos();
jit->write_int32(num);
return offs;
}
inline jitoffs_t X64_Mov_Reg_Imm64(JitWriter *jit, jit_uint8_t dest, jit_int64_t num)
{
jitoffs_t offs;
jit->write_ubyte(x64_rex(true, 0, 0, dest));
jit->write_ubyte(IA32_MOV_REG_IMM+(dest & 7));
offs = jit->get_outputpos();
jit->write_int64(num);
return offs;
}
inline void X64_Mov_Rm8_Reg8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode)
{
if (dest >= kREG_R8 || src > kREG_R8)
jit->write_ubyte(x64_rex(false, src, 0, dest));
jit->write_ubyte(IA32_MOV_RM8_REG8);
if ((dest & 7) == kREG_RBP) // Using rbp/r13 requires a displacement
mode = MOD_DISP8;
jit->write_ubyte(ia32_modrm(mode, src & 7, dest & 7));
if ((dest & 7) == kREG_RSP) // rsp/r12 needs SIB byte
jit->write_ubyte(ia32_sib(NOSCALE, kREG_NOIDX, dest & 7));
else if ((dest & 7) == kREG_RBP)
jit->write_ubyte(0); // Displacement of 0 needed to use rbp/r13
}
inline void X64_Mov_Rm32_Reg32(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode)
{
if (dest >= kREG_R8 || src > kREG_R8)
jit->write_ubyte(x64_rex(false, src, 0, dest));
jit->write_ubyte(IA32_MOV_RM_REG);
if ((dest & 7) == kREG_RBP) // Using rbp/r13 requires a displacement
mode = MOD_DISP8;
jit->write_ubyte(ia32_modrm(mode, src & 7, dest & 7));
if ((dest & 7) == kREG_RSP) // rsp/r12 needs SIB byte
jit->write_ubyte(ia32_sib(NOSCALE, kREG_NOIDX, dest & 7));
else if ((dest & 7) == kREG_RBP)
jit->write_ubyte(0); // Displacement of 0 needed to use rbp/r13
}
inline void X64_Mov_Rm16_Reg16(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode)
{
jit->write_ubyte(IA32_16BIT_PREFIX);
X64_Mov_Rm32_Reg32(jit, dest, src, mode);
}
inline void X64_Mov_Rm_Reg(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode)
{
jit->write_ubyte(x64_rex(true, src, 0, dest));
jit->write_ubyte(IA32_MOV_RM_REG);
if ((dest & 7) == kREG_RBP) // Using rbp/r13 requires a displacement
mode = MOD_DISP8;
jit->write_ubyte(ia32_modrm(mode, src & 7, dest & 7));
if ((dest & 7) == kREG_RSP) // rsp/r12 needs SIB byte
jit->write_ubyte(ia32_sib(NOSCALE, kREG_NOIDX, dest & 7));
else if ((dest & 7) == kREG_RBP)
jit->write_ubyte(0); // Displacement of 0 needed to use rbp/r13
}
inline void X64_Mov_Rm_Reg_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp)
{
jit->write_ubyte(x64_rex(true, src, 0, dest));
IA32_Mov_Rm_Reg_Disp8(jit, dest & 7, src & 7, disp);
}
inline jitoffs_t X64_Call_Imm32(JitWriter *jit, jit_int32_t disp)
{
return IA32_Call_Imm32(jit, disp);
}
inline void X64_Write_Jump32_Abs(JitWriter *jit, jitoffs_t jmp, void *target)
{
IA32_Write_Jump32_Abs(jit, jmp, target);
}
inline void X64_Call_Reg(JitWriter *jit, jit_uint8_t reg)
{
if (reg >= kREG_R8)
jit->write_ubyte(x64_rex(false, 0, 0, reg));
IA32_Call_Reg(jit, reg & 7);
}
inline jitoffs_t X64_Mov_Reg8_Imm8(JitWriter *jit, jit_uint8_t dest, jit_int8_t value)
{
jitoffs_t offs;
if (dest >= kREG_R8)
jit->write_ubyte(x64_rex(false, 0, 0, dest));
jit->write_ubyte(IA32_MOV_REG8_IMM8+(dest & 7));
offs = jit->get_outputpos();
jit->write_byte(value);
return offs;
}
inline void X64_Movd_Reg32_Xmm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src)
{
jit->write_ubyte(0x66);
if (dest >= kREG_R8 || src >= kREG_XMM8)
jit->write_ubyte(x64_rex(false, src, 0, dest));
jit->write_ubyte(0x0F);
jit->write_ubyte(0x7E);
jit->write_ubyte(ia32_modrm(MOD_REG, src & 7, dest & 7));
}
inline void X64_Movq_Reg_Xmm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src)
{
jit->write_ubyte(0x66);
jit->write_ubyte(x64_rex(true, src, 0, dest));
jit->write_ubyte(0x0F);
jit->write_ubyte(0x7E);
jit->write_ubyte(ia32_modrm(MOD_REG, src & 7, dest & 7));
}
+18 -17
View File
@@ -1,23 +1,24 @@
# vim: set sts=2 ts=8 sw=2 tw=99 et ft=python:
import os
binary = SM.ExtLibrary(builder, 'clientprefs.ext')
binary.compiler.cxxincludes += [
os.path.join(SM.mms_root, 'core', 'sourcehook'),
]
if binary.compiler.family == 'gcc' or binary.compiler.family == 'clang':
binary.compiler.cxxflags += ['-fno-rtti']
elif binary.compiler.family == 'msvc':
binary.compiler.cxxflags += ['/GR-']
for arch in SM.archs:
binary = SM.ExtLibrary(builder, 'clientprefs.ext', arch)
binary.compiler.cxxincludes += [
os.path.join(SM.mms_root, 'core', 'sourcehook'),
]
if binary.compiler.family == 'gcc' or binary.compiler.family == 'clang':
binary.compiler.cxxflags += ['-fno-rtti']
elif binary.compiler.family == 'msvc':
binary.compiler.cxxflags += ['/GR-']
binary.sources += [
'extension.cpp',
'cookie.cpp',
'menus.cpp',
'natives.cpp',
'query.cpp',
'../../public/smsdk_ext.cpp'
]
binary.sources += [
'extension.cpp',
'cookie.cpp',
'menus.cpp',
'natives.cpp',
'query.cpp',
'../../public/smsdk_ext.cpp'
]
SM.extensions += [builder.Add(binary)]
SM.extensions += [builder.Add(binary)]
+4 -10
View File
@@ -56,20 +56,14 @@ bool ClientPrefs::SDK_OnLoad(char *error, size_t maxlength, bool late)
if (DBInfo == NULL)
{
DBInfo = dbi->FindDatabaseConf("default");
DBInfo = dbi->FindDatabaseConf("storage-local");
if (DBInfo == NULL)
{
DBInfo = dbi->FindDatabaseConf("storage-local");
ke::SafeStrcpy(error, maxlength, "Could not find any suitable database configs");
return false;
}
}
if (DBInfo == NULL)
{
snprintf(error, maxlength, "Could not find any suitable database configs");
return false;
}
if (DBInfo->driver && DBInfo->driver[0] != '\0')
{
Driver = dbi->FindOrLoadDriver(DBInfo->driver);
@@ -81,7 +75,7 @@ bool ClientPrefs::SDK_OnLoad(char *error, size_t maxlength, bool late)
if (Driver == NULL)
{
snprintf(error, maxlength, "Could not load DB Driver \"%s\"", DBInfo->driver);
ke::SafeSprintf(error, maxlength, "Could not load DB Driver \"%s\"", DBInfo->driver);
return false;
}
+75 -13
View File
@@ -471,20 +471,82 @@ cell_t GetClientCookieTime(IPluginContext *pContext, const cell_t *params)
return value;
}
static cell_t Cookie_Set(IPluginContext *pContext, const cell_t *params)
{
// This version takes (handle, client, value). The original is (client, handle, value).
const cell_t new_params[4] = {
3,
params[2],
params[1],
params[3]
};
return SetClientPrefCookie(pContext, new_params);
}
static cell_t Cookie_Get(IPluginContext *pContext, const cell_t *params)
{
// This verson takes (handle, client, buffer, maxlen). The original is (client, handle, buffer, maxlen).
const cell_t new_params[5] = {
4,
params[2],
params[1],
params[3],
params[4]
};
return GetClientPrefCookie(pContext, new_params);
}
static cell_t Cookie_SetByAuthId(IPluginContext *pContext, const cell_t *params)
{
// This version takes (handle, authid, value). The original is (authid, handle, value).
const cell_t new_params[4] = {
3,
params[2],
params[1],
params[3]
};
return SetAuthIdCookie(pContext, new_params);
}
static cell_t Cookie_GetClientTime(IPluginContext *pContext, const cell_t *params)
{
// This version takes (handle, client). The original is (client, handle)
const cell_t new_params[3] = {
2,
params[2],
params[1],
};
return GetClientCookieTime(pContext, new_params);
}
sp_nativeinfo_t g_ClientPrefNatives[] =
{
{"RegClientCookie", RegClientPrefCookie},
{"FindClientCookie", FindClientPrefCookie},
{"SetClientCookie", SetClientPrefCookie},
{"SetAuthIdCookie", SetAuthIdCookie},
{"GetClientCookie", GetClientPrefCookie},
{"AreClientCookiesCached", AreClientCookiesCached},
{"GetCookieAccess", GetCookieAccess},
{"ReadCookieIterator", ReadCookieIterator},
{"GetCookieIterator", GetCookieIterator},
{"ShowCookieMenu", ShowSettingsMenu},
{"SetCookieMenuItem", AddSettingsMenuItem},
{"SetCookiePrefabMenu", AddSettingsPrefabMenuItem},
{"RegClientCookie", RegClientPrefCookie},
{"FindClientCookie", FindClientPrefCookie},
{"SetClientCookie", SetClientPrefCookie},
{"SetAuthIdCookie", SetAuthIdCookie},
{"GetClientCookie", GetClientPrefCookie},
{"AreClientCookiesCached", AreClientCookiesCached},
{"GetCookieAccess", GetCookieAccess},
{"ReadCookieIterator", ReadCookieIterator},
{"GetCookieIterator", GetCookieIterator},
{"ShowCookieMenu", ShowSettingsMenu},
{"SetCookieMenuItem", AddSettingsMenuItem},
{"SetCookiePrefabMenu", AddSettingsPrefabMenuItem},
{"GetClientCookieTime", GetClientCookieTime},
{NULL, NULL}
{"Cookie.Cookie", RegClientPrefCookie},
{"Cookie.Find", FindClientPrefCookie},
{"Cookie.Set", Cookie_Set},
{"Cookie.Get", Cookie_Get},
{"Cookie.SetByAuthId", Cookie_SetByAuthId},
{"Cookie.SetPrefabMenu", AddSettingsPrefabMenuItem},
{"Cookie.GetClientTime", Cookie_GetClientTime},
{"Cookie.AccessLevel.get", GetCookieAccess},
{NULL, NULL}
};
+13 -3
View File
@@ -11,14 +11,24 @@ project.sources += [
'util_cstrike.cpp',
'../../public/smsdk_ext.cpp',
'../../public/CDetour/detours.cpp',
'../../public/asm/asm.c'
'../../public/asm/asm.c',
'../../public/libudis86/decode.c',
'../../public/libudis86/itab.c',
'../../public/libudis86/syn-att.c',
'../../public/libudis86/syn-intel.c',
'../../public/libudis86/syn.c',
'../../public/libudis86/udis86.c',
]
project.compiler.defines += ['HAVE_STRING_H'];
for sdk_name in ['css', 'csgo']:
if sdk_name not in SM.sdks:
continue
sdk = SM.sdks[sdk_name]
SM.HL2Config(project, 'game.cstrike.ext.' + sdk.ext, sdk)
for arch in SM.archs:
if not arch in sdk.platformSpec[builder.target.platform]:
continue
SM.HL2Config(project, 'game.cstrike.ext.' + sdk.ext, sdk, arch)
SM.extensions += builder.Add(project)
+2 -2
View File
@@ -64,7 +64,7 @@ bool CStrike::SDK_OnLoad(char *error, size_t maxlength, bool late)
#if SOURCE_ENGINE != SE_CSGO
if (strcmp(g_pSM->GetGameFolderName(), "cstrike") != 0)
{
snprintf(error, maxlength, "Cannot Load Cstrike Extension on mods other than CS:S and CS:GO");
ke::SafeStrcpy(error, maxlength, "Cannot Load Cstrike Extension on mods other than CS:S and CS:GO");
return false;
}
#endif
@@ -77,7 +77,7 @@ bool CStrike::SDK_OnLoad(char *error, size_t maxlength, bool late)
{
if (error)
{
snprintf(error, maxlength, "Could not read sm-cstrike.games: %s", conf_error);
ke::SafeSprintf(error, maxlength, "Could not read sm-cstrike.games: %s", conf_error);
}
return false;
}
+4 -4
View File
@@ -126,7 +126,7 @@ DETOUR_DECL_MEMBER0(DetourWeaponPrice, int)
}
#endif
#if SOURCE_ENGINE != SE_CSGO
#if SOURCE_ENGINE == SE_CSS
DETOUR_DECL_MEMBER2(DetourTerminateRound, void, float, delay, int, reason)
{
if (g_pIgnoreTerminateDetour)
@@ -135,7 +135,7 @@ DETOUR_DECL_MEMBER2(DetourTerminateRound, void, float, delay, int, reason)
DETOUR_MEMBER_CALL(DetourTerminateRound)(delay, reason);
return;
}
#elif !defined(WIN32)
#elif SOURCE_ENGINE == SE_CSGO && !defined(WIN32)
DETOUR_DECL_MEMBER4(DetourTerminateRound, void, float, delay, int, reason, int, unknown, int, unknown2)
{
if (g_pIgnoreTerminateDetour)
@@ -189,12 +189,12 @@ DETOUR_DECL_MEMBER3(DetourTerminateRound, void, int, reason, int, unknown, int,
reason++;
#endif
#if SOURCE_ENGINE != SE_CSGO
#if SOURCE_ENGINE == SE_CSS
if (result == Pl_Changed)
return DETOUR_MEMBER_CALL(DetourTerminateRound)(delay, reason);
return DETOUR_MEMBER_CALL(DetourTerminateRound)(orgdelay, orgreason);
#elif !defined(WIN32)
#elif SOURCE_ENGINE == SE_CSGO && !defined(WIN32)
if (result == Pl_Changed)
return DETOUR_MEMBER_CALL(DetourTerminateRound)(delay, reason, unknown, unknown2);
+4
View File
@@ -18,7 +18,11 @@ struct HashItemDef_Node
class CHashItemDef
{
public:
#ifdef PLATFORM_X86
unsigned char padding[36];
#else
unsigned char padding[56];
#endif
HashItemDef_Node *pMem;
int nAllocatedCount;
int nGrowSize;

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