Compare commits
167
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b635dace11 | ||
|
|
d990f956f9 | ||
|
|
955f1e0d3a | ||
|
|
b4cd559186 | ||
|
|
46e89891e1 | ||
|
|
080e2563c3 | ||
|
|
e1e0c33f2c | ||
|
|
0160d3cc71 | ||
|
|
81f0d82c67 | ||
|
|
b5276b435a | ||
|
|
16aecfb404 | ||
|
|
7054ef56f6 | ||
|
|
bfae78d1ec | ||
|
|
c82f2b4659 | ||
|
|
46d71790be | ||
|
|
647811f930 | ||
|
|
7ca80d1c7c | ||
|
|
8823bab3f3 | ||
|
|
b9d5b59bd1 | ||
|
|
7fc892d38b | ||
|
|
09040231a0 | ||
|
|
16541a5668 | ||
|
|
e1b3b14311 | ||
|
|
300632db86 | ||
|
|
d1776dd641 | ||
|
|
22cee6a2dd | ||
|
|
a2194df273 | ||
|
|
27e20996dd | ||
|
|
b5f16142e5 | ||
|
|
23f1f9e148 | ||
|
|
990f99af5a | ||
|
|
6ca9d86e8f | ||
|
|
fae8b4d49a | ||
|
|
7f2d9dd8eb | ||
|
|
8ae1b3e1e7 | ||
|
|
c77c853c02 | ||
|
|
2b0daba573 | ||
|
|
ba4aa4d37f | ||
|
|
e3f31af5d3 | ||
|
|
bc0bf4e270 | ||
|
|
60c5ad6324 | ||
|
|
e996a00675 | ||
|
|
0be3f0afed | ||
|
|
86bdfa2205 | ||
|
|
56c87e927f | ||
|
|
be54443918 | ||
|
|
676ea8b29c | ||
|
|
d77ff38428 | ||
|
|
d3256ef339 | ||
|
|
3d11742f91 | ||
|
|
a2aa5d1cda | ||
|
|
8860e18026 | ||
|
|
7dba540b97 | ||
|
|
0dd9a5b842 | ||
|
|
e6c3565544 | ||
|
|
8cacba922a | ||
|
|
767396d4ee | ||
|
|
07a51a0d4e | ||
|
|
9f042625d0 | ||
|
|
fc29f4249a | ||
|
|
5ca5ecee85 | ||
|
|
c79d547492 | ||
|
|
f079773195 | ||
|
|
e6ead8b5aa | ||
|
|
9eba6402eb | ||
|
|
f95be3b10c | ||
|
|
2220cc961e | ||
|
|
cfc6b2fee9 | ||
|
|
d188859fc5 | ||
|
|
96a8003448 | ||
|
|
696f702204 | ||
|
|
8b26ce73c2 | ||
|
|
ee5f488aa2 | ||
|
|
3a5cf80e2b | ||
|
|
3e4f7af96a | ||
|
|
a1a483fa27 | ||
|
|
b32f8a4803 | ||
|
|
96ee6dbf8a | ||
|
|
ac07cf95e1 | ||
|
|
8f51e33167 | ||
|
|
8366f371ad | ||
|
|
9b44dfea11 | ||
|
|
7ede8e0924 | ||
|
|
9fe2d9c1cf | ||
|
|
1836ec9d45 | ||
|
|
380d7adc09 | ||
|
|
4109d0df39 | ||
|
|
9cab1e3ab7 | ||
|
|
e9d8bfcdfc | ||
|
|
f134602991 | ||
|
|
b493532ee1 | ||
|
|
84dec75fb8 | ||
|
|
b1094f87c6 | ||
|
|
284b4bfe20 | ||
|
|
b46537ddd5 | ||
|
|
c9446c4d7d | ||
|
|
d4610ab340 | ||
|
|
0016b8ef2f | ||
|
|
72e08f7e44 | ||
|
|
b06cfa5414 | ||
|
|
a7742cae3d | ||
|
|
8a78285659 | ||
|
|
6847c8eec0 | ||
|
|
66790254ac | ||
|
|
86b8a0b16a | ||
|
|
25fced78e8 | ||
|
|
22d11160ba | ||
|
|
8d65b3e94e | ||
|
|
5518544ecd | ||
|
|
af3523bd2d | ||
|
|
8646cca538 | ||
|
|
c7cea1b40b | ||
|
|
58914f71bd | ||
|
|
3841e98c4f | ||
|
|
acd025dba2 | ||
|
|
78c2206628 | ||
|
|
5c47bf8803 | ||
|
|
8e78ee6f57 | ||
|
|
a2da4cc868 | ||
|
|
00e44ad3c3 | ||
|
|
29ba84fc5c | ||
|
|
283f1f012d | ||
|
|
fff17f8043 | ||
|
|
847eaf38f9 | ||
|
|
1d59a329eb | ||
|
|
5689888682 | ||
|
|
a01768525a | ||
|
|
e3d2ddf278 | ||
|
|
b3e48b0ad7 | ||
|
|
6d528b5c55 | ||
|
|
22daf26e3e | ||
|
|
73061969da | ||
|
|
4653530095 | ||
|
|
ef5faaaa4a | ||
|
|
f52ea98eb4 | ||
|
|
d315d4bf53 | ||
|
|
eaef2a46fb | ||
|
|
b0304a89a6 | ||
|
|
a4790f0358 | ||
|
|
d3d5cd8181 | ||
|
|
64be2bc5a0 | ||
|
|
30e476c35e | ||
|
|
88af208cdd | ||
|
|
b64751c1af | ||
|
|
2e158a72e2 | ||
|
|
c8fb05dd4b | ||
|
|
860af1e6cb | ||
|
|
5c1cadb64e | ||
|
|
bfb97a4207 | ||
|
|
7e26691b99 | ||
|
|
ca469a218a | ||
|
|
6052ddaa64 | ||
|
|
0ddc675472 | ||
|
|
9412f687cb | ||
|
|
0e865c0618 | ||
|
|
462b5213d7 | ||
|
|
f52e84730f | ||
|
|
b8873efa0d | ||
|
|
4132b9bd21 | ||
|
|
c0caa9f158 | ||
|
|
7346b0c081 | ||
|
|
6a361e3045 | ||
|
|
61d7519ef5 | ||
|
|
3e1a78703e | ||
|
|
bb195a9b2d | ||
|
|
6f095a064c | ||
|
|
eb334f5fe2 |
@@ -1,5 +0,0 @@
|
|||||||
{
|
|
||||||
"project_id" : "sourcemod",
|
|
||||||
"conduit_uri" : "https://phabricator.alliedmods.net/",
|
|
||||||
"history.immutable" : false
|
|
||||||
}
|
|
||||||
-37
@@ -1,37 +0,0 @@
|
|||||||
# Binaries
|
|
||||||
*.dll
|
|
||||||
*.dylib
|
|
||||||
*.exe
|
|
||||||
*.so
|
|
||||||
|
|
||||||
# Files generated by Visual Studio
|
|
||||||
*.aps
|
|
||||||
*.ipch
|
|
||||||
*.ncb
|
|
||||||
*.opensdf
|
|
||||||
*.sdf
|
|
||||||
*.suo
|
|
||||||
*.user
|
|
||||||
|
|
||||||
# Build directories
|
|
||||||
CrazyDebug*/
|
|
||||||
Debug*/
|
|
||||||
Release*/
|
|
||||||
LIB-Release/
|
|
||||||
LIB-Debug/
|
|
||||||
|
|
||||||
# Files generated by Mac OS X Finder
|
|
||||||
.DS_Store
|
|
||||||
|
|
||||||
# Files generated by Windows Explorer
|
|
||||||
[Dd]esktop.ini
|
|
||||||
[Tt]humbs.db
|
|
||||||
|
|
||||||
# AMBuild build directories
|
|
||||||
build/
|
|
||||||
obj-*/
|
|
||||||
*~
|
|
||||||
*.rej
|
|
||||||
*.orig
|
|
||||||
*.smx
|
|
||||||
*.swp
|
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
# Binaries
|
||||||
|
\.dll$
|
||||||
|
\.dylib$
|
||||||
|
\.exe$
|
||||||
|
\.so$
|
||||||
|
|
||||||
|
# Files generated by Visual Studio
|
||||||
|
\.aps$
|
||||||
|
\.ipch$
|
||||||
|
\.ncb$
|
||||||
|
\.opensdf$
|
||||||
|
\.sdf$
|
||||||
|
\.suo$
|
||||||
|
\.user$
|
||||||
|
|
||||||
|
# Build directories
|
||||||
|
/CrazyDebug.*
|
||||||
|
/Debug.*
|
||||||
|
/Release.*
|
||||||
|
|
||||||
|
# Files generated by Mac OS X Finder
|
||||||
|
(^|/)\.DS_Store$
|
||||||
|
|
||||||
|
# Files generated by Windows Explorer
|
||||||
|
(^|/)[dD]esktop\.ini$
|
||||||
|
(^|/)[tT]humbs\.db$
|
||||||
|
syntax: glob
|
||||||
|
build/*
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
54539fa4e51f98d7841c853c1370dff6ccd3cdf2 sourcemod-1.0.0
|
||||||
|
e6ef5ecdf8d75740ca2685a709bf321f8873bc3b sourcemod-1.1.0
|
||||||
|
e877885fac80be71822641f7a9122cebc9812521 sourcemod-1.1.1
|
||||||
|
b3ffa8a4511c4eadaf533fc790aa6b14f7f0c6ea sourcemod-1.1.2
|
||||||
|
3a73bbf60f34befa9b66be03fa5974b394bb3411 sourcemod-1.2.0
|
||||||
|
78a1f1b1c6fa86fd7691c70ebf48a9fb3dfb3c11 sourcemod-1.5.0
|
||||||
|
5574bfe07731b7dba171c1300f6022319d2dbc89 sourcemod-1.5.1
|
||||||
-11
@@ -1,11 +0,0 @@
|
|||||||
language: cpp
|
|
||||||
compiler:
|
|
||||||
- clang
|
|
||||||
before_script:
|
|
||||||
- sudo apt-get update -qq
|
|
||||||
- sudo apt-get install -y g++-multilib libc6-dev-i386 lib32stdc++6 lib32z1-dev
|
|
||||||
- CHECKOUT_DIR=$PWD && cd .. && $CHECKOUT_DIR/tools/checkout-deps.sh && cd $CHECKOUT_DIR
|
|
||||||
script:
|
|
||||||
- mkdir build && cd build
|
|
||||||
- python ../configure.py --enable-optimize --sdks=episode1,tf2,l4d2,csgo,dota
|
|
||||||
- ambuild
|
|
||||||
+490
-505
File diff suppressed because it is too large
Load Diff
@@ -1,6 +0,0 @@
|
|||||||
Contributing
|
|
||||||
------------
|
|
||||||
|
|
||||||
Please visit [our wiki](https://wiki.alliedmods.net/Contributing_to_SourceMod) for information on how to contribute to Sourcemod.
|
|
||||||
|
|
||||||
As a sidenote, [Travis](https://travis-ci.org/alliedmodders/sourcemod) will automatically build your PR to make sure it compiles on Linux.
|
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
|
||||||
|
CONFIGURE YOUR IDENTITY FOR MERCURIAL!
|
||||||
|
IF YOU ARE A DEVELOPER WITH PUSH ACCESS, DO IT NOW KPLZTHX.
|
||||||
|
|
||||||
|
http://wiki.alliedmods.net/Mercurial_Tutorial#Identity
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
SourceMod
|
|
||||||
=========
|
|
||||||
|
|
||||||
General
|
|
||||||
-------
|
|
||||||
- [SourceMod website](http://www.sourcemod.net): Source Engine scripting and server administration
|
|
||||||
- [Forum](https://forums.alliedmods.net/forumdisplay.php?f=52): Discussion forum including plugin/extension development
|
|
||||||
- [General documentation](https://wiki.alliedmods.net/Category:SourceMod_Documentation): Miscellaneous information about SourceMod
|
|
||||||
- [Latest release](http://www.sourcemod.net/downloads.php): The latest stable SourceMod release
|
|
||||||
- [Build snapshots](http://www.sourcemod.net/snapshots.php): Builds of recent development versions
|
|
||||||
|
|
||||||
Development
|
|
||||||
-----------
|
|
||||||
- [Issue tracker](https://bugs.alliedmods.net): 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 extension development](https://wiki.alliedmods.net/Category:SourceMod_Development): C++ examples and introduction to various extension interfaces
|
|
||||||
-222
@@ -1,227 +1,5 @@
|
|||||||
SourceMod Changelog
|
SourceMod Changelog
|
||||||
|
|
||||||
SourceMod 1.6.3 [2014-11-25]
|
|
||||||
|
|
||||||
URL: http://wiki.alliedmods.net/SourceMod_1.6.3_Release_Notes
|
|
||||||
|
|
||||||
User Changes:
|
|
||||||
- Updated game support for TF2, CS:GO, No More Room in Hell, Insurgency, PVK2 and Fistful of Frags.
|
|
||||||
- Made changes to make TF2, CSS, DoDS, HL2DM, and SDK 2013 mods less likely to break on game update (PR 174, PR 192).
|
|
||||||
- Added support for longer key names in languages.cfg (to fix Portuguese) (bug 6282, PR 208).
|
|
||||||
|
|
||||||
Developer Changes:
|
|
||||||
- Updated TF2 player condition and holiday enums (Ross "Powerlord" Bemrose) (PR 183, PR 181).
|
|
||||||
- Add support for TF2 player conditions >= 96 for condition functions/forwards (PR 205).
|
|
||||||
|
|
||||||
----------------------------------------------------------
|
|
||||||
SourceMod 1.6.2 [2014-09-20]
|
|
||||||
|
|
||||||
URL: http://wiki.alliedmods.net/SourceMod_1.6.2_Release_Notes
|
|
||||||
|
|
||||||
User Changes:
|
|
||||||
- Updated game support for TF2, CS:GO, No More Room in Hell and Fistful of Frags.
|
|
||||||
- Added compatibility shim to force Steam player auth strings to be in "Steam2" rendered format (PR 136).
|
|
||||||
- Fixed possible performance regression in DBI handling.
|
|
||||||
|
|
||||||
Developer Changes:
|
|
||||||
- Added new GetClientAuthId native to retrieve player auth strings in desired format (PR 159).
|
|
||||||
- Updated TF2 weapon and player condition enums (FlaminSarge).
|
|
||||||
|
|
||||||
----------------------------------------------------------
|
|
||||||
SourceMod 1.6.1 [2014-08-17]
|
|
||||||
|
|
||||||
URL: http://wiki.alliedmods.net/SourceMod_1.6.1_Release_Notes
|
|
||||||
|
|
||||||
User Changes:
|
|
||||||
- Updated game support for CS:GO and Fistful of Frags.
|
|
||||||
- Added support for Romanian language.
|
|
||||||
- Re-added languages.cfg, missing from 1.6.0, causing all clients to use server language.
|
|
||||||
- Fixed a regression in version 1.6.0 that caused certain SDKHooks usage patterns to cause a server crash (PR 107).
|
|
||||||
- Improved error reporting in basebans plugin when banreasons.txt is missing (PR 115).
|
|
||||||
- Fixed incorrect logged gravity value for sm_gravity command (Ryan "VoiDeD" Stecker) (PR 116).
|
|
||||||
- Fixed a regression in version 1.6.0 causing SDKHook_ReloadPost hooks to not fire in plugins (Peace-Maker) (PR 96).
|
|
||||||
- Added workaround for game bug in TF2_RemoveWeaponSlot to avoid wearable entities left on map (Ryan "VoiDeD" Stecker) (bug 6206, PR 121).
|
|
||||||
- Removed DisableJIT option from core.cfg. (It was never meant for normal use.)
|
|
||||||
|
|
||||||
Developer Changes:
|
|
||||||
- Added new TF2_RemoveWearable native (Ryan "VoiDeD" Stecker, WildCard65) (PR 114).
|
|
||||||
- Added new functions for interacting with and playing scripted game sounds (Ross "Powerlord" Bemrose) (bug 5942, PR 65).
|
|
||||||
- Added new StringToKeyValues natives (Ryan "VoiDeD" Stecker) (PR 74).
|
|
||||||
|
|
||||||
----------------------------------------------------------
|
|
||||||
SourceMod 1.6.0 [2014-07-03]
|
|
||||||
|
|
||||||
URL: http://wiki.alliedmods.net/SourceMod_1.6.0_Release_Notes
|
|
||||||
|
|
||||||
User Changes:
|
|
||||||
- Added support for Dota 2 (bug 5656, bug 6068).
|
|
||||||
- Added support for Source SDK 2013 mods (bug 5917).
|
|
||||||
- Added support for Insurgency (bug 5951).
|
|
||||||
- Added support for Contagion (bug 6007).
|
|
||||||
- Added support for Blade Symphony (bug 5949).
|
|
||||||
- Updated support for some mods that moved to SDK 2013 - No More Room In Hell, Fistful of Frags, Empires, Synergy.
|
|
||||||
- Updated gamedata and other support for TF2, DoD:S, HL2:DM, CS:S, CS:GO, Left 4 Dead, and Nuclear Dawn.
|
|
||||||
- Added support for customizing ban reasons in basebans.sp (bug 5762) (Matthias "House" Kollek).
|
|
||||||
- Added support for searching all gameinfo search paths when seeking mapcycle file (bug 5839).
|
|
||||||
- Added sm_reload_translations command (bug 5750).
|
|
||||||
- Added support for single-file gamedata custom overrides (bug 5386) (Ondrej "RavuAlHemio" Hošek).
|
|
||||||
- Re-enabled SteamAuthstringValidation config option by default (bug 5791, PR 20).
|
|
||||||
- Fixed plugins not reaching ext dep lists, making dependent plugin not unload on ext unload (bug 5851) (Peace-Maker).
|
|
||||||
- Added printing of SendProp flags to netprop dumps (bug 6082).
|
|
||||||
- Removed support for obsolete plugin_settings.cfg (bug 5605).
|
|
||||||
- Fixed topmenu sorting not getting refreshed after reloading sorting config (bug 6032) (Peace-Maker).
|
|
||||||
- Fixed error log filename date sometimes being incorrect (bug 5761) (Matheus "M28" Valadares).
|
|
||||||
- Dump handle information when a plugin is forcefully unloaded. (bug 5666).
|
|
||||||
- Fixed sm_cancelvote not resetting rtv state. (bug 5808) (Peace-Maker).
|
|
||||||
- Fixed Mapchooser dying on single map rotation servers (bug 5179).
|
|
||||||
- Fixed various problems with unloading ClientPrefs and SourceMod (bug 5874).
|
|
||||||
- Fixed "sm version" command reporting incorrect compile time in many cases (bug 6078) (SystematicMania).
|
|
||||||
- Clear default database driver reference if backing extension is unloaded (bug 5934) (Peace-Maker).
|
|
||||||
- Moved funcommands material and sound definitions to gamedata for easier cross-game support (bug 6085).
|
|
||||||
- Implement a watchdog timer for scripts that take too long to execute (bug 5837).
|
|
||||||
- Use Linux game data for offsets and signatures/symbols on OS X if Mac-specific data is not available (bug 6056).
|
|
||||||
|
|
||||||
Developer Changes:
|
|
||||||
- Added an API for off-thread SQL transactions. (bug 3775, PR 26).
|
|
||||||
- Added string literal concatenation using ellipses "..." (bug 4261, PR 5) (Peace-Maker).
|
|
||||||
- Added support for nested datatables. (bug 5446).
|
|
||||||
- Added PbRemoveRepeatedFieldValue native (bug 6066).
|
|
||||||
- Added support for getting/setting protobuf enum values with PbGetInt, PbSetInt, and PbAddInt natives.
|
|
||||||
- Removed deprecated PbReadRepeated natives that existed briefly in 1.5.0-dev prerelease versions.
|
|
||||||
- Added RequestFrame native for one-off next-frame actions (bug 5965).
|
|
||||||
- Added CS_DMG_HEADSHOT define for CS:S and CS:GO (PR 7) (Bara20).
|
|
||||||
- Added CS_SLOT_KNIFE define for CS:S and CS:GO (bug 6131).
|
|
||||||
- Updated TF_WEAPON enum (PR 37) (FlaminSarge).
|
|
||||||
- Added TFHoliday_AprilFools to TFHoliday enum (bug 6092) (Ross "Powerlord" Bemrose).
|
|
||||||
- Added new TF2_IsHolidayActive native to TF2 Ext (bug 6095) (Ross "Powerlord" Bemrose).
|
|
||||||
- Switch TF2 extension to hook CTFGameRules::IsHolidayActive for holiday forward (bug 6137, PR 42).
|
|
||||||
- Added GetPlayerJingleFile native. (bug 5690) (FlaminSarge).
|
|
||||||
- Added PrepSDKCall_SetAddress and Address support to PrepSDKCall_SetFromConf (bug 5261).
|
|
||||||
- Added ability to disable TopMenu Title Caching (bug 6034) (Peace-Maker).
|
|
||||||
- Added DisplayTopMenuCategory native (bug 6033) (Peace-Maker).
|
|
||||||
- Added support for Valve search paths to GetFileSize native (bug 5931).
|
|
||||||
- Fixed invalid entities sometimes passed to OnEntityCreated and OnEntityDestroyed (bug 6119).
|
|
||||||
- Fixed inconsistencies with OnClientDisconnected foward calls (bug 5988, PR 16).
|
|
||||||
- Changed OnClientSayCommand to now pass non-silent chat triggers onward (bug 5926) (SystematicMania).
|
|
||||||
- Changed OnClientSayCommand forwards to strip quotes from chat (bug 5986) (SystematicMania).
|
|
||||||
- Fixed FindStringIndex native not returning INVALID_STRING_INDEX when string not found (bug 6144, PR 40).
|
|
||||||
- Fixed GroundEntChanged hooks not being called (bug 6050) (Peace-Maker).
|
|
||||||
- Fixed INetChannelInfo natives to no longer require clients to be ingame (bug 5775) (SystematicMania).
|
|
||||||
- Fixed replace param being respected inconsistently in SetTrieArray (bug 6113).
|
|
||||||
- Fixed crash creating a timer when there are no handles available. (bug 5317) (Peace-Maker).
|
|
||||||
- Fixed crash in ReconnectClient and InactivateClient natives when IServer ptr is null (bug 6122).
|
|
||||||
- Fixed StoreFromAddress and LoadFromAddress continuing with bad values, usually crashing after error (bug 6080).
|
|
||||||
- Fixed compiler bug with multidimensional array variable release (bug 6100).
|
|
||||||
- Changed float comparison operators to return false for NaN (bug 6107).
|
|
||||||
- Added support in spcomp for sp/inc files > 32767 lines (bug 5959).
|
|
||||||
- Fixed FindFlagChar returning '?' for Admin_Custom6.
|
|
||||||
- Fixed AllPluginsLoaded activities happening before SM is loaded.
|
|
||||||
- Deduplicated a number of files used by extensions by moving them to the public directory (bug 5341).
|
|
||||||
- Removed 'state' keyword from compiler (bug 4572) (Ryan "VoiDeD" Stecker).
|
|
||||||
- Removed LogMessageEx definition from logging.inc because it never existed (bug 5897) (Peace-Maker).
|
|
||||||
- Removed native override API (bug 5852).
|
|
||||||
- Call OnLibraryAdded for all available libraries (bug 5925, PR 4).
|
|
||||||
- Made IGameConfig::GetMemSig return value clearer (bug 6081).
|
|
||||||
- Switched StringToInt(Ex) from using strtol to strtoul internally (bug 5939).
|
|
||||||
- Added an spcomp option to print #included files (bug 5997).
|
|
||||||
- Recompiled Regex extension libpcre against v8.32, enabling utf8, unicode props, and jit (bug 5593).
|
|
||||||
- Optimized native calls if statically bound (bug 5842).
|
|
||||||
|
|
||||||
Internal Changes:
|
|
||||||
- Now using new AlliedModders Template Library (AMTL) in many places, https://github.com/alliedmodders/amtl
|
|
||||||
- Ported buildscripts to new AMBuild2 platform, https://github.com/alliedmodders/ambuild
|
|
||||||
- Moved much logic from core to logic binary to reduce file sizes and compile times (bug 5606, bug 5607, bug 5680, bug 5953, PR 12, PR 13).
|
|
||||||
- Refactored the JIT to use a newer, simpler macro assembler. (bug 5827).
|
|
||||||
- Added sourcepawn interpreter (bug 5902).
|
|
||||||
- Added support for compiling spcomp with emscripten.
|
|
||||||
- Rewrite IThreader implementation around new synchronization primitives (bug 5862).
|
|
||||||
- Rewrite DBManager to use the new synchronization primitives (bug 5870).
|
|
||||||
- Overhauled internals of ClientPrefs extension for improved stability (bug 5538).
|
|
||||||
- Changed ShareSys to store C++ native lists more optimally (bug 5852).
|
|
||||||
- Simplified NativeEntry state (bug 5852).
|
|
||||||
- Changed NativeEntry to use Refcounted to manage (bug 5852).
|
|
||||||
- Switched Translator and GameConfigs to hash tables (bug 5878).
|
|
||||||
- Switched numerous subsystems from KTrie to AMTL NameHashSet (bug 5884).
|
|
||||||
- Refactored Trie natives to use AMTL HashMap instead of KTrie (bug 5892).
|
|
||||||
- Removed usages of memtables from many subsystems (bug 5899).
|
|
||||||
- Changed EventHook name storage to use AMTL AString (bug 6188).
|
|
||||||
- Replaced SH List usages in game extensions with AMTL variants (PR 23).
|
|
||||||
- Replaced SourceHook list usages in clientprefs with AMTL (PR 25).
|
|
||||||
- Changed floating-point operations to use SSE when available (bug 5841).
|
|
||||||
- Moved tracker related opcodes entirely to C++.
|
|
||||||
- Statically align the stack at function boundaries (bug 5842).
|
|
||||||
- Removed InfoVars, reassigned DAT from EBP to ESI to preserve C++ stacktraces in JIT code (5844).
|
|
||||||
- Fixed dereferencing potential null pointer in CPlugin::GetProperty (bug 5725).
|
|
||||||
- Fixed memory corruption when parsing natives. (bug 5840).
|
|
||||||
- Fixed some memory errors (bug 5904).
|
|
||||||
- Fixed unaligned memory access in spcomp.
|
|
||||||
- Move versioning to a static library to improve trivial build speed (bug 5997).
|
|
||||||
- Added many missing handle security checks (bug 5595).
|
|
||||||
- Made GetEntityClassname get and cache m_iClassname offset from worldspawn for ents not having it in datadesc (bug 5654).
|
|
||||||
- Cache m_iEFlags offset for datamaps dump instead of getting for each ent (bug 5657).
|
|
||||||
- Fixed mismatched delete [] on thunks in JIT CompData dtor (bug 5639).
|
|
||||||
- Fixed various memory issues. (bug 5766).
|
|
||||||
- Added reference counting and use it for CGameConfig and IDatabase (bug 5876).
|
|
||||||
- Added atomic reference counting and port DBI (bug 5876).
|
|
||||||
- Replaced usages of deprecated Sourcehook Add/Remove macros (bug 5631).
|
|
||||||
- Fixed SDKHooks hook ent validation missing first datatable name (bug 5881).
|
|
||||||
- Fixed case where bots leave server without disconnect notice (hibernation) (PR 20).
|
|
||||||
- Changed FindConVar to utilize convar cache for improved performance (PR 27) (VoiDeD).
|
|
||||||
- Gave define value (of 1) to PLATFORM defs to match the same-name defs in some SDKs (PR 10).
|
|
||||||
- Wrapped ClientPrintf into IGamePlayer (bug 6021).
|
|
||||||
- Consolidated FileExists usage in logic bin (bug 5931).
|
|
||||||
- Removed hardcoded paths to tier0/vstdlib in ICommandLine lookup.
|
|
||||||
- Use updated IServerTools iface on TF2 for getting tempent list and FindEntityByClassname (PR 33).
|
|
||||||
- Added early exit in entity output detour if entity has no classname to prevent crash.
|
|
||||||
- Updated SDKTools entity output functions to use core's GetEntityClassname instead of own (PR 39).
|
|
||||||
- Consolidated SDKTools entity factory lookups.
|
|
||||||
- Changed SDKTools PlayerRunCmd to a global vtable hook to improve performance (bug 6051).
|
|
||||||
- Changed SDKHooks to use global vtable hooks to improve performance (bug 6070).
|
|
||||||
- Added client validation checks to EmitSound SoundsHooks (bug 5873).
|
|
||||||
- Added missing meta results to some pre-hooks in SDKHooks.
|
|
||||||
- Replaced magic numbers for sm_show_activity with named constants (PR 14).
|
|
||||||
|
|
||||||
----------------------------------------------------------
|
|
||||||
SourceMod 1.5.3 [2014-03-22]
|
|
||||||
|
|
||||||
URL: http://wiki.alliedmods.net/SourceMod_1.5.3_Release_Notes
|
|
||||||
|
|
||||||
User Changes:
|
|
||||||
- Updated support for CS:GO after multiple breaking game updates.
|
|
||||||
- Updated gamedata support for GoldenEye: Source (Peace-Maker).
|
|
||||||
- Fixed crash on SDKHooks extension load in Alien Swarm (bug 6059).
|
|
||||||
- Fixed memory leak from unmanaged forwards never being freed (bug 6025).
|
|
||||||
- Fixed possible crash when unloading the CStrike extension.
|
|
||||||
- Fixed crash in SDKHooks Reload post-hook (Peace-Maker).
|
|
||||||
- Fixed FakeClientCommandEx always leaking memory (bug 5678).
|
|
||||||
- Fixed extra entity networking occuring with SetEntProp natives on some games.
|
|
||||||
- Fixed being able to nominate same map multiple times (bug 5109).
|
|
||||||
- Fixed spurious FindEntityByClassname error being logged on some games and platforms.
|
|
||||||
- Fixed an Anti-Flood bypass exploit (bug 5394).
|
|
||||||
- Removed part of Addresses gamedata error handling which could cause false errors to be logged (bug 6044).
|
|
||||||
- Fixed mapchooser not resetting nominations count when clearing nominations list (bug 5359).
|
|
||||||
- Improved performances of client convar query handling (bug 6003).
|
|
||||||
|
|
||||||
Developer Changes:
|
|
||||||
- Added GiveAmmo native to SDKTools (bug 6039) (Peace-Maker).
|
|
||||||
- Added SQL_SetCharset native to (re)set charset even after reconnect (bug 5786) (Peace-Maker).
|
|
||||||
- Added support for entity references in SDKHooks natives (bug 6069).
|
|
||||||
- Added support for server passwords to DisplayAskConnectBox stock (bug 5984) (FlaminSarge).
|
|
||||||
- Renamed SortFunc2D parameters to match documentation (bug 6014) (Peace-Maker).
|
|
||||||
- Fixed param order in AddToTopMenu function doc (bug 6035) (Peace-Maker).
|
|
||||||
- Added |any| tag to WritePackCell and ReadPackCell native param/return values (bug 6001).
|
|
||||||
- Updated SDKHook_TakeDamage native for game updates.
|
|
||||||
- Added default infinite value for TF2_AddCondition duration.
|
|
||||||
- Added support for conditions >= 64 in TF2_OnConditionAdded/Removed (bug 5565, bug 5976) (FlaminSarge).
|
|
||||||
- Updated TFCond and TF customkill enum values (bug 6012) (FlaminSarge).
|
|
||||||
- Fixed regression causing incorrect return and inability to block in TF2_OnCalcIsAttackCritical forward.
|
|
||||||
- Fixed TE_* natives operating on incorrect data for some tempents (bug 6072).
|
|
||||||
- Fixed CS_AliasToWeaponID not returning a valid weaponID for cz75a.
|
|
||||||
- Fixed CS_GetWeaponPrice returning incorrect value for M4A1 in CS:GO (bug 6045).
|
|
||||||
- Increased max gamedata byte signature length.
|
|
||||||
- Ported SM build scripts to AMBuild2 (bug 5997).
|
|
||||||
|
|
||||||
----------------------------------------------------------
|
|
||||||
SourceMod 1.5.2 [2013-10-29]
|
SourceMod 1.5.2 [2013-10-29]
|
||||||
|
|
||||||
URL: http://wiki.alliedmods.net/SourceMod_1.5.2_Release_Notes
|
URL: http://wiki.alliedmods.net/SourceMod_1.5.2_Release_Notes
|
||||||
|
|||||||
@@ -1,16 +0,0 @@
|
|||||||
"banreasons"
|
|
||||||
{
|
|
||||||
"Abusive" "Abusive"
|
|
||||||
"Racism" "Racism"
|
|
||||||
"General cheating/exploits" "General cheating/exploits"
|
|
||||||
"Wallhack" "Wallhack"
|
|
||||||
"Aimbot" "Aimbot"
|
|
||||||
"Speedhacking" "Speedhacking"
|
|
||||||
"Mic spamming" "Mic spamming"
|
|
||||||
"Admin disrespect" "Admin disrespect"
|
|
||||||
"Camping" "Camping"
|
|
||||||
"Team killing" "Team killing"
|
|
||||||
"Unacceptable Spray" "Unacceptable Spray"
|
|
||||||
"Breaking Server Rules" "Breaking Server Rules"
|
|
||||||
"Other" "Other"
|
|
||||||
}
|
|
||||||
+1
-9
@@ -114,7 +114,7 @@
|
|||||||
* If Steam is down, admins will not be authenticated until Steam comes back up.
|
* If Steam is down, admins will not be authenticated until Steam comes back up.
|
||||||
* This option increases the security of your server, but is still experimental.
|
* This option increases the security of your server, but is still experimental.
|
||||||
*/
|
*/
|
||||||
"SteamAuthstringValidation" "yes"
|
"SteamAuthstringValidation" "no"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enables or disables whether SourceMod blocks known or potentially malicious plugins from loading.
|
* Enables or disables whether SourceMod blocks known or potentially malicious plugins from loading.
|
||||||
@@ -125,12 +125,4 @@
|
|||||||
* "no" - Warn about malware or illegal plugins loading
|
* "no" - Warn about malware or illegal plugins loading
|
||||||
*/
|
*/
|
||||||
"BlockBadPlugins" "yes"
|
"BlockBadPlugins" "yes"
|
||||||
|
|
||||||
/**
|
|
||||||
* If a plugin takes too long to execute, hanging or freezing the game server in the process,
|
|
||||||
* SourceMod will attempt to terminate that plugin after the specified timeout length has
|
|
||||||
* passed. You can disable this feature by setting the value to "0".
|
|
||||||
*/
|
|
||||||
"SlowScriptTimeout" "8"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
/**
|
||||||
|
* Each sub-section of "Plugins" should have a title which specifies a plugin filename.
|
||||||
|
* Filenames have a wildcard of *. Appending .smx is not required.
|
||||||
|
* If the filename has no explicit path, it will be patched to any sub-path in the plugins folder.
|
||||||
|
*
|
||||||
|
* Available properties for plugins are:
|
||||||
|
* "pause" - Whether or not the plugin should load paused - "yes" or "no" (default)
|
||||||
|
* "lifetime" - Lifetime of the plugin. Options:
|
||||||
|
* "mapsync" - Plugins should be reloaded on mapchange if changed (default)
|
||||||
|
* "global" - Plugin will never be unloaded or updated
|
||||||
|
* "blockload" - Plugin will always be blocked from loading. Implicit (automatic) loads
|
||||||
|
* produce no error, but explicit (manual) loads will show an error message.
|
||||||
|
* (Options are one of "yes" or "no")
|
||||||
|
*
|
||||||
|
* You can also have an "Options" section declaring options to pass onto the JIT:
|
||||||
|
* "profile" - Bit flags for profiling level. Add flags together to reach a value.
|
||||||
|
* WARNING: Profiler is _ALPHA_ software! Use it at your own risk for
|
||||||
|
* development cycles only (not production setups).
|
||||||
|
* See the wiki article "SourceMod Profiler" for more information.
|
||||||
|
* 1 - Profile natives
|
||||||
|
* 2 - Profile callbacks
|
||||||
|
* 4 - Profile internal plugin function calls
|
||||||
|
*/
|
||||||
|
|
||||||
|
"Plugins"
|
||||||
|
{
|
||||||
|
"*"
|
||||||
|
{
|
||||||
|
"pause" "no"
|
||||||
|
"lifetime" "mapsync"
|
||||||
|
|
||||||
|
"Options"
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+3
-22
@@ -1,25 +1,8 @@
|
|||||||
# vim: set ts=2 sw=2 tw=99 noet:
|
# vim: set ts=2 sw=2 tw=99 noet:
|
||||||
import sys
|
import sys
|
||||||
try:
|
import ambuild.runner as runner
|
||||||
from ambuild2 import run
|
|
||||||
except:
|
|
||||||
try:
|
|
||||||
import ambuild
|
|
||||||
sys.stderr.write('It looks like you have AMBuild 1 installed, but this project uses AMBuild 2.\n')
|
|
||||||
sys.stderr.write('Upgrade to the latest version of AMBuild to continue.\n')
|
|
||||||
except:
|
|
||||||
sys.stderr.write('AMBuild must be installed to build this project.\n')
|
|
||||||
sys.stderr.write('http://www.alliedmods.net/ambuild\n')
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
run = run.PrepareBuild(sourcePath=sys.path[0])
|
run = runner.Runner()
|
||||||
run.default_build_folder = 'obj-' + run.target_platform
|
|
||||||
run.options.add_option('--hl2sdk-root', type=str, dest='hl2sdk_root', default=None,
|
|
||||||
help='Root search folder for HL2SDKs')
|
|
||||||
run.options.add_option('--mysql-path', type=str, dest='mysql_path', default=None,
|
|
||||||
help='Path to MySQL 5')
|
|
||||||
run.options.add_option('--mms-path', type=str, dest='mms_path', default=None,
|
|
||||||
help='Path to Metamod:Source')
|
|
||||||
run.options.add_option('--enable-debug', action='store_const', const='1', dest='debug',
|
run.options.add_option('--enable-debug', action='store_const', const='1', dest='debug',
|
||||||
help='Enable debugging symbols')
|
help='Enable debugging symbols')
|
||||||
run.options.add_option('--enable-optimize', action='store_const', const='1', dest='opt',
|
run.options.add_option('--enable-optimize', action='store_const', const='1', dest='opt',
|
||||||
@@ -29,6 +12,4 @@ run.options.add_option('--no-mysql', action='store_false', default=True, dest='h
|
|||||||
run.options.add_option('-s', '--sdks', default='all', dest='sdks',
|
run.options.add_option('-s', '--sdks', default='all', dest='sdks',
|
||||||
help='Build against specified SDKs; valid args are "all", "present", or '
|
help='Build against specified SDKs; valid args are "all", "present", or '
|
||||||
'comma-delimited list of engine names (default: %default)')
|
'comma-delimited list of engine names (default: %default)')
|
||||||
run.options.add_option('--breakpad-dump', action='store_true', dest='breakpad_dump',
|
run.Configure(sys.path[0])
|
||||||
default=False, help='Dump and upload breakpad symbols')
|
|
||||||
run.Configure()
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* vim: set ts=4 sw=4 tw=99 noet :
|
* vim: set ts=4 :
|
||||||
* =============================================================================
|
* =============================================================================
|
||||||
* SourceMod
|
* SourceMod
|
||||||
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
||||||
@@ -30,6 +30,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "ADTFactory.h"
|
#include "ADTFactory.h"
|
||||||
|
#include "sm_globals.h"
|
||||||
#include "ShareSys.h"
|
#include "ShareSys.h"
|
||||||
|
|
||||||
ADTFactory g_AdtFactory;
|
ADTFactory g_AdtFactory;
|
||||||
@@ -56,30 +57,32 @@ IBasicTrie *ADTFactory::CreateBasicTrie()
|
|||||||
|
|
||||||
BaseTrie::BaseTrie()
|
BaseTrie::BaseTrie()
|
||||||
{
|
{
|
||||||
|
m_pTrie = sm_trie_create();
|
||||||
}
|
}
|
||||||
|
|
||||||
BaseTrie::~BaseTrie()
|
BaseTrie::~BaseTrie()
|
||||||
{
|
{
|
||||||
|
sm_trie_destroy(m_pTrie);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BaseTrie::Insert(const char *key, void *value)
|
bool BaseTrie::Insert(const char *key, void *value)
|
||||||
{
|
{
|
||||||
return map_.insert(key, value);
|
return sm_trie_insert(m_pTrie, key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BaseTrie::Retrieve(const char *key, void **value)
|
bool BaseTrie::Retrieve(const char *key, void **value)
|
||||||
{
|
{
|
||||||
return map_.retrieve(key, value);
|
return sm_trie_retrieve(m_pTrie, key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BaseTrie::Delete(const char *key)
|
bool BaseTrie::Delete(const char *key)
|
||||||
{
|
{
|
||||||
return map_.remove(key);
|
return sm_trie_delete(m_pTrie, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BaseTrie::Clear()
|
void BaseTrie::Clear()
|
||||||
{
|
{
|
||||||
map_.clear();
|
sm_trie_clear(m_pTrie);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BaseTrie::Destroy()
|
void BaseTrie::Destroy()
|
||||||
@@ -89,5 +92,5 @@ void BaseTrie::Destroy()
|
|||||||
|
|
||||||
bool BaseTrie::Replace(const char *key, void *value)
|
bool BaseTrie::Replace(const char *key, void *value)
|
||||||
{
|
{
|
||||||
return map_.replace(key, value);
|
return sm_trie_replace(m_pTrie, key, value);
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* vim: set ts=4 sw=4 tw=99 noet :
|
* vim: set ts=4 :
|
||||||
* =============================================================================
|
* =============================================================================
|
||||||
* SourceMod
|
* SourceMod
|
||||||
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
||||||
@@ -33,8 +33,8 @@
|
|||||||
#define _INCLUDE_SOURCEMOD_ADTFACTORY_H_
|
#define _INCLUDE_SOURCEMOD_ADTFACTORY_H_
|
||||||
|
|
||||||
#include <IADTFactory.h>
|
#include <IADTFactory.h>
|
||||||
#include "common_logic.h"
|
#include "sm_globals.h"
|
||||||
#include <sm_stringhashmap.h>
|
#include "sm_trie.h"
|
||||||
|
|
||||||
using namespace SourceMod;
|
using namespace SourceMod;
|
||||||
|
|
||||||
@@ -50,7 +50,7 @@ public:
|
|||||||
virtual void Clear();
|
virtual void Clear();
|
||||||
virtual void Destroy();
|
virtual void Destroy();
|
||||||
private:
|
private:
|
||||||
StringHashMap<void *> map_;
|
Trie *m_pTrie;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ADTFactory :
|
class ADTFactory :
|
||||||
+117
-107
@@ -1,118 +1,128 @@
|
|||||||
# vim: set sts=2 ts=8 sw=2 tw=99 et ft=python:
|
# vim: set ts=2 sw=2 tw=99 noet ft=python:
|
||||||
import os
|
import os
|
||||||
|
from ambuild.command import SymlinkCommand
|
||||||
|
|
||||||
project = SM.HL2Project(builder, 'sourcemod')
|
for i in SM.sdkInfo:
|
||||||
project.sources += [
|
sdk = SM.sdkInfo[i]
|
||||||
'MenuStyle_Valve.cpp',
|
if AMBuild.target['platform'] not in sdk['platform']:
|
||||||
'logic_bridge.cpp',
|
continue
|
||||||
'smn_entities.cpp',
|
|
||||||
'sm_stringutil.cpp',
|
|
||||||
'MenuVoting.cpp',
|
|
||||||
'smn_events.cpp',
|
|
||||||
'smn_menus.cpp',
|
|
||||||
'CDataPack.cpp',
|
|
||||||
'frame_hooks.cpp',
|
|
||||||
'smn_nextmap.cpp',
|
|
||||||
'sourcemm_api.cpp',
|
|
||||||
'ChatTriggers.cpp',
|
|
||||||
'smn_player.cpp',
|
|
||||||
'sourcemod.cpp',
|
|
||||||
'concmd_cleaner.cpp',
|
|
||||||
'HalfLife2.cpp',
|
|
||||||
'NextMap.cpp',
|
|
||||||
'ConCmdManager.cpp',
|
|
||||||
'ConVarManager.cpp',
|
|
||||||
'LibrarySys.cpp',
|
|
||||||
'PlayerManager.cpp',
|
|
||||||
'TimerSys.cpp',
|
|
||||||
'CoreConfig.cpp',
|
|
||||||
'Logger.cpp',
|
|
||||||
'smn_halflife.cpp',
|
|
||||||
'smn_console.cpp',
|
|
||||||
'UserMessages.cpp',
|
|
||||||
'MenuManager.cpp',
|
|
||||||
'smn_core.cpp',
|
|
||||||
'smn_hudtext.cpp',
|
|
||||||
'smn_usermsgs.cpp',
|
|
||||||
'MenuStyle_Base.cpp',
|
|
||||||
'smn_keyvalues.cpp',
|
|
||||||
'smn_vector.cpp',
|
|
||||||
'EventManager.cpp',
|
|
||||||
'MenuStyle_Radio.cpp',
|
|
||||||
'sm_autonatives.cpp',
|
|
||||||
'sm_srvcmds.cpp',
|
|
||||||
'ConsoleDetours.cpp'
|
|
||||||
]
|
|
||||||
|
|
||||||
for sdk_name in SM.sdks:
|
name = 'sourcemod.' + sdk['ext']
|
||||||
sdk = SM.sdks[sdk_name]
|
|
||||||
binary_name = 'sourcemod.' + sdk.ext
|
|
||||||
|
|
||||||
binary = SM.HL2Config(project, binary_name, sdk)
|
compiler = SM.DefaultHL2Compiler('core', i)
|
||||||
compiler = binary.compiler
|
|
||||||
|
|
||||||
if sdk.name == 'csgo':
|
if i == 'csgo':
|
||||||
compiler.cxxincludes += [
|
# Protobuf 2.3 headers have some signed/unsigned compares. I believe that it's fixed in later versions, but Valve.
|
||||||
os.path.join(sdk.path, 'common', 'protobuf-2.5.0', 'src'),
|
if isinstance(compiler.cxx, Cpp.CompatGCC):
|
||||||
os.path.join(sdk.path, 'public', 'engine', 'protobuf'),
|
compiler.AddToListVar('CFLAGS', '-Wno-sign-compare')
|
||||||
os.path.join(sdk.path, 'public', 'game', 'shared', 'csgo', 'protobuf')
|
compiler['CXXINCLUDES'].append(os.path.join(AMBuild.cache[sdk['sdk']], 'common', 'protobuf-2.3.0', 'src'))
|
||||||
]
|
compiler['CXXINCLUDES'].append(os.path.join(AMBuild.cache[sdk['sdk']], 'public', 'engine', 'protobuf'))
|
||||||
elif sdk.name == 'dota':
|
compiler['CXXINCLUDES'].append(os.path.join(AMBuild.cache[sdk['sdk']], 'public', 'game', 'shared', 'csgo', 'protobuf'))
|
||||||
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', 'protobuf'),
|
|
||||||
os.path.join(sdk.path, 'public', 'game', 'shared', 'dota', 'protobuf')
|
|
||||||
]
|
|
||||||
|
|
||||||
if builder.target_platform == 'linux':
|
extension = AMBuild.AddJob(name)
|
||||||
compiler.postlink += ['-lpthread', '-lrt']
|
binary = Cpp.LibraryBuilder(name, AMBuild, extension, compiler)
|
||||||
|
SM.PreSetupHL2Job(extension, binary, i)
|
||||||
|
|
||||||
if sdk.name == 'csgo' or sdk.name == 'dota':
|
if i == 'csgo':
|
||||||
if builder.target_platform == 'linux':
|
if AMBuild.target['platform'] == 'linux':
|
||||||
lib_path = os.path.join(sdk.path, 'lib', 'linux32', 'release', 'libprotobuf.a')
|
link = os.path.join(os.path.join(AMBuild.outputFolder, extension.workFolder), 'libprotobuf.a')
|
||||||
elif builder.target_platform == 'mac':
|
target = os.path.join(os.path.join(AMBuild.cache[sdk['sdk']], 'lib', 'linux32', 'release'), 'libprotobuf.a')
|
||||||
lib_path = os.path.join(sdk.path, 'lib', 'osx32', 'release', 'libprotobuf.a')
|
try:
|
||||||
elif builder.target_platform == 'windows':
|
os.lstat(link)
|
||||||
msvc_ver = compiler.version
|
except:
|
||||||
vs_year = ''
|
extension.AddCommand(SymlinkCommand(link, target))
|
||||||
if msvc_ver == 1800:
|
elif AMBuild.target['platform'] == 'darwin':
|
||||||
vs_year = '2013'
|
link = os.path.join(os.path.join(AMBuild.outputFolder, extension.workFolder), 'libprotobuf.a')
|
||||||
elif msvc_ver == 1700:
|
target = os.path.join(os.path.join(AMBuild.cache[sdk['sdk']], 'lib', 'osx32', 'release'), 'libprotobuf.a')
|
||||||
vs_year = '2012'
|
try:
|
||||||
elif msvc_ver == 1600:
|
os.lstat(link)
|
||||||
vs_year = '2010'
|
except:
|
||||||
else:
|
extension.AddCommand(SymlinkCommand(link, target))
|
||||||
raise Exception('Cannot find libprotobuf for MSVC version "' + compiler.version + '"')
|
elif AMBuild.target['platform'] == 'windows':
|
||||||
|
libPath = os.path.join(AMBuild.cache[sdk['sdk']], 'lib', 'win32', 'release', 'vs2010', 'libprotobuf.lib')
|
||||||
|
binary.RebuildIfNewer(libPath)
|
||||||
|
binary['POSTLINKFLAGS'].append(libPath)
|
||||||
|
|
||||||
if 'DEBUG' in compiler.defines:
|
files = [
|
||||||
lib_path = os.path.join(sdk.path, 'lib', 'win32', 'debug', 'vs' + vs_year, 'libprotobuf.lib')
|
'AdminCache.cpp',
|
||||||
else:
|
'ExtensionSys.cpp',
|
||||||
lib_path = os.path.join(sdk.path, 'lib', 'win32', 'release', 'vs' + vs_year, 'libprotobuf.lib')
|
'MenuStyle_Valve.cpp',
|
||||||
compiler.linkflags.insert(0, binary.Dep(lib_path))
|
'logic_bridge.cpp',
|
||||||
|
'smn_entities.cpp',
|
||||||
if sdk.name in ['csgo', 'dota']:
|
'sm_stringutil.cpp',
|
||||||
binary.sources += ['smn_protobuf.cpp']
|
'ADTFactory.cpp',
|
||||||
else:
|
'ForwardSys.cpp',
|
||||||
binary.sources += ['smn_bitbuffer.cpp']
|
'MenuVoting.cpp',
|
||||||
|
'smn_events.cpp',
|
||||||
|
'smn_menus.cpp',
|
||||||
|
'sm_trie.cpp',
|
||||||
|
'CDataPack.cpp',
|
||||||
|
'frame_hooks.cpp',
|
||||||
|
'NativeInvoker.cpp',
|
||||||
|
'smn_fakenatives.cpp',
|
||||||
|
'smn_nextmap.cpp',
|
||||||
|
'sourcemm_api.cpp',
|
||||||
|
'ChatTriggers.cpp',
|
||||||
|
'NativeOwner.cpp',
|
||||||
|
'smn_filesystem.cpp',
|
||||||
|
'smn_player.cpp',
|
||||||
|
'sourcemod.cpp',
|
||||||
|
'concmd_cleaner.cpp',
|
||||||
|
'HalfLife2.cpp',
|
||||||
|
'NextMap.cpp',
|
||||||
|
'ConCmdManager.cpp',
|
||||||
|
'HandleSys.cpp',
|
||||||
|
'ConVarManager.cpp',
|
||||||
|
'LibrarySys.cpp',
|
||||||
|
'PlayerManager.cpp',
|
||||||
|
'TimerSys.cpp',
|
||||||
|
'CoreConfig.cpp',
|
||||||
|
'Logger.cpp',
|
||||||
|
'PluginInfoDatabase.cpp',
|
||||||
|
'smn_halflife.cpp',
|
||||||
|
'PluginSys.cpp',
|
||||||
|
'smn_console.cpp',
|
||||||
|
'UserMessages.cpp',
|
||||||
|
'Database.cpp',
|
||||||
|
'MenuManager.cpp',
|
||||||
|
'smn_core.cpp',
|
||||||
|
'smn_hudtext.cpp',
|
||||||
|
'smn_usermsgs.cpp',
|
||||||
|
'DebugReporter.cpp',
|
||||||
|
'MenuStyle_Base.cpp',
|
||||||
|
'ShareSys.cpp',
|
||||||
|
'smn_database.cpp',
|
||||||
|
'smn_keyvalues.cpp',
|
||||||
|
'smn_vector.cpp',
|
||||||
|
'EventManager.cpp',
|
||||||
|
'MenuStyle_Radio.cpp',
|
||||||
|
'sm_autonatives.cpp',
|
||||||
|
'sm_srvcmds.cpp',
|
||||||
|
'ConsoleDetours.cpp'
|
||||||
|
]
|
||||||
|
|
||||||
|
if i == 'csgo':
|
||||||
|
files.append('smn_protobuf.cpp')
|
||||||
|
else:
|
||||||
|
files.append('smn_bitbuffer.cpp')
|
||||||
|
|
||||||
if sdk.name == 'csgo':
|
binary.AddSourceFiles('core', files)
|
||||||
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'),
|
|
||||||
]
|
|
||||||
elif sdk.name == 'dota':
|
|
||||||
binary.sources += [
|
|
||||||
os.path.join(sdk.path, 'public', 'engine', 'protobuf', 'networkbasetypes.pb.cc'),
|
|
||||||
os.path.join(sdk.path, 'public', 'engine', 'protobuf', 'netmessages.pb.cc'),
|
|
||||||
os.path.join(sdk.path, 'public', 'engine', 'protobuf', 'network_connection.pb.cc'),
|
|
||||||
os.path.join(sdk.path, 'public', 'game', 'shared', 'protobuf', 'ai_activity.pb.cc'),
|
|
||||||
os.path.join(sdk.path, 'public', 'game', 'shared', 'protobuf', 'usermessages.pb.cc'),
|
|
||||||
os.path.join(sdk.path, 'public', 'game', 'shared', 'dota', 'protobuf', 'dota_commonmessages.pb.cc'),
|
|
||||||
os.path.join(sdk.path, 'public', 'game', 'shared', 'dota', 'protobuf', 'dota_usermessages.pb.cc'),
|
|
||||||
os.path.join(sdk.path, 'public', 'game', 'shared', 'dota', 'protobuf', 'dota_usermessage_helpers.cpp'),
|
|
||||||
]
|
|
||||||
|
|
||||||
SM.binaries += builder.Add(project)
|
if i == 'csgo':
|
||||||
|
files = [
|
||||||
|
os.path.join('public', 'engine', 'protobuf', 'netmessages.pb.cc'),
|
||||||
|
os.path.join('public', 'game', 'shared', 'csgo', 'protobuf', 'cstrike15_usermessages.pb.cc'),
|
||||||
|
os.path.join('public', 'game', 'shared', 'csgo', 'protobuf', 'cstrike15_usermessage_helpers.cpp'),
|
||||||
|
]
|
||||||
|
binary.AddSourceFiles(AMBuild.cache[sdk['sdk']], files)
|
||||||
|
|
||||||
|
SM.PostSetupHL2Job(extension, binary, i)
|
||||||
|
|
||||||
|
if i == 'csgo':
|
||||||
|
if AMBuild.target['platform'] in ['linux', 'darwin']:
|
||||||
|
binary.AddObjectFiles(['libprotobuf.a'])
|
||||||
|
|
||||||
|
SM.AutoVersion('core', binary)
|
||||||
|
SM.ExtractDebugInfo(extension, binary)
|
||||||
|
binary.SendToJob()
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,226 +1,208 @@
|
|||||||
/**
|
/**
|
||||||
* vim: set ts=4 sw=4 tw=99 noet :
|
* vim: set ts=4 :
|
||||||
* =============================================================================
|
* =============================================================================
|
||||||
* SourceMod
|
* SourceMod
|
||||||
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
||||||
* =============================================================================
|
* =============================================================================
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it under
|
* This program is free software; you can redistribute it and/or modify it under
|
||||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||||
* Free Software Foundation.
|
* Free Software Foundation.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
* 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
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
* details.
|
* details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along with
|
* You should have received a copy of the GNU General Public License along with
|
||||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
* 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
|
* 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
|
* "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
|
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||||
* this exception to all derivative works. AlliedModders LLC defines further
|
* this exception to all derivative works. AlliedModders LLC defines further
|
||||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||||
* or <http://www.sourcemod.net/license.php>.
|
* or <http://www.sourcemod.net/license.php>.
|
||||||
*
|
*
|
||||||
* Version: $Id$
|
* Version: $Id$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _INCLUDE_SOURCEMOD_ADMINCACHE_H_
|
#ifndef _INCLUDE_SOURCEMOD_ADMINCACHE_H_
|
||||||
#define _INCLUDE_SOURCEMOD_ADMINCACHE_H_
|
#define _INCLUDE_SOURCEMOD_ADMINCACHE_H_
|
||||||
|
|
||||||
#include "common_logic.h"
|
#include "sm_memtable.h"
|
||||||
#include <IAdminSystem.h>
|
#include <sm_trie.h>
|
||||||
#include "sm_memtable.h"
|
#include <sh_list.h>
|
||||||
#include <sm_trie.h>
|
#include <sh_string.h>
|
||||||
#include <sh_list.h>
|
#include <IAdminSystem.h>
|
||||||
#include <sh_string.h>
|
#include "sm_globals.h"
|
||||||
#include <IForwardSys.h>
|
#include <IForwardSys.h>
|
||||||
#include <sm_stringhashmap.h>
|
|
||||||
#include <sm_namehashset.h>
|
using namespace SourceHook;
|
||||||
|
|
||||||
using namespace SourceHook;
|
#define GRP_MAGIC_SET 0xDEADFADE
|
||||||
|
#define GRP_MAGIC_UNSET 0xFACEFACE
|
||||||
#define GRP_MAGIC_SET 0xDEADFADE
|
#define USR_MAGIC_SET 0xDEADFACE
|
||||||
#define GRP_MAGIC_UNSET 0xFACEFACE
|
#define USR_MAGIC_UNSET 0xFADEDEAD
|
||||||
#define USR_MAGIC_SET 0xDEADFACE
|
|
||||||
#define USR_MAGIC_UNSET 0xFADEDEAD
|
struct AdminGroup
|
||||||
|
{
|
||||||
typedef StringHashMap<OverrideRule> OverrideMap;
|
uint32_t magic; /* Magic flag, for memory validation (ugh) */
|
||||||
|
unsigned int immunity_level; /* Immunity level */
|
||||||
struct AdminGroup
|
/* Immune from target table (-1 = nonexistent)
|
||||||
{
|
* [0] = number of entries
|
||||||
uint32_t magic; /* Magic flag, for memory validation (ugh) */
|
* [1...N] = immune targets
|
||||||
unsigned int immunity_level; /* Immunity level */
|
*/
|
||||||
/* Immune from target table (-1 = nonexistent)
|
int immune_table;
|
||||||
* [0] = number of entries
|
Trie *pCmdTable; /* Command override table (can be NULL) */
|
||||||
* [1...N] = immune targets
|
Trie *pCmdGrpTable; /* Command group override table (can be NULL) */
|
||||||
*/
|
int next_grp; /* Next group in the chain */
|
||||||
int immune_table;
|
int prev_grp; /* Previous group in the chain */
|
||||||
OverrideMap *pCmdTable; /* Command override table (can be NULL) */
|
int nameidx; /* Name */
|
||||||
OverrideMap *pCmdGrpTable; /* Command group override table (can be NULL) */
|
FlagBits addflags; /* Additive flags */
|
||||||
int next_grp; /* Next group in the chain */
|
};
|
||||||
int prev_grp; /* Previous group in the chain */
|
|
||||||
int nameidx; /* Name */
|
struct AuthMethod
|
||||||
FlagBits addflags; /* Additive flags */
|
{
|
||||||
};
|
String name;
|
||||||
|
Trie *table;
|
||||||
struct AuthMethod
|
};
|
||||||
{
|
|
||||||
String name;
|
struct UserAuth
|
||||||
StringHashMap<AdminId> identities;
|
{
|
||||||
|
unsigned int index; /* Index into auth table */
|
||||||
AuthMethod(const char *name)
|
int identidx; /* Index into the string table */
|
||||||
: name(name)
|
};
|
||||||
{
|
|
||||||
}
|
struct AdminUser
|
||||||
|
{
|
||||||
static inline bool matches(const char *name, const AuthMethod *method)
|
uint32_t magic; /* Magic flag, for memory validation */
|
||||||
{
|
FlagBits flags; /* Flags */
|
||||||
return strcmp(name, method->name.c_str()) == 0;
|
FlagBits eflags; /* Effective flags */
|
||||||
}
|
int nameidx; /* Name index */
|
||||||
};
|
int password; /* Password index */
|
||||||
|
unsigned int grp_count; /* Number of groups */
|
||||||
struct UserAuth
|
unsigned int grp_size; /* Size of groups table */
|
||||||
{
|
int grp_table; /* Group table itself */
|
||||||
unsigned int index; /* Index into auth table */
|
int next_user; /* Next user in the list */
|
||||||
int identidx; /* Index into the string table */
|
int prev_user; /* Previous user in the list */
|
||||||
};
|
UserAuth auth; /* Auth method for this user */
|
||||||
|
unsigned int immunity_level; /* Immunity level */
|
||||||
struct AdminUser
|
unsigned int serialchange; /* Serial # for changes */
|
||||||
{
|
};
|
||||||
uint32_t magic; /* Magic flag, for memory validation */
|
|
||||||
FlagBits flags; /* Flags */
|
class AdminCache :
|
||||||
FlagBits eflags; /* Effective flags */
|
public IAdminSystem,
|
||||||
int nameidx; /* Name index */
|
public SMGlobalClass
|
||||||
int password; /* Password index */
|
{
|
||||||
unsigned int grp_count; /* Number of groups */
|
public:
|
||||||
unsigned int grp_size; /* Size of groups table */
|
AdminCache();
|
||||||
int grp_table; /* Group table itself */
|
~AdminCache();
|
||||||
int next_user; /* Next user in the list */
|
public: //SMGlobalClass
|
||||||
int prev_user; /* Previous user in the list */
|
void OnSourceModStartup(bool late);
|
||||||
UserAuth auth; /* Auth method for this user */
|
void OnSourceModAllInitialized();
|
||||||
unsigned int immunity_level; /* Immunity level */
|
void OnSourceModLevelChange(const char *mapName);
|
||||||
unsigned int serialchange; /* Serial # for changes */
|
void OnSourceModShutdown();
|
||||||
};
|
void OnSourceModPluginsLoaded();
|
||||||
|
public: //IAdminSystem
|
||||||
class AdminCache :
|
/** Command cache stuff */
|
||||||
public IAdminSystem,
|
void AddCommandOverride(const char *cmd, OverrideType type, FlagBits flags);
|
||||||
public SMGlobalClass
|
bool GetCommandOverride(const char *cmd, OverrideType type, FlagBits *flags);
|
||||||
{
|
void UnsetCommandOverride(const char *cmd, OverrideType type);
|
||||||
public:
|
/** Group cache stuff */
|
||||||
AdminCache();
|
GroupId AddGroup(const char *group_name);
|
||||||
~AdminCache();
|
GroupId FindGroupByName(const char *group_name);
|
||||||
public: //SMGlobalClass
|
void SetGroupAddFlag(GroupId id, AdminFlag flag, bool enabled);
|
||||||
void OnSourceModStartup(bool late);
|
bool GetGroupAddFlag(GroupId id, AdminFlag flag);
|
||||||
void OnSourceModAllInitialized();
|
FlagBits GetGroupAddFlags(GroupId id);
|
||||||
void OnSourceModLevelChange(const char *mapName);
|
void SetGroupGenericImmunity(GroupId id, ImmunityType type, bool enabled);
|
||||||
void OnSourceModShutdown();
|
bool GetGroupGenericImmunity(GroupId id, ImmunityType type);
|
||||||
void OnSourceModPluginsLoaded();
|
void InvalidateGroup(GroupId id);
|
||||||
public: //IAdminSystem
|
void AddGroupImmunity(GroupId id, GroupId other_id);
|
||||||
/** Command cache stuff */
|
unsigned int GetGroupImmunityCount(GroupId id);
|
||||||
void AddCommandOverride(const char *cmd, OverrideType type, FlagBits flags);
|
GroupId GetGroupImmunity(GroupId id, unsigned int number);
|
||||||
bool GetCommandOverride(const char *cmd, OverrideType type, FlagBits *flags);
|
void AddGroupCommandOverride(GroupId id, const char *name, OverrideType type, OverrideRule rule);
|
||||||
void UnsetCommandOverride(const char *cmd, OverrideType type);
|
bool GetGroupCommandOverride(GroupId id, const char *name, OverrideType type, OverrideRule *pRule);
|
||||||
/** Group cache stuff */
|
void DumpAdminCache(AdminCachePart part, bool rebuild);
|
||||||
GroupId AddGroup(const char *group_name);
|
void AddAdminListener(IAdminListener *pListener);
|
||||||
GroupId FindGroupByName(const char *group_name);
|
void RemoveAdminListener(IAdminListener *pListener);
|
||||||
void SetGroupAddFlag(GroupId id, AdminFlag flag, bool enabled);
|
/** User stuff */
|
||||||
bool GetGroupAddFlag(GroupId id, AdminFlag flag);
|
void RegisterAuthIdentType(const char *name);
|
||||||
FlagBits GetGroupAddFlags(GroupId id);
|
AdminId CreateAdmin(const char *name);
|
||||||
void SetGroupGenericImmunity(GroupId id, ImmunityType type, bool enabled);
|
const char *GetAdminName(AdminId id);
|
||||||
bool GetGroupGenericImmunity(GroupId id, ImmunityType type);
|
bool BindAdminIdentity(AdminId id, const char *auth, const char *ident);
|
||||||
void InvalidateGroup(GroupId id);
|
virtual void SetAdminFlag(AdminId id, AdminFlag flag, bool enabled);
|
||||||
void AddGroupImmunity(GroupId id, GroupId other_id);
|
bool GetAdminFlag(AdminId id, AdminFlag flag, AccessMode mode);
|
||||||
unsigned int GetGroupImmunityCount(GroupId id);
|
FlagBits GetAdminFlags(AdminId id, AccessMode mode);
|
||||||
GroupId GetGroupImmunity(GroupId id, unsigned int number);
|
bool AdminInheritGroup(AdminId id, GroupId gid);
|
||||||
void AddGroupCommandOverride(GroupId id, const char *name, OverrideType type, OverrideRule rule);
|
unsigned int GetAdminGroupCount(AdminId id);
|
||||||
bool GetGroupCommandOverride(GroupId id, const char *name, OverrideType type, OverrideRule *pRule);
|
GroupId GetAdminGroup(AdminId id, unsigned int index, const char **name);
|
||||||
void DumpAdminCache(AdminCachePart part, bool rebuild);
|
void SetAdminPassword(AdminId id, const char *password);
|
||||||
void AddAdminListener(IAdminListener *pListener);
|
const char *GetAdminPassword(AdminId id);
|
||||||
void RemoveAdminListener(IAdminListener *pListener);
|
AdminId FindAdminByIdentity(const char *auth, const char *identity);
|
||||||
/** User stuff */
|
bool InvalidateAdmin(AdminId id);
|
||||||
void RegisterAuthIdentType(const char *name);
|
unsigned int FlagBitsToBitArray(FlagBits bits, bool array[], unsigned int maxSize);
|
||||||
AdminId CreateAdmin(const char *name);
|
FlagBits FlagBitArrayToBits(const bool array[], unsigned int maxSize);
|
||||||
const char *GetAdminName(AdminId id);
|
FlagBits FlagArrayToBits(const AdminFlag array[], unsigned int numFlags);
|
||||||
bool BindAdminIdentity(AdminId id, const char *auth, const char *ident);
|
unsigned int FlagBitsToArray(FlagBits bits, AdminFlag array[], unsigned int maxSize);
|
||||||
virtual void SetAdminFlag(AdminId id, AdminFlag flag, bool enabled);
|
bool CheckAdminFlags(AdminId id, FlagBits bits);
|
||||||
bool GetAdminFlag(AdminId id, AdminFlag flag, AccessMode mode);
|
bool CanAdminTarget(AdminId id, AdminId target);
|
||||||
FlagBits GetAdminFlags(AdminId id, AccessMode mode);
|
void SetAdminFlags(AdminId id, AccessMode mode, FlagBits bits);
|
||||||
bool AdminInheritGroup(AdminId id, GroupId gid);
|
bool FindFlag(const char *str, AdminFlag *pFlag);
|
||||||
unsigned int GetAdminGroupCount(AdminId id);
|
bool FindFlag(char c, AdminFlag *pAdmFlag);
|
||||||
GroupId GetAdminGroup(AdminId id, unsigned int index, const char **name);
|
FlagBits ReadFlagString(const char *flags, const char **end);
|
||||||
void SetAdminPassword(AdminId id, const char *password);
|
size_t FillFlagString(FlagBits bits, char *buffer, size_t maxlen);
|
||||||
const char *GetAdminPassword(AdminId id);
|
unsigned int GetAdminSerialChange(AdminId id);
|
||||||
AdminId FindAdminByIdentity(const char *auth, const char *identity);
|
bool CanAdminUseCommand(int client, const char *cmd);
|
||||||
bool InvalidateAdmin(AdminId id);
|
const char *GetGroupName(GroupId gid);
|
||||||
unsigned int FlagBitsToBitArray(FlagBits bits, bool array[], unsigned int maxSize);
|
unsigned int SetGroupImmunityLevel(GroupId gid, unsigned int level);
|
||||||
FlagBits FlagBitArrayToBits(const bool array[], unsigned int maxSize);
|
unsigned int GetGroupImmunityLevel(GroupId gid);
|
||||||
FlagBits FlagArrayToBits(const AdminFlag array[], unsigned int numFlags);
|
unsigned int SetAdminImmunityLevel(AdminId id, unsigned int level);
|
||||||
unsigned int FlagBitsToArray(FlagBits bits, AdminFlag array[], unsigned int maxSize);
|
unsigned int GetAdminImmunityLevel(AdminId id);
|
||||||
bool CheckAdminFlags(AdminId id, FlagBits bits);
|
bool CheckAccess(int client,
|
||||||
bool CanAdminTarget(AdminId id, AdminId target);
|
const char *cmd,
|
||||||
void SetAdminFlags(AdminId id, AccessMode mode, FlagBits bits);
|
FlagBits flags,
|
||||||
bool FindFlag(const char *str, AdminFlag *pFlag);
|
bool override_only);
|
||||||
bool FindFlag(char c, AdminFlag *pAdmFlag);
|
bool FindFlagChar(AdminFlag flag, char *c);
|
||||||
FlagBits ReadFlagString(const char *flags, const char **end);
|
public:
|
||||||
size_t FillFlagString(FlagBits bits, char *buffer, size_t maxlen);
|
bool IsValidAdmin(AdminId id);
|
||||||
unsigned int GetAdminSerialChange(AdminId id);
|
void DumpCache(FILE *fp);
|
||||||
bool CanAdminUseCommand(int client, const char *cmd);
|
AdminGroup *GetGroup(GroupId gid);
|
||||||
const char *GetGroupName(GroupId gid);
|
AdminUser *GetUser(AdminId id);
|
||||||
unsigned int SetGroupImmunityLevel(GroupId gid, unsigned int level);
|
const char *GetString(int idx);
|
||||||
unsigned int GetGroupImmunityLevel(GroupId gid);
|
private:
|
||||||
unsigned int SetAdminImmunityLevel(AdminId id, unsigned int level);
|
void _UnsetCommandOverride(const char *cmd);
|
||||||
unsigned int GetAdminImmunityLevel(AdminId id);
|
void _UnsetCommandGroupOverride(const char *group);
|
||||||
bool CheckAccess(int client,
|
void InvalidateGroupCache();
|
||||||
const char *cmd,
|
void InvalidateAdminCache(bool unlink_admins);
|
||||||
FlagBits flags,
|
void DumpCommandOverrideCache(OverrideType type);
|
||||||
bool override_only);
|
Trie *GetMethodByIndex(unsigned int index);
|
||||||
bool FindFlagChar(AdminFlag flag, char *c);
|
bool GetMethodIndex(const char *name, unsigned int *_index);
|
||||||
bool IsValidAdmin(AdminId id);
|
const char *GetMethodName(unsigned int index);
|
||||||
bool CheckClientCommandAccess(int client, const char *cmd, FlagBits cmdflags);
|
void NameFlag(const char *str, AdminFlag flag);
|
||||||
public:
|
public:
|
||||||
void DumpCache(FILE *fp);
|
BaseStringTable *m_pStrings;
|
||||||
AdminGroup *GetGroup(GroupId gid);
|
BaseMemTable *m_pMemory;
|
||||||
AdminUser *GetUser(AdminId id);
|
Trie *m_pCmdOverrides;
|
||||||
const char *GetString(int idx);
|
Trie *m_pCmdGrpOverrides;
|
||||||
bool CheckAdminCommandAccess(AdminId adm, const char *cmd, FlagBits flags);
|
int m_FirstGroup;
|
||||||
private:
|
int m_LastGroup;
|
||||||
void _UnsetCommandOverride(const char *cmd);
|
int m_FreeGroupList;
|
||||||
void _UnsetCommandGroupOverride(const char *group);
|
Trie *m_pGroups;
|
||||||
void InvalidateGroupCache();
|
List<IAdminListener *> m_hooks;
|
||||||
void InvalidateAdminCache(bool unlink_admins);
|
List<AuthMethod> m_AuthMethods;
|
||||||
void DumpCommandOverrideCache(OverrideType type);
|
Trie *m_pAuthTables;
|
||||||
AuthMethod *GetMethodByIndex(unsigned int index);
|
IForward *m_pCacheFwd;
|
||||||
bool GetMethodIndex(const char *name, unsigned int *_index);
|
int m_FirstUser;
|
||||||
const char *GetMethodName(unsigned int index);
|
int m_LastUser;
|
||||||
void NameFlag(const char *str, AdminFlag flag);
|
int m_FreeUserList;
|
||||||
public:
|
bool m_InvalidatingAdmins;
|
||||||
typedef StringHashMap<FlagBits> FlagMap;
|
bool m_destroying;
|
||||||
|
Trie *m_pLevelNames;
|
||||||
BaseStringTable *m_pStrings;
|
};
|
||||||
BaseMemTable *m_pMemory;
|
|
||||||
FlagMap m_CmdOverrides;
|
extern AdminCache g_Admins;
|
||||||
FlagMap m_CmdGrpOverrides;
|
|
||||||
int m_FirstGroup;
|
#endif //_INCLUDE_SOURCEMOD_ADMINCACHE_H_
|
||||||
int m_LastGroup;
|
|
||||||
int m_FreeGroupList;
|
|
||||||
StringHashMap<GroupId> m_Groups;
|
|
||||||
List<IAdminListener *> m_hooks;
|
|
||||||
List<AuthMethod *> m_AuthMethods;
|
|
||||||
NameHashSet<AuthMethod *> m_AuthTables;
|
|
||||||
IForward *m_pCacheFwd;
|
|
||||||
int m_FirstUser;
|
|
||||||
int m_LastUser;
|
|
||||||
int m_FreeUserList;
|
|
||||||
bool m_InvalidatingAdmins;
|
|
||||||
bool m_destroying;
|
|
||||||
StringHashMap<AdminFlag> m_LevelNames;
|
|
||||||
};
|
|
||||||
|
|
||||||
extern AdminCache g_Admins;
|
|
||||||
|
|
||||||
#endif //_INCLUDE_SOURCEMOD_ADMINCACHE_H_
|
|
||||||
@@ -44,11 +44,7 @@ public: //IRecipientFilter
|
|||||||
bool IsReliable() const;
|
bool IsReliable() const;
|
||||||
bool IsInitMessage() const;
|
bool IsInitMessage() const;
|
||||||
int GetRecipientCount() const;
|
int GetRecipientCount() const;
|
||||||
#if SOURCE_ENGINE == SE_DOTA
|
|
||||||
CEntityIndex GetRecipientIndex(int slot) const;
|
|
||||||
#else
|
|
||||||
int GetRecipientIndex(int slot) const;
|
int GetRecipientIndex(int slot) const;
|
||||||
#endif
|
|
||||||
public:
|
public:
|
||||||
void Initialize(const cell_t *ptr, size_t count);
|
void Initialize(const cell_t *ptr, size_t count);
|
||||||
void SetToReliable(bool isreliable);
|
void SetToReliable(bool isreliable);
|
||||||
@@ -83,27 +79,13 @@ inline int CellRecipientFilter::GetRecipientCount() const
|
|||||||
return m_Size;
|
return m_Size;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if SOURCE_ENGINE == SE_DOTA
|
|
||||||
inline CEntityIndex CellRecipientFilter::GetRecipientIndex(int slot) const
|
|
||||||
#else
|
|
||||||
inline int CellRecipientFilter::GetRecipientIndex(int slot) const
|
inline int CellRecipientFilter::GetRecipientIndex(int slot) const
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
int ret;
|
|
||||||
if ((slot < 0) || (slot >= GetRecipientCount()))
|
if ((slot < 0) || (slot >= GetRecipientCount()))
|
||||||
{
|
{
|
||||||
ret = -1;
|
return -1;
|
||||||
}
|
}
|
||||||
else
|
return static_cast<int>(m_Players[slot]);
|
||||||
{
|
|
||||||
ret = static_cast<int>(m_Players[slot]);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if SOURCE_ENGINE == SE_DOTA
|
|
||||||
return CEntityIndex(ret);
|
|
||||||
#else
|
|
||||||
return ret;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void CellRecipientFilter::SetToInit(bool isinitmsg)
|
inline void CellRecipientFilter::SetToInit(bool isinitmsg)
|
||||||
|
|||||||
+84
-121
@@ -36,35 +36,37 @@
|
|||||||
#include "PlayerManager.h"
|
#include "PlayerManager.h"
|
||||||
#include "HalfLife2.h"
|
#include "HalfLife2.h"
|
||||||
#include "logic_bridge.h"
|
#include "logic_bridge.h"
|
||||||
#include "sourcemod.h"
|
|
||||||
|
|
||||||
#if SOURCE_ENGINE == SE_DOTA
|
/* :HACKHACK: We can't SH_DECL here because ConCmdManager.cpp does.
|
||||||
SH_DECL_EXTERN2_void(ConCommand, Dispatch, SH_NOATTRIB, false, const CCommandContext &, const CCommand &);
|
* While the OB build only runs on MM:S 1.6.0+ (SH 5+), the older one
|
||||||
#elif SOURCE_ENGINE >= SE_ORANGEBOX
|
* can technically be compiled against any MM:S version after 1.4.2.
|
||||||
SH_DECL_EXTERN1_void(ConCommand, Dispatch, SH_NOATTRIB, false, const CCommand &);
|
*/
|
||||||
#elif SOURCE_ENGINE == SE_DARKMESSIAH
|
#if SOURCE_ENGINE >= SE_ORANGEBOX
|
||||||
SH_DECL_EXTERN0_void(ConCommand, Dispatch, SH_NOATTRIB, false);
|
extern bool __SourceHook_FHRemoveConCommandDispatch(void *, bool, class fastdelegate::FastDelegate1<const CCommand &, void>);
|
||||||
|
extern int __SourceHook_FHAddConCommandDispatch(void *, ISourceHook::AddHookMode, bool, class fastdelegate::FastDelegate1<const CCommand &, void>);
|
||||||
#else
|
#else
|
||||||
# if SH_IMPL_VERSION >= 4
|
extern bool __SourceHook_FHRemoveConCommandDispatch(void *, bool, class fastdelegate::FastDelegate0<void>);
|
||||||
extern int __SourceHook_FHAddConCommandDispatch(void *,bool,class fastdelegate::FastDelegate0<void>);
|
#if SH_IMPL_VERSION >= 5
|
||||||
# else
|
extern int __SourceHook_FHAddConCommandDispatch(void *, ISourceHook::AddHookMode, bool, class fastdelegate::FastDelegate0<void>);
|
||||||
extern bool __SourceHook_FHAddConCommandDispatch(void *,bool,class fastdelegate::FastDelegate0<void>);
|
#elif SH_IMPL_VERSION == 4
|
||||||
# endif
|
extern int __SourceHook_FHAddConCommandDispatch(void *, bool, class fastdelegate::FastDelegate0<void>);
|
||||||
extern bool __SourceHook_FHRemoveConCommandDispatch(void *,bool,class fastdelegate::FastDelegate0<void>);
|
#elif SH_IMPL_VERSION == 3
|
||||||
#endif
|
extern bool __SourceHook_FHAddConCommandDispatch(void *, bool, class fastdelegate::FastDelegate0<void>);
|
||||||
|
#endif //SH_IMPL_VERSION
|
||||||
|
#endif //SE_ORANGEBOX
|
||||||
|
|
||||||
ChatTriggers g_ChatTriggers;
|
ChatTriggers g_ChatTriggers;
|
||||||
bool g_bSupressSilentFails = false;
|
bool g_bSupressSilentFails = false;
|
||||||
|
|
||||||
ChatTriggers::ChatTriggers() : m_pSayCmd(NULL), m_bWillProcessInPost(false),
|
ChatTriggers::ChatTriggers() : m_pSayCmd(NULL), m_bWillProcessInPost(false),
|
||||||
m_ReplyTo(SM_REPLY_CONSOLE), m_ArgSBackup(NULL)
|
m_ReplyTo(SM_REPLY_CONSOLE)
|
||||||
{
|
{
|
||||||
m_PubTrigger = sm_strdup("!");
|
m_PubTrigger = sm_strdup("!");
|
||||||
m_PrivTrigger = sm_strdup("/");
|
m_PrivTrigger = sm_strdup("/");
|
||||||
m_PubTriggerSize = 1;
|
m_PubTriggerSize = 1;
|
||||||
m_PrivTriggerSize = 1;
|
m_PrivTriggerSize = 1;
|
||||||
m_bIsChatTrigger = false;
|
m_bIsChatTrigger = false;
|
||||||
m_bPluginIgnored = true;
|
m_bPluginIgnored = false;
|
||||||
#if SOURCE_ENGINE == SE_EPISODEONE
|
#if SOURCE_ENGINE == SE_EPISODEONE
|
||||||
m_bIsINS = false;
|
m_bIsINS = false;
|
||||||
#endif
|
#endif
|
||||||
@@ -76,8 +78,6 @@ ChatTriggers::~ChatTriggers()
|
|||||||
m_PubTrigger = NULL;
|
m_PubTrigger = NULL;
|
||||||
delete [] m_PrivTrigger;
|
delete [] m_PrivTrigger;
|
||||||
m_PrivTrigger = NULL;
|
m_PrivTrigger = NULL;
|
||||||
delete [] m_ArgSBackup;
|
|
||||||
m_ArgSBackup = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfigResult ChatTriggers::OnSourceModConfigChanged(const char *key,
|
ConfigResult ChatTriggers::OnSourceModConfigChanged(const char *key,
|
||||||
@@ -111,10 +111,10 @@ ConfigResult ChatTriggers::OnSourceModConfigChanged(const char *key,
|
|||||||
|
|
||||||
void ChatTriggers::OnSourceModAllInitialized()
|
void ChatTriggers::OnSourceModAllInitialized()
|
||||||
{
|
{
|
||||||
m_pShouldFloodBlock = forwardsys->CreateForward("OnClientFloodCheck", ET_Event, 1, NULL, Param_Cell);
|
m_pShouldFloodBlock = g_Forwards.CreateForward("OnClientFloodCheck", ET_Event, 1, NULL, Param_Cell);
|
||||||
m_pDidFloodBlock = forwardsys->CreateForward("OnClientFloodResult", ET_Event, 2, NULL, Param_Cell, Param_Cell);
|
m_pDidFloodBlock = g_Forwards.CreateForward("OnClientFloodResult", ET_Event, 2, NULL, Param_Cell, Param_Cell);
|
||||||
m_pOnClientSayCmd = forwardsys->CreateForward("OnClientSayCommand", ET_Event, 3, NULL, Param_Cell, Param_String, Param_String);
|
m_pOnClientSayCmd = g_Forwards.CreateForward("OnClientSayCommand", ET_Event, 3, NULL, Param_Cell, Param_String, Param_String);
|
||||||
m_pOnClientSayCmd_Post = forwardsys->CreateForward("OnClientSayCommand_Post", ET_Ignore, 3, NULL, Param_Cell, Param_String, Param_String);
|
m_pOnClientSayCmd_Post = g_Forwards.CreateForward("OnClientSayCommand_Post", ET_Ignore, 3, NULL, Param_Cell, Param_String, Param_String);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatTriggers::OnSourceModAllInitialized_Post()
|
void ChatTriggers::OnSourceModAllInitialized_Post()
|
||||||
@@ -129,13 +129,13 @@ void ChatTriggers::OnSourceModGameInitialized()
|
|||||||
|
|
||||||
if (m_pSayCmd)
|
if (m_pSayCmd)
|
||||||
{
|
{
|
||||||
SH_ADD_HOOK(ConCommand, Dispatch, m_pSayCmd, SH_MEMBER(this, &ChatTriggers::OnSayCommand_Pre), false);
|
SH_ADD_HOOK_MEMFUNC(ConCommand, Dispatch, m_pSayCmd, this, &ChatTriggers::OnSayCommand_Pre, false);
|
||||||
SH_ADD_HOOK(ConCommand, Dispatch, m_pSayCmd, SH_MEMBER(this, &ChatTriggers::OnSayCommand_Post), true);
|
SH_ADD_HOOK_MEMFUNC(ConCommand, Dispatch, m_pSayCmd, this, &ChatTriggers::OnSayCommand_Post, true);
|
||||||
}
|
}
|
||||||
if (m_pSayTeamCmd)
|
if (m_pSayTeamCmd)
|
||||||
{
|
{
|
||||||
SH_ADD_HOOK(ConCommand, Dispatch, m_pSayTeamCmd, SH_MEMBER(this, &ChatTriggers::OnSayCommand_Pre), false);
|
SH_ADD_HOOK_MEMFUNC(ConCommand, Dispatch, m_pSayTeamCmd, this, &ChatTriggers::OnSayCommand_Pre, false);
|
||||||
SH_ADD_HOOK(ConCommand, Dispatch, m_pSayTeamCmd, SH_MEMBER(this, &ChatTriggers::OnSayCommand_Post), true);
|
SH_ADD_HOOK_MEMFUNC(ConCommand, Dispatch, m_pSayTeamCmd, this, &ChatTriggers::OnSayCommand_Post, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if SOURCE_ENGINE == SE_EPISODEONE
|
#if SOURCE_ENGINE == SE_EPISODEONE
|
||||||
@@ -165,8 +165,8 @@ void ChatTriggers::OnSourceModShutdown()
|
|||||||
{
|
{
|
||||||
if (m_pSayCmd)
|
if (m_pSayCmd)
|
||||||
{
|
{
|
||||||
SH_REMOVE_HOOK(ConCommand, Dispatch, m_pSayCmd, SH_MEMBER(this, &ChatTriggers::OnSayCommand_Post), true);
|
SH_REMOVE_HOOK_MEMFUNC(ConCommand, Dispatch, m_pSayCmd, this, &ChatTriggers::OnSayCommand_Post, true);
|
||||||
SH_REMOVE_HOOK(ConCommand, Dispatch, m_pSayCmd, SH_MEMBER(this, &ChatTriggers::OnSayCommand_Pre), false);
|
SH_REMOVE_HOOK_MEMFUNC(ConCommand, Dispatch, m_pSayCmd, this, &ChatTriggers::OnSayCommand_Pre, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_pSayTeamCmd)
|
if (m_pSayTeamCmd)
|
||||||
@@ -189,16 +189,13 @@ void ChatTriggers::OnSourceModShutdown()
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
forwardsys->ReleaseForward(m_pShouldFloodBlock);
|
g_Forwards.ReleaseForward(m_pShouldFloodBlock);
|
||||||
forwardsys->ReleaseForward(m_pDidFloodBlock);
|
g_Forwards.ReleaseForward(m_pDidFloodBlock);
|
||||||
forwardsys->ReleaseForward(m_pOnClientSayCmd);
|
g_Forwards.ReleaseForward(m_pOnClientSayCmd);
|
||||||
forwardsys->ReleaseForward(m_pOnClientSayCmd_Post);
|
g_Forwards.ReleaseForward(m_pOnClientSayCmd_Post);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if SOURCE_ENGINE == SE_DOTA
|
#if SOURCE_ENGINE >= SE_ORANGEBOX
|
||||||
void ChatTriggers::OnSayCommand_Pre(const CCommandContext &context, const CCommand &command)
|
|
||||||
{
|
|
||||||
#elif SOURCE_ENGINE >= SE_ORANGEBOX
|
|
||||||
void ChatTriggers::OnSayCommand_Pre(const CCommand &command)
|
void ChatTriggers::OnSayCommand_Pre(const CCommand &command)
|
||||||
{
|
{
|
||||||
#else
|
#else
|
||||||
@@ -209,10 +206,10 @@ void ChatTriggers::OnSayCommand_Pre()
|
|||||||
int client = g_ConCmds.GetCommandClient();
|
int client = g_ConCmds.GetCommandClient();
|
||||||
m_bIsChatTrigger = false;
|
m_bIsChatTrigger = false;
|
||||||
m_bWasFloodedMessage = false;
|
m_bWasFloodedMessage = false;
|
||||||
m_bPluginIgnored = true;
|
m_bPluginIgnored = false;
|
||||||
|
|
||||||
const char *args = command.ArgS();
|
const char *args = command.ArgS();
|
||||||
|
|
||||||
if (!args)
|
if (!args)
|
||||||
{
|
{
|
||||||
RETURN_META(MRES_IGNORED);
|
RETURN_META(MRES_IGNORED);
|
||||||
@@ -221,73 +218,17 @@ void ChatTriggers::OnSayCommand_Pre()
|
|||||||
/* Save these off for post hook as the command data returned from the engine in older engine versions
|
/* Save these off for post hook as the command data returned from the engine in older engine versions
|
||||||
* can be NULL, despite the data still being there and valid. */
|
* can be NULL, despite the data still being there and valid. */
|
||||||
m_Arg0Backup = command.Arg(0);
|
m_Arg0Backup = command.Arg(0);
|
||||||
size_t len = strlen(args);
|
m_ArgSBackup = command.ArgS();
|
||||||
|
|
||||||
#if SOURCE_ENGINE == SE_EPISODEONE
|
|
||||||
if (m_bIsINS)
|
|
||||||
{
|
|
||||||
if (strcmp(m_Arg0Backup, "say2") == 0 && len >= 4)
|
|
||||||
{
|
|
||||||
args += 4;
|
|
||||||
len -= 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (len == 0)
|
|
||||||
{
|
|
||||||
RETURN_META(MRES_SUPERCEDE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* The first pair of quotes are stripped from client say commands, but not console ones.
|
|
||||||
* We do not want the forwards to differ from what is displayed.
|
|
||||||
* So only strip the first pair of quotes from client say commands. */
|
|
||||||
bool is_quoted = false;
|
|
||||||
|
|
||||||
if (
|
|
||||||
#if SOURCE_ENGINE == SE_EPISODEONE
|
|
||||||
!m_bIsINS &&
|
|
||||||
#endif
|
|
||||||
client != 0 && args[0] == '"' && args[len-1] == '"')
|
|
||||||
{
|
|
||||||
/* The server normally won't display empty say commands, but in this case it does.
|
|
||||||
* I don't think it's desired so let's block it. */
|
|
||||||
if (len <= 2)
|
|
||||||
{
|
|
||||||
RETURN_META(MRES_SUPERCEDE);
|
|
||||||
}
|
|
||||||
|
|
||||||
args++;
|
|
||||||
len--;
|
|
||||||
is_quoted = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Some? engines strip the last quote when printing the string to chat.
|
|
||||||
* This results in having a double-quoted message passed to the OnClientSayCommand ("message") forward,
|
|
||||||
* but losing the last quote in the OnClientSayCommand_Post ("message) forward.
|
|
||||||
* To compensate this, we copy the args into our own buffer where the engine won't mess with
|
|
||||||
* and strip the quotes. */
|
|
||||||
delete [] m_ArgSBackup;
|
|
||||||
m_ArgSBackup = new char[CCommand::MaxCommandLength()+1];
|
|
||||||
memcpy(m_ArgSBackup, args, len+1);
|
|
||||||
|
|
||||||
/* Strip the quotes from the argument */
|
|
||||||
if (is_quoted)
|
|
||||||
{
|
|
||||||
if (m_ArgSBackup[len-1] == '"')
|
|
||||||
{
|
|
||||||
m_ArgSBackup[--len] = '\0';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The server console cannot do this */
|
/* The server console cannot do this */
|
||||||
if (client == 0)
|
if (client == 0)
|
||||||
{
|
{
|
||||||
if (CallOnClientSayCommand(client) >= Pl_Handled)
|
cell_t res = CallOnClientSayCommand(client);
|
||||||
|
if (res >= Pl_Handled)
|
||||||
{
|
{
|
||||||
|
m_bPluginIgnored = (res >= Pl_Stop);
|
||||||
RETURN_META(MRES_SUPERCEDE);
|
RETURN_META(MRES_SUPERCEDE);
|
||||||
}
|
}
|
||||||
|
|
||||||
RETURN_META(MRES_IGNORED);
|
RETURN_META(MRES_IGNORED);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -318,26 +259,41 @@ void ChatTriggers::OnSayCommand_Pre()
|
|||||||
RETURN_META(MRES_SUPERCEDE);
|
RETURN_META(MRES_SUPERCEDE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Handle quoted string sets */
|
||||||
|
bool is_quoted = false;
|
||||||
|
if (args[0] == '"')
|
||||||
|
{
|
||||||
|
args++;
|
||||||
|
is_quoted = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if SOURCE_ENGINE == SE_EPISODEONE
|
||||||
|
if (m_bIsINS && strcmp(m_Arg0Backup, "say2") == 0 && strlen(args) >= 4)
|
||||||
|
{
|
||||||
|
args += 4;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
bool is_trigger = false;
|
bool is_trigger = false;
|
||||||
bool is_silent = false;
|
bool is_silent = false;
|
||||||
|
|
||||||
/* Check for either trigger */
|
/* Check for either trigger */
|
||||||
if (m_PubTriggerSize && strncmp(m_ArgSBackup, m_PubTrigger, m_PubTriggerSize) == 0)
|
if (m_PubTriggerSize && strncmp(args, m_PubTrigger, m_PubTriggerSize) == 0)
|
||||||
{
|
{
|
||||||
is_trigger = true;
|
is_trigger = true;
|
||||||
args = &m_ArgSBackup[m_PubTriggerSize];
|
args = &args[m_PubTriggerSize];
|
||||||
}
|
}
|
||||||
else if (m_PrivTriggerSize && strncmp(m_ArgSBackup, m_PrivTrigger, m_PrivTriggerSize) == 0)
|
else if (m_PrivTriggerSize && strncmp(args, m_PrivTrigger, m_PrivTriggerSize) == 0)
|
||||||
{
|
{
|
||||||
is_trigger = true;
|
is_trigger = true;
|
||||||
is_silent = true;
|
is_silent = true;
|
||||||
args = &m_ArgSBackup[m_PrivTriggerSize];
|
args = &args[m_PrivTriggerSize];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test if this is actually a command!
|
* Test if this is actually a command!
|
||||||
*/
|
*/
|
||||||
if (is_trigger && PreProcessTrigger(PEntityOfEntIndex(client), args))
|
if (is_trigger && PreProcessTrigger(PEntityOfEntIndex(client), args, is_quoted))
|
||||||
{
|
{
|
||||||
m_bIsChatTrigger = true;
|
m_bIsChatTrigger = true;
|
||||||
|
|
||||||
@@ -347,12 +303,15 @@ void ChatTriggers::OnSayCommand_Pre()
|
|||||||
m_bWillProcessInPost = true;
|
m_bWillProcessInPost = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_silent && (m_bIsChatTrigger || (g_bSupressSilentFails && pPlayer->GetAdminId() != INVALID_ADMIN_ID)))
|
cell_t res = CallOnClientSayCommand(client);
|
||||||
|
|
||||||
|
if (res >= Pl_Handled)
|
||||||
{
|
{
|
||||||
|
m_bPluginIgnored = (res >= Pl_Stop);
|
||||||
RETURN_META(MRES_SUPERCEDE);
|
RETURN_META(MRES_SUPERCEDE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CallOnClientSayCommand(client) >= Pl_Handled)
|
if (is_silent && (m_bIsChatTrigger || (g_bSupressSilentFails && pPlayer->GetAdminId() != INVALID_ADMIN_ID)))
|
||||||
{
|
{
|
||||||
RETURN_META(MRES_SUPERCEDE);
|
RETURN_META(MRES_SUPERCEDE);
|
||||||
}
|
}
|
||||||
@@ -361,9 +320,7 @@ void ChatTriggers::OnSayCommand_Pre()
|
|||||||
RETURN_META(MRES_IGNORED);
|
RETURN_META(MRES_IGNORED);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if SOURCE_ENGINE == SE_DOTA
|
#if SOURCE_ENGINE >= SE_ORANGEBOX
|
||||||
void ChatTriggers::OnSayCommand_Post(const CCommandContext &context, const CCommand &command)
|
|
||||||
#elif SOURCE_ENGINE >= SE_ORANGEBOX
|
|
||||||
void ChatTriggers::OnSayCommand_Post(const CCommand &command)
|
void ChatTriggers::OnSayCommand_Post(const CCommand &command)
|
||||||
#else
|
#else
|
||||||
void ChatTriggers::OnSayCommand_Post()
|
void ChatTriggers::OnSayCommand_Post()
|
||||||
@@ -375,19 +332,19 @@ void ChatTriggers::OnSayCommand_Post()
|
|||||||
{
|
{
|
||||||
/* Reset this for re-entrancy */
|
/* Reset this for re-entrancy */
|
||||||
m_bWillProcessInPost = false;
|
m_bWillProcessInPost = false;
|
||||||
|
|
||||||
/* Execute the cached command */
|
/* Execute the cached command */
|
||||||
unsigned int old = SetReplyTo(SM_REPLY_CHAT);
|
unsigned int old = SetReplyTo(SM_REPLY_CHAT);
|
||||||
#if SOURCE_ENGINE == SE_DOTA
|
|
||||||
engine->ClientCommand(client, "%s", m_ToExecute);
|
|
||||||
#else
|
|
||||||
serverpluginhelpers->ClientCommand(PEntityOfEntIndex(client), m_ToExecute);
|
serverpluginhelpers->ClientCommand(PEntityOfEntIndex(client), m_ToExecute);
|
||||||
#endif
|
|
||||||
SetReplyTo(old);
|
SetReplyTo(old);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_bPluginIgnored && m_pOnClientSayCmd_Post->GetFunctionCount() != 0)
|
if (m_bPluginIgnored)
|
||||||
{
|
{
|
||||||
|
m_bPluginIgnored = false;
|
||||||
|
}
|
||||||
|
else if (!m_bWasFloodedMessage && !m_bIsChatTrigger && m_pOnClientSayCmd_Post->GetFunctionCount() != 0)
|
||||||
|
{
|
||||||
m_pOnClientSayCmd_Post->PushCell(client);
|
m_pOnClientSayCmd_Post->PushCell(client);
|
||||||
m_pOnClientSayCmd_Post->PushString(m_Arg0Backup);
|
m_pOnClientSayCmd_Post->PushString(m_Arg0Backup);
|
||||||
m_pOnClientSayCmd_Post->PushString(m_ArgSBackup);
|
m_pOnClientSayCmd_Post->PushString(m_ArgSBackup);
|
||||||
@@ -398,7 +355,7 @@ void ChatTriggers::OnSayCommand_Post()
|
|||||||
m_bWasFloodedMessage = false;
|
m_bWasFloodedMessage = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ChatTriggers::PreProcessTrigger(edict_t *pEdict, const char *args)
|
bool ChatTriggers::PreProcessTrigger(edict_t *pEdict, const char *args, bool is_quoted)
|
||||||
{
|
{
|
||||||
/* Extract a command. This is kind of sloppy. */
|
/* Extract a command. This is kind of sloppy. */
|
||||||
char cmd_buf[64];
|
char cmd_buf[64];
|
||||||
@@ -440,12 +397,12 @@ bool ChatTriggers::PreProcessTrigger(edict_t *pEdict, const char *args)
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
prepended = true;
|
prepended = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* See if we need to do extra string manipulation */
|
/* See if we need to do extra string manipulation */
|
||||||
if (prepended)
|
if (is_quoted || prepended)
|
||||||
{
|
{
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
@@ -456,6 +413,15 @@ bool ChatTriggers::PreProcessTrigger(edict_t *pEdict, const char *args)
|
|||||||
} else {
|
} else {
|
||||||
len = strncopy(m_ToExecute, args, sizeof(m_ToExecute));
|
len = strncopy(m_ToExecute, args, sizeof(m_ToExecute));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check if we need to strip a quote */
|
||||||
|
if (is_quoted)
|
||||||
|
{
|
||||||
|
if (m_ToExecute[len-1] == '"')
|
||||||
|
{
|
||||||
|
m_ToExecute[--len] = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
strncopy(m_ToExecute, args, sizeof(m_ToExecute));
|
strncopy(m_ToExecute, args, sizeof(m_ToExecute));
|
||||||
}
|
}
|
||||||
@@ -466,16 +432,13 @@ bool ChatTriggers::PreProcessTrigger(edict_t *pEdict, const char *args)
|
|||||||
cell_t ChatTriggers::CallOnClientSayCommand(int client)
|
cell_t ChatTriggers::CallOnClientSayCommand(int client)
|
||||||
{
|
{
|
||||||
cell_t res = Pl_Continue;
|
cell_t res = Pl_Continue;
|
||||||
if (m_pOnClientSayCmd->GetFunctionCount() != 0)
|
if (!m_bIsChatTrigger && m_pOnClientSayCmd->GetFunctionCount() != 0)
|
||||||
{
|
{
|
||||||
m_pOnClientSayCmd->PushCell(client);
|
m_pOnClientSayCmd->PushCell(client);
|
||||||
m_pOnClientSayCmd->PushString(m_Arg0Backup);
|
m_pOnClientSayCmd->PushString(m_Arg0Backup);
|
||||||
m_pOnClientSayCmd->PushString(m_ArgSBackup);
|
m_pOnClientSayCmd->PushString(m_ArgSBackup);
|
||||||
m_pOnClientSayCmd->Execute(&res);
|
m_pOnClientSayCmd->Execute(&res);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_bPluginIgnored = (res >= Pl_Stop);
|
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-6
@@ -54,10 +54,7 @@ public: //SMGlobalClass
|
|||||||
char *error,
|
char *error,
|
||||||
size_t maxlength);
|
size_t maxlength);
|
||||||
private: //ConCommand
|
private: //ConCommand
|
||||||
#if SOURCE_ENGINE == SE_DOTA
|
#if SOURCE_ENGINE >= SE_ORANGEBOX
|
||||||
void OnSayCommand_Pre(const CCommandContext &, const CCommand &command);
|
|
||||||
void OnSayCommand_Post(const CCommandContext &, const CCommand &command);
|
|
||||||
#elif SOURCE_ENGINE >= SE_ORANGEBOX
|
|
||||||
void OnSayCommand_Pre(const CCommand &command);
|
void OnSayCommand_Pre(const CCommand &command);
|
||||||
void OnSayCommand_Post(const CCommand &command);
|
void OnSayCommand_Post(const CCommand &command);
|
||||||
#else
|
#else
|
||||||
@@ -70,7 +67,7 @@ public:
|
|||||||
bool IsChatTrigger();
|
bool IsChatTrigger();
|
||||||
bool WasFloodedMessage();
|
bool WasFloodedMessage();
|
||||||
private:
|
private:
|
||||||
bool PreProcessTrigger(edict_t *pEdict, const char *args);
|
bool PreProcessTrigger(edict_t *pEdict, const char *args, bool is_quoted);
|
||||||
bool ClientIsFlooding(int client);
|
bool ClientIsFlooding(int client);
|
||||||
cell_t CallOnClientSayCommand(int client);
|
cell_t CallOnClientSayCommand(int client);
|
||||||
private:
|
private:
|
||||||
@@ -92,7 +89,7 @@ private:
|
|||||||
unsigned int m_ReplyTo;
|
unsigned int m_ReplyTo;
|
||||||
char m_ToExecute[300];
|
char m_ToExecute[300];
|
||||||
const char *m_Arg0Backup;
|
const char *m_Arg0Backup;
|
||||||
char *m_ArgSBackup;
|
const char *m_ArgSBackup;
|
||||||
IForward *m_pShouldFloodBlock;
|
IForward *m_pShouldFloodBlock;
|
||||||
IForward *m_pDidFloodBlock;
|
IForward *m_pDidFloodBlock;
|
||||||
IForward *m_pOnClientSayCmd;
|
IForward *m_pOnClientSayCmd;
|
||||||
|
|||||||
+487
-201
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* vim: set ts=4 sw=4 tw=99 noet :
|
* vim: set ts=4 :
|
||||||
* =============================================================================
|
* =============================================================================
|
||||||
* SourceMod
|
* SourceMod
|
||||||
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
||||||
@@ -31,19 +31,16 @@
|
|||||||
|
|
||||||
#include "ConCmdManager.h"
|
#include "ConCmdManager.h"
|
||||||
#include "sm_srvcmds.h"
|
#include "sm_srvcmds.h"
|
||||||
|
#include "AdminCache.h"
|
||||||
#include "sm_stringutil.h"
|
#include "sm_stringutil.h"
|
||||||
#include "PlayerManager.h"
|
#include "PlayerManager.h"
|
||||||
#include "HalfLife2.h"
|
#include "HalfLife2.h"
|
||||||
#include "ChatTriggers.h"
|
#include "ChatTriggers.h"
|
||||||
#include "logic_bridge.h"
|
#include "logic_bridge.h"
|
||||||
|
|
||||||
using namespace ke;
|
|
||||||
|
|
||||||
ConCmdManager g_ConCmds;
|
ConCmdManager g_ConCmds;
|
||||||
|
|
||||||
#if SOURCE_ENGINE == SE_DOTA
|
#if SOURCE_ENGINE >= SE_ORANGEBOX
|
||||||
SH_DECL_HOOK2_void(ConCommand, Dispatch, SH_NOATTRIB, false, const CCommandContext &, const CCommand &);
|
|
||||||
#elif SOURCE_ENGINE >= SE_ORANGEBOX
|
|
||||||
SH_DECL_HOOK1_void(ConCommand, Dispatch, SH_NOATTRIB, false, const CCommand &);
|
SH_DECL_HOOK1_void(ConCommand, Dispatch, SH_NOATTRIB, false, const CCommand &);
|
||||||
#else
|
#else
|
||||||
SH_DECL_HOOK0_void(ConCommand, Dispatch, SH_NOATTRIB, false);
|
SH_DECL_HOOK0_void(ConCommand, Dispatch, SH_NOATTRIB, false);
|
||||||
@@ -51,30 +48,40 @@ ConCmdManager g_ConCmds;
|
|||||||
|
|
||||||
SH_DECL_HOOK1_void(IServerGameClients, SetCommandClient, SH_NOATTRIB, false, int);
|
SH_DECL_HOOK1_void(IServerGameClients, SetCommandClient, SH_NOATTRIB, false, int);
|
||||||
|
|
||||||
typedef ke::LinkedList<CmdHook *> PluginHookList;
|
struct PlCmdInfo
|
||||||
void RegisterInPlugin(CmdHook *hook);
|
|
||||||
|
|
||||||
ConCmdManager::ConCmdManager()
|
|
||||||
{
|
{
|
||||||
|
ConCmdInfo *pInfo;
|
||||||
|
CmdHook *pHook;
|
||||||
|
CmdType type;
|
||||||
|
};
|
||||||
|
typedef List<PlCmdInfo> CmdList;
|
||||||
|
|
||||||
|
void AddToPlCmdList(CmdList *pList, const PlCmdInfo &info);
|
||||||
|
|
||||||
|
ConCmdManager::ConCmdManager() : m_Strings(1024)
|
||||||
|
{
|
||||||
|
m_pCmds = sm_trie_create();
|
||||||
|
m_pCmdGrps = sm_trie_create();
|
||||||
m_CmdClient = 0;
|
m_CmdClient = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ConCmdManager::~ConCmdManager()
|
ConCmdManager::~ConCmdManager()
|
||||||
{
|
{
|
||||||
|
sm_trie_destroy(m_pCmds);
|
||||||
|
sm_trie_destroy(m_pCmdGrps);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConCmdManager::OnSourceModAllInitialized()
|
void ConCmdManager::OnSourceModAllInitialized()
|
||||||
{
|
{
|
||||||
scripts->AddPluginsListener(this);
|
g_PluginSys.AddPluginsListener(this);
|
||||||
g_RootMenu.AddRootConsoleCommand("cmds", "List console commands", this);
|
g_RootMenu.AddRootConsoleCommand("cmds", "List console commands", this);
|
||||||
SH_ADD_HOOK(IServerGameClients, SetCommandClient, serverClients, SH_MEMBER(this, &ConCmdManager::SetCommandClient), false);
|
SH_ADD_HOOK_MEMFUNC(IServerGameClients, SetCommandClient, serverClients, this, &ConCmdManager::SetCommandClient, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConCmdManager::OnSourceModShutdown()
|
void ConCmdManager::OnSourceModShutdown()
|
||||||
{
|
{
|
||||||
scripts->RemovePluginsListener(this);
|
|
||||||
/* All commands should already be removed by the time we're done */
|
/* All commands should already be removed by the time we're done */
|
||||||
SH_REMOVE_HOOK(IServerGameClients, SetCommandClient, serverClients, SH_MEMBER(this, &ConCmdManager::SetCommandClient), false);
|
SH_REMOVE_HOOK_MEMFUNC(IServerGameClients, SetCommandClient, serverClients, this, &ConCmdManager::SetCommandClient, false);
|
||||||
g_RootMenu.RemoveRootConsoleCommand("cmds", this);
|
g_RootMenu.RemoveRootConsoleCommand("cmds", this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,68 +90,122 @@ void ConCmdManager::OnUnlinkConCommandBase(ConCommandBase *pBase, const char *na
|
|||||||
/* Whoa, first get its information struct */
|
/* Whoa, first get its information struct */
|
||||||
ConCmdInfo *pInfo;
|
ConCmdInfo *pInfo;
|
||||||
|
|
||||||
if (!m_Cmds.retrieve(name, &pInfo))
|
if (!sm_trie_retrieve(m_pCmds, name, (void **)&pInfo))
|
||||||
return;
|
|
||||||
|
|
||||||
CmdHookList::iterator iter = pInfo->hooks.begin();
|
|
||||||
while (iter != pInfo->hooks.end())
|
|
||||||
{
|
{
|
||||||
CmdHook *hook = *iter;
|
return;
|
||||||
|
|
||||||
IPluginContext *pContext = hook->pf->GetParentContext();
|
|
||||||
IPlugin *pPlugin = scripts->FindPluginByContext(pContext->GetContext());
|
|
||||||
|
|
||||||
// The list is guaranteed to exist.
|
|
||||||
PluginHookList *list;
|
|
||||||
pPlugin->GetProperty("CommandList", (void **)&list, false);
|
|
||||||
for (PluginHookList::iterator hiter = list->begin(); hiter != list->end(); hiter++)
|
|
||||||
{
|
|
||||||
if (*hiter == hook)
|
|
||||||
{
|
|
||||||
list->erase(hiter);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hook->admin)
|
|
||||||
hook->admin->group->hooks.remove(hook);
|
|
||||||
|
|
||||||
iter = pInfo->hooks.erase(iter);
|
|
||||||
delete hook;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RemoveConCmds(pInfo->srvhooks);
|
||||||
|
RemoveConCmds(pInfo->conhooks);
|
||||||
|
|
||||||
RemoveConCmd(pInfo, name, is_read_safe, false);
|
RemoveConCmd(pInfo, name, is_read_safe, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConCmdManager::OnPluginDestroyed(IPlugin *plugin)
|
void ConCmdManager::RemoveConCmds(List<CmdHook *> &cmdlist)
|
||||||
{
|
{
|
||||||
PluginHookList *pList;
|
List<CmdHook *>::iterator iter = cmdlist.begin();
|
||||||
if (!plugin->GetProperty("CommandList", (void **)&pList, true))
|
|
||||||
return;
|
|
||||||
|
|
||||||
PluginHookList::iterator iter = pList->begin();
|
while (iter != cmdlist.end())
|
||||||
while (iter != pList->end())
|
|
||||||
{
|
{
|
||||||
CmdHook *hook = *iter;
|
CmdHook *pHook = (*iter);
|
||||||
|
IPluginContext *pContext = pHook->pf->GetParentContext();
|
||||||
|
IPlugin *pPlugin = g_PluginSys.GetPluginByCtx(pContext->GetContext());
|
||||||
|
CmdList *pList = NULL;
|
||||||
|
|
||||||
|
//gaben
|
||||||
|
if (!pPlugin->GetProperty("CommandList", (void **)&pList, false) || !pList)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
hook->info->hooks.remove(hook);
|
CmdList::iterator p_iter = pList->begin();
|
||||||
if (hook->admin)
|
while (p_iter != pList->end())
|
||||||
hook->admin->group->hooks.remove(hook);
|
{
|
||||||
|
PlCmdInfo &cmd = (*p_iter);
|
||||||
|
if (cmd.pHook == pHook)
|
||||||
|
{
|
||||||
|
p_iter = pList->erase(p_iter);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p_iter++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (hook->info->hooks.empty())
|
delete pHook->pAdmin;
|
||||||
RemoveConCmd(hook->info, hook->info->pCmd->GetName(), true, true);
|
delete pHook;
|
||||||
|
|
||||||
iter = pList->erase(iter);
|
iter = cmdlist.erase(iter);
|
||||||
delete hook;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
delete pList;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if SOURCE_ENGINE == SE_DOTA
|
void ConCmdManager::RemoveConCmds(List<CmdHook *> &cmdlist, IPluginContext *pContext)
|
||||||
void CommandCallback(const CCommandContext &context, const CCommand &command)
|
|
||||||
{
|
{
|
||||||
#elif SOURCE_ENGINE >= SE_ORANGEBOX
|
List<CmdHook *>::iterator iter = cmdlist.begin();
|
||||||
|
CmdHook *pHook;
|
||||||
|
|
||||||
|
while (iter != cmdlist.end())
|
||||||
|
{
|
||||||
|
pHook = (*iter);
|
||||||
|
if (pHook->pf->GetParentContext() == pContext)
|
||||||
|
{
|
||||||
|
delete pHook->pAdmin;
|
||||||
|
delete pHook;
|
||||||
|
iter = cmdlist.erase(iter);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
iter++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConCmdManager::OnPluginDestroyed(IPlugin *plugin)
|
||||||
|
{
|
||||||
|
CmdList *pList;
|
||||||
|
List<ConCmdInfo *> removed;
|
||||||
|
if (plugin->GetProperty("CommandList", (void **)&pList, true))
|
||||||
|
{
|
||||||
|
IPluginContext *pContext = plugin->GetBaseContext();
|
||||||
|
CmdList::iterator iter;
|
||||||
|
/* First pass!
|
||||||
|
* Only bother if there's an actual command list on this plugin...
|
||||||
|
*/
|
||||||
|
for (iter=pList->begin();
|
||||||
|
iter!=pList->end();
|
||||||
|
iter++)
|
||||||
|
{
|
||||||
|
PlCmdInfo &cmd = (*iter);
|
||||||
|
ConCmdInfo *pInfo = cmd.pInfo;
|
||||||
|
|
||||||
|
/* Has this chain already been fully cleaned/removed? */
|
||||||
|
if (removed.find(pInfo) != removed.end())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remove any hooks from us on this command */
|
||||||
|
RemoveConCmds(pInfo->conhooks, pContext);
|
||||||
|
RemoveConCmds(pInfo->srvhooks, pContext);
|
||||||
|
|
||||||
|
/* See if there are still hooks */
|
||||||
|
if (pInfo->srvhooks.size())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (pInfo->conhooks.size())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remove the command, it should be safe now */
|
||||||
|
RemoveConCmd(pInfo, pInfo->pCmd->GetName(), true, true);
|
||||||
|
removed.push_back(pInfo);
|
||||||
|
}
|
||||||
|
delete pList;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#if SOURCE_ENGINE >= SE_ORANGEBOX
|
||||||
void CommandCallback(const CCommand &command)
|
void CommandCallback(const CCommand &command)
|
||||||
{
|
{
|
||||||
#else
|
#else
|
||||||
@@ -168,7 +229,7 @@ void ConCmdManager::SetCommandClient(int client)
|
|||||||
ConCmdInfo *ConCmdManager::FindInTrie(const char *name)
|
ConCmdInfo *ConCmdManager::FindInTrie(const char *name)
|
||||||
{
|
{
|
||||||
ConCmdInfo *pInfo;
|
ConCmdInfo *pInfo;
|
||||||
if (!m_Cmds.retrieve(name, &pInfo))
|
if (!sm_trie_retrieve(m_pCmds, name, (void **)&pInfo))
|
||||||
return NULL;
|
return NULL;
|
||||||
return pInfo;
|
return pInfo;
|
||||||
}
|
}
|
||||||
@@ -200,34 +261,44 @@ ResultType ConCmdManager::DispatchClientCommand(int client, const char *cmd, int
|
|||||||
}
|
}
|
||||||
|
|
||||||
cell_t result = type;
|
cell_t result = type;
|
||||||
for (CmdHookList::iterator iter = pInfo->hooks.begin(); iter != pInfo->hooks.end(); iter++)
|
cell_t tempres = result;
|
||||||
|
List<CmdHook *>::iterator iter;
|
||||||
|
CmdHook *pHook;
|
||||||
|
for (iter=pInfo->conhooks.begin();
|
||||||
|
iter!=pInfo->conhooks.end();
|
||||||
|
iter++)
|
||||||
{
|
{
|
||||||
CmdHook *hook = *iter;
|
pHook = (*iter);
|
||||||
|
if (!pHook->pf->IsRunnable())
|
||||||
if (hook->type == CmdHook::Server || !hook->pf->IsRunnable())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (hook->admin && !CheckAccess(client, cmd, hook->admin))
|
|
||||||
{
|
{
|
||||||
if (result < Pl_Handled)
|
|
||||||
result = Pl_Handled;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (pHook->pAdmin && !CheckAccess(client, cmd, pHook->pAdmin))
|
||||||
hook->pf->PushCell(client);
|
{
|
||||||
hook->pf->PushCell(args);
|
if (result < Pl_Handled)
|
||||||
|
{
|
||||||
cell_t tempres = result;
|
result = Pl_Handled;
|
||||||
if (hook->pf->Execute(&tempres) == SP_ERROR_NONE)
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
pHook->pf->PushCell(client);
|
||||||
|
pHook->pf->PushCell(args);
|
||||||
|
if (pHook->pf->Execute(&tempres) == SP_ERROR_NONE)
|
||||||
{
|
{
|
||||||
if (tempres > result)
|
if (tempres > result)
|
||||||
|
{
|
||||||
result = tempres;
|
result = tempres;
|
||||||
|
}
|
||||||
if (result == Pl_Stop)
|
if (result == Pl_Stop)
|
||||||
|
{
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (ResultType)result;
|
type = (ResultType)result;
|
||||||
|
|
||||||
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConCmdManager::InternalDispatch(const CCommand &command)
|
void ConCmdManager::InternalDispatch(const CCommand &command)
|
||||||
@@ -238,7 +309,9 @@ void ConCmdManager::InternalDispatch(const CCommand &command)
|
|||||||
{
|
{
|
||||||
CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
|
CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
|
||||||
if (!pPlayer || !pPlayer->IsConnected())
|
if (!pPlayer || !pPlayer->IsConnected())
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -270,78 +343,198 @@ void ConCmdManager::InternalDispatch(const CCommand &command)
|
|||||||
* "nicer" when we expose explicit say hooks.
|
* "nicer" when we expose explicit say hooks.
|
||||||
*/
|
*/
|
||||||
if (g_ChatTriggers.WasFloodedMessage())
|
if (g_ChatTriggers.WasFloodedMessage())
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
cell_t result = Pl_Continue;
|
cell_t result = Pl_Continue;
|
||||||
int args = command.ArgC() - 1;
|
int args = command.ArgC() - 1;
|
||||||
|
|
||||||
// On a listen server, sometimes the server host's client index can be set
|
List<CmdHook *>::iterator iter;
|
||||||
// as 0. So index 1 is passed to the command callback to correct this
|
CmdHook *pHook;
|
||||||
// potential problem.
|
|
||||||
int realClient = (!engine->IsDedicatedServer() && client == 0)
|
|
||||||
? g_Players.ListenClient()
|
|
||||||
: client;
|
|
||||||
int dedicatedClient = engine->IsDedicatedServer() ? 0 : g_Players.ListenClient();
|
|
||||||
|
|
||||||
for (CmdHookList::iterator iter = pInfo->hooks.begin(); iter != pInfo->hooks.end(); iter++)
|
/* Execute server-only commands if viable */
|
||||||
|
if (client == 0 && pInfo->srvhooks.size())
|
||||||
{
|
{
|
||||||
CmdHook *hook = *iter;
|
cell_t tempres = result;
|
||||||
|
for (iter=pInfo->srvhooks.begin();
|
||||||
if (!hook->pf->IsRunnable())
|
iter!=pInfo->srvhooks.end();
|
||||||
continue;
|
iter++)
|
||||||
|
|
||||||
if (hook->type == CmdHook::Server)
|
|
||||||
{
|
{
|
||||||
// Don't execute unless we're in the server console.
|
pHook = (*iter);
|
||||||
if (realClient != dedicatedClient)
|
if (!pHook->pf->IsRunnable())
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
} else {
|
}
|
||||||
// Check admin rights if needed. realClient isn't needed since we
|
pHook->pf->PushCell(args);
|
||||||
// should bypass admin checks if client == 0 anyway.
|
if (pHook->pf->Execute(&tempres) == SP_ERROR_NONE)
|
||||||
if (client && hook->admin && !CheckAccess(client, cmd, hook->admin))
|
{
|
||||||
|
if (tempres > result)
|
||||||
|
{
|
||||||
|
result = tempres;
|
||||||
|
}
|
||||||
|
if (result == Pl_Stop)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if there's an early stop */
|
||||||
|
if (result >= Pl_Stop)
|
||||||
|
{
|
||||||
|
if (!pInfo->sourceMod)
|
||||||
|
{
|
||||||
|
RETURN_META(MRES_SUPERCEDE);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Execute console commands */
|
||||||
|
if (pInfo->conhooks.size())
|
||||||
|
{
|
||||||
|
cell_t tempres = result;
|
||||||
|
for (iter=pInfo->conhooks.begin();
|
||||||
|
iter!=pInfo->conhooks.end();
|
||||||
|
iter++)
|
||||||
|
{
|
||||||
|
pHook = (*iter);
|
||||||
|
if (!pHook->pf->IsRunnable())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (client
|
||||||
|
&& pHook->pAdmin
|
||||||
|
&& !CheckAccess(client, cmd, pHook->pAdmin))
|
||||||
{
|
{
|
||||||
if (result < Pl_Handled)
|
if (result < Pl_Handled)
|
||||||
|
{
|
||||||
result = Pl_Handled;
|
result = Pl_Handled;
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Client hooks get a client argument.
|
/* On a listen server, sometimes the server host's client index can be set as 0.
|
||||||
hook->pf->PushCell(realClient);
|
* So index 1 is passed to the command callback to correct this potential problem.
|
||||||
}
|
*/
|
||||||
|
if (!engine->IsDedicatedServer())
|
||||||
|
{
|
||||||
|
client = g_Players.ListenClient();
|
||||||
|
}
|
||||||
|
|
||||||
hook->pf->PushCell(args);
|
pHook->pf->PushCell(client);
|
||||||
|
pHook->pf->PushCell(args);
|
||||||
|
|
||||||
cell_t tempres = result;
|
if (pHook->pf->Execute(&tempres) == SP_ERROR_NONE)
|
||||||
if (hook->pf->Execute(&tempres) == SP_ERROR_NONE)
|
{
|
||||||
{
|
if (tempres > result)
|
||||||
if (tempres > result)
|
{
|
||||||
result = tempres;
|
result = tempres;
|
||||||
if (result == Pl_Stop)
|
}
|
||||||
break;
|
if (result == Pl_Stop)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result >= Pl_Handled)
|
if (result >= Pl_Handled)
|
||||||
{
|
{
|
||||||
if (!pInfo->sourceMod)
|
if (!pInfo->sourceMod)
|
||||||
|
{
|
||||||
RETURN_META(MRES_SUPERCEDE);
|
RETURN_META(MRES_SUPERCEDE);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ConCmdManager::CheckAccess(int client, const char *cmd, AdminCmdInfo *pAdmin)
|
bool ConCmdManager::CheckClientCommandAccess(int client, const char *cmd, FlagBits cmdflags)
|
||||||
{
|
{
|
||||||
if (adminsys->CheckClientCommandAccess(client, cmd, pAdmin->eflags))
|
if (cmdflags == 0 || client == 0)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
CPlayer *pPlayer = g_Players.GetPlayerByIndex(client);
|
/* If running listen server, then client 1 is the server host and should have 'root' access */
|
||||||
if (!pPlayer)
|
if (client == 1 && !engine->IsDedicatedServer())
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
CPlayer *player = g_Players.GetPlayerByIndex(client);
|
||||||
|
if (!player
|
||||||
|
|| player->GetEdict() == NULL
|
||||||
|
|| player->IsFakeClient())
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return CheckAdminCommandAccess(player->GetAdminId(), cmd, cmdflags);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ConCmdManager::CheckAdminCommandAccess(AdminId adm, const char *cmd, FlagBits cmdflags)
|
||||||
|
{
|
||||||
|
if (adm != INVALID_ADMIN_ID)
|
||||||
|
{
|
||||||
|
FlagBits bits = g_Admins.GetAdminFlags(adm, Access_Effective);
|
||||||
|
|
||||||
|
/* root knows all, WHOA */
|
||||||
|
if ((bits & ADMFLAG_ROOT) == ADMFLAG_ROOT)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check for overrides
|
||||||
|
* :TODO: is it worth optimizing this?
|
||||||
|
*/
|
||||||
|
unsigned int groups = g_Admins.GetAdminGroupCount(adm);
|
||||||
|
GroupId gid;
|
||||||
|
OverrideRule rule;
|
||||||
|
bool override = false;
|
||||||
|
for (unsigned int i=0; i<groups; i++)
|
||||||
|
{
|
||||||
|
gid = g_Admins.GetAdminGroup(adm, i, NULL);
|
||||||
|
/* First get group-level override */
|
||||||
|
override = g_Admins.GetGroupCommandOverride(gid, cmd, Override_CommandGroup, &rule);
|
||||||
|
/* Now get the specific command override */
|
||||||
|
if (g_Admins.GetGroupCommandOverride(gid, cmd, Override_Command, &rule))
|
||||||
|
{
|
||||||
|
override = true;
|
||||||
|
}
|
||||||
|
if (override)
|
||||||
|
{
|
||||||
|
if (rule == Command_Allow)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (rule == Command_Deny)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* See if our other flags match */
|
||||||
|
if ((bits & cmdflags) == cmdflags)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ConCmdManager::CheckAccess(int client, const char *cmd, AdminCmdInfo *pAdmin)
|
||||||
|
{
|
||||||
|
if (CheckClientCommandAccess(client, cmd, pAdmin->eflags))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
edict_t *pEdict = PEntityOfEntIndex(client);
|
||||||
|
|
||||||
/* If we got here, the command failed... */
|
/* If we got here, the command failed... */
|
||||||
char buffer[128];
|
char buffer[128];
|
||||||
if (!logicore.CoreTranslate(buffer, sizeof(buffer), "%T", 2, NULL, "No Access", &client))
|
if (!logicore.CoreTranslate(buffer, sizeof(buffer), "%T", 2, NULL, "No Access", &client))
|
||||||
@@ -354,7 +547,7 @@ bool ConCmdManager::CheckAccess(int client, const char *cmd, AdminCmdInfo *pAdmi
|
|||||||
{
|
{
|
||||||
char fullbuffer[192];
|
char fullbuffer[192];
|
||||||
UTIL_Format(fullbuffer, sizeof(fullbuffer), "[SM] %s.\n", buffer);
|
UTIL_Format(fullbuffer, sizeof(fullbuffer), "[SM] %s.\n", buffer);
|
||||||
pPlayer->PrintToConsole(fullbuffer);
|
engine->ClientPrintf(pEdict, fullbuffer);
|
||||||
}
|
}
|
||||||
else if (replyto == SM_REPLY_CHAT)
|
else if (replyto == SM_REPLY_CHAT)
|
||||||
{
|
{
|
||||||
@@ -376,41 +569,72 @@ bool ConCmdManager::AddAdminCommand(IPluginFunction *pFunction,
|
|||||||
ConCmdInfo *pInfo = AddOrFindCommand(name, description, flags);
|
ConCmdInfo *pInfo = AddOrFindCommand(name, description, flags);
|
||||||
|
|
||||||
if (!pInfo)
|
if (!pInfo)
|
||||||
return false;
|
|
||||||
|
|
||||||
GroupMap::Insert i = m_CmdGrps.findForAdd(group);
|
|
||||||
if (!i.found())
|
|
||||||
{
|
{
|
||||||
if (!m_CmdGrps.add(i, group))
|
return false;
|
||||||
return false;
|
|
||||||
i->value = NoAddRef(new CommandGroup());
|
|
||||||
}
|
}
|
||||||
Ref<CommandGroup> cmdgroup = i->value;
|
|
||||||
|
|
||||||
CmdHook *pHook = new CmdHook(CmdHook::Client, pInfo, pFunction, description);
|
CmdHook *pHook = new CmdHook();
|
||||||
pHook->admin = new AdminCmdInfo(cmdgroup, adminflags);
|
AdminCmdInfo *pAdmin = new AdminCmdInfo();
|
||||||
|
|
||||||
|
pHook->pf = pFunction;
|
||||||
|
if (description && description[0])
|
||||||
|
{
|
||||||
|
pHook->helptext.assign(description);
|
||||||
|
}
|
||||||
|
pHook->pAdmin = pAdmin;
|
||||||
|
|
||||||
|
void *object;
|
||||||
|
int grpid;
|
||||||
|
if (!sm_trie_retrieve(m_pCmdGrps, group, (void **)&object))
|
||||||
|
{
|
||||||
|
grpid = m_Strings.AddString(group);
|
||||||
|
sm_trie_insert(m_pCmdGrps, group, (void *)grpid);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
grpid = (int)object;
|
||||||
|
}
|
||||||
|
|
||||||
|
pAdmin->cmdGrpId = grpid;
|
||||||
|
pAdmin->flags = adminflags;
|
||||||
|
|
||||||
/* First get the command group override, if any */
|
/* First get the command group override, if any */
|
||||||
bool override = adminsys->GetCommandOverride(group,
|
bool override = g_Admins.GetCommandOverride(group,
|
||||||
Override_CommandGroup,
|
Override_CommandGroup,
|
||||||
&(pHook->admin->eflags));
|
&(pAdmin->eflags));
|
||||||
|
|
||||||
/* Next get the command override, if any */
|
/* Next get the command override, if any */
|
||||||
if (adminsys->GetCommandOverride(name,
|
if (g_Admins.GetCommandOverride(name,
|
||||||
Override_Command,
|
Override_Command,
|
||||||
&(pHook->admin->eflags)))
|
&(pAdmin->eflags)))
|
||||||
{
|
{
|
||||||
override = true;
|
override = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Assign normal flags if there were no overrides */
|
/* Assign normal flags if there were no overrides */
|
||||||
if (!override)
|
if (!override)
|
||||||
pHook->admin->eflags = pHook->admin->flags;
|
{
|
||||||
pInfo->eflags = pHook->admin->eflags;
|
pAdmin->eflags = pAdmin->flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Finally, add the hook */
|
||||||
|
pInfo->conhooks.push_back(pHook);
|
||||||
|
pInfo->admin = *(pHook->pAdmin);
|
||||||
|
|
||||||
|
/* Now add to the plugin */
|
||||||
|
CmdList *pList;
|
||||||
|
IPlugin *pPlugin = g_PluginSys.GetPluginByCtx(pFunction->GetParentContext()->GetContext());
|
||||||
|
if (!pPlugin->GetProperty("CommandList", (void **)&pList))
|
||||||
|
{
|
||||||
|
pList = new CmdList();
|
||||||
|
pPlugin->SetProperty("CommandList", pList);
|
||||||
|
}
|
||||||
|
PlCmdInfo info;
|
||||||
|
info.pInfo = pInfo;
|
||||||
|
info.type = Cmd_Admin;
|
||||||
|
info.pHook = pHook;
|
||||||
|
AddToPlCmdList(pList, info);
|
||||||
|
|
||||||
cmdgroup->hooks.append(pHook);
|
|
||||||
pInfo->hooks.append(pHook);
|
|
||||||
RegisterInPlugin(pHook);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -423,42 +647,63 @@ bool ConCmdManager::AddServerCommand(IPluginFunction *pFunction,
|
|||||||
ConCmdInfo *pInfo = AddOrFindCommand(name, description, flags);
|
ConCmdInfo *pInfo = AddOrFindCommand(name, description, flags);
|
||||||
|
|
||||||
if (!pInfo)
|
if (!pInfo)
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
CmdHook *pHook = new CmdHook(CmdHook::Server, pInfo, pFunction, description);
|
CmdHook *pHook = new CmdHook();
|
||||||
|
|
||||||
|
pHook->pf = pFunction;
|
||||||
|
if (description && description[0])
|
||||||
|
{
|
||||||
|
pHook->helptext.assign(description);
|
||||||
|
}
|
||||||
|
|
||||||
|
pInfo->srvhooks.push_back(pHook);
|
||||||
|
|
||||||
|
/* Add to the plugin */
|
||||||
|
CmdList *pList;
|
||||||
|
IPlugin *pPlugin = g_PluginSys.GetPluginByCtx(pFunction->GetParentContext()->GetContext());
|
||||||
|
if (!pPlugin->GetProperty("CommandList", (void **)&pList))
|
||||||
|
{
|
||||||
|
pList = new CmdList();
|
||||||
|
pPlugin->SetProperty("CommandList", pList);
|
||||||
|
}
|
||||||
|
PlCmdInfo info;
|
||||||
|
info.pInfo = pInfo;
|
||||||
|
info.type = Cmd_Server;
|
||||||
|
info.pHook = pHook;
|
||||||
|
AddToPlCmdList(pList, info);
|
||||||
|
|
||||||
pInfo->hooks.append(pHook);
|
|
||||||
RegisterInPlugin(pHook);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RegisterInPlugin(CmdHook *hook)
|
void AddToPlCmdList(CmdList *pList, const PlCmdInfo &info)
|
||||||
{
|
{
|
||||||
PluginHookList *pList;
|
CmdList::iterator iter = pList->begin();
|
||||||
|
bool inserted = false;
|
||||||
|
const char *orig = NULL;
|
||||||
|
|
||||||
IPlugin *pPlugin = scripts->FindPluginByContext(hook->pf->GetParentContext());
|
orig = info.pInfo->pCmd->GetName();
|
||||||
if (!pPlugin->GetProperty("CommandList", (void **)&pList))
|
|
||||||
{
|
|
||||||
pList = new PluginHookList();
|
|
||||||
pPlugin->SetProperty("CommandList", pList);
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *orig = hook->info->pCmd->GetName();
|
|
||||||
|
|
||||||
/* Insert this into the help list, SORTED alphabetically. */
|
/* Insert this into the help list, SORTED alphabetically. */
|
||||||
PluginHookList::iterator iter = pList->begin();
|
|
||||||
while (iter != pList->end())
|
while (iter != pList->end())
|
||||||
{
|
{
|
||||||
const char *cmd = (*iter)->info->pCmd->GetName();
|
PlCmdInfo &obj = (*iter);
|
||||||
|
const char *cmd = obj.pInfo->pCmd->GetName();
|
||||||
if (strcmp(orig, cmd) < 0)
|
if (strcmp(orig, cmd) < 0)
|
||||||
{
|
{
|
||||||
pList->insertBefore(iter, hook);
|
pList->insert(iter, info);
|
||||||
return;
|
inserted = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
iter++;
|
iter++;
|
||||||
}
|
}
|
||||||
|
|
||||||
pList->append(hook);
|
if (!inserted)
|
||||||
|
{
|
||||||
|
pList->push_back(info);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConCmdManager::AddToCmdList(ConCmdInfo *info)
|
void ConCmdManager::AddToCmdList(ConCmdInfo *info)
|
||||||
@@ -493,40 +738,64 @@ void ConCmdManager::AddToCmdList(ConCmdInfo *info)
|
|||||||
|
|
||||||
void ConCmdManager::UpdateAdminCmdFlags(const char *cmd, OverrideType type, FlagBits bits, bool remove)
|
void ConCmdManager::UpdateAdminCmdFlags(const char *cmd, OverrideType type, FlagBits bits, bool remove)
|
||||||
{
|
{
|
||||||
|
ConCmdInfo *pInfo;
|
||||||
|
|
||||||
if (type == Override_Command)
|
if (type == Override_Command)
|
||||||
{
|
{
|
||||||
ConCmdInfo *pInfo;
|
if (!sm_trie_retrieve(m_pCmds, cmd, (void **)&pInfo))
|
||||||
if (!m_Cmds.retrieve(cmd, &pInfo))
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (CmdHookList::iterator iter = pInfo->hooks.begin(); iter != pInfo->hooks.end(); iter++)
|
|
||||||
{
|
{
|
||||||
if (!iter->admin)
|
return;
|
||||||
continue;
|
}
|
||||||
|
|
||||||
if (!remove)
|
List<CmdHook *>::iterator iter;
|
||||||
iter->admin->eflags = bits;
|
CmdHook *pHook;
|
||||||
else
|
|
||||||
iter->admin->eflags = iter->admin->flags;
|
for (iter=pInfo->conhooks.begin(); iter!=pInfo->conhooks.end(); iter++)
|
||||||
pInfo->eflags = iter->admin->eflags;
|
{
|
||||||
|
pHook = (*iter);
|
||||||
|
if (pHook->pAdmin)
|
||||||
|
{
|
||||||
|
if (!remove)
|
||||||
|
{
|
||||||
|
pHook->pAdmin->eflags = bits;
|
||||||
|
} else {
|
||||||
|
pHook->pAdmin->eflags = pHook->pAdmin->flags;
|
||||||
|
}
|
||||||
|
pInfo->admin = *(pHook->pAdmin);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (type == Override_CommandGroup)
|
else if (type == Override_CommandGroup)
|
||||||
{
|
{
|
||||||
GroupMap::Result r = m_CmdGrps.find(cmd);
|
void *object;
|
||||||
if (!r.found())
|
if (!sm_trie_retrieve(m_pCmdGrps, cmd, &object))
|
||||||
return;
|
|
||||||
|
|
||||||
Ref<CommandGroup> group(r->value);
|
|
||||||
|
|
||||||
for (PluginHookList::iterator iter = group->hooks.begin(); iter != group->hooks.end(); iter++)
|
|
||||||
{
|
{
|
||||||
CmdHook *hook = *iter;
|
return;
|
||||||
if (remove)
|
}
|
||||||
hook->admin->eflags = bits;
|
int grpid = (int)object;
|
||||||
else
|
|
||||||
hook->admin->eflags = hook->admin->flags;
|
/* This is bad :( loop through all commands */
|
||||||
hook->info->eflags = hook->admin->eflags;
|
List<ConCmdInfo *>::iterator iter;
|
||||||
|
CmdHook *pHook;
|
||||||
|
for (iter=m_CmdList.begin(); iter!=m_CmdList.end(); iter++)
|
||||||
|
{
|
||||||
|
pInfo = (*iter);
|
||||||
|
for (List<CmdHook *>::iterator citer=pInfo->conhooks.begin();
|
||||||
|
citer!=pInfo->conhooks.end();
|
||||||
|
citer++)
|
||||||
|
{
|
||||||
|
pHook = (*citer);
|
||||||
|
if (pHook->pAdmin && pHook->pAdmin->cmdGrpId == grpid)
|
||||||
|
{
|
||||||
|
if (remove)
|
||||||
|
{
|
||||||
|
pHook->pAdmin->eflags = bits;
|
||||||
|
} else {
|
||||||
|
pHook->pAdmin->eflags = pHook->pAdmin->flags;
|
||||||
|
}
|
||||||
|
pInfo->admin = *(pHook->pAdmin);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -534,7 +803,7 @@ void ConCmdManager::UpdateAdminCmdFlags(const char *cmd, OverrideType type, Flag
|
|||||||
void ConCmdManager::RemoveConCmd(ConCmdInfo *info, const char *name, bool is_read_safe, bool untrack)
|
void ConCmdManager::RemoveConCmd(ConCmdInfo *info, const char *name, bool is_read_safe, bool untrack)
|
||||||
{
|
{
|
||||||
/* Remove from the trie */
|
/* Remove from the trie */
|
||||||
m_Cmds.remove(name);
|
sm_trie_delete(m_pCmds, name);
|
||||||
|
|
||||||
/* Remove console-specific information
|
/* Remove console-specific information
|
||||||
* This should always be true as of right now
|
* This should always be true as of right now
|
||||||
@@ -557,7 +826,7 @@ void ConCmdManager::RemoveConCmd(ConCmdInfo *info, const char *name, bool is_rea
|
|||||||
if (is_read_safe)
|
if (is_read_safe)
|
||||||
{
|
{
|
||||||
/* Remove the external hook */
|
/* Remove the external hook */
|
||||||
SH_REMOVE_HOOK(ConCommand, Dispatch, info->pCmd, SH_STATIC(CommandCallback), false);
|
SH_REMOVE_HOOK_STATICFUNC(ConCommand, Dispatch, info->pCmd, CommandCallback, false);
|
||||||
}
|
}
|
||||||
if (untrack)
|
if (untrack)
|
||||||
{
|
{
|
||||||
@@ -575,26 +844,33 @@ void ConCmdManager::RemoveConCmd(ConCmdInfo *info, const char *name, bool is_rea
|
|||||||
bool ConCmdManager::LookForSourceModCommand(const char *cmd)
|
bool ConCmdManager::LookForSourceModCommand(const char *cmd)
|
||||||
{
|
{
|
||||||
ConCmdInfo *pInfo;
|
ConCmdInfo *pInfo;
|
||||||
if (!m_Cmds.retrieve(cmd, &pInfo))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return pInfo->sourceMod && !pInfo->hooks.empty();
|
if (!sm_trie_retrieve(m_pCmds, cmd, (void **)&pInfo))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pInfo->sourceMod && (pInfo->conhooks.size() > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ConCmdManager::LookForCommandAdminFlags(const char *cmd, FlagBits *pFlags)
|
bool ConCmdManager::LookForCommandAdminFlags(const char *cmd, FlagBits *pFlags)
|
||||||
{
|
{
|
||||||
ConCmdInfo *pInfo;
|
ConCmdInfo *pInfo;
|
||||||
if (!m_Cmds.retrieve(cmd, &pInfo))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
*pFlags = pInfo->eflags;
|
if (!sm_trie_retrieve(m_pCmds, cmd, (void **)&pInfo))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
*pFlags = pInfo->admin.eflags;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ConCmdInfo *ConCmdManager::AddOrFindCommand(const char *name, const char *description, int flags)
|
ConCmdInfo *ConCmdManager::AddOrFindCommand(const char *name, const char *description, int flags)
|
||||||
{
|
{
|
||||||
ConCmdInfo *pInfo;
|
ConCmdInfo *pInfo;
|
||||||
if (!m_Cmds.retrieve(name, &pInfo))
|
if (!sm_trie_retrieve(m_pCmds, name, (void **)&pInfo))
|
||||||
{
|
{
|
||||||
ConCmdList::iterator item = FindInList(name);
|
ConCmdList::iterator item = FindInList(name);
|
||||||
if (item != m_CmdList.end())
|
if (item != m_CmdList.end())
|
||||||
@@ -621,12 +897,12 @@ ConCmdInfo *ConCmdManager::AddOrFindCommand(const char *name, const char *descri
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
TrackConCommandBase(pCmd, this);
|
TrackConCommandBase(pCmd, this);
|
||||||
SH_ADD_HOOK(ConCommand, Dispatch, pCmd, SH_STATIC(CommandCallback), false);
|
SH_ADD_HOOK_STATICFUNC(ConCommand, Dispatch, pCmd, CommandCallback, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
pInfo->pCmd = pCmd;
|
pInfo->pCmd = pCmd;
|
||||||
|
|
||||||
m_Cmds.insert(name, pInfo);
|
sm_trie_insert(m_pCmds, name, pInfo);
|
||||||
AddToCmdList(pInfo);
|
AddToCmdList(pInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -639,7 +915,7 @@ void ConCmdManager::OnRootConsoleCommand(const char *cmdname, const CCommand &co
|
|||||||
{
|
{
|
||||||
const char *text = command.Arg(2);
|
const char *text = command.Arg(2);
|
||||||
|
|
||||||
IPlugin *pPlugin = scripts->FindPluginByConsoleArg(text);
|
CPlugin *pPlugin = g_PluginSys.FindPluginByConsoleArg(text);
|
||||||
|
|
||||||
if (!pPlugin)
|
if (!pPlugin)
|
||||||
{
|
{
|
||||||
@@ -650,36 +926,46 @@ void ConCmdManager::OnRootConsoleCommand(const char *cmdname, const CCommand &co
|
|||||||
const sm_plugininfo_t *plinfo = pPlugin->GetPublicInfo();
|
const sm_plugininfo_t *plinfo = pPlugin->GetPublicInfo();
|
||||||
const char *plname = IS_STR_FILLED(plinfo->name) ? plinfo->name : pPlugin->GetFilename();
|
const char *plname = IS_STR_FILLED(plinfo->name) ? plinfo->name : pPlugin->GetFilename();
|
||||||
|
|
||||||
PluginHookList *pList;
|
CmdList *pList;
|
||||||
if (!pPlugin->GetProperty("CommandList", (void **)&pList))
|
if (!pPlugin->GetProperty("CommandList", (void **)&pList))
|
||||||
{
|
{
|
||||||
g_RootMenu.ConsolePrint("[SM] No commands found for: %s", plname);
|
g_RootMenu.ConsolePrint("[SM] No commands found for: %s", plname);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (pList->empty())
|
if (!pList->size())
|
||||||
{
|
{
|
||||||
g_RootMenu.ConsolePrint("[SM] No commands found for: %s", plname);
|
g_RootMenu.ConsolePrint("[SM] No commands found for: %s", plname);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CmdList::iterator iter;
|
||||||
const char *type = NULL;
|
const char *type = NULL;
|
||||||
const char *name;
|
const char *name;
|
||||||
const char *help;
|
const char *help;
|
||||||
g_RootMenu.ConsolePrint("[SM] Listing commands for: %s", plname);
|
g_RootMenu.ConsolePrint("[SM] Listing %d commands for: %s", pList->size(), plname);
|
||||||
g_RootMenu.ConsolePrint(" %-17.16s %-8.7s %s", "[Name]", "[Type]", "[Help]");
|
g_RootMenu.ConsolePrint(" %-17.16s %-8.7s %s", "[Name]", "[Type]", "[Help]");
|
||||||
for (PluginHookList::iterator iter = pList->begin(); iter != pList->end(); iter++)
|
for (iter=pList->begin();
|
||||||
|
iter!=pList->end();
|
||||||
|
iter++)
|
||||||
{
|
{
|
||||||
CmdHook *hook = *iter;
|
PlCmdInfo &cmd = (*iter);
|
||||||
if (hook->type == CmdHook::Server)
|
if (cmd.type == Cmd_Server)
|
||||||
|
{
|
||||||
type = "server";
|
type = "server";
|
||||||
else
|
}
|
||||||
type = hook->info->eflags == 0 ? "console" : "admin";
|
else if (cmd.type == Cmd_Admin)
|
||||||
|
{
|
||||||
name = hook->info->pCmd->GetName();
|
type = (cmd.pInfo->admin.eflags == 0)?"console":"admin";
|
||||||
if (hook->helptext.length())
|
}
|
||||||
help = hook->helptext.chars();
|
name = cmd.pInfo->pCmd->GetName();
|
||||||
|
if (cmd.pHook->helptext.size())
|
||||||
|
{
|
||||||
|
help = cmd.pHook->helptext.c_str();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
help = hook->info->pCmd->GetHelpText();
|
{
|
||||||
|
help = cmd.pInfo->pCmd->GetHelpText();
|
||||||
|
}
|
||||||
g_RootMenu.ConsolePrint(" %-17.16s %-12.11s %s", name, type, help);
|
g_RootMenu.ConsolePrint(" %-17.16s %-12.11s %s", name, type, help);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+30
-46
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* vim: set ts=4 sw=4 tw=99 noet :
|
* vim: set ts=4 :
|
||||||
* =============================================================================
|
* =============================================================================
|
||||||
* SourceMod
|
* SourceMod
|
||||||
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
||||||
@@ -34,77 +34,60 @@
|
|||||||
|
|
||||||
#include "sm_globals.h"
|
#include "sm_globals.h"
|
||||||
#include "sourcemm_api.h"
|
#include "sourcemm_api.h"
|
||||||
#include <IForwardSys.h>
|
#include "ForwardSys.h"
|
||||||
|
#include "sm_trie.h"
|
||||||
|
#include "sm_memtable.h"
|
||||||
#include <sh_list.h>
|
#include <sh_list.h>
|
||||||
#include <sh_string.h>
|
#include <sh_string.h>
|
||||||
#include <IRootConsoleMenu.h>
|
#include <IRootConsoleMenu.h>
|
||||||
#include <IAdminSystem.h>
|
#include <IAdminSystem.h>
|
||||||
#include "concmd_cleaner.h"
|
#include "concmd_cleaner.h"
|
||||||
#include <sm_stringhashmap.h>
|
|
||||||
#include <am-utility.h>
|
|
||||||
#include <am-inlinelist.h>
|
|
||||||
#include <am-linkedlist.h>
|
|
||||||
#include <am-refcounting.h>
|
|
||||||
|
|
||||||
using namespace SourceHook;
|
using namespace SourceHook;
|
||||||
|
|
||||||
struct CmdHook;
|
enum CmdType
|
||||||
struct ConCmdInfo;
|
|
||||||
|
|
||||||
struct CommandGroup : public ke::Refcounted<CommandGroup>
|
|
||||||
{
|
{
|
||||||
ke::LinkedList<CmdHook *> hooks;
|
Cmd_Server,
|
||||||
|
Cmd_Admin,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AdminCmdInfo
|
struct AdminCmdInfo
|
||||||
{
|
{
|
||||||
AdminCmdInfo(const ke::Ref<CommandGroup> &group, FlagBits flags)
|
AdminCmdInfo()
|
||||||
: group(group),
|
|
||||||
flags(flags),
|
|
||||||
eflags(0)
|
|
||||||
{
|
{
|
||||||
|
cmdGrpId = -1;
|
||||||
|
flags = 0;
|
||||||
|
eflags = 0;
|
||||||
}
|
}
|
||||||
ke::Ref<CommandGroup> group;
|
int cmdGrpId; /* index into cmdgroup string table */
|
||||||
FlagBits flags; /* default flags */
|
FlagBits flags; /* default flags */
|
||||||
FlagBits eflags; /* effective flags */
|
FlagBits eflags; /* effective flags */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CmdHook : public ke::InlineListNode<CmdHook>
|
struct CmdHook
|
||||||
{
|
{
|
||||||
enum Type {
|
CmdHook()
|
||||||
Server,
|
|
||||||
Client
|
|
||||||
};
|
|
||||||
|
|
||||||
CmdHook(Type type, ConCmdInfo *cmd, IPluginFunction *fun, const char *description)
|
|
||||||
: type(type),
|
|
||||||
info(cmd),
|
|
||||||
pf(fun),
|
|
||||||
helptext(description)
|
|
||||||
{
|
{
|
||||||
|
pf = NULL;
|
||||||
|
pAdmin = NULL;
|
||||||
}
|
}
|
||||||
|
IPluginFunction *pf; /* function hook */
|
||||||
Type type;
|
String helptext; /* help text */
|
||||||
ConCmdInfo *info;
|
AdminCmdInfo *pAdmin; /* admin requirements, if any */
|
||||||
IPluginFunction *pf; /* function hook */
|
|
||||||
ke::AString helptext; /* help text */
|
|
||||||
ke::AutoPtr<AdminCmdInfo> admin; /* admin requirements, if any */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef ke::InlineList<CmdHook> CmdHookList;
|
|
||||||
|
|
||||||
struct ConCmdInfo
|
struct ConCmdInfo
|
||||||
{
|
{
|
||||||
ConCmdInfo()
|
ConCmdInfo()
|
||||||
{
|
{
|
||||||
sourceMod = false;
|
sourceMod = false;
|
||||||
pCmd = NULL;
|
pCmd = NULL;
|
||||||
eflags = 0;
|
|
||||||
}
|
}
|
||||||
bool sourceMod; /**< Determines whether or not concmd was created by a SourceMod plugin */
|
bool sourceMod; /**< Determines whether or not concmd was created by a SourceMod plugin */
|
||||||
ConCommand *pCmd; /**< Pointer to the command itself */
|
ConCommand *pCmd; /**< Pointer to the command itself */
|
||||||
CmdHookList hooks; /**< Hook list */
|
List<CmdHook *> srvhooks; /**< Hooks as a server command */
|
||||||
FlagBits eflags; /**< Effective admin flags */
|
List<CmdHook *> conhooks; /**< Hooks as a console command */
|
||||||
|
AdminCmdInfo admin; /**< Admin info, if any */
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef List<ConCmdInfo *> ConCmdList;
|
typedef List<ConCmdInfo *> ConCmdList;
|
||||||
@@ -115,9 +98,7 @@ class ConCmdManager :
|
|||||||
public IPluginsListener,
|
public IPluginsListener,
|
||||||
public IConCommandTracker
|
public IConCommandTracker
|
||||||
{
|
{
|
||||||
#if SOURCE_ENGINE == SE_DOTA
|
#if SOURCE_ENGINE >= SE_ORANGEBOX
|
||||||
friend void CommandCallback(const CCommandContext &context, const CCommand &command);
|
|
||||||
#elif SOURCE_ENGINE >= SE_ORANGEBOX
|
|
||||||
friend void CommandCallback(const CCommand &command);
|
friend void CommandCallback(const CCommand &command);
|
||||||
#else
|
#else
|
||||||
friend void CommandCallback();
|
friend void CommandCallback();
|
||||||
@@ -146,6 +127,8 @@ public:
|
|||||||
void UpdateAdminCmdFlags(const char *cmd, OverrideType type, FlagBits bits, bool remove);
|
void UpdateAdminCmdFlags(const char *cmd, OverrideType type, FlagBits bits, bool remove);
|
||||||
bool LookForSourceModCommand(const char *cmd);
|
bool LookForSourceModCommand(const char *cmd);
|
||||||
bool LookForCommandAdminFlags(const char *cmd, FlagBits *pFlags);
|
bool LookForCommandAdminFlags(const char *cmd, FlagBits *pFlags);
|
||||||
|
bool CheckClientCommandAccess(int client, const char *cmd, FlagBits flags);
|
||||||
|
bool CheckAdminCommandAccess(AdminId adm, const char *cmd, FlagBits flags);
|
||||||
private:
|
private:
|
||||||
void InternalDispatch(const CCommand &command);
|
void InternalDispatch(const CCommand &command);
|
||||||
ResultType RunAdminCommand(ConCmdInfo *pInfo, int client, int args);
|
ResultType RunAdminCommand(ConCmdInfo *pInfo, int client, int args);
|
||||||
@@ -153,6 +136,8 @@ private:
|
|||||||
void SetCommandClient(int client);
|
void SetCommandClient(int client);
|
||||||
void AddToCmdList(ConCmdInfo *info);
|
void AddToCmdList(ConCmdInfo *info);
|
||||||
void RemoveConCmd(ConCmdInfo *info, const char *cmd, bool is_read_safe, bool untrack);
|
void RemoveConCmd(ConCmdInfo *info, const char *cmd, bool is_read_safe, bool untrack);
|
||||||
|
void RemoveConCmds(List<CmdHook *> &cmdlist);
|
||||||
|
void RemoveConCmds(List<CmdHook *> &cmdlist, IPluginContext *pContext);
|
||||||
bool CheckAccess(int client, const char *cmd, AdminCmdInfo *pAdmin);
|
bool CheckAccess(int client, const char *cmd, AdminCmdInfo *pAdmin);
|
||||||
|
|
||||||
// Case insensitive
|
// Case insensitive
|
||||||
@@ -170,12 +155,11 @@ public:
|
|||||||
return m_CmdList;
|
return m_CmdList;
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
typedef StringHashMap<ke::Ref<CommandGroup> > GroupMap;
|
Trie *m_pCmds; /* command lookup */
|
||||||
|
Trie *m_pCmdGrps; /* command group lookup */
|
||||||
StringHashMap<ConCmdInfo *> m_Cmds; /* command lookup */
|
|
||||||
GroupMap m_CmdGrps; /* command group map */
|
|
||||||
ConCmdList m_CmdList; /* command list */
|
ConCmdList m_CmdList; /* command list */
|
||||||
int m_CmdClient; /* current client */
|
int m_CmdClient; /* current client */
|
||||||
|
BaseStringTable m_Strings; /* string table */
|
||||||
};
|
};
|
||||||
|
|
||||||
extern ConCmdManager g_ConCmds;
|
extern ConCmdManager g_ConCmds;
|
||||||
|
|||||||
+56
-103
@@ -29,31 +29,34 @@
|
|||||||
|
|
||||||
#include "ConVarManager.h"
|
#include "ConVarManager.h"
|
||||||
#include "HalfLife2.h"
|
#include "HalfLife2.h"
|
||||||
|
#include "PluginSys.h"
|
||||||
|
#include "ForwardSys.h"
|
||||||
|
#include "HandleSys.h"
|
||||||
#include "sm_srvcmds.h"
|
#include "sm_srvcmds.h"
|
||||||
#include "sm_stringutil.h"
|
#include "sm_stringutil.h"
|
||||||
#include <sh_vector.h>
|
#include <sh_vector.h>
|
||||||
#include <sm_namehashset.h>
|
#include <sm_trie_tpl.h>
|
||||||
#include "logic_bridge.h"
|
|
||||||
|
|
||||||
ConVarManager g_ConVarManager;
|
ConVarManager g_ConVarManager;
|
||||||
|
|
||||||
|
#if SOURCE_ENGINE <= SE_DARKMESSIAH
|
||||||
|
#define CallGlobalChangeCallbacks CallGlobalChangeCallback
|
||||||
|
#endif
|
||||||
|
|
||||||
#if SOURCE_ENGINE >= SE_ORANGEBOX
|
#if SOURCE_ENGINE >= SE_ORANGEBOX
|
||||||
SH_DECL_HOOK3_void(ICvar, CallGlobalChangeCallbacks, SH_NOATTRIB, false, ConVar *, const char *, float);
|
SH_DECL_HOOK3_void(ICvar, CallGlobalChangeCallbacks, SH_NOATTRIB, false, ConVar *, const char *, float);
|
||||||
#else
|
#else
|
||||||
SH_DECL_HOOK2_void(ICvar, CallGlobalChangeCallback, SH_NOATTRIB, false, ConVar *, const char *);
|
SH_DECL_HOOK2_void(ICvar, CallGlobalChangeCallbacks, SH_NOATTRIB, false, ConVar *, const char *);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if SOURCE_ENGINE == SE_DOTA
|
#if SOURCE_ENGINE != SE_DARKMESSIAH
|
||||||
SH_DECL_HOOK5_void(IServerGameDLL, OnQueryCvarValueFinished, SH_NOATTRIB, 0, QueryCvarCookie_t, CEntityIndex, EQueryCvarValueStatus, const char *, const char *);
|
|
||||||
SH_DECL_HOOK5_void(IServerPluginCallbacks, OnQueryCvarValueFinished, SH_NOATTRIB, 0, QueryCvarCookie_t, CEntityIndex, EQueryCvarValueStatus, const char *, const char *);
|
|
||||||
#elif SOURCE_ENGINE != SE_DARKMESSIAH
|
|
||||||
SH_DECL_HOOK5_void(IServerGameDLL, OnQueryCvarValueFinished, SH_NOATTRIB, 0, QueryCvarCookie_t, edict_t *, EQueryCvarValueStatus, const char *, const char *);
|
SH_DECL_HOOK5_void(IServerGameDLL, OnQueryCvarValueFinished, SH_NOATTRIB, 0, QueryCvarCookie_t, edict_t *, EQueryCvarValueStatus, const char *, const char *);
|
||||||
SH_DECL_HOOK5_void(IServerPluginCallbacks, OnQueryCvarValueFinished, SH_NOATTRIB, 0, QueryCvarCookie_t, edict_t *, EQueryCvarValueStatus, const char *, const char *);
|
SH_DECL_HOOK5_void(IServerPluginCallbacks, OnQueryCvarValueFinished, SH_NOATTRIB, 0, QueryCvarCookie_t, edict_t *, EQueryCvarValueStatus, const char *, const char *);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const ParamType CONVARCHANGE_PARAMS[] = {Param_Cell, Param_String, Param_String};
|
const ParamType CONVARCHANGE_PARAMS[] = {Param_Cell, Param_String, Param_String};
|
||||||
typedef List<const ConVar *> ConVarList;
|
typedef List<const ConVar *> ConVarList;
|
||||||
NameHashSet<ConVarInfo *> convar_cache;
|
KTrie<ConVarInfo *> convar_cache;
|
||||||
|
|
||||||
class ConVarReentrancyGuard
|
class ConVarReentrancyGuard
|
||||||
{
|
{
|
||||||
@@ -107,7 +110,7 @@ void ConVarManager::OnSourceModStartup(bool late)
|
|||||||
sec.access[HandleAccess_Clone] = HANDLE_RESTRICT_IDENTITY | HANDLE_RESTRICT_OWNER;
|
sec.access[HandleAccess_Clone] = HANDLE_RESTRICT_IDENTITY | HANDLE_RESTRICT_OWNER;
|
||||||
|
|
||||||
/* Create the 'ConVar' handle type */
|
/* Create the 'ConVar' handle type */
|
||||||
m_ConVarType = handlesys->CreateType("ConVar", this, 0, NULL, &sec, g_pCoreIdent, NULL);
|
m_ConVarType = g_HandleSys.CreateType("ConVar", this, 0, NULL, &sec, g_pCoreIdent, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConVarManager::OnSourceModAllInitialized()
|
void ConVarManager::OnSourceModAllInitialized()
|
||||||
@@ -118,20 +121,14 @@ void ConVarManager::OnSourceModAllInitialized()
|
|||||||
#if SOURCE_ENGINE == SE_EPISODEONE
|
#if SOURCE_ENGINE == SE_EPISODEONE
|
||||||
if (g_SMAPI->GetGameDLLVersion() >= 6)
|
if (g_SMAPI->GetGameDLLVersion() >= 6)
|
||||||
{
|
{
|
||||||
SH_ADD_HOOK(IServerGameDLL, OnQueryCvarValueFinished, gamedll, SH_MEMBER(this, &ConVarManager::OnQueryCvarValueFinished), false);
|
SH_ADD_HOOK_MEMFUNC(IServerGameDLL, OnQueryCvarValueFinished, gamedll, this, &ConVarManager::OnQueryCvarValueFinished, false);
|
||||||
m_bIsDLLQueryHooked = true;
|
m_bIsDLLQueryHooked = true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
g_Players.AddClientListener(this);
|
SH_ADD_HOOK_STATICFUNC(ICvar, CallGlobalChangeCallbacks, icvar, OnConVarChanged, false);
|
||||||
|
|
||||||
#if SOURCE_ENGINE >= SE_ORANGEBOX
|
g_PluginSys.AddPluginsListener(this);
|
||||||
SH_ADD_HOOK(ICvar, CallGlobalChangeCallbacks, icvar, SH_STATIC(OnConVarChanged), false);
|
|
||||||
#else
|
|
||||||
SH_ADD_HOOK(ICvar, CallGlobalChangeCallback, icvar, SH_STATIC(OnConVarChanged), false);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
scripts->AddPluginsListener(this);
|
|
||||||
|
|
||||||
/* Add the 'convars' option to the 'sm' console command */
|
/* Add the 'convars' option to the 'sm' console command */
|
||||||
g_RootMenu.AddRootConsoleCommand("cvars", "View convars created by a plugin", this);
|
g_RootMenu.AddRootConsoleCommand("cvars", "View convars created by a plugin", this);
|
||||||
@@ -149,10 +146,10 @@ void ConVarManager::OnSourceModShutdown()
|
|||||||
|
|
||||||
iter = m_ConVars.erase(iter);
|
iter = m_ConVars.erase(iter);
|
||||||
|
|
||||||
handlesys->FreeHandle(pInfo->handle, &sec);
|
g_HandleSys.FreeHandle(pInfo->handle, &sec);
|
||||||
if (pInfo->pChangeForward != NULL)
|
if (pInfo->pChangeForward != NULL)
|
||||||
{
|
{
|
||||||
forwardsys->ReleaseForward(pInfo->pChangeForward);
|
g_Forwards.ReleaseForward(pInfo->pChangeForward);
|
||||||
}
|
}
|
||||||
if (pInfo->sourceMod)
|
if (pInfo->sourceMod)
|
||||||
{
|
{
|
||||||
@@ -184,33 +181,25 @@ void ConVarManager::OnSourceModShutdown()
|
|||||||
/* Unhook things */
|
/* Unhook things */
|
||||||
if (m_bIsDLLQueryHooked)
|
if (m_bIsDLLQueryHooked)
|
||||||
{
|
{
|
||||||
SH_REMOVE_HOOK(IServerGameDLL, OnQueryCvarValueFinished, gamedll, SH_MEMBER(this, &ConVarManager::OnQueryCvarValueFinished), false);
|
SH_REMOVE_HOOK_MEMFUNC(IServerGameDLL, OnQueryCvarValueFinished, gamedll, this, &ConVarManager::OnQueryCvarValueFinished, false);
|
||||||
m_bIsDLLQueryHooked = false;
|
m_bIsDLLQueryHooked = false;
|
||||||
}
|
}
|
||||||
else if (m_bIsVSPQueryHooked)
|
else if (m_bIsVSPQueryHooked)
|
||||||
{
|
{
|
||||||
#if SOURCE_ENGINE != SE_DOTA
|
SH_REMOVE_HOOK_MEMFUNC(IServerPluginCallbacks, OnQueryCvarValueFinished, vsp_interface, this, &ConVarManager::OnQueryCvarValueFinished, false);
|
||||||
SH_REMOVE_HOOK(IServerPluginCallbacks, OnQueryCvarValueFinished, vsp_interface, SH_MEMBER(this, &ConVarManager::OnQueryCvarValueFinished), false);
|
|
||||||
#endif
|
|
||||||
m_bIsVSPQueryHooked = false;
|
m_bIsVSPQueryHooked = false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
g_Players.RemoveClientListener(this);
|
SH_REMOVE_HOOK_STATICFUNC(ICvar, CallGlobalChangeCallbacks, icvar, OnConVarChanged, false);
|
||||||
|
|
||||||
#if SOURCE_ENGINE >= SE_ORANGEBOX
|
|
||||||
SH_REMOVE_HOOK(ICvar, CallGlobalChangeCallbacks, icvar, SH_STATIC(OnConVarChanged), false);
|
|
||||||
#else
|
|
||||||
SH_REMOVE_HOOK(ICvar, CallGlobalChangeCallback, icvar, SH_STATIC(OnConVarChanged), false);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Remove the 'convars' option from the 'sm' console command */
|
/* Remove the 'convars' option from the 'sm' console command */
|
||||||
g_RootMenu.RemoveRootConsoleCommand("cvars", this);
|
g_RootMenu.RemoveRootConsoleCommand("cvars", this);
|
||||||
|
|
||||||
scripts->RemovePluginsListener(this);
|
g_PluginSys.RemovePluginsListener(this);
|
||||||
|
|
||||||
/* Remove the 'ConVar' handle type */
|
/* Remove the 'ConVar' handle type */
|
||||||
handlesys->RemoveType(m_ConVarType, g_pCoreIdent);
|
g_HandleSys.RemoveType(m_ConVarType, g_pCoreIdent);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -240,15 +229,24 @@ void ConVarManager::OnSourceModVSPReceived()
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if SOURCE_ENGINE != SE_DARKMESSIAH && SOURCE_ENGINE != SE_DOTA
|
#if SOURCE_ENGINE != SE_DARKMESSIAH
|
||||||
SH_ADD_HOOK(IServerPluginCallbacks, OnQueryCvarValueFinished, vsp_interface, SH_MEMBER(this, &ConVarManager::OnQueryCvarValueFinished), false);
|
SH_ADD_HOOK_MEMFUNC(IServerPluginCallbacks, OnQueryCvarValueFinished, vsp_interface, this, &ConVarManager::OnQueryCvarValueFinished, false);
|
||||||
m_bIsVSPQueryHooked = true;
|
m_bIsVSPQueryHooked = true;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool convar_cache_lookup(const char *name, ConVarInfo **pVar)
|
bool convar_cache_lookup(const char *name, ConVarInfo **pVar)
|
||||||
{
|
{
|
||||||
return convar_cache.retrieve(name, pVar);
|
ConVarInfo **pLookup = convar_cache.retrieve(name);
|
||||||
|
if (pLookup != NULL)
|
||||||
|
{
|
||||||
|
*pVar = *pLookup;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConVarManager::OnUnlinkConCommandBase(ConCommandBase *pBase, const char *name, bool is_read_safe)
|
void ConVarManager::OnUnlinkConCommandBase(ConCommandBase *pBase, const char *name, bool is_read_safe)
|
||||||
@@ -267,7 +265,7 @@ void ConVarManager::OnUnlinkConCommandBase(ConCommandBase *pBase, const char *na
|
|||||||
convar_cache.remove(name);
|
convar_cache.remove(name);
|
||||||
|
|
||||||
/* Now make sure no plugins are referring to this pointer */
|
/* Now make sure no plugins are referring to this pointer */
|
||||||
IPluginIterator *pl_iter = scripts->GetPluginIterator();
|
IPluginIterator *pl_iter = g_PluginSys.GetPluginIterator();
|
||||||
while (pl_iter->MorePlugins())
|
while (pl_iter->MorePlugins())
|
||||||
{
|
{
|
||||||
IPlugin *pl = pl_iter->GetPlugin();
|
IPlugin *pl = pl_iter->GetPlugin();
|
||||||
@@ -283,7 +281,7 @@ void ConVarManager::OnUnlinkConCommandBase(ConCommandBase *pBase, const char *na
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Free resources */
|
/* Free resources */
|
||||||
handlesys->FreeHandle(pInfo->handle, &sec);
|
g_HandleSys.FreeHandle(pInfo->handle, &sec);
|
||||||
delete pInfo;
|
delete pInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -298,35 +296,14 @@ void ConVarManager::OnPluginUnloaded(IPlugin *plugin)
|
|||||||
delete pConVarList;
|
delete pConVarList;
|
||||||
}
|
}
|
||||||
|
|
||||||
const IPluginRuntime * pRuntime = plugin->GetRuntime();
|
|
||||||
|
|
||||||
/* Remove convar queries for this plugin that haven't returned results yet */
|
/* Remove convar queries for this plugin that haven't returned results yet */
|
||||||
for (iter = m_ConVarQueries.begin(); iter != m_ConVarQueries.end();)
|
for (iter = m_ConVarQueries.begin(); iter != m_ConVarQueries.end(); iter++)
|
||||||
{
|
{
|
||||||
ConVarQuery &query = (*iter);
|
ConVarQuery &query = (*iter);
|
||||||
if (query.pCallback->GetParentRuntime() == pRuntime)
|
if (query.pCallback->GetParentRuntime() == plugin->GetRuntime())
|
||||||
{
|
{
|
||||||
iter = m_ConVarQueries.erase(iter);
|
m_ConVarQueries.erase(iter);
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
++iter;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConVarManager::OnClientDisconnected(int client)
|
|
||||||
{
|
|
||||||
/* Remove convar queries for this client that haven't returned results yet */
|
|
||||||
for (List<ConVarQuery>::iterator iter = m_ConVarQueries.begin(); iter != m_ConVarQueries.end();)
|
|
||||||
{
|
|
||||||
ConVarQuery &query = (*iter);
|
|
||||||
if (query.client == client)
|
|
||||||
{
|
|
||||||
iter = m_ConVarQueries.erase(iter);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
++iter;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -356,7 +333,7 @@ void ConVarManager::OnRootConsoleCommand(const char *cmdname, const CCommand &co
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Get plugin object */
|
/* Get plugin object */
|
||||||
IPlugin *plugin = scripts->FindPluginByConsoleArg(arg);
|
CPlugin *plugin = g_PluginSys.FindPluginByConsoleArg(arg);
|
||||||
|
|
||||||
if (!plugin)
|
if (!plugin)
|
||||||
{
|
{
|
||||||
@@ -437,7 +414,7 @@ Handle_t ConVarManager::CreateConVar(IPluginContext *pContext, const char *name,
|
|||||||
pInfo->pVar = pConVar;
|
pInfo->pVar = pConVar;
|
||||||
|
|
||||||
/* If we don't, then create a new handle from the convar */
|
/* If we don't, then create a new handle from the convar */
|
||||||
hndl = handlesys->CreateHandle(m_ConVarType, pInfo, NULL, g_pCoreIdent, NULL);
|
hndl = g_HandleSys.CreateHandle(m_ConVarType, pInfo, NULL, g_pCoreIdent, NULL);
|
||||||
if (hndl == BAD_HANDLE)
|
if (hndl == BAD_HANDLE)
|
||||||
{
|
{
|
||||||
delete pInfo;
|
delete pInfo;
|
||||||
@@ -468,7 +445,7 @@ Handle_t ConVarManager::CreateConVar(IPluginContext *pContext, const char *name,
|
|||||||
pInfo->pChangeForward = NULL;
|
pInfo->pChangeForward = NULL;
|
||||||
|
|
||||||
/* Create a handle from the new convar */
|
/* Create a handle from the new convar */
|
||||||
hndl = handlesys->CreateHandle(m_ConVarType, pInfo, NULL, g_pCoreIdent, NULL);
|
hndl = g_HandleSys.CreateHandle(m_ConVarType, pInfo, NULL, g_pCoreIdent, NULL);
|
||||||
if (hndl == BAD_HANDLE)
|
if (hndl == BAD_HANDLE)
|
||||||
{
|
{
|
||||||
delete pInfo;
|
delete pInfo;
|
||||||
@@ -497,13 +474,7 @@ Handle_t ConVarManager::FindConVar(const char *name)
|
|||||||
ConVarInfo *pInfo;
|
ConVarInfo *pInfo;
|
||||||
Handle_t hndl;
|
Handle_t hndl;
|
||||||
|
|
||||||
/* Check convar cache to find out if we already have a handle */
|
/* Search for convar */
|
||||||
if (convar_cache_lookup(name, &pInfo))
|
|
||||||
{
|
|
||||||
return pInfo->handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Couldn't find it in cache, so search for it */
|
|
||||||
pConVar = icvar->FindVar(name);
|
pConVar = icvar->FindVar(name);
|
||||||
|
|
||||||
/* If it doesn't exist, then return an invalid handle */
|
/* If it doesn't exist, then return an invalid handle */
|
||||||
@@ -512,6 +483,12 @@ Handle_t ConVarManager::FindConVar(const char *name)
|
|||||||
return BAD_HANDLE;
|
return BAD_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* At this point, the convar exists. So, find out if we already have a handle */
|
||||||
|
if (convar_cache_lookup(name, &pInfo))
|
||||||
|
{
|
||||||
|
return pInfo->handle;
|
||||||
|
}
|
||||||
|
|
||||||
/* Create and initialize ConVarInfo structure */
|
/* Create and initialize ConVarInfo structure */
|
||||||
pInfo = new ConVarInfo();
|
pInfo = new ConVarInfo();
|
||||||
pInfo->sourceMod = false;
|
pInfo->sourceMod = false;
|
||||||
@@ -519,7 +496,7 @@ Handle_t ConVarManager::FindConVar(const char *name)
|
|||||||
pInfo->pVar = pConVar;
|
pInfo->pVar = pConVar;
|
||||||
|
|
||||||
/* If we don't have a handle, then create a new one */
|
/* If we don't have a handle, then create a new one */
|
||||||
hndl = handlesys->CreateHandle(m_ConVarType, pInfo, NULL, g_pCoreIdent, NULL);
|
hndl = g_HandleSys.CreateHandle(m_ConVarType, pInfo, NULL, g_pCoreIdent, NULL);
|
||||||
if (hndl == BAD_HANDLE)
|
if (hndl == BAD_HANDLE)
|
||||||
{
|
{
|
||||||
delete pInfo;
|
delete pInfo;
|
||||||
@@ -577,7 +554,7 @@ void ConVarManager::HookConVarChange(ConVar *pConVar, IPluginFunction *pFunction
|
|||||||
/* If forward does not exist, create it */
|
/* If forward does not exist, create it */
|
||||||
if (!pForward)
|
if (!pForward)
|
||||||
{
|
{
|
||||||
pForward = forwardsys->CreateForwardEx(NULL, ET_Ignore, 3, CONVARCHANGE_PARAMS);
|
pForward = g_Forwards.CreateForwardEx(NULL, ET_Ignore, 3, CONVARCHANGE_PARAMS);
|
||||||
pInfo->pChangeForward = pForward;
|
pInfo->pChangeForward = pForward;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -617,7 +594,7 @@ void ConVarManager::UnhookConVarChange(ConVar *pConVar, IPluginFunction *pFuncti
|
|||||||
!ConVarReentrancyGuard::IsCvarInChain(pConVar))
|
!ConVarReentrancyGuard::IsCvarInChain(pConVar))
|
||||||
{
|
{
|
||||||
/* Free this forward */
|
/* Free this forward */
|
||||||
forwardsys->ReleaseForward(pForward);
|
g_Forwards.ReleaseForward(pForward);
|
||||||
pInfo->pChangeForward = NULL;
|
pInfo->pChangeForward = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -631,28 +608,19 @@ QueryCvarCookie_t ConVarManager::QueryClientConVar(edict_t *pPlayer, const char
|
|||||||
/* Call StartQueryCvarValue() in either the IVEngineServer or IServerPluginHelpers depending on situation */
|
/* Call StartQueryCvarValue() in either the IVEngineServer or IServerPluginHelpers depending on situation */
|
||||||
if (m_bIsDLLQueryHooked)
|
if (m_bIsDLLQueryHooked)
|
||||||
{
|
{
|
||||||
#if SOURCE_ENGINE == SE_DOTA
|
|
||||||
cookie = engine->StartQueryCvarValue(CEntityIndex(IndexOfEdict(pPlayer)), name);
|
|
||||||
#else
|
|
||||||
cookie = engine->StartQueryCvarValue(pPlayer, name);
|
cookie = engine->StartQueryCvarValue(pPlayer, name);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
#if SOURCE_ENGINE != SE_DOTA
|
|
||||||
else if (m_bIsVSPQueryHooked)
|
else if (m_bIsVSPQueryHooked)
|
||||||
{
|
{
|
||||||
cookie = serverpluginhelpers->StartQueryCvarValue(pPlayer, name);
|
cookie = serverpluginhelpers->StartQueryCvarValue(pPlayer, name);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return InvalidQueryCvarCookie;
|
return InvalidQueryCvarCookie;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pCallback != NULL)
|
ConVarQuery query = {cookie, pCallback, hndl};
|
||||||
{
|
m_ConVarQueries.push_back(query);
|
||||||
ConVarQuery query = { cookie, pCallback, (cell_t) hndl, IndexOfEdict(pPlayer) };
|
|
||||||
m_ConVarQueries.push_back(query);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return cookie;
|
return cookie;
|
||||||
@@ -665,7 +633,7 @@ void ConVarManager::AddConVarToPluginList(IPluginContext *pContext, const ConVar
|
|||||||
bool inserted = false;
|
bool inserted = false;
|
||||||
const char *orig = pConVar->GetName();
|
const char *orig = pConVar->GetName();
|
||||||
|
|
||||||
IPlugin *plugin = scripts->FindPluginByContext(pContext->GetContext());
|
IPlugin *plugin = g_PluginSys.FindPluginByContext(pContext->GetContext());
|
||||||
|
|
||||||
/* Check plugin for an existing convar list */
|
/* Check plugin for an existing convar list */
|
||||||
if (!plugin->GetProperty("ConVarList", (void **)&pConVarList))
|
if (!plugin->GetProperty("ConVarList", (void **)&pConVarList))
|
||||||
@@ -750,19 +718,8 @@ bool ConVarManager::IsQueryingSupported()
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if SOURCE_ENGINE != SE_DARKMESSIAH
|
#if SOURCE_ENGINE != SE_DARKMESSIAH
|
||||||
#if SOURCE_ENGINE == SE_DOTA
|
|
||||||
void ConVarManager::OnQueryCvarValueFinished(QueryCvarCookie_t cookie, CEntityIndex player, EQueryCvarValueStatus result, const char *cvarName, const char *cvarValue)
|
|
||||||
#else
|
|
||||||
void ConVarManager::OnQueryCvarValueFinished(QueryCvarCookie_t cookie, edict_t *pPlayer, EQueryCvarValueStatus result, const char *cvarName, const char *cvarValue)
|
void ConVarManager::OnQueryCvarValueFinished(QueryCvarCookie_t cookie, edict_t *pPlayer, EQueryCvarValueStatus result, const char *cvarName, const char *cvarValue)
|
||||||
#endif // SE_DOTA
|
|
||||||
{
|
{
|
||||||
#if SOURCE_ENGINE == SE_CSGO
|
|
||||||
if (g_Players.HandleConVarQuery(cookie, pPlayer, result, cvarName, cvarValue))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
IPluginFunction *pCallback = NULL;
|
IPluginFunction *pCallback = NULL;
|
||||||
cell_t value = 0;
|
cell_t value = 0;
|
||||||
List<ConVarQuery>::iterator iter;
|
List<ConVarQuery>::iterator iter;
|
||||||
@@ -783,11 +740,7 @@ void ConVarManager::OnQueryCvarValueFinished(QueryCvarCookie_t cookie, edict_t *
|
|||||||
cell_t ret;
|
cell_t ret;
|
||||||
|
|
||||||
pCallback->PushCell(cookie);
|
pCallback->PushCell(cookie);
|
||||||
#if SOURCE_ENGINE == SE_DOTA
|
|
||||||
pCallback->PushCell(player.Get());
|
|
||||||
#else
|
|
||||||
pCallback->PushCell(IndexOfEdict(pPlayer));
|
pCallback->PushCell(IndexOfEdict(pPlayer));
|
||||||
#endif
|
|
||||||
pCallback->PushCell(result);
|
pCallback->PushCell(result);
|
||||||
pCallback->PushString(cvarName);
|
pCallback->PushString(cvarName);
|
||||||
|
|
||||||
@@ -813,7 +766,7 @@ HandleError ConVarManager::ReadConVarHandle(Handle_t hndl, ConVar **pVar)
|
|||||||
ConVarInfo *pInfo;
|
ConVarInfo *pInfo;
|
||||||
HandleError error;
|
HandleError error;
|
||||||
|
|
||||||
if ((error = handlesys->ReadHandle(hndl, m_ConVarType, NULL, (void **)&pInfo)) != HandleError_None)
|
if ((error = g_HandleSys.ReadHandle(hndl, m_ConVarType, NULL, (void **)&pInfo)) != HandleError_None)
|
||||||
{
|
{
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-17
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* vim: set ts=4 sw=4 tw=99 noet :
|
* vim: set ts=4 :
|
||||||
* =============================================================================
|
* =============================================================================
|
||||||
* SourceMod
|
* SourceMod
|
||||||
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
||||||
@@ -39,10 +39,8 @@
|
|||||||
#include <IForwardSys.h>
|
#include <IForwardSys.h>
|
||||||
#include <IHandleSys.h>
|
#include <IHandleSys.h>
|
||||||
#include <IRootConsoleMenu.h>
|
#include <IRootConsoleMenu.h>
|
||||||
#include <IPlayerHelpers.h>
|
|
||||||
#include <compat_wrappers.h>
|
#include <compat_wrappers.h>
|
||||||
#include "concmd_cleaner.h"
|
#include "concmd_cleaner.h"
|
||||||
#include "PlayerManager.h"
|
|
||||||
|
|
||||||
#if SOURCE_ENGINE == SE_DARKMESSIAH
|
#if SOURCE_ENGINE == SE_DARKMESSIAH
|
||||||
class EQueryCvarValueStatus;
|
class EQueryCvarValueStatus;
|
||||||
@@ -67,11 +65,6 @@ struct ConVarInfo
|
|||||||
IChangeableForward *pChangeForward; /**< Forward associated with convar */
|
IChangeableForward *pChangeForward; /**< Forward associated with convar */
|
||||||
ConVar *pVar; /**< The actual convar */
|
ConVar *pVar; /**< The actual convar */
|
||||||
List<IConVarChangeListener *> changeListeners;
|
List<IConVarChangeListener *> changeListeners;
|
||||||
|
|
||||||
static inline bool matches(const char *name, const ConVarInfo *info)
|
|
||||||
{
|
|
||||||
return strcmp(name, info->pVar->GetName()) == 0;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -82,7 +75,6 @@ struct ConVarQuery
|
|||||||
QueryCvarCookie_t cookie; /**< Cookie that identifies query */
|
QueryCvarCookie_t cookie; /**< Cookie that identifies query */
|
||||||
IPluginFunction *pCallback; /**< Function that will be called when query is finished */
|
IPluginFunction *pCallback; /**< Function that will be called when query is finished */
|
||||||
cell_t value; /**< Optional value passed to query function */
|
cell_t value; /**< Optional value passed to query function */
|
||||||
cell_t client; /**< Only used for cleaning up on client disconnection */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class ConVarManager :
|
class ConVarManager :
|
||||||
@@ -90,8 +82,7 @@ class ConVarManager :
|
|||||||
public IHandleTypeDispatch,
|
public IHandleTypeDispatch,
|
||||||
public IPluginsListener,
|
public IPluginsListener,
|
||||||
public IRootConsoleCommand,
|
public IRootConsoleCommand,
|
||||||
public IConCommandTracker,
|
public IConCommandTracker
|
||||||
public IClientListener
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ConVarManager();
|
ConVarManager();
|
||||||
@@ -110,8 +101,6 @@ public: //IRootConsoleCommand
|
|||||||
void OnRootConsoleCommand(const char *cmdname, const CCommand &command);
|
void OnRootConsoleCommand(const char *cmdname, const CCommand &command);
|
||||||
public: //IConCommandTracker
|
public: //IConCommandTracker
|
||||||
void OnUnlinkConCommandBase(ConCommandBase *pBase, const char *name, bool is_read_safe);
|
void OnUnlinkConCommandBase(ConCommandBase *pBase, const char *name, bool is_read_safe);
|
||||||
public: //IClientListener
|
|
||||||
void OnClientDisconnected(int client);
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Create a convar and return a handle to it.
|
* Create a convar and return a handle to it.
|
||||||
@@ -165,10 +154,7 @@ private:
|
|||||||
/**
|
/**
|
||||||
* Callback for when StartQueryCvarValue() has finished.
|
* Callback for when StartQueryCvarValue() has finished.
|
||||||
*/
|
*/
|
||||||
#if SOURCE_ENGINE == SE_DOTA
|
#if SOURCE_ENGINE != SE_DARKMESSIAH
|
||||||
void OnQueryCvarValueFinished(QueryCvarCookie_t cookie, CEntityIndex player, EQueryCvarValueStatus result,
|
|
||||||
const char *cvarName, const char *cvarValue);
|
|
||||||
#elif SOURCE_ENGINE != SE_DARKMESSIAH
|
|
||||||
void OnQueryCvarValueFinished(QueryCvarCookie_t cookie, edict_t *pPlayer, EQueryCvarValueStatus result,
|
void OnQueryCvarValueFinished(QueryCvarCookie_t cookie, edict_t *pPlayer, EQueryCvarValueStatus result,
|
||||||
const char *cvarName, const char *cvarValue);
|
const char *cvarName, const char *cvarValue);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+43
-35
@@ -49,8 +49,7 @@
|
|||||||
#include "ConCmdManager.h"
|
#include "ConCmdManager.h"
|
||||||
#include "HalfLife2.h"
|
#include "HalfLife2.h"
|
||||||
#include "ConCommandBaseIterator.h"
|
#include "ConCommandBaseIterator.h"
|
||||||
#include "logic_bridge.h"
|
#include "ShareSys.h"
|
||||||
#include <am-utility.h>
|
|
||||||
|
|
||||||
#if defined PLATFORM_POSIX
|
#if defined PLATFORM_POSIX
|
||||||
# include <dlfcn.h>
|
# include <dlfcn.h>
|
||||||
@@ -60,9 +59,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if SH_IMPL_VERSION >= 5
|
#if SH_IMPL_VERSION >= 5
|
||||||
# if SOURCE_ENGINE == SE_DOTA
|
# if SOURCE_ENGINE >= SE_ORANGEBOX
|
||||||
SH_DECL_EXTERN2_void(ConCommand, Dispatch, SH_NOATTRIB, false, const CCommandContext &, const CCommand &);
|
|
||||||
# elif SOURCE_ENGINE >= SE_ORANGEBOX
|
|
||||||
SH_DECL_EXTERN1_void(ConCommand, Dispatch, SH_NOATTRIB, false, const CCommand &);
|
SH_DECL_EXTERN1_void(ConCommand, Dispatch, SH_NOATTRIB, false, const CCommand &);
|
||||||
# else
|
# else
|
||||||
SH_DECL_EXTERN0_void(ConCommand, Dispatch, SH_NOATTRIB, false);
|
SH_DECL_EXTERN0_void(ConCommand, Dispatch, SH_NOATTRIB, false);
|
||||||
@@ -134,9 +131,7 @@ class GenericCommandHooker : public IConCommandLinkListener
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# if SOURCE_ENGINE == SE_DOTA
|
# if SOURCE_ENGINE >= SE_ORANGEBOX
|
||||||
void Dispatch(const CCommandContext &context, const CCommand& args)
|
|
||||||
# elif SOURCE_ENGINE >= SE_ORANGEBOX
|
|
||||||
void Dispatch(const CCommand& args)
|
void Dispatch(const CCommand& args)
|
||||||
# else
|
# else
|
||||||
void Dispatch()
|
void Dispatch()
|
||||||
@@ -579,21 +574,23 @@ ConsoleDetours::ConsoleDetours() : status(FeatureStatus_Unknown)
|
|||||||
|
|
||||||
void ConsoleDetours::OnSourceModAllInitialized()
|
void ConsoleDetours::OnSourceModAllInitialized()
|
||||||
{
|
{
|
||||||
m_pForward = forwardsys->CreateForwardEx("OnAnyCommand", ET_Hook, 3, NULL, Param_Cell,
|
m_pForward = g_Forwards.CreateForwardEx("OnAnyCommand", ET_Hook, 3, NULL, Param_Cell,
|
||||||
Param_String, Param_Cell);
|
Param_String, Param_Cell);
|
||||||
sharesys->AddCapabilityProvider(NULL, this, FEATURECAP_COMMANDLISTENER);
|
g_ShareSys.AddCapabilityProvider(NULL, this, FEATURECAP_COMMANDLISTENER);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConsoleDetours::OnSourceModShutdown()
|
void ConsoleDetours::OnSourceModShutdown()
|
||||||
{
|
{
|
||||||
for (StringHashMap<IChangeableForward *>::iterator iter = m_Listeners.iter();
|
List<Listener*>::iterator iter = m_Listeners.begin();
|
||||||
!iter.empty();
|
while (iter != m_Listeners.end())
|
||||||
iter.next())
|
|
||||||
{
|
{
|
||||||
forwardsys->ReleaseForward(iter->value);
|
Listener *listener = (*iter);
|
||||||
|
g_Forwards.ReleaseForward(listener->forward);
|
||||||
|
delete listener;
|
||||||
|
iter = m_Listeners.erase(iter);
|
||||||
}
|
}
|
||||||
|
|
||||||
forwardsys->ReleaseForward(m_pForward);
|
g_Forwards.ReleaseForward(m_pForward);
|
||||||
s_GenericHooker.Disable();
|
s_GenericHooker.Disable();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -622,15 +619,22 @@ bool ConsoleDetours::AddListener(IPluginFunction *fun, const char *command)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ke::AutoArray<char> str(UTIL_ToLowerCase(command));
|
const char *str = UTIL_ToLowerCase(command);
|
||||||
IChangeableForward *forward;
|
Listener *listener;
|
||||||
if (!m_Listeners.retrieve(str, &forward))
|
Listener **plistener = m_CmdLookup.retrieve(str);
|
||||||
|
if (plistener == NULL)
|
||||||
{
|
{
|
||||||
forward = forwardsys->CreateForwardEx(NULL, ET_Hook, 3, NULL, Param_Cell,
|
listener = new Listener;
|
||||||
Param_String, Param_Cell);
|
listener->forward = g_Forwards.CreateForwardEx(NULL, ET_Hook, 3, NULL, Param_Cell,
|
||||||
m_Listeners.insert(str, forward);
|
Param_String, Param_Cell);
|
||||||
|
m_CmdLookup.insert(str, listener);
|
||||||
}
|
}
|
||||||
forward->AddFunction(fun);
|
else
|
||||||
|
{
|
||||||
|
listener = *plistener;
|
||||||
|
}
|
||||||
|
listener->forward->AddFunction(fun);
|
||||||
|
delete [] str;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -644,11 +648,14 @@ bool ConsoleDetours::RemoveListener(IPluginFunction *fun, const char *command)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ke::AutoArray<char> str(UTIL_ToLowerCase(command));
|
const char *str = UTIL_ToLowerCase(command);
|
||||||
IChangeableForward *forward;
|
Listener *listener;
|
||||||
if (!m_Listeners.retrieve(str, &forward))
|
Listener **plistener = m_CmdLookup.retrieve(str);
|
||||||
|
delete [] str;
|
||||||
|
if (plistener == NULL)
|
||||||
return false;
|
return false;
|
||||||
return forward->RemoveFunction(fun);
|
listener = *plistener;
|
||||||
|
return listener->forward->RemoveFunction(fun);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -684,17 +691,18 @@ cell_t ConsoleDetours::InternalDispatch(int client, const CCommand& args)
|
|||||||
if (result >= Pl_Handled)
|
if (result >= Pl_Handled)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
IChangeableForward *forward;
|
Listener **plistener = m_CmdLookup.retrieve(name);
|
||||||
if (!m_Listeners.retrieve(name, &forward))
|
if (plistener == NULL)
|
||||||
return result;
|
return result;
|
||||||
if (forward->GetFunctionCount() == 0)
|
Listener *listener = *plistener;
|
||||||
|
if (listener->forward->GetFunctionCount() == 0)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
cell_t result2 = Pl_Continue;
|
cell_t result2 = Pl_Continue;
|
||||||
forward->PushCell(client);
|
listener->forward->PushCell(client);
|
||||||
forward->PushString(name);
|
listener->forward->PushString(name);
|
||||||
forward->PushCell(args.ArgC() - 1);
|
listener->forward->PushCell(args.ArgC() - 1);
|
||||||
forward->Execute(&result2, NULL);
|
listener->forward->Execute(&result2, NULL);
|
||||||
|
|
||||||
if (result2 > result)
|
if (result2 > result)
|
||||||
result = result2;
|
result = result2;
|
||||||
@@ -723,10 +731,10 @@ cell_t ConsoleDetours::Dispatch(ConCommand *pBase)
|
|||||||
/* See bug 4020 - we can't optimize this because looking at the vtable
|
/* See bug 4020 - we can't optimize this because looking at the vtable
|
||||||
* is probably more expensive, since there's no SH_GET_ORIG_VFNPTR_ENTRY.
|
* is probably more expensive, since there's no SH_GET_ORIG_VFNPTR_ENTRY.
|
||||||
*/
|
*/
|
||||||
SH_ADD_HOOK(ConCommand, Dispatch, pBase, SH_STATIC(DummyHook), false);
|
SH_ADD_HOOK_STATICFUNC(ConCommand, Dispatch, pBase, DummyHook, false);
|
||||||
dummy_hook_set = true;
|
dummy_hook_set = true;
|
||||||
pBase->Dispatch();
|
pBase->Dispatch();
|
||||||
SH_REMOVE_HOOK(ConCommand, Dispatch, pBase, SH_STATIC(DummyHook), false);
|
SH_REMOVE_HOOK_STATICFUNC(ConCommand, Dispatch, pBase, DummyHook, false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -33,8 +33,8 @@
|
|||||||
|
|
||||||
#include "sm_globals.h"
|
#include "sm_globals.h"
|
||||||
#include "sourcemm_api.h"
|
#include "sourcemm_api.h"
|
||||||
#include <IForwardSys.h>
|
#include "ForwardSys.h"
|
||||||
#include <sm_stringhashmap.h>
|
#include <sm_trie_tpl.h>
|
||||||
|
|
||||||
class ConsoleDetours :
|
class ConsoleDetours :
|
||||||
public SMGlobalClass,
|
public SMGlobalClass,
|
||||||
@@ -43,6 +43,10 @@ class ConsoleDetours :
|
|||||||
friend class PlayerManager;
|
friend class PlayerManager;
|
||||||
friend class GenericCommandHooker;
|
friend class GenericCommandHooker;
|
||||||
|
|
||||||
|
struct Listener
|
||||||
|
{
|
||||||
|
IChangeableForward *forward;
|
||||||
|
};
|
||||||
public:
|
public:
|
||||||
ConsoleDetours();
|
ConsoleDetours();
|
||||||
public: //SMGlobalClass
|
public: //SMGlobalClass
|
||||||
@@ -69,7 +73,8 @@ public:
|
|||||||
private:
|
private:
|
||||||
FeatureStatus status;
|
FeatureStatus status;
|
||||||
IChangeableForward *m_pForward;
|
IChangeableForward *m_pForward;
|
||||||
StringHashMap<IChangeableForward *> m_Listeners;
|
KTrie<Listener*> m_CmdLookup;
|
||||||
|
List<Listener*> m_Listeners;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern ConsoleDetours g_ConsoleDetours;
|
extern ConsoleDetours g_ConsoleDetours;
|
||||||
|
|||||||
+34
-34
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* vim: set ts=4 sw=4 tw=99 noet :
|
* vim: set ts=4 :
|
||||||
* =============================================================================
|
* =============================================================================
|
||||||
* SourceMod
|
* SourceMod
|
||||||
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
||||||
@@ -34,12 +34,13 @@
|
|||||||
#include "sourcemod.h"
|
#include "sourcemod.h"
|
||||||
#include "sourcemm_api.h"
|
#include "sourcemm_api.h"
|
||||||
#include "sm_srvcmds.h"
|
#include "sm_srvcmds.h"
|
||||||
|
#include <sourcemod_version.h>
|
||||||
#include "sm_stringutil.h"
|
#include "sm_stringutil.h"
|
||||||
#include "LibrarySys.h"
|
#include "LibrarySys.h"
|
||||||
#include "Logger.h"
|
#include "Logger.h"
|
||||||
|
#include "PluginSys.h"
|
||||||
|
#include "ForwardSys.h"
|
||||||
#include "frame_hooks.h"
|
#include "frame_hooks.h"
|
||||||
#include "logic_bridge.h"
|
|
||||||
#include <sourcemod_version.h>
|
|
||||||
|
|
||||||
#ifdef PLATFORM_WINDOWS
|
#ifdef PLATFORM_WINDOWS
|
||||||
ConVar sm_corecfgfile("sm_corecfgfile", "addons\\sourcemod\\configs\\core.cfg", 0, "SourceMod core configuration file");
|
ConVar sm_corecfgfile("sm_corecfgfile", "addons\\sourcemod\\configs\\core.cfg", 0, "SourceMod core configuration file");
|
||||||
@@ -60,10 +61,7 @@ ConVar *g_ServerCfgFile = NULL;
|
|||||||
|
|
||||||
void CheckAndFinalizeConfigs();
|
void CheckAndFinalizeConfigs();
|
||||||
|
|
||||||
#if SOURCE_ENGINE == SE_DOTA
|
#if SOURCE_ENGINE >= SE_ORANGEBOX
|
||||||
SH_DECL_EXTERN2_void(ConCommand, Dispatch, SH_NOATTRIB, false, const CCommandContext &, const CCommand &);
|
|
||||||
void Hook_ExecDispatchPre(const CCommandContext &context, const CCommand &cmd)
|
|
||||||
#elif SOURCE_ENGINE >= SE_ORANGEBOX
|
|
||||||
SH_DECL_EXTERN1_void(ConCommand, Dispatch, SH_NOATTRIB, false, const CCommand &);
|
SH_DECL_EXTERN1_void(ConCommand, Dispatch, SH_NOATTRIB, false, const CCommand &);
|
||||||
void Hook_ExecDispatchPre(const CCommand &cmd)
|
void Hook_ExecDispatchPre(const CCommand &cmd)
|
||||||
#elif SOURCE_ENGINE == SE_DARKMESSIAH
|
#elif SOURCE_ENGINE == SE_DARKMESSIAH
|
||||||
@@ -91,9 +89,7 @@ void Hook_ExecDispatchPre()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if SOURCE_ENGINE == SE_DOTA
|
#if SOURCE_ENGINE >= SE_ORANGEBOX
|
||||||
void Hook_ExecDispatchPost(const CCommandContext &context, const CCommand &cmd)
|
|
||||||
#elif SOURCE_ENGINE >= SE_ORANGEBOX
|
|
||||||
void Hook_ExecDispatchPost(const CCommand &cmd)
|
void Hook_ExecDispatchPost(const CCommand &cmd)
|
||||||
#else
|
#else
|
||||||
void Hook_ExecDispatchPost()
|
void Hook_ExecDispatchPost()
|
||||||
@@ -118,12 +114,12 @@ void CheckAndFinalizeConfigs()
|
|||||||
void CoreConfig::OnSourceModAllInitialized()
|
void CoreConfig::OnSourceModAllInitialized()
|
||||||
{
|
{
|
||||||
g_RootMenu.AddRootConsoleCommand("config", "Set core configuration options", this);
|
g_RootMenu.AddRootConsoleCommand("config", "Set core configuration options", this);
|
||||||
g_pOnServerCfg = forwardsys->CreateForward("OnServerCfg", ET_Ignore, 0, NULL);
|
g_pOnServerCfg = g_Forwards.CreateForward("OnServerCfg", ET_Ignore, 0, NULL);
|
||||||
g_pOnConfigsExecuted = forwardsys->CreateForward("OnConfigsExecuted", ET_Ignore, 0, NULL);
|
g_pOnConfigsExecuted = g_Forwards.CreateForward("OnConfigsExecuted", ET_Ignore, 0, NULL);
|
||||||
g_pOnAutoConfigsBuffered = forwardsys->CreateForward("OnAutoConfigsBuffered", ET_Ignore, 0, NULL);
|
g_pOnAutoConfigsBuffered = g_Forwards.CreateForward("OnAutoConfigsBuffered", ET_Ignore, 0, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
CoreConfig::CoreConfig()
|
CoreConfig::CoreConfig() : m_Strings(512)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -134,14 +130,14 @@ CoreConfig::~CoreConfig()
|
|||||||
void CoreConfig::OnSourceModShutdown()
|
void CoreConfig::OnSourceModShutdown()
|
||||||
{
|
{
|
||||||
g_RootMenu.RemoveRootConsoleCommand("config", this);
|
g_RootMenu.RemoveRootConsoleCommand("config", this);
|
||||||
forwardsys->ReleaseForward(g_pOnServerCfg);
|
g_Forwards.ReleaseForward(g_pOnServerCfg);
|
||||||
forwardsys->ReleaseForward(g_pOnConfigsExecuted);
|
g_Forwards.ReleaseForward(g_pOnConfigsExecuted);
|
||||||
forwardsys->ReleaseForward(g_pOnAutoConfigsBuffered);
|
g_Forwards.ReleaseForward(g_pOnAutoConfigsBuffered);
|
||||||
|
|
||||||
if (g_pExecPtr != NULL)
|
if (g_pExecPtr != NULL)
|
||||||
{
|
{
|
||||||
SH_REMOVE_HOOK(ConCommand, Dispatch, g_pExecPtr, SH_STATIC(Hook_ExecDispatchPre), false);
|
SH_REMOVE_HOOK_STATICFUNC(ConCommand, Dispatch, g_pExecPtr, Hook_ExecDispatchPre, false);
|
||||||
SH_REMOVE_HOOK(ConCommand, Dispatch, g_pExecPtr, SH_STATIC(Hook_ExecDispatchPost), true);
|
SH_REMOVE_HOOK_STATICFUNC(ConCommand, Dispatch, g_pExecPtr, Hook_ExecDispatchPost, true);
|
||||||
g_pExecPtr = NULL;
|
g_pExecPtr = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -166,8 +162,8 @@ void CoreConfig::OnSourceModLevelChange(const char *mapName)
|
|||||||
g_pExecPtr = FindCommand("exec");
|
g_pExecPtr = FindCommand("exec");
|
||||||
if (g_pExecPtr != NULL)
|
if (g_pExecPtr != NULL)
|
||||||
{
|
{
|
||||||
SH_ADD_HOOK(ConCommand, Dispatch, g_pExecPtr, SH_STATIC(Hook_ExecDispatchPre), false);
|
SH_ADD_HOOK_STATICFUNC(ConCommand, Dispatch, g_pExecPtr, Hook_ExecDispatchPre, false);
|
||||||
SH_ADD_HOOK(ConCommand, Dispatch, g_pExecPtr, SH_STATIC(Hook_ExecDispatchPost), true);
|
SH_ADD_HOOK_STATICFUNC(ConCommand, Dispatch, g_pExecPtr, Hook_ExecDispatchPost, true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -256,6 +252,7 @@ void CoreConfig::Initialize()
|
|||||||
|
|
||||||
/* Reset cached key values */
|
/* Reset cached key values */
|
||||||
m_KeyValues.clear();
|
m_KeyValues.clear();
|
||||||
|
m_Strings.Reset();
|
||||||
|
|
||||||
/* Parse config file */
|
/* Parse config file */
|
||||||
if ((err=textparsers->ParseFile_SMC(filePath, this, NULL)) != SMCError_Okay)
|
if ((err=textparsers->ParseFile_SMC(filePath, this, NULL)) != SMCError_Okay)
|
||||||
@@ -295,18 +292,19 @@ ConfigResult CoreConfig::SetConfigOption(const char *option, const char *value,
|
|||||||
pBase = pBase->m_pGlobalClassNext;
|
pBase = pBase->m_pGlobalClassNext;
|
||||||
}
|
}
|
||||||
|
|
||||||
ke::AString vstr(value);
|
m_KeyValues.replace(option, m_Strings.AddString(value));
|
||||||
m_KeyValues.replace(option, ke::Move(vstr));
|
|
||||||
|
|
||||||
return ConfigResult_Ignore;
|
return ConfigResult_Ignore;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *CoreConfig::GetCoreConfigValue(const char *key)
|
const char *CoreConfig::GetCoreConfigValue(const char *key)
|
||||||
{
|
{
|
||||||
StringHashMap<ke::AString>::Result r = m_KeyValues.find(key);
|
int *pKey = m_KeyValues.retrieve(key);
|
||||||
if (!r.found())
|
if (pKey == NULL)
|
||||||
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
return r->value.chars();
|
}
|
||||||
|
return m_Strings.GetString(*pKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SM_AreConfigsExecuted()
|
bool SM_AreConfigsExecuted()
|
||||||
@@ -323,7 +321,7 @@ inline bool IsPathSepChar(char c)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SM_ExecuteConfig(IPlugin *pl, AutoConfig *cfg, bool can_create)
|
bool SM_ExecuteConfig(CPlugin *pl, AutoConfig *cfg, bool can_create)
|
||||||
{
|
{
|
||||||
bool will_create = false;
|
bool will_create = false;
|
||||||
|
|
||||||
@@ -410,7 +408,7 @@ bool SM_ExecuteConfig(IPlugin *pl, AutoConfig *cfg, bool can_create)
|
|||||||
FILE *fp = fopen(file, "wt");
|
FILE *fp = fopen(file, "wt");
|
||||||
if (fp)
|
if (fp)
|
||||||
{
|
{
|
||||||
fprintf(fp, "// This file was auto-generated by SourceMod (v%s)\n", SOURCEMOD_VERSION);
|
fprintf(fp, "// This file was auto-generated by SourceMod (v%s)\n", SM_VERSION_STRING);
|
||||||
fprintf(fp, "// ConVars for plugin \"%s\"\n", pl->GetFilename());
|
fprintf(fp, "// ConVars for plugin \"%s\"\n", pl->GetFilename());
|
||||||
fprintf(fp, "\n\n");
|
fprintf(fp, "\n\n");
|
||||||
|
|
||||||
@@ -502,10 +500,10 @@ void SM_DoSingleExecFwds(IPluginContext *ctx)
|
|||||||
|
|
||||||
void SM_ConfigsExecuted_Plugin(unsigned int serial)
|
void SM_ConfigsExecuted_Plugin(unsigned int serial)
|
||||||
{
|
{
|
||||||
IPluginIterator *iter = scripts->GetPluginIterator();
|
IPluginIterator *iter = g_PluginSys.GetPluginIterator();
|
||||||
while (iter->MorePlugins())
|
while (iter->MorePlugins())
|
||||||
{
|
{
|
||||||
IPlugin *plugin = iter->GetPlugin();
|
CPlugin *plugin = (CPlugin *)(iter->GetPlugin());
|
||||||
if (plugin->GetSerial() == serial)
|
if (plugin->GetSerial() == serial)
|
||||||
{
|
{
|
||||||
SM_DoSingleExecFwds(plugin->GetBaseContext());
|
SM_DoSingleExecFwds(plugin->GetBaseContext());
|
||||||
@@ -518,7 +516,7 @@ void SM_ConfigsExecuted_Plugin(unsigned int serial)
|
|||||||
|
|
||||||
void SM_ExecuteForPlugin(IPluginContext *ctx)
|
void SM_ExecuteForPlugin(IPluginContext *ctx)
|
||||||
{
|
{
|
||||||
SMPlugin *plugin = scripts->FindPluginByContext(ctx->GetContext());
|
CPlugin *plugin = (CPlugin *)g_PluginSys.GetPluginByCtx(ctx->GetContext());
|
||||||
|
|
||||||
unsigned int num = plugin->GetConfigCount();
|
unsigned int num = plugin->GetConfigCount();
|
||||||
if (!num)
|
if (!num)
|
||||||
@@ -547,17 +545,19 @@ void SM_ExecuteAllConfigs()
|
|||||||
|
|
||||||
engine->ServerCommand("exec sourcemod/sourcemod.cfg\n");
|
engine->ServerCommand("exec sourcemod/sourcemod.cfg\n");
|
||||||
|
|
||||||
AutoPluginList plugins(scripts);
|
IPluginIterator *iter = g_PluginSys.GetPluginIterator();
|
||||||
for (size_t i = 0; i < plugins->size(); i++)
|
while (iter->MorePlugins())
|
||||||
{
|
{
|
||||||
SMPlugin *plugin = plugins->at(i);
|
CPlugin *plugin = (CPlugin *)(iter->GetPlugin());
|
||||||
unsigned int num = plugin->GetConfigCount();
|
unsigned int num = plugin->GetConfigCount();
|
||||||
bool can_create = true;
|
bool can_create = true;
|
||||||
for (unsigned int i=0; i<num; i++)
|
for (unsigned int i=0; i<num; i++)
|
||||||
{
|
{
|
||||||
can_create = SM_ExecuteConfig(plugin, plugin->GetConfig(i), can_create);
|
can_create = SM_ExecuteConfig(plugin, plugin->GetConfig(i), can_create);
|
||||||
}
|
}
|
||||||
|
iter->NextPlugin();
|
||||||
}
|
}
|
||||||
|
iter->Release();
|
||||||
|
|
||||||
g_bGotServerStart = true;
|
g_bGotServerStart = true;
|
||||||
CheckAndFinalizeConfigs();
|
CheckAndFinalizeConfigs();
|
||||||
|
|||||||
+5
-4
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* vim: set ts=4 sw=4 tw=99 noet :
|
* vim: set ts=4 :
|
||||||
* =============================================================================
|
* =============================================================================
|
||||||
* SourceMod
|
* SourceMod
|
||||||
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
||||||
@@ -35,8 +35,8 @@
|
|||||||
#include "sm_globals.h"
|
#include "sm_globals.h"
|
||||||
#include <ITextParsers.h>
|
#include <ITextParsers.h>
|
||||||
#include <IRootConsoleMenu.h>
|
#include <IRootConsoleMenu.h>
|
||||||
#include <am-string.h>
|
#include <sm_trie_tpl.h>
|
||||||
#include <sm_stringhashmap.h>
|
#include "sm_memtable.h"
|
||||||
|
|
||||||
using namespace SourceMod;
|
using namespace SourceMod;
|
||||||
|
|
||||||
@@ -68,7 +68,8 @@ private:
|
|||||||
*/
|
*/
|
||||||
ConfigResult SetConfigOption(const char *option, const char *value, ConfigSource, char *Error, size_t maxlength);
|
ConfigResult SetConfigOption(const char *option, const char *value, ConfigSource, char *Error, size_t maxlength);
|
||||||
private:
|
private:
|
||||||
StringHashMap<ke::AString> m_KeyValues;
|
BaseStringTable m_Strings;
|
||||||
|
KTrie<int> m_KeyValues;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern bool SM_AreConfigsExecuted();
|
extern bool SM_AreConfigsExecuted();
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* vim: set ts=4 sw=4 tw=99 noet :
|
* vim: set ts=4 :
|
||||||
* =============================================================================
|
* =============================================================================
|
||||||
* SourceMod
|
* SourceMod
|
||||||
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
||||||
@@ -30,10 +30,12 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "Database.h"
|
#include "Database.h"
|
||||||
#include "ISourceMod.h"
|
|
||||||
#include "HandleSys.h"
|
#include "HandleSys.h"
|
||||||
|
#include "ShareSys.h"
|
||||||
|
#include "sourcemod.h"
|
||||||
|
#include "sm_stringutil.h"
|
||||||
|
#include "Logger.h"
|
||||||
#include "ExtensionSys.h"
|
#include "ExtensionSys.h"
|
||||||
#include "PluginSys.h"
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <IThreader.h>
|
#include <IThreader.h>
|
||||||
|
|
||||||
@@ -45,18 +47,10 @@ DBManager g_DBMan;
|
|||||||
static bool s_OneTimeThreaderErrorMsg = false;
|
static bool s_OneTimeThreaderErrorMsg = false;
|
||||||
|
|
||||||
DBManager::DBManager()
|
DBManager::DBManager()
|
||||||
: m_Terminate(false),
|
: m_ParseLevel(0), m_ParseState(0), m_pDefault(NULL)
|
||||||
m_ParseLevel(0),
|
|
||||||
m_ParseState(0),
|
|
||||||
m_pDefault(NULL)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static void FrameHook(bool simulating)
|
|
||||||
{
|
|
||||||
g_DBMan.RunFrame();
|
|
||||||
}
|
|
||||||
|
|
||||||
void DBManager::OnSourceModAllInitialized()
|
void DBManager::OnSourceModAllInitialized()
|
||||||
{
|
{
|
||||||
HandleAccess sec;
|
HandleAccess sec;
|
||||||
@@ -70,11 +64,13 @@ void DBManager::OnSourceModAllInitialized()
|
|||||||
|
|
||||||
g_ShareSys.AddInterface(NULL, this);
|
g_ShareSys.AddInterface(NULL, this);
|
||||||
|
|
||||||
g_pSM->BuildPath(Path_SM, m_Filename, sizeof(m_Filename), "configs/databases.cfg");
|
g_SourceMod.BuildPath(Path_SM, m_Filename, sizeof(m_Filename), "configs/databases.cfg");
|
||||||
|
|
||||||
|
m_pConfigLock = g_pThreader->MakeMutex();
|
||||||
|
m_pThinkLock = g_pThreader->MakeMutex();
|
||||||
|
m_pQueueLock = g_pThreader->MakeMutex();
|
||||||
|
|
||||||
g_PluginSys.AddPluginsListener(this);
|
g_PluginSys.AddPluginsListener(this);
|
||||||
|
|
||||||
g_pSM->AddGameFrameHook(&FrameHook);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DBManager::OnSourceModLevelChange(const char *mapName)
|
void DBManager::OnSourceModLevelChange(const char *mapName)
|
||||||
@@ -86,23 +82,26 @@ void DBManager::OnSourceModLevelChange(const char *mapName)
|
|||||||
* This way the thread's search won't be searching through a
|
* This way the thread's search won't be searching through a
|
||||||
* potentially empty/corrupt list, which would be very bad.
|
* potentially empty/corrupt list, which would be very bad.
|
||||||
*/
|
*/
|
||||||
ke::AutoLock lock(&m_ConfigLock);
|
m_pConfigLock->Lock();
|
||||||
if ((err = textparsers->ParseFile_SMC(m_Filename, this, &states)) != SMCError_Okay)
|
if ((err = textparsers->ParseFile_SMC(m_Filename, this, &states)) != SMCError_Okay)
|
||||||
{
|
{
|
||||||
smcore.LogError("[SM] Detected parse error(s) in file \"%s\"", m_Filename);
|
g_Logger.LogError("[SM] Detected parse error(s) in file \"%s\"", m_Filename);
|
||||||
if (err != SMCError_Custom)
|
if (err != SMCError_Custom)
|
||||||
{
|
{
|
||||||
const char *txt = textparsers->GetSMCErrorString(err);
|
const char *txt = textparsers->GetSMCErrorString(err);
|
||||||
smcore.LogError("[SM] Line %d: %s", states.line, txt);
|
g_Logger.LogError("[SM] Line %d: %s", states.line, txt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
m_pConfigLock->Unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DBManager::OnSourceModShutdown()
|
void DBManager::OnSourceModShutdown()
|
||||||
{
|
{
|
||||||
g_pSM->RemoveGameFrameHook(&FrameHook);
|
|
||||||
KillWorkerThread();
|
KillWorkerThread();
|
||||||
g_PluginSys.RemovePluginsListener(this);
|
g_PluginSys.RemovePluginsListener(this);
|
||||||
|
m_pConfigLock->DestroyThis();
|
||||||
|
m_pThinkLock->DestroyThis();
|
||||||
|
m_pQueueLock->DestroyThis();
|
||||||
g_HandleSys.RemoveType(m_DatabaseType, g_pCoreIdent);
|
g_HandleSys.RemoveType(m_DatabaseType, g_pCoreIdent);
|
||||||
g_HandleSys.RemoveType(m_DriverType, g_pCoreIdent);
|
g_HandleSys.RemoveType(m_DriverType, g_pCoreIdent);
|
||||||
ClearConfigs();
|
ClearConfigs();
|
||||||
@@ -271,7 +270,7 @@ bool DBManager::Connect(const char *name, IDBDriver **pdr, IDatabase **pdb, bool
|
|||||||
*pdr = NULL;
|
*pdr = NULL;
|
||||||
}
|
}
|
||||||
*pdb = NULL;
|
*pdb = NULL;
|
||||||
g_pSM->Format(error, maxlength, "Configuration \"%s\" not found", name);
|
UTIL_Format(error, maxlength, "Configuration \"%s\" not found", name);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -308,7 +307,7 @@ bool DBManager::Connect(const char *name, IDBDriver **pdr, IDatabase **pdb, bool
|
|||||||
}
|
}
|
||||||
*pdb = NULL;
|
*pdb = NULL;
|
||||||
|
|
||||||
g_pSM->Format(error, maxlength, "Driver \"%s\" not found", dname);
|
UTIL_Format(error, maxlength, "Driver \"%s\" not found", dname);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -353,12 +352,6 @@ void DBManager::RemoveDriver(IDBDriver *pDriver)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Someone unloaded the default driver? Silly.. */
|
|
||||||
if (pDriver == m_pDefault)
|
|
||||||
{
|
|
||||||
m_pDefault = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Now that the driver is gone, we have to test the think queue.
|
/* Now that the driver is gone, we have to test the think queue.
|
||||||
* Whatever happens therein is up to the db op!
|
* Whatever happens therein is up to the db op!
|
||||||
*/
|
*/
|
||||||
@@ -490,7 +483,7 @@ IDBDriver *DBManager::FindOrLoadDriver(const char *name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
char filename[PLATFORM_MAX_PATH];
|
char filename[PLATFORM_MAX_PATH];
|
||||||
g_pSM->Format(filename, sizeof(filename), "dbi.%s.ext", name);
|
UTIL_Format(filename, sizeof(filename), "dbi.%s.ext", name);
|
||||||
|
|
||||||
IExtension *pExt = g_Extensions.LoadAutoExtension(filename);
|
IExtension *pExt = g_Extensions.LoadAutoExtension(filename);
|
||||||
if (!pExt || !pExt->IsLoaded() || m_drivers.size() <= last_size)
|
if (!pExt || !pExt->IsLoaded() || m_drivers.size() <= last_size)
|
||||||
@@ -511,17 +504,12 @@ IDBDriver *DBManager::FindOrLoadDriver(const char *name)
|
|||||||
|
|
||||||
void DBManager::KillWorkerThread()
|
void DBManager::KillWorkerThread()
|
||||||
{
|
{
|
||||||
if (m_Worker)
|
if (m_pWorker)
|
||||||
{
|
{
|
||||||
{
|
m_pWorker->Stop(false);
|
||||||
ke::AutoLock lock(&m_QueueEvent);
|
g_pThreader->DestroyWorker(m_pWorker);
|
||||||
m_Terminate = true;
|
m_pWorker = NULL;
|
||||||
m_QueueEvent.Notify();
|
|
||||||
}
|
|
||||||
m_Worker->Join();
|
|
||||||
m_Worker = NULL;
|
|
||||||
s_OneTimeThreaderErrorMsg = false;
|
s_OneTimeThreaderErrorMsg = false;
|
||||||
m_Terminate = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -534,106 +522,99 @@ bool DBManager::AddToThreadQueue(IDBThreadOperation *op, PrioQueueLevel prio)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_Worker)
|
if (!m_pWorker)
|
||||||
{
|
{
|
||||||
m_Worker = new ke::Thread(this, "SM SQL Worker");
|
m_pWorker = g_pThreader->MakeWorker(this, true);
|
||||||
if (!m_Worker->Succeeded())
|
if (!m_pWorker)
|
||||||
{
|
{
|
||||||
if (!s_OneTimeThreaderErrorMsg)
|
if (!s_OneTimeThreaderErrorMsg)
|
||||||
{
|
{
|
||||||
smcore.LogError("[SM] Unable to create db threader (error unknown)");
|
g_Logger.LogError("[SM] Unable to create db threader (error unknown)");
|
||||||
s_OneTimeThreaderErrorMsg = true;
|
s_OneTimeThreaderErrorMsg = true;
|
||||||
}
|
}
|
||||||
m_Worker = NULL;
|
return false;
|
||||||
|
}
|
||||||
|
if (!m_pWorker->Start())
|
||||||
|
{
|
||||||
|
if (!s_OneTimeThreaderErrorMsg)
|
||||||
|
{
|
||||||
|
g_Logger.LogError("[SM] Unable to start db threader (error unknown)");
|
||||||
|
s_OneTimeThreaderErrorMsg = true;
|
||||||
|
}
|
||||||
|
g_pThreader->DestroyWorker(m_pWorker);
|
||||||
|
m_pWorker = NULL;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add to the queue */
|
/* Add to the queue */
|
||||||
{
|
{
|
||||||
ke::AutoLock lock(&m_QueueEvent);
|
m_pQueueLock->Lock();
|
||||||
Queue<IDBThreadOperation *> &queue = m_OpQueue.GetQueue(prio);
|
Queue<IDBThreadOperation *> &queue = m_OpQueue.GetQueue(prio);
|
||||||
queue.push(op);
|
queue.push(op);
|
||||||
m_QueueEvent.Notify();
|
m_pQueueLock->Unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Make the thread */
|
||||||
|
m_pWorker->MakeThread(this);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DBManager::Run()
|
void DBManager::OnWorkerStart(IThreadWorker *pWorker)
|
||||||
{
|
{
|
||||||
// Initialize DB threadsafety.
|
m_drSafety.clear();
|
||||||
for (size_t i=0; i < m_drivers.size(); i++)
|
for (size_t i=0; i<m_drivers.size(); i++)
|
||||||
{
|
{
|
||||||
if (m_drivers[i]->IsThreadSafe())
|
if (m_drivers[i]->IsThreadSafe())
|
||||||
|
{
|
||||||
m_drSafety.push_back(m_drivers[i]->InitializeThreadSafety());
|
m_drSafety.push_back(m_drivers[i]->InitializeThreadSafety());
|
||||||
else
|
} else {
|
||||||
m_drSafety.push_back(false);
|
m_drSafety.push_back(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Run actual worker thread logic.
|
void DBManager::OnWorkerStop(IThreadWorker *pWorker)
|
||||||
ThreadMain();
|
{
|
||||||
|
|
||||||
// Shutdown DB threadsafety.
|
|
||||||
for (size_t i=0; i<m_drivers.size(); i++)
|
for (size_t i=0; i<m_drivers.size(); i++)
|
||||||
{
|
{
|
||||||
if (m_drSafety[i])
|
if (m_drSafety[i])
|
||||||
|
{
|
||||||
m_drivers[i]->ShutdownThreadSafety();
|
m_drivers[i]->ShutdownThreadSafety();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
m_drSafety.clear();
|
m_drSafety.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DBManager::ThreadMain()
|
void DBManager::RunThread(IThreadHandle *pThread)
|
||||||
{
|
{
|
||||||
ke::AutoLock lock(&m_QueueEvent);
|
IDBThreadOperation *op = NULL;
|
||||||
|
|
||||||
while (true) {
|
/* Get something from the queue */
|
||||||
// The lock has been acquired. Grab everything we can out of the
|
{
|
||||||
// queue. Since we want to flush the queue even if we're terminated,
|
m_pQueueLock->Lock();
|
||||||
// we process all operations we can before checking to terminate.
|
Queue<IDBThreadOperation *> &queue = m_OpQueue.GetLikelyQueue();
|
||||||
// There's no risk of starvation since the main thread blocks on us
|
if (!queue.empty())
|
||||||
// terminating.
|
|
||||||
while (true)
|
|
||||||
{
|
{
|
||||||
Queue<IDBThreadOperation *> &queue = m_OpQueue.GetLikelyQueue();
|
op = queue.first();
|
||||||
if (queue.empty())
|
|
||||||
break;
|
|
||||||
|
|
||||||
IDBThreadOperation *op = queue.first();
|
|
||||||
queue.pop();
|
queue.pop();
|
||||||
|
|
||||||
// Unlock the queue when we run the query, so the main thread can
|
|
||||||
// keep pumping events. We re-acquire the lock to check for more
|
|
||||||
// items. It's okay if we terminate while unlocked; the main
|
|
||||||
// thread would be blocked and we'd need to flush the queue
|
|
||||||
// anyway, so after we've depleted the queue here, we'll just
|
|
||||||
// reach the terminate at the top of the loop.
|
|
||||||
{
|
|
||||||
ke::AutoUnlock unlock(&m_QueueEvent);
|
|
||||||
op->RunThreadPart();
|
|
||||||
|
|
||||||
ke::AutoLock lock(&m_ThinkLock);
|
|
||||||
m_ThinkQueue.push(op);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (!m_Terminate)
|
|
||||||
{
|
|
||||||
ke::AutoUnlock unlock(&m_QueueEvent);
|
|
||||||
#ifdef _WIN32
|
|
||||||
Sleep(20);
|
|
||||||
#else
|
|
||||||
usleep(20000);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
m_pQueueLock->Unlock();
|
||||||
if (m_Terminate)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Release the lock and wait for a signal.
|
|
||||||
m_QueueEvent.Wait();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* whoa. hi. did we get something? we should have. */
|
||||||
|
if (!op)
|
||||||
|
{
|
||||||
|
/* wtf? */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
op->RunThreadPart();
|
||||||
|
|
||||||
|
m_pThinkLock->Lock();
|
||||||
|
m_ThinkQueue.push(op);
|
||||||
|
m_pThinkLock->Unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DBManager::RunFrame()
|
void DBManager::RunFrame()
|
||||||
@@ -645,16 +626,19 @@ void DBManager::RunFrame()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Dump one thing per-frame so the server stays sane. */
|
/* Dump one thing per-frame so the server stays sane. */
|
||||||
IDBThreadOperation *op;
|
m_pThinkLock->Lock();
|
||||||
{
|
IDBThreadOperation *op = m_ThinkQueue.first();
|
||||||
ke::AutoLock lock(&m_ThinkLock);
|
m_ThinkQueue.pop();
|
||||||
op = m_ThinkQueue.first();
|
m_pThinkLock->Unlock();
|
||||||
m_ThinkQueue.pop();
|
|
||||||
}
|
|
||||||
op->RunThinkPart();
|
op->RunThinkPart();
|
||||||
op->Destroy();
|
op->Destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DBManager::OnTerminate(IThreadHandle *pThread, bool cancel)
|
||||||
|
{
|
||||||
|
/* Do nothing */
|
||||||
|
}
|
||||||
|
|
||||||
void DBManager::OnSourceModIdentityDropped(IdentityToken_t *pToken)
|
void DBManager::OnSourceModIdentityDropped(IdentityToken_t *pToken)
|
||||||
{
|
{
|
||||||
s_pAddBlock = pToken;
|
s_pAddBlock = pToken;
|
||||||
@@ -730,12 +714,12 @@ void DBManager::OnPluginUnloaded(IPlugin *plugin)
|
|||||||
|
|
||||||
void DBManager::LockConfig()
|
void DBManager::LockConfig()
|
||||||
{
|
{
|
||||||
m_ConfigLock.Lock();
|
m_pConfigLock->Lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DBManager::UnlockConfig()
|
void DBManager::UnlockConfig()
|
||||||
{
|
{
|
||||||
m_ConfigLock.Unlock();
|
m_pConfigLock->Unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *DBManager::GetDefaultDriverName()
|
const char *DBManager::GetDefaultDriverName()
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* vim: set ts=4 sw=4 tw=99 noet :
|
* vim: set ts=4 :
|
||||||
* =============================================================================
|
* =============================================================================
|
||||||
* SourceMod
|
* SourceMod
|
||||||
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
||||||
@@ -33,15 +33,15 @@
|
|||||||
#define _INCLUDE_DATABASE_MANAGER_H_
|
#define _INCLUDE_DATABASE_MANAGER_H_
|
||||||
|
|
||||||
#include <IDBDriver.h>
|
#include <IDBDriver.h>
|
||||||
#include "common_logic.h"
|
#include "sm_globals.h"
|
||||||
#include <sh_vector.h>
|
#include <sh_vector.h>
|
||||||
#include <sh_string.h>
|
#include <sh_string.h>
|
||||||
#include <sh_list.h>
|
#include <sh_list.h>
|
||||||
#include <ITextParsers.h>
|
#include <ITextParsers.h>
|
||||||
|
#include "sm_memtable.h"
|
||||||
#include <IThreader.h>
|
#include <IThreader.h>
|
||||||
#include <IPluginSys.h>
|
|
||||||
#include <am-thread-utils.h>
|
|
||||||
#include "sm_simple_prioqueue.h"
|
#include "sm_simple_prioqueue.h"
|
||||||
|
#include "PluginSys.h"
|
||||||
|
|
||||||
using namespace SourceHook;
|
using namespace SourceHook;
|
||||||
|
|
||||||
@@ -65,8 +65,9 @@ class DBManager :
|
|||||||
public SMGlobalClass,
|
public SMGlobalClass,
|
||||||
public IHandleTypeDispatch,
|
public IHandleTypeDispatch,
|
||||||
public ITextListener_SMC,
|
public ITextListener_SMC,
|
||||||
public IPluginsListener,
|
public IThread,
|
||||||
public ke::IRunnable
|
public IThreadWorkerCallbacks,
|
||||||
|
public IPluginsListener
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DBManager();
|
DBManager();
|
||||||
@@ -97,9 +98,12 @@ public: //ITextListener_SMC
|
|||||||
SMCResult ReadSMC_KeyValue(const SMCStates *states, const char *key, const char *value);
|
SMCResult ReadSMC_KeyValue(const SMCStates *states, const char *key, const char *value);
|
||||||
SMCResult ReadSMC_LeavingSection(const SMCStates *states);
|
SMCResult ReadSMC_LeavingSection(const SMCStates *states);
|
||||||
void ReadSMC_ParseEnd(bool halted, bool failed);
|
void ReadSMC_ParseEnd(bool halted, bool failed);
|
||||||
public: //ke::IRunnable
|
public: //IThread
|
||||||
void Run();
|
void RunThread(IThreadHandle *pThread);
|
||||||
void ThreadMain();
|
void OnTerminate(IThreadHandle *pThread, bool cancel);
|
||||||
|
public: //IThreadWorkerCallbacks
|
||||||
|
void OnWorkerStart(IThreadWorker *pWorker);
|
||||||
|
void OnWorkerStop(IThreadWorker *pWorker);
|
||||||
public: //IPluginsListener
|
public: //IPluginsListener
|
||||||
void OnPluginUnloaded(IPlugin *plugin);
|
void OnPluginUnloaded(IPlugin *plugin);
|
||||||
public:
|
public:
|
||||||
@@ -125,11 +129,10 @@ private:
|
|||||||
PrioQueue<IDBThreadOperation *> m_OpQueue;
|
PrioQueue<IDBThreadOperation *> m_OpQueue;
|
||||||
Queue<IDBThreadOperation *> m_ThinkQueue;
|
Queue<IDBThreadOperation *> m_ThinkQueue;
|
||||||
CVector<bool> m_drSafety; /* which drivers are safe? */
|
CVector<bool> m_drSafety; /* which drivers are safe? */
|
||||||
ke::AutoPtr<ke::Thread> m_Worker;
|
IThreadWorker *m_pWorker; /* Worker thread object */
|
||||||
ke::ConditionVariable m_QueueEvent;
|
IMutex *m_pConfigLock; /* Configuration lock */
|
||||||
ke::Mutex m_ConfigLock;
|
IMutex *m_pQueueLock; /* Queue safety lock */
|
||||||
ke::Mutex m_ThinkLock;
|
IMutex *m_pThinkLock; /* Think-queue lock */
|
||||||
bool m_Terminate;
|
|
||||||
|
|
||||||
List<ConfDbInfo *> m_confs;
|
List<ConfDbInfo *> m_confs;
|
||||||
HandleType_t m_DriverType;
|
HandleType_t m_DriverType;
|
||||||
@@ -29,9 +29,10 @@
|
|||||||
* Version: $Id$
|
* Version: $Id$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <IPluginSys.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include "DebugReporter.h"
|
#include "DebugReporter.h"
|
||||||
|
#include "Logger.h"
|
||||||
|
#include "PluginSys.h"
|
||||||
|
#include "sm_stringutil.h"
|
||||||
|
|
||||||
DebugReport g_DbgReporter;
|
DebugReport g_DbgReporter;
|
||||||
|
|
||||||
@@ -46,10 +47,10 @@ void DebugReport::OnDebugSpew(const char *msg, ...)
|
|||||||
char buffer[512];
|
char buffer[512];
|
||||||
|
|
||||||
va_start(ap, msg);
|
va_start(ap, msg);
|
||||||
smcore.FormatArgs(buffer, sizeof(buffer), msg, ap);
|
UTIL_FormatArgs(buffer, sizeof(buffer), msg, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
smcore.Log("[SM] %s", buffer);
|
g_Logger.LogMessage("[SM] %s", buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebugReport::GenerateError(IPluginContext *ctx, cell_t func_idx, int err, const char *message, ...)
|
void DebugReport::GenerateError(IPluginContext *ctx, cell_t func_idx, int err, const char *message, ...)
|
||||||
@@ -64,19 +65,19 @@ void DebugReport::GenerateError(IPluginContext *ctx, cell_t func_idx, int err, c
|
|||||||
void DebugReport::GenerateErrorVA(IPluginContext *ctx, cell_t func_idx, int err, const char *message, va_list ap)
|
void DebugReport::GenerateErrorVA(IPluginContext *ctx, cell_t func_idx, int err, const char *message, va_list ap)
|
||||||
{
|
{
|
||||||
char buffer[512];
|
char buffer[512];
|
||||||
smcore.FormatArgs(buffer, sizeof(buffer), message, ap);
|
UTIL_FormatArgs(buffer, sizeof(buffer), message, ap);
|
||||||
|
|
||||||
const char *plname = pluginsys->FindPluginByContext(ctx->GetContext())->GetFilename();
|
const char *plname = g_PluginSys.FindPluginByContext(ctx->GetContext())->GetFilename();
|
||||||
const char *error = g_pSourcePawn2->GetErrorString(err);
|
const char *error = g_pSourcePawn2->GetErrorString(err);
|
||||||
|
|
||||||
if (error)
|
if (error)
|
||||||
{
|
{
|
||||||
smcore.LogError("[SM] Plugin \"%s\" encountered error %d: %s", plname, err, error);
|
g_Logger.LogError("[SM] Plugin \"%s\" encountered error %d: %s", plname, err, error);
|
||||||
} else {
|
} else {
|
||||||
smcore.LogError("[SM] Plugin \"%s\" encountered unknown error %d", plname, err);
|
g_Logger.LogError("[SM] Plugin \"%s\" encountered unknown error %d", plname, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
smcore.LogError("[SM] %s", buffer);
|
g_Logger.LogError("[SM] %s", buffer);
|
||||||
|
|
||||||
if (func_idx != -1)
|
if (func_idx != -1)
|
||||||
{
|
{
|
||||||
@@ -86,7 +87,7 @@ void DebugReport::GenerateErrorVA(IPluginContext *ctx, cell_t func_idx, int err,
|
|||||||
sp_public_t *function;
|
sp_public_t *function;
|
||||||
if (ctx->GetRuntime()->GetPublicByIndex(func_idx, &function) == SP_ERROR_NONE)
|
if (ctx->GetRuntime()->GetPublicByIndex(func_idx, &function) == SP_ERROR_NONE)
|
||||||
{
|
{
|
||||||
smcore.LogError("[SM] Unable to call function \"%s\" due to above error(s).", function->name);
|
g_Logger.LogError("[SM] Unable to call function \"%s\" due to above error(s).", function->name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -98,26 +99,26 @@ void DebugReport::GenerateCodeError(IPluginContext *pContext, uint32_t code_addr
|
|||||||
char buffer[512];
|
char buffer[512];
|
||||||
|
|
||||||
va_start(ap, message);
|
va_start(ap, message);
|
||||||
smcore.FormatArgs(buffer, sizeof(buffer), message, ap);
|
UTIL_FormatArgs(buffer, sizeof(buffer), message, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
const char *plname = pluginsys->FindPluginByContext(pContext->GetContext())->GetFilename();
|
const char *plname = g_PluginSys.FindPluginByContext(pContext->GetContext())->GetFilename();
|
||||||
const char *error = g_pSourcePawn2->GetErrorString(err);
|
const char *error = g_pSourcePawn2->GetErrorString(err);
|
||||||
|
|
||||||
if (error)
|
if (error)
|
||||||
{
|
{
|
||||||
smcore.LogError("[SM] Plugin \"%s\" encountered error %d: %s", plname, err, error);
|
g_Logger.LogError("[SM] Plugin \"%s\" encountered error %d: %s", plname, err, error);
|
||||||
} else {
|
} else {
|
||||||
smcore.LogError("[SM] Plugin \"%s\" encountered unknown error %d", plname, err);
|
g_Logger.LogError("[SM] Plugin \"%s\" encountered unknown error %d", plname, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
smcore.LogError("[SM] %s", buffer);
|
g_Logger.LogError("[SM] %s", buffer);
|
||||||
|
|
||||||
IPluginDebugInfo *pDebug;
|
IPluginDebugInfo *pDebug;
|
||||||
if ((pDebug = pContext->GetRuntime()->GetDebugInfo()) == NULL)
|
if ((pDebug = pContext->GetRuntime()->GetDebugInfo()) == NULL)
|
||||||
{
|
{
|
||||||
smcore.LogError("[SM] Debug mode is not enabled for \"%s\"", plname);
|
g_Logger.LogError("[SM] Debug mode is not enabled for \"%s\"", plname);
|
||||||
smcore.LogError("[SM] To enable debug mode, edit plugin_settings.cfg, or type: sm plugins debug %d on",
|
g_Logger.LogError("[SM] To enable debug mode, edit plugin_settings.cfg, or type: sm plugins debug %d on",
|
||||||
_GetPluginIndex(pContext));
|
_GetPluginIndex(pContext));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -125,21 +126,21 @@ void DebugReport::GenerateCodeError(IPluginContext *pContext, uint32_t code_addr
|
|||||||
const char *name;
|
const char *name;
|
||||||
if (pDebug->LookupFunction(code_addr, &name) == SP_ERROR_NONE)
|
if (pDebug->LookupFunction(code_addr, &name) == SP_ERROR_NONE)
|
||||||
{
|
{
|
||||||
smcore.LogError("[SM] Unable to call function \"%s\" due to above error(s).", name);
|
g_Logger.LogError("[SM] Unable to call function \"%s\" due to above error(s).", name);
|
||||||
} else {
|
} else {
|
||||||
smcore.LogError("[SM] Unable to call function (name unknown, address \"%x\").", code_addr);
|
g_Logger.LogError("[SM] Unable to call function (name unknown, address \"%x\").", code_addr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebugReport::OnContextExecuteError(IPluginContext *ctx, IContextTrace *error)
|
void DebugReport::OnContextExecuteError(IPluginContext *ctx, IContextTrace *error)
|
||||||
{
|
{
|
||||||
const char *lastname;
|
const char *lastname;
|
||||||
const char *plname = pluginsys->FindPluginByContext(ctx->GetContext())->GetFilename();
|
const char *plname = g_PluginSys.FindPluginByContext(ctx->GetContext())->GetFilename();
|
||||||
int n_err = error->GetErrorCode();
|
int n_err = error->GetErrorCode();
|
||||||
|
|
||||||
if (n_err != SP_ERROR_NATIVE)
|
if (n_err != SP_ERROR_NATIVE)
|
||||||
{
|
{
|
||||||
smcore.LogError("[SM] Plugin encountered error %d: %s",
|
g_Logger.LogError("[SM] Plugin encountered error %d: %s",
|
||||||
n_err,
|
n_err,
|
||||||
error->GetErrorString());
|
error->GetErrorString());
|
||||||
}
|
}
|
||||||
@@ -149,26 +150,26 @@ void DebugReport::OnContextExecuteError(IPluginContext *ctx, IContextTrace *erro
|
|||||||
const char *custerr;
|
const char *custerr;
|
||||||
if ((custerr=error->GetCustomErrorString()) != NULL)
|
if ((custerr=error->GetCustomErrorString()) != NULL)
|
||||||
{
|
{
|
||||||
smcore.LogError("[SM] Native \"%s\" reported: %s", lastname, custerr);
|
g_Logger.LogError("[SM] Native \"%s\" reported: %s", lastname, custerr);
|
||||||
} else {
|
} else {
|
||||||
smcore.LogError("[SM] Native \"%s\" encountered a generic error.", lastname);
|
g_Logger.LogError("[SM] Native \"%s\" encountered a generic error.", lastname);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!error->DebugInfoAvailable())
|
if (!error->DebugInfoAvailable())
|
||||||
{
|
{
|
||||||
smcore.LogError("[SM] Debug mode is not enabled for \"%s\"", plname);
|
g_Logger.LogError("[SM] Debug mode is not enabled for \"%s\"", plname);
|
||||||
smcore.LogError("[SM] To enable debug mode, edit plugin_settings.cfg, or type: sm plugins debug %d on",
|
g_Logger.LogError("[SM] To enable debug mode, edit plugin_settings.cfg, or type: sm plugins debug %d on",
|
||||||
_GetPluginIndex(ctx));
|
_GetPluginIndex(ctx));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
CallStackInfo stk_info;
|
CallStackInfo stk_info;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
smcore.LogError("[SM] Displaying call stack trace for plugin \"%s\":", plname);
|
g_Logger.LogError("[SM] Displaying call stack trace for plugin \"%s\":", plname);
|
||||||
while (error->GetTraceInfo(&stk_info))
|
while (error->GetTraceInfo(&stk_info))
|
||||||
{
|
{
|
||||||
smcore.LogError("[SM] [%d] Line %d, %s::%s()",
|
g_Logger.LogError("[SM] [%d] Line %d, %s::%s()",
|
||||||
i++,
|
i++,
|
||||||
stk_info.line,
|
stk_info.line,
|
||||||
stk_info.filename,
|
stk_info.filename,
|
||||||
@@ -179,7 +180,7 @@ void DebugReport::OnContextExecuteError(IPluginContext *ctx, IContextTrace *erro
|
|||||||
int DebugReport::_GetPluginIndex(IPluginContext *ctx)
|
int DebugReport::_GetPluginIndex(IPluginContext *ctx)
|
||||||
{
|
{
|
||||||
int id = 1;
|
int id = 1;
|
||||||
IPluginIterator *iter = pluginsys->GetPluginIterator();
|
IPluginIterator *iter = g_PluginSys.GetPluginIterator();
|
||||||
|
|
||||||
for (; iter->MorePlugins(); iter->NextPlugin(), id++)
|
for (; iter->MorePlugins(); iter->NextPlugin(), id++)
|
||||||
{
|
{
|
||||||
@@ -195,6 +196,6 @@ int DebugReport::_GetPluginIndex(IPluginContext *ctx)
|
|||||||
|
|
||||||
/* If we don't know which plugin this is, it's one being loaded. Fake its index for now. */
|
/* If we don't know which plugin this is, it's one being loaded. Fake its index for now. */
|
||||||
|
|
||||||
return pluginsys->GetPluginCount() + 1;
|
return g_PluginSys.GetPluginCount() + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -33,7 +33,7 @@
|
|||||||
#define _INCLUDE_SOURCEMOD_CDBGREPORTER_H_
|
#define _INCLUDE_SOURCEMOD_CDBGREPORTER_H_
|
||||||
|
|
||||||
#include "sp_vm_api.h"
|
#include "sp_vm_api.h"
|
||||||
#include "common_logic.h"
|
#include "sm_globals.h"
|
||||||
|
|
||||||
class DebugReport :
|
class DebugReport :
|
||||||
public SMGlobalClass,
|
public SMGlobalClass,
|
||||||
+39
-29
@@ -30,8 +30,10 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "EventManager.h"
|
#include "EventManager.h"
|
||||||
|
#include "ForwardSys.h"
|
||||||
|
#include "HandleSys.h"
|
||||||
|
#include "PluginSys.h"
|
||||||
#include "sm_stringutil.h"
|
#include "sm_stringutil.h"
|
||||||
#include "logic_bridge.h"
|
|
||||||
|
|
||||||
EventManager g_EventManager;
|
EventManager g_EventManager;
|
||||||
|
|
||||||
@@ -56,10 +58,14 @@ public:
|
|||||||
|
|
||||||
EventManager::EventManager() : m_EventType(0)
|
EventManager::EventManager() : m_EventType(0)
|
||||||
{
|
{
|
||||||
|
/* Create an event lookup trie */
|
||||||
|
m_EventHooks = sm_trie_create();
|
||||||
}
|
}
|
||||||
|
|
||||||
EventManager::~EventManager()
|
EventManager::~EventManager()
|
||||||
{
|
{
|
||||||
|
sm_trie_destroy(m_EventHooks);
|
||||||
|
|
||||||
/* Free memory used by EventInfo structs if any */
|
/* Free memory used by EventInfo structs if any */
|
||||||
CStack<EventInfo *>::iterator iter;
|
CStack<EventInfo *>::iterator iter;
|
||||||
for (iter = m_FreeEvents.begin(); iter != m_FreeEvents.end(); iter++)
|
for (iter = m_FreeEvents.begin(); iter != m_FreeEvents.end(); iter++)
|
||||||
@@ -73,8 +79,8 @@ EventManager::~EventManager()
|
|||||||
void EventManager::OnSourceModAllInitialized()
|
void EventManager::OnSourceModAllInitialized()
|
||||||
{
|
{
|
||||||
/* Add a hook for IGameEventManager2::FireEvent() */
|
/* Add a hook for IGameEventManager2::FireEvent() */
|
||||||
SH_ADD_HOOK(IGameEventManager2, FireEvent, gameevents, SH_MEMBER(this, &EventManager::OnFireEvent), false);
|
SH_ADD_HOOK_MEMFUNC(IGameEventManager2, FireEvent, gameevents, this, &EventManager::OnFireEvent, false);
|
||||||
SH_ADD_HOOK(IGameEventManager2, FireEvent, gameevents, SH_MEMBER(this, &EventManager::OnFireEvent_Post), true);
|
SH_ADD_HOOK_MEMFUNC(IGameEventManager2, FireEvent, gameevents, this, &EventManager::OnFireEvent_Post, true);
|
||||||
|
|
||||||
HandleAccess sec;
|
HandleAccess sec;
|
||||||
|
|
||||||
@@ -84,17 +90,17 @@ void EventManager::OnSourceModAllInitialized()
|
|||||||
sec.access[HandleAccess_Clone] = HANDLE_RESTRICT_IDENTITY | HANDLE_RESTRICT_OWNER;
|
sec.access[HandleAccess_Clone] = HANDLE_RESTRICT_IDENTITY | HANDLE_RESTRICT_OWNER;
|
||||||
|
|
||||||
/* Create the 'GameEvent' handle type */
|
/* Create the 'GameEvent' handle type */
|
||||||
m_EventType = handlesys->CreateType("GameEvent", this, 0, NULL, &sec, g_pCoreIdent, NULL);
|
m_EventType = g_HandleSys.CreateType("GameEvent", this, 0, NULL, &sec, g_pCoreIdent, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EventManager::OnSourceModShutdown()
|
void EventManager::OnSourceModShutdown()
|
||||||
{
|
{
|
||||||
/* Remove hook for IGameEventManager2::FireEvent() */
|
/* Remove hook for IGameEventManager2::FireEvent() */
|
||||||
SH_REMOVE_HOOK(IGameEventManager2, FireEvent, gameevents, SH_MEMBER(this, &EventManager::OnFireEvent), false);
|
SH_REMOVE_HOOK_MEMFUNC(IGameEventManager2, FireEvent, gameevents, this, &EventManager::OnFireEvent, false);
|
||||||
SH_REMOVE_HOOK(IGameEventManager2, FireEvent, gameevents, SH_MEMBER(this, &EventManager::OnFireEvent_Post), true);
|
SH_REMOVE_HOOK_MEMFUNC(IGameEventManager2, FireEvent, gameevents, this, &EventManager::OnFireEvent_Post, true);
|
||||||
|
|
||||||
/* Remove the 'GameEvent' handle type */
|
/* Remove the 'GameEvent' handle type */
|
||||||
handlesys->RemoveType(m_EventType, g_pCoreIdent);
|
g_HandleSys.RemoveType(m_EventType, g_pCoreIdent);
|
||||||
|
|
||||||
/* Remove ourselves as listener for events */
|
/* Remove ourselves as listener for events */
|
||||||
gameevents->RemoveListener(this);
|
gameevents->RemoveListener(this);
|
||||||
@@ -132,12 +138,12 @@ void EventManager::OnPluginUnloaded(IPlugin *plugin)
|
|||||||
{
|
{
|
||||||
if (pHook->pPreHook)
|
if (pHook->pPreHook)
|
||||||
{
|
{
|
||||||
forwardsys->ReleaseForward(pHook->pPreHook);
|
g_Forwards.ReleaseForward(pHook->pPreHook);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pHook->pPostHook)
|
if (pHook->pPostHook)
|
||||||
{
|
{
|
||||||
forwardsys->ReleaseForward(pHook->pPostHook);
|
g_Forwards.ReleaseForward(pHook->pPostHook);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete pHook;
|
delete pHook;
|
||||||
@@ -155,7 +161,7 @@ void EventManager::FireGameEvent(IGameEvent *pEvent)
|
|||||||
Just need to add ourselves as a listener to make our hook on IGameEventManager2::FireEvent work */
|
Just need to add ourselves as a listener to make our hook on IGameEventManager2::FireEvent work */
|
||||||
}
|
}
|
||||||
|
|
||||||
#if SOURCE_ENGINE >= SE_LEFT4DEAD && SOURCE_ENGINE != SE_DOTA
|
#if SOURCE_ENGINE >= SE_LEFT4DEAD
|
||||||
int EventManager::GetEventDebugID()
|
int EventManager::GetEventDebugID()
|
||||||
{
|
{
|
||||||
return EVENT_DEBUG_ID_INIT;
|
return EVENT_DEBUG_ID_INIT;
|
||||||
@@ -178,10 +184,10 @@ EventHookError EventManager::HookEvent(const char *name, IPluginFunction *pFunct
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* If a hook structure does not exist... */
|
/* If a hook structure does not exist... */
|
||||||
if (!m_EventHooks.retrieve(name, &pHook))
|
if (!sm_trie_retrieve(m_EventHooks, name, (void **)&pHook))
|
||||||
{
|
{
|
||||||
EventHookList *pHookList;
|
EventHookList *pHookList;
|
||||||
IPlugin *plugin = scripts->FindPluginByContext(pFunction->GetParentContext()->GetContext());
|
IPlugin *plugin = g_PluginSys.GetPluginByCtx(pFunction->GetParentContext()->GetContext());
|
||||||
|
|
||||||
/* Check plugin for an existing EventHook list */
|
/* Check plugin for an existing EventHook list */
|
||||||
if (!plugin->GetProperty("EventHooks", (void **)&pHookList))
|
if (!plugin->GetProperty("EventHooks", (void **)&pHookList))
|
||||||
@@ -196,12 +202,12 @@ EventHookError EventManager::HookEvent(const char *name, IPluginFunction *pFunct
|
|||||||
if (mode == EventHookMode_Pre)
|
if (mode == EventHookMode_Pre)
|
||||||
{
|
{
|
||||||
/* Create forward for a pre hook */
|
/* Create forward for a pre hook */
|
||||||
pHook->pPreHook = forwardsys->CreateForwardEx(NULL, ET_Hook, 3, GAMEEVENT_PARAMS);
|
pHook->pPreHook = g_Forwards.CreateForwardEx(NULL, ET_Hook, 3, GAMEEVENT_PARAMS);
|
||||||
/* Add to forward list */
|
/* Add to forward list */
|
||||||
pHook->pPreHook->AddFunction(pFunction);
|
pHook->pPreHook->AddFunction(pFunction);
|
||||||
} else {
|
} else {
|
||||||
/* Create forward for a post hook */
|
/* Create forward for a post hook */
|
||||||
pHook->pPostHook = forwardsys->CreateForwardEx(NULL, ET_Ignore, 3, GAMEEVENT_PARAMS);
|
pHook->pPostHook = g_Forwards.CreateForwardEx(NULL, ET_Ignore, 3, GAMEEVENT_PARAMS);
|
||||||
/* Should we copy data from a pre hook to the post hook? */
|
/* Should we copy data from a pre hook to the post hook? */
|
||||||
pHook->postCopy = (mode == EventHookMode_Post);
|
pHook->postCopy = (mode == EventHookMode_Post);
|
||||||
/* Add to forward list */
|
/* Add to forward list */
|
||||||
@@ -209,14 +215,14 @@ EventHookError EventManager::HookEvent(const char *name, IPluginFunction *pFunct
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Cache the name for post hooks */
|
/* Cache the name for post hooks */
|
||||||
pHook->name = name;
|
pHook->name = sm_strdup(name);
|
||||||
|
|
||||||
/* Increase reference count */
|
/* Increase reference count */
|
||||||
pHook->refCount++;
|
pHook->refCount++;
|
||||||
|
|
||||||
/* Add hook structure to hook lists */
|
/* Add hook structure to hook lists */
|
||||||
pHookList->push_back(pHook);
|
pHookList->push_back(pHook);
|
||||||
m_EventHooks.insert(name, pHook);
|
sm_trie_insert(m_EventHooks, name, pHook);
|
||||||
|
|
||||||
return EventHookErr_Okay;
|
return EventHookErr_Okay;
|
||||||
}
|
}
|
||||||
@@ -228,7 +234,7 @@ EventHookError EventManager::HookEvent(const char *name, IPluginFunction *pFunct
|
|||||||
/* Create pre hook forward if necessary */
|
/* Create pre hook forward if necessary */
|
||||||
if (!pHook->pPreHook)
|
if (!pHook->pPreHook)
|
||||||
{
|
{
|
||||||
pHook->pPreHook = forwardsys->CreateForwardEx(NULL, ET_Event, 3, GAMEEVENT_PARAMS);
|
pHook->pPreHook = g_Forwards.CreateForwardEx(NULL, ET_Event, 3, GAMEEVENT_PARAMS);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add plugin function to forward list */
|
/* Add plugin function to forward list */
|
||||||
@@ -237,7 +243,7 @@ EventHookError EventManager::HookEvent(const char *name, IPluginFunction *pFunct
|
|||||||
/* Create post hook forward if necessary */
|
/* Create post hook forward if necessary */
|
||||||
if (!pHook->pPostHook)
|
if (!pHook->pPostHook)
|
||||||
{
|
{
|
||||||
pHook->pPostHook = forwardsys->CreateForwardEx(NULL, ET_Ignore, 3, GAMEEVENT_PARAMS);
|
pHook->pPostHook = g_Forwards.CreateForwardEx(NULL, ET_Ignore, 3, GAMEEVENT_PARAMS);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If postCopy is false, then we may want to set it to true */
|
/* If postCopy is false, then we may want to set it to true */
|
||||||
@@ -262,7 +268,7 @@ EventHookError EventManager::UnhookEvent(const char *name, IPluginFunction *pFun
|
|||||||
IChangeableForward **pEventForward;
|
IChangeableForward **pEventForward;
|
||||||
|
|
||||||
/* If hook does not exist at all */
|
/* If hook does not exist at all */
|
||||||
if (!m_EventHooks.retrieve(name, &pHook))
|
if (!sm_trie_retrieve(m_EventHooks, name, (void **)&pHook))
|
||||||
{
|
{
|
||||||
return EventHookErr_NotActive;
|
return EventHookErr_NotActive;
|
||||||
}
|
}
|
||||||
@@ -284,7 +290,7 @@ EventHookError EventManager::UnhookEvent(const char *name, IPluginFunction *pFun
|
|||||||
/* If forward's list contains 0 functions now, free it */
|
/* If forward's list contains 0 functions now, free it */
|
||||||
if ((*pEventForward)->GetFunctionCount() == 0)
|
if ((*pEventForward)->GetFunctionCount() == 0)
|
||||||
{
|
{
|
||||||
forwardsys->ReleaseForward(*pEventForward);
|
g_Forwards.ReleaseForward(*pEventForward);
|
||||||
*pEventForward = NULL;
|
*pEventForward = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -294,7 +300,7 @@ EventHookError EventManager::UnhookEvent(const char *name, IPluginFunction *pFun
|
|||||||
/* If reference count is now 0, free hook structure */
|
/* If reference count is now 0, free hook structure */
|
||||||
|
|
||||||
EventHookList *pHookList;
|
EventHookList *pHookList;
|
||||||
IPlugin *plugin = scripts->FindPluginByContext(pFunction->GetParentContext()->GetContext());
|
IPlugin *plugin = g_PluginSys.GetPluginByCtx(pFunction->GetParentContext()->GetContext());
|
||||||
|
|
||||||
/* Get plugin's event hook list */
|
/* Get plugin's event hook list */
|
||||||
if (!plugin->GetProperty("EventHooks", (void**)&pHookList))
|
if (!plugin->GetProperty("EventHooks", (void**)&pHookList))
|
||||||
@@ -312,7 +318,10 @@ EventHookError EventManager::UnhookEvent(const char *name, IPluginFunction *pFun
|
|||||||
pHookList->remove(pHook);
|
pHookList->remove(pHook);
|
||||||
|
|
||||||
/* Delete entry in trie */
|
/* Delete entry in trie */
|
||||||
m_EventHooks.remove(name);
|
sm_trie_delete(m_EventHooks, name);
|
||||||
|
|
||||||
|
/* Free the cached name */
|
||||||
|
delete pHook->name;
|
||||||
|
|
||||||
/* And finally free structure memory */
|
/* And finally free structure memory */
|
||||||
delete pHook;
|
delete pHook;
|
||||||
@@ -388,7 +397,7 @@ bool EventManager::OnFireEvent(IGameEvent *pEvent, bool bDontBroadcast)
|
|||||||
|
|
||||||
name = pEvent->GetName();
|
name = pEvent->GetName();
|
||||||
|
|
||||||
if (m_EventHooks.retrieve(name, &pHook))
|
if (sm_trie_retrieve(m_EventHooks, name, reinterpret_cast<void **>(&pHook)))
|
||||||
{
|
{
|
||||||
/* Push the event onto the event stack. The reference count is increased to make sure
|
/* Push the event onto the event stack. The reference count is increased to make sure
|
||||||
* the structure is not garbage collected in between now and the post hook.
|
* the structure is not garbage collected in between now and the post hook.
|
||||||
@@ -402,7 +411,7 @@ bool EventManager::OnFireEvent(IGameEvent *pEvent, bool bDontBroadcast)
|
|||||||
{
|
{
|
||||||
EventInfo info(pEvent, NULL);
|
EventInfo info(pEvent, NULL);
|
||||||
HandleSecurity sec(NULL, g_pCoreIdent);
|
HandleSecurity sec(NULL, g_pCoreIdent);
|
||||||
Handle_t hndl = handlesys->CreateHandle(m_EventType, &info, NULL, g_pCoreIdent, NULL);
|
Handle_t hndl = g_HandleSys.CreateHandle(m_EventType, &info, NULL, g_pCoreIdent, NULL);
|
||||||
|
|
||||||
info.bDontBroadcast = bDontBroadcast;
|
info.bDontBroadcast = bDontBroadcast;
|
||||||
|
|
||||||
@@ -415,7 +424,7 @@ bool EventManager::OnFireEvent(IGameEvent *pEvent, bool bDontBroadcast)
|
|||||||
|
|
||||||
broadcast = info.bDontBroadcast;
|
broadcast = info.bDontBroadcast;
|
||||||
|
|
||||||
handlesys->FreeHandle(hndl, &sec);
|
g_HandleSys.FreeHandle(hndl, &sec);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pHook->postCopy)
|
if (pHook->postCopy)
|
||||||
@@ -467,14 +476,14 @@ bool EventManager::OnFireEvent_Post(IGameEvent *pEvent, bool bDontBroadcast)
|
|||||||
info.bDontBroadcast = bDontBroadcast;
|
info.bDontBroadcast = bDontBroadcast;
|
||||||
info.pEvent = m_EventCopies.front();
|
info.pEvent = m_EventCopies.front();
|
||||||
info.pOwner = NULL;
|
info.pOwner = NULL;
|
||||||
hndl = handlesys->CreateHandle(m_EventType, &info, NULL, g_pCoreIdent, NULL);
|
hndl = g_HandleSys.CreateHandle(m_EventType, &info, NULL, g_pCoreIdent, NULL);
|
||||||
|
|
||||||
pForward->PushCell(hndl);
|
pForward->PushCell(hndl);
|
||||||
} else {
|
} else {
|
||||||
pForward->PushCell(BAD_HANDLE);
|
pForward->PushCell(BAD_HANDLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
pForward->PushString(pHook->name.chars());
|
pForward->PushString(pHook->name);
|
||||||
pForward->PushCell(bDontBroadcast);
|
pForward->PushCell(bDontBroadcast);
|
||||||
pForward->Execute(NULL);
|
pForward->Execute(NULL);
|
||||||
|
|
||||||
@@ -482,7 +491,7 @@ bool EventManager::OnFireEvent_Post(IGameEvent *pEvent, bool bDontBroadcast)
|
|||||||
{
|
{
|
||||||
/* Free handle */
|
/* Free handle */
|
||||||
HandleSecurity sec(NULL, g_pCoreIdent);
|
HandleSecurity sec(NULL, g_pCoreIdent);
|
||||||
handlesys->FreeHandle(hndl, &sec);
|
g_HandleSys.FreeHandle(hndl, &sec);
|
||||||
|
|
||||||
/* Free event structure */
|
/* Free event structure */
|
||||||
gameevents->FreeEvent(info.pEvent);
|
gameevents->FreeEvent(info.pEvent);
|
||||||
@@ -495,7 +504,8 @@ bool EventManager::OnFireEvent_Post(IGameEvent *pEvent, bool bDontBroadcast)
|
|||||||
{
|
{
|
||||||
assert(pHook->pPostHook == NULL);
|
assert(pHook->pPostHook == NULL);
|
||||||
assert(pHook->pPreHook == NULL);
|
assert(pHook->pPreHook == NULL);
|
||||||
m_EventHooks.remove(pHook->name.chars());
|
sm_trie_delete(m_EventHooks, pHook->name);
|
||||||
|
delete pHook->name;
|
||||||
delete pHook;
|
delete pHook;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-10
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* vim: set ts=4 sw=4 tw=99 noet :
|
* vim: set ts=4 :
|
||||||
* =============================================================================
|
* =============================================================================
|
||||||
* SourceMod
|
* SourceMod
|
||||||
* Copyright (C) 2004-2010 AlliedModders LLC. All rights reserved.
|
* Copyright (C) 2004-2010 AlliedModders LLC. All rights reserved.
|
||||||
@@ -34,7 +34,7 @@
|
|||||||
|
|
||||||
#include "sm_globals.h"
|
#include "sm_globals.h"
|
||||||
#include "sourcemm_api.h"
|
#include "sourcemm_api.h"
|
||||||
#include <sm_namehashset.h>
|
#include "sm_trie.h"
|
||||||
#include <sh_list.h>
|
#include <sh_list.h>
|
||||||
#include <sh_stack.h>
|
#include <sh_stack.h>
|
||||||
#include <IHandleSys.h>
|
#include <IHandleSys.h>
|
||||||
@@ -69,12 +69,7 @@ struct EventHook
|
|||||||
IChangeableForward *pPostHook;
|
IChangeableForward *pPostHook;
|
||||||
bool postCopy;
|
bool postCopy;
|
||||||
unsigned int refCount;
|
unsigned int refCount;
|
||||||
ke::AString name;
|
char *name;
|
||||||
|
|
||||||
static inline bool matches(const char *name, const EventHook *hook)
|
|
||||||
{
|
|
||||||
return strcmp(name, hook->name.chars()) == 0;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum EventHookMode
|
enum EventHookMode
|
||||||
@@ -110,7 +105,7 @@ public: // IPluginsListener
|
|||||||
void OnPluginUnloaded(IPlugin *plugin);
|
void OnPluginUnloaded(IPlugin *plugin);
|
||||||
public: // IGameEventListener2
|
public: // IGameEventListener2
|
||||||
void FireGameEvent(IGameEvent *pEvent);
|
void FireGameEvent(IGameEvent *pEvent);
|
||||||
#if SOURCE_ENGINE >= SE_LEFT4DEAD && SOURCE_ENGINE != SE_DOTA
|
#if SOURCE_ENGINE >= SE_LEFT4DEAD
|
||||||
int GetEventDebugID();
|
int GetEventDebugID();
|
||||||
#endif
|
#endif
|
||||||
public:
|
public:
|
||||||
@@ -132,7 +127,7 @@ private: // IGameEventManager2 hooks
|
|||||||
bool OnFireEvent_Post(IGameEvent *pEvent, bool bDontBroadcast);
|
bool OnFireEvent_Post(IGameEvent *pEvent, bool bDontBroadcast);
|
||||||
private:
|
private:
|
||||||
HandleType_t m_EventType;
|
HandleType_t m_EventType;
|
||||||
NameHashSet<EventHook *> m_EventHooks;
|
Trie *m_EventHooks;
|
||||||
CStack<EventInfo *> m_FreeEvents;
|
CStack<EventInfo *> m_FreeEvents;
|
||||||
CStack<EventHook *> m_EventStack;
|
CStack<EventHook *> m_EventStack;
|
||||||
CStack<IGameEvent *> m_EventCopies;
|
CStack<IGameEvent *> m_EventCopies;
|
||||||
|
|||||||
@@ -31,11 +31,13 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "ExtensionSys.h"
|
#include "ExtensionSys.h"
|
||||||
#include <ILibrarySys.h>
|
#include "LibrarySys.h"
|
||||||
#include <ISourceMod.h>
|
#include "ShareSys.h"
|
||||||
#include "common_logic.h"
|
#include "Logger.h"
|
||||||
#include "PluginSys.h"
|
#include "sourcemm_api.h"
|
||||||
#include <am-utility.h>
|
#include "sm_srvcmds.h"
|
||||||
|
#include "sm_stringutil.h"
|
||||||
|
#include "PlayerManager.h"
|
||||||
|
|
||||||
CExtensionManager g_Extensions;
|
CExtensionManager g_Extensions;
|
||||||
IdentityType_t g_ExtType;
|
IdentityType_t g_ExtType;
|
||||||
@@ -49,7 +51,7 @@ void CExtension::Initialize(const char *filename, const char *path)
|
|||||||
m_File.assign(filename);
|
m_File.assign(filename);
|
||||||
m_Path.assign(path);
|
m_Path.assign(path);
|
||||||
char real_name[PLATFORM_MAX_PATH];
|
char real_name[PLATFORM_MAX_PATH];
|
||||||
libsys->GetFileFromPath(real_name, sizeof(real_name), m_Path.c_str());
|
g_LibSys.GetFileFromPath(real_name, sizeof(real_name), m_Path.c_str());
|
||||||
m_RealFile.assign(real_name);
|
m_RealFile.assign(real_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,6 +61,42 @@ CRemoteExtension::CRemoteExtension(IExtensionInterface *pAPI, const char *filena
|
|||||||
m_pAPI = pAPI;
|
m_pAPI = pAPI;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined METAMOD_PLAPI_VERSION
|
||||||
|
#if SOURCE_ENGINE == SE_LEFT4DEAD
|
||||||
|
#define GAMEFIX "2.l4d"
|
||||||
|
#elif SOURCE_ENGINE == SE_LEFT4DEAD2
|
||||||
|
#define GAMEFIX "2.l4d2"
|
||||||
|
#elif SOURCE_ENGINE == SE_NUCLEARDAWN
|
||||||
|
#define GAMEFIX "2.nd"
|
||||||
|
#elif SOURCE_ENGINE == SE_ALIENSWARM
|
||||||
|
#define GAMEFIX "2.swarm"
|
||||||
|
#elif SOURCE_ENGINE == SE_ORANGEBOX
|
||||||
|
#define GAMEFIX "2.ep2"
|
||||||
|
#elif SOURCE_ENGINE == SE_BLOODYGOODTIME
|
||||||
|
#define GAMEFIX "2.bgt"
|
||||||
|
#elif SOURCE_ENGINE == SE_EYE
|
||||||
|
#define GAMEFIX "2.eye"
|
||||||
|
#elif SOURCE_ENGINE == SE_CSS
|
||||||
|
#define GAMEFIX "2.css"
|
||||||
|
#elif SOURCE_ENGINE == SE_HL2DM
|
||||||
|
#define GAMEFIX "2.hl2dm"
|
||||||
|
#elif SOURCE_ENGINE == SE_DODS
|
||||||
|
#define GAMEFIX "2.dods"
|
||||||
|
#elif SOURCE_ENGINE == SE_TF2
|
||||||
|
#define GAMEFIX "2.tf2"
|
||||||
|
#elif SOURCE_ENGINE == SE_DARKMESSIAH
|
||||||
|
#define GAMEFIX "2.darkm"
|
||||||
|
#elif SOURCE_ENGINE == SE_PORTAL2
|
||||||
|
#define GAMEFIX "2.portal2"
|
||||||
|
#elif SOURCE_ENGINE == SE_CSGO
|
||||||
|
#define GAMEFIX "2.csgo"
|
||||||
|
#else
|
||||||
|
#define GAMEFIX "2.ep1"
|
||||||
|
#endif //(SOURCE_ENGINE == SE_LEFT4DEAD) || (SOURCE_ENGINE == SE_LEFT4DEAD2)
|
||||||
|
#else //METAMOD_PLAPI_VERSION
|
||||||
|
#define GAMEFIX "1.ep1"
|
||||||
|
#endif //METAMOD_PLAPI_VERSION
|
||||||
|
|
||||||
CLocalExtension::CLocalExtension(const char *filename)
|
CLocalExtension::CLocalExtension(const char *filename)
|
||||||
{
|
{
|
||||||
m_PlId = 0;
|
m_PlId = 0;
|
||||||
@@ -73,62 +111,54 @@ CLocalExtension::CLocalExtension(const char *filename)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Zeroth, see if there is an engine specific build in the new place. */
|
/* Zeroth, see if there is an engine specific build in the new place. */
|
||||||
g_pSM->BuildPath(Path_SM,
|
g_SourceMod.BuildPath(Path_SM,
|
||||||
path,
|
path,
|
||||||
PLATFORM_MAX_PATH,
|
PLATFORM_MAX_PATH,
|
||||||
"extensions/%s.%s." PLATFORM_LIB_EXT,
|
"extensions/%s." GAMEFIX "." PLATFORM_LIB_EXT,
|
||||||
filename,
|
filename);
|
||||||
smcore.gamesuffix);
|
|
||||||
|
|
||||||
if (libsys->IsPathFile(path))
|
if (g_LibSys.IsPathFile(path))
|
||||||
{
|
{
|
||||||
goto found;
|
goto found;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if SOURCE_ENGINE == SE_TF2 || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_HL2DM
|
||||||
/* COMPAT HACK: One-halfth, if ep2v, see if there is an engine specific build in the new place with old naming */
|
/* COMPAT HACK: One-halfth, if ep2v, see if there is an engine specific build in the new place with old naming */
|
||||||
if (strcmp(smcore.gamesuffix, "2.tf2") == 0
|
g_SourceMod.BuildPath(Path_SM,
|
||||||
|| strcmp(smcore.gamesuffix, "2.dods") == 0
|
path,
|
||||||
|| strcmp(smcore.gamesuffix, "2.hl2dm") == 0
|
PLATFORM_MAX_PATH,
|
||||||
)
|
"extensions/%s.2.ep2v." PLATFORM_LIB_EXT,
|
||||||
{
|
filename);
|
||||||
g_pSM->BuildPath(Path_SM,
|
|
||||||
path,
|
|
||||||
PLATFORM_MAX_PATH,
|
|
||||||
"extensions/%s.2.ep2v." PLATFORM_LIB_EXT,
|
|
||||||
filename);
|
|
||||||
|
|
||||||
if (libsys->IsPathFile(path))
|
if (g_LibSys.IsPathFile(path))
|
||||||
{
|
|
||||||
goto found;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (strcmp(smcore.gamesuffix, "2.nd") == 0)
|
|
||||||
{
|
{
|
||||||
g_pSM->BuildPath(Path_SM,
|
goto found;
|
||||||
path,
|
|
||||||
PLATFORM_MAX_PATH,
|
|
||||||
"extensions/%s.2.l4d2." PLATFORM_LIB_EXT,
|
|
||||||
filename);
|
|
||||||
|
|
||||||
if (libsys->IsPathFile(path))
|
|
||||||
{
|
|
||||||
goto found;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
#elif SOURCE_ENGINE == SE_NUCLEARDAWN
|
||||||
|
g_SourceMod.BuildPath(Path_SM,
|
||||||
|
path,
|
||||||
|
PLATFORM_MAX_PATH,
|
||||||
|
"extensions/%s.2.l4d2." PLATFORM_LIB_EXT,
|
||||||
|
filename);
|
||||||
|
|
||||||
|
if (g_LibSys.IsPathFile(path))
|
||||||
|
{
|
||||||
|
goto found;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* First see if there is an engine specific build! */
|
/* First see if there is an engine specific build! */
|
||||||
g_pSM->BuildPath(Path_SM,
|
g_SourceMod.BuildPath(Path_SM,
|
||||||
path,
|
path,
|
||||||
PLATFORM_MAX_PATH,
|
PLATFORM_MAX_PATH,
|
||||||
"extensions/auto.%s/%s." PLATFORM_LIB_EXT,
|
"extensions/auto." GAMEFIX "/%s." PLATFORM_LIB_EXT,
|
||||||
filename,
|
filename);
|
||||||
smcore.gamesuffix);
|
|
||||||
|
|
||||||
/* Try the "normal" version */
|
/* Try the "normal" version */
|
||||||
if (!libsys->IsPathFile(path))
|
if (!g_LibSys.IsPathFile(path))
|
||||||
{
|
{
|
||||||
normal:
|
normal:
|
||||||
g_pSM->BuildPath(Path_SM,
|
g_SourceMod.BuildPath(Path_SM,
|
||||||
path,
|
path,
|
||||||
PLATFORM_MAX_PATH,
|
PLATFORM_MAX_PATH,
|
||||||
"extensions/%s." PLATFORM_LIB_EXT,
|
"extensions/%s." PLATFORM_LIB_EXT,
|
||||||
@@ -158,7 +188,7 @@ bool CRemoteExtension::Load(char *error, size_t maxlength)
|
|||||||
|
|
||||||
bool CLocalExtension::Load(char *error, size_t maxlength)
|
bool CLocalExtension::Load(char *error, size_t maxlength)
|
||||||
{
|
{
|
||||||
m_pLib = libsys->OpenLibrary(m_Path.c_str(), error, maxlength);
|
m_pLib = g_LibSys.OpenLibrary(m_Path.c_str(), error, maxlength);
|
||||||
|
|
||||||
if (m_pLib == NULL)
|
if (m_pLib == NULL)
|
||||||
{
|
{
|
||||||
@@ -190,10 +220,24 @@ bool CLocalExtension::Load(char *error, size_t maxlength)
|
|||||||
/* Load as MM:S */
|
/* Load as MM:S */
|
||||||
if (m_pAPI->IsMetamodExtension())
|
if (m_pAPI->IsMetamodExtension())
|
||||||
{
|
{
|
||||||
bool ok;
|
bool already;
|
||||||
m_PlId = smcore.LoadMMSPlugin(m_Path.c_str(), &ok, error, maxlength);
|
m_PlId = g_pMMPlugins->Load(m_Path.c_str(), g_PLID, already, error, maxlength);
|
||||||
|
|
||||||
if (!m_PlId || !ok)
|
// Check the plugin didn't refuse load
|
||||||
|
Pl_Status status;
|
||||||
|
|
||||||
|
#ifndef METAMOD_PLAPI_VERSION
|
||||||
|
const char *file;
|
||||||
|
PluginId source;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!m_PlId || (
|
||||||
|
#ifndef METAMOD_PLAPI_VERSION
|
||||||
|
g_pMMPlugins->Query(m_PlId, file, status, source)
|
||||||
|
#else
|
||||||
|
g_pMMPlugins->Query(m_PlId, NULL, &status, NULL)
|
||||||
|
#endif
|
||||||
|
&& status < Pl_Paused))
|
||||||
{
|
{
|
||||||
m_pLib->CloseLibrary();
|
m_pLib->CloseLibrary();
|
||||||
m_pLib = NULL;
|
m_pLib = NULL;
|
||||||
@@ -208,7 +252,8 @@ bool CLocalExtension::Load(char *error, size_t maxlength)
|
|||||||
{
|
{
|
||||||
if (m_PlId)
|
if (m_PlId)
|
||||||
{
|
{
|
||||||
smcore.UnloadMMSPlugin(m_PlId);
|
char dummy[255];
|
||||||
|
g_pMMPlugins->Unload(m_PlId, true, dummy, sizeof(dummy));
|
||||||
m_PlId = 0;
|
m_PlId = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -229,7 +274,8 @@ void CLocalExtension::Unload()
|
|||||||
{
|
{
|
||||||
if (m_pAPI != NULL && m_PlId)
|
if (m_pAPI != NULL && m_PlId)
|
||||||
{
|
{
|
||||||
smcore.UnloadMMSPlugin(m_PlId);
|
char temp_buffer[255];
|
||||||
|
g_pMMPlugins->Unload(m_PlId, true, temp_buffer, sizeof(temp_buffer));
|
||||||
m_PlId = 0;
|
m_PlId = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -292,7 +338,7 @@ bool CExtension::PerformAPICheck(char *error, size_t maxlength)
|
|||||||
bool CExtension::Load(char *error, size_t maxlength)
|
bool CExtension::Load(char *error, size_t maxlength)
|
||||||
{
|
{
|
||||||
CreateIdentity();
|
CreateIdentity();
|
||||||
if (!m_pAPI->OnExtensionLoad(this, &g_ShareSys, error, maxlength, !smcore.IsMapLoading()))
|
if (!m_pAPI->OnExtensionLoad(this, &g_ShareSys, error, maxlength, !g_SourceMod.IsMapLoading()))
|
||||||
{
|
{
|
||||||
DestroyIdentity();
|
DestroyIdentity();
|
||||||
return false;
|
return false;
|
||||||
@@ -300,7 +346,7 @@ bool CExtension::Load(char *error, size_t maxlength)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Check if we're past load time */
|
/* Check if we're past load time */
|
||||||
if (!smcore.IsMapLoading())
|
if (!g_SourceMod.IsMapLoading())
|
||||||
{
|
{
|
||||||
m_pAPI->OnExtensionsAllLoaded();
|
m_pAPI->OnExtensionsAllLoaded();
|
||||||
}
|
}
|
||||||
@@ -343,7 +389,7 @@ void CExtension::MarkAllLoaded()
|
|||||||
void CExtension::AddPlugin(CPlugin *pPlugin)
|
void CExtension::AddPlugin(CPlugin *pPlugin)
|
||||||
{
|
{
|
||||||
/* Unfortunately we have to do this :( */
|
/* Unfortunately we have to do this :( */
|
||||||
if (m_Dependents.find(pPlugin) == m_Dependents.end())
|
if (m_Dependents.find(pPlugin) != m_Dependents.end())
|
||||||
{
|
{
|
||||||
m_Dependents.push_back(pPlugin);
|
m_Dependents.push_back(pPlugin);
|
||||||
}
|
}
|
||||||
@@ -510,15 +556,14 @@ void CExtension::AddLibrary(const char *library)
|
|||||||
void CExtensionManager::OnSourceModAllInitialized()
|
void CExtensionManager::OnSourceModAllInitialized()
|
||||||
{
|
{
|
||||||
g_ExtType = g_ShareSys.CreateIdentType("EXTENSION");
|
g_ExtType = g_ShareSys.CreateIdentType("EXTENSION");
|
||||||
pluginsys->AddPluginsListener(this);
|
g_PluginSys.AddPluginsListener(this);
|
||||||
rootmenu->AddRootConsoleCommand("exts", "Manage extensions", this);
|
g_RootMenu.AddRootConsoleCommand("exts", "Manage extensions", this);
|
||||||
g_ShareSys.AddInterface(NULL, this);
|
g_ShareSys.AddInterface(NULL, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CExtensionManager::OnSourceModShutdown()
|
void CExtensionManager::OnSourceModShutdown()
|
||||||
{
|
{
|
||||||
rootmenu->RemoveRootConsoleCommand("exts", this);
|
g_RootMenu.RemoveRootConsoleCommand("exts", this);
|
||||||
pluginsys->RemovePluginsListener(this);
|
|
||||||
g_ShareSys.DestroyIdentType(g_ExtType);
|
g_ShareSys.DestroyIdentType(g_ExtType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -536,11 +581,13 @@ void CExtensionManager::TryAutoload()
|
|||||||
{
|
{
|
||||||
char path[PLATFORM_MAX_PATH];
|
char path[PLATFORM_MAX_PATH];
|
||||||
|
|
||||||
g_pSM->BuildPath(Path_SM, path, sizeof(path), "extensions");
|
g_SourceMod.BuildPath(Path_SM, path, sizeof(path), "extensions");
|
||||||
|
|
||||||
ke::AutoPtr<IDirectory> pDir(libsys->OpenDirectory(path));
|
IDirectory *pDir = g_LibSys.OpenDirectory(path);
|
||||||
if (!pDir)
|
if (!pDir)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const char *lfile;
|
const char *lfile;
|
||||||
size_t len;
|
size_t len;
|
||||||
@@ -567,7 +614,7 @@ void CExtensionManager::TryAutoload()
|
|||||||
}
|
}
|
||||||
|
|
||||||
char file[PLATFORM_MAX_PATH];
|
char file[PLATFORM_MAX_PATH];
|
||||||
len = smcore.Format(file, sizeof(file), "%s", lfile);
|
len = UTIL_Format(file, sizeof(file), "%s", lfile);
|
||||||
strcpy(&file[len - 9], ".ext");
|
strcpy(&file[len - 9], ".ext");
|
||||||
|
|
||||||
LoadAutoExtension(file);
|
LoadAutoExtension(file);
|
||||||
@@ -579,11 +626,11 @@ void CExtensionManager::TryAutoload()
|
|||||||
IExtension *CExtensionManager::LoadAutoExtension(const char *path, bool bErrorOnMissing)
|
IExtension *CExtensionManager::LoadAutoExtension(const char *path, bool bErrorOnMissing)
|
||||||
{
|
{
|
||||||
/* Remove platform extension if it's there. Compat hack. */
|
/* Remove platform extension if it's there. Compat hack. */
|
||||||
const char *ext = libsys->GetFileExtension(path);
|
const char *ext = g_LibSys.GetFileExtension(path);
|
||||||
if (strcmp(ext, PLATFORM_LIB_EXT) == 0)
|
if (strcmp(ext, PLATFORM_LIB_EXT) == 0)
|
||||||
{
|
{
|
||||||
char path2[PLATFORM_MAX_PATH];
|
char path2[PLATFORM_MAX_PATH];
|
||||||
smcore.Format(path2, sizeof(path2), "%s", path);
|
UTIL_Format(path2, sizeof(path2), "%s", path);
|
||||||
path2[strlen(path) - strlen(PLATFORM_LIB_EXT) - 1] = '\0';
|
path2[strlen(path) - strlen(PLATFORM_LIB_EXT) - 1] = '\0';
|
||||||
return LoadAutoExtension(path2, bErrorOnMissing);
|
return LoadAutoExtension(path2, bErrorOnMissing);
|
||||||
}
|
}
|
||||||
@@ -604,11 +651,11 @@ IExtension *CExtensionManager::LoadAutoExtension(const char *path, bool bErrorOn
|
|||||||
|
|
||||||
if (!p->Load(error, sizeof(error)) || !p->IsLoaded())
|
if (!p->Load(error, sizeof(error)) || !p->IsLoaded())
|
||||||
{
|
{
|
||||||
if (bErrorOnMissing || libsys->IsPathFile(p->GetPath()))
|
if (bErrorOnMissing || g_LibSys.IsPathFile(p->GetPath()))
|
||||||
{
|
{
|
||||||
smcore.LogError("[SM] Unable to load extension \"%s\": %s", path, error);
|
g_Logger.LogError("[SM] Unable to load extension \"%s\": %s", path, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
p->SetError(error);
|
p->SetError(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -622,7 +669,7 @@ IExtension *CExtensionManager::FindExtensionByFile(const char *file)
|
|||||||
|
|
||||||
/* Chomp off the path */
|
/* Chomp off the path */
|
||||||
char lookup[PLATFORM_MAX_PATH];
|
char lookup[PLATFORM_MAX_PATH];
|
||||||
libsys->GetFileFromPath(lookup, sizeof(lookup), file);
|
g_LibSys.GetFileFromPath(lookup, sizeof(lookup), file);
|
||||||
|
|
||||||
for (iter=m_Libs.begin(); iter!=m_Libs.end(); iter++)
|
for (iter=m_Libs.begin(); iter!=m_Libs.end(); iter++)
|
||||||
{
|
{
|
||||||
@@ -671,11 +718,11 @@ IExtension *CExtensionManager::FindExtensionByName(const char *ext)
|
|||||||
IExtension *CExtensionManager::LoadExtension(const char *file, char *error, size_t maxlength)
|
IExtension *CExtensionManager::LoadExtension(const char *file, char *error, size_t maxlength)
|
||||||
{
|
{
|
||||||
/* Remove platform extension if it's there. Compat hack. */
|
/* Remove platform extension if it's there. Compat hack. */
|
||||||
const char *ext = libsys->GetFileExtension(file);
|
const char *ext = g_LibSys.GetFileExtension(file);
|
||||||
if (strcmp(ext, PLATFORM_LIB_EXT) == 0)
|
if (strcmp(ext, PLATFORM_LIB_EXT) == 0)
|
||||||
{
|
{
|
||||||
char path2[PLATFORM_MAX_PATH];
|
char path2[PLATFORM_MAX_PATH];
|
||||||
smcore.Format(path2, sizeof(path2), "%s", file);
|
UTIL_Format(path2, sizeof(path2), "%s", file);
|
||||||
path2[strlen(file) - strlen(PLATFORM_LIB_EXT) - 1] = '\0';
|
path2[strlen(file) - strlen(PLATFORM_LIB_EXT) - 1] = '\0';
|
||||||
return LoadExtension(path2, error, maxlength);
|
return LoadExtension(path2, error, maxlength);
|
||||||
}
|
}
|
||||||
@@ -737,11 +784,11 @@ void CExtensionManager::AddInterface(IExtension *pOwner, SMInterface *pInterface
|
|||||||
pExt->AddInterface(pInterface);
|
pExt->AddInterface(pInterface);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CExtensionManager::BindChildPlugin(IExtension *pParent, SMPlugin *pPlugin)
|
void CExtensionManager::BindChildPlugin( IExtension *pParent, CPlugin *pPlugin )
|
||||||
{
|
{
|
||||||
CExtension *pExt = (CExtension *)pParent;
|
CExtension *pExt = (CExtension *)pParent;
|
||||||
|
|
||||||
pExt->AddPlugin(static_cast<CPlugin *>(pPlugin));
|
pExt->AddPlugin(pPlugin);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CExtensionManager::OnPluginDestroyed(IPlugin *plugin)
|
void CExtensionManager::OnPluginDestroyed(IPlugin *plugin)
|
||||||
@@ -750,7 +797,7 @@ void CExtensionManager::OnPluginDestroyed(IPlugin *plugin)
|
|||||||
|
|
||||||
for (iter=m_Libs.begin(); iter!=m_Libs.end(); iter++)
|
for (iter=m_Libs.begin(); iter!=m_Libs.end(); iter++)
|
||||||
{
|
{
|
||||||
(*iter)->DropRefsTo(static_cast<CPlugin *>(plugin));
|
(*iter)->DropRefsTo((CPlugin *)plugin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -778,21 +825,25 @@ CExtension *CExtensionManager::FindByOrder(unsigned int num)
|
|||||||
bool CExtensionManager::UnloadExtension(IExtension *_pExt)
|
bool CExtensionManager::UnloadExtension(IExtension *_pExt)
|
||||||
{
|
{
|
||||||
if (!_pExt)
|
if (!_pExt)
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
CExtension *pExt = (CExtension *)_pExt;
|
CExtension *pExt = (CExtension *)_pExt;
|
||||||
|
|
||||||
if (m_Libs.find(pExt) == m_Libs.end())
|
if (m_Libs.find(pExt) == m_Libs.end())
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/* Tell it to unload */
|
/* Tell it to unload */
|
||||||
if (pExt->IsLoaded())
|
if (pExt->IsLoaded())
|
||||||
pExt->GetAPI()->OnExtensionUnload();
|
{
|
||||||
|
IExtensionInterface *pAPI = pExt->GetAPI();
|
||||||
|
pAPI->OnExtensionUnload();
|
||||||
|
}
|
||||||
|
|
||||||
// Remove us from internal lists. Note that because we do this, it's
|
/* First remove us from internal lists */
|
||||||
// possible that our extension could be added back if another plugin
|
|
||||||
// tries to load during this process. If we ever find this to happen,
|
|
||||||
// we can just block plugin loading.
|
|
||||||
g_ShareSys.RemoveInterfaces(_pExt);
|
g_ShareSys.RemoveInterfaces(_pExt);
|
||||||
m_Libs.remove(pExt);
|
m_Libs.remove(pExt);
|
||||||
|
|
||||||
@@ -806,7 +857,7 @@ bool CExtensionManager::UnloadExtension(IExtension *_pExt)
|
|||||||
while (p_iter != pExt->m_Dependents.end())
|
while (p_iter != pExt->m_Dependents.end())
|
||||||
{
|
{
|
||||||
/* We have to manually unlink ourselves here, since we're no longer being managed */
|
/* We have to manually unlink ourselves here, since we're no longer being managed */
|
||||||
scripts->UnloadPlugin((*p_iter));
|
g_PluginSys.UnloadPlugin((*p_iter));
|
||||||
p_iter = pExt->m_Dependents.erase(p_iter);
|
p_iter = pExt->m_Dependents.erase(p_iter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -815,7 +866,7 @@ bool CExtensionManager::UnloadExtension(IExtension *_pExt)
|
|||||||
s_iter != pExt->m_Libraries.end();
|
s_iter != pExt->m_Libraries.end();
|
||||||
s_iter++)
|
s_iter++)
|
||||||
{
|
{
|
||||||
scripts->OnLibraryAction((*s_iter).c_str(), LibraryAction_Removed);
|
g_PluginSys.OnLibraryAction((*s_iter).c_str(), LibraryAction_Removed);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Notify and/or unload all dependencies */
|
/* Notify and/or unload all dependencies */
|
||||||
@@ -826,9 +877,13 @@ bool CExtensionManager::UnloadExtension(IExtension *_pExt)
|
|||||||
{
|
{
|
||||||
pDep = (*c_iter);
|
pDep = (*c_iter);
|
||||||
if ((pAPI=pDep->GetAPI()) == NULL)
|
if ((pAPI=pDep->GetAPI()) == NULL)
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
if (pDep == pExt)
|
if (pDep == pExt)
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
/* Now, get its dependency list */
|
/* Now, get its dependency list */
|
||||||
bool dropped = false;
|
bool dropped = false;
|
||||||
List<IfaceInfo>::iterator i_iter = pDep->m_Deps.begin();
|
List<IfaceInfo>::iterator i_iter = pDep->m_Deps.begin();
|
||||||
@@ -857,9 +912,13 @@ bool CExtensionManager::UnloadExtension(IExtension *_pExt)
|
|||||||
while (i_iter != pDep->m_ChildDeps.end())
|
while (i_iter != pDep->m_ChildDeps.end())
|
||||||
{
|
{
|
||||||
if ((*i_iter).owner == pExt)
|
if ((*i_iter).owner == pExt)
|
||||||
|
{
|
||||||
i_iter = pDep->m_ChildDeps.erase(i_iter);
|
i_iter = pDep->m_ChildDeps.erase(i_iter);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
i_iter++;
|
i_iter++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -878,11 +937,6 @@ bool CExtensionManager::UnloadExtension(IExtension *_pExt)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Everything has been informed that we're unloading, so give the
|
|
||||||
// extension one last notification.
|
|
||||||
if (pExt->IsLoaded() && pExt->GetAPI()->GetExtensionVersion() >= 7)
|
|
||||||
pExt->GetAPI()->OnDependenciesDropped();
|
|
||||||
|
|
||||||
pExt->Unload();
|
pExt->Unload();
|
||||||
delete pExt;
|
delete pExt;
|
||||||
|
|
||||||
@@ -930,10 +984,10 @@ void CExtensionManager::AddDependency(IExtension *pSource, const char *file, boo
|
|||||||
|
|
||||||
void CExtensionManager::OnRootConsoleCommand(const char *cmdname, const CCommand &command)
|
void CExtensionManager::OnRootConsoleCommand(const char *cmdname, const CCommand &command)
|
||||||
{
|
{
|
||||||
int argcount = smcore.Argc(command);
|
int argcount = command.ArgC();
|
||||||
if (argcount >= 3)
|
if (argcount >= 3)
|
||||||
{
|
{
|
||||||
const char *cmd = smcore.Arg(command, 2);
|
const char *cmd = command.Arg(2);
|
||||||
if (strcmp(cmd, "list") == 0)
|
if (strcmp(cmd, "list") == 0)
|
||||||
{
|
{
|
||||||
List<CExtension *>::iterator iter;
|
List<CExtension *>::iterator iter;
|
||||||
@@ -943,17 +997,17 @@ void CExtensionManager::OnRootConsoleCommand(const char *cmdname, const CCommand
|
|||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
{
|
{
|
||||||
rootmenu->ConsolePrint("[SM] Displaying 1 extension:");
|
g_RootMenu.ConsolePrint("[SM] Displaying 1 extension:");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 0:
|
case 0:
|
||||||
{
|
{
|
||||||
rootmenu->ConsolePrint("[SM] No extensions are loaded.");
|
g_RootMenu.ConsolePrint("[SM] No extensions are loaded.");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
rootmenu->ConsolePrint("[SM] Displaying %d extensions:", m_Libs.size());
|
g_RootMenu.ConsolePrint("[SM] Displaying %d extensions:", m_Libs.size());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -965,7 +1019,7 @@ void CExtensionManager::OnRootConsoleCommand(const char *cmdname, const CCommand
|
|||||||
char error[255];
|
char error[255];
|
||||||
if (!pExt->IsRunning(error, sizeof(error)))
|
if (!pExt->IsRunning(error, sizeof(error)))
|
||||||
{
|
{
|
||||||
rootmenu->ConsolePrint("[%02d] <FAILED> file \"%s\": %s", num, pExt->GetFilename(), error);
|
g_RootMenu.ConsolePrint("[%02d] <FAILED> file \"%s\": %s", num, pExt->GetFilename(), error);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -973,10 +1027,10 @@ void CExtensionManager::OnRootConsoleCommand(const char *cmdname, const CCommand
|
|||||||
const char *name = pAPI->GetExtensionName();
|
const char *name = pAPI->GetExtensionName();
|
||||||
const char *version = pAPI->GetExtensionVerString();
|
const char *version = pAPI->GetExtensionVerString();
|
||||||
const char *descr = pAPI->GetExtensionDescription();
|
const char *descr = pAPI->GetExtensionDescription();
|
||||||
rootmenu->ConsolePrint("[%02d] %s (%s): %s", num, name, version, descr);
|
g_RootMenu.ConsolePrint("[%02d] %s (%s): %s", num, name, version, descr);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
rootmenu->ConsolePrint("[%02d] <FAILED> file \"%s\": %s", num, pExt->GetFilename(), pExt->m_Error.c_str());
|
g_RootMenu.ConsolePrint("[%02d] <FAILED> file \"%s\": %s", num, pExt->GetFilename(), pExt->m_Error.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@@ -985,29 +1039,29 @@ void CExtensionManager::OnRootConsoleCommand(const char *cmdname, const CCommand
|
|||||||
{
|
{
|
||||||
if (argcount < 4)
|
if (argcount < 4)
|
||||||
{
|
{
|
||||||
rootmenu->ConsolePrint("[SM] Usage: sm exts load <file>");
|
g_RootMenu.ConsolePrint("[SM] Usage: sm exts load <file>");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *filename = smcore.Arg(command, 3);
|
const char *filename = command.Arg(3);
|
||||||
char path[PLATFORM_MAX_PATH];
|
char path[PLATFORM_MAX_PATH];
|
||||||
char error[256];
|
char error[256];
|
||||||
|
|
||||||
smcore.Format(path, sizeof(path), "%s%s%s", filename, !strstr(filename, ".ext") ? ".ext" : "",
|
UTIL_Format(path, sizeof(path), "%s%s%s", filename, !strstr(filename, ".ext") ? ".ext" : "",
|
||||||
!strstr(filename, "." PLATFORM_LIB_EXT) ? "." PLATFORM_LIB_EXT : "");
|
!strstr(filename, "." PLATFORM_LIB_EXT) ? "." PLATFORM_LIB_EXT : "");
|
||||||
|
|
||||||
if (FindExtensionByFile(path) != NULL)
|
if (FindExtensionByFile(path) != NULL)
|
||||||
{
|
{
|
||||||
rootmenu->ConsolePrint("[SM] Extension %s is already loaded.", path);
|
g_RootMenu.ConsolePrint("[SM] Extension %s is already loaded.", path);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (LoadExtension(path, error, sizeof(error)))
|
if (LoadExtension(path, error, sizeof(error)))
|
||||||
{
|
{
|
||||||
rootmenu->ConsolePrint("[SM] Loaded extension %s successfully.", path);
|
g_RootMenu.ConsolePrint("[SM] Loaded extension %s successfully.", path);
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
rootmenu->ConsolePrint("[SM] Extension %s failed to load: %s", path, error);
|
g_RootMenu.ConsolePrint("[SM] Extension %s failed to load: %s", path, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@@ -1016,27 +1070,27 @@ void CExtensionManager::OnRootConsoleCommand(const char *cmdname, const CCommand
|
|||||||
{
|
{
|
||||||
if (argcount < 4)
|
if (argcount < 4)
|
||||||
{
|
{
|
||||||
rootmenu->ConsolePrint("[SM] Usage: sm exts info <#>");
|
g_RootMenu.ConsolePrint("[SM] Usage: sm exts info <#>");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *sId = smcore.Arg(command, 3);
|
const char *sId = command.Arg(3);
|
||||||
unsigned int id = atoi(sId);
|
unsigned int id = atoi(sId);
|
||||||
if (id <= 0)
|
if (id <= 0)
|
||||||
{
|
{
|
||||||
rootmenu->ConsolePrint("[SM] Usage: sm exts info <#>");
|
g_RootMenu.ConsolePrint("[SM] Usage: sm exts info <#>");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_Libs.size() == 0)
|
if (m_Libs.size() == 0)
|
||||||
{
|
{
|
||||||
rootmenu->ConsolePrint("[SM] No extensions are loaded.");
|
g_RootMenu.ConsolePrint("[SM] No extensions are loaded.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (id > m_Libs.size())
|
if (id > m_Libs.size())
|
||||||
{
|
{
|
||||||
rootmenu->ConsolePrint("[SM] No extension was found with id %d.", id);
|
g_RootMenu.ConsolePrint("[SM] No extension was found with id %d.", id);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1054,44 +1108,44 @@ void CExtensionManager::OnRootConsoleCommand(const char *cmdname, const CCommand
|
|||||||
/* This should never happen */
|
/* This should never happen */
|
||||||
if (!pExt)
|
if (!pExt)
|
||||||
{
|
{
|
||||||
rootmenu->ConsolePrint("[SM] No extension was found with id %d.", id);
|
g_RootMenu.ConsolePrint("[SM] No extension was found with id %d.", id);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pExt->IsLoaded())
|
if (!pExt->IsLoaded())
|
||||||
{
|
{
|
||||||
rootmenu->ConsolePrint(" File: %s", pExt->GetFilename());
|
g_RootMenu.ConsolePrint(" File: %s", pExt->GetFilename());
|
||||||
rootmenu->ConsolePrint(" Loaded: No (%s)", pExt->m_Error.c_str());
|
g_RootMenu.ConsolePrint(" Loaded: No (%s)", pExt->m_Error.c_str());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
char error[255];
|
char error[255];
|
||||||
if (!pExt->IsRunning(error, sizeof(error)))
|
if (!pExt->IsRunning(error, sizeof(error)))
|
||||||
{
|
{
|
||||||
rootmenu->ConsolePrint(" File: %s", pExt->GetFilename());
|
g_RootMenu.ConsolePrint(" File: %s", pExt->GetFilename());
|
||||||
rootmenu->ConsolePrint(" Loaded: Yes");
|
g_RootMenu.ConsolePrint(" Loaded: Yes");
|
||||||
rootmenu->ConsolePrint(" Running: No (%s)", error);
|
g_RootMenu.ConsolePrint(" Running: No (%s)", error);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
IExtensionInterface *pAPI = pExt->GetAPI();
|
IExtensionInterface *pAPI = pExt->GetAPI();
|
||||||
rootmenu->ConsolePrint(" File: %s", pExt->GetFilename());
|
g_RootMenu.ConsolePrint(" File: %s", pExt->GetFilename());
|
||||||
rootmenu->ConsolePrint(" Loaded: Yes (version %s)", pAPI->GetExtensionVerString());
|
g_RootMenu.ConsolePrint(" Loaded: Yes (version %s)", pAPI->GetExtensionVerString());
|
||||||
rootmenu->ConsolePrint(" Name: %s (%s)", pAPI->GetExtensionName(), pAPI->GetExtensionDescription());
|
g_RootMenu.ConsolePrint(" Name: %s (%s)", pAPI->GetExtensionName(), pAPI->GetExtensionDescription());
|
||||||
rootmenu->ConsolePrint(" Author: %s (%s)", pAPI->GetExtensionAuthor(), pAPI->GetExtensionURL());
|
g_RootMenu.ConsolePrint(" Author: %s (%s)", pAPI->GetExtensionAuthor(), pAPI->GetExtensionURL());
|
||||||
rootmenu->ConsolePrint(" Binary info: API version %d (compiled %s)", pAPI->GetExtensionVersion(), pAPI->GetExtensionDateString());
|
g_RootMenu.ConsolePrint(" Binary info: API version %d (compiled %s)", pAPI->GetExtensionVersion(), pAPI->GetExtensionDateString());
|
||||||
|
|
||||||
if (pExt->IsExternal())
|
if (pExt->IsExternal())
|
||||||
{
|
{
|
||||||
rootmenu->ConsolePrint(" Method: Loaded by Metamod:Source, attached to SourceMod");
|
g_RootMenu.ConsolePrint(" Method: Loaded by Metamod:Source, attached to SourceMod");
|
||||||
}
|
}
|
||||||
else if (pAPI->IsMetamodExtension())
|
else if (pAPI->IsMetamodExtension())
|
||||||
{
|
{
|
||||||
rootmenu->ConsolePrint(" Method: Loaded by SourceMod, attached to Metamod:Source");
|
g_RootMenu.ConsolePrint(" Method: Loaded by SourceMod, attached to Metamod:Source");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rootmenu->ConsolePrint(" Method: Loaded by SourceMod");
|
g_RootMenu.ConsolePrint(" Method: Loaded by SourceMod");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1101,33 +1155,33 @@ void CExtensionManager::OnRootConsoleCommand(const char *cmdname, const CCommand
|
|||||||
{
|
{
|
||||||
if (argcount < 4)
|
if (argcount < 4)
|
||||||
{
|
{
|
||||||
rootmenu->ConsolePrint("[SM] Usage: sm exts unload <#> [code]");
|
g_RootMenu.ConsolePrint("[SM] Usage: sm exts unload <#> [code]");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *arg = smcore.Arg(command, 3);
|
const char *arg = command.Arg(3);
|
||||||
unsigned int num = atoi(arg);
|
unsigned int num = atoi(arg);
|
||||||
CExtension *pExt = FindByOrder(num);
|
CExtension *pExt = FindByOrder(num);
|
||||||
|
|
||||||
if (!pExt)
|
if (!pExt)
|
||||||
{
|
{
|
||||||
rootmenu->ConsolePrint("[SM] Extension number %d was not found.", num);
|
g_RootMenu.ConsolePrint("[SM] Extension number %d was not found.", num);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argcount > 4 && pExt->unload_code)
|
if (argcount > 4 && pExt->unload_code)
|
||||||
{
|
{
|
||||||
const char *unload = smcore.Arg(command, 4);
|
const char *unload = command.Arg(4);
|
||||||
if (pExt->unload_code == (unsigned)atoi(unload))
|
if (pExt->unload_code == (unsigned)atoi(unload))
|
||||||
{
|
{
|
||||||
char filename[PLATFORM_MAX_PATH];
|
char filename[PLATFORM_MAX_PATH];
|
||||||
snprintf(filename, PLATFORM_MAX_PATH, "%s", pExt->GetFilename());
|
snprintf(filename, PLATFORM_MAX_PATH, "%s", pExt->GetFilename());
|
||||||
UnloadExtension(pExt);
|
UnloadExtension(pExt);
|
||||||
rootmenu->ConsolePrint("[SM] Extension %s is now unloaded.", filename);
|
g_RootMenu.ConsolePrint("[SM] Extension %s is now unloaded.", filename);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rootmenu->ConsolePrint("[SM] Please try again, the correct unload code is \"%d\"", pExt->unload_code);
|
g_RootMenu.ConsolePrint("[SM] Please try again, the correct unload code is \"%d\"", pExt->unload_code);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1138,7 +1192,7 @@ void CExtensionManager::OnRootConsoleCommand(const char *cmdname, const CCommand
|
|||||||
char filename[PLATFORM_MAX_PATH];
|
char filename[PLATFORM_MAX_PATH];
|
||||||
snprintf(filename, PLATFORM_MAX_PATH, "%s", pExt->GetFilename());
|
snprintf(filename, PLATFORM_MAX_PATH, "%s", pExt->GetFilename());
|
||||||
UnloadExtension(pExt);
|
UnloadExtension(pExt);
|
||||||
rootmenu->ConsolePrint("[SM] Extension %s is now unloaded.", filename);
|
g_RootMenu.ConsolePrint("[SM] Extension %s is now unloaded.", filename);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1146,7 +1200,7 @@ void CExtensionManager::OnRootConsoleCommand(const char *cmdname, const CCommand
|
|||||||
List<CPlugin *> plugins;
|
List<CPlugin *> plugins;
|
||||||
if (pExt->m_ChildDeps.size())
|
if (pExt->m_ChildDeps.size())
|
||||||
{
|
{
|
||||||
rootmenu->ConsolePrint("[SM] Unloading %s will unload the following extensions: ", pExt->GetFilename());
|
g_RootMenu.ConsolePrint("[SM] Unloading %s will unload the following extensions: ", pExt->GetFilename());
|
||||||
List<CExtension *>::iterator iter;
|
List<CExtension *>::iterator iter;
|
||||||
CExtension *pOther;
|
CExtension *pOther;
|
||||||
/* Get list of all extensions */
|
/* Get list of all extensions */
|
||||||
@@ -1171,7 +1225,7 @@ void CExtensionManager::OnRootConsoleCommand(const char *cmdname, const CCommand
|
|||||||
/* Will our dependent care? */
|
/* Will our dependent care? */
|
||||||
if (!pExt->GetAPI()->QueryInterfaceDrop((*i_iter).iface))
|
if (!pExt->GetAPI()->QueryInterfaceDrop((*i_iter).iface))
|
||||||
{
|
{
|
||||||
rootmenu->ConsolePrint(" -> %s", pExt->GetFilename());
|
g_RootMenu.ConsolePrint(" -> %s", pExt->GetFilename());
|
||||||
/* Add to plugin unload list */
|
/* Add to plugin unload list */
|
||||||
List<CPlugin *>::iterator p_iter;
|
List<CPlugin *>::iterator p_iter;
|
||||||
for (p_iter=pOther->m_Dependents.begin();
|
for (p_iter=pOther->m_Dependents.begin();
|
||||||
@@ -1189,7 +1243,7 @@ void CExtensionManager::OnRootConsoleCommand(const char *cmdname, const CCommand
|
|||||||
}
|
}
|
||||||
if (pExt->m_Dependents.size())
|
if (pExt->m_Dependents.size())
|
||||||
{
|
{
|
||||||
rootmenu->ConsolePrint("[SM] Unloading %s will unload the following plugins: ", pExt->GetFilename());
|
g_RootMenu.ConsolePrint("[SM] Unloading %s will unload the following plugins: ", pExt->GetFilename());
|
||||||
List<CPlugin *>::iterator iter;
|
List<CPlugin *>::iterator iter;
|
||||||
CPlugin *pPlugin;
|
CPlugin *pPlugin;
|
||||||
for (iter = pExt->m_Dependents.begin(); iter != pExt->m_Dependents.end(); iter++)
|
for (iter = pExt->m_Dependents.begin(); iter != pExt->m_Dependents.end(); iter++)
|
||||||
@@ -1203,13 +1257,13 @@ void CExtensionManager::OnRootConsoleCommand(const char *cmdname, const CCommand
|
|||||||
for (iter = plugins.begin(); iter != plugins.end(); iter++)
|
for (iter = plugins.begin(); iter != plugins.end(); iter++)
|
||||||
{
|
{
|
||||||
pPlugin = (*iter);
|
pPlugin = (*iter);
|
||||||
rootmenu->ConsolePrint(" -> %s", pPlugin->GetFilename());
|
g_RootMenu.ConsolePrint(" -> %s", pPlugin->GetFilename());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
srand(static_cast<int>(time(NULL)));
|
srand(static_cast<int>(time(NULL)));
|
||||||
pExt->unload_code = (rand() % 877) + 123; //123 to 999
|
pExt->unload_code = (rand() % 877) + 123; //123 to 999
|
||||||
rootmenu->ConsolePrint("[SM] To verify unloading %s, please use the following: ", pExt->GetFilename());
|
g_RootMenu.ConsolePrint("[SM] To verify unloading %s, please use the following: ", pExt->GetFilename());
|
||||||
rootmenu->ConsolePrint("[SM] sm exts unload %d %d", num, pExt->unload_code);
|
g_RootMenu.ConsolePrint("[SM] sm exts unload %d %d", num, pExt->unload_code);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1218,17 +1272,17 @@ void CExtensionManager::OnRootConsoleCommand(const char *cmdname, const CCommand
|
|||||||
{
|
{
|
||||||
if (argcount < 4)
|
if (argcount < 4)
|
||||||
{
|
{
|
||||||
rootmenu->ConsolePrint("[SM] Usage: sm exts reload <#>");
|
g_RootMenu.ConsolePrint("[SM] Usage: sm exts reload <#>");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *arg = smcore.Arg(command, 3);
|
const char *arg = command.Arg(3);
|
||||||
unsigned int num = atoi(arg);
|
unsigned int num = atoi(arg);
|
||||||
CExtension *pExt = FindByOrder(num);
|
CExtension *pExt = FindByOrder(num);
|
||||||
|
|
||||||
if (!pExt)
|
if (!pExt)
|
||||||
{
|
{
|
||||||
rootmenu->ConsolePrint("[SM] Extension number %d was not found.", num);
|
g_RootMenu.ConsolePrint("[SM] Extension number %d was not found.", num);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1241,18 +1295,18 @@ void CExtensionManager::OnRootConsoleCommand(const char *cmdname, const CCommand
|
|||||||
|
|
||||||
if (pExt->Reload(error, sizeof(error)))
|
if (pExt->Reload(error, sizeof(error)))
|
||||||
{
|
{
|
||||||
rootmenu->ConsolePrint("[SM] Extension %s is now reloaded.", filename);
|
g_RootMenu.ConsolePrint("[SM] Extension %s is now reloaded.", filename);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rootmenu->ConsolePrint("[SM] Extension %s failed to reload: %s", filename, error);
|
g_RootMenu.ConsolePrint("[SM] Extension %s failed to reload: %s", filename, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rootmenu->ConsolePrint("[SM] Extension %s is not loaded.", pExt->GetFilename());
|
g_RootMenu.ConsolePrint("[SM] Extension %s is not loaded.", pExt->GetFilename());
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1260,12 +1314,100 @@ void CExtensionManager::OnRootConsoleCommand(const char *cmdname, const CCommand
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rootmenu->ConsolePrint("SourceMod Extensions Menu:");
|
g_RootMenu.ConsolePrint("SourceMod Extensions Menu:");
|
||||||
rootmenu->DrawGenericOption("info", "Extra extension information");
|
g_RootMenu.DrawGenericOption("info", "Extra extension information");
|
||||||
rootmenu->DrawGenericOption("list", "List extensions");
|
g_RootMenu.DrawGenericOption("list", "List extensions");
|
||||||
rootmenu->DrawGenericOption("load", "Load an extension");
|
g_RootMenu.DrawGenericOption("load", "Load an extension");
|
||||||
rootmenu->DrawGenericOption("reload", "Reload an extension");
|
g_RootMenu.DrawGenericOption("reload", "Reload an extension");
|
||||||
rootmenu->DrawGenericOption("unload", "Unload an extension");
|
g_RootMenu.DrawGenericOption("unload", "Unload an extension");
|
||||||
|
}
|
||||||
|
|
||||||
|
void CExtensionManager::ListExtensionsToClient(CPlayer *player, const CCommand &args)
|
||||||
|
{
|
||||||
|
char buffer[256];
|
||||||
|
int numExtensions = m_Libs.size();
|
||||||
|
edict_t *edict = player->GetEdict();
|
||||||
|
unsigned int id = 0;
|
||||||
|
unsigned int start = 0;
|
||||||
|
|
||||||
|
if (!numExtensions)
|
||||||
|
{
|
||||||
|
ClientConsolePrint(edict, "[SM] No extensions found.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args.ArgC() > 2)
|
||||||
|
{
|
||||||
|
start = atoi(args.Arg(2));
|
||||||
|
}
|
||||||
|
|
||||||
|
CExtension *ext;
|
||||||
|
SourceHook::List<CExtension *>::iterator iter;
|
||||||
|
|
||||||
|
for (iter = m_Libs.begin();
|
||||||
|
iter != m_Libs.end();
|
||||||
|
iter++)
|
||||||
|
{
|
||||||
|
ext = (*iter);
|
||||||
|
|
||||||
|
char error[255];
|
||||||
|
if (!ext->IsRunning(error, sizeof(error)))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
id++;
|
||||||
|
if (id < start)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (id - start > 10)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
IExtensionInterface *api = ext->GetAPI();
|
||||||
|
|
||||||
|
const char *name = api->GetExtensionName();
|
||||||
|
const char *version = api->GetExtensionVerString();
|
||||||
|
const char *author = api->GetExtensionAuthor();
|
||||||
|
const char *description = api->GetExtensionDescription();
|
||||||
|
|
||||||
|
size_t len = UTIL_Format(buffer, sizeof(buffer), " \"%s\"", name);
|
||||||
|
|
||||||
|
if (version != NULL && IS_STR_FILLED(version))
|
||||||
|
{
|
||||||
|
len += UTIL_Format(&buffer[len], sizeof(buffer)-len, " (%s)", version);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (author != NULL && IS_STR_FILLED(author))
|
||||||
|
{
|
||||||
|
len += UTIL_Format(&buffer[len], sizeof(buffer)-len, " by %s", author);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (description != NULL && IS_STR_FILLED(description))
|
||||||
|
{
|
||||||
|
len += UTIL_Format(&buffer[len], sizeof(buffer)-len, ": %s", description);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ClientConsolePrint(edict, "%s", buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (iter != m_Libs.end())
|
||||||
|
{
|
||||||
|
char error[255];
|
||||||
|
if ((*iter)->IsRunning(error, sizeof(error)))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iter != m_Libs.end())
|
||||||
|
{
|
||||||
|
ClientConsolePrint(edict, "To see more, type \"sm exts %d\"", id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CExtension *CExtensionManager::GetExtensionFromIdent(IdentityToken_t *ptr)
|
CExtension *CExtensionManager::GetExtensionFromIdent(IdentityToken_t *ptr)
|
||||||
@@ -1290,7 +1432,7 @@ void CExtensionManager::AddLibrary(IExtension *pSource, const char *library)
|
|||||||
{
|
{
|
||||||
CExtension *pExt = (CExtension *)pSource;
|
CExtension *pExt = (CExtension *)pSource;
|
||||||
pExt->AddLibrary(library);
|
pExt->AddLibrary(library);
|
||||||
scripts->OnLibraryAction(library, LibraryAction_Added);
|
g_PluginSys.OnLibraryAction(library, LibraryAction_Added);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CExtensionManager::LibraryExists(const char *library)
|
bool CExtensionManager::LibraryExists(const char *library)
|
||||||
@@ -1360,19 +1502,6 @@ void CExtensionManager::CallOnCoreMapStart(edict_t *pEdictList, int edictCount,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const CVector<IExtension *> *CExtensionManager::ListExtensions()
|
|
||||||
{
|
|
||||||
CVector<IExtension *> *list = new CVector<IExtension *>();
|
|
||||||
for (List<CExtension *>::iterator iter = m_Libs.begin(); iter != m_Libs.end(); iter++)
|
|
||||||
list->push_back(*iter);
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CExtensionManager::FreeExtensionList(const CVector<IExtension *> *list)
|
|
||||||
{
|
|
||||||
delete const_cast<CVector<IExtension *> *>(list);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CLocalExtension::IsSameFile(const char *file)
|
bool CLocalExtension::IsSameFile(const char *file)
|
||||||
{
|
{
|
||||||
/* Only care about the shortened name. */
|
/* Only care about the shortened name. */
|
||||||
@@ -36,11 +36,14 @@
|
|||||||
#include <ILibrarySys.h>
|
#include <ILibrarySys.h>
|
||||||
#include <sh_list.h>
|
#include <sh_list.h>
|
||||||
#include <sh_string.h>
|
#include <sh_string.h>
|
||||||
#include "common_logic.h"
|
#include <sm_trie_tpl.h>
|
||||||
|
#include "sm_globals.h"
|
||||||
|
#include "ShareSys.h"
|
||||||
|
#include <ISmmAPI.h>
|
||||||
#include <IPluginSys.h>
|
#include <IPluginSys.h>
|
||||||
#include <IRootConsoleMenu.h>
|
#include <IRootConsoleMenu.h>
|
||||||
|
#include "PluginSys.h"
|
||||||
#include "NativeOwner.h"
|
#include "NativeOwner.h"
|
||||||
#include "ShareSys.h"
|
|
||||||
|
|
||||||
class CPlayer;
|
class CPlayer;
|
||||||
|
|
||||||
@@ -117,7 +120,7 @@ public:
|
|||||||
bool IsExternal();
|
bool IsExternal();
|
||||||
bool IsSameFile(const char *file);
|
bool IsSameFile(const char *file);
|
||||||
private:
|
private:
|
||||||
int m_PlId;
|
PluginId m_PlId;
|
||||||
ILibrary *m_pLib;
|
ILibrary *m_pLib;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -135,7 +138,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
class CExtensionManager :
|
class CExtensionManager :
|
||||||
public IExtensionSys,
|
public IExtensionManager,
|
||||||
public SMGlobalClass,
|
public SMGlobalClass,
|
||||||
public IPluginsListener,
|
public IPluginsListener,
|
||||||
public IRootConsoleCommand
|
public IRootConsoleCommand
|
||||||
@@ -166,7 +169,7 @@ public:
|
|||||||
IExtension *LoadAutoExtension(const char *path, bool bErrorOnMissing=true);
|
IExtension *LoadAutoExtension(const char *path, bool bErrorOnMissing=true);
|
||||||
void BindDependency(IExtension *pOwner, IfaceInfo *pInfo);
|
void BindDependency(IExtension *pOwner, IfaceInfo *pInfo);
|
||||||
void AddInterface(IExtension *pOwner, SMInterface *pInterface);
|
void AddInterface(IExtension *pOwner, SMInterface *pInterface);
|
||||||
void BindChildPlugin(IExtension *pParent, SMPlugin *pPlugin);
|
void BindChildPlugin(IExtension *pParent, CPlugin *pPlugin);
|
||||||
void MarkAllLoaded();
|
void MarkAllLoaded();
|
||||||
void AddDependency(IExtension *pSource, const char *file, bool required, bool autoload);
|
void AddDependency(IExtension *pSource, const char *file, bool required, bool autoload);
|
||||||
void TryAutoload();
|
void TryAutoload();
|
||||||
@@ -174,8 +177,8 @@ public:
|
|||||||
bool LibraryExists(const char *library);
|
bool LibraryExists(const char *library);
|
||||||
void CallOnCoreMapStart(edict_t *pEdictList, int edictCount, int clientMax);
|
void CallOnCoreMapStart(edict_t *pEdictList, int edictCount, int clientMax);
|
||||||
void AddRawDependency(IExtension *ext, IdentityToken_t *other, void *iface);
|
void AddRawDependency(IExtension *ext, IdentityToken_t *other, void *iface);
|
||||||
const CVector<IExtension *> *ListExtensions();
|
public:
|
||||||
void FreeExtensionList(const CVector<IExtension *> *list);
|
void ListExtensionsToClient(CPlayer *player, const CCommand &args);
|
||||||
public:
|
public:
|
||||||
CExtension *GetExtensionFromIdent(IdentityToken_t *ptr);
|
CExtension *GetExtensionFromIdent(IdentityToken_t *ptr);
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
@@ -33,8 +33,9 @@
|
|||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "ForwardSys.h"
|
#include "ForwardSys.h"
|
||||||
|
#include "PluginSys.h"
|
||||||
|
#include "ShareSys.h"
|
||||||
#include "DebugReporter.h"
|
#include "DebugReporter.h"
|
||||||
#include "common_logic.h"
|
|
||||||
|
|
||||||
CForwardManager g_Forwards;
|
CForwardManager g_Forwards;
|
||||||
|
|
||||||
@@ -62,8 +63,8 @@ CForwardManager::~CForwardManager()
|
|||||||
|
|
||||||
void CForwardManager::OnSourceModAllInitialized()
|
void CForwardManager::OnSourceModAllInitialized()
|
||||||
{
|
{
|
||||||
scripts->AddPluginsListener(this);
|
g_PluginSys.AddPluginsListener(this);
|
||||||
sharesys->AddInterface(NULL, this);
|
g_ShareSys.AddInterface(NULL, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
IForward *CForwardManager::CreateForward(const char *name, ExecType et, unsigned int num_params, const ParamType *types, ...)
|
IForward *CForwardManager::CreateForward(const char *name, ExecType et, unsigned int num_params, const ParamType *types, ...)
|
||||||
@@ -78,7 +79,7 @@ IForward *CForwardManager::CreateForward(const char *name, ExecType et, unsigned
|
|||||||
|
|
||||||
if (fwd)
|
if (fwd)
|
||||||
{
|
{
|
||||||
scripts->AddFunctionsToForward(name, fwd);
|
g_PluginSys.AddFunctionsToForward(name, fwd);
|
||||||
|
|
||||||
m_managed.push_back(fwd);
|
m_managed.push_back(fwd);
|
||||||
}
|
}
|
||||||
@@ -192,7 +193,6 @@ void CForwardManager::ForwardFree(CForward *fwd)
|
|||||||
|
|
||||||
m_FreeForwards.push(fwd);
|
m_FreeForwards.push(fwd);
|
||||||
m_managed.remove(fwd);
|
m_managed.remove(fwd);
|
||||||
m_unmanaged.remove(fwd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CForward *CForwardManager::ForwardMake()
|
CForward *CForwardManager::ForwardMake()
|
||||||
@@ -210,23 +210,7 @@ CForward *CForwardManager::ForwardMake()
|
|||||||
|
|
||||||
void CForwardManager::OnPluginPauseChange(IPlugin *plugin, bool paused)
|
void CForwardManager::OnPluginPauseChange(IPlugin *plugin, bool paused)
|
||||||
{
|
{
|
||||||
if(paused)
|
/* No longer used */
|
||||||
return;
|
|
||||||
|
|
||||||
/* Attach any globally managed forwards */
|
|
||||||
List<CForward *>::iterator iter;
|
|
||||||
CForward *fwd;
|
|
||||||
|
|
||||||
for (iter=m_managed.begin(); iter!=m_managed.end(); iter++)
|
|
||||||
{
|
|
||||||
fwd = (*iter);
|
|
||||||
IPluginFunction *pFunc = plugin->GetBaseContext()->GetFunctionByName(fwd->GetForwardName());
|
|
||||||
// Only add functions, if they aren't registered yet!
|
|
||||||
if (pFunc && !fwd->IsFunctionRegistered(pFunc))
|
|
||||||
{
|
|
||||||
fwd->AddFunction(pFunc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*************************************
|
/*************************************
|
||||||
@@ -699,7 +683,7 @@ bool CForward::RemoveFunction(IPluginFunction *func)
|
|||||||
lst = &m_paused;
|
lst = &m_paused;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (iter=lst->begin(); iter!=lst->end(); iter++)
|
for (iter=m_functions.begin(); iter!=m_functions.end(); iter++)
|
||||||
{
|
{
|
||||||
if ((*iter) == func)
|
if ((*iter) == func)
|
||||||
{
|
{
|
||||||
@@ -757,28 +741,6 @@ bool CForward::AddFunction(IPluginFunction *func)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CForward::IsFunctionRegistered(IPluginFunction *func)
|
|
||||||
{
|
|
||||||
FuncIter iter;
|
|
||||||
List<IPluginFunction *> *lst;
|
|
||||||
|
|
||||||
if (func->IsRunnable())
|
|
||||||
{
|
|
||||||
lst = &m_functions;
|
|
||||||
} else {
|
|
||||||
lst = &m_paused;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (iter=m_functions.begin(); iter!=m_functions.end(); iter++)
|
|
||||||
{
|
|
||||||
if ((*iter) == func)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *CForward::GetForwardName()
|
const char *CForward::GetForwardName()
|
||||||
{
|
{
|
||||||
return m_name;
|
return m_name;
|
||||||
@@ -34,10 +34,10 @@
|
|||||||
|
|
||||||
#include <IForwardSys.h>
|
#include <IForwardSys.h>
|
||||||
#include <IPluginSys.h>
|
#include <IPluginSys.h>
|
||||||
#include "common_logic.h"
|
#include "sm_globals.h"
|
||||||
#include <sh_list.h>
|
#include <sh_list.h>
|
||||||
#include <sh_stack.h>
|
#include <sh_stack.h>
|
||||||
#include "ISourceMod.h"
|
#include "sourcemod.h"
|
||||||
|
|
||||||
using namespace SourceHook;
|
using namespace SourceHook;
|
||||||
|
|
||||||
@@ -46,6 +46,29 @@ typedef List<IPluginFunction *>::iterator FuncIter;
|
|||||||
/* :TODO: a global name max define for sourcepawn, should mirror compiler's sNAMEMAX */
|
/* :TODO: a global name max define for sourcepawn, should mirror compiler's sNAMEMAX */
|
||||||
#define FORWARDS_NAME_MAX 64
|
#define FORWARDS_NAME_MAX 64
|
||||||
|
|
||||||
|
struct ByrefInfo
|
||||||
|
{
|
||||||
|
unsigned int cells;
|
||||||
|
cell_t *orig_addr;
|
||||||
|
int flags;
|
||||||
|
int sz_flags;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FwdParamInfo
|
||||||
|
{
|
||||||
|
cell_t val;
|
||||||
|
ByrefInfo byref;
|
||||||
|
ParamType pushedas;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SourceMod::IForwardFilter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void Preprocess(IPluginFunction *fun, FwdParamInfo *params)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class FuncIteratorGuard
|
class FuncIteratorGuard
|
||||||
{
|
{
|
||||||
bool triggered;
|
bool triggered;
|
||||||
@@ -118,7 +141,6 @@ public:
|
|||||||
unsigned int num_params,
|
unsigned int num_params,
|
||||||
const ParamType *types,
|
const ParamType *types,
|
||||||
va_list ap);
|
va_list ap);
|
||||||
bool IsFunctionRegistered(IPluginFunction *func);
|
|
||||||
private:
|
private:
|
||||||
void _Int_PushArray(cell_t *inarray, unsigned int cells, int flags);
|
void _Int_PushArray(cell_t *inarray, unsigned int cells, int flags);
|
||||||
void _Int_PushString(cell_t *inarray, unsigned int cells, int sz_flags, int cp_flags);
|
void _Int_PushString(cell_t *inarray, unsigned int cells, int sz_flags, int cp_flags);
|
||||||
+189
-227
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* vim: set ts=4 sw=4 tw=99 noet :
|
* vim: set ts=4 :
|
||||||
* =============================================================================
|
* =============================================================================
|
||||||
* SourceMod
|
* SourceMod
|
||||||
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
||||||
@@ -42,24 +42,21 @@
|
|||||||
#include "logic_bridge.h"
|
#include "logic_bridge.h"
|
||||||
#include <tier0/mem.h>
|
#include <tier0/mem.h>
|
||||||
|
|
||||||
#if SOURCE_ENGINE == SE_DOTA
|
#if SOURCE_ENGINE == SE_CSGO
|
||||||
#include <game/shared/protobuf/usermessages.pb.h>
|
|
||||||
#elif SOURCE_ENGINE == SE_CSGO
|
|
||||||
#include <cstrike15_usermessages.pb.h>
|
#include <cstrike15_usermessages.pb.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
typedef ICommandLine *(*FakeGetCommandLine)();
|
typedef ICommandLine *(*FakeGetCommandLine)();
|
||||||
|
|
||||||
#if defined _WIN32
|
#if defined _WIN32
|
||||||
#define TIER0_NAME "tier0.dll"
|
#define TIER0_NAME "tier0.dll"
|
||||||
#define VSTDLIB_NAME "vstdlib.dll"
|
#define VSTDLIB_NAME "vstdlib.dll"
|
||||||
#elif defined __APPLE__
|
#elif defined __APPLE__
|
||||||
#define TIER0_NAME "libtier0.dylib"
|
#define TIER0_NAME "libtier0.dylib"
|
||||||
#define VSTDLIB_NAME "libvstdlib.dylib"
|
#define VSTDLIB_NAME "libvstdlib.dylib"
|
||||||
#elif defined __linux__
|
#elif defined __linux__
|
||||||
#if SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_TF2 \
|
#if SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_TF2 || SOURCE_ENGINE == SE_LEFT4DEAD2
|
||||||
|| SOURCE_ENGINE == SE_SDK2013 || SOURCE_ENGINE == SE_LEFT4DEAD2 || SOURCE_ENGINE == SE_NUCLEARDAWN
|
|
||||||
#define TIER0_NAME "libtier0_srv.so"
|
#define TIER0_NAME "libtier0_srv.so"
|
||||||
#define VSTDLIB_NAME "libvstdlib_srv.so"
|
#define VSTDLIB_NAME "libvstdlib_srv.so"
|
||||||
#elif SOURCE_ENGINE >= SE_LEFT4DEAD
|
#elif SOURCE_ENGINE >= SE_LEFT4DEAD
|
||||||
@@ -68,44 +65,60 @@ typedef ICommandLine *(*FakeGetCommandLine)();
|
|||||||
#else
|
#else
|
||||||
#define TIER0_NAME "tier0_i486.so"
|
#define TIER0_NAME "tier0_i486.so"
|
||||||
#define VSTDLIB_NAME "vstdlib_i486.so"
|
#define VSTDLIB_NAME "vstdlib_i486.so"
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
CHalfLife2 g_HL2;
|
CHalfLife2 g_HL2;
|
||||||
ConVar *sv_lan = NULL;
|
ConVar *sv_lan = NULL;
|
||||||
|
|
||||||
static void *g_EntList = NULL;
|
static void *g_EntList = NULL;
|
||||||
static void **g_pEntInfoList = NULL;
|
|
||||||
static int entInfoOffset = -1;
|
static int entInfoOffset = -1;
|
||||||
|
|
||||||
static CEntInfo *EntInfoArray()
|
namespace SourceHook
|
||||||
{
|
{
|
||||||
if (g_EntList != NULL)
|
template<>
|
||||||
|
int HashFunction<datamap_t *>(datamap_t * const &k)
|
||||||
{
|
{
|
||||||
return (CEntInfo *)((intp)g_EntList + entInfoOffset);
|
return reinterpret_cast<int>(k);
|
||||||
}
|
}
|
||||||
else if (g_pEntInfoList)
|
|
||||||
|
template<>
|
||||||
|
int Compare<datamap_t *>(datamap_t * const &k1, datamap_t * const &k2)
|
||||||
{
|
{
|
||||||
return *(CEntInfo **)g_pEntInfoList;
|
return (k1-k2);
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CHalfLife2::CHalfLife2()
|
CHalfLife2::CHalfLife2()
|
||||||
{
|
{
|
||||||
m_Maps.init();
|
m_pClasses = sm_trie_create();
|
||||||
|
|
||||||
m_pGetCommandLine = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CHalfLife2::~CHalfLife2()
|
CHalfLife2::~CHalfLife2()
|
||||||
{
|
{
|
||||||
for (NameHashSet<DataTableInfo *>::iterator iter = m_Classes.iter(); !iter.empty(); iter.next())
|
sm_trie_destroy(m_pClasses);
|
||||||
delete *iter;
|
|
||||||
|
|
||||||
for (DataTableMap::iterator iter = m_Maps.iter(); !iter.empty(); iter.next())
|
List<DataTableInfo *>::iterator iter;
|
||||||
delete iter->value;
|
DataTableInfo *pInfo;
|
||||||
|
for (iter=m_Tables.begin(); iter!=m_Tables.end(); iter++)
|
||||||
|
{
|
||||||
|
pInfo = (*iter);
|
||||||
|
delete pInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_Tables.clear();
|
||||||
|
|
||||||
|
THash<datamap_t *, DataMapTrie>::iterator h_iter;
|
||||||
|
for (h_iter=m_Maps.begin(); h_iter!=m_Maps.end(); h_iter++)
|
||||||
|
{
|
||||||
|
if (h_iter->val.trie)
|
||||||
|
{
|
||||||
|
sm_trie_destroy(h_iter->val.trie);
|
||||||
|
h_iter->val.trie = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_Maps.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if SOURCE_ENGINE != SE_DARKMESSIAH
|
#if SOURCE_ENGINE != SE_DARKMESSIAH
|
||||||
@@ -142,7 +155,7 @@ void CHalfLife2::OnSourceModAllInitialized()
|
|||||||
m_HinTextMsg = g_UserMsgs.GetMessageIndex("HintText");
|
m_HinTextMsg = g_UserMsgs.GetMessageIndex("HintText");
|
||||||
m_SayTextMsg = g_UserMsgs.GetMessageIndex("SayText");
|
m_SayTextMsg = g_UserMsgs.GetMessageIndex("SayText");
|
||||||
m_VGUIMenu = g_UserMsgs.GetMessageIndex("VGUIMenu");
|
m_VGUIMenu = g_UserMsgs.GetMessageIndex("VGUIMenu");
|
||||||
sharesys->AddInterface(NULL, this);
|
g_ShareSys.AddInterface(NULL, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHalfLife2::OnSourceModAllInitialized_Post()
|
void CHalfLife2::OnSourceModAllInitialized_Post()
|
||||||
@@ -153,18 +166,6 @@ void CHalfLife2::OnSourceModAllInitialized_Post()
|
|||||||
|
|
||||||
void CHalfLife2::InitLogicalEntData()
|
void CHalfLife2::InitLogicalEntData()
|
||||||
{
|
{
|
||||||
#if SOURCE_ENGINE == SE_TF2 \
|
|
||||||
|| SOURCE_ENGINE == SE_DODS \
|
|
||||||
|| SOURCE_ENGINE == SE_HL2DM \
|
|
||||||
|| SOURCE_ENGINE == SE_CSS \
|
|
||||||
|| SOURCE_ENGINE == SE_SDK2013
|
|
||||||
|
|
||||||
if (g_SMAPI->GetServerFactory(false)("VSERVERTOOLS003", NULL))
|
|
||||||
{
|
|
||||||
g_EntList = servertools->GetEntityList();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
char *addr = NULL;
|
char *addr = NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -174,99 +175,108 @@ void CHalfLife2::InitLogicalEntData()
|
|||||||
* If symbols aren't present (Windows or stripped Linux/Mac),
|
* If symbols aren't present (Windows or stripped Linux/Mac),
|
||||||
* attempt find via LevelShutdown + offset
|
* attempt find via LevelShutdown + offset
|
||||||
*/
|
*/
|
||||||
if (!g_EntList)
|
if (g_pGameConf->GetMemSig("gEntList", (void **)&addr))
|
||||||
{
|
{
|
||||||
if (g_pGameConf->GetMemSig("gEntList", (void **) &addr))
|
#if !defined PLATFORM_WINDOWS
|
||||||
|
if (!addr)
|
||||||
{
|
{
|
||||||
#if !defined PLATFORM_WINDOWS
|
// Key exists so notify if lookup fails, but try other method.
|
||||||
if (!addr)
|
g_Logger.LogError("Failed lookup of gEntList directly - Reverting to lookup via LevelShutdown");
|
||||||
{
|
|
||||||
// Key exists so notify if lookup fails, but try other method.
|
|
||||||
g_Logger.LogError("Failed lookup of gEntList directly - Reverting to lookup via LevelShutdown");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
#endif
|
|
||||||
g_EntList = reinterpret_cast<void *>(addr);
|
|
||||||
#if !defined PLATFORM_WINDOWS
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
g_EntList = reinterpret_cast<void *>(addr);
|
||||||
|
#if !defined PLATFORM_WINDOWS
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (!g_EntList)
|
if (!g_EntList)
|
||||||
{
|
{
|
||||||
if (g_pGameConf->GetMemSig("LevelShutdown", (void **) &addr) && addr)
|
if (!g_pGameConf->GetMemSig("LevelShutdown", (void **)&addr))
|
||||||
{
|
{
|
||||||
int offset;
|
g_Logger.LogError("Logical Entities not supported by this mod (LevelShutdown) - Reverting to networkable entities only");
|
||||||
if (!g_pGameConf->GetOffset("gEntList", &offset))
|
return;
|
||||||
{
|
|
||||||
g_Logger.LogError("Logical Entities not supported by this mod (gEntList) - Reverting to networkable entities only");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_EntList = *reinterpret_cast<void **>(addr + offset);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// If we have g_EntList from either of the above methods, make sure we can get the offset from it to EntInfo as well
|
if (!addr)
|
||||||
if (g_EntList && !g_pGameConf->GetOffset("EntInfo", &entInfoOffset))
|
{
|
||||||
|
g_Logger.LogError("Failed lookup of LevelShutdown - Reverting to networkable entities only");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int offset;
|
||||||
|
if (!g_pGameConf->GetOffset("gEntList", &offset))
|
||||||
|
{
|
||||||
|
g_Logger.LogError("Logical Entities not supported by this mod (gEntList) - Reverting to networkable entities only");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_EntList = *reinterpret_cast<void **>(addr + offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!g_EntList)
|
||||||
{
|
{
|
||||||
g_Logger.LogError("Logical Entities not supported by this mod (EntInfo) - Reverting to networkable entities only");
|
g_Logger.LogError("Failed lookup of gEntList - Reverting to networkable entities only");
|
||||||
g_EntList = NULL;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we don't have g_EntList or have it but don't know where EntInfo is on it, use fallback.
|
if (!g_pGameConf->GetOffset("EntInfo", &entInfoOffset))
|
||||||
if (!g_EntList || entInfoOffset == -1)
|
|
||||||
{
|
{
|
||||||
g_pGameConf->GetAddress("EntInfosPtr", (void **)&g_pEntInfoList);
|
g_Logger.LogError("Logical Entities not supported by this mod (EntInfo) - Reverting to networkable entities only");
|
||||||
}
|
|
||||||
|
|
||||||
if (!g_EntList && !g_pEntInfoList)
|
|
||||||
{
|
|
||||||
g_Logger.LogError("Failed lookup of gEntList - Reverting to networkable entities only");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHalfLife2::InitCommandLine()
|
void CHalfLife2::InitCommandLine()
|
||||||
{
|
{
|
||||||
|
char path[PLATFORM_MAX_PATH];
|
||||||
char error[256];
|
char error[256];
|
||||||
|
|
||||||
if (!is_original_engine)
|
|
||||||
{
|
|
||||||
ke::AutoPtr<ILibrary> lib(g_LibSys.OpenLibrary(TIER0_NAME, error, sizeof(error)));
|
|
||||||
if (lib == NULL)
|
|
||||||
{
|
|
||||||
g_Logger.LogError("Could not load %s: %s", TIER0_NAME, error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_pGetCommandLine = lib->GetSymbolAddress("CommandLine_Tier0");
|
|
||||||
|
|
||||||
/* '_Tier0' dropped on Alien Swarm version */
|
|
||||||
if (m_pGetCommandLine == NULL)
|
|
||||||
{
|
|
||||||
m_pGetCommandLine = lib->GetSymbolAddress("CommandLine");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ke::AutoPtr<ILibrary> lib(g_LibSys.OpenLibrary(VSTDLIB_NAME, error, sizeof(error)));
|
|
||||||
if (lib == NULL)
|
|
||||||
{
|
|
||||||
g_Logger.LogError("Could not load %s: %s", VSTDLIB_NAME, error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_pGetCommandLine = lib->GetSymbolAddress("CommandLine");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_pGetCommandLine == NULL)
|
g_SourceMod.BuildPath(Path_Game, path, sizeof(path), "../bin/" TIER0_NAME);
|
||||||
|
|
||||||
|
if (!g_LibSys.IsPathFile(path))
|
||||||
{
|
{
|
||||||
g_Logger.LogError("Could not locate any command line functionality");
|
g_Logger.LogError("Could not find path for: " TIER0_NAME);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ILibrary *lib = g_LibSys.OpenLibrary(path, error, sizeof(error));
|
||||||
|
m_pGetCommandLine = lib->GetSymbolAddress("CommandLine_Tier0");
|
||||||
|
|
||||||
|
/* '_Tier0' dropped on Alien Swarm version */
|
||||||
|
if (m_pGetCommandLine == NULL)
|
||||||
|
{
|
||||||
|
m_pGetCommandLine = lib->GetSymbolAddress("CommandLine");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_pGetCommandLine == NULL)
|
||||||
|
{
|
||||||
|
/* We probably have a Ship engine. */
|
||||||
|
lib->CloseLibrary();
|
||||||
|
g_SourceMod.BuildPath(Path_Game, path, sizeof(path), "../bin/" VSTDLIB_NAME);
|
||||||
|
if (!g_LibSys.IsPathFile(path))
|
||||||
|
{
|
||||||
|
g_Logger.LogError("Could not find path for: " VSTDLIB_NAME);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((lib = g_LibSys.OpenLibrary(path, error, sizeof(error))) == NULL)
|
||||||
|
{
|
||||||
|
g_Logger.LogError("Could not load %s: %s", path, error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_pGetCommandLine = lib->GetSymbolAddress("CommandLine");
|
||||||
|
|
||||||
|
if (m_pGetCommandLine == NULL)
|
||||||
|
{
|
||||||
|
g_Logger.LogError("Could not locate any command line functionality");
|
||||||
|
}
|
||||||
|
|
||||||
|
lib->CloseLibrary();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -288,11 +298,7 @@ bool CHalfLife2::IsOriginalEngine()
|
|||||||
#if SOURCE_ENGINE != SE_DARKMESSIAH
|
#if SOURCE_ENGINE != SE_DARKMESSIAH
|
||||||
IChangeInfoAccessor *CBaseEdict::GetChangeAccessor()
|
IChangeInfoAccessor *CBaseEdict::GetChangeAccessor()
|
||||||
{
|
{
|
||||||
#if SOURCE_ENGINE == SE_DOTA
|
|
||||||
return engine->GetChangeAccessor( IndexOfEdict((const edict_t *)this) );
|
|
||||||
#else
|
|
||||||
return engine->GetChangeAccessor( (const edict_t *)this );
|
return engine->GetChangeAccessor( (const edict_t *)this );
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -331,11 +337,16 @@ bool UTIL_FindInSendTable(SendTable *pTable,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool UTIL_FindDataMapInfo(datamap_t *pMap, const char *name, sm_datatable_info_t *pDataTable)
|
typedescription_t *UTIL_FindInDataMap(datamap_t *pMap, const char *name, bool *isNested)
|
||||||
{
|
{
|
||||||
|
if (isNested)
|
||||||
|
{
|
||||||
|
*isNested = false;
|
||||||
|
}
|
||||||
|
|
||||||
while (pMap)
|
while (pMap)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < pMap->dataNumFields; ++i)
|
for (int i=0; i<pMap->dataNumFields; i++)
|
||||||
{
|
{
|
||||||
if (pMap->dataDesc[i].fieldName == NULL)
|
if (pMap->dataDesc[i].fieldName == NULL)
|
||||||
{
|
{
|
||||||
@@ -343,23 +354,32 @@ bool UTIL_FindDataMapInfo(datamap_t *pMap, const char *name, sm_datatable_info_t
|
|||||||
}
|
}
|
||||||
if (strcmp(name, pMap->dataDesc[i].fieldName) == 0)
|
if (strcmp(name, pMap->dataDesc[i].fieldName) == 0)
|
||||||
{
|
{
|
||||||
pDataTable->prop = &(pMap->dataDesc[i]);
|
return &(pMap->dataDesc[i]);
|
||||||
pDataTable->actual_offset = GetTypeDescOffs(pDataTable->prop);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
if (pMap->dataDesc[i].td == NULL || !UTIL_FindDataMapInfo(pMap->dataDesc[i].td, name, pDataTable))
|
if (pMap->dataDesc[i].td)
|
||||||
{
|
{
|
||||||
continue;
|
if (isNested)
|
||||||
|
{
|
||||||
|
*isNested = (UTIL_FindInDataMap(pMap->dataDesc[i].td, name, NULL) != NULL);
|
||||||
|
if (*isNested)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else { // Use the old behaviour, we dont want to spring this on extensions - even if they're doing bad things.
|
||||||
|
typedescription_t *_td;
|
||||||
|
if ((_td=UTIL_FindInDataMap(pMap->dataDesc[i].td, name, NULL)) != NULL)
|
||||||
|
{
|
||||||
|
return _td;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pDataTable->actual_offset += GetTypeDescOffs(&(pMap->dataDesc[i]));
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pMap = pMap->baseMap;
|
pMap = pMap->baseMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ServerClass *CHalfLife2::FindServerClass(const char *classname)
|
ServerClass *CHalfLife2::FindServerClass(const char *classname)
|
||||||
@@ -367,7 +387,9 @@ ServerClass *CHalfLife2::FindServerClass(const char *classname)
|
|||||||
DataTableInfo *pInfo = _FindServerClass(classname);
|
DataTableInfo *pInfo = _FindServerClass(classname);
|
||||||
|
|
||||||
if (!pInfo)
|
if (!pInfo)
|
||||||
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return pInfo->sc;
|
return pInfo->sc;
|
||||||
}
|
}
|
||||||
@@ -375,21 +397,26 @@ ServerClass *CHalfLife2::FindServerClass(const char *classname)
|
|||||||
DataTableInfo *CHalfLife2::_FindServerClass(const char *classname)
|
DataTableInfo *CHalfLife2::_FindServerClass(const char *classname)
|
||||||
{
|
{
|
||||||
DataTableInfo *pInfo = NULL;
|
DataTableInfo *pInfo = NULL;
|
||||||
if (!m_Classes.retrieve(classname, &pInfo))
|
|
||||||
|
if (!sm_trie_retrieve(m_pClasses, classname, (void **)&pInfo))
|
||||||
{
|
{
|
||||||
ServerClass *sc = gamedll->GetAllServerClasses();
|
ServerClass *sc = gamedll->GetAllServerClasses();
|
||||||
while (sc)
|
while (sc)
|
||||||
{
|
{
|
||||||
if (strcmp(classname, sc->GetName()) == 0)
|
if (strcmp(classname, sc->GetName()) == 0)
|
||||||
{
|
{
|
||||||
pInfo = new DataTableInfo(sc);
|
pInfo = new DataTableInfo;
|
||||||
m_Classes.insert(classname, pInfo);
|
pInfo->sc = sc;
|
||||||
|
sm_trie_insert(m_pClasses, classname, pInfo);
|
||||||
|
m_Tables.push_back(pInfo);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
sc = sc->m_pNext;
|
sc = sc->m_pNext;
|
||||||
}
|
}
|
||||||
if (!pInfo)
|
if (!pInfo)
|
||||||
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return pInfo;
|
return pInfo;
|
||||||
@@ -398,13 +425,14 @@ DataTableInfo *CHalfLife2::_FindServerClass(const char *classname)
|
|||||||
bool CHalfLife2::FindSendPropInfo(const char *classname, const char *offset, sm_sendprop_info_t *info)
|
bool CHalfLife2::FindSendPropInfo(const char *classname, const char *offset, sm_sendprop_info_t *info)
|
||||||
{
|
{
|
||||||
DataTableInfo *pInfo;
|
DataTableInfo *pInfo;
|
||||||
|
sm_sendprop_info_t *prop;
|
||||||
|
|
||||||
if ((pInfo = _FindServerClass(classname)) == NULL)
|
if ((pInfo = _FindServerClass(classname)) == NULL)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pInfo->lookup.retrieve(offset, info))
|
if ((prop = pInfo->lookup.retrieve(offset)) == NULL)
|
||||||
{
|
{
|
||||||
sm_sendprop_info_t temp_info;
|
sm_sendprop_info_t temp_info;
|
||||||
|
|
||||||
@@ -416,6 +444,10 @@ bool CHalfLife2::FindSendPropInfo(const char *classname, const char *offset, sm_
|
|||||||
pInfo->lookup.insert(offset, temp_info);
|
pInfo->lookup.insert(offset, temp_info);
|
||||||
*info = temp_info;
|
*info = temp_info;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*info = *prop;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -434,32 +466,27 @@ SendProp *CHalfLife2::FindInSendTable(const char *classname, const char *offset)
|
|||||||
|
|
||||||
typedescription_t *CHalfLife2::FindInDataMap(datamap_t *pMap, const char *offset)
|
typedescription_t *CHalfLife2::FindInDataMap(datamap_t *pMap, const char *offset)
|
||||||
{
|
{
|
||||||
sm_datatable_info_t dt_info;
|
return this->FindInDataMap(pMap, offset, NULL);
|
||||||
|
|
||||||
if (!(this->FindDataMapInfo(pMap, offset, &dt_info)))
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return dt_info.prop;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CHalfLife2::FindDataMapInfo(datamap_t *pMap, const char *offset, sm_datatable_info_t *pDataTable)
|
typedescription_t *CHalfLife2::FindInDataMap(datamap_t *pMap, const char *offset, bool *isNested)
|
||||||
{
|
{
|
||||||
DataTableMap::Insert i = m_Maps.findForAdd(pMap);
|
typedescription_t *td = NULL;
|
||||||
if (!i.found())
|
DataMapTrie &val = m_Maps[pMap];
|
||||||
m_Maps.add(i, pMap, new DataMapCache());
|
|
||||||
|
|
||||||
DataMapCache *cache = i->value;
|
if (!val.trie)
|
||||||
|
|
||||||
if (!cache->retrieve(offset, pDataTable))
|
|
||||||
{
|
{
|
||||||
if (!UTIL_FindDataMapInfo(pMap, offset, pDataTable))
|
val.trie = sm_trie_create();
|
||||||
return false;
|
}
|
||||||
cache->insert(offset, *pDataTable);
|
if (!sm_trie_retrieve(val.trie, offset, (void **)&td))
|
||||||
|
{
|
||||||
|
if ((td = UTIL_FindInDataMap(pMap, offset, isNested)) != NULL)
|
||||||
|
{
|
||||||
|
sm_trie_insert(val.trie, offset, td);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return td;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHalfLife2::SetEdictStateChanged(edict_t *pEdict, unsigned short offset)
|
void CHalfLife2::SetEdictStateChanged(edict_t *pEdict, unsigned short offset)
|
||||||
@@ -485,7 +512,7 @@ void CHalfLife2::SetEdictStateChanged(edict_t *pEdict, unsigned short offset)
|
|||||||
|
|
||||||
bool CHalfLife2::TextMsg(int client, int dest, const char *msg)
|
bool CHalfLife2::TextMsg(int client, int dest, const char *msg)
|
||||||
{
|
{
|
||||||
#ifndef USE_PROTOBUF_USERMESSAGES
|
#if SOURCE_ENGINE != SE_CSGO
|
||||||
bf_write *pBitBuf = NULL;
|
bf_write *pBitBuf = NULL;
|
||||||
#endif
|
#endif
|
||||||
cell_t players[] = {client};
|
cell_t players[] = {client};
|
||||||
@@ -500,17 +527,7 @@ bool CHalfLife2::TextMsg(int client, int dest, const char *msg)
|
|||||||
char buffer[192];
|
char buffer[192];
|
||||||
UTIL_Format(buffer, sizeof(buffer), "%s\1\n", msg);
|
UTIL_Format(buffer, sizeof(buffer), "%s\1\n", msg);
|
||||||
|
|
||||||
#if SOURCE_ENGINE == SE_DOTA
|
#if SOURCE_ENGINE == SE_CSGO
|
||||||
CUserMsg_SayText *pMsg;
|
|
||||||
if ((pMsg = (CUserMsg_SayText *)g_UserMsgs.StartProtobufMessage(m_SayTextMsg, players, 1, USERMSG_RELIABLE)) == NULL)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
pMsg->set_client(0);
|
|
||||||
pMsg->set_text(buffer);
|
|
||||||
pMsg->set_chat(false);
|
|
||||||
#elif SOURCE_ENGINE == SE_CSGO
|
|
||||||
CCSUsrMsg_SayText *pMsg;
|
CCSUsrMsg_SayText *pMsg;
|
||||||
if ((pMsg = (CCSUsrMsg_SayText *)g_UserMsgs.StartProtobufMessage(m_SayTextMsg, players, 1, USERMSG_RELIABLE)) == NULL)
|
if ((pMsg = (CCSUsrMsg_SayText *)g_UserMsgs.StartProtobufMessage(m_SayTextMsg, players, 1, USERMSG_RELIABLE)) == NULL)
|
||||||
{
|
{
|
||||||
@@ -537,16 +554,7 @@ bool CHalfLife2::TextMsg(int client, int dest, const char *msg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if SOURCE_ENGINE == SE_DOTA
|
#if SOURCE_ENGINE == SE_CSGO
|
||||||
CUserMsg_TextMsg *pMsg;
|
|
||||||
if ((pMsg = (CUserMsg_TextMsg *)g_UserMsgs.StartProtobufMessage(m_MsgTextMsg, players, 1, USERMSG_RELIABLE)) == NULL)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
pMsg->set_dest(dest);
|
|
||||||
pMsg->add_param(msg);
|
|
||||||
#elif SOURCE_ENGINE == SE_CSGO
|
|
||||||
CCSUsrMsg_TextMsg *pMsg;
|
CCSUsrMsg_TextMsg *pMsg;
|
||||||
if ((pMsg = (CCSUsrMsg_TextMsg *)g_UserMsgs.StartProtobufMessage(m_MsgTextMsg, players, 1, USERMSG_RELIABLE)) == NULL)
|
if ((pMsg = (CCSUsrMsg_TextMsg *)g_UserMsgs.StartProtobufMessage(m_MsgTextMsg, players, 1, USERMSG_RELIABLE)) == NULL)
|
||||||
{
|
{
|
||||||
@@ -579,15 +587,7 @@ bool CHalfLife2::HintTextMsg(int client, const char *msg)
|
|||||||
{
|
{
|
||||||
cell_t players[] = {client};
|
cell_t players[] = {client};
|
||||||
|
|
||||||
#if SOURCE_ENGINE == SE_DOTA
|
#if SOURCE_ENGINE == SE_CSGO
|
||||||
CUserMsg_HintText *pMsg;
|
|
||||||
if ((pMsg = (CUserMsg_HintText *)g_UserMsgs.StartProtobufMessage(m_HinTextMsg, players, 1, USERMSG_RELIABLE)) == NULL)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
pMsg->set_message(msg);
|
|
||||||
#elif SOURCE_ENGINE == SE_CSGO
|
|
||||||
CCSUsrMsg_HintText *pMsg;
|
CCSUsrMsg_HintText *pMsg;
|
||||||
if ((pMsg = (CCSUsrMsg_HintText *)g_UserMsgs.StartProtobufMessage(m_HinTextMsg, players, 1, USERMSG_RELIABLE)) == NULL)
|
if ((pMsg = (CCSUsrMsg_HintText *)g_UserMsgs.StartProtobufMessage(m_HinTextMsg, players, 1, USERMSG_RELIABLE)) == NULL)
|
||||||
{
|
{
|
||||||
@@ -617,15 +617,7 @@ bool CHalfLife2::HintTextMsg(int client, const char *msg)
|
|||||||
|
|
||||||
bool CHalfLife2::HintTextMsg(cell_t *players, int count, const char *msg)
|
bool CHalfLife2::HintTextMsg(cell_t *players, int count, const char *msg)
|
||||||
{
|
{
|
||||||
#if SOURCE_ENGINE == SE_DOTA
|
#if SOURCE_ENGINE == SE_CSGO
|
||||||
CUserMsg_HintText *pMsg;
|
|
||||||
if ((pMsg = (CUserMsg_HintText *)g_UserMsgs.StartProtobufMessage(m_HinTextMsg, players, count, USERMSG_RELIABLE)) == NULL)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
pMsg->set_message(msg);
|
|
||||||
#elif SOURCE_ENGINE == SE_CSGO
|
|
||||||
CCSUsrMsg_HintText *pMsg;
|
CCSUsrMsg_HintText *pMsg;
|
||||||
if ((pMsg = (CCSUsrMsg_HintText *)g_UserMsgs.StartProtobufMessage(m_HinTextMsg, players, count, USERMSG_RELIABLE)) == NULL)
|
if ((pMsg = (CCSUsrMsg_HintText *)g_UserMsgs.StartProtobufMessage(m_HinTextMsg, players, count, USERMSG_RELIABLE)) == NULL)
|
||||||
{
|
{
|
||||||
@@ -660,13 +652,7 @@ bool CHalfLife2::ShowVGUIMenu(int client, const char *name, KeyValues *data, boo
|
|||||||
int count = 0;
|
int count = 0;
|
||||||
cell_t players[] = {client};
|
cell_t players[] = {client};
|
||||||
|
|
||||||
#if SOURCE_ENGINE == SE_DOTA
|
#if SOURCE_ENGINE == SE_CSGO
|
||||||
CUserMsg_VGUIMenu *pMsg;
|
|
||||||
if ((pMsg = (CUserMsg_VGUIMenu *)g_UserMsgs.StartProtobufMessage(m_VGUIMenu, players, 1, USERMSG_RELIABLE)) == NULL)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#elif SOURCE_ENGINE == SE_CSGO
|
|
||||||
CCSUsrMsg_VGUIMenu *pMsg;
|
CCSUsrMsg_VGUIMenu *pMsg;
|
||||||
if ((pMsg = (CCSUsrMsg_VGUIMenu *)g_UserMsgs.StartProtobufMessage(m_VGUIMenu, players, 1, USERMSG_RELIABLE)) == NULL)
|
if ((pMsg = (CCSUsrMsg_VGUIMenu *)g_UserMsgs.StartProtobufMessage(m_VGUIMenu, players, 1, USERMSG_RELIABLE)) == NULL)
|
||||||
{
|
{
|
||||||
@@ -691,18 +677,7 @@ bool CHalfLife2::ShowVGUIMenu(int client, const char *name, KeyValues *data, boo
|
|||||||
SubKey = data->GetFirstSubKey();
|
SubKey = data->GetFirstSubKey();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if SOURCE_ENGINE == SE_DOTA
|
#if SOURCE_ENGINE == SE_CSGO
|
||||||
pMsg->set_name(name);
|
|
||||||
pMsg->set_show(show);
|
|
||||||
|
|
||||||
while (SubKey)
|
|
||||||
{
|
|
||||||
CUserMsg_VGUIMenu_Keys *key = pMsg->add_keys();
|
|
||||||
key->set_name(SubKey->GetName());
|
|
||||||
key->set_value(SubKey->GetString());
|
|
||||||
SubKey = SubKey->GetNextKey();
|
|
||||||
}
|
|
||||||
#elif SOURCE_ENGINE == SE_CSGO
|
|
||||||
pMsg->set_name(name);
|
pMsg->set_name(name);
|
||||||
pMsg->set_show(show);
|
pMsg->set_show(show);
|
||||||
|
|
||||||
@@ -758,15 +733,10 @@ void CHalfLife2::ProcessFakeCliCmdQueue()
|
|||||||
if (g_Players.GetClientOfUserId(pFake->userid) == pFake->client)
|
if (g_Players.GetClientOfUserId(pFake->userid) == pFake->client)
|
||||||
{
|
{
|
||||||
CPlayer *pPlayer = g_Players.GetPlayerByIndex(pFake->client);
|
CPlayer *pPlayer = g_Players.GetPlayerByIndex(pFake->client);
|
||||||
#if SOURCE_ENGINE == SE_DOTA
|
|
||||||
engine->ClientCommand(pPlayer->GetIndex(), "%s", pFake->cmd.c_str());
|
|
||||||
#else
|
|
||||||
serverpluginhelpers->ClientCommand(pPlayer->GetEdict(), pFake->cmd.c_str());
|
serverpluginhelpers->ClientCommand(pPlayer->GetEdict(), pFake->cmd.c_str());
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_CmdQueue.pop();
|
m_CmdQueue.pop();
|
||||||
m_FreeCmds.push(pFake);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1023,9 +993,7 @@ CEntInfo *CHalfLife2::LookupEntity(int entIndex)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
CEntInfo *entInfos = EntInfoArray();
|
if (!g_EntList || entInfoOffset == -1)
|
||||||
|
|
||||||
if (!entInfos)
|
|
||||||
{
|
{
|
||||||
/* Attempt to use engine interface instead */
|
/* Attempt to use engine interface instead */
|
||||||
static CEntInfo tempInfo;
|
static CEntInfo tempInfo;
|
||||||
@@ -1052,7 +1020,8 @@ CEntInfo *CHalfLife2::LookupEntity(int entIndex)
|
|||||||
return &tempInfo;
|
return &tempInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
return &entInfos[entIndex];
|
CEntInfo *pArray = (CEntInfo *)(((unsigned char *)g_EntList) + entInfoOffset);
|
||||||
|
return &pArray[entIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1184,16 +1153,9 @@ const char *CHalfLife2::GetEntityClassname(CBaseEntity *pEntity)
|
|||||||
static int offset = -1;
|
static int offset = -1;
|
||||||
if (offset == -1)
|
if (offset == -1)
|
||||||
{
|
{
|
||||||
CBaseEntity *pGetterEnt = ReferenceToEntity(0);
|
datamap_t *pMap = GetDataMap(pEntity);
|
||||||
datamap_t *pMap = GetDataMap(pGetterEnt);
|
typedescription_t *pDesc = FindInDataMap(pMap, "m_iClassname");
|
||||||
|
offset = GetTypeDescOffs(pDesc);
|
||||||
sm_datatable_info_t info;
|
|
||||||
if (!FindDataMapInfo(pMap, "m_iClassname", &info))
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
offset = info.actual_offset;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return *(const char **)(((unsigned char *)pEntity) + offset);
|
return *(const char **)(((unsigned char *)pEntity) + offset);
|
||||||
|
|||||||
+12
-37
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* vim: set ts=4 sw=4 tw=99 noet :
|
* vim: set ts=4 :
|
||||||
* =============================================================================
|
* =============================================================================
|
||||||
* SourceMod
|
* SourceMod
|
||||||
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
||||||
@@ -35,10 +35,8 @@
|
|||||||
#include <sh_list.h>
|
#include <sh_list.h>
|
||||||
#include <sh_string.h>
|
#include <sh_string.h>
|
||||||
#include <sh_tinyhash.h>
|
#include <sh_tinyhash.h>
|
||||||
#include <am-utility.h>
|
#include <sm_trie_tpl.h>
|
||||||
#include <am-hashmap.h>
|
#include "sm_trie.h"
|
||||||
#include <sm_stringhashmap.h>
|
|
||||||
#include <sm_namehashset.h>
|
|
||||||
#include "sm_globals.h"
|
#include "sm_globals.h"
|
||||||
#include "sm_queue.h"
|
#include "sm_queue.h"
|
||||||
#include <IGameHelpers.h>
|
#include <IGameHelpers.h>
|
||||||
@@ -61,38 +59,16 @@ using namespace SourceMod;
|
|||||||
|
|
||||||
struct DataTableInfo
|
struct DataTableInfo
|
||||||
{
|
{
|
||||||
struct SendPropPolicy
|
|
||||||
{
|
|
||||||
static inline bool matches(const char *name, const sm_sendprop_info_t &info)
|
|
||||||
{
|
|
||||||
return strcmp(name, info.prop->GetName()) == 0;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline bool matches(const char *name, const DataTableInfo *info)
|
|
||||||
{
|
|
||||||
return strcmp(name, info->sc->GetName()) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
DataTableInfo(ServerClass *sc)
|
|
||||||
: sc(sc)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
ServerClass *sc;
|
ServerClass *sc;
|
||||||
NameHashSet<sm_sendprop_info_t, SendPropPolicy> lookup;
|
KTrie<sm_sendprop_info_t> lookup;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DataMapCachePolicy
|
struct DataMapTrie
|
||||||
{
|
{
|
||||||
static inline bool matches(const char *name, const sm_datatable_info_t &info)
|
DataMapTrie() : trie(NULL) {}
|
||||||
{
|
Trie *trie;
|
||||||
return strcmp(name, info.prop->fieldName) == 0;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef NameHashSet<sm_datatable_info_t, DataMapCachePolicy> DataMapCache;
|
|
||||||
|
|
||||||
struct DelayedFakeCliCmd
|
struct DelayedFakeCliCmd
|
||||||
{
|
{
|
||||||
String cmd;
|
String cmd;
|
||||||
@@ -123,7 +99,7 @@ public:
|
|||||||
int m_SerialNumber;
|
int m_SerialNumber;
|
||||||
CEntInfo *m_pPrev;
|
CEntInfo *m_pPrev;
|
||||||
CEntInfo *m_pNext;
|
CEntInfo *m_pNext;
|
||||||
#if (SOURCE_ENGINE >= SE_PORTAL2) && (SOURCE_ENGINE != SE_DOTA)
|
#if SOURCE_ENGINE >= SE_PORTAL2
|
||||||
string_t m_iName;
|
string_t m_iName;
|
||||||
string_t m_iClassName;
|
string_t m_iClassName;
|
||||||
#endif
|
#endif
|
||||||
@@ -147,7 +123,7 @@ public: //IGameHelpers
|
|||||||
datamap_t *GetDataMap(CBaseEntity *pEntity);
|
datamap_t *GetDataMap(CBaseEntity *pEntity);
|
||||||
ServerClass *FindServerClass(const char *classname);
|
ServerClass *FindServerClass(const char *classname);
|
||||||
typedescription_t *FindInDataMap(datamap_t *pMap, const char *offset);
|
typedescription_t *FindInDataMap(datamap_t *pMap, const char *offset);
|
||||||
bool FindDataMapInfo(datamap_t *pMap, const char *offset, sm_datatable_info_t *pDataTable);
|
typedescription_t *FindInDataMap(datamap_t *pMap, const char *offset, bool *isNested);
|
||||||
void SetEdictStateChanged(edict_t *pEdict, unsigned short offset);
|
void SetEdictStateChanged(edict_t *pEdict, unsigned short offset);
|
||||||
bool TextMsg(int client, int dest, const char *msg);
|
bool TextMsg(int client, int dest, const char *msg);
|
||||||
bool HintTextMsg(int client, const char *msg);
|
bool HintTextMsg(int client, const char *msg);
|
||||||
@@ -193,10 +169,9 @@ private:
|
|||||||
void InitLogicalEntData();
|
void InitLogicalEntData();
|
||||||
void InitCommandLine();
|
void InitCommandLine();
|
||||||
private:
|
private:
|
||||||
typedef ke::HashMap<datamap_t *, DataMapCache *, ke::PointerPolicy<datamap_t> > DataTableMap;
|
Trie *m_pClasses;
|
||||||
|
List<DataTableInfo *> m_Tables;
|
||||||
NameHashSet<DataTableInfo *> m_Classes;
|
THash<datamap_t *, DataMapTrie> m_Maps;
|
||||||
DataTableMap m_Maps;
|
|
||||||
int m_MsgTextMsg;
|
int m_MsgTextMsg;
|
||||||
int m_HinTextMsg;
|
int m_HinTextMsg;
|
||||||
int m_SayTextMsg;
|
int m_SayTextMsg;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* vim: set ts=4 sw=4 tw=99 noet :
|
* vim: set ts=4 :
|
||||||
* =============================================================================
|
* =============================================================================
|
||||||
* SourceMod
|
* SourceMod
|
||||||
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
||||||
@@ -30,12 +30,13 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "HandleSys.h"
|
#include "HandleSys.h"
|
||||||
|
#include "ShareSys.h"
|
||||||
|
#include "PluginSys.h"
|
||||||
|
#include "ExtensionSys.h"
|
||||||
|
#include "Logger.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "common_logic.h"
|
#include "sm_stringutil.h"
|
||||||
#include "ShareSys.h"
|
|
||||||
#include "ExtensionSys.h"
|
|
||||||
#include "PluginSys.h"
|
|
||||||
|
|
||||||
HandleSystem g_HandleSys;
|
HandleSystem g_HandleSys;
|
||||||
|
|
||||||
@@ -59,6 +60,9 @@ HandleSystem::HandleSystem()
|
|||||||
m_Types = new QHandleType[HANDLESYS_TYPEARRAY_SIZE];
|
m_Types = new QHandleType[HANDLESYS_TYPEARRAY_SIZE];
|
||||||
memset(m_Types, 0, sizeof(QHandleType) * HANDLESYS_TYPEARRAY_SIZE);
|
memset(m_Types, 0, sizeof(QHandleType) * HANDLESYS_TYPEARRAY_SIZE);
|
||||||
|
|
||||||
|
m_TypeLookup = sm_trie_create();
|
||||||
|
m_strtab = new BaseStringTable(512);
|
||||||
|
|
||||||
m_TypeTail = 0;
|
m_TypeTail = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,6 +70,8 @@ HandleSystem::~HandleSystem()
|
|||||||
{
|
{
|
||||||
delete [] m_Handles;
|
delete [] m_Handles;
|
||||||
delete [] m_Types;
|
delete [] m_Types;
|
||||||
|
sm_trie_destroy(m_TypeLookup);
|
||||||
|
delete m_strtab;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -139,10 +145,12 @@ HandleType_t HandleSystem::CreateType(const char *name,
|
|||||||
|
|
||||||
if (name && name[0] != '\0')
|
if (name && name[0] != '\0')
|
||||||
{
|
{
|
||||||
if (m_TypeLookup.contains(name))
|
if (sm_trie_retrieve(m_TypeLookup, name, NULL))
|
||||||
{
|
{
|
||||||
if (err)
|
if (err)
|
||||||
|
{
|
||||||
*err = HandleError_Parameter;
|
*err = HandleError_Parameter;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -204,8 +212,10 @@ HandleType_t HandleSystem::CreateType(const char *name,
|
|||||||
pType->dispatch = dispatch;
|
pType->dispatch = dispatch;
|
||||||
if (name && name[0] != '\0')
|
if (name && name[0] != '\0')
|
||||||
{
|
{
|
||||||
pType->name = new ke::AString(name);
|
pType->nameIdx = m_strtab->AddString(name);
|
||||||
m_TypeLookup.insert(name, pType);
|
sm_trie_insert(m_TypeLookup, name, (void *)pType);
|
||||||
|
} else {
|
||||||
|
pType->nameIdx = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
pType->opened = 0;
|
pType->opened = 0;
|
||||||
@@ -233,14 +243,21 @@ HandleType_t HandleSystem::CreateType(const char *name,
|
|||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HandleSystem::FindHandleType(const char *name, HandleType_t *aResult)
|
bool HandleSystem::FindHandleType(const char *name, HandleType_t *type)
|
||||||
{
|
{
|
||||||
QHandleType *type;
|
QHandleType *_type;
|
||||||
if (!m_TypeLookup.retrieve(name, &type))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (aResult)
|
if (!sm_trie_retrieve(m_TypeLookup, name, (void **)&_type))
|
||||||
*aResult = type - m_Types;
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int offset = _type - m_Types;
|
||||||
|
|
||||||
|
if (type)
|
||||||
|
{
|
||||||
|
*type = offset;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -643,13 +660,13 @@ void HandleSystem::GetHandleUnchecked(Handle_t hndl, QHandle *& pHandle, unsigne
|
|||||||
|
|
||||||
HandleError HandleSystem::FreeHandle(QHandle *pHandle, unsigned int index)
|
HandleError HandleSystem::FreeHandle(QHandle *pHandle, unsigned int index)
|
||||||
{
|
{
|
||||||
if (pHandle->is_destroying)
|
if (pHandle->is_destroying)
|
||||||
{
|
{
|
||||||
/* Someone tried to free this recursively.
|
/* Someone tried to free this recursively.
|
||||||
* We'll just ignore this safely.
|
* We'll just ignore this safely.
|
||||||
*/
|
*/
|
||||||
return HandleError_None;
|
return HandleError_None;
|
||||||
}
|
}
|
||||||
|
|
||||||
QHandleType *pType = &m_Types[pHandle->type];
|
QHandleType *pType = &m_Types[pHandle->type];
|
||||||
|
|
||||||
@@ -674,9 +691,9 @@ HandleError HandleSystem::FreeHandle(QHandle *pHandle, unsigned int index)
|
|||||||
/* Type should be the same but do this anyway... */
|
/* Type should be the same but do this anyway... */
|
||||||
pType = &m_Types[pMaster->type];
|
pType = &m_Types[pMaster->type];
|
||||||
pMaster->is_destroying = true;
|
pMaster->is_destroying = true;
|
||||||
if (pMaster->object)
|
if (pMaster->object)
|
||||||
{
|
{
|
||||||
pType->dispatch->OnHandleDestroy(pMaster->type, pMaster->object);
|
pType->dispatch->OnHandleDestroy(pMaster->type, pMaster->object);
|
||||||
}
|
}
|
||||||
ReleasePrimHandle(master);
|
ReleasePrimHandle(master);
|
||||||
}
|
}
|
||||||
@@ -691,9 +708,9 @@ HandleError HandleSystem::FreeHandle(QHandle *pHandle, unsigned int index)
|
|||||||
if (--pHandle->refcount == 0)
|
if (--pHandle->refcount == 0)
|
||||||
{
|
{
|
||||||
pHandle->is_destroying = true;
|
pHandle->is_destroying = true;
|
||||||
if (pHandle->object)
|
if (pHandle->object)
|
||||||
{
|
{
|
||||||
pType->dispatch->OnHandleDestroy(pHandle->type, pHandle->object);
|
pType->dispatch->OnHandleDestroy(pHandle->type, pHandle->object);
|
||||||
}
|
}
|
||||||
ReleasePrimHandle(index);
|
ReleasePrimHandle(index);
|
||||||
} else {
|
} else {
|
||||||
@@ -897,6 +914,10 @@ bool HandleSystem::RemoveType(HandleType_t type, IdentityToken_t *ident)
|
|||||||
m_Types[++m_FreeTypes].freeID = type;
|
m_Types[++m_FreeTypes].freeID = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Invalidate the type now */
|
||||||
|
IHandleTypeDispatch *dispatch = pType->dispatch;
|
||||||
|
pType->dispatch = NULL;
|
||||||
|
|
||||||
/* Make sure nothing is using this type. */
|
/* Make sure nothing is using this type. */
|
||||||
if (pType->opened)
|
if (pType->opened)
|
||||||
{
|
{
|
||||||
@@ -918,12 +939,14 @@ bool HandleSystem::RemoveType(HandleType_t type, IdentityToken_t *ident)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Invalidate the type now */
|
|
||||||
pType->dispatch = NULL;
|
|
||||||
|
|
||||||
/* Remove it from the type cache. */
|
/* Remove it from the type cache. */
|
||||||
if (pType->name)
|
if (pType->nameIdx != -1)
|
||||||
m_TypeLookup.remove(pType->name->chars());
|
{
|
||||||
|
const char *typeName;
|
||||||
|
|
||||||
|
typeName = m_strtab->GetString(pType->nameIdx);
|
||||||
|
sm_trie_delete(m_TypeLookup, typeName);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -957,8 +980,8 @@ bool HandleSystem::InitAccessDefaults(TypeAccess *pTypeAccess, HandleAccess *pHa
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define HANDLE_LOG_VERY_BAD(message, ...) \
|
#define HANDLE_LOG_VERY_BAD(message, ...) \
|
||||||
smcore.LogFatal(message, ##__VA_ARGS__); \
|
g_Logger.LogFatal(message, ##__VA_ARGS__); \
|
||||||
smcore.LogError(message, ##__VA_ARGS__);
|
g_Logger.LogError(message, ##__VA_ARGS__);
|
||||||
|
|
||||||
bool HandleSystem::TryAndFreeSomeHandles()
|
bool HandleSystem::TryAndFreeSomeHandles()
|
||||||
{
|
{
|
||||||
@@ -1005,63 +1028,10 @@ bool HandleSystem::TryAndFreeSomeHandles()
|
|||||||
HANDLE_LOG_VERY_BAD("[SM] MEMORY LEAK DETECTED IN PLUGIN (file \"%s\")", highest_owner->GetFilename());
|
HANDLE_LOG_VERY_BAD("[SM] MEMORY LEAK DETECTED IN PLUGIN (file \"%s\")", highest_owner->GetFilename());
|
||||||
HANDLE_LOG_VERY_BAD("[SM] Unloading plugin to free %d handles.", highest_handle_count);
|
HANDLE_LOG_VERY_BAD("[SM] Unloading plugin to free %d handles.", highest_handle_count);
|
||||||
HANDLE_LOG_VERY_BAD("[SM] Contact the author(s) of this plugin to correct this error.", highest_handle_count);
|
HANDLE_LOG_VERY_BAD("[SM] Contact the author(s) of this plugin to correct this error.", highest_handle_count);
|
||||||
HANDLE_LOG_VERY_BAD("--------------------------------------------------------------------------");
|
|
||||||
|
|
||||||
const IdentityToken_t *pIdentity = highest_owner->GetIdentity();
|
|
||||||
unsigned int total = 0, highest_index = 0, total_size = 0, size;
|
|
||||||
unsigned int * pCount = new unsigned int[HANDLESYS_TYPEARRAY_SIZE+1];
|
|
||||||
memset(pCount, 0, ((HANDLESYS_TYPEARRAY_SIZE + 1) * sizeof(unsigned int)));
|
|
||||||
|
|
||||||
for (unsigned int i = 1; i <= m_HandleTail; ++i)
|
|
||||||
{
|
|
||||||
const QHandle &Handle = m_Handles[i];
|
|
||||||
if (Handle.set != HandleSet_Used || Handle.owner != pIdentity)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
++pCount[Handle.type];
|
|
||||||
++total;
|
|
||||||
|
|
||||||
if (Handle.type >= highest_index)
|
|
||||||
{
|
|
||||||
highest_index = ((Handle.type) + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Handle.clone != 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_Types[Handle.type].dispatch->GetHandleApproxSize(Handle.type, Handle.object, &size))
|
|
||||||
{
|
|
||||||
total_size += size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const char * pTypeName = NULL;
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < highest_index; ++i)
|
|
||||||
{
|
|
||||||
if (pCount[i] == 0)
|
|
||||||
{
|
|
||||||
continue; /* We may have gaps, it's fine. */
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_Types[i].name)
|
|
||||||
pTypeName = m_Types[i].name->chars();
|
|
||||||
else
|
|
||||||
pTypeName = "ANON";
|
|
||||||
|
|
||||||
HANDLE_LOG_VERY_BAD("Type\t%-20.20s|\tCount\t%u", pTypeName, pCount[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
HANDLE_LOG_VERY_BAD("-- Approximately %d bytes of memory are in use by (%u) Handles.\n", total_size, total);
|
|
||||||
delete [] pCount;
|
|
||||||
|
|
||||||
highest_owner->GetBaseContext()->ThrowNativeErrorEx(SP_ERROR_MEMACCESS, "Memory leak");
|
highest_owner->GetBaseContext()->ThrowNativeErrorEx(SP_ERROR_MEMACCESS, "Memory leak");
|
||||||
|
|
||||||
return scripts->UnloadPlugin(highest_owner);
|
return g_PluginSys.UnloadPlugin(highest_owner);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HandleSystem::Dump(HANDLE_REPORTER rep)
|
void HandleSystem::Dump(HANDLE_REPORTER rep)
|
||||||
@@ -1086,20 +1056,20 @@ void HandleSystem::Dump(HANDLE_REPORTER rep)
|
|||||||
{
|
{
|
||||||
owner = "CORE";
|
owner = "CORE";
|
||||||
}
|
}
|
||||||
else if (pOwner == scripts->GetIdentity())
|
else if (pOwner == g_PluginSys.GetIdentity())
|
||||||
{
|
{
|
||||||
owner = "PLUGINSYS";
|
owner = "PLUGINSYS";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
IExtension *ext = g_Extensions.GetExtensionFromIdent(pOwner);
|
CExtension *ext = g_Extensions.GetExtensionFromIdent(pOwner);
|
||||||
if (ext)
|
if (ext)
|
||||||
{
|
{
|
||||||
owner = ext->GetFilename();
|
owner = ext->GetFilename();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SMPlugin *pPlugin = scripts->FindPluginByIdentity(pOwner);
|
CPlugin *pPlugin = g_PluginSys.GetPluginFromIdentity(pOwner);
|
||||||
if (pPlugin)
|
if (pPlugin)
|
||||||
{
|
{
|
||||||
owner = pPlugin->GetFilename();
|
owner = pPlugin->GetFilename();
|
||||||
@@ -1116,24 +1086,26 @@ void HandleSystem::Dump(HANDLE_REPORTER rep)
|
|||||||
unsigned int size = 0;
|
unsigned int size = 0;
|
||||||
unsigned int parentIdx;
|
unsigned int parentIdx;
|
||||||
bool bresult;
|
bool bresult;
|
||||||
if (pType->name)
|
if (pType->nameIdx != -1)
|
||||||
type = pType->name->chars();
|
|
||||||
|
|
||||||
if ((parentIdx = m_Handles[i].clone) != 0)
|
|
||||||
{
|
{
|
||||||
if (m_Handles[parentIdx].refcount > 0)
|
type = m_strtab->GetString(pType->nameIdx);
|
||||||
{
|
|
||||||
size = 0;
|
|
||||||
bresult = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
bresult = pType->dispatch->GetHandleApproxSize(m_Handles[parentIdx].type, m_Handles[parentIdx].object, &size);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
if ((parentIdx = m_Handles[i].clone) != 0)
|
||||||
bresult = pType->dispatch->GetHandleApproxSize(m_Handles[i].type, m_Handles[i].object, &size);
|
{
|
||||||
|
if (m_Handles[parentIdx].refcount > 0)
|
||||||
|
{
|
||||||
|
size = 0;
|
||||||
|
bresult = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bresult = pType->dispatch->GetHandleApproxSize(m_Handles[parentIdx].type, m_Handles[parentIdx].object, &size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bresult = pType->dispatch->GetHandleApproxSize(m_Handles[i].type, m_Handles[i].object, &size);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pType->dispatch->GetDispatchVersion() < HANDLESYS_MEMUSAGE_MIN_VERSION
|
if (pType->dispatch->GetDispatchVersion() < HANDLESYS_MEMUSAGE_MIN_VERSION
|
||||||
@@ -1144,7 +1116,7 @@ void HandleSystem::Dump(HANDLE_REPORTER rep)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
char buffer[32];
|
char buffer[32];
|
||||||
smcore.Format(buffer, sizeof(buffer), "%d", size);
|
UTIL_Format(buffer, sizeof(buffer), "%d", size);
|
||||||
rep("0x%08x\t%-20.20s\t%-20.20s\t%-10.10s", index, owner, type, buffer);
|
rep("0x%08x\t%-20.20s\t%-20.20s\t%-10.10s", index, owner, type, buffer);
|
||||||
total_size += size;
|
total_size += size;
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* vim: set ts=4 sw=4 tw=99 noet :
|
* vim: set ts=4 :
|
||||||
* =============================================================================
|
* =============================================================================
|
||||||
* SourceMod
|
* SourceMod
|
||||||
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
||||||
@@ -34,9 +34,10 @@
|
|||||||
|
|
||||||
#include <IHandleSys.h>
|
#include <IHandleSys.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sm_namehashset.h>
|
#include "sm_globals.h"
|
||||||
#include <am-string.h>
|
#include "sm_trie.h"
|
||||||
#include "common_logic.h"
|
#include "sourcemod.h"
|
||||||
|
#include "sm_memtable.h"
|
||||||
|
|
||||||
#define HANDLESYS_MAX_HANDLES (1<<14)
|
#define HANDLESYS_MAX_HANDLES (1<<14)
|
||||||
#define HANDLESYS_MAX_TYPES (1<<9)
|
#define HANDLESYS_MAX_TYPES (1<<9)
|
||||||
@@ -103,12 +104,7 @@ struct QHandleType
|
|||||||
TypeAccess typeSec;
|
TypeAccess typeSec;
|
||||||
HandleAccess hndlSec;
|
HandleAccess hndlSec;
|
||||||
unsigned int opened;
|
unsigned int opened;
|
||||||
ke::AutoPtr<ke::AString> name;
|
int nameIdx;
|
||||||
|
|
||||||
static inline bool matches(const char *key, const QHandleType *type)
|
|
||||||
{
|
|
||||||
return type->name && type->name->compare(key) == 0;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef void (HANDLE_REPORTER)(const char *str, ...);
|
typedef void (HANDLE_REPORTER)(const char *str, ...);
|
||||||
@@ -221,12 +217,13 @@ protected:
|
|||||||
private:
|
private:
|
||||||
QHandle *m_Handles;
|
QHandle *m_Handles;
|
||||||
QHandleType *m_Types;
|
QHandleType *m_Types;
|
||||||
NameHashSet<QHandleType *> m_TypeLookup;
|
Trie *m_TypeLookup;
|
||||||
unsigned int m_TypeTail;
|
unsigned int m_TypeTail;
|
||||||
unsigned int m_FreeTypes;
|
unsigned int m_FreeTypes;
|
||||||
unsigned int m_HandleTail;
|
unsigned int m_HandleTail;
|
||||||
unsigned int m_FreeHandles;
|
unsigned int m_FreeHandles;
|
||||||
unsigned int m_HSerial;
|
unsigned int m_HSerial;
|
||||||
|
BaseStringTable *m_strtab;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern HandleSystem g_HandleSys;
|
extern HandleSystem g_HandleSys;
|
||||||
+16
-40
@@ -36,13 +36,10 @@
|
|||||||
#include "Logger.h"
|
#include "Logger.h"
|
||||||
#include "LibrarySys.h"
|
#include "LibrarySys.h"
|
||||||
#include "TimerSys.h"
|
#include "TimerSys.h"
|
||||||
#include "logic_bridge.h"
|
|
||||||
#include <sourcemod_version.h>
|
#include <sourcemod_version.h>
|
||||||
|
|
||||||
Logger g_Logger;
|
Logger g_Logger;
|
||||||
|
|
||||||
SH_DECL_HOOK1_void(IVEngineServer, LogPrint, SH_NOATTRIB, false, const char *);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* :TODO: This should be creating the log folder if it doesn't exist
|
* :TODO: This should be creating the log folder if it doesn't exist
|
||||||
*/
|
*/
|
||||||
@@ -94,27 +91,14 @@ ConfigResult Logger::OnSourceModConfigChanged(const char *key,
|
|||||||
return ConfigResult_Ignore;
|
return ConfigResult_Ignore;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void HookLogPrint(const char *message)
|
|
||||||
{
|
|
||||||
g_in_game_log_hook = true;
|
|
||||||
bool stopped = logicore.OnLogPrint(message);
|
|
||||||
g_in_game_log_hook = false;
|
|
||||||
|
|
||||||
if (stopped)
|
|
||||||
RETURN_META(MRES_SUPERCEDE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Logger::OnSourceModStartup(bool late)
|
void Logger::OnSourceModStartup(bool late)
|
||||||
{
|
{
|
||||||
InitLogger(m_Mode);
|
InitLogger(m_Mode);
|
||||||
|
|
||||||
SH_ADD_HOOK(IVEngineServer, LogPrint, engine, SH_STATIC(HookLogPrint), false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Logger::OnSourceModAllShutdown()
|
void Logger::OnSourceModAllShutdown()
|
||||||
{
|
{
|
||||||
CloseLogger();
|
CloseLogger();
|
||||||
SH_REMOVE_HOOK(IVEngineServer, LogPrint, engine, SH_STATIC(HookLogPrint), false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Logger::OnSourceModLevelChange(const char *mapName)
|
void Logger::OnSourceModLevelChange(const char *mapName)
|
||||||
@@ -165,7 +149,7 @@ void Logger::_NewMapFile()
|
|||||||
} else {
|
} else {
|
||||||
char date[32];
|
char date[32];
|
||||||
strftime(date, sizeof(date), "%m/%d/%Y - %H:%M:%S", curtime);
|
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);
|
fprintf(fp, "L %s: SourceMod log file started (file \"L%02d%02d%03d.log\") (Version \"%s\")\n", date, curtime->tm_mon + 1, curtime->tm_mday, i, SM_VERSION_STRING);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -212,8 +196,7 @@ void Logger::InitLogger(LoggingMode mode)
|
|||||||
time_t t;
|
time_t t;
|
||||||
GetAdjustedTime(&t);
|
GetAdjustedTime(&t);
|
||||||
tm *curtime = localtime(&t);
|
tm *curtime = localtime(&t);
|
||||||
m_NrmCurDay = curtime->tm_mday;
|
m_CurDay = curtime->tm_mday;
|
||||||
m_ErrCurDay = curtime->tm_mday;
|
|
||||||
|
|
||||||
char _filename[256];
|
char _filename[256];
|
||||||
g_SourceMod.BuildPath(Path_SM, _filename, sizeof(_filename), "logs/errors_%04d%02d%02d.log", curtime->tm_year + 1900, curtime->tm_mon + 1, curtime->tm_mday);
|
g_SourceMod.BuildPath(Path_SM, _filename, sizeof(_filename), "logs/errors_%04d%02d%02d.log", curtime->tm_year + 1900, curtime->tm_mon + 1, curtime->tm_mday);
|
||||||
@@ -322,14 +305,6 @@ void Logger::LogToFileOnlyEx(FILE *fp, const char *msg, va_list ap)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Logger::LogMessage(const char *vafmt, ...)
|
void Logger::LogMessage(const char *vafmt, ...)
|
||||||
{
|
|
||||||
va_list ap;
|
|
||||||
va_start(ap, vafmt);
|
|
||||||
LogMessageEx(vafmt, ap);
|
|
||||||
va_end(ap);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Logger::LogMessageEx(const char *vafmt, va_list ap)
|
|
||||||
{
|
{
|
||||||
if (!m_Active)
|
if (!m_Active)
|
||||||
{
|
{
|
||||||
@@ -338,7 +313,10 @@ void Logger::LogMessageEx(const char *vafmt, va_list ap)
|
|||||||
|
|
||||||
if (m_Mode == LoggingMode_Game)
|
if (m_Mode == LoggingMode_Game)
|
||||||
{
|
{
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, vafmt);
|
||||||
_PrintToGameLog(vafmt, ap);
|
_PrintToGameLog(vafmt, ap);
|
||||||
|
va_end(ap);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -366,12 +344,12 @@ void Logger::LogMessageEx(const char *vafmt, va_list ap)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (m_NrmCurDay != curtime->tm_mday)
|
if (m_CurDay != curtime->tm_mday)
|
||||||
{
|
{
|
||||||
char _filename[256];
|
char _filename[256];
|
||||||
g_SourceMod.BuildPath(Path_SM, _filename, sizeof(_filename), "logs/L%04d%02d%02d.log", curtime->tm_year + 1900, curtime->tm_mon + 1, curtime->tm_mday);
|
g_SourceMod.BuildPath(Path_SM, _filename, sizeof(_filename), "logs/L%04d%02d%02d.log", curtime->tm_year + 1900, curtime->tm_mon + 1, curtime->tm_mday);
|
||||||
m_NrmFileName.assign(_filename);
|
m_NrmFileName.assign(_filename);
|
||||||
m_NrmCurDay = curtime->tm_mday;
|
m_CurDay = curtime->tm_mday;
|
||||||
m_DailyPrintHdr = true;
|
m_DailyPrintHdr = true;
|
||||||
}
|
}
|
||||||
fp = fopen(m_NrmFileName.c_str(), "a+");
|
fp = fopen(m_NrmFileName.c_str(), "a+");
|
||||||
@@ -384,9 +362,12 @@ void Logger::LogMessageEx(const char *vafmt, va_list ap)
|
|||||||
char date[32];
|
char date[32];
|
||||||
m_DailyPrintHdr = false;
|
m_DailyPrintHdr = false;
|
||||||
strftime(date, sizeof(date), "%m/%d/%Y - %H:%M:%S", curtime);
|
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);
|
fprintf(fp, "L %s: SourceMod log file session started (file \"L%04d%02d%02d.log\") (Version \"%s\")\n", date, curtime->tm_year + 1900, curtime->tm_mon + 1, curtime->tm_mday, SM_VERSION_STRING);
|
||||||
}
|
}
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, vafmt);
|
||||||
LogToOpenFileEx(fp, vafmt, ap);
|
LogToOpenFileEx(fp, vafmt, ap);
|
||||||
|
va_end(ap);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
} else {
|
} else {
|
||||||
goto print_error;
|
goto print_error;
|
||||||
@@ -421,12 +402,12 @@ void Logger::LogErrorEx(const char *vafmt, va_list ap)
|
|||||||
GetAdjustedTime(&t);
|
GetAdjustedTime(&t);
|
||||||
tm *curtime = localtime(&t);
|
tm *curtime = localtime(&t);
|
||||||
|
|
||||||
if (curtime->tm_mday != m_ErrCurDay)
|
if (curtime->tm_mday != m_CurDay)
|
||||||
{
|
{
|
||||||
char _filename[256];
|
char _filename[256];
|
||||||
g_SourceMod.BuildPath(Path_SM, _filename, sizeof(_filename), "logs/errors_%04d%02d%02d.log", curtime->tm_year + 1900, curtime->tm_mon + 1, curtime->tm_mday);
|
g_SourceMod.BuildPath(Path_SM, _filename, sizeof(_filename), "logs/errors_%04d%02d%02d.log", curtime->tm_year + 1900, curtime->tm_mon + 1, curtime->tm_mday);
|
||||||
m_ErrFileName.assign(_filename);
|
m_ErrFileName.assign(_filename);
|
||||||
m_ErrCurDay = curtime->tm_mday;
|
m_CurDay = curtime->tm_mday;
|
||||||
m_ErrMapStart = false;
|
m_ErrMapStart = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -545,20 +526,13 @@ void Logger::DisableLogging()
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Logger::LogFatal(const char *msg, ...)
|
void Logger::LogFatal(const char *msg, ...)
|
||||||
{
|
|
||||||
va_list ap;
|
|
||||||
va_start(ap, msg);
|
|
||||||
LogFatalEx(msg, ap);
|
|
||||||
va_end(ap);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Logger::LogFatalEx(const char *msg, va_list ap)
|
|
||||||
{
|
{
|
||||||
/* :TODO: make this print all pretty-like
|
/* :TODO: make this print all pretty-like
|
||||||
* In fact, the pretty log printing function should be abstracted.
|
* In fact, the pretty log printing function should be abstracted.
|
||||||
* It's already implemented twice which is bad.
|
* It's already implemented twice which is bad.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
va_list ap;
|
||||||
char path[PLATFORM_MAX_PATH];
|
char path[PLATFORM_MAX_PATH];
|
||||||
|
|
||||||
g_SourceMod.BuildPath(Path_Game, path, sizeof(path), "sourcemod_fatal.log");
|
g_SourceMod.BuildPath(Path_Game, path, sizeof(path), "sourcemod_fatal.log");
|
||||||
@@ -567,7 +541,9 @@ void Logger::LogFatalEx(const char *msg, va_list ap)
|
|||||||
if (fp)
|
if (fp)
|
||||||
{
|
{
|
||||||
m_Active = true;
|
m_Active = true;
|
||||||
|
va_start(ap, msg);
|
||||||
LogToOpenFileEx(fp, msg, ap);
|
LogToOpenFileEx(fp, msg, ap);
|
||||||
|
va_end(ap);
|
||||||
m_Active = false;
|
m_Active = false;
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-4
@@ -74,11 +74,9 @@ public:
|
|||||||
void EnableLogging();
|
void EnableLogging();
|
||||||
void DisableLogging();
|
void DisableLogging();
|
||||||
void LogMessage(const char *msg, ...);
|
void LogMessage(const char *msg, ...);
|
||||||
void LogMessageEx(const char *msg, va_list ap);
|
|
||||||
void LogError(const char *msg, ...);
|
void LogError(const char *msg, ...);
|
||||||
void LogErrorEx(const char *msg, va_list ap);
|
void LogErrorEx(const char *msg, va_list ap);
|
||||||
void LogFatal(const char *msg, ...);
|
void LogFatal(const char *msg, ...);
|
||||||
void LogFatalEx(const char *msg, va_list ap);
|
|
||||||
void LogToOpenFile(FILE *fp, const char *msg, ...);
|
void LogToOpenFile(FILE *fp, const char *msg, ...);
|
||||||
void LogToOpenFileEx(FILE *fp, const char *msg, va_list ap);
|
void LogToOpenFileEx(FILE *fp, const char *msg, va_list ap);
|
||||||
/* This version does not print to console, and is thus thread-safe */
|
/* This version does not print to console, and is thus thread-safe */
|
||||||
@@ -96,8 +94,7 @@ private:
|
|||||||
String m_ErrFileName;
|
String m_ErrFileName;
|
||||||
String m_CurMapName;
|
String m_CurMapName;
|
||||||
LoggingMode m_Mode;
|
LoggingMode m_Mode;
|
||||||
int m_NrmCurDay;
|
int m_CurDay;
|
||||||
int m_ErrCurDay;
|
|
||||||
bool m_ErrMapStart;
|
bool m_ErrMapStart;
|
||||||
bool m_Active;
|
bool m_Active;
|
||||||
bool m_DelayedStart;
|
bool m_DelayedStart;
|
||||||
|
|||||||
+12
-10
@@ -38,6 +38,8 @@
|
|||||||
#include "sourcemm_api.h"
|
#include "sourcemm_api.h"
|
||||||
#include "PlayerManager.h"
|
#include "PlayerManager.h"
|
||||||
#include "MenuStyle_Valve.h"
|
#include "MenuStyle_Valve.h"
|
||||||
|
#include "ShareSys.h"
|
||||||
|
#include "HandleSys.h"
|
||||||
#include "sourcemm_api.h"
|
#include "sourcemm_api.h"
|
||||||
#include "logic_bridge.h"
|
#include "logic_bridge.h"
|
||||||
|
|
||||||
@@ -54,24 +56,24 @@ MenuManager::MenuManager()
|
|||||||
|
|
||||||
void MenuManager::OnSourceModAllInitialized()
|
void MenuManager::OnSourceModAllInitialized()
|
||||||
{
|
{
|
||||||
sharesys->AddInterface(NULL, this);
|
g_ShareSys.AddInterface(NULL, this);
|
||||||
|
|
||||||
HandleAccess access;
|
HandleAccess access;
|
||||||
handlesys->InitAccessDefaults(NULL, &access);
|
g_HandleSys.InitAccessDefaults(NULL, &access);
|
||||||
|
|
||||||
/* Deny cloning to menus */
|
/* Deny cloning to menus */
|
||||||
access.access[HandleAccess_Clone] = HANDLE_RESTRICT_OWNER|HANDLE_RESTRICT_IDENTITY;
|
access.access[HandleAccess_Clone] = HANDLE_RESTRICT_OWNER|HANDLE_RESTRICT_IDENTITY;
|
||||||
m_MenuType = handlesys->CreateType("IBaseMenu", this, 0, NULL, &access, g_pCoreIdent, NULL);
|
m_MenuType = g_HandleSys.CreateType("IBaseMenu", this, 0, NULL, &access, g_pCoreIdent, NULL);
|
||||||
|
|
||||||
/* Also deny deletion to styles */
|
/* Also deny deletion to styles */
|
||||||
access.access[HandleAccess_Delete] = HANDLE_RESTRICT_OWNER|HANDLE_RESTRICT_IDENTITY;
|
access.access[HandleAccess_Delete] = HANDLE_RESTRICT_OWNER|HANDLE_RESTRICT_IDENTITY;
|
||||||
m_StyleType = handlesys->CreateType("IMenuStyle", this, 0, NULL, &access, g_pCoreIdent, NULL);
|
m_StyleType = g_HandleSys.CreateType("IMenuStyle", this, 0, NULL, &access, g_pCoreIdent, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MenuManager::OnSourceModAllShutdown()
|
void MenuManager::OnSourceModAllShutdown()
|
||||||
{
|
{
|
||||||
handlesys->RemoveType(m_MenuType, g_pCoreIdent);
|
g_HandleSys.RemoveType(m_MenuType, g_pCoreIdent);
|
||||||
handlesys->RemoveType(m_StyleType, g_pCoreIdent);
|
g_HandleSys.RemoveType(m_StyleType, g_pCoreIdent);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MenuManager::OnHandleDestroy(HandleType_t type, void *object)
|
void MenuManager::OnHandleDestroy(HandleType_t type, void *object)
|
||||||
@@ -110,7 +112,7 @@ Handle_t MenuManager::CreateMenuHandle(IBaseMenu *menu, IdentityToken_t *pOwner)
|
|||||||
return BAD_HANDLE;
|
return BAD_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return handlesys->CreateHandle(m_MenuType, menu, pOwner, g_pCoreIdent, NULL);
|
return g_HandleSys.CreateHandle(m_MenuType, menu, pOwner, g_pCoreIdent, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle_t MenuManager::CreateStyleHandle(IMenuStyle *style)
|
Handle_t MenuManager::CreateStyleHandle(IMenuStyle *style)
|
||||||
@@ -120,7 +122,7 @@ Handle_t MenuManager::CreateStyleHandle(IMenuStyle *style)
|
|||||||
return BAD_HANDLE;
|
return BAD_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return handlesys->CreateHandle(m_StyleType, style, g_pCoreIdent, g_pCoreIdent, NULL);
|
return g_HandleSys.CreateHandle(m_StyleType, style, g_pCoreIdent, g_pCoreIdent, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
HandleError MenuManager::ReadMenuHandle(Handle_t handle, IBaseMenu **menu)
|
HandleError MenuManager::ReadMenuHandle(Handle_t handle, IBaseMenu **menu)
|
||||||
@@ -130,7 +132,7 @@ HandleError MenuManager::ReadMenuHandle(Handle_t handle, IBaseMenu **menu)
|
|||||||
sec.pIdentity = g_pCoreIdent;
|
sec.pIdentity = g_pCoreIdent;
|
||||||
sec.pOwner = NULL;
|
sec.pOwner = NULL;
|
||||||
|
|
||||||
return handlesys->ReadHandle(handle, m_MenuType, &sec, (void **)menu);
|
return g_HandleSys.ReadHandle(handle, m_MenuType, &sec, (void **)menu);
|
||||||
}
|
}
|
||||||
|
|
||||||
HandleError MenuManager::ReadStyleHandle(Handle_t handle, IMenuStyle **style)
|
HandleError MenuManager::ReadStyleHandle(Handle_t handle, IMenuStyle **style)
|
||||||
@@ -140,7 +142,7 @@ HandleError MenuManager::ReadStyleHandle(Handle_t handle, IMenuStyle **style)
|
|||||||
sec.pIdentity = g_pCoreIdent;
|
sec.pIdentity = g_pCoreIdent;
|
||||||
sec.pOwner = g_pCoreIdent;
|
sec.pOwner = g_pCoreIdent;
|
||||||
|
|
||||||
return handlesys->ReadHandle(handle, m_StyleType, &sec, (void **)style);
|
return g_HandleSys.ReadHandle(handle, m_StyleType, &sec, (void **)style);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MenuManager::SetDefaultStyle(IMenuStyle *style)
|
bool MenuManager::SetDefaultStyle(IMenuStyle *style)
|
||||||
|
|||||||
@@ -37,6 +37,7 @@
|
|||||||
#include <sh_stack.h>
|
#include <sh_stack.h>
|
||||||
#include <sh_list.h>
|
#include <sh_list.h>
|
||||||
#include <sh_string.h>
|
#include <sh_string.h>
|
||||||
|
#include "sm_memtable.h"
|
||||||
#include "sm_globals.h"
|
#include "sm_globals.h"
|
||||||
|
|
||||||
using namespace SourceMod;
|
using namespace SourceMod;
|
||||||
|
|||||||
+46
-25
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* vim: set ts=4 sw=4 tw=99 noet :
|
* vim: set ts=4 :
|
||||||
* =============================================================================
|
* =============================================================================
|
||||||
* SourceMod
|
* SourceMod
|
||||||
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
||||||
@@ -34,12 +34,11 @@
|
|||||||
#include "MenuStyle_Base.h"
|
#include "MenuStyle_Base.h"
|
||||||
#include "PlayerManager.h"
|
#include "PlayerManager.h"
|
||||||
#include "MenuManager.h"
|
#include "MenuManager.h"
|
||||||
|
#include "HandleSys.h"
|
||||||
#include "CellRecipientFilter.h"
|
#include "CellRecipientFilter.h"
|
||||||
#if defined MENU_DEBUG
|
#if defined MENU_DEBUG
|
||||||
#include "Logger.h"
|
#include "Logger.h"
|
||||||
#endif
|
#endif
|
||||||
#include "logic_bridge.h"
|
|
||||||
#include "AutoHandleRooter.h"
|
|
||||||
|
|
||||||
BaseMenuStyle::BaseMenuStyle() : m_WatchList(256), m_hHandle(BAD_HANDLE)
|
BaseMenuStyle::BaseMenuStyle() : m_WatchList(256), m_hHandle(BAD_HANDLE)
|
||||||
{
|
{
|
||||||
@@ -338,7 +337,7 @@ void BaseMenuStyle::ClientPressedKey(int client, unsigned int key_press)
|
|||||||
#endif
|
#endif
|
||||||
0,
|
0,
|
||||||
PITCH_NORM,
|
PITCH_NORM,
|
||||||
#if SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_SDK2013 || SOURCE_ENGINE == SE_TF2
|
#if SOURCE_ENGINE == SE_CSS || SOURCE_ENGINE == SE_HL2DM || SOURCE_ENGINE == SE_DODS || SOURCE_ENGINE == SE_TF2
|
||||||
0,
|
0,
|
||||||
#endif
|
#endif
|
||||||
&pos);
|
&pos);
|
||||||
@@ -604,7 +603,7 @@ bool BaseMenuStyle::RedoClientMenu(int client, ItemOrder order)
|
|||||||
}
|
}
|
||||||
|
|
||||||
CBaseMenu::CBaseMenu(IMenuHandler *pHandler, IMenuStyle *pStyle, IdentityToken_t *pOwner) :
|
CBaseMenu::CBaseMenu(IMenuHandler *pHandler, IMenuStyle *pStyle, IdentityToken_t *pOwner) :
|
||||||
m_pStyle(pStyle), m_Pagination(7), m_bShouldDelete(false), m_bCancelling(false),
|
m_pStyle(pStyle), m_Strings(512), m_Pagination(7), m_bShouldDelete(false), m_bCancelling(false),
|
||||||
m_pOwner(pOwner ? pOwner : g_pCoreIdent), m_bDeleting(false), m_bWillFreeHandle(false),
|
m_pOwner(pOwner ? pOwner : g_pCoreIdent), m_bDeleting(false), m_bWillFreeHandle(false),
|
||||||
m_hHandle(BAD_HANDLE), m_pHandler(pHandler), m_nFlags(MENUFLAG_BUTTON_EXIT)
|
m_hHandle(BAD_HANDLE), m_pHandler(pHandler), m_nFlags(MENUFLAG_BUTTON_EXIT)
|
||||||
{
|
{
|
||||||
@@ -627,74 +626,94 @@ Handle_t CBaseMenu::GetHandle()
|
|||||||
bool CBaseMenu::AppendItem(const char *info, const ItemDrawInfo &draw)
|
bool CBaseMenu::AppendItem(const char *info, const ItemDrawInfo &draw)
|
||||||
{
|
{
|
||||||
if (m_Pagination == (unsigned)MENU_NO_PAGINATION
|
if (m_Pagination == (unsigned)MENU_NO_PAGINATION
|
||||||
&& m_items.length() >= m_pStyle->GetMaxPageItems())
|
&& m_items.size() >= m_pStyle->GetMaxPageItems())
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
CItem item;
|
CItem item;
|
||||||
|
|
||||||
item.info = info;
|
item.infoString = m_Strings.AddString(info);
|
||||||
if (draw.display)
|
if (draw.display)
|
||||||
item.display = new ke::AString(draw.display);
|
{
|
||||||
|
item.displayString = m_Strings.AddString(draw.display);
|
||||||
|
}
|
||||||
item.style = draw.style;
|
item.style = draw.style;
|
||||||
|
|
||||||
m_items.append(ke::Move(item));
|
m_items.push_back(item);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CBaseMenu::InsertItem(unsigned int position, const char *info, const ItemDrawInfo &draw)
|
bool CBaseMenu::InsertItem(unsigned int position, const char *info, const ItemDrawInfo &draw)
|
||||||
{
|
{
|
||||||
if (m_Pagination == (unsigned)MENU_NO_PAGINATION &&
|
if (m_Pagination == (unsigned)MENU_NO_PAGINATION
|
||||||
m_items.length() >= m_pStyle->GetMaxPageItems())
|
&& m_items.size() >= m_pStyle->GetMaxPageItems())
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (position >= m_items.length())
|
if (position >= m_items.size())
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
CItem item;
|
CItem item;
|
||||||
item.info = info;
|
item.infoString = m_Strings.AddString(info);
|
||||||
if (draw.display)
|
if (draw.display)
|
||||||
item.display = new ke::AString(draw.display);
|
{
|
||||||
|
item.displayString = m_Strings.AddString(draw.display);
|
||||||
|
}
|
||||||
item.style = draw.style;
|
item.style = draw.style;
|
||||||
|
|
||||||
m_items.insert(position, ke::Move(item));
|
CVector<CItem>::iterator iter = m_items.iterAt(position);
|
||||||
|
m_items.insert(iter, item);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CBaseMenu::RemoveItem(unsigned int position)
|
bool CBaseMenu::RemoveItem(unsigned int position)
|
||||||
{
|
{
|
||||||
if (position >= m_items.length())
|
if (position >= m_items.size())
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_items.erase(m_items.iterAt(position));
|
||||||
|
|
||||||
|
if (m_items.size() == 0)
|
||||||
|
{
|
||||||
|
m_Strings.Reset();
|
||||||
|
}
|
||||||
|
|
||||||
m_items.remove(position);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBaseMenu::RemoveAllItems()
|
void CBaseMenu::RemoveAllItems()
|
||||||
{
|
{
|
||||||
m_items.clear();
|
m_items.clear();
|
||||||
|
m_Strings.Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *CBaseMenu::GetItemInfo(unsigned int position, ItemDrawInfo *draw/* =NULL */)
|
const char *CBaseMenu::GetItemInfo(unsigned int position, ItemDrawInfo *draw/* =NULL */)
|
||||||
{
|
{
|
||||||
if (position >= m_items.length())
|
if (position >= m_items.size())
|
||||||
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (draw)
|
if (draw)
|
||||||
{
|
{
|
||||||
draw->display = m_items[position].display->chars();
|
draw->display = m_Strings.GetString(m_items[position].displayString);
|
||||||
draw->style = m_items[position].style;
|
draw->style = m_items[position].style;
|
||||||
}
|
}
|
||||||
|
|
||||||
return m_items[position].info.chars();
|
return m_Strings.GetString(m_items[position].infoString);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int CBaseMenu::GetItemCount()
|
unsigned int CBaseMenu::GetItemCount()
|
||||||
{
|
{
|
||||||
return m_items.length();
|
return m_items.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CBaseMenu::SetPagination(unsigned int itemsPerPage)
|
bool CBaseMenu::SetPagination(unsigned int itemsPerPage)
|
||||||
@@ -727,12 +746,12 @@ IMenuStyle *CBaseMenu::GetDrawStyle()
|
|||||||
|
|
||||||
void CBaseMenu::SetDefaultTitle(const char *message)
|
void CBaseMenu::SetDefaultTitle(const char *message)
|
||||||
{
|
{
|
||||||
m_Title = message;
|
m_Title.assign(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *CBaseMenu::GetDefaultTitle()
|
const char *CBaseMenu::GetDefaultTitle()
|
||||||
{
|
{
|
||||||
return m_Title.chars();
|
return m_Title.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBaseMenu::Cancel()
|
void CBaseMenu::Cancel()
|
||||||
@@ -799,7 +818,7 @@ void CBaseMenu::InternalDelete()
|
|||||||
|
|
||||||
m_hHandle = BAD_HANDLE;
|
m_hHandle = BAD_HANDLE;
|
||||||
m_bDeleting = true;
|
m_bDeleting = true;
|
||||||
handlesys->FreeHandle(hndl, &sec);
|
g_HandleSys.FreeHandle(hndl, &sec);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_pHandler->OnMenuDestroy(this);
|
m_pHandler->OnMenuDestroy(this);
|
||||||
@@ -824,5 +843,7 @@ IMenuHandler *CBaseMenu::GetHandler()
|
|||||||
|
|
||||||
unsigned int CBaseMenu::GetBaseMemUsage()
|
unsigned int CBaseMenu::GetBaseMemUsage()
|
||||||
{
|
{
|
||||||
return m_Title.length() + (m_items.length() * sizeof(CItem));
|
return m_Title.size()
|
||||||
|
+ m_Strings.GetMemTable()->GetMemUsage()
|
||||||
|
+ (m_items.size() * sizeof(CItem));
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-27
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* vim: set ts=4 sw=4 tw=99 noet :
|
* vim: set ts=4 :
|
||||||
* =============================================================================
|
* =============================================================================
|
||||||
* SourceMod
|
* SourceMod
|
||||||
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
||||||
@@ -34,45 +34,29 @@
|
|||||||
|
|
||||||
#include <IMenuManager.h>
|
#include <IMenuManager.h>
|
||||||
#include <IPlayerHelpers.h>
|
#include <IPlayerHelpers.h>
|
||||||
#include <am-string.h>
|
#include <sh_string.h>
|
||||||
#include <am-vector.h>
|
#include <sh_vector.h>
|
||||||
|
#include "sm_memtable.h"
|
||||||
#include "sm_fastlink.h"
|
#include "sm_fastlink.h"
|
||||||
|
|
||||||
using namespace SourceMod;
|
using namespace SourceMod;
|
||||||
|
using namespace SourceHook;
|
||||||
|
|
||||||
class CItem
|
class CItem
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CItem()
|
CItem()
|
||||||
{
|
{
|
||||||
|
infoString = -1;
|
||||||
|
displayString = -1;
|
||||||
style = 0;
|
style = 0;
|
||||||
access = 0;
|
access = 0;
|
||||||
}
|
}
|
||||||
CItem(ke::Moveable<CItem> other)
|
|
||||||
: info(ke::Move(other->info)),
|
|
||||||
display(ke::Move(other->display))
|
|
||||||
{
|
|
||||||
style = other->style;
|
|
||||||
access = other->access;
|
|
||||||
}
|
|
||||||
CItem & operator =(ke::Moveable<CItem> other)
|
|
||||||
{
|
|
||||||
info = ke::Move(other->info);
|
|
||||||
display = ke::Move(other->display);
|
|
||||||
style = other->style;
|
|
||||||
access = other->access;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ke::AString info;
|
int infoString;
|
||||||
ke::AutoPtr<ke::AString> display;
|
int displayString;
|
||||||
unsigned int style;
|
unsigned int style;
|
||||||
unsigned int access;
|
unsigned int access;
|
||||||
|
|
||||||
private:
|
|
||||||
CItem(const CItem &other) KE_DELETE;
|
|
||||||
CItem &operator =(const CItem &other) KE_DELETE;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class CBaseMenuPlayer
|
class CBaseMenuPlayer
|
||||||
@@ -155,10 +139,11 @@ public:
|
|||||||
private:
|
private:
|
||||||
void InternalDelete();
|
void InternalDelete();
|
||||||
protected:
|
protected:
|
||||||
ke::AString m_Title;
|
String m_Title;
|
||||||
IMenuStyle *m_pStyle;
|
IMenuStyle *m_pStyle;
|
||||||
|
BaseStringTable m_Strings;
|
||||||
unsigned int m_Pagination;
|
unsigned int m_Pagination;
|
||||||
ke::Vector<CItem> m_items;
|
CVector<CItem> m_items;
|
||||||
bool m_bShouldDelete;
|
bool m_bShouldDelete;
|
||||||
bool m_bCancelling;
|
bool m_bCancelling;
|
||||||
IdentityToken_t *m_pOwner;
|
IdentityToken_t *m_pOwner;
|
||||||
|
|||||||
@@ -138,11 +138,7 @@ void CRadioStyle::OnSourceModShutdown()
|
|||||||
|
|
||||||
bool CRadioStyle::IsSupported()
|
bool CRadioStyle::IsSupported()
|
||||||
{
|
{
|
||||||
#if SOURCE_ENGINE == SE_DOTA
|
|
||||||
return false;
|
|
||||||
#else
|
|
||||||
return (g_ShowMenuId != -1);
|
return (g_ShowMenuId != -1);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CRadioStyle::OnClientCommand(int client, const char *cmdname, const CCommand &cmd)
|
bool CRadioStyle::OnClientCommand(int client, const char *cmdname, const CCommand &cmd)
|
||||||
@@ -173,7 +169,6 @@ void CRadioStyle::OnUserMessage(int msg_id, protobuf::Message &msg, IRecipientFi
|
|||||||
void CRadioStyle::OnUserMessage(int msg_id, bf_write *bf, IRecipientFilter *pFilter)
|
void CRadioStyle::OnUserMessage(int msg_id, bf_write *bf, IRecipientFilter *pFilter)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
#if SOURCE_ENGINE != SE_DOTA
|
|
||||||
int count = pFilter->GetRecipientCount();
|
int count = pFilter->GetRecipientCount();
|
||||||
|
|
||||||
#ifdef USE_PROTOBUF_USERMESSAGES
|
#ifdef USE_PROTOBUF_USERMESSAGES
|
||||||
@@ -191,7 +186,6 @@ void CRadioStyle::OnUserMessage(int msg_id, bf_write *bf, IRecipientFilter *pFil
|
|||||||
{
|
{
|
||||||
g_last_clients[g_last_client_count++] = pFilter->GetRecipientIndex(i);
|
g_last_clients[g_last_client_count++] = pFilter->GetRecipientIndex(i);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CRadioStyle::OnUserMessageSent(int msg_id)
|
void CRadioStyle::OnUserMessageSent(int msg_id)
|
||||||
@@ -479,8 +473,7 @@ void CRadioMenuPlayer::Radio_Init(int keys, const char *title, const char *text)
|
|||||||
|
|
||||||
void CRadioMenuPlayer::Radio_Refresh()
|
void CRadioMenuPlayer::Radio_Refresh()
|
||||||
{
|
{
|
||||||
#if SOURCE_ENGINE != SE_DOTA
|
cell_t players[1] = {m_index};
|
||||||
cell_t players[1] = { (cell_t)m_index };
|
|
||||||
char *ptr = display_pkt;
|
char *ptr = display_pkt;
|
||||||
char save = 0;
|
char save = 0;
|
||||||
size_t len = display_len;
|
size_t len = display_len;
|
||||||
@@ -533,7 +526,6 @@ void CRadioMenuPlayer::Radio_Refresh()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
display_last_refresh = gpGlobals->curtime;
|
display_last_refresh = gpGlobals->curtime;
|
||||||
#endif // !DOTA
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int CRadioDisplay::GetAmountRemaining()
|
int CRadioDisplay::GetAmountRemaining()
|
||||||
|
|||||||
@@ -65,20 +65,16 @@ bool ValveMenuStyle::OnClientCommand(int client, const char *cmdname, const CCom
|
|||||||
|
|
||||||
void ValveMenuStyle::OnSourceModAllInitialized()
|
void ValveMenuStyle::OnSourceModAllInitialized()
|
||||||
{
|
{
|
||||||
#if SOURCE_ENGINE != SE_DOTA
|
|
||||||
g_Players.AddClientListener(this);
|
g_Players.AddClientListener(this);
|
||||||
SH_ADD_HOOK(IServerPluginHelpers, CreateMessage, serverpluginhelpers, SH_MEMBER(this, &ValveMenuStyle::HookCreateMessage), false);
|
SH_ADD_HOOK_MEMFUNC(IServerPluginHelpers, CreateMessage, serverpluginhelpers, this, &ValveMenuStyle::HookCreateMessage, false);
|
||||||
g_pSPHCC = SH_GET_CALLCLASS(serverpluginhelpers);
|
g_pSPHCC = SH_GET_CALLCLASS(serverpluginhelpers);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ValveMenuStyle::OnSourceModShutdown()
|
void ValveMenuStyle::OnSourceModShutdown()
|
||||||
{
|
{
|
||||||
#if SOURCE_ENGINE != SE_DOTA
|
|
||||||
SH_RELEASE_CALLCLASS(g_pSPHCC);
|
SH_RELEASE_CALLCLASS(g_pSPHCC);
|
||||||
SH_REMOVE_HOOK(IServerPluginHelpers, CreateMessage, serverpluginhelpers, SH_MEMBER(this, &ValveMenuStyle::HookCreateMessage), false);
|
SH_REMOVE_HOOK_MEMFUNC(IServerPluginHelpers, CreateMessage, serverpluginhelpers, this, &ValveMenuStyle::HookCreateMessage, false);
|
||||||
g_Players.RemoveClientListener(this);
|
g_Players.RemoveClientListener(this);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ValveMenuStyle::HookCreateMessage(edict_t *pEdict,
|
void ValveMenuStyle::HookCreateMessage(edict_t *pEdict,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* vim: set ts=4 sw=4 tw=99 noet :
|
* vim: set ts=4 :
|
||||||
* =============================================================================
|
* =============================================================================
|
||||||
* SourcePawn
|
* SourcePawn
|
||||||
* Copyright (C) 2004-2009 AlliedModders LLC. All rights reserved.
|
* Copyright (C) 2004-2009 AlliedModders LLC. All rights reserved.
|
||||||
@@ -54,7 +54,7 @@ unsigned int NativeInterface::GetInterfaceVersion()
|
|||||||
|
|
||||||
void NativeInterface::OnSourceModAllInitialized()
|
void NativeInterface::OnSourceModAllInitialized()
|
||||||
{
|
{
|
||||||
sharesys->AddInterface(NULL, &g_NInvoke);
|
g_ShareSys.AddInterface(NULL, &g_NInvoke);
|
||||||
}
|
}
|
||||||
|
|
||||||
IPluginRuntime *NativeInterface::CreateRuntime(const char *name, size_t bytes)
|
IPluginRuntime *NativeInterface::CreateRuntime(const char *name, size_t bytes)
|
||||||
@@ -69,15 +69,30 @@ INativeInvoker *NativeInterface::CreateInvoker()
|
|||||||
|
|
||||||
bool NativeInvoker::Start(IPluginContext *pContext, const char *name)
|
bool NativeInvoker::Start(IPluginContext *pContext, const char *name)
|
||||||
{
|
{
|
||||||
ke::Ref<Native> entry = g_ShareSys.FindNative(name);
|
NativeEntry *entry;
|
||||||
if (!entry)
|
|
||||||
|
entry = g_ShareSys.FindNative(name);
|
||||||
|
if (entry == NULL)
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (!entry->owner)
|
native = NULL;
|
||||||
|
if (entry->replacement.owner != NULL)
|
||||||
|
{
|
||||||
|
native = entry->replacement.func;
|
||||||
|
}
|
||||||
|
else if (entry->owner != NULL)
|
||||||
|
{
|
||||||
|
native = entry->func;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (native == NULL)
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
native_ = entry->func();
|
this->pContext = pContext;
|
||||||
context_ = pContext;
|
|
||||||
|
|
||||||
m_curparam = 0;
|
m_curparam = 0;
|
||||||
m_errorstate = SP_ERROR_NONE;
|
m_errorstate = SP_ERROR_NONE;
|
||||||
@@ -169,13 +184,15 @@ int NativeInvoker::_PushString(const char *string, int sz_flags, int cp_flags, s
|
|||||||
|
|
||||||
void NativeInvoker::Cancel()
|
void NativeInvoker::Cancel()
|
||||||
{
|
{
|
||||||
if (context_ == NULL)
|
if (pContext == NULL)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
m_errorstate = SP_ERROR_NONE;
|
m_errorstate = SP_ERROR_NONE;
|
||||||
m_curparam = 0;
|
m_curparam = 0;
|
||||||
context_ = NULL;
|
pContext = NULL;
|
||||||
native_ = NULL;
|
native = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int NativeInvoker::SetError(int err)
|
int NativeInvoker::SetError(int err)
|
||||||
@@ -188,8 +205,10 @@ int NativeInvoker::Invoke(cell_t *result)
|
|||||||
{
|
{
|
||||||
int err = SP_ERROR_NONE;
|
int err = SP_ERROR_NONE;
|
||||||
|
|
||||||
if (context_ == NULL)
|
if (pContext == NULL)
|
||||||
|
{
|
||||||
return SP_ERROR_INVALID_NATIVE;
|
return SP_ERROR_INVALID_NATIVE;
|
||||||
|
}
|
||||||
|
|
||||||
if (m_errorstate != SP_ERROR_NONE)
|
if (m_errorstate != SP_ERROR_NONE)
|
||||||
{
|
{
|
||||||
@@ -206,7 +225,7 @@ int NativeInvoker::Invoke(cell_t *result)
|
|||||||
}
|
}
|
||||||
|
|
||||||
//This is for re-entrancy!
|
//This is for re-entrancy!
|
||||||
IPluginContext *ctx = context_;
|
IPluginContext *ctx = pContext;
|
||||||
cell_t _temp_params[SP_MAX_EXEC_PARAMS + 1];
|
cell_t _temp_params[SP_MAX_EXEC_PARAMS + 1];
|
||||||
cell_t *temp_params = &_temp_params[1];
|
cell_t *temp_params = &_temp_params[1];
|
||||||
ParamInfo temp_info[SP_MAX_EXEC_PARAMS];
|
ParamInfo temp_info[SP_MAX_EXEC_PARAMS];
|
||||||
@@ -220,7 +239,7 @@ int NativeInvoker::Invoke(cell_t *result)
|
|||||||
memcpy(temp_info, m_info, numparams * sizeof(ParamInfo));
|
memcpy(temp_info, m_info, numparams * sizeof(ParamInfo));
|
||||||
}
|
}
|
||||||
m_curparam = 0;
|
m_curparam = 0;
|
||||||
context_ = NULL;
|
pContext = NULL;
|
||||||
|
|
||||||
/* Initialize 0th parameter */
|
/* Initialize 0th parameter */
|
||||||
_temp_params[0] = numparams;
|
_temp_params[0] = numparams;
|
||||||
@@ -305,7 +324,7 @@ int NativeInvoker::Invoke(cell_t *result)
|
|||||||
/* Make the call if we can */
|
/* Make the call if we can */
|
||||||
if (err == SP_ERROR_NONE)
|
if (err == SP_ERROR_NONE)
|
||||||
{
|
{
|
||||||
*result = native_(ctx, _temp_params);
|
*result = native(ctx, _temp_params);
|
||||||
if (ctx->GetLastNativeError() != SP_ERROR_NONE)
|
if (ctx->GetLastNativeError() != SP_ERROR_NONE)
|
||||||
{
|
{
|
||||||
docopies = false;
|
docopies = false;
|
||||||
@@ -32,12 +32,8 @@
|
|||||||
#ifndef _INCLUDE_SOURCEMOD_NATIVE_INVOKER_H_
|
#ifndef _INCLUDE_SOURCEMOD_NATIVE_INVOKER_H_
|
||||||
#define _INCLUDE_SOURCEMOD_NATIVE_INVOKER_H_
|
#define _INCLUDE_SOURCEMOD_NATIVE_INVOKER_H_
|
||||||
|
|
||||||
#include <sp_vm_api.h>
|
#include "sm_globals.h"
|
||||||
#include <INativeInvoker.h>
|
#include <INativeInvoker.h>
|
||||||
#include "common_logic.h"
|
|
||||||
|
|
||||||
using namespace SourceMod;
|
|
||||||
using namespace SourcePawn;
|
|
||||||
|
|
||||||
struct ParamInfo
|
struct ParamInfo
|
||||||
{
|
{
|
||||||
@@ -75,8 +71,8 @@ private:
|
|||||||
int _PushString(const char *string, int sz_flags, int cp_flags, size_t len);
|
int _PushString(const char *string, int sz_flags, int cp_flags, size_t len);
|
||||||
int SetError(int err);
|
int SetError(int err);
|
||||||
private:
|
private:
|
||||||
IPluginContext *context_;
|
IPluginContext *pContext;
|
||||||
SPVM_NATIVE_FUNC native_;
|
SPVM_NATIVE_FUNC native;
|
||||||
cell_t m_params[SP_MAX_EXEC_PARAMS];
|
cell_t m_params[SP_MAX_EXEC_PARAMS];
|
||||||
ParamInfo m_info[SP_MAX_EXEC_PARAMS];
|
ParamInfo m_info[SP_MAX_EXEC_PARAMS];
|
||||||
unsigned int m_curparam;
|
unsigned int m_curparam;
|
||||||
@@ -0,0 +1,144 @@
|
|||||||
|
#include "NativeOwner.h"
|
||||||
|
#include "ShareSys.h"
|
||||||
|
#include "PluginSys.h"
|
||||||
|
|
||||||
|
CNativeOwner::CNativeOwner() : m_nMarkSerial(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CNativeOwner::SetMarkSerial(unsigned int serial)
|
||||||
|
{
|
||||||
|
m_nMarkSerial = serial;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int CNativeOwner::GetMarkSerial()
|
||||||
|
{
|
||||||
|
return m_nMarkSerial;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CNativeOwner::AddDependent(CPlugin *pPlugin)
|
||||||
|
{
|
||||||
|
m_Dependents.push_back(pPlugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CNativeOwner::AddWeakRef(const WeakNative & ref)
|
||||||
|
{
|
||||||
|
m_WeakRefs.push_back(ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CNativeOwner::AddNatives(const sp_nativeinfo_t *natives)
|
||||||
|
{
|
||||||
|
NativeEntry *pEntry;
|
||||||
|
|
||||||
|
for (unsigned int i = 0; natives[i].func != NULL && natives[i].name != NULL; i++)
|
||||||
|
{
|
||||||
|
if ((pEntry = g_ShareSys.AddNativeToCache(this, &natives[i])) == NULL)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_Natives.push_back(pEntry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CNativeOwner::PropogateMarkSerial(unsigned int serial)
|
||||||
|
{
|
||||||
|
CNativeOwner *pOwner;
|
||||||
|
List<CPlugin *>::iterator iter;
|
||||||
|
|
||||||
|
for (iter = m_Dependents.begin();
|
||||||
|
iter != m_Dependents.end();
|
||||||
|
iter++)
|
||||||
|
{
|
||||||
|
pOwner = (*iter);
|
||||||
|
pOwner->SetMarkSerial(serial);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CNativeOwner::UnbindWeakRef(const WeakNative & ref)
|
||||||
|
{
|
||||||
|
sp_native_t *native;
|
||||||
|
IPluginContext *pContext;
|
||||||
|
|
||||||
|
pContext = ref.pl->GetBaseContext();
|
||||||
|
if ((pContext->GetNativeByIndex(ref.idx, &native)) == SP_ERROR_NONE)
|
||||||
|
{
|
||||||
|
/* If there is no reference, the native must be unbound */
|
||||||
|
if (ref.entry == NULL)
|
||||||
|
{
|
||||||
|
native->status = SP_NATIVE_UNBOUND;
|
||||||
|
native->pfn = NULL;
|
||||||
|
}
|
||||||
|
/* If we've cached a reference, it's a core native we can
|
||||||
|
* rebind back to its original (this was a replacement).
|
||||||
|
*/
|
||||||
|
else
|
||||||
|
{
|
||||||
|
native->pfn = ref.entry->func;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CNativeOwner::DropEverything()
|
||||||
|
{
|
||||||
|
NativeEntry *pEntry;
|
||||||
|
List<WeakNative>::iterator iter;
|
||||||
|
List<NativeEntry *>::iterator ntv_iter;
|
||||||
|
|
||||||
|
/* Unbind and remove all weak references to us */
|
||||||
|
iter = m_WeakRefs.begin();
|
||||||
|
while (iter != m_WeakRefs.end())
|
||||||
|
{
|
||||||
|
UnbindWeakRef((*iter));
|
||||||
|
iter = m_WeakRefs.erase(iter);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unmark our replacement natives */
|
||||||
|
ntv_iter = m_ReplacedNatives.begin();
|
||||||
|
while (ntv_iter != m_ReplacedNatives.end())
|
||||||
|
{
|
||||||
|
pEntry = (*ntv_iter);
|
||||||
|
pEntry->replacement.func = NULL;
|
||||||
|
pEntry->replacement.owner = NULL;
|
||||||
|
ntv_iter = m_ReplacedNatives.erase(ntv_iter);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Strip all of our natives from the cache */
|
||||||
|
ntv_iter = m_Natives.begin();
|
||||||
|
while (ntv_iter != m_Natives.end())
|
||||||
|
{
|
||||||
|
g_ShareSys.ClearNativeFromCache(this, (*ntv_iter)->name);
|
||||||
|
ntv_iter = m_Natives.erase(ntv_iter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CNativeOwner::DropWeakRefsTo(CPlugin *pPlugin)
|
||||||
|
{
|
||||||
|
List<WeakNative>::iterator iter;
|
||||||
|
|
||||||
|
iter = m_WeakRefs.begin();
|
||||||
|
while (iter != m_WeakRefs.end())
|
||||||
|
{
|
||||||
|
WeakNative & ref = (*iter);
|
||||||
|
|
||||||
|
if (ref.pl == pPlugin)
|
||||||
|
{
|
||||||
|
iter = m_WeakRefs.erase(iter);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
iter++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CNativeOwner::DropRefsTo(CPlugin *pPlugin)
|
||||||
|
{
|
||||||
|
m_Dependents.remove(pPlugin);
|
||||||
|
DropWeakRefsTo(pPlugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CNativeOwner::AddReplacedNative(NativeEntry *pEntry)
|
||||||
|
{
|
||||||
|
m_ReplacedNatives.push_back(pEntry);
|
||||||
|
}
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
#ifndef _INCLUDE_SOURCEMOD_NATIVE_OWNER_H_
|
||||||
|
#define _INCLUDE_SOURCEMOD_NATIVE_OWNER_H_
|
||||||
|
|
||||||
|
#include <sp_vm_types.h>
|
||||||
|
#include <sh_list.h>
|
||||||
|
|
||||||
|
class CPlugin;
|
||||||
|
struct NativeEntry;
|
||||||
|
|
||||||
|
struct WeakNative
|
||||||
|
{
|
||||||
|
WeakNative(CPlugin *plugin, uint32_t index) :
|
||||||
|
pl(plugin), idx(index), entry(NULL)
|
||||||
|
{
|
||||||
|
pl = plugin;
|
||||||
|
idx = index;
|
||||||
|
}
|
||||||
|
WeakNative(CPlugin *plugin, uint32_t index, NativeEntry *pEntry) :
|
||||||
|
pl(plugin), idx(index), entry(pEntry)
|
||||||
|
{
|
||||||
|
pl = plugin;
|
||||||
|
idx = index;
|
||||||
|
}
|
||||||
|
CPlugin *pl;
|
||||||
|
uint32_t idx;
|
||||||
|
NativeEntry *entry;
|
||||||
|
};
|
||||||
|
|
||||||
|
using namespace SourceHook;
|
||||||
|
|
||||||
|
class CNativeOwner
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CNativeOwner();
|
||||||
|
public:
|
||||||
|
virtual void DropEverything();
|
||||||
|
public:
|
||||||
|
void AddNatives(const sp_nativeinfo_t *info);
|
||||||
|
public:
|
||||||
|
void SetMarkSerial(unsigned int serial);
|
||||||
|
unsigned int GetMarkSerial();
|
||||||
|
void PropogateMarkSerial(unsigned int serial);
|
||||||
|
public:
|
||||||
|
void AddDependent(CPlugin *pPlugin);
|
||||||
|
void AddWeakRef(const WeakNative & ref);
|
||||||
|
void DropRefsTo(CPlugin *pPlugin);
|
||||||
|
void AddReplacedNative(NativeEntry *pEntry);
|
||||||
|
private:
|
||||||
|
void DropWeakRefsTo(CPlugin *pPlugin);
|
||||||
|
void UnbindWeakRef(const WeakNative & ref);
|
||||||
|
protected:
|
||||||
|
List<CPlugin *> m_Dependents;
|
||||||
|
unsigned int m_nMarkSerial;
|
||||||
|
List<WeakNative> m_WeakRefs;
|
||||||
|
List<NativeEntry *> m_Natives;
|
||||||
|
List<NativeEntry *> m_ReplacedNatives;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //_INCLUDE_SOURCEMOD_NATIVE_OWNER_H_
|
||||||
+6
-11
@@ -45,9 +45,7 @@ SH_DECL_HOOK2_void(IVEngineServer, ChangeLevel, SH_NOATTRIB, 0, const char *, co
|
|||||||
SH_DECL_HOOK4_void(IVEngineServer, ChangeLevel, SH_NOATTRIB, 0, const char *, const char *, const char *, bool);
|
SH_DECL_HOOK4_void(IVEngineServer, ChangeLevel, SH_NOATTRIB, 0, const char *, const char *, const char *, bool);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if SOURCE_ENGINE == SE_DOTA
|
#if SOURCE_ENGINE >= SE_ORANGEBOX
|
||||||
SH_DECL_EXTERN2_void(ConCommand, Dispatch, SH_NOATTRIB, false, const CCommandContext &, const CCommand &);
|
|
||||||
#elif SOURCE_ENGINE >= SE_ORANGEBOX
|
|
||||||
SH_DECL_EXTERN1_void(ConCommand, Dispatch, SH_NOATTRIB, false, const CCommand &);
|
SH_DECL_EXTERN1_void(ConCommand, Dispatch, SH_NOATTRIB, false, const CCommand &);
|
||||||
#elif SOURCE_ENGINE == SE_DARKMESSIAH
|
#elif SOURCE_ENGINE == SE_DARKMESSIAH
|
||||||
SH_DECL_EXTERN0_void(ConCommand, Dispatch, SH_NOATTRIB, false);
|
SH_DECL_EXTERN0_void(ConCommand, Dispatch, SH_NOATTRIB, false);
|
||||||
@@ -71,13 +69,13 @@ void NextMapManager::OnSourceModAllInitialized_Post()
|
|||||||
#if SOURCE_ENGINE >= SE_ORANGEBOX
|
#if SOURCE_ENGINE >= SE_ORANGEBOX
|
||||||
SH_ADD_HOOK(IVEngineServer, ChangeLevel, engine, SH_MEMBER(this, &NextMapManager::HookChangeLevel), false);
|
SH_ADD_HOOK(IVEngineServer, ChangeLevel, engine, SH_MEMBER(this, &NextMapManager::HookChangeLevel), false);
|
||||||
#else
|
#else
|
||||||
SH_ADD_HOOK(IVEngineServer, ChangeLevel, engine, SH_MEMBER(this, &NextMapManager::HookChangeLevel), false);
|
SH_ADD_HOOK_MEMFUNC(IVEngineServer, ChangeLevel, engine, this, &NextMapManager::HookChangeLevel, false);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ConCommand *pCmd = FindCommand("changelevel");
|
ConCommand *pCmd = FindCommand("changelevel");
|
||||||
if (pCmd != NULL)
|
if (pCmd != NULL)
|
||||||
{
|
{
|
||||||
SH_ADD_HOOK(ConCommand, Dispatch, pCmd, SH_STATIC(CmdChangeLevelCallback), false);
|
SH_ADD_HOOK_STATICFUNC(ConCommand, Dispatch, pCmd, CmdChangeLevelCallback, false);
|
||||||
changeLevelCmd = pCmd;
|
changeLevelCmd = pCmd;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -87,12 +85,12 @@ void NextMapManager::OnSourceModShutdown()
|
|||||||
#if SOURCE_ENGINE >= SE_ORANGEBOX
|
#if SOURCE_ENGINE >= SE_ORANGEBOX
|
||||||
SH_REMOVE_HOOK(IVEngineServer, ChangeLevel, engine, SH_MEMBER(this, &NextMapManager::HookChangeLevel), false);
|
SH_REMOVE_HOOK(IVEngineServer, ChangeLevel, engine, SH_MEMBER(this, &NextMapManager::HookChangeLevel), false);
|
||||||
#else
|
#else
|
||||||
SH_REMOVE_HOOK(IVEngineServer, ChangeLevel, engine, SH_MEMBER(this, &NextMapManager::HookChangeLevel), false);
|
SH_REMOVE_HOOK_MEMFUNC(IVEngineServer, ChangeLevel, engine, this, &NextMapManager::HookChangeLevel, false);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (changeLevelCmd != NULL)
|
if (changeLevelCmd != NULL)
|
||||||
{
|
{
|
||||||
SH_REMOVE_HOOK(ConCommand, Dispatch, changeLevelCmd, SH_STATIC(CmdChangeLevelCallback), false);
|
SH_REMOVE_HOOK_STATICFUNC(ConCommand, Dispatch, changeLevelCmd, CmdChangeLevelCallback, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
SourceHook::List<MapChangeData *>::iterator iter;
|
SourceHook::List<MapChangeData *>::iterator iter;
|
||||||
@@ -207,10 +205,7 @@ NextMapManager::NextMapManager()
|
|||||||
m_mapHistory = SourceHook::List<MapChangeData *>();
|
m_mapHistory = SourceHook::List<MapChangeData *>();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if SOURCE_ENGINE == SE_DOTA
|
#if SOURCE_ENGINE >= SE_ORANGEBOX
|
||||||
void CmdChangeLevelCallback(const CCommandContext &context, const CCommand &command)
|
|
||||||
{
|
|
||||||
#elif SOURCE_ENGINE >= SE_ORANGEBOX
|
|
||||||
void CmdChangeLevelCallback(const CCommand &command)
|
void CmdChangeLevelCallback(const CCommand &command)
|
||||||
{
|
{
|
||||||
#else
|
#else
|
||||||
|
|||||||
+2
-6
@@ -58,9 +58,7 @@ struct MapChangeData
|
|||||||
time_t startTime;
|
time_t startTime;
|
||||||
};
|
};
|
||||||
|
|
||||||
#if SOURCE_ENGINE == SE_DOTA
|
#if SOURCE_ENGINE >= SE_ORANGEBOX
|
||||||
void CmdChangeLevelCallback(const CCommandContext &context, const CCommand &command);
|
|
||||||
#elif SOURCE_ENGINE >= SE_ORANGEBOX
|
|
||||||
void CmdChangeLevelCallback(const CCommand &command);
|
void CmdChangeLevelCallback(const CCommand &command);
|
||||||
#else
|
#else
|
||||||
void CmdChangeLevelCallback();
|
void CmdChangeLevelCallback();
|
||||||
@@ -71,9 +69,7 @@ class NextMapManager : public SMGlobalClass
|
|||||||
public:
|
public:
|
||||||
NextMapManager();
|
NextMapManager();
|
||||||
|
|
||||||
#if SOURCE_ENGINE == SE_DOTA
|
#if SOURCE_ENGINE >= SE_ORANGEBOX
|
||||||
friend void CmdChangeLevelCallback(const CCommandContext &context, const CCommand &command);
|
|
||||||
#elif SOURCE_ENGINE >= SE_ORANGEBOX
|
|
||||||
friend void CmdChangeLevelCallback(const CCommand &command);
|
friend void CmdChangeLevelCallback(const CCommand &command);
|
||||||
#else
|
#else
|
||||||
friend void CmdChangeLevelCallback();
|
friend void CmdChangeLevelCallback();
|
||||||
|
|||||||
+110
-546
File diff suppressed because it is too large
Load Diff
+4
-30
@@ -90,9 +90,6 @@ public:
|
|||||||
bool RunAdminCacheChecks();
|
bool RunAdminCacheChecks();
|
||||||
void NotifyPostAdminChecks();
|
void NotifyPostAdminChecks();
|
||||||
unsigned int GetSerial();
|
unsigned int GetSerial();
|
||||||
int GetIndex() const;
|
|
||||||
void PrintToConsole(const char *pMsg);
|
|
||||||
void ClearAdmin();
|
|
||||||
public:
|
public:
|
||||||
void DoBasicAdminChecks();
|
void DoBasicAdminChecks();
|
||||||
void MarkAsBeingKicked();
|
void MarkAsBeingKicked();
|
||||||
@@ -131,9 +128,6 @@ private:
|
|||||||
bool m_bIsReplay;
|
bool m_bIsReplay;
|
||||||
serial_t m_Serial;
|
serial_t m_Serial;
|
||||||
unsigned int m_SteamAccountID;
|
unsigned int m_SteamAccountID;
|
||||||
#if SOURCE_ENGINE == SE_CSGO
|
|
||||||
QueryCvarCookie_t m_LanguageCookie;
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class PlayerManager :
|
class PlayerManager :
|
||||||
@@ -153,17 +147,9 @@ public: //SMGlobalClass
|
|||||||
public:
|
public:
|
||||||
CPlayer *GetPlayerByIndex(int client) const;
|
CPlayer *GetPlayerByIndex(int client) const;
|
||||||
void RunAuthChecks();
|
void RunAuthChecks();
|
||||||
|
void ClearAdminId(AdminId id);
|
||||||
|
void ClearAllAdmins();
|
||||||
public:
|
public:
|
||||||
#if SOURCE_ENGINE == SE_DOTA
|
|
||||||
bool OnClientConnect(CEntityIndex index, const char *pszName, const char *pszAddress, char *reject, int maxrejectlen);
|
|
||||||
bool OnClientConnect_Post(CEntityIndex index, const char *pszName, const char *pszAddress, char *reject, int maxrejectlen);
|
|
||||||
void OnClientPutInServer(CEntityIndex index, char const *playername);
|
|
||||||
void OnClientDisconnect(CEntityIndex index, int reason);
|
|
||||||
void OnClientDisconnect_Post(CEntityIndex index, int reason);
|
|
||||||
void OnClientCommand(CEntityIndex index, const CCommand &args);
|
|
||||||
void OnClientSettingsChanged(CEntityIndex index);
|
|
||||||
//void OnClientSettingsChanged_Pre(CEntityIndex client);
|
|
||||||
#else
|
|
||||||
bool OnClientConnect(edict_t *pEntity, const char *pszName, const char *pszAddress, char *reject, int maxrejectlen);
|
bool OnClientConnect(edict_t *pEntity, const char *pszName, const char *pszAddress, char *reject, int maxrejectlen);
|
||||||
bool OnClientConnect_Post(edict_t *pEntity, const char *pszName, const char *pszAddress, char *reject, int maxrejectlen);
|
bool OnClientConnect_Post(edict_t *pEntity, const char *pszName, const char *pszAddress, char *reject, int maxrejectlen);
|
||||||
void OnClientPutInServer(edict_t *pEntity, char const *playername);
|
void OnClientPutInServer(edict_t *pEntity, char const *playername);
|
||||||
@@ -176,8 +162,6 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
void OnClientSettingsChanged(edict_t *pEntity);
|
void OnClientSettingsChanged(edict_t *pEntity);
|
||||||
//void OnClientSettingsChanged_Pre(edict_t *pEntity);
|
//void OnClientSettingsChanged_Pre(edict_t *pEntity);
|
||||||
#endif
|
|
||||||
void OnServerHibernationUpdate(bool bHibernating);
|
|
||||||
public: //IPlayerManager
|
public: //IPlayerManager
|
||||||
void AddClientListener(IClientListener *listener);
|
void AddClientListener(IClientListener *listener);
|
||||||
void RemoveClientListener(IClientListener *listener);
|
void RemoveClientListener(IClientListener *listener);
|
||||||
@@ -193,8 +177,6 @@ public: //IPlayerManager
|
|||||||
void UnregisterCommandTargetProcessor(ICommandTargetProcessor *pHandler);
|
void UnregisterCommandTargetProcessor(ICommandTargetProcessor *pHandler);
|
||||||
void ProcessCommandTarget(cmd_target_info_t *info);
|
void ProcessCommandTarget(cmd_target_info_t *info);
|
||||||
int GetClientFromSerial(unsigned int serial);
|
int GetClientFromSerial(unsigned int serial);
|
||||||
void ClearAdminId(AdminId id);
|
|
||||||
void RecheckAnyAdmins();
|
|
||||||
public:
|
public:
|
||||||
inline int MaxClients()
|
inline int MaxClients()
|
||||||
{
|
{
|
||||||
@@ -211,18 +193,12 @@ public:
|
|||||||
bool CheckSetAdmin(int index, CPlayer *pPlayer, AdminId id);
|
bool CheckSetAdmin(int index, CPlayer *pPlayer, AdminId id);
|
||||||
bool CheckSetAdminName(int index, CPlayer *pPlayer, AdminId id);
|
bool CheckSetAdminName(int index, CPlayer *pPlayer, AdminId id);
|
||||||
const char *GetPassInfoVar();
|
const char *GetPassInfoVar();
|
||||||
|
void RecheckAnyAdmins();
|
||||||
unsigned int GetReplyTo();
|
unsigned int GetReplyTo();
|
||||||
unsigned int SetReplyTo(unsigned int reply);
|
unsigned int SetReplyTo(unsigned int reply);
|
||||||
void MaxPlayersChanged(int newvalue = -1);
|
void MaxPlayersChanged(int newvalue = -1);
|
||||||
#if SOURCE_ENGINE == SE_CSGO
|
|
||||||
bool HandleConVarQuery(QueryCvarCookie_t cookie, edict_t *pPlayer, EQueryCvarValueStatus result, const char *cvarName, const char *cvarValue);
|
|
||||||
#endif
|
|
||||||
private:
|
private:
|
||||||
#if SOURCE_ENGINE == SE_DOTA
|
|
||||||
void OnServerActivate();
|
|
||||||
#else
|
|
||||||
void OnServerActivate(edict_t *pEdictList, int edictCount, int clientMax);
|
void OnServerActivate(edict_t *pEdictList, int edictCount, int clientMax);
|
||||||
#endif
|
|
||||||
void InvalidatePlayer(CPlayer *pPlayer);
|
void InvalidatePlayer(CPlayer *pPlayer);
|
||||||
private:
|
private:
|
||||||
List<IClientListener *> m_hooks;
|
List<IClientListener *> m_hooks;
|
||||||
@@ -254,9 +230,7 @@ private:
|
|||||||
int m_ReplayUserId;
|
int m_ReplayUserId;
|
||||||
};
|
};
|
||||||
|
|
||||||
#if SOURCE_ENGINE == SE_DOTA
|
#if SOURCE_ENGINE >= SE_ORANGEBOX
|
||||||
void CmdMaxplayersCallback(const CCommandContext &context, const CCommand &command);
|
|
||||||
#elif SOURCE_ENGINE >= SE_ORANGEBOX
|
|
||||||
void CmdMaxplayersCallback(const CCommand &command);
|
void CmdMaxplayersCallback(const CCommand &command);
|
||||||
#else
|
#else
|
||||||
void CmdMaxplayersCallback();
|
void CmdMaxplayersCallback();
|
||||||
|
|||||||
@@ -0,0 +1,349 @@
|
|||||||
|
/**
|
||||||
|
* vim: set ts=4 :
|
||||||
|
* =============================================================================
|
||||||
|
* SourceMod
|
||||||
|
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
||||||
|
* =============================================================================
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it under
|
||||||
|
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||||
|
* Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
|
* details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with
|
||||||
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||||
|
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||||
|
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||||
|
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||||
|
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||||
|
* this exception to all derivative works. AlliedModders LLC defines further
|
||||||
|
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||||
|
* or <http://www.sourcemod.net/license.php>.
|
||||||
|
*
|
||||||
|
* Version: $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "PluginInfoDatabase.h"
|
||||||
|
#include "PluginSys.h"
|
||||||
|
|
||||||
|
void PluginSettings::Init()
|
||||||
|
{
|
||||||
|
name = -1;
|
||||||
|
pause_val = false;
|
||||||
|
type_val = PluginType_MapUpdated;
|
||||||
|
optarray = -1;
|
||||||
|
opts_num = 0;
|
||||||
|
opts_size = 0;
|
||||||
|
blockload_val = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* :TODO: write the logger, make these errors log instead of being static
|
||||||
|
* NOTE: once we do that, we will have to change some code to ignore sections
|
||||||
|
*/
|
||||||
|
|
||||||
|
CPluginInfoDatabase::CPluginInfoDatabase()
|
||||||
|
{
|
||||||
|
m_strtab = NULL;
|
||||||
|
m_infodb_count = 0;
|
||||||
|
m_infodb_size = 0;
|
||||||
|
m_infodb = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
CPluginInfoDatabase::~CPluginInfoDatabase()
|
||||||
|
{
|
||||||
|
delete m_strtab;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CPluginInfoDatabase::ReadSMC_ParseStart()
|
||||||
|
{
|
||||||
|
/* Create or reset our string table */
|
||||||
|
if (m_strtab)
|
||||||
|
{
|
||||||
|
m_strtab->Reset();
|
||||||
|
} else {
|
||||||
|
m_strtab = new BaseStringTable(1024);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set our internal states to the beginning */
|
||||||
|
in_plugins = false;
|
||||||
|
cur_plugin = -1;
|
||||||
|
in_options = false;
|
||||||
|
m_infodb_size = 0;
|
||||||
|
m_infodb_count = 0;
|
||||||
|
m_infodb = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
SMCResult CPluginInfoDatabase::MakeError(const char *fmt, ...)
|
||||||
|
{
|
||||||
|
char buffer[512];
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
va_start(ap, fmt);
|
||||||
|
vsnprintf(buffer, sizeof(buffer), fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
m_errmsg = m_strtab->AddString(buffer);
|
||||||
|
|
||||||
|
return SMCResult_HaltFail;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int CPluginInfoDatabase::GetSettingsNum()
|
||||||
|
{
|
||||||
|
return m_infodb_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
PluginSettings *CPluginInfoDatabase::GetSettingsIfMatch(unsigned int index, const char *filename)
|
||||||
|
{
|
||||||
|
BaseMemTable *memtab = m_strtab->GetMemTable();
|
||||||
|
int *table = (int *)memtab->GetAddress(m_infodb);
|
||||||
|
|
||||||
|
if (!table || index >= m_infodb_count)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
PluginSettings *plugin = (PluginSettings *)memtab->GetAddress(table[index]);
|
||||||
|
|
||||||
|
const char *name = m_strtab->GetString(plugin->name);
|
||||||
|
|
||||||
|
if (!name)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!g_PluginSys.TestAliasMatch(name, filename))
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CPluginInfoDatabase::GetOptionsForPlugin(PluginSettings *settings, unsigned int opt_num, const char **key, const char **val)
|
||||||
|
{
|
||||||
|
PluginOpts *table = (PluginOpts *)m_strtab->GetMemTable()->GetAddress(settings->optarray);
|
||||||
|
if (!table)
|
||||||
|
{
|
||||||
|
*key = NULL;
|
||||||
|
*val = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (opt_num >= settings->opts_num)
|
||||||
|
{
|
||||||
|
*key = NULL;
|
||||||
|
*val = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
*key = m_strtab->GetString(table[opt_num].key);
|
||||||
|
*val = m_strtab->GetString(table[opt_num].val);
|
||||||
|
}
|
||||||
|
|
||||||
|
SMCResult CPluginInfoDatabase::ReadSMC_KeyValue(const SMCStates *states, const char *key, const char *value)
|
||||||
|
{
|
||||||
|
if (cur_plugin != -1)
|
||||||
|
{
|
||||||
|
PluginSettings *plugin = (PluginSettings *)m_strtab->GetMemTable()->GetAddress(cur_plugin);
|
||||||
|
if (!in_options)
|
||||||
|
{
|
||||||
|
if (strcmp(key, "pause") == 0)
|
||||||
|
{
|
||||||
|
if (strcasecmp(value, "yes") == 0)
|
||||||
|
{
|
||||||
|
plugin->pause_val = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
plugin->pause_val = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (strcmp(key, "lifetime") == 0)
|
||||||
|
{
|
||||||
|
if (strcasecmp(value, "private") == 0)
|
||||||
|
{
|
||||||
|
plugin->type_val = PluginType_Private;
|
||||||
|
}
|
||||||
|
else if (strcasecmp(value, "mapsync") == 0)
|
||||||
|
{
|
||||||
|
plugin->type_val = PluginType_MapUpdated;
|
||||||
|
}
|
||||||
|
else if (strcasecmp(value, "maponly") == 0)
|
||||||
|
{
|
||||||
|
plugin->type_val = PluginType_MapOnly;
|
||||||
|
}
|
||||||
|
else if (strcasecmp(value, "global") == 0)
|
||||||
|
{
|
||||||
|
plugin->type_val = PluginType_Global;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return MakeError("Unknown value for key \"lifetime\": \"%s\"", value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (strcmp(key, "blockload") == 0)
|
||||||
|
{
|
||||||
|
plugin->blockload_val = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return MakeError("Unknown property key: \"%s\"", key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Cache every option, valid or not */
|
||||||
|
int keyidx = m_strtab->AddString(key);
|
||||||
|
int validx = m_strtab->AddString(value);
|
||||||
|
PluginOpts *table;
|
||||||
|
BaseMemTable *memtab = m_strtab->GetMemTable();
|
||||||
|
plugin = (PluginSettings *)memtab->GetAddress(cur_plugin);
|
||||||
|
if (plugin->opts_num + 1 > plugin->opts_size)
|
||||||
|
{
|
||||||
|
unsigned int oldsize = plugin->opts_size;
|
||||||
|
if (oldsize == 0)
|
||||||
|
{
|
||||||
|
//right now we don't have many
|
||||||
|
plugin->opts_size = 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
plugin->opts_size *= 2;
|
||||||
|
}
|
||||||
|
int newidx = memtab->CreateMem(plugin->opts_size * sizeof(PluginOpts), (void **)&table);
|
||||||
|
/* in case it resized */
|
||||||
|
plugin = (PluginSettings *)memtab->GetAddress(cur_plugin);
|
||||||
|
if (plugin->optarray != -1)
|
||||||
|
{
|
||||||
|
void *oldtable = memtab->GetAddress(plugin->optarray);
|
||||||
|
memcpy(table, oldtable, oldsize * sizeof(PluginOpts));
|
||||||
|
}
|
||||||
|
plugin->optarray = newidx;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
table = (PluginOpts *)memtab->GetAddress(plugin->optarray);
|
||||||
|
}
|
||||||
|
PluginOpts *opt = &table[plugin->opts_num++];
|
||||||
|
opt->key = keyidx;
|
||||||
|
opt->val = validx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (in_plugins)
|
||||||
|
{
|
||||||
|
return MakeError("Unknown property key: \"%s\"", key);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Ignore anything we don't know about! */
|
||||||
|
}
|
||||||
|
|
||||||
|
return SMCResult_Continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
SMCResult CPluginInfoDatabase::ReadSMC_LeavingSection(const SMCStates *states)
|
||||||
|
{
|
||||||
|
if (in_plugins)
|
||||||
|
{
|
||||||
|
if (cur_plugin != -1)
|
||||||
|
{
|
||||||
|
if (in_options)
|
||||||
|
{
|
||||||
|
in_options = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* If the plugin is ending, add it to the table */
|
||||||
|
BaseMemTable *memtab = m_strtab->GetMemTable();
|
||||||
|
int *table;
|
||||||
|
if (m_infodb_count + 1 > m_infodb_size)
|
||||||
|
{
|
||||||
|
unsigned int oldsize = m_infodb_size;
|
||||||
|
if (!m_infodb_size)
|
||||||
|
{
|
||||||
|
m_infodb_size = 8;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_infodb_size *= 2;
|
||||||
|
}
|
||||||
|
int newidx = memtab->CreateMem(m_infodb_size * sizeof(int), (void **)&table);
|
||||||
|
if (m_infodb != -1)
|
||||||
|
{
|
||||||
|
void *oldtable = (int *)memtab->GetAddress(m_infodb);
|
||||||
|
memcpy(table, oldtable, oldsize * sizeof(int));
|
||||||
|
}
|
||||||
|
m_infodb = newidx;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
table = (int *)memtab->GetAddress(m_infodb);
|
||||||
|
}
|
||||||
|
/* Assign to table and scrap the current plugin */
|
||||||
|
table[m_infodb_count++] = cur_plugin;
|
||||||
|
cur_plugin = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
in_plugins = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return SMCResult_Continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
SMCResult CPluginInfoDatabase::ReadSMC_NewSection(const SMCStates *states, const char *name)
|
||||||
|
{
|
||||||
|
if (!in_plugins)
|
||||||
|
{
|
||||||
|
/* If we're not in the main Plugins section, and we don't get it for the name, error out */
|
||||||
|
if (strcmp(name, "Plugins") != 0)
|
||||||
|
{
|
||||||
|
return MakeError("Unknown root section: \"%s\"", name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Otherwise set our states */
|
||||||
|
in_plugins = true;
|
||||||
|
cur_plugin = -1;
|
||||||
|
in_options = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (cur_plugin == -1)
|
||||||
|
{
|
||||||
|
/* If we get a plugin node and we don't have a current plugin, create a new one */
|
||||||
|
PluginSettings *plugin;
|
||||||
|
int i_name = m_strtab->AddString(name);
|
||||||
|
cur_plugin = m_strtab->GetMemTable()->CreateMem(sizeof(PluginSettings), (void **)&plugin);
|
||||||
|
plugin->Init();
|
||||||
|
plugin->name = i_name;
|
||||||
|
in_options = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!in_options && strcmp(name, "Options") == 0)
|
||||||
|
{
|
||||||
|
in_options = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return MakeError("Unknown plugin sub-section: \"%s\"", name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return SMCResult_Continue;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,106 @@
|
|||||||
|
/**
|
||||||
|
* vim: set ts=4 :
|
||||||
|
* =============================================================================
|
||||||
|
* SourceMod
|
||||||
|
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
||||||
|
* =============================================================================
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it under
|
||||||
|
* the terms of the GNU General Public License, version 3.0, as published by the
|
||||||
|
* Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
|
* details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with
|
||||||
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* As a special exception, AlliedModders LLC gives you permission to link the
|
||||||
|
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
||||||
|
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
||||||
|
* by the Valve Corporation. You must obey the GNU General Public License in
|
||||||
|
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
||||||
|
* this exception to all derivative works. AlliedModders LLC defines further
|
||||||
|
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
||||||
|
* or <http://www.sourcemod.net/license.php>.
|
||||||
|
*
|
||||||
|
* Version: $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _INCLUDE_SOURCEMOD_CORE_SYSTEM_PLUGININFODATABASE_H_
|
||||||
|
#define _INCLUDE_SOURCEMOD_CORE_SYSTEM_PLUGININFODATABASE_H_
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This file parses plugin_settings.cfg and stores the information in cached memory.
|
||||||
|
* It provides simplistic abstraction to retrieving the info.
|
||||||
|
* :TODO: currently untested
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "sm_memtable.h"
|
||||||
|
#include "ITextParsers.h"
|
||||||
|
#include "IPluginSys.h"
|
||||||
|
#include "sm_globals.h"
|
||||||
|
|
||||||
|
struct PluginOpts
|
||||||
|
{
|
||||||
|
int key;
|
||||||
|
int val;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PluginSettings
|
||||||
|
{
|
||||||
|
void Init();
|
||||||
|
int name;
|
||||||
|
bool pause_val;
|
||||||
|
PluginType type_val;
|
||||||
|
int optarray;
|
||||||
|
size_t opts_num;
|
||||||
|
size_t opts_size;
|
||||||
|
bool blockload_val;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CPluginInfoDatabase : public ITextListener_SMC
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CPluginInfoDatabase();
|
||||||
|
~CPluginInfoDatabase();
|
||||||
|
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);
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Returns the number of plugin settings available.
|
||||||
|
*/
|
||||||
|
unsigned int GetSettingsNum();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given an index, returns the plugin settings block if the filename matches.
|
||||||
|
* Otherwise, returns NULL.
|
||||||
|
*/
|
||||||
|
PluginSettings *GetSettingsIfMatch(unsigned int index, const char *filename);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given a plugin settings struct and an index,
|
||||||
|
* returns the given JIT key/value option pair at that index.
|
||||||
|
* If the input is invalid, key and val will be set to NULL.
|
||||||
|
*/
|
||||||
|
void GetOptionsForPlugin(PluginSettings *settings, unsigned int opt_num, const char **key, const char **val);
|
||||||
|
private:
|
||||||
|
SMCResult MakeError(const char *fmt, ...);
|
||||||
|
private:
|
||||||
|
BaseStringTable *m_strtab;
|
||||||
|
int m_errmsg;
|
||||||
|
bool in_plugins;
|
||||||
|
bool in_options;
|
||||||
|
int m_infodb;
|
||||||
|
size_t m_infodb_count;
|
||||||
|
size_t m_infodb_size;
|
||||||
|
int cur_plugin;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //_INCLUDE_SOURCEMOD_CORE_SYSTEM_PLUGININFODATABASE_H_
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* vim: set ts=4 sw=4 tw=99 noet :
|
* vim: set ts=4 :
|
||||||
* =============================================================================
|
* =============================================================================
|
||||||
* SourceMod
|
* SourceMod
|
||||||
* Copyright (C) 2004-2010 AlliedModders LLC. All rights reserved.
|
* Copyright (C) 2004-2010 AlliedModders LLC. All rights reserved.
|
||||||
@@ -42,10 +42,20 @@
|
|||||||
#include <sh_stack.h>
|
#include <sh_stack.h>
|
||||||
#include <sh_vector.h>
|
#include <sh_vector.h>
|
||||||
#include <sh_string.h>
|
#include <sh_string.h>
|
||||||
#include "common_logic.h"
|
#include "sm_globals.h"
|
||||||
|
#include "PluginInfoDatabase.h"
|
||||||
|
#include "sm_trie.h"
|
||||||
|
#include "sourcemod.h"
|
||||||
#include <IRootConsoleMenu.h>
|
#include <IRootConsoleMenu.h>
|
||||||
#include <sm_stringhashmap.h>
|
#if SOURCE_ENGINE >= SE_ALIENSWARM
|
||||||
#include <sm_namehashset.h>
|
#include "convar_sm_swarm.h"
|
||||||
|
#elif SOURCE_ENGINE >= SE_LEFT4DEAD
|
||||||
|
#include "convar_sm_l4d.h"
|
||||||
|
#elif SOURCE_ENGINE >= SE_ORANGEBOX
|
||||||
|
#include "convar_sm_ob.h"
|
||||||
|
#else
|
||||||
|
#include "convar_sm.h"
|
||||||
|
#endif
|
||||||
#include "ITranslator.h"
|
#include "ITranslator.h"
|
||||||
#include "IGameConfigs.h"
|
#include "IGameConfigs.h"
|
||||||
#include "NativeOwner.h"
|
#include "NativeOwner.h"
|
||||||
@@ -121,8 +131,23 @@ enum APLRes
|
|||||||
APLRes_SilentFailure
|
APLRes_SilentFailure
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum LibraryAction
|
||||||
|
{
|
||||||
|
LibraryAction_Removed,
|
||||||
|
LibraryAction_Added
|
||||||
|
};
|
||||||
|
|
||||||
|
struct AutoConfig
|
||||||
|
{
|
||||||
|
String autocfg;
|
||||||
|
String folder;
|
||||||
|
bool create;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CPlugin;
|
||||||
|
|
||||||
class CPlugin :
|
class CPlugin :
|
||||||
public SMPlugin,
|
public IPlugin,
|
||||||
public CNativeOwner
|
public CNativeOwner
|
||||||
{
|
{
|
||||||
friend class CPluginManager;
|
friend class CPluginManager;
|
||||||
@@ -149,9 +174,6 @@ public:
|
|||||||
bool GetProperty(const char *prop, void **ptr, bool remove=false);
|
bool GetProperty(const char *prop, void **ptr, bool remove=false);
|
||||||
void DropEverything();
|
void DropEverything();
|
||||||
SourcePawn::IPluginRuntime *GetRuntime();
|
SourcePawn::IPluginRuntime *GetRuntime();
|
||||||
CNativeOwner *ToNativeOwner() {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Creates a plugin object with default values.
|
* Creates a plugin object with default values.
|
||||||
@@ -161,11 +183,6 @@ public:
|
|||||||
* a valid (but error-stated) CPlugin will be returned.
|
* a valid (but error-stated) CPlugin will be returned.
|
||||||
*/
|
*/
|
||||||
static CPlugin *CreatePlugin(const char *file, char *error, size_t maxlength);
|
static CPlugin *CreatePlugin(const char *file, char *error, size_t maxlength);
|
||||||
|
|
||||||
static inline bool matches(const char *file, const CPlugin *plugin)
|
|
||||||
{
|
|
||||||
return strcmp(plugin->m_filename, file) == 0;
|
|
||||||
}
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -204,11 +221,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
void Call_OnAllPluginsLoaded();
|
void Call_OnAllPluginsLoaded();
|
||||||
|
|
||||||
/**
|
|
||||||
* Calls the OnLibraryAdded function.
|
|
||||||
*/
|
|
||||||
void Call_OnLibraryAdded(const char *lib);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if a plugin is usable.
|
* Returns true if a plugin is usable.
|
||||||
*/
|
*/
|
||||||
@@ -238,8 +250,8 @@ public:
|
|||||||
|
|
||||||
bool AddFakeNative(IPluginFunction *pFunc, const char *name, SPVM_FAKENATIVE_FUNC func);
|
bool AddFakeNative(IPluginFunction *pFunc, const char *name, SPVM_FAKENATIVE_FUNC func);
|
||||||
void AddConfig(bool autoCreate, const char *cfg, const char *folder);
|
void AddConfig(bool autoCreate, const char *cfg, const char *folder);
|
||||||
size_t GetConfigCount();
|
unsigned int GetConfigCount();
|
||||||
AutoConfig *GetConfig(size_t i);
|
AutoConfig *GetConfig(unsigned int i);
|
||||||
inline void AddLibrary(const char *name)
|
inline void AddLibrary(const char *name)
|
||||||
{
|
{
|
||||||
m_Libraries.push_back(name);
|
m_Libraries.push_back(name);
|
||||||
@@ -265,7 +277,7 @@ private:
|
|||||||
IPhraseCollection *m_pPhrases;
|
IPhraseCollection *m_pPhrases;
|
||||||
List<String> m_RequiredLibs;
|
List<String> m_RequiredLibs;
|
||||||
List<String> m_Libraries;
|
List<String> m_Libraries;
|
||||||
StringHashMap<void *> m_Props;
|
Trie *m_pProps;
|
||||||
bool m_FakeNativesMissing;
|
bool m_FakeNativesMissing;
|
||||||
bool m_LibraryMissing;
|
bool m_LibraryMissing;
|
||||||
CVector<AutoConfig *> m_configs;
|
CVector<AutoConfig *> m_configs;
|
||||||
@@ -278,7 +290,7 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
class CPluginManager :
|
class CPluginManager :
|
||||||
public IScriptManager,
|
public IPluginManager,
|
||||||
public SMGlobalClass,
|
public SMGlobalClass,
|
||||||
public IHandleTypeDispatch,
|
public IHandleTypeDispatch,
|
||||||
public IRootConsoleCommand
|
public IRootConsoleCommand
|
||||||
@@ -305,7 +317,7 @@ public:
|
|||||||
List<CPlugin *>::iterator current;
|
List<CPlugin *>::iterator current;
|
||||||
};
|
};
|
||||||
friend class CPluginManager::CPluginIterator;
|
friend class CPluginManager::CPluginIterator;
|
||||||
public: //IScriptManager
|
public: //IPluginManager
|
||||||
IPlugin *LoadPlugin(const char *path,
|
IPlugin *LoadPlugin(const char *path,
|
||||||
bool debug,
|
bool debug,
|
||||||
PluginType type,
|
PluginType type,
|
||||||
@@ -318,26 +330,6 @@ public: //IScriptManager
|
|||||||
IPluginIterator *GetPluginIterator();
|
IPluginIterator *GetPluginIterator();
|
||||||
void AddPluginsListener(IPluginsListener *listener);
|
void AddPluginsListener(IPluginsListener *listener);
|
||||||
void RemovePluginsListener(IPluginsListener *listener);
|
void RemovePluginsListener(IPluginsListener *listener);
|
||||||
void LoadAll(const char *config_path, const char *plugins_path);
|
|
||||||
void RefreshAll();
|
|
||||||
SMPlugin *FindPluginByOrder(unsigned num) {
|
|
||||||
return GetPluginByOrder(num);
|
|
||||||
}
|
|
||||||
SMPlugin *FindPluginByIdentity(IdentityToken_t *ident) {
|
|
||||||
return GetPluginFromIdentity(ident);
|
|
||||||
}
|
|
||||||
SMPlugin *FindPluginByContext(IPluginContext *ctx) {
|
|
||||||
return GetPluginByCtx(ctx->GetContext());
|
|
||||||
}
|
|
||||||
SMPlugin *FindPluginByContext(sp_context_t *ctx) {
|
|
||||||
return GetPluginByCtx(ctx);
|
|
||||||
}
|
|
||||||
SMPlugin *FindPluginByConsoleArg(const char *text);
|
|
||||||
SMPlugin *FindPluginByHandle(Handle_t hndl, HandleError *errp) {
|
|
||||||
return static_cast<SMPlugin *>(PluginFromHandle(hndl, errp));
|
|
||||||
}
|
|
||||||
const CVector<SMPlugin *> *ListPlugins();
|
|
||||||
void FreePluginList(const CVector<SMPlugin *> *plugins);
|
|
||||||
public: //SMGlobalClass
|
public: //SMGlobalClass
|
||||||
void OnSourceModAllInitialized();
|
void OnSourceModAllInitialized();
|
||||||
void OnSourceModShutdown();
|
void OnSourceModShutdown();
|
||||||
@@ -397,6 +389,11 @@ public:
|
|||||||
*/
|
*/
|
||||||
const char *GetStatusText(PluginStatus status);
|
const char *GetStatusText(PluginStatus status);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reload or update plugins on level shutdown.
|
||||||
|
*/
|
||||||
|
void ReloadOrUnloadPlugins();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add public functions from all running or paused
|
* Add public functions from all running or paused
|
||||||
* plugins to the specified forward if the names match.
|
* plugins to the specified forward if the names match.
|
||||||
@@ -420,6 +417,8 @@ public:
|
|||||||
|
|
||||||
void UnloadAll();
|
void UnloadAll();
|
||||||
|
|
||||||
|
CPlugin *FindPluginByConsoleArg(const char *arg);
|
||||||
|
|
||||||
void SyncMaxClients(int max_clients);
|
void SyncMaxClients(int max_clients);
|
||||||
|
|
||||||
void ListPluginsToClient(CPlayer *player, const CCommand &args);
|
void ListPluginsToClient(CPlayer *player, const CCommand &args);
|
||||||
@@ -464,14 +463,14 @@ public:
|
|||||||
{
|
{
|
||||||
return m_MyIdent;
|
return m_MyIdent;
|
||||||
}
|
}
|
||||||
IPluginManager *GetOldAPI();
|
|
||||||
private:
|
private:
|
||||||
void TryRefreshDependencies(CPlugin *pOther);
|
void TryRefreshDependencies(CPlugin *pOther);
|
||||||
private:
|
private:
|
||||||
List<IPluginsListener *> m_listeners;
|
List<IPluginsListener *> m_listeners;
|
||||||
List<CPlugin *> m_plugins;
|
List<CPlugin *> m_plugins;
|
||||||
CStack<CPluginManager::CPluginIterator *> m_iters;
|
CStack<CPluginManager::CPluginIterator *> m_iters;
|
||||||
NameHashSet<CPlugin *> m_LoadLookup;
|
CPluginInfoDatabase m_PluginInfo;
|
||||||
|
Trie *m_LoadLookup;
|
||||||
bool m_AllPluginsLoaded;
|
bool m_AllPluginsLoaded;
|
||||||
IdentityToken_t *m_MyIdent;
|
IdentityToken_t *m_MyIdent;
|
||||||
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* vim: set ts=4 sw=4 tw=99 noet :
|
* vim: set ts=4 :
|
||||||
* =============================================================================
|
* =============================================================================
|
||||||
* SourceMod
|
* SourceMod
|
||||||
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
||||||
@@ -30,14 +30,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "ShareSys.h"
|
#include "ShareSys.h"
|
||||||
#include "ExtensionSys.h"
|
|
||||||
#include <ILibrarySys.h>
|
|
||||||
#include "common_logic.h"
|
|
||||||
#include "PluginSys.h"
|
|
||||||
#include "HandleSys.h"
|
#include "HandleSys.h"
|
||||||
#include <assert.h>
|
#include "ExtensionSys.h"
|
||||||
|
#include "LibrarySys.h"
|
||||||
using namespace ke;
|
#include "PluginSys.h"
|
||||||
|
#include "sm_stringutil.h"
|
||||||
|
|
||||||
ShareSystem g_ShareSys;
|
ShareSystem g_ShareSys;
|
||||||
static unsigned int g_mark_serial = 0;
|
static unsigned int g_mark_serial = 0;
|
||||||
@@ -64,36 +61,36 @@ void ShareSystem::Initialize()
|
|||||||
{
|
{
|
||||||
TypeAccess sec;
|
TypeAccess sec;
|
||||||
|
|
||||||
handlesys->InitAccessDefaults(&sec, NULL);
|
g_HandleSys.InitAccessDefaults(&sec, NULL);
|
||||||
sec.ident = GetIdentRoot();
|
sec.ident = GetIdentRoot();
|
||||||
|
|
||||||
m_TypeRoot = handlesys->CreateType("Identity", this, 0, &sec, NULL, NULL, NULL);
|
m_TypeRoot = g_HandleSys.CreateType("Identity", this, 0, &sec, NULL, NULL, NULL);
|
||||||
m_IfaceType = handlesys->CreateType("Interface", this, 0, NULL, NULL, GetIdentRoot(), NULL);
|
m_IfaceType = g_HandleSys.CreateType("Interface", this, 0, NULL, NULL, GetIdentRoot(), NULL);
|
||||||
|
|
||||||
/* Initialize our static identity handle */
|
/* Initialize our static identity handle */
|
||||||
m_IdentRoot.ident = handlesys->CreateHandle(m_TypeRoot, NULL, NULL, GetIdentRoot(), NULL);
|
m_IdentRoot.ident = g_HandleSys.CreateHandle(m_TypeRoot, NULL, NULL, GetIdentRoot(), NULL);
|
||||||
|
|
||||||
/* Add the Handle System and others... they are too innocent and pure to do it themselves */
|
/* Add the Handle System and others... they are too innocent and pure to do it themselves */
|
||||||
AddInterface(NULL, handlesys);
|
AddInterface(NULL, &g_HandleSys);
|
||||||
AddInterface(NULL, libsys);
|
AddInterface(NULL, &g_LibSys);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShareSystem::OnSourceModShutdown()
|
void ShareSystem::OnSourceModShutdown()
|
||||||
{
|
{
|
||||||
if (m_CoreType)
|
if (m_CoreType)
|
||||||
{
|
{
|
||||||
handlesys->RemoveType(m_CoreType, GetIdentRoot());
|
g_HandleSys.RemoveType(m_CoreType, GetIdentRoot());
|
||||||
}
|
}
|
||||||
|
|
||||||
handlesys->RemoveType(m_IfaceType, GetIdentRoot());
|
g_HandleSys.RemoveType(m_IfaceType, GetIdentRoot());
|
||||||
handlesys->RemoveType(m_TypeRoot, GetIdentRoot());
|
g_HandleSys.RemoveType(m_TypeRoot, GetIdentRoot());
|
||||||
}
|
}
|
||||||
|
|
||||||
IdentityType_t ShareSystem::FindIdentType(const char *name)
|
IdentityType_t ShareSystem::FindIdentType(const char *name)
|
||||||
{
|
{
|
||||||
HandleType_t type;
|
HandleType_t type;
|
||||||
|
|
||||||
if (handlesys->FindHandleType(name, &type))
|
if (g_HandleSys.FindHandleType(name, &type))
|
||||||
{
|
{
|
||||||
if (g_HandleSys.TypeCheck(type, m_TypeRoot))
|
if (g_HandleSys.TypeCheck(type, m_TypeRoot))
|
||||||
{
|
{
|
||||||
@@ -111,7 +108,7 @@ IdentityType_t ShareSystem::CreateIdentType(const char *name)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return handlesys->CreateType(name, this, m_TypeRoot, NULL, NULL, GetIdentRoot(), NULL);
|
return g_HandleSys.CreateType(name, this, m_TypeRoot, NULL, NULL, GetIdentRoot(), NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShareSystem::OnHandleDestroy(HandleType_t type, void *object)
|
void ShareSystem::OnHandleDestroy(HandleType_t type, void *object)
|
||||||
@@ -220,13 +217,13 @@ void ShareSystem::DestroyIdentity(IdentityToken_t *identity)
|
|||||||
sec.pOwner = GetIdentRoot();
|
sec.pOwner = GetIdentRoot();
|
||||||
sec.pIdentity = GetIdentRoot();
|
sec.pIdentity = GetIdentRoot();
|
||||||
|
|
||||||
handlesys->FreeHandle(identity->ident, &sec);
|
g_HandleSys.FreeHandle(identity->ident, &sec);
|
||||||
delete identity;
|
delete identity;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShareSystem::DestroyIdentType(IdentityType_t type)
|
void ShareSystem::DestroyIdentType(IdentityType_t type)
|
||||||
{
|
{
|
||||||
handlesys->RemoveType(type, GetIdentRoot());
|
g_HandleSys.RemoveType(type, GetIdentRoot());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShareSystem::RemoveInterfaces(IExtension *pExtension)
|
void ShareSystem::RemoveInterfaces(IExtension *pExtension)
|
||||||
@@ -258,19 +255,51 @@ void ShareSystem::RegisterLibrary(IExtension *myself, const char *name)
|
|||||||
|
|
||||||
void ShareSystem::OverrideNatives(IExtension *myself, const sp_nativeinfo_t *natives)
|
void ShareSystem::OverrideNatives(IExtension *myself, const sp_nativeinfo_t *natives)
|
||||||
{
|
{
|
||||||
assert(false);
|
unsigned int i;
|
||||||
|
NativeEntry *pEntry;
|
||||||
|
CNativeOwner *pOwner;
|
||||||
|
|
||||||
|
pOwner = g_Extensions.GetNativeOwner(myself);
|
||||||
|
|
||||||
|
for (i = 0; natives[i].func != NULL && natives[i].name != NULL; i++)
|
||||||
|
{
|
||||||
|
if ((pEntry = FindNative(natives[i].name)) == NULL)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pEntry->owner != g_pCoreNatives)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pEntry->replacement.owner != NULL)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now it's safe to add the override */
|
||||||
|
pEntry->replacement.func = natives[i].func;
|
||||||
|
pEntry->replacement.owner = pOwner;
|
||||||
|
pOwner->AddReplacedNative(pEntry);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PassRef<Native> ShareSystem::FindNative(const char *name)
|
NativeEntry *ShareSystem::FindNative(const char *name)
|
||||||
{
|
{
|
||||||
NativeCache::Result r = m_NtvCache.find(name);
|
NativeEntry **ppEntry;
|
||||||
if (!r.found())
|
|
||||||
|
if ((ppEntry = m_NtvCache.retrieve(name)) == NULL)
|
||||||
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
return *r;
|
}
|
||||||
|
|
||||||
|
return *ppEntry;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShareSystem::BindNativesToPlugin(CPlugin *pPlugin, bool bCoreOnly)
|
void ShareSystem::BindNativesToPlugin(CPlugin *pPlugin, bool bCoreOnly)
|
||||||
{
|
{
|
||||||
|
NativeEntry *pEntry;
|
||||||
sp_native_t *native;
|
sp_native_t *native;
|
||||||
uint32_t i, native_count;
|
uint32_t i, native_count;
|
||||||
IPluginContext *pContext;
|
IPluginContext *pContext;
|
||||||
@@ -279,152 +308,230 @@ void ShareSystem::BindNativesToPlugin(CPlugin *pPlugin, bool bCoreOnly)
|
|||||||
|
|
||||||
/* Generate a new serial ID, mark our dependencies with it. */
|
/* Generate a new serial ID, mark our dependencies with it. */
|
||||||
g_mark_serial++;
|
g_mark_serial++;
|
||||||
pPlugin->PropagateMarkSerial(g_mark_serial);
|
pPlugin->PropogateMarkSerial(g_mark_serial);
|
||||||
|
|
||||||
native_count = pContext->GetNativesNum();
|
native_count = pContext->GetNativesNum();
|
||||||
for (i = 0; i < native_count; i++)
|
for (i = 0; i < native_count; i++)
|
||||||
{
|
{
|
||||||
if (pContext->GetNativeByIndex(i, &native) != SP_ERROR_NONE)
|
if (pContext->GetNativeByIndex(i, &native) != SP_ERROR_NONE)
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// If we're already bound, no need to do anything else.
|
/* If we're bound, check if there is a replacement available.
|
||||||
|
* If not, this native is totally finalized.
|
||||||
|
*/
|
||||||
if (native->status == SP_NATIVE_BOUND)
|
if (native->status == SP_NATIVE_BOUND)
|
||||||
continue;
|
{
|
||||||
|
pEntry = (NativeEntry *)native->user;
|
||||||
|
assert(pEntry != NULL);
|
||||||
|
if (pEntry->replacement.owner == NULL
|
||||||
|
|| (pEntry->replacement.owner != NULL
|
||||||
|
&& pEntry->replacement.func == native->pfn))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
/* Otherwise, the native must be in our cache. */
|
/* Otherwise, the native must be in our cache. */
|
||||||
Ref<Native> pEntry = FindNative(native->name);
|
else if ((pEntry = FindNative(native->name)) == NULL)
|
||||||
if (!pEntry)
|
{
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (bCoreOnly && pEntry->owner != &g_CoreNatives)
|
if (bCoreOnly && pEntry->owner != g_pCoreNatives)
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
BindNativeToPlugin(pPlugin, native, i, pEntry);
|
BindNativeToPlugin(pPlugin, native, i, pEntry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShareSystem::BindNativeToPlugin(CPlugin *pPlugin, const Ref<Native> &entry)
|
void ShareSystem::BindNativeToPlugin(CPlugin *pPlugin, NativeEntry *pEntry)
|
||||||
{
|
{
|
||||||
if (!entry->owner)
|
|
||||||
return;
|
|
||||||
|
|
||||||
IPluginContext *pContext = pPlugin->GetBaseContext();
|
|
||||||
|
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
if (pContext->FindNativeByName(entry->name(), &i) != SP_ERROR_NONE)
|
|
||||||
return;
|
|
||||||
|
|
||||||
sp_native_t *native;
|
sp_native_t *native;
|
||||||
if (pContext->GetNativeByIndex(i, &native) != SP_ERROR_NONE)
|
IPluginContext *pContext;
|
||||||
|
|
||||||
|
pContext = pPlugin->GetBaseContext();
|
||||||
|
|
||||||
|
if (pContext->FindNativeByName(pEntry->name, &i) != SP_ERROR_NONE)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
if (pContext->GetNativeByIndex(i, &native) != SP_ERROR_NONE)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (native->status == SP_NATIVE_BOUND)
|
if (native->status == SP_NATIVE_BOUND)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
BindNativeToPlugin(pPlugin, native, i, entry);
|
BindNativeToPlugin(pPlugin, native, i, pEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShareSystem::BindNativeToPlugin(CPlugin *pPlugin, sp_native_t *native, uint32_t index,
|
void ShareSystem::BindNativeToPlugin(CPlugin *pPlugin,
|
||||||
const Ref<Native> &pEntry)
|
sp_native_t *native,
|
||||||
|
uint32_t index,
|
||||||
|
NativeEntry *pEntry)
|
||||||
{
|
{
|
||||||
/* Mark as bound... we do the rest next. */
|
/* Mark as bound... we do the rest next. */
|
||||||
native->status = SP_NATIVE_BOUND;
|
native->status = SP_NATIVE_BOUND;
|
||||||
native->pfn = pEntry->func();
|
native->user = pEntry;
|
||||||
|
|
||||||
if (pEntry->fake)
|
/* See if a replacement is available. */
|
||||||
|
if (pEntry->replacement.owner != NULL)
|
||||||
{
|
{
|
||||||
/* This native is not necessarily optional, but we don't guarantee
|
/* Perform a replacement bind. */
|
||||||
* that its address is long-lived. */
|
native->pfn = pEntry->replacement.func;
|
||||||
native->flags |= SP_NTVFLAG_EPHEMERAL;
|
pEntry->replacement.owner->AddWeakRef(WeakNative(pPlugin, index, pEntry));
|
||||||
}
|
}
|
||||||
|
else
|
||||||
/* We don't bother with dependency crap if the owner is Core. */
|
|
||||||
if (pEntry->owner != &g_CoreNatives)
|
|
||||||
{
|
{
|
||||||
/* The native is optional, this is a special case */
|
/* Perform a normal bind. */
|
||||||
if ((native->flags & SP_NTVFLAG_OPTIONAL) == SP_NTVFLAG_OPTIONAL)
|
native->pfn = pEntry->func;
|
||||||
|
|
||||||
|
/* We don't bother with dependency crap if the owner is Core. */
|
||||||
|
if (pEntry->owner != g_pCoreNatives)
|
||||||
{
|
{
|
||||||
/* Only add if there is a valid owner. */
|
/* The native is optional, this is a special case */
|
||||||
if (pEntry->owner)
|
if ((native->flags & SP_NTVFLAG_OPTIONAL) == SP_NTVFLAG_OPTIONAL)
|
||||||
pEntry->owner->AddWeakRef(WeakNative(pPlugin, index));
|
|
||||||
else
|
|
||||||
native->status = SP_NATIVE_UNBOUND;
|
|
||||||
}
|
|
||||||
/* Otherwise, we're a strong dependent and not a weak one */
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* See if this has already been marked as a dependent.
|
|
||||||
* If it has, it means this relationship has already occurred,
|
|
||||||
* and there is no reason to do it again.
|
|
||||||
*/
|
|
||||||
if (pEntry->owner != pPlugin->ToNativeOwner()
|
|
||||||
&& pEntry->owner->GetMarkSerial() != g_mark_serial)
|
|
||||||
{
|
{
|
||||||
/* This has not been marked as a dependency yet */
|
/* Only add if there is a valid owner. */
|
||||||
//pPlugin->AddDependency(pEntry->owner);
|
if (pEntry->owner != NULL)
|
||||||
pEntry->owner->AddDependent(pPlugin);
|
{
|
||||||
pEntry->owner->SetMarkSerial(g_mark_serial);
|
pEntry->owner->AddWeakRef(WeakNative(pPlugin, index));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
native->status = SP_NATIVE_UNBOUND;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Otherwise, we're a strong dependent and not a weak one */
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* See if this has already been marked as a dependent.
|
||||||
|
* If it has, it means this relationship has already occurred,
|
||||||
|
* and there is no reason to do it again.
|
||||||
|
*/
|
||||||
|
if (pEntry->owner != pPlugin
|
||||||
|
&& pEntry->owner->GetMarkSerial() != g_mark_serial)
|
||||||
|
{
|
||||||
|
/* This has not been marked as a dependency yet */
|
||||||
|
//pPlugin->AddDependency(pEntry->owner);
|
||||||
|
pEntry->owner->AddDependent(pPlugin);
|
||||||
|
pEntry->owner->SetMarkSerial(g_mark_serial);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PassRef<Native> ShareSystem::AddNativeToCache(CNativeOwner *pOwner, const sp_nativeinfo_t *ntv)
|
NativeEntry *ShareSystem::AddNativeToCache(CNativeOwner *pOwner, const sp_nativeinfo_t *ntv)
|
||||||
{
|
{
|
||||||
NativeCache::Insert i = m_NtvCache.findForAdd(ntv->name);
|
NativeEntry *pEntry;
|
||||||
if (i.found())
|
|
||||||
|
if ((pEntry = FindNative(ntv->name)) == NULL)
|
||||||
|
{
|
||||||
|
pEntry = new NativeEntry;
|
||||||
|
|
||||||
|
pEntry->owner = pOwner;
|
||||||
|
pEntry->name = ntv->name;
|
||||||
|
pEntry->func = ntv->func;
|
||||||
|
pEntry->replacement.func = NULL;
|
||||||
|
pEntry->replacement.owner = NULL;
|
||||||
|
pEntry->fake = NULL;
|
||||||
|
|
||||||
|
m_NtvCache.insert(ntv->name, pEntry);
|
||||||
|
|
||||||
|
return pEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pEntry->owner != NULL)
|
||||||
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
Ref<Native> entry = Newborn<Native>(new Native(pOwner, ntv));
|
pEntry->owner = pOwner;
|
||||||
m_NtvCache.insert(ntv->name, entry);
|
pEntry->func = ntv->func;
|
||||||
return entry;
|
pEntry->name = ntv->name;
|
||||||
}
|
|
||||||
|
|
||||||
FakeNative::~FakeNative()
|
return pEntry;
|
||||||
{
|
|
||||||
g_pSourcePawn2->DestroyFakeNative(gate);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShareSystem::ClearNativeFromCache(CNativeOwner *pOwner, const char *name)
|
void ShareSystem::ClearNativeFromCache(CNativeOwner *pOwner, const char *name)
|
||||||
{
|
{
|
||||||
NativeCache::Result r = m_NtvCache.find(name);
|
NativeEntry *pEntry;
|
||||||
if (!r.found())
|
|
||||||
|
if ((pEntry = FindNative(name)) == NULL)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Ref<Native> entry(*r);
|
if (pEntry->owner != pOwner)
|
||||||
if (entry->owner != pOwner)
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Clear out the owner bit as a sanity measure.
|
if (pEntry->fake != NULL)
|
||||||
entry->owner = NULL;
|
{
|
||||||
|
g_pSourcePawn2->DestroyFakeNative(pEntry->func);
|
||||||
|
delete pEntry->fake;
|
||||||
|
pEntry->fake = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
m_NtvCache.remove(r);
|
pEntry->func = NULL;
|
||||||
|
pEntry->name = NULL;
|
||||||
|
pEntry->owner = NULL;
|
||||||
|
pEntry->replacement.func = NULL;
|
||||||
|
pEntry->replacement.owner = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
PassRef<Native> ShareSystem::AddFakeNative(IPluginFunction *pFunc, const char *name, SPVM_FAKENATIVE_FUNC func)
|
NativeEntry *ShareSystem::AddFakeNative(IPluginFunction *pFunc, const char *name, SPVM_FAKENATIVE_FUNC func)
|
||||||
{
|
{
|
||||||
Ref<Native> entry(FindNative(name));
|
FakeNative *pFake;
|
||||||
if (entry)
|
NativeEntry *pEntry;
|
||||||
|
SPVM_NATIVE_FUNC gate;
|
||||||
|
|
||||||
|
if ((pEntry = FindNative(name)) != NULL && pEntry->owner != NULL)
|
||||||
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
AutoPtr<FakeNative> fake(new FakeNative(name, pFunc));
|
pFake = new FakeNative;
|
||||||
|
|
||||||
fake->gate = g_pSourcePawn2->CreateFakeNative(func, fake);
|
if ((gate = g_pSourcePawn2->CreateFakeNative(func, pFake)) == NULL)
|
||||||
if (!fake->gate)
|
{
|
||||||
|
delete pFake;
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
CNativeOwner *owner = g_PluginSys.GetPluginByCtx(fake->ctx->GetContext());
|
if (pEntry == NULL)
|
||||||
|
{
|
||||||
|
pEntry = new NativeEntry;
|
||||||
|
m_NtvCache.insert(name, pEntry);
|
||||||
|
}
|
||||||
|
|
||||||
entry = Newborn<Native>(new Native(owner, fake.take()));
|
pFake->call = pFunc;
|
||||||
m_NtvCache.insert(name, entry);
|
pFake->ctx = pFunc->GetParentContext();
|
||||||
|
strncopy(pFake->name, name, sizeof(pFake->name));
|
||||||
|
|
||||||
|
pEntry->fake = pFake;
|
||||||
|
pEntry->func = gate;
|
||||||
|
pEntry->name = pFake->name;
|
||||||
|
pEntry->owner = g_PluginSys.GetPluginByCtx(pFake->ctx->GetContext());
|
||||||
|
pEntry->replacement.func = NULL;
|
||||||
|
pEntry->replacement.owner = NULL;
|
||||||
|
|
||||||
return entry;
|
return pEntry;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShareSystem::AddCapabilityProvider(IExtension *myself, IFeatureProvider *provider,
|
void ShareSystem::AddCapabilityProvider(IExtension *myself, IFeatureProvider *provider,
|
||||||
const char *name)
|
const char *name)
|
||||||
{
|
{
|
||||||
if (m_caps.contains(name))
|
if (m_caps.retrieve(name) != NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Capability cap;
|
Capability cap;
|
||||||
@@ -437,13 +544,14 @@ void ShareSystem::AddCapabilityProvider(IExtension *myself, IFeatureProvider *pr
|
|||||||
void ShareSystem::DropCapabilityProvider(IExtension *myself, IFeatureProvider *provider,
|
void ShareSystem::DropCapabilityProvider(IExtension *myself, IFeatureProvider *provider,
|
||||||
const char *name)
|
const char *name)
|
||||||
{
|
{
|
||||||
StringHashMap<Capability>::Result r = m_caps.find(name);
|
Capability *pCap = m_caps.retrieve(name);
|
||||||
if (!r.found())
|
if (pCap == NULL)
|
||||||
return;
|
|
||||||
if (r->value.ext != myself || r->value.provider != provider)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_caps.remove(r);
|
if (pCap->ext != myself || pCap->provider != provider)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_caps.remove(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
FeatureStatus ShareSystem::TestFeature(IPluginRuntime *pRuntime, FeatureType feature,
|
FeatureStatus ShareSystem::TestFeature(IPluginRuntime *pRuntime, FeatureType feature,
|
||||||
@@ -478,18 +586,26 @@ FeatureStatus ShareSystem::TestNative(IPluginRuntime *pRuntime, const char *name
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<Native> entry = FindNative(name);
|
NativeEntry *entry = FindNative(name);
|
||||||
if (!entry)
|
if (entry == NULL)
|
||||||
return FeatureStatus_Unknown;
|
return FeatureStatus_Unknown;
|
||||||
|
|
||||||
return FeatureStatus_Unavailable;
|
if ((entry->replacement.owner != NULL || entry->owner != NULL) &&
|
||||||
|
(entry->replacement.func != NULL || entry->func != NULL))
|
||||||
|
{
|
||||||
|
return FeatureStatus_Available;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return FeatureStatus_Unavailable;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FeatureStatus ShareSystem::TestCap(const char *name)
|
FeatureStatus ShareSystem::TestCap(const char *name)
|
||||||
{
|
{
|
||||||
StringHashMap<Capability>::Result r = m_caps.find(name);
|
Capability *cap = m_caps.retrieve(name);
|
||||||
if (!r.found())
|
if (cap == NULL)
|
||||||
return FeatureStatus_Unknown;
|
return FeatureStatus_Unknown;
|
||||||
|
|
||||||
return r->value.provider->GetFeatureStatus(FeatureType_Capability, name);
|
return cap->provider->GetFeatureStatus(FeatureType_Capability, name);
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* vim: set ts=4 sw=4 tw=99 noet :
|
* vim: set ts=4 :
|
||||||
* =============================================================================
|
* =============================================================================
|
||||||
* SourceMod
|
* SourceMod
|
||||||
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
||||||
@@ -34,14 +34,10 @@
|
|||||||
|
|
||||||
#include <IShareSys.h>
|
#include <IShareSys.h>
|
||||||
#include <IHandleSys.h>
|
#include <IHandleSys.h>
|
||||||
#include <am-string.h>
|
|
||||||
#include <am-utility.h>
|
|
||||||
#include <am-refcounting.h>
|
|
||||||
#include <sh_list.h>
|
#include <sh_list.h>
|
||||||
#include <sm_stringhashmap.h>
|
#include <sm_trie_tpl.h>
|
||||||
#include <sm_namehashset.h>
|
#include "sm_globals.h"
|
||||||
#include "common_logic.h"
|
#include "sourcemod.h"
|
||||||
#include "Native.h"
|
|
||||||
|
|
||||||
using namespace SourceHook;
|
using namespace SourceHook;
|
||||||
|
|
||||||
@@ -67,6 +63,29 @@ struct IfaceInfo
|
|||||||
|
|
||||||
class CNativeOwner;
|
class CNativeOwner;
|
||||||
class CPlugin;
|
class CPlugin;
|
||||||
|
struct NativeEntry;
|
||||||
|
|
||||||
|
struct ReplaceNative
|
||||||
|
{
|
||||||
|
CNativeOwner *owner;
|
||||||
|
SPVM_NATIVE_FUNC func;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FakeNative
|
||||||
|
{
|
||||||
|
char name[64];
|
||||||
|
IPluginContext *ctx;
|
||||||
|
IPluginFunction *call;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct NativeEntry
|
||||||
|
{
|
||||||
|
CNativeOwner *owner;
|
||||||
|
SPVM_NATIVE_FUNC func;
|
||||||
|
const char *name;
|
||||||
|
ReplaceNative replacement;
|
||||||
|
FakeNative *fake;
|
||||||
|
};
|
||||||
|
|
||||||
struct Capability
|
struct Capability
|
||||||
{
|
{
|
||||||
@@ -120,23 +139,24 @@ public:
|
|||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
void BindNativesToPlugin(CPlugin *pPlugin, bool bCoreOnly);
|
void BindNativesToPlugin(CPlugin *pPlugin, bool bCoreOnly);
|
||||||
void BindNativeToPlugin(CPlugin *pPlugin, const ke::Ref<Native> &pEntry);
|
void BindNativeToPlugin(CPlugin *pPlugin, NativeEntry *pEntry);
|
||||||
ke::PassRef<Native> AddFakeNative(IPluginFunction *pFunc, const char *name, SPVM_FAKENATIVE_FUNC func);
|
NativeEntry *AddFakeNative(IPluginFunction *pFunc, const char *name, SPVM_FAKENATIVE_FUNC func);
|
||||||
ke::PassRef<Native> FindNative(const char *name);
|
NativeEntry *FindNative(const char *name);
|
||||||
private:
|
private:
|
||||||
ke::PassRef<Native> AddNativeToCache(CNativeOwner *pOwner, const sp_nativeinfo_t *ntv);
|
NativeEntry *AddNativeToCache(CNativeOwner *pOwner, const sp_nativeinfo_t *ntv);
|
||||||
void ClearNativeFromCache(CNativeOwner *pOwner, const char *name);
|
void ClearNativeFromCache(CNativeOwner *pOwner, const char *name);
|
||||||
void BindNativeToPlugin(CPlugin *pPlugin, sp_native_t *ntv, uint32_t index, const ke::Ref<Native> &pEntry);
|
void BindNativeToPlugin(CPlugin *pPlugin,
|
||||||
|
sp_native_t *ntv,
|
||||||
|
uint32_t index,
|
||||||
|
NativeEntry *pEntry);
|
||||||
private:
|
private:
|
||||||
typedef NameHashSet<ke::Ref<Native>, Native> NativeCache;
|
|
||||||
|
|
||||||
List<IfaceInfo> m_Interfaces;
|
List<IfaceInfo> m_Interfaces;
|
||||||
HandleType_t m_TypeRoot;
|
HandleType_t m_TypeRoot;
|
||||||
IdentityToken_t m_IdentRoot;
|
IdentityToken_t m_IdentRoot;
|
||||||
HandleType_t m_IfaceType;
|
HandleType_t m_IfaceType;
|
||||||
IdentityType_t m_CoreType;
|
IdentityType_t m_CoreType;
|
||||||
NativeCache m_NtvCache;
|
KTrie<NativeEntry *> m_NtvCache;
|
||||||
StringHashMap<Capability> m_caps;
|
KTrie<Capability> m_caps;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern ShareSystem g_ShareSys;
|
extern ShareSystem g_ShareSys;
|
||||||
+6
-6
@@ -31,10 +31,10 @@
|
|||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include "TimerSys.h"
|
#include "TimerSys.h"
|
||||||
|
#include "ForwardSys.h"
|
||||||
#include "sourcemm_api.h"
|
#include "sourcemm_api.h"
|
||||||
#include "frame_hooks.h"
|
#include "frame_hooks.h"
|
||||||
#include "ConVarManager.h"
|
#include "ConVarManager.h"
|
||||||
#include "logic_bridge.h"
|
|
||||||
|
|
||||||
#define TIMER_MIN_ACCURACY 0.1
|
#define TIMER_MIN_ACCURACY 0.1
|
||||||
|
|
||||||
@@ -180,9 +180,9 @@ TimerSystem::~TimerSystem()
|
|||||||
|
|
||||||
void TimerSystem::OnSourceModAllInitialized()
|
void TimerSystem::OnSourceModAllInitialized()
|
||||||
{
|
{
|
||||||
sharesys->AddInterface(NULL, this);
|
g_ShareSys.AddInterface(NULL, this);
|
||||||
m_pOnGameFrame = forwardsys->CreateForward("OnGameFrame", ET_Ignore, 0, NULL);
|
m_pOnGameFrame = g_Forwards.CreateForward("OnGameFrame", ET_Ignore, 0, NULL);
|
||||||
m_pOnMapTimeLeftChanged = forwardsys->CreateForward("OnMapTimeLeftChanged", ET_Ignore, 0, NULL);
|
m_pOnMapTimeLeftChanged = g_Forwards.CreateForward("OnMapTimeLeftChanged", ET_Ignore, 0, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TimerSystem::OnSourceModGameInitialized()
|
void TimerSystem::OnSourceModGameInitialized()
|
||||||
@@ -198,8 +198,8 @@ void TimerSystem::OnSourceModGameInitialized()
|
|||||||
void TimerSystem::OnSourceModShutdown()
|
void TimerSystem::OnSourceModShutdown()
|
||||||
{
|
{
|
||||||
SetMapTimer(NULL);
|
SetMapTimer(NULL);
|
||||||
forwardsys->ReleaseForward(m_pOnGameFrame);
|
g_Forwards.ReleaseForward(m_pOnGameFrame);
|
||||||
forwardsys->ReleaseForward(m_pOnMapTimeLeftChanged);
|
g_Forwards.ReleaseForward(m_pOnMapTimeLeftChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TimerSystem::OnSourceModLevelEnd()
|
void TimerSystem::OnSourceModLevelEnd()
|
||||||
|
|||||||
+1
-1
@@ -32,11 +32,11 @@
|
|||||||
#ifndef _INCLUDE_SOURCEMOD_CTIMERSYS_H_
|
#ifndef _INCLUDE_SOURCEMOD_CTIMERSYS_H_
|
||||||
#define _INCLUDE_SOURCEMOD_CTIMERSYS_H_
|
#define _INCLUDE_SOURCEMOD_CTIMERSYS_H_
|
||||||
|
|
||||||
|
#include "ShareSys.h"
|
||||||
#include <ITimerSystem.h>
|
#include <ITimerSystem.h>
|
||||||
#include <sh_stack.h>
|
#include <sh_stack.h>
|
||||||
#include <sh_list.h>
|
#include <sh_list.h>
|
||||||
#include "sourcemm_api.h"
|
#include "sourcemm_api.h"
|
||||||
#include "sm_globals.h"
|
|
||||||
|
|
||||||
using namespace SourceHook;
|
using namespace SourceHook;
|
||||||
using namespace SourceMod;
|
using namespace SourceMod;
|
||||||
|
|||||||
+16
-103
@@ -56,15 +56,6 @@
|
|||||||
return false; \
|
return false; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CHECK_FIELD_TYPE3(type1, type2, type3) \
|
|
||||||
protobuf::FieldDescriptor::CppType fieldType = field->cpp_type(); \
|
|
||||||
if (fieldType != protobuf::FieldDescriptor::CPPTYPE_##type1 \
|
|
||||||
&& fieldType != protobuf::FieldDescriptor::CPPTYPE_##type2 \
|
|
||||||
&& fieldType != protobuf::FieldDescriptor::CPPTYPE_##type3) \
|
|
||||||
{ \
|
|
||||||
return false; \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define CHECK_FIELD_REPEATED() \
|
#define CHECK_FIELD_REPEATED() \
|
||||||
if (field->label() != protobuf::FieldDescriptor::LABEL_REPEATED) \
|
if (field->label() != protobuf::FieldDescriptor::LABEL_REPEATED) \
|
||||||
{ \
|
{ \
|
||||||
@@ -102,7 +93,7 @@ public:
|
|||||||
Handle_t &hndl = (*iter);
|
Handle_t &hndl = (*iter);
|
||||||
HandleSecurity sec;
|
HandleSecurity sec;
|
||||||
sec.pIdentity = g_pCoreIdent;
|
sec.pIdentity = g_pCoreIdent;
|
||||||
handlesys->FreeHandle(hndl, &sec);
|
g_HandleSys.FreeHandle(hndl, &sec);
|
||||||
iter = childHandles.erase(iter);
|
iter = childHandles.erase(iter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -325,114 +316,74 @@ public:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool GetInt32OrUnsignedOrEnum(const char *pszFieldName, int32 *out)
|
inline bool GetInt32OrUnsigned(const char *pszFieldName, int32 *out)
|
||||||
{
|
{
|
||||||
GETCHECK_FIELD();
|
GETCHECK_FIELD();
|
||||||
CHECK_FIELD_TYPE3(INT32, UINT32, ENUM);
|
CHECK_FIELD_TYPE2(INT32, UINT32);
|
||||||
CHECK_FIELD_NOT_REPEATED();
|
CHECK_FIELD_NOT_REPEATED();
|
||||||
|
|
||||||
if (fieldType == protobuf::FieldDescriptor::CPPTYPE_UINT32)
|
if (fieldType == protobuf::FieldDescriptor::CPPTYPE_UINT32)
|
||||||
*out = (int32)msg->GetReflection()->GetUInt32(*msg, field);
|
*out = (int32)msg->GetReflection()->GetUInt32(*msg, field);
|
||||||
else if (fieldType == protobuf::FieldDescriptor::CPPTYPE_INT32)
|
else
|
||||||
*out = msg->GetReflection()->GetInt32(*msg, field);
|
*out = msg->GetReflection()->GetInt32(*msg, field);
|
||||||
else // CPPTYPE_ENUM
|
|
||||||
*out = msg->GetReflection()->GetEnum(*msg, field)->number();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool SetInt32OrUnsignedOrEnum(const char *pszFieldName, int32 value)
|
inline bool SetInt32OrUnsigned(const char *pszFieldName, int32 value)
|
||||||
{
|
{
|
||||||
GETCHECK_FIELD();
|
GETCHECK_FIELD();
|
||||||
CHECK_FIELD_TYPE3(INT32, UINT32, ENUM);
|
CHECK_FIELD_TYPE2(INT32, UINT32);
|
||||||
CHECK_FIELD_NOT_REPEATED();
|
CHECK_FIELD_NOT_REPEATED();
|
||||||
|
|
||||||
if (fieldType == protobuf::FieldDescriptor::CPPTYPE_UINT32)
|
if (fieldType == protobuf::FieldDescriptor::CPPTYPE_UINT32)
|
||||||
{
|
|
||||||
msg->GetReflection()->SetUInt32(msg, field, (uint32)value);
|
msg->GetReflection()->SetUInt32(msg, field, (uint32)value);
|
||||||
}
|
else
|
||||||
else if (fieldType == protobuf::FieldDescriptor::CPPTYPE_INT32)
|
|
||||||
{
|
|
||||||
msg->GetReflection()->SetInt32(msg, field, value);
|
msg->GetReflection()->SetInt32(msg, field, value);
|
||||||
}
|
|
||||||
else // CPPTYPE_ENUM
|
|
||||||
{
|
|
||||||
const protobuf::EnumValueDescriptor *pEnumValue = field->enum_type()->FindValueByNumber(value);
|
|
||||||
if (!pEnumValue)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
msg->GetReflection()->SetEnum(msg, field, pEnumValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool GetRepeatedInt32OrUnsignedOrEnum(const char *pszFieldName, int index, int32 *out)
|
inline bool GetRepeatedInt32OrUnsigned(const char *pszFieldName, int index, int32 *out)
|
||||||
{
|
{
|
||||||
GETCHECK_FIELD();
|
GETCHECK_FIELD();
|
||||||
CHECK_FIELD_TYPE3(INT32, UINT32, ENUM);
|
CHECK_FIELD_TYPE2(INT32, UINT32);
|
||||||
CHECK_FIELD_REPEATED();
|
CHECK_FIELD_REPEATED();
|
||||||
CHECK_REPEATED_ELEMENT(index);
|
CHECK_REPEATED_ELEMENT(index);
|
||||||
|
|
||||||
if (fieldType == protobuf::FieldDescriptor::CPPTYPE_UINT32)
|
if (fieldType == protobuf::FieldDescriptor::CPPTYPE_UINT32)
|
||||||
*out = (int32)msg->GetReflection()->GetRepeatedUInt32(*msg, field, index);
|
*out = (int32)msg->GetReflection()->GetRepeatedUInt32(*msg, field, index);
|
||||||
else if (fieldType == protobuf::FieldDescriptor::CPPTYPE_INT32)
|
else
|
||||||
*out = msg->GetReflection()->GetRepeatedInt32(*msg, field, index);
|
*out = msg->GetReflection()->GetRepeatedInt32(*msg, field, index);
|
||||||
else // CPPTYPE_ENUM
|
|
||||||
*out = msg->GetReflection()->GetRepeatedEnum(*msg, field, index)->number();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool SetRepeatedInt32OrUnsignedOrEnum(const char *pszFieldName, int index, int32 value)
|
inline bool SetRepeatedInt32OrUnsigned(const char *pszFieldName, int index, int32 value)
|
||||||
{
|
{
|
||||||
GETCHECK_FIELD();
|
GETCHECK_FIELD();
|
||||||
CHECK_FIELD_TYPE3(INT32, UINT32, ENUM);
|
CHECK_FIELD_TYPE2(INT32, UINT32);
|
||||||
CHECK_FIELD_REPEATED();
|
CHECK_FIELD_REPEATED();
|
||||||
CHECK_REPEATED_ELEMENT(index);
|
CHECK_REPEATED_ELEMENT(index);
|
||||||
|
|
||||||
if (fieldType == protobuf::FieldDescriptor::CPPTYPE_UINT32)
|
if (fieldType == protobuf::FieldDescriptor::CPPTYPE_UINT32)
|
||||||
{
|
|
||||||
msg->GetReflection()->SetRepeatedUInt32(msg, field, index, (uint32)value);
|
msg->GetReflection()->SetRepeatedUInt32(msg, field, index, (uint32)value);
|
||||||
}
|
else
|
||||||
else if (fieldType == protobuf::FieldDescriptor::CPPTYPE_INT32)
|
|
||||||
{
|
|
||||||
msg->GetReflection()->SetRepeatedInt32(msg, field, index, value);
|
msg->GetReflection()->SetRepeatedInt32(msg, field, index, value);
|
||||||
}
|
|
||||||
else // CPPTYPE_ENUM
|
|
||||||
{
|
|
||||||
const protobuf::EnumValueDescriptor *pEnumValue = field->enum_type()->FindValueByNumber(value);
|
|
||||||
if (!pEnumValue)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
msg->GetReflection()->SetRepeatedEnum(msg, field, index, pEnumValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool AddInt32OrUnsignedOrEnum(const char *pszFieldName, int32 value)
|
inline bool AddInt32OrUnsigned(const char *pszFieldName, int32 value)
|
||||||
{
|
{
|
||||||
GETCHECK_FIELD();
|
GETCHECK_FIELD();
|
||||||
CHECK_FIELD_TYPE3(INT32, UINT32, ENUM);
|
CHECK_FIELD_TYPE2(INT32, UINT32);
|
||||||
CHECK_FIELD_REPEATED();
|
CHECK_FIELD_REPEATED();
|
||||||
|
|
||||||
if (fieldType == protobuf::FieldDescriptor::CPPTYPE_UINT32)
|
if (fieldType == protobuf::FieldDescriptor::CPPTYPE_UINT32)
|
||||||
{
|
|
||||||
msg->GetReflection()->AddUInt32(msg, field, (uint32)value);
|
msg->GetReflection()->AddUInt32(msg, field, (uint32)value);
|
||||||
}
|
else
|
||||||
else if (fieldType == protobuf::FieldDescriptor::CPPTYPE_INT32)
|
|
||||||
{
|
|
||||||
msg->GetReflection()->AddInt32(msg, field, value);
|
msg->GetReflection()->AddInt32(msg, field, value);
|
||||||
}
|
|
||||||
else // CPPTYPE_ENUM
|
|
||||||
{
|
|
||||||
const protobuf::EnumValueDescriptor *pEnumValue = field->enum_type()->FindValueByNumber(value);
|
|
||||||
if (!pEnumValue)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
msg->GetReflection()->AddEnum(msg, field, pEnumValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -724,9 +675,6 @@ public:
|
|||||||
|
|
||||||
inline bool GetColor(const char *pszFieldName, Color *out)
|
inline bool GetColor(const char *pszFieldName, Color *out)
|
||||||
{
|
{
|
||||||
#if SOURCE_ENGINE != SE_CSGO
|
|
||||||
return false;
|
|
||||||
#else
|
|
||||||
GETCHECK_FIELD();
|
GETCHECK_FIELD();
|
||||||
CHECK_FIELD_TYPE(MESSAGE);
|
CHECK_FIELD_TYPE(MESSAGE);
|
||||||
CHECK_FIELD_NOT_REPEATED();
|
CHECK_FIELD_NOT_REPEATED();
|
||||||
@@ -740,14 +688,10 @@ public:
|
|||||||
);
|
);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool SetColor(const char *pszFieldName, const Color &value)
|
inline bool SetColor(const char *pszFieldName, const Color &value)
|
||||||
{
|
{
|
||||||
#if SOURCE_ENGINE != SE_CSGO
|
|
||||||
return false;
|
|
||||||
#else
|
|
||||||
GETCHECK_FIELD();
|
GETCHECK_FIELD();
|
||||||
CHECK_FIELD_TYPE(MESSAGE);
|
CHECK_FIELD_TYPE(MESSAGE);
|
||||||
CHECK_FIELD_NOT_REPEATED();
|
CHECK_FIELD_NOT_REPEATED();
|
||||||
@@ -759,14 +703,10 @@ public:
|
|||||||
msgRGBA->set_a(value.a());
|
msgRGBA->set_a(value.a());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool GetRepeatedColor(const char *pszFieldName, int index, Color *out)
|
inline bool GetRepeatedColor(const char *pszFieldName, int index, Color *out)
|
||||||
{
|
{
|
||||||
#if SOURCE_ENGINE != SE_CSGO
|
|
||||||
return false;
|
|
||||||
#else
|
|
||||||
GETCHECK_FIELD();
|
GETCHECK_FIELD();
|
||||||
CHECK_FIELD_TYPE(MESSAGE);
|
CHECK_FIELD_TYPE(MESSAGE);
|
||||||
CHECK_FIELD_REPEATED();
|
CHECK_FIELD_REPEATED();
|
||||||
@@ -781,14 +721,10 @@ public:
|
|||||||
);
|
);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool SetRepeatedColor(const char *pszFieldName, int index, const Color &value)
|
inline bool SetRepeatedColor(const char *pszFieldName, int index, const Color &value)
|
||||||
{
|
{
|
||||||
#if SOURCE_ENGINE != SE_CSGO
|
|
||||||
return false;
|
|
||||||
#else
|
|
||||||
GETCHECK_FIELD();
|
GETCHECK_FIELD();
|
||||||
CHECK_FIELD_TYPE(MESSAGE);
|
CHECK_FIELD_TYPE(MESSAGE);
|
||||||
CHECK_FIELD_REPEATED();
|
CHECK_FIELD_REPEATED();
|
||||||
@@ -801,14 +737,10 @@ public:
|
|||||||
msgRGBA->set_a(value.a());
|
msgRGBA->set_a(value.a());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool AddColor(const char *pszFieldName, const Color &value)
|
inline bool AddColor(const char *pszFieldName, const Color &value)
|
||||||
{
|
{
|
||||||
#if SOURCE_ENGINE != SE_CSGO
|
|
||||||
return false;
|
|
||||||
#else
|
|
||||||
GETCHECK_FIELD();
|
GETCHECK_FIELD();
|
||||||
CHECK_FIELD_TYPE(MESSAGE);
|
CHECK_FIELD_TYPE(MESSAGE);
|
||||||
CHECK_FIELD_REPEATED();
|
CHECK_FIELD_REPEATED();
|
||||||
@@ -820,7 +752,6 @@ public:
|
|||||||
msgRGBA->set_a(value.a());
|
msgRGBA->set_a(value.a());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool GetVector2D(const char *pszFieldName, Vector2D *out)
|
inline bool GetVector2D(const char *pszFieldName, Vector2D *out)
|
||||||
@@ -1093,24 +1024,6 @@ public:
|
|||||||
return msg->GetReflection()->FieldSize(*msg, field);
|
return msg->GetReflection()->FieldSize(*msg, field);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool RemoveRepeatedFieldValue(const char *pszFieldName, int index)
|
|
||||||
{
|
|
||||||
GETCHECK_FIELD();
|
|
||||||
CHECK_FIELD_REPEATED();
|
|
||||||
CHECK_REPEATED_ELEMENT(index);
|
|
||||||
|
|
||||||
// Protobuf guarantees that repeated field values will stay in order and so must we.
|
|
||||||
const protobuf::Reflection *pReflection = msg->GetReflection();
|
|
||||||
for (int i = index; i < elemCount - 1; ++i)
|
|
||||||
{
|
|
||||||
pReflection->SwapElements(msg, field, i, i + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
pReflection->RemoveLast(msg, field);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
protobuf::Message *msg;
|
protobuf::Message *msg;
|
||||||
PBHandleList childHandles;
|
PBHandleList childHandles;
|
||||||
|
|||||||
+52
-76
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* vim: set ts=4 sw=4 tw=99 noet :
|
* vim: set ts=4 :
|
||||||
* =============================================================================
|
* =============================================================================
|
||||||
* SourceMod
|
* SourceMod
|
||||||
* Copyright (C) 2004-2010 AlliedModders LLC. All rights reserved.
|
* Copyright (C) 2004-2010 AlliedModders LLC. All rights reserved.
|
||||||
@@ -31,17 +31,14 @@
|
|||||||
|
|
||||||
#include "UserMessages.h"
|
#include "UserMessages.h"
|
||||||
#include "sm_stringutil.h"
|
#include "sm_stringutil.h"
|
||||||
#include "logic_bridge.h"
|
|
||||||
|
|
||||||
#if SOURCE_ENGINE == SE_DOTA
|
#if SOURCE_ENGINE == SE_CSGO
|
||||||
#include <dota_usermessage_helpers.h>
|
|
||||||
#elif SOURCE_ENGINE == SE_CSGO
|
|
||||||
#include <cstrike15_usermessage_helpers.h>
|
#include <cstrike15_usermessage_helpers.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
UserMessages g_UserMsgs;
|
UserMessages g_UserMsgs;
|
||||||
|
|
||||||
#if SOURCE_ENGINE == SE_CSGO || SOURCE_ENGINE == SE_DOTA
|
#if SOURCE_ENGINE == SE_CSGO
|
||||||
SH_DECL_HOOK3_void(IVEngineServer, SendUserMessage, SH_NOATTRIB, 0, IRecipientFilter &, int, const protobuf::Message &);
|
SH_DECL_HOOK3_void(IVEngineServer, SendUserMessage, SH_NOATTRIB, 0, IRecipientFilter &, int, const protobuf::Message &);
|
||||||
#else
|
#else
|
||||||
#if SOURCE_ENGINE >= SE_LEFT4DEAD
|
#if SOURCE_ENGINE >= SE_LEFT4DEAD
|
||||||
@@ -56,6 +53,7 @@ UserMessages::UserMessages()
|
|||||||
#ifndef USE_PROTOBUF_USERMESSAGES
|
#ifndef USE_PROTOBUF_USERMESSAGES
|
||||||
: m_InterceptBuffer(m_pBase, 2500)
|
: m_InterceptBuffer(m_pBase, 2500)
|
||||||
{
|
{
|
||||||
|
m_Names = sm_trie_create();
|
||||||
#else
|
#else
|
||||||
: m_InterceptBuffer(NULL)
|
: m_InterceptBuffer(NULL)
|
||||||
{
|
{
|
||||||
@@ -69,6 +67,10 @@ UserMessages::UserMessages()
|
|||||||
|
|
||||||
UserMessages::~UserMessages()
|
UserMessages::~UserMessages()
|
||||||
{
|
{
|
||||||
|
#ifndef USE_PROTOBUF_USERMESSAGES
|
||||||
|
sm_trie_destroy(m_Names);
|
||||||
|
#endif
|
||||||
|
|
||||||
CStack<ListenerInfo *>::iterator iter;
|
CStack<ListenerInfo *>::iterator iter;
|
||||||
for (iter=m_FreeListeners.begin(); iter!=m_FreeListeners.end(); iter++)
|
for (iter=m_FreeListeners.begin(); iter!=m_FreeListeners.end(); iter++)
|
||||||
{
|
{
|
||||||
@@ -87,21 +89,21 @@ void UserMessages::OnSourceModStartup(bool late)
|
|||||||
|
|
||||||
void UserMessages::OnSourceModAllInitialized()
|
void UserMessages::OnSourceModAllInitialized()
|
||||||
{
|
{
|
||||||
sharesys->AddInterface(NULL, this);
|
g_ShareSys.AddInterface(NULL, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UserMessages::OnSourceModAllShutdown()
|
void UserMessages::OnSourceModAllShutdown()
|
||||||
{
|
{
|
||||||
if (m_HookCount)
|
if (m_HookCount)
|
||||||
{
|
{
|
||||||
#if SOURCE_ENGINE == SE_CSGO || SOURCE_ENGINE == SE_DOTA
|
#if SOURCE_ENGINE == SE_CSGO
|
||||||
SH_REMOVE_HOOK(IVEngineServer, SendUserMessage, engine, SH_MEMBER(this, &UserMessages::OnSendUserMessage_Pre), false);
|
SH_REMOVE_HOOK_MEMFUNC(IVEngineServer, SendUserMessage, engine, this, &UserMessages::OnSendUserMessage_Pre, false);
|
||||||
SH_REMOVE_HOOK(IVEngineServer, SendUserMessage, engine, SH_MEMBER(this, &UserMessages::OnSendUserMessage_Post), true);
|
SH_REMOVE_HOOK_MEMFUNC(IVEngineServer, SendUserMessage, engine, this, &UserMessages::OnSendUserMessage_Post, true);
|
||||||
#else
|
#else
|
||||||
SH_REMOVE_HOOK(IVEngineServer, UserMessageBegin, engine, SH_MEMBER(this, &UserMessages::OnStartMessage_Pre), false);
|
SH_REMOVE_HOOK_MEMFUNC(IVEngineServer, UserMessageBegin, engine, this, &UserMessages::OnStartMessage_Pre, false);
|
||||||
SH_REMOVE_HOOK(IVEngineServer, UserMessageBegin, engine, SH_MEMBER(this, &UserMessages::OnStartMessage_Post), true);
|
SH_REMOVE_HOOK_MEMFUNC(IVEngineServer, UserMessageBegin, engine, this, &UserMessages::OnStartMessage_Post, true);
|
||||||
SH_REMOVE_HOOK(IVEngineServer, MessageEnd, engine, SH_MEMBER(this, &UserMessages::OnMessageEnd_Pre), false);
|
SH_REMOVE_HOOK_MEMFUNC(IVEngineServer, MessageEnd, engine, this, &UserMessages::OnMessageEnd_Pre, false);
|
||||||
SH_REMOVE_HOOK(IVEngineServer, MessageEnd, engine, SH_MEMBER(this, &UserMessages::OnMessageEnd_Post), true);
|
SH_REMOVE_HOOK_MEMFUNC(IVEngineServer, MessageEnd, engine, this, &UserMessages::OnMessageEnd_Post, true);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
m_HookCount = 0;
|
m_HookCount = 0;
|
||||||
@@ -109,16 +111,13 @@ void UserMessages::OnSourceModAllShutdown()
|
|||||||
|
|
||||||
int UserMessages::GetMessageIndex(const char *msg)
|
int UserMessages::GetMessageIndex(const char *msg)
|
||||||
{
|
{
|
||||||
#if SOURCE_ENGINE == SE_DOTA
|
#if SOURCE_ENGINE == SE_CSGO
|
||||||
// Can split this per engine and/or game later
|
|
||||||
return g_DotaUsermessageHelpers.GetIndex(msg);
|
|
||||||
#elif SOURCE_ENGINE == SE_CSGO
|
|
||||||
// Can split this per engine and/or game later
|
// Can split this per engine and/or game later
|
||||||
return g_Cstrike15UsermessageHelpers.GetIndex(msg);
|
return g_Cstrike15UsermessageHelpers.GetIndex(msg);
|
||||||
#else
|
#else
|
||||||
|
|
||||||
int msgid;
|
int msgid;
|
||||||
if (!m_Names.retrieve(msg, &msgid))
|
|
||||||
|
if (!sm_trie_retrieve(m_Names, msg, reinterpret_cast<void **>(&msgid)))
|
||||||
{
|
{
|
||||||
if (m_FallbackSearch)
|
if (m_FallbackSearch)
|
||||||
{
|
{
|
||||||
@@ -130,7 +129,7 @@ int UserMessages::GetMessageIndex(const char *msg)
|
|||||||
{
|
{
|
||||||
if (strcmp(msgbuf, msg) == 0)
|
if (strcmp(msgbuf, msg) == 0)
|
||||||
{
|
{
|
||||||
m_Names.insert(msg, msgid);
|
sm_trie_insert(m_Names, msg, reinterpret_cast<void *>(msgid));
|
||||||
return msgid;
|
return msgid;
|
||||||
}
|
}
|
||||||
msgid++;
|
msgid++;
|
||||||
@@ -140,7 +139,9 @@ int UserMessages::GetMessageIndex(const char *msg)
|
|||||||
msgid = g_SMAPI->FindUserMessage(msg);
|
msgid = g_SMAPI->FindUserMessage(msg);
|
||||||
|
|
||||||
if (msgid != INVALID_MESSAGE_ID)
|
if (msgid != INVALID_MESSAGE_ID)
|
||||||
m_Names.insert(msg, msgid);
|
{
|
||||||
|
sm_trie_insert(m_Names, msg, reinterpret_cast<void *>(msgid));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return msgid;
|
return msgid;
|
||||||
@@ -149,12 +150,8 @@ int UserMessages::GetMessageIndex(const char *msg)
|
|||||||
|
|
||||||
bool UserMessages::GetMessageName(int msgid, char *buffer, size_t maxlength) const
|
bool UserMessages::GetMessageName(int msgid, char *buffer, size_t maxlength) const
|
||||||
{
|
{
|
||||||
#ifdef USE_PROTOBUF_USERMESSAGES
|
#if SOURCE_ENGINE == SE_CSGO
|
||||||
#if SOURCE_ENGINE == SE_DOTA
|
|
||||||
const char *pszName = g_DotaUsermessageHelpers.GetName(msgid);
|
|
||||||
#elif SOURCE_ENGINE == SE_CSGO
|
|
||||||
const char *pszName = g_Cstrike15UsermessageHelpers.GetName(msgid);
|
const char *pszName = g_Cstrike15UsermessageHelpers.GetName(msgid);
|
||||||
#endif
|
|
||||||
if (!pszName)
|
if (!pszName)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -262,7 +259,7 @@ google::protobuf::Message *UserMessages::StartProtobufMessage(int msg_id, const
|
|||||||
if (m_CurFlags & USERMSG_BLOCKHOOKS)
|
if (m_CurFlags & USERMSG_BLOCKHOOKS)
|
||||||
{
|
{
|
||||||
// direct message creation, return buffer "from engine". keep track
|
// direct message creation, return buffer "from engine". keep track
|
||||||
m_FakeEngineBuffer = GetMessagePrototype(msg_id)->New();
|
m_FakeEngineBuffer = g_Cstrike15UsermessageHelpers.GetPrototype(msg_id)->New();
|
||||||
buffer = m_FakeEngineBuffer;
|
buffer = m_FakeEngineBuffer;
|
||||||
} else {
|
} else {
|
||||||
char messageName[32];
|
char messageName[32];
|
||||||
@@ -277,12 +274,12 @@ google::protobuf::Message *UserMessages::StartProtobufMessage(int msg_id, const
|
|||||||
{
|
{
|
||||||
case MRES_IGNORED:
|
case MRES_IGNORED:
|
||||||
case MRES_HANDLED:
|
case MRES_HANDLED:
|
||||||
m_FakeEngineBuffer = GetMessagePrototype(msg_id)->New();
|
m_FakeEngineBuffer = g_Cstrike15UsermessageHelpers.GetPrototype(msg_id)->New();
|
||||||
buffer = m_FakeEngineBuffer;
|
buffer = m_FakeEngineBuffer;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MRES_OVERRIDE:
|
case MRES_OVERRIDE:
|
||||||
m_FakeEngineBuffer = GetMessagePrototype(msg_id)->New();
|
m_FakeEngineBuffer = g_Cstrike15UsermessageHelpers.GetPrototype(msg_id)->New();
|
||||||
// fallthrough
|
// fallthrough
|
||||||
case MRES_SUPERCEDE:
|
case MRES_SUPERCEDE:
|
||||||
buffer = msg;
|
buffer = msg;
|
||||||
@@ -303,7 +300,7 @@ bool UserMessages::EndMessage()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if SOURCE_ENGINE == SE_CSGO || SOURCE_ENGINE == SE_DOTA
|
#if SOURCE_ENGINE == SE_CSGO
|
||||||
if (m_CurFlags & USERMSG_BLOCKHOOKS)
|
if (m_CurFlags & USERMSG_BLOCKHOOKS)
|
||||||
{
|
{
|
||||||
ENGINE_CALL(SendUserMessage)(static_cast<IRecipientFilter &>(m_CellRecFilter), m_CurId, *m_FakeEngineBuffer);
|
ENGINE_CALL(SendUserMessage)(static_cast<IRecipientFilter &>(m_CellRecFilter), m_CurId, *m_FakeEngineBuffer);
|
||||||
@@ -333,7 +330,7 @@ bool UserMessages::EndMessage()
|
|||||||
} else {
|
} else {
|
||||||
engine->MessageEnd();
|
engine->MessageEnd();
|
||||||
}
|
}
|
||||||
#endif // SE_CSGO || SE_DOTA
|
#endif // SE_CSGO
|
||||||
|
|
||||||
m_InExec = false;
|
m_InExec = false;
|
||||||
m_CurFlags = 0;
|
m_CurFlags = 0;
|
||||||
@@ -418,14 +415,14 @@ bool UserMessages::InternalHook(int msg_id, IBitBufUserMessageListener *pListene
|
|||||||
|
|
||||||
if (!m_HookCount++)
|
if (!m_HookCount++)
|
||||||
{
|
{
|
||||||
#if SOURCE_ENGINE == SE_CSGO || SOURCE_ENGINE == SE_DOTA
|
#if SOURCE_ENGINE == SE_CSGO
|
||||||
SH_ADD_HOOK(IVEngineServer, SendUserMessage, engine, SH_MEMBER(this, &UserMessages::OnSendUserMessage_Pre), false);
|
SH_ADD_HOOK_MEMFUNC(IVEngineServer, SendUserMessage, engine, this, &UserMessages::OnSendUserMessage_Pre, false);
|
||||||
SH_ADD_HOOK(IVEngineServer, SendUserMessage, engine, SH_MEMBER(this, &UserMessages::OnSendUserMessage_Post), true);
|
SH_ADD_HOOK_MEMFUNC(IVEngineServer, SendUserMessage, engine, this, &UserMessages::OnSendUserMessage_Post, true);
|
||||||
#else
|
#else
|
||||||
SH_ADD_HOOK(IVEngineServer, UserMessageBegin, engine, SH_MEMBER(this, &UserMessages::OnStartMessage_Pre), false);
|
SH_ADD_HOOK_MEMFUNC(IVEngineServer, UserMessageBegin, engine, this, &UserMessages::OnStartMessage_Pre, false);
|
||||||
SH_ADD_HOOK(IVEngineServer, UserMessageBegin, engine, SH_MEMBER(this, &UserMessages::OnStartMessage_Post), true);
|
SH_ADD_HOOK_MEMFUNC(IVEngineServer, UserMessageBegin, engine, this, &UserMessages::OnStartMessage_Post, true);
|
||||||
SH_ADD_HOOK(IVEngineServer, MessageEnd, engine, SH_MEMBER(this, &UserMessages::OnMessageEnd_Pre), false);
|
SH_ADD_HOOK_MEMFUNC(IVEngineServer, MessageEnd, engine, this, &UserMessages::OnMessageEnd_Pre, false);
|
||||||
SH_ADD_HOOK(IVEngineServer, MessageEnd, engine, SH_MEMBER(this, &UserMessages::OnMessageEnd_Post), true);
|
SH_ADD_HOOK_MEMFUNC(IVEngineServer, MessageEnd, engine, this, &UserMessages::OnMessageEnd_Post, true);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -439,17 +436,6 @@ bool UserMessages::InternalHook(int msg_id, IBitBufUserMessageListener *pListene
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_PROTOBUF_USERMESSAGES
|
|
||||||
const protobuf::Message *UserMessages::GetMessagePrototype(int msg_type)
|
|
||||||
{
|
|
||||||
#if SOURCE_ENGINE == SE_DOTA
|
|
||||||
return g_DotaUsermessageHelpers.GetPrototype(msg_type);
|
|
||||||
#elif SOURCE_ENGINE == SE_CSGO
|
|
||||||
return g_Cstrike15UsermessageHelpers.GetPrototype(msg_type);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_PROTOBUF_USERMESSAGES
|
#ifdef USE_PROTOBUF_USERMESSAGES
|
||||||
bool UserMessages::InternalUnhook(int msg_id, IProtobufUserMessageListener *pListener, bool intercept, bool isNew)
|
bool UserMessages::InternalUnhook(int msg_id, IProtobufUserMessageListener *pListener, bool intercept, bool isNew)
|
||||||
#else
|
#else
|
||||||
@@ -495,26 +481,22 @@ void UserMessages::_DecRefCounter()
|
|||||||
{
|
{
|
||||||
if (--m_HookCount == 0)
|
if (--m_HookCount == 0)
|
||||||
{
|
{
|
||||||
#if SOURCE_ENGINE == SE_CSGO || SOURCE_ENGINE == SE_DOTA
|
#if SOURCE_ENGINE == SE_CSGO
|
||||||
SH_REMOVE_HOOK(IVEngineServer, SendUserMessage, engine, SH_MEMBER(this, &UserMessages::OnSendUserMessage_Pre), false);
|
SH_REMOVE_HOOK_MEMFUNC(IVEngineServer, SendUserMessage, engine, this, &UserMessages::OnSendUserMessage_Pre, false);
|
||||||
SH_REMOVE_HOOK(IVEngineServer, SendUserMessage, engine, SH_MEMBER(this, &UserMessages::OnSendUserMessage_Post), true);
|
SH_REMOVE_HOOK_MEMFUNC(IVEngineServer, SendUserMessage, engine, this, &UserMessages::OnSendUserMessage_Post, true);
|
||||||
#else
|
#else
|
||||||
SH_REMOVE_HOOK(IVEngineServer, UserMessageBegin, engine, SH_MEMBER(this, &UserMessages::OnStartMessage_Pre), false);
|
SH_REMOVE_HOOK_MEMFUNC(IVEngineServer, UserMessageBegin, engine, this, &UserMessages::OnStartMessage_Pre, false);
|
||||||
SH_REMOVE_HOOK(IVEngineServer, UserMessageBegin, engine, SH_MEMBER(this, &UserMessages::OnStartMessage_Post), true);
|
SH_REMOVE_HOOK_MEMFUNC(IVEngineServer, UserMessageBegin, engine, this, &UserMessages::OnStartMessage_Post, true);
|
||||||
SH_REMOVE_HOOK(IVEngineServer, MessageEnd, engine, SH_MEMBER(this, &UserMessages::OnMessageEnd_Pre), false);
|
SH_REMOVE_HOOK_MEMFUNC(IVEngineServer, MessageEnd, engine, this, &UserMessages::OnMessageEnd_Pre, false);
|
||||||
SH_REMOVE_HOOK(IVEngineServer, MessageEnd, engine, SH_MEMBER(this, &UserMessages::OnMessageEnd_Post), true);
|
SH_REMOVE_HOOK_MEMFUNC(IVEngineServer, MessageEnd, engine, this, &UserMessages::OnMessageEnd_Post, true);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if SOURCE_ENGINE == SE_CSGO || SOURCE_ENGINE == SE_DOTA
|
#if SOURCE_ENGINE == SE_CSGO
|
||||||
void UserMessages::OnSendUserMessage_Pre(IRecipientFilter &filter, int msg_type, const protobuf::Message &msg)
|
void UserMessages::OnSendUserMessage_Pre(IRecipientFilter &filter, int msg_type, const protobuf::Message &msg)
|
||||||
{
|
{
|
||||||
#if SOURCE_ENGINE == SE_DOTA
|
|
||||||
OnStartMessage_Pre(&filter, msg_type, g_DotaUsermessageHelpers.GetName(msg_type));
|
|
||||||
#elif SOURCE_ENGINE == SE_CSGO
|
|
||||||
OnStartMessage_Pre(&filter, msg_type, g_Cstrike15UsermessageHelpers.GetName(msg_type));
|
OnStartMessage_Pre(&filter, msg_type, g_Cstrike15UsermessageHelpers.GetName(msg_type));
|
||||||
#endif
|
|
||||||
if (m_FakeMetaRes == MRES_SUPERCEDE)
|
if (m_FakeMetaRes == MRES_SUPERCEDE)
|
||||||
{
|
{
|
||||||
int size = msg.ByteSize();
|
int size = msg.ByteSize();
|
||||||
@@ -527,11 +509,7 @@ void UserMessages::OnSendUserMessage_Pre(IRecipientFilter &filter, int msg_type,
|
|||||||
m_FakeEngineBuffer = &const_cast<protobuf::Message &>(msg);
|
m_FakeEngineBuffer = &const_cast<protobuf::Message &>(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if SOURCE_ENGINE == SE_DOTA
|
|
||||||
OnStartMessage_Post(&filter, msg_type, g_DotaUsermessageHelpers.GetName(msg_type));
|
|
||||||
#elif SOURCE_ENGINE == SE_CSGO
|
|
||||||
OnStartMessage_Post(&filter, msg_type, g_Cstrike15UsermessageHelpers.GetName(msg_type));
|
OnStartMessage_Post(&filter, msg_type, g_Cstrike15UsermessageHelpers.GetName(msg_type));
|
||||||
#endif
|
|
||||||
|
|
||||||
OnMessageEnd_Pre();
|
OnMessageEnd_Pre();
|
||||||
if (m_FakeMetaRes == MRES_SUPERCEDE)
|
if (m_FakeMetaRes == MRES_SUPERCEDE)
|
||||||
@@ -563,7 +541,7 @@ void UserMessages::OnSendUserMessage_Post(IRecipientFilter &filter, int msg_type
|
|||||||
RETURN_META(res)
|
RETURN_META(res)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if SOURCE_ENGINE == SE_CSGO || SOURCE_ENGINE == SE_DOTA
|
#if SOURCE_ENGINE == SE_CSGO
|
||||||
protobuf::Message *UserMessages::OnStartMessage_Pre(IRecipientFilter *filter, int msg_type, const char *msg_name)
|
protobuf::Message *UserMessages::OnStartMessage_Pre(IRecipientFilter *filter, int msg_type, const char *msg_name)
|
||||||
#elif SOURCE_ENGINE >= SE_LEFT4DEAD
|
#elif SOURCE_ENGINE >= SE_LEFT4DEAD
|
||||||
bf_write *UserMessages::OnStartMessage_Pre(IRecipientFilter *filter, int msg_type, const char *msg_name)
|
bf_write *UserMessages::OnStartMessage_Pre(IRecipientFilter *filter, int msg_type, const char *msg_name)
|
||||||
@@ -591,8 +569,7 @@ bf_write *UserMessages::OnStartMessage_Pre(IRecipientFilter *filter, int msg_typ
|
|||||||
#ifdef USE_PROTOBUF_USERMESSAGES
|
#ifdef USE_PROTOBUF_USERMESSAGES
|
||||||
if (m_InterceptBuffer)
|
if (m_InterceptBuffer)
|
||||||
delete m_InterceptBuffer;
|
delete m_InterceptBuffer;
|
||||||
m_InterceptBuffer = GetMessagePrototype(msg_type)->New();
|
m_InterceptBuffer = g_Cstrike15UsermessageHelpers.GetPrototype(msg_type)->New();
|
||||||
|
|
||||||
UM_RETURN_META_VALUE(MRES_SUPERCEDE, m_InterceptBuffer);
|
UM_RETURN_META_VALUE(MRES_SUPERCEDE, m_InterceptBuffer);
|
||||||
#else
|
#else
|
||||||
m_InterceptBuffer.Reset();
|
m_InterceptBuffer.Reset();
|
||||||
@@ -603,7 +580,7 @@ bf_write *UserMessages::OnStartMessage_Pre(IRecipientFilter *filter, int msg_typ
|
|||||||
UM_RETURN_META_VALUE(MRES_IGNORED, NULL);
|
UM_RETURN_META_VALUE(MRES_IGNORED, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if SOURCE_ENGINE == SE_CSGO || SOURCE_ENGINE == SE_DOTA
|
#if SOURCE_ENGINE == SE_CSGO
|
||||||
protobuf::Message *UserMessages::OnStartMessage_Post(IRecipientFilter *filter, int msg_type, const char *msg_name)
|
protobuf::Message *UserMessages::OnStartMessage_Post(IRecipientFilter *filter, int msg_type, const char *msg_name)
|
||||||
#elif SOURCE_ENGINE >= SE_LEFT4DEAD
|
#elif SOURCE_ENGINE >= SE_LEFT4DEAD
|
||||||
bf_write *UserMessages::OnStartMessage_Post(IRecipientFilter *filter, int msg_type, const char *msg_name)
|
bf_write *UserMessages::OnStartMessage_Post(IRecipientFilter *filter, int msg_type, const char *msg_name)
|
||||||
@@ -768,7 +745,7 @@ void UserMessages::OnMessageEnd_Pre()
|
|||||||
|
|
||||||
if (!handled && intercepted)
|
if (!handled && intercepted)
|
||||||
{
|
{
|
||||||
#if SOURCE_ENGINE == SE_CSGO || SOURCE_ENGINE == SE_DOTA
|
#if SOURCE_ENGINE == SE_CSGO
|
||||||
ENGINE_CALL(SendUserMessage)(static_cast<IRecipientFilter &>(*m_CurRecFilter), m_CurId, *m_InterceptBuffer);
|
ENGINE_CALL(SendUserMessage)(static_cast<IRecipientFilter &>(*m_CurRecFilter), m_CurId, *m_InterceptBuffer);
|
||||||
#else
|
#else
|
||||||
bf_write *engine_bfw;
|
bf_write *engine_bfw;
|
||||||
@@ -780,16 +757,15 @@ void UserMessages::OnMessageEnd_Pre()
|
|||||||
m_ReadBuffer.StartReading(m_InterceptBuffer.GetBasePointer(), m_InterceptBuffer.GetNumBytesWritten());
|
m_ReadBuffer.StartReading(m_InterceptBuffer.GetBasePointer(), m_InterceptBuffer.GetNumBytesWritten());
|
||||||
engine_bfw->WriteBitsFromBuffer(&m_ReadBuffer, m_InterceptBuffer.GetNumBitsWritten());
|
engine_bfw->WriteBitsFromBuffer(&m_ReadBuffer, m_InterceptBuffer.GetNumBitsWritten());
|
||||||
ENGINE_CALL(MessageEnd)();
|
ENGINE_CALL(MessageEnd)();
|
||||||
#endif // SE_CSGO || SE_DOTA
|
#endif // SE_CSGO
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
#if SOURCE_ENGINE == SE_CSGO || SOURCE_ENGINE == SE_DOTA
|
#if SOURCE_ENGINE == SE_CSGO
|
||||||
int size = m_OrigBuffer->ByteSize();
|
int size = m_OrigBuffer->ByteSize();
|
||||||
uint8 *data = (uint8 *)stackalloc(size);
|
uint8 *data = (uint8 *)stackalloc(size);
|
||||||
m_OrigBuffer->SerializePartialToArray(data, size);
|
m_OrigBuffer->SerializePartialToArray(data, size);
|
||||||
|
protobuf::Message *pTempMsg = g_Cstrike15UsermessageHelpers.GetPrototype(m_CurId)->New();
|
||||||
protobuf::Message *pTempMsg = GetMessagePrototype(m_CurId)->New();
|
|
||||||
pTempMsg->ParsePartialFromArray(data, size);
|
pTempMsg->ParsePartialFromArray(data, size);
|
||||||
#else
|
#else
|
||||||
bf_write *pTempMsg = m_OrigBuffer;
|
bf_write *pTempMsg = m_OrigBuffer;
|
||||||
@@ -814,7 +790,7 @@ void UserMessages::OnMessageEnd_Pre()
|
|||||||
iter++;
|
iter++;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if SOURCE_ENGINE == SE_CSGO || SOURCE_ENGINE == SE_DOTA
|
#if SOURCE_ENGINE == SE_CSGO
|
||||||
delete pTempMsg;
|
delete pTempMsg;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-10
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* vim: set ts=4 sw=4 tw=99 noet :
|
* vim: set ts=4 :
|
||||||
* =============================================================================
|
* =============================================================================
|
||||||
* SourceMod
|
* SourceMod
|
||||||
* Copyright (C) 2004-2010 AlliedModders LLC. All rights reserved.
|
* Copyright (C) 2004-2010 AlliedModders LLC. All rights reserved.
|
||||||
@@ -32,19 +32,17 @@
|
|||||||
#ifndef _INCLUDE_SOURCEMOD_CUSERMESSAGES_H_
|
#ifndef _INCLUDE_SOURCEMOD_CUSERMESSAGES_H_
|
||||||
#define _INCLUDE_SOURCEMOD_CUSERMESSAGES_H_
|
#define _INCLUDE_SOURCEMOD_CUSERMESSAGES_H_
|
||||||
|
|
||||||
|
#include "ShareSys.h"
|
||||||
#include <IUserMessages.h>
|
#include <IUserMessages.h>
|
||||||
#include "sourcemm_api.h"
|
#include "sourcemm_api.h"
|
||||||
#include <sm_stringhashmap.h>
|
#include "sm_trie.h"
|
||||||
#include "sm_stringutil.h"
|
#include "sm_stringutil.h"
|
||||||
#include "CellRecipientFilter.h"
|
#include "CellRecipientFilter.h"
|
||||||
#include "sm_globals.h"
|
|
||||||
#include <sh_list.h>
|
|
||||||
#include <sh_stack.h>
|
|
||||||
|
|
||||||
using namespace SourceHook;
|
using namespace SourceHook;
|
||||||
using namespace SourceMod;
|
using namespace SourceMod;
|
||||||
|
|
||||||
#if SOURCE_ENGINE == SE_CSGO || SOURCE_ENGINE == SE_DOTA
|
#if SOURCE_ENGINE == SE_CSGO
|
||||||
#define USE_PROTOBUF_USERMESSAGES
|
#define USE_PROTOBUF_USERMESSAGES
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -102,12 +100,12 @@ public: //IUserMessages
|
|||||||
bool intercept=false);
|
bool intercept=false);
|
||||||
UserMessageType GetUserMessageType() const;
|
UserMessageType GetUserMessageType() const;
|
||||||
public:
|
public:
|
||||||
#if SOURCE_ENGINE == SE_CSGO || SOURCE_ENGINE == SE_DOTA
|
#if SOURCE_ENGINE == SE_CSGO
|
||||||
void OnSendUserMessage_Pre(IRecipientFilter &filter, int msg_type, const protobuf::Message &msg);
|
void OnSendUserMessage_Pre(IRecipientFilter &filter, int msg_type, const protobuf::Message &msg);
|
||||||
void OnSendUserMessage_Post(IRecipientFilter &filter, int msg_type, const protobuf::Message &msg);
|
void OnSendUserMessage_Post(IRecipientFilter &filter, int msg_type, const protobuf::Message &msg);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if SOURCE_ENGINE == SE_CSGO || SOURCE_ENGINE == SE_DOTA
|
#if SOURCE_ENGINE == SE_CSGO
|
||||||
protobuf::Message *OnStartMessage_Pre(IRecipientFilter *filter, int msg_type, const char *msg_name);
|
protobuf::Message *OnStartMessage_Pre(IRecipientFilter *filter, int msg_type, const char *msg_name);
|
||||||
protobuf::Message *OnStartMessage_Post(IRecipientFilter *filter, int msg_type, const char *msg_name);
|
protobuf::Message *OnStartMessage_Post(IRecipientFilter *filter, int msg_type, const char *msg_name);
|
||||||
#elif SOURCE_ENGINE >= SE_LEFT4DEAD
|
#elif SOURCE_ENGINE >= SE_LEFT4DEAD
|
||||||
@@ -121,7 +119,6 @@ public:
|
|||||||
void OnMessageEnd_Post();
|
void OnMessageEnd_Post();
|
||||||
private:
|
private:
|
||||||
#ifdef USE_PROTOBUF_USERMESSAGES
|
#ifdef USE_PROTOBUF_USERMESSAGES
|
||||||
const protobuf::Message *GetMessagePrototype(int msg_type);
|
|
||||||
bool InternalHook(int msg_id, IProtobufUserMessageListener *pListener, bool intercept, bool isNew);
|
bool InternalHook(int msg_id, IProtobufUserMessageListener *pListener, bool intercept, bool isNew);
|
||||||
bool InternalUnhook(int msg_id, IProtobufUserMessageListener *pListener, bool intercept, bool isNew);
|
bool InternalUnhook(int msg_id, IProtobufUserMessageListener *pListener, bool intercept, bool isNew);
|
||||||
#else
|
#else
|
||||||
@@ -153,7 +150,7 @@ private:
|
|||||||
#ifndef USE_PROTOBUF_USERMESSAGES
|
#ifndef USE_PROTOBUF_USERMESSAGES
|
||||||
bool m_FallbackSearch;
|
bool m_FallbackSearch;
|
||||||
|
|
||||||
StringHashMap<int> m_Names;
|
Trie *m_Names;
|
||||||
#endif
|
#endif
|
||||||
CellRecipientFilter m_CellRecFilter;
|
CellRecipientFilter m_CellRecFilter;
|
||||||
bool m_InExec;
|
bool m_InExec;
|
||||||
|
|||||||
@@ -64,20 +64,20 @@ public:
|
|||||||
void OnSourceModAllInitialized()
|
void OnSourceModAllInitialized()
|
||||||
{
|
{
|
||||||
#if SOURCE_ENGINE >= SE_ORANGEBOX
|
#if SOURCE_ENGINE >= SE_ORANGEBOX
|
||||||
SH_ADD_HOOK(ICvar, UnregisterConCommand, icvar, SH_MEMBER(this, &ConCommandCleaner::UnlinkConCommandBase), false);
|
SH_ADD_HOOK_MEMFUNC(ICvar, UnregisterConCommand, icvar, this, &ConCommandCleaner::UnlinkConCommandBase, false);
|
||||||
SH_ADD_HOOK(ICvar, RegisterConCommand, icvar, SH_MEMBER(this, &ConCommandCleaner::LinkConCommandBase), false);
|
SH_ADD_HOOK_MEMFUNC(ICvar, RegisterConCommand, icvar, this, &ConCommandCleaner::LinkConCommandBase, false);
|
||||||
#else
|
#else
|
||||||
SH_ADD_HOOK(ICvar, RegisterConCommandBase, icvar, SH_MEMBER(this, &ConCommandCleaner::LinkConCommandBase), false);
|
SH_ADD_HOOK_MEMFUNC(ICvar, RegisterConCommandBase, icvar, this, &ConCommandCleaner::LinkConCommandBase, false);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnSourceModShutdown()
|
void OnSourceModShutdown()
|
||||||
{
|
{
|
||||||
#if SOURCE_ENGINE >= SE_ORANGEBOX
|
#if SOURCE_ENGINE >= SE_ORANGEBOX
|
||||||
SH_REMOVE_HOOK(ICvar, UnregisterConCommand, icvar, SH_MEMBER(this, &ConCommandCleaner::UnlinkConCommandBase), false);
|
SH_REMOVE_HOOK_MEMFUNC(ICvar, UnregisterConCommand, icvar, this, &ConCommandCleaner::UnlinkConCommandBase, false);
|
||||||
SH_REMOVE_HOOK(ICvar, RegisterConCommand, icvar, SH_MEMBER(this, &ConCommandCleaner::LinkConCommandBase), false);
|
SH_REMOVE_HOOK_MEMFUNC(ICvar, RegisterConCommand, icvar, this, &ConCommandCleaner::LinkConCommandBase, false);
|
||||||
#else
|
#else
|
||||||
SH_REMOVE_HOOK(ICvar, RegisterConCommandBase, icvar, SH_MEMBER(this, &ConCommandCleaner::LinkConCommandBase), false);
|
SH_REMOVE_HOOK_MEMFUNC(ICvar, RegisterConCommandBase, icvar, this, &ConCommandCleaner::LinkConCommandBase, false);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -381,7 +381,7 @@ public:
|
|||||||
FnChangeCallback_t GetChangeCallback( int slot ) const { return m_pParent->m_fnChangeCallbacks[ slot ]; }
|
FnChangeCallback_t GetChangeCallback( int slot ) const { return m_pParent->m_fnChangeCallbacks[ slot ]; }
|
||||||
|
|
||||||
// Retrieve value
|
// Retrieve value
|
||||||
#if SOURCE_ENGINE >= SE_INSURGENCY
|
#if SOURCE_ENGINE == SE_CSGO
|
||||||
virtual float GetFloat( void ) const;
|
virtual float GetFloat( void ) const;
|
||||||
virtual int GetInt( void ) const;
|
virtual int GetInt( void ) const;
|
||||||
#else
|
#else
|
||||||
|
|||||||
@@ -30,6 +30,7 @@
|
|||||||
*/
|
*/
|
||||||
#include "frame_hooks.h"
|
#include "frame_hooks.h"
|
||||||
#include "TimerSys.h"
|
#include "TimerSys.h"
|
||||||
|
#include "Database.h"
|
||||||
#include "HalfLife2.h"
|
#include "HalfLife2.h"
|
||||||
#include "MenuStyle_Valve.h"
|
#include "MenuStyle_Valve.h"
|
||||||
#include "MenuStyle_Radio.h"
|
#include "MenuStyle_Radio.h"
|
||||||
@@ -37,7 +38,6 @@
|
|||||||
#include "CoreConfig.h"
|
#include "CoreConfig.h"
|
||||||
#include <sm_queue.h>
|
#include <sm_queue.h>
|
||||||
#include <IThreader.h>
|
#include <IThreader.h>
|
||||||
#include "sourcemod.h"
|
|
||||||
|
|
||||||
static IMutex *frame_mutex;
|
static IMutex *frame_mutex;
|
||||||
static Queue<FrameAction> *frame_queue;
|
static Queue<FrameAction> *frame_queue;
|
||||||
@@ -95,6 +95,7 @@ void RunFrameHooks(bool simulating)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Frame based hooks */
|
/* Frame based hooks */
|
||||||
|
g_DBMan.RunFrame();
|
||||||
g_HL2.ProcessFakeCliCmdQueue();
|
g_HL2.ProcessFakeCliCmdQueue();
|
||||||
g_HL2.ProcessDelayedKicks();
|
g_HL2.ProcessDelayedKicks();
|
||||||
|
|
||||||
|
|||||||
+55
-75
@@ -1,81 +1,61 @@
|
|||||||
# vim: set sts=2 ts=8 sw=2 tw=99 et ft=python:
|
# vim: set ts=2 sw=2 tw=99 noet ft=python:
|
||||||
import os
|
import os
|
||||||
|
|
||||||
binary = SM.Library(builder, 'sourcemod.logic')
|
compiler = SM.DefaultCompiler()
|
||||||
binary.compiler.cxxincludes += [
|
base = AMBuild.sourceFolder
|
||||||
os.path.join(builder.sourcePath, 'core', 'logic'),
|
compiler['CXXINCLUDES'].append(os.path.join(SM.mmsPath, 'core', 'sourcehook'))
|
||||||
os.path.join(builder.sourcePath, 'public'),
|
compiler['CXXINCLUDES'].append(os.path.join(base, 'core', 'logic'))
|
||||||
os.path.join(builder.sourcePath, 'public', 'sourcepawn'),
|
compiler['CXXINCLUDES'].append(os.path.join(base, 'public'))
|
||||||
os.path.join(builder.sourcePath, 'public', 'amtl'),
|
compiler['CXXINCLUDES'].append(os.path.join(base, 'public', 'sourcepawn'))
|
||||||
os.path.join(SM.mms_root, 'core', 'sourcehook')
|
compiler['CDEFINES'].append('SM_DEFAULT_THREADER')
|
||||||
]
|
compiler['CDEFINES'].append('SM_LOGIC')
|
||||||
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 binary.compiler.vendor == 'gcc' or binary.compiler.vendor == 'clang':
|
if AMBuild.target['platform'] == 'linux':
|
||||||
binary.compiler.cxxflags += ['-fno-rtti']
|
compiler['POSTLINKFLAGS'].append('-lpthread')
|
||||||
elif binary.compiler.vendor == 'msvc':
|
if AMBuild.target['platform'] == 'darwin':
|
||||||
binary.compiler.cxxflags += ['/GR-']
|
compiler['CFLAGS'].extend(['-Wno-deprecated-declarations'])
|
||||||
|
compiler['POSTLINKFLAGS'].extend(['-framework', 'CoreServices'])
|
||||||
|
|
||||||
binary.sources += [
|
extension = AMBuild.AddJob('sourcemod.logic')
|
||||||
'common_logic.cpp',
|
binary = Cpp.LibraryBuilder('sourcemod.logic', AMBuild, extension, compiler)
|
||||||
'smn_adt_array.cpp',
|
files = [
|
||||||
'smn_sorting.cpp',
|
'common_logic.cpp',
|
||||||
'smn_maplists.cpp',
|
'smn_adt_array.cpp',
|
||||||
'ADTFactory.cpp',
|
'smn_sorting.cpp',
|
||||||
'smn_adt_stack.cpp',
|
'smn_maplists.cpp',
|
||||||
'thread/ThreadWorker.cpp',
|
'smn_adt_stack.cpp',
|
||||||
'thread/BaseWorker.cpp',
|
'thread/ThreadWorker.cpp',
|
||||||
'ThreadSupport.cpp',
|
'thread/BaseWorker.cpp',
|
||||||
'smn_float.cpp',
|
'ThreadSupport.cpp',
|
||||||
'TextParsers.cpp',
|
'smn_float.cpp',
|
||||||
'smn_textparse.cpp',
|
'TextParsers.cpp',
|
||||||
'smn_adt_trie.cpp',
|
'smn_textparse.cpp',
|
||||||
'Profiler.cpp',
|
'smn_adt_trie.cpp',
|
||||||
'smn_functions.cpp',
|
'Profiler.cpp',
|
||||||
'smn_timers.cpp',
|
'smn_functions.cpp',
|
||||||
'smn_players.cpp',
|
'smn_timers.cpp',
|
||||||
'MemoryUtils.cpp',
|
'smn_players.cpp',
|
||||||
'smn_admin.cpp',
|
'MemoryUtils.cpp',
|
||||||
'smn_banning.cpp',
|
'smn_admin.cpp',
|
||||||
'smn_filesystem.cpp',
|
'smn_banning.cpp',
|
||||||
'stringutil.cpp',
|
'stringutil.cpp',
|
||||||
'Translator.cpp',
|
'Translator.cpp',
|
||||||
'PhraseCollection.cpp',
|
'PhraseCollection.cpp',
|
||||||
'smn_lang.cpp',
|
'smn_lang.cpp',
|
||||||
'smn_string.cpp',
|
'smn_string.cpp',
|
||||||
'smn_handles.cpp',
|
'smn_handles.cpp',
|
||||||
'smn_datapacks.cpp',
|
'smn_datapacks.cpp',
|
||||||
'smn_gameconfigs.cpp',
|
'smn_gameconfigs.cpp',
|
||||||
'smn_fakenatives.cpp',
|
'GameConfigs.cpp',
|
||||||
'GameConfigs.cpp',
|
'sm_crc32.cpp',
|
||||||
'sm_crc32.cpp',
|
'smn_profiler.cpp'
|
||||||
'smn_profiler.cpp',
|
]
|
||||||
'ShareSys.cpp',
|
if AMBuild.target['platform'] == 'windows':
|
||||||
'PluginSys.cpp',
|
files.append('thread/WinThreads.cpp')
|
||||||
'HandleSys.cpp',
|
|
||||||
'NativeOwner.cpp',
|
|
||||||
'NativeInvoker.cpp',
|
|
||||||
'ExtensionSys.cpp',
|
|
||||||
'DebugReporter.cpp',
|
|
||||||
'Database.cpp',
|
|
||||||
'smn_database.cpp',
|
|
||||||
'ForwardSys.cpp',
|
|
||||||
'AdminCache.cpp',
|
|
||||||
'sm_trie.cpp',
|
|
||||||
'smn_console.cpp',
|
|
||||||
]
|
|
||||||
if builder.target_platform == 'windows':
|
|
||||||
binary.sources += ['thread/WinThreads.cpp']
|
|
||||||
else:
|
else:
|
||||||
binary.sources += ['thread/PosixThreads.cpp']
|
files.append('thread/PosixThreads.cpp')
|
||||||
|
binary.AddSourceFiles('core/logic', files)
|
||||||
|
SM.AutoVersion('core/logic', binary)
|
||||||
|
SM.ExtractDebugInfo(extension, binary)
|
||||||
|
binary.SendToJob()
|
||||||
|
|
||||||
SM.binaries += [builder.Add(binary)]
|
|
||||||
|
|||||||
@@ -32,6 +32,7 @@
|
|||||||
#ifndef _INCLUDE_SOURCEMOD_AUTO_HANDLE_ROOTER_H_
|
#ifndef _INCLUDE_SOURCEMOD_AUTO_HANDLE_ROOTER_H_
|
||||||
#define _INCLUDE_SOURCEMOD_AUTO_HANDLE_ROOTER_H_
|
#define _INCLUDE_SOURCEMOD_AUTO_HANDLE_ROOTER_H_
|
||||||
|
|
||||||
|
#include "common_logic.h"
|
||||||
#include <IHandleSys.h>
|
#include <IHandleSys.h>
|
||||||
|
|
||||||
class AutoHandleRooter
|
class AutoHandleRooter
|
||||||
+111
-104
@@ -77,12 +77,10 @@ static const char *g_pParseEngine = NULL;
|
|||||||
#define PLATFORM_SERVER_BINARY "server.dll"
|
#define PLATFORM_SERVER_BINARY "server.dll"
|
||||||
#elif defined PLATFORM_LINUX
|
#elif defined PLATFORM_LINUX
|
||||||
#define PLATFORM_NAME "linux"
|
#define PLATFORM_NAME "linux"
|
||||||
#define PLATFORM_COMPAT_ALT "mac" /* Alternate platform name if game data is missing for primary one */
|
|
||||||
#define PLATFORM_SERVER_BINARY "server_i486.so"
|
#define PLATFORM_SERVER_BINARY "server_i486.so"
|
||||||
#elif defined PLATFORM_APPLE
|
#elif defined PLATFORM_APPLE
|
||||||
#define PLATFORM_NAME "mac"
|
#define PLATFORM_NAME "mac"
|
||||||
#define PLATFORM_COMPAT_ALT "linux"
|
#define PLATFORM_SERVER_BINARY "server.dylib"
|
||||||
#define PLATFORM_SERVER_BINARY "server.dylib"
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct TempSigInfo
|
struct TempSigInfo
|
||||||
@@ -92,7 +90,7 @@ struct TempSigInfo
|
|||||||
library[0] = '\0';
|
library[0] = '\0';
|
||||||
sig[0] = '\0';
|
sig[0] = '\0';
|
||||||
}
|
}
|
||||||
char sig[1024];
|
char sig[512];
|
||||||
char library[64];
|
char library[64];
|
||||||
} s_TempSig;
|
} s_TempSig;
|
||||||
unsigned int s_ServerBinCRC;
|
unsigned int s_ServerBinCRC;
|
||||||
@@ -118,33 +116,12 @@ static bool DoesEngineMatch(const char *value)
|
|||||||
return strcmp(value, g_pParseEngine) == 0;
|
return strcmp(value, g_pParseEngine) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool DoesPlatformMatch(const char *platform)
|
|
||||||
{
|
|
||||||
return strcmp(platform, PLATFORM_NAME) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool IsPlatformCompatible(const char *platform, bool *hadPrimaryMatch)
|
|
||||||
{
|
|
||||||
if (DoesPlatformMatch(platform))
|
|
||||||
{
|
|
||||||
#if defined PLATFORM_COMPAT_ALT
|
|
||||||
*hadPrimaryMatch = true;
|
|
||||||
#endif
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined PLATFORM_COMPAT_ALT
|
|
||||||
/* If entry hasn't been found for the primary platform name, check for compatible alternate */
|
|
||||||
if (!*hadPrimaryMatch)
|
|
||||||
return strcmp(platform, PLATFORM_COMPAT_ALT) == 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
CGameConfig::CGameConfig(const char *file, const char *engine)
|
CGameConfig::CGameConfig(const char *file, const char *engine)
|
||||||
{
|
{
|
||||||
strncopy(m_File, file, sizeof(m_File));
|
strncopy(m_File, file, sizeof(m_File));
|
||||||
|
m_pAddresses = new KTrie<AddressConf>();
|
||||||
|
m_pStrings = new BaseStringTable(512);
|
||||||
|
m_RefCount = 0;
|
||||||
|
|
||||||
m_CustomLevel = 0;
|
m_CustomLevel = 0;
|
||||||
m_CustomHandler = NULL;
|
m_CustomHandler = NULL;
|
||||||
@@ -164,7 +141,8 @@ CGameConfig::CGameConfig(const char *file, const char *engine)
|
|||||||
|
|
||||||
CGameConfig::~CGameConfig()
|
CGameConfig::~CGameConfig()
|
||||||
{
|
{
|
||||||
g_GameConfigs.RemoveCachedConfig(this);
|
delete m_pAddresses;
|
||||||
|
delete m_pStrings;
|
||||||
}
|
}
|
||||||
|
|
||||||
SMCResult CGameConfig::ReadSMC_NewSection(const SMCStates *states, const char *name)
|
SMCResult CGameConfig::ReadSMC_NewSection(const SMCStates *states, const char *name)
|
||||||
@@ -236,10 +214,13 @@ SMCResult CGameConfig::ReadSMC_NewSection(const SMCStates *states, const char *n
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (g_GameConfigs.m_customHandlers.retrieve(name, &m_CustomHandler))
|
ITextListener_SMC **pListen = g_GameConfigs.m_customHandlers.retrieve(name);
|
||||||
|
|
||||||
|
if (pListen != NULL)
|
||||||
{
|
{
|
||||||
m_CustomLevel = 0;
|
m_CustomLevel = 0;
|
||||||
m_ParseState = PSTATE_GAMEDEFS_CUSTOM;
|
m_ParseState = PSTATE_GAMEDEFS_CUSTOM;
|
||||||
|
m_CustomHandler = *pListen;
|
||||||
m_CustomHandler->ReadSMC_ParseStart();
|
m_CustomHandler->ReadSMC_ParseStart();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -254,7 +235,6 @@ SMCResult CGameConfig::ReadSMC_NewSection(const SMCStates *states, const char *n
|
|||||||
m_Class[0] = '\0';
|
m_Class[0] = '\0';
|
||||||
strncopy(m_offset, name, sizeof(m_offset));
|
strncopy(m_offset, name, sizeof(m_offset));
|
||||||
m_ParseState = PSTATE_GAMEDEFS_OFFSETS_OFFSET;
|
m_ParseState = PSTATE_GAMEDEFS_OFFSETS_OFFSET;
|
||||||
matched_platform = false;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PSTATE_GAMEDEFS_SIGNATURES:
|
case PSTATE_GAMEDEFS_SIGNATURES:
|
||||||
@@ -262,7 +242,6 @@ SMCResult CGameConfig::ReadSMC_NewSection(const SMCStates *states, const char *n
|
|||||||
strncopy(m_offset, name, sizeof(m_offset));
|
strncopy(m_offset, name, sizeof(m_offset));
|
||||||
s_TempSig.Reset();
|
s_TempSig.Reset();
|
||||||
m_ParseState = PSTATE_GAMEDEFS_SIGNATURES_SIG;
|
m_ParseState = PSTATE_GAMEDEFS_SIGNATURES_SIG;
|
||||||
matched_platform = false;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PSTATE_GAMEDEFS_CRC:
|
case PSTATE_GAMEDEFS_CRC:
|
||||||
@@ -327,7 +306,7 @@ SMCResult CGameConfig::ReadSMC_NewSection(const SMCStates *states, const char *n
|
|||||||
}
|
}
|
||||||
case PSTATE_GAMEDEFS_ADDRESSES_ADDRESS:
|
case PSTATE_GAMEDEFS_ADDRESSES_ADDRESS:
|
||||||
{
|
{
|
||||||
if (DoesPlatformMatch(name))
|
if (strcmp(name, PLATFORM_NAME) == 0)
|
||||||
{
|
{
|
||||||
m_ParseState = PSTATE_GAMEDEFS_ADDRESSES_ADDRESS_READ;
|
m_ParseState = PSTATE_GAMEDEFS_ADDRESSES_ADDRESS_READ;
|
||||||
}
|
}
|
||||||
@@ -375,12 +354,11 @@ SMCResult CGameConfig::ReadSMC_KeyValue(const SMCStates *states, const char *key
|
|||||||
strncopy(m_Class, value, sizeof(m_Class));
|
strncopy(m_Class, value, sizeof(m_Class));
|
||||||
} else if (strcmp(key, "prop") == 0) {
|
} else if (strcmp(key, "prop") == 0) {
|
||||||
strncopy(m_Prop, value, sizeof(m_Prop));
|
strncopy(m_Prop, value, sizeof(m_Prop));
|
||||||
} else if (IsPlatformCompatible(key, &matched_platform)) {
|
} else if (strcmp(key, PLATFORM_NAME) == 0) {
|
||||||
m_Offsets.replace(m_offset, atoi(value));
|
m_Offsets.replace(m_offset, atoi(value));
|
||||||
}
|
}
|
||||||
} else if (m_ParseState == PSTATE_GAMEDEFS_KEYS) {
|
} else if (m_ParseState == PSTATE_GAMEDEFS_KEYS) {
|
||||||
ke::AString vstr(value);
|
m_Keys.replace(key, m_pStrings->AddString(value));
|
||||||
m_Keys.replace(key, ke::Move(vstr));
|
|
||||||
} else if (m_ParseState == PSTATE_GAMEDEFS_SUPPORTED) {
|
} else if (m_ParseState == PSTATE_GAMEDEFS_SUPPORTED) {
|
||||||
if (strcmp(key, "game") == 0)
|
if (strcmp(key, "game") == 0)
|
||||||
{
|
{
|
||||||
@@ -407,14 +385,14 @@ SMCResult CGameConfig::ReadSMC_KeyValue(const SMCStates *states, const char *key
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (m_ParseState == PSTATE_GAMEDEFS_SIGNATURES_SIG) {
|
} else if (m_ParseState == PSTATE_GAMEDEFS_SIGNATURES_SIG) {
|
||||||
if (IsPlatformCompatible(key, &matched_platform))
|
if (strcmp(key, PLATFORM_NAME) == 0)
|
||||||
{
|
{
|
||||||
strncopy(s_TempSig.sig, value, sizeof(s_TempSig.sig));
|
strncopy(s_TempSig.sig, value, sizeof(s_TempSig.sig));
|
||||||
} else if (strcmp(key, "library") == 0) {
|
} else if (strcmp(key, "library") == 0) {
|
||||||
strncopy(s_TempSig.library, value, sizeof(s_TempSig.library));
|
strncopy(s_TempSig.library, value, sizeof(s_TempSig.library));
|
||||||
}
|
}
|
||||||
} else if (m_ParseState == PSTATE_GAMEDEFS_CRC_BINARY) {
|
} else if (m_ParseState == PSTATE_GAMEDEFS_CRC_BINARY) {
|
||||||
if (DoesPlatformMatch(key)
|
if (strcmp(key, PLATFORM_NAME) == 0
|
||||||
&& s_ServerBinCRC_Ok
|
&& s_ServerBinCRC_Ok
|
||||||
&& !bShouldBeReadingDefault)
|
&& !bShouldBeReadingDefault)
|
||||||
{
|
{
|
||||||
@@ -559,9 +537,7 @@ SMCResult CGameConfig::ReadSMC_LeavingSection(const SMCStates *states)
|
|||||||
smcore.LogError("[SM] Unrecognized library \"%s\" (gameconf \"%s\")",
|
smcore.LogError("[SM] Unrecognized library \"%s\" (gameconf \"%s\")",
|
||||||
s_TempSig.library,
|
s_TempSig.library,
|
||||||
m_CurFile);
|
m_CurFile);
|
||||||
}
|
} else {
|
||||||
else if (s_TempSig.sig[0])
|
|
||||||
{
|
|
||||||
if (s_TempSig.sig[0] == '@')
|
if (s_TempSig.sig[0] == '@')
|
||||||
{
|
{
|
||||||
#if defined PLATFORM_WINDOWS
|
#if defined PLATFORM_WINDOWS
|
||||||
@@ -596,28 +572,28 @@ SMCResult CGameConfig::ReadSMC_LeavingSection(const SMCStates *states)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
if (final_addr)
|
||||||
if (!final_addr)
|
|
||||||
{
|
{
|
||||||
/* First, preprocess the signature */
|
goto skip_find;
|
||||||
unsigned char real_sig[511];
|
|
||||||
size_t real_bytes;
|
|
||||||
size_t length;
|
|
||||||
|
|
||||||
real_bytes = 0;
|
|
||||||
length = strlen(s_TempSig.sig);
|
|
||||||
|
|
||||||
real_bytes = UTIL_DecodeHexString(real_sig, sizeof(real_sig), s_TempSig.sig);
|
|
||||||
|
|
||||||
if (real_bytes >= 1)
|
|
||||||
{
|
|
||||||
final_addr = g_MemUtils.FindPattern(addrInBase, (char*) real_sig, real_bytes);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
/* First, preprocess the signature */
|
||||||
|
unsigned char real_sig[511];
|
||||||
|
size_t real_bytes;
|
||||||
|
size_t length;
|
||||||
|
|
||||||
m_Sigs.replace(m_offset, final_addr);
|
real_bytes = 0;
|
||||||
|
length = strlen(s_TempSig.sig);
|
||||||
|
|
||||||
|
real_bytes = UTIL_DecodeHexString(real_sig, sizeof(real_sig), s_TempSig.sig);
|
||||||
|
|
||||||
|
if (real_bytes >= 1)
|
||||||
|
{
|
||||||
|
final_addr = g_MemUtils.FindPattern(addrInBase, (char*)real_sig, real_bytes);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
skip_find:
|
||||||
|
m_Sigs.replace(m_offset, final_addr);
|
||||||
m_ParseState = PSTATE_GAMEDEFS_SIGNATURES;
|
m_ParseState = PSTATE_GAMEDEFS_SIGNATURES;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -631,11 +607,19 @@ SMCResult CGameConfig::ReadSMC_LeavingSection(const SMCStates *states)
|
|||||||
{
|
{
|
||||||
m_ParseState = PSTATE_GAMEDEFS_ADDRESSES;
|
m_ParseState = PSTATE_GAMEDEFS_ADDRESSES;
|
||||||
|
|
||||||
if (m_Address[0] != '\0' && m_AddressSignature[0] != '\0')
|
if (m_Address[0] == '\0')
|
||||||
{
|
{
|
||||||
AddressConf addrConf(m_AddressSignature, sizeof(m_AddressSignature), m_AddressReadCount, m_AddressRead);
|
smcore.LogError("[SM] Address sections must have names (gameconf \"%s\")", m_CurFile);
|
||||||
m_Addresses.replace(m_Address, addrConf);
|
break;
|
||||||
}
|
}
|
||||||
|
if (m_AddressSignature[0] == '\0')
|
||||||
|
{
|
||||||
|
smcore.LogError("[SM] Address section for \"%s\" did not specify a signature (gameconf \"%s\")", m_Address, m_CurFile);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
AddressConf addrConf(m_AddressSignature, sizeof(m_AddressSignature), m_AddressReadCount, m_AddressRead);
|
||||||
|
m_pAddresses->replace(m_Address, addrConf);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -779,10 +763,11 @@ static MasterReader master_reader;
|
|||||||
bool CGameConfig::Reparse(char *error, size_t maxlength)
|
bool CGameConfig::Reparse(char *error, size_t maxlength)
|
||||||
{
|
{
|
||||||
/* Reset cached data */
|
/* Reset cached data */
|
||||||
|
m_pStrings->Reset();
|
||||||
m_Offsets.clear();
|
m_Offsets.clear();
|
||||||
m_Props.clear();
|
m_Props.clear();
|
||||||
m_Keys.clear();
|
m_Keys.clear();
|
||||||
m_Addresses.clear();
|
m_pAddresses->clear();
|
||||||
|
|
||||||
char path[PLATFORM_MAX_PATH];
|
char path[PLATFORM_MAX_PATH];
|
||||||
|
|
||||||
@@ -792,19 +777,7 @@ bool CGameConfig::Reparse(char *error, size_t maxlength)
|
|||||||
{
|
{
|
||||||
/* Nope, use the old mechanism. */
|
/* Nope, use the old mechanism. */
|
||||||
smcore.Format(path, sizeof(path), "%s.txt", m_File);
|
smcore.Format(path, sizeof(path), "%s.txt", m_File);
|
||||||
if (!EnterFile(path, error, maxlength))
|
return EnterFile(path, error, maxlength);
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Allow customization. */
|
|
||||||
g_pSM->BuildPath(Path_SM, path, sizeof(path), "gamedata/custom/%s.txt", m_File);
|
|
||||||
if (libsys->PathExists(path))
|
|
||||||
{
|
|
||||||
smcore.Format(path, sizeof(path), "custom/%s.txt", m_File);
|
|
||||||
return EnterFile(path, error, maxlength);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Otherwise, it's time to parse the master. */
|
/* Otherwise, it's time to parse the master. */
|
||||||
@@ -949,15 +922,20 @@ void CGameConfig::SetParseEngine(const char *engine)
|
|||||||
|
|
||||||
bool CGameConfig::GetOffset(const char *key, int *value)
|
bool CGameConfig::GetOffset(const char *key, int *value)
|
||||||
{
|
{
|
||||||
return m_Offsets.retrieve(key, value);
|
int *pvalue;
|
||||||
|
if ((pvalue = m_Offsets.retrieve(key)) == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
*value = *pvalue;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *CGameConfig::GetKeyValue(const char *key)
|
const char *CGameConfig::GetKeyValue(const char *key)
|
||||||
{
|
{
|
||||||
StringHashMap<ke::AString>::Result r = m_Keys.find(key);
|
int *pkey;
|
||||||
if (!r.found())
|
if ((pkey = m_Keys.retrieve(key)) == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
return r->value.chars();
|
return m_pStrings->GetString(*pkey);
|
||||||
}
|
}
|
||||||
|
|
||||||
//memory addresses below 0x10000 are automatically considered invalid for dereferencing
|
//memory addresses below 0x10000 are automatically considered invalid for dereferencing
|
||||||
@@ -965,25 +943,25 @@ const char *CGameConfig::GetKeyValue(const char *key)
|
|||||||
|
|
||||||
bool CGameConfig::GetAddress(const char *key, void **retaddr)
|
bool CGameConfig::GetAddress(const char *key, void **retaddr)
|
||||||
{
|
{
|
||||||
StringHashMap<AddressConf>::Result r = m_Addresses.find(key);
|
AddressConf *addrConf;
|
||||||
if (!r.found())
|
|
||||||
|
addrConf = m_pAddresses->retrieve(key);
|
||||||
|
if (!addrConf)
|
||||||
{
|
{
|
||||||
*retaddr = NULL;
|
*retaddr = NULL;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
AddressConf &addrConf = r->value;
|
|
||||||
|
|
||||||
void *addr;
|
void *addr;
|
||||||
if (!GetMemSig(addrConf.signatureName, &addr))
|
if (!GetMemSig(addrConf->signatureName, &addr))
|
||||||
{
|
{
|
||||||
*retaddr = NULL;
|
*retaddr = NULL;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < addrConf.readCount; ++i)
|
for (int i = 0; i < addrConf->readCount; ++i)
|
||||||
{
|
{
|
||||||
int offset = addrConf.read[i];
|
int offset = addrConf->read[i];
|
||||||
|
|
||||||
//NULLs in the middle of an indirection chain are bad, end NULL is ok
|
//NULLs in the middle of an indirection chain are bad, end NULL is ok
|
||||||
if (addr == NULL || reinterpret_cast<uintptr_t>(addr) < VALID_MINIMUM_MEMORY_ADDRESS)
|
if (addr == NULL || reinterpret_cast<uintptr_t>(addr) < VALID_MINIMUM_MEMORY_ADDRESS)
|
||||||
@@ -1014,15 +992,32 @@ CGameConfig::AddressConf::AddressConf(char *sigName, unsigned sigLength, unsigne
|
|||||||
|
|
||||||
SendProp *CGameConfig::GetSendProp(const char *key)
|
SendProp *CGameConfig::GetSendProp(const char *key)
|
||||||
{
|
{
|
||||||
SendProp *prop;
|
SendProp **pProp;
|
||||||
if (!m_Props.retrieve(key, &prop))
|
|
||||||
|
if ((pProp = m_Props.retrieve(key)) == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
return prop;
|
|
||||||
|
return *pProp;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CGameConfig::GetMemSig(const char *key, void **addr)
|
bool CGameConfig::GetMemSig(const char *key, void **addr)
|
||||||
{
|
{
|
||||||
return m_Sigs.retrieve(key, addr);
|
void **paddr;
|
||||||
|
if ((paddr = m_Sigs.retrieve(key)) == NULL)
|
||||||
|
return false;
|
||||||
|
*addr = *paddr;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CGameConfig::IncRefCount()
|
||||||
|
{
|
||||||
|
m_RefCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int CGameConfig::DecRefCount()
|
||||||
|
{
|
||||||
|
m_RefCount--;
|
||||||
|
return m_RefCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
GameConfigManager::GameConfigManager()
|
GameConfigManager::GameConfigManager()
|
||||||
@@ -1073,10 +1068,12 @@ bool GameConfigManager::LoadGameConfigFile(const char *file, IGameConfig **_pCon
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
CGameConfig *pConfig;
|
CGameConfig *pConfig;
|
||||||
|
CGameConfig **ppConfig;
|
||||||
|
|
||||||
if (m_Lookup.retrieve(file, &pConfig))
|
if ((ppConfig = m_Lookup.retrieve(file)) != NULL)
|
||||||
{
|
{
|
||||||
pConfig->AddRef();
|
pConfig = *ppConfig;
|
||||||
|
pConfig->IncRefCount();
|
||||||
*_pConfig = pConfig;
|
*_pConfig = pConfig;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -1090,16 +1087,25 @@ bool GameConfigManager::LoadGameConfigFile(const char *file, IGameConfig **_pCon
|
|||||||
retval = pConfig->Reparse(error, maxlength);
|
retval = pConfig->Reparse(error, maxlength);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_cfgs.push_back(pConfig);
|
||||||
m_Lookup.insert(file, pConfig);
|
m_Lookup.insert(file, pConfig);
|
||||||
|
|
||||||
|
pConfig->IncRefCount();
|
||||||
|
|
||||||
*_pConfig = pConfig;
|
*_pConfig = pConfig;
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameConfigManager::CloseGameConfigFile(IGameConfig *cfg)
|
void GameConfigManager::CloseGameConfigFile(IGameConfig *cfg)
|
||||||
{
|
{
|
||||||
CGameConfig *pConfig = (CGameConfig *)cfg;
|
CGameConfig *pConfig = (CGameConfig *)cfg;
|
||||||
pConfig->Release();
|
|
||||||
|
if (pConfig->DecRefCount() == 0)
|
||||||
|
{
|
||||||
|
m_Lookup.remove(pConfig->m_File);
|
||||||
|
delete pConfig;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern Handle_t g_GameConfigsType;
|
extern Handle_t g_GameConfigsType;
|
||||||
@@ -1123,16 +1129,22 @@ void GameConfigManager::AddUserConfigHook(const char *sectionname, ITextListener
|
|||||||
m_customHandlers.insert(sectionname, listener);
|
m_customHandlers.insert(sectionname, listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameConfigManager::RemoveUserConfigHook(const char *sectionname, ITextListener_SMC *aListener)
|
void GameConfigManager::RemoveUserConfigHook(const char *sectionname, ITextListener_SMC *listener)
|
||||||
{
|
{
|
||||||
ITextListener_SMC *listener;
|
ITextListener_SMC **pListener = m_customHandlers.retrieve(sectionname);
|
||||||
if (!m_customHandlers.retrieve(sectionname, &listener))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (listener != aListener)
|
if (pListener == NULL)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*pListener != listener)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
m_customHandlers.remove(sectionname);
|
m_customHandlers.remove(sectionname);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1143,8 +1155,3 @@ void GameConfigManager::AcquireLock()
|
|||||||
void GameConfigManager::ReleaseLock()
|
void GameConfigManager::ReleaseLock()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameConfigManager::RemoveCachedConfig(CGameConfig *config)
|
|
||||||
{
|
|
||||||
m_Lookup.remove(config->m_File);
|
|
||||||
}
|
|
||||||
|
|||||||
+18
-21
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* vim: set ts=4 sw=4 tw=99 noet:
|
* vim: set ts=4 :
|
||||||
* =============================================================================
|
* =============================================================================
|
||||||
* SourceMod
|
* SourceMod
|
||||||
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
||||||
@@ -35,9 +35,9 @@
|
|||||||
#include "common_logic.h"
|
#include "common_logic.h"
|
||||||
#include <IGameConfigs.h>
|
#include <IGameConfigs.h>
|
||||||
#include <ITextParsers.h>
|
#include <ITextParsers.h>
|
||||||
#include <am-refcounting.h>
|
#include <sh_list.h>
|
||||||
#include <sm_stringhashmap.h>
|
#include "sm_memtable.h"
|
||||||
#include <sm_namehashset.h>
|
#include <sm_trie_tpl.h>
|
||||||
|
|
||||||
using namespace SourceMod;
|
using namespace SourceMod;
|
||||||
using namespace SourceHook;
|
using namespace SourceHook;
|
||||||
@@ -46,8 +46,7 @@ class SendProp;
|
|||||||
|
|
||||||
class CGameConfig :
|
class CGameConfig :
|
||||||
public ITextListener_SMC,
|
public ITextListener_SMC,
|
||||||
public IGameConfig,
|
public IGameConfig
|
||||||
public ke::Refcounted<CGameConfig>
|
|
||||||
{
|
{
|
||||||
friend class GameConfigManager;
|
friend class GameConfigManager;
|
||||||
public:
|
public:
|
||||||
@@ -68,18 +67,18 @@ public: //IGameConfig
|
|||||||
SendProp *GetSendProp(const char *key);
|
SendProp *GetSendProp(const char *key);
|
||||||
bool GetMemSig(const char *key, void **addr);
|
bool GetMemSig(const char *key, void **addr);
|
||||||
bool GetAddress(const char *key, void **addr);
|
bool GetAddress(const char *key, void **addr);
|
||||||
public: //NameHashSet
|
public:
|
||||||
static inline bool matches(const char *key, const CGameConfig *value)
|
void IncRefCount();
|
||||||
{
|
unsigned int DecRefCount();
|
||||||
return strcmp(key, value->m_File) == 0;
|
|
||||||
}
|
|
||||||
private:
|
private:
|
||||||
|
BaseStringTable *m_pStrings;
|
||||||
char m_File[PLATFORM_MAX_PATH];
|
char m_File[PLATFORM_MAX_PATH];
|
||||||
char m_CurFile[PLATFORM_MAX_PATH];
|
char m_CurFile[PLATFORM_MAX_PATH];
|
||||||
StringHashMap<int> m_Offsets;
|
KTrie<int> m_Offsets;
|
||||||
StringHashMap<SendProp *> m_Props;
|
KTrie<SendProp *> m_Props;
|
||||||
StringHashMap<ke::AString> m_Keys;
|
KTrie<int> m_Keys;
|
||||||
StringHashMap<void *> m_Sigs;
|
KTrie<void *> m_Sigs;
|
||||||
|
unsigned int m_RefCount;
|
||||||
/* Parse states */
|
/* Parse states */
|
||||||
int m_ParseState;
|
int m_ParseState;
|
||||||
unsigned int m_IgnoreLevel;
|
unsigned int m_IgnoreLevel;
|
||||||
@@ -92,7 +91,6 @@ private:
|
|||||||
bool matched_game;
|
bool matched_game;
|
||||||
bool had_engine;
|
bool had_engine;
|
||||||
bool matched_engine;
|
bool matched_engine;
|
||||||
bool matched_platform;
|
|
||||||
|
|
||||||
/* Custom Sections */
|
/* Custom Sections */
|
||||||
unsigned int m_CustomLevel;
|
unsigned int m_CustomLevel;
|
||||||
@@ -114,7 +112,7 @@ private:
|
|||||||
char m_AddressSignature[64];
|
char m_AddressSignature[64];
|
||||||
int m_AddressReadCount;
|
int m_AddressReadCount;
|
||||||
int m_AddressRead[8];
|
int m_AddressRead[8];
|
||||||
StringHashMap<AddressConf> m_Addresses;
|
KTrie<AddressConf> *m_pAddresses;
|
||||||
const char *m_pEngine;
|
const char *m_pEngine;
|
||||||
const char *m_pBaseEngine;
|
const char *m_pBaseEngine;
|
||||||
};
|
};
|
||||||
@@ -140,12 +138,11 @@ public: //SMGlobalClass
|
|||||||
void OnSourceModStartup(bool late);
|
void OnSourceModStartup(bool late);
|
||||||
void OnSourceModAllInitialized();
|
void OnSourceModAllInitialized();
|
||||||
void OnSourceModAllShutdown();
|
void OnSourceModAllShutdown();
|
||||||
public:
|
|
||||||
void RemoveCachedConfig(CGameConfig *config);
|
|
||||||
private:
|
private:
|
||||||
NameHashSet<CGameConfig *> m_Lookup;
|
List<CGameConfig *> m_cfgs;
|
||||||
|
KTrie<CGameConfig *> m_Lookup;
|
||||||
public:
|
public:
|
||||||
StringHashMap<ITextListener_SMC *> m_customHandlers;
|
KTrie<ITextListener_SMC *> m_customHandlers;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern GameConfigManager g_GameConfigs;
|
extern GameConfigManager g_GameConfigs;
|
||||||
|
|||||||
@@ -1,143 +0,0 @@
|
|||||||
/**
|
|
||||||
* vim: set ts=4 sw=4 tw=99 noet :
|
|
||||||
* =============================================================================
|
|
||||||
* SourcePawn
|
|
||||||
* Copyright (C) 2004-2009 AlliedModders LLC. All rights reserved.
|
|
||||||
* =============================================================================
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify it under
|
|
||||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
|
||||||
* Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
||||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
||||||
* details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along with
|
|
||||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
|
||||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
|
||||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
|
||||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
|
||||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
|
||||||
* this exception to all derivative works. AlliedModders LLC defines further
|
|
||||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
|
||||||
* or <http://www.sourcemod.net/license.php>.
|
|
||||||
*
|
|
||||||
* Version: $Id$
|
|
||||||
*/
|
|
||||||
#include "NativeOwner.h"
|
|
||||||
#include "ShareSys.h"
|
|
||||||
#include "PluginSys.h"
|
|
||||||
|
|
||||||
CNativeOwner::CNativeOwner() : m_nMarkSerial(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNativeOwner::SetMarkSerial(unsigned int serial)
|
|
||||||
{
|
|
||||||
m_nMarkSerial = serial;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int CNativeOwner::GetMarkSerial()
|
|
||||||
{
|
|
||||||
return m_nMarkSerial;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNativeOwner::AddDependent(CPlugin *pPlugin)
|
|
||||||
{
|
|
||||||
m_Dependents.push_back(pPlugin);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNativeOwner::AddWeakRef(const WeakNative & ref)
|
|
||||||
{
|
|
||||||
m_WeakRefs.push_back(ref);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNativeOwner::AddNatives(const sp_nativeinfo_t *natives)
|
|
||||||
{
|
|
||||||
for (const sp_nativeinfo_t *native = natives; native->func && native->name; native++)
|
|
||||||
g_ShareSys.AddNativeToCache(this, native);
|
|
||||||
|
|
||||||
m_natives.append(natives);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNativeOwner::PropagateMarkSerial(unsigned int serial)
|
|
||||||
{
|
|
||||||
CNativeOwner *pOwner;
|
|
||||||
List<CPlugin *>::iterator iter;
|
|
||||||
|
|
||||||
for (iter = m_Dependents.begin();
|
|
||||||
iter != m_Dependents.end();
|
|
||||||
iter++)
|
|
||||||
{
|
|
||||||
pOwner = (*iter);
|
|
||||||
pOwner->SetMarkSerial(serial);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNativeOwner::UnbindWeakRef(const WeakNative &ref)
|
|
||||||
{
|
|
||||||
sp_native_t *native;
|
|
||||||
IPluginContext *pContext;
|
|
||||||
|
|
||||||
pContext = ref.pl->GetBaseContext();
|
|
||||||
if ((pContext->GetNativeByIndex(ref.idx, &native)) == SP_ERROR_NONE)
|
|
||||||
{
|
|
||||||
native->status = SP_NATIVE_UNBOUND;
|
|
||||||
native->pfn = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNativeOwner::DropEverything()
|
|
||||||
{
|
|
||||||
List<WeakNative>::iterator iter;
|
|
||||||
|
|
||||||
/* Unbind and remove all weak references to us */
|
|
||||||
iter = m_WeakRefs.begin();
|
|
||||||
while (iter != m_WeakRefs.end())
|
|
||||||
{
|
|
||||||
UnbindWeakRef((*iter));
|
|
||||||
iter = m_WeakRefs.erase(iter);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Strip all of our natives from the cache */
|
|
||||||
for (size_t i = 0; i < m_natives.length(); i++) {
|
|
||||||
const sp_nativeinfo_t *natives = m_natives[i];
|
|
||||||
for (const sp_nativeinfo_t *native = natives; native->func && native->name; native++)
|
|
||||||
g_ShareSys.ClearNativeFromCache(this, native->name);
|
|
||||||
}
|
|
||||||
m_natives.clear();
|
|
||||||
|
|
||||||
for (size_t i = 0; i < m_fakes.length(); i++)
|
|
||||||
g_ShareSys.ClearNativeFromCache(this, m_fakes[i]->name());
|
|
||||||
m_fakes.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNativeOwner::DropWeakRefsTo(CPlugin *pPlugin)
|
|
||||||
{
|
|
||||||
List<WeakNative>::iterator iter;
|
|
||||||
|
|
||||||
iter = m_WeakRefs.begin();
|
|
||||||
while (iter != m_WeakRefs.end())
|
|
||||||
{
|
|
||||||
WeakNative & ref = (*iter);
|
|
||||||
|
|
||||||
if (ref.pl == pPlugin)
|
|
||||||
{
|
|
||||||
iter = m_WeakRefs.erase(iter);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
iter++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CNativeOwner::DropRefsTo(CPlugin *pPlugin)
|
|
||||||
{
|
|
||||||
m_Dependents.remove(pPlugin);
|
|
||||||
DropWeakRefsTo(pPlugin);
|
|
||||||
}
|
|
||||||
@@ -1,89 +0,0 @@
|
|||||||
/**
|
|
||||||
* vim: set ts=4 sw=4 tw=99 noet :
|
|
||||||
* =============================================================================
|
|
||||||
* SourcePawn
|
|
||||||
* Copyright (C) 2004-2009 AlliedModders LLC. All rights reserved.
|
|
||||||
* =============================================================================
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify it under
|
|
||||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
|
||||||
* Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
||||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
||||||
* details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along with
|
|
||||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
|
||||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
|
||||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
|
||||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
|
||||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
|
||||||
* this exception to all derivative works. AlliedModders LLC defines further
|
|
||||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
|
||||||
* or <http://www.sourcemod.net/license.php>.
|
|
||||||
*
|
|
||||||
* Version: $Id$
|
|
||||||
*/
|
|
||||||
#ifndef _INCLUDE_SOURCEMOD_NATIVE_OWNER_H_
|
|
||||||
#define _INCLUDE_SOURCEMOD_NATIVE_OWNER_H_
|
|
||||||
|
|
||||||
#include <sp_vm_types.h>
|
|
||||||
#include <sh_list.h>
|
|
||||||
#include <am-linkedlist.h>
|
|
||||||
#include <am-vector.h>
|
|
||||||
#include "common_logic.h"
|
|
||||||
#include "Native.h"
|
|
||||||
|
|
||||||
struct Native;
|
|
||||||
class CPlugin;
|
|
||||||
|
|
||||||
using namespace SourceMod;
|
|
||||||
|
|
||||||
struct WeakNative
|
|
||||||
{
|
|
||||||
WeakNative(IPlugin *plugin, uint32_t index) :
|
|
||||||
pl(plugin), idx(index)
|
|
||||||
{
|
|
||||||
pl = plugin;
|
|
||||||
idx = index;
|
|
||||||
}
|
|
||||||
IPlugin *pl;
|
|
||||||
uint32_t idx;
|
|
||||||
};
|
|
||||||
|
|
||||||
using namespace SourceHook;
|
|
||||||
|
|
||||||
class CNativeOwner
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CNativeOwner();
|
|
||||||
public:
|
|
||||||
virtual void DropEverything();
|
|
||||||
public:
|
|
||||||
void AddNatives(const sp_nativeinfo_t *info);
|
|
||||||
public:
|
|
||||||
void SetMarkSerial(unsigned int serial);
|
|
||||||
unsigned int GetMarkSerial();
|
|
||||||
void PropagateMarkSerial(unsigned int serial);
|
|
||||||
public:
|
|
||||||
void AddDependent(CPlugin *pPlugin);
|
|
||||||
void AddWeakRef(const WeakNative & ref);
|
|
||||||
void DropRefsTo(CPlugin *pPlugin);
|
|
||||||
private:
|
|
||||||
void DropWeakRefsTo(CPlugin *pPlugin);
|
|
||||||
void UnbindWeakRef(const WeakNative & ref);
|
|
||||||
protected:
|
|
||||||
List<CPlugin *> m_Dependents;
|
|
||||||
unsigned int m_nMarkSerial;
|
|
||||||
List<WeakNative> m_WeakRefs;
|
|
||||||
ke::Vector<const sp_nativeinfo_t *> m_natives;
|
|
||||||
ke::Vector<ke::Ref<Native> > m_fakes;
|
|
||||||
};
|
|
||||||
|
|
||||||
extern CNativeOwner g_CoreNatives;
|
|
||||||
|
|
||||||
#endif //_INCLUDE_SOURCEMOD_NATIVE_OWNER_H_
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* vim: set ts=4 sw=4 tw=99 noet :
|
* vim: set ts=4 :
|
||||||
* =============================================================================
|
* =============================================================================
|
||||||
* SourceMod
|
* SourceMod
|
||||||
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
||||||
@@ -465,7 +465,7 @@ void ProfileReport::SaveAtom(const prof_atom_t &atom)
|
|||||||
{
|
{
|
||||||
double atom_time;
|
double atom_time;
|
||||||
char full_name[256];
|
char full_name[256];
|
||||||
prof_atom_report_t *report;
|
prof_atom_report_t **pReport, *report;
|
||||||
|
|
||||||
if (atom.atom_type == SP_PROF_NATIVES)
|
if (atom.atom_type == SP_PROF_NATIVES)
|
||||||
{
|
{
|
||||||
@@ -487,7 +487,7 @@ void ProfileReport::SaveAtom(const prof_atom_t &atom)
|
|||||||
|
|
||||||
atom_time = CalcAtomTime(atom);
|
atom_time = CalcAtomTime(atom);
|
||||||
|
|
||||||
if (!m_ReportLookup.retrieve(full_name, &report))
|
if ((pReport = m_ReportLookup.retrieve(full_name)) == NULL)
|
||||||
{
|
{
|
||||||
report = new prof_atom_report_t;
|
report = new prof_atom_report_t;
|
||||||
|
|
||||||
@@ -502,6 +502,8 @@ void ProfileReport::SaveAtom(const prof_atom_t &atom)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
report = *pReport;
|
||||||
|
|
||||||
if (atom_time > report->max_time)
|
if (atom_time > report->max_time)
|
||||||
{
|
{
|
||||||
report->max_time = atom_time;
|
report->max_time = atom_time;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* vim: set ts=4 sw=4 tw=99 noet :
|
* vim: set ts=4 :
|
||||||
* =============================================================================
|
* =============================================================================
|
||||||
* SourceMod
|
* SourceMod
|
||||||
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
||||||
@@ -34,9 +34,9 @@
|
|||||||
|
|
||||||
#include <sp_vm_api.h>
|
#include <sp_vm_api.h>
|
||||||
#include <sm_platform.h>
|
#include <sm_platform.h>
|
||||||
|
#include <sm_trie_tpl.h>
|
||||||
#include <sh_vector.h>
|
#include <sh_vector.h>
|
||||||
#include <sh_stack.h>
|
#include <sh_stack.h>
|
||||||
#include <sm_namehashset.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "common_logic.h"
|
#include "common_logic.h"
|
||||||
#include <IRootConsoleMenu.h>
|
#include <IRootConsoleMenu.h>
|
||||||
@@ -72,11 +72,6 @@ struct prof_atom_report_t
|
|||||||
unsigned int num_calls; /* Number of invocations */
|
unsigned int num_calls; /* Number of invocations */
|
||||||
double min_time; /* Min time spent in one call, in s */
|
double min_time; /* Min time spent in one call, in s */
|
||||||
double max_time; /* Max time spent in one call, in s */
|
double max_time; /* Max time spent in one call, in s */
|
||||||
|
|
||||||
static inline bool matches(const char *name, const prof_atom_report_t *report)
|
|
||||||
{
|
|
||||||
return strcmp(report->atom_name, name) == 0;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class ProfileReport
|
class ProfileReport
|
||||||
@@ -89,7 +84,7 @@ public:
|
|||||||
prof_atom_report_t *GetReport(size_t i);
|
prof_atom_report_t *GetReport(size_t i);
|
||||||
void Clear();
|
void Clear();
|
||||||
private:
|
private:
|
||||||
NameHashSet<prof_atom_report_t *> m_ReportLookup;
|
KTrie<prof_atom_report_t *> m_ReportLookup;
|
||||||
CVector<prof_atom_report_t *> m_Reports;
|
CVector<prof_atom_report_t *> m_Reports;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -33,48 +33,9 @@
|
|||||||
#define _INCLUDE_SOURCEMOD_THREAD_SUPPORT_H
|
#define _INCLUDE_SOURCEMOD_THREAD_SUPPORT_H
|
||||||
|
|
||||||
#include <IThreader.h>
|
#include <IThreader.h>
|
||||||
#include <am-thread-utils.h>
|
|
||||||
#include <am-utility.h>
|
|
||||||
|
|
||||||
using namespace SourceMod;
|
using namespace SourceMod;
|
||||||
|
|
||||||
class CompatMutex : public IMutex
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
bool TryLock() {
|
|
||||||
return mutex_.TryLock();
|
|
||||||
}
|
|
||||||
void Lock() {
|
|
||||||
mutex_.Lock();
|
|
||||||
}
|
|
||||||
void Unlock() {
|
|
||||||
mutex_.Unlock();
|
|
||||||
}
|
|
||||||
void DestroyThis() {
|
|
||||||
delete this;
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
ke::Mutex mutex_;
|
|
||||||
};
|
|
||||||
|
|
||||||
class CompatCondVar : public IEventSignal
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
void Wait() {
|
|
||||||
ke::AutoLock lock(&cv_);
|
|
||||||
cv_.Wait();
|
|
||||||
}
|
|
||||||
void Signal() {
|
|
||||||
ke::AutoLock lock(&cv_);
|
|
||||||
cv_.Notify();
|
|
||||||
}
|
|
||||||
void DestroyThis() {
|
|
||||||
delete this;
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
ke::ConditionVariable cv_;
|
|
||||||
};
|
|
||||||
|
|
||||||
extern IThreader *g_pThreader;
|
extern IThreader *g_pThreader;
|
||||||
|
|
||||||
#endif //_INCLUDE_SOURCEMOD_THREAD_SUPPORT_H
|
#endif //_INCLUDE_SOURCEMOD_THREAD_SUPPORT_H
|
||||||
|
|||||||
+48
-25
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* vim: set ts=4 sw=4 tw=99 noet:
|
* vim: set ts=4 :
|
||||||
* =============================================================================
|
* =============================================================================
|
||||||
* SourceMod
|
* SourceMod
|
||||||
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
||||||
@@ -210,7 +210,12 @@ SMCResult CPhraseFile::ReadSMC_NewSection(const SMCStates *states, const char *n
|
|||||||
m_ParseState = PPS_InPhrase;
|
m_ParseState = PPS_InPhrase;
|
||||||
recognized = true;
|
recognized = true;
|
||||||
|
|
||||||
if (!m_PhraseLookup.retrieve(name, &m_CurPhrase))
|
int *pvalue;
|
||||||
|
if ((pvalue = m_PhraseLookup.retrieve(name)) != NULL)
|
||||||
|
{
|
||||||
|
m_CurPhrase = *pvalue;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
phrase_t *pPhrase;
|
phrase_t *pPhrase;
|
||||||
|
|
||||||
@@ -647,11 +652,11 @@ TransError CPhraseFile::GetTranslation(const char *szPhrase, unsigned int lang_i
|
|||||||
return Trans_BadLanguage;
|
return Trans_BadLanguage;
|
||||||
}
|
}
|
||||||
|
|
||||||
int address;
|
int *pvalue;
|
||||||
if (!m_PhraseLookup.retrieve(szPhrase, &address))
|
if ((pvalue = m_PhraseLookup.retrieve(szPhrase)) == NULL)
|
||||||
return Trans_BadPhrase;
|
return Trans_BadPhrase;
|
||||||
|
|
||||||
phrase_t *pPhrase = (phrase_t *)m_pMemory->GetAddress(address);
|
phrase_t *pPhrase = (phrase_t *)m_pMemory->GetAddress(*pvalue);
|
||||||
trans_t *trans = (trans_t *)m_pMemory->GetAddress(pPhrase->trans_tbl);
|
trans_t *trans = (trans_t *)m_pMemory->GetAddress(pPhrase->trans_tbl);
|
||||||
|
|
||||||
trans = &trans[lang_id];
|
trans = &trans[lang_id];
|
||||||
@@ -728,7 +733,10 @@ ConfigResult Translator::OnSourceModConfigChanged(const char *key,
|
|||||||
|
|
||||||
void Translator::OnSourceModLevelChange(const char *mapName)
|
void Translator::OnSourceModLevelChange(const char *mapName)
|
||||||
{
|
{
|
||||||
RebuildLanguageDatabase();
|
/* Refresh language stuff */
|
||||||
|
char path[PLATFORM_MAX_PATH];
|
||||||
|
g_pSM->BuildPath(Path_SM, path, sizeof(path), "configs/languages.cfg");
|
||||||
|
RebuildLanguageDatabase(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Translator::OnSourceModAllInitialized()
|
void Translator::OnSourceModAllInitialized()
|
||||||
@@ -754,7 +762,15 @@ void Translator::OnSourceModShutdown()
|
|||||||
|
|
||||||
bool Translator::GetLanguageByCode(const char *code, unsigned int *index)
|
bool Translator::GetLanguageByCode(const char *code, unsigned int *index)
|
||||||
{
|
{
|
||||||
return m_LCodeLookup.retrieve(code, index);
|
unsigned int *pindex;
|
||||||
|
|
||||||
|
if ((pindex = m_LCodeLookup.retrieve(code)) == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (index)
|
||||||
|
*index = *pindex;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Translator::GetLanguageByName(const char *name, unsigned int *index)
|
bool Translator::GetLanguageByName(const char *name, unsigned int *index)
|
||||||
@@ -771,7 +787,15 @@ bool Translator::GetLanguageByName(const char *name, unsigned int *index)
|
|||||||
}
|
}
|
||||||
lower[len] = '\0';
|
lower[len] = '\0';
|
||||||
|
|
||||||
return m_LAliases.retrieve(lower, index);
|
unsigned int *pIndex;
|
||||||
|
|
||||||
|
if ((pIndex = m_LAliases.retrieve(lower)) == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (index)
|
||||||
|
*index = *pIndex;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int Translator::GetLanguageCount()
|
unsigned int Translator::GetLanguageCount()
|
||||||
@@ -804,7 +828,7 @@ unsigned int Translator::FindOrAddPhraseFile(const char *phrase_file)
|
|||||||
return idx;
|
return idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Translator::RebuildLanguageDatabase()
|
void Translator::RebuildLanguageDatabase(const char *lang_header_file)
|
||||||
{
|
{
|
||||||
/* Erase everything we have */
|
/* Erase everything we have */
|
||||||
m_LCodeLookup.clear();
|
m_LCodeLookup.clear();
|
||||||
@@ -818,12 +842,9 @@ void Translator::RebuildLanguageDatabase()
|
|||||||
m_Languages.clear();
|
m_Languages.clear();
|
||||||
|
|
||||||
/* Start anew */
|
/* Start anew */
|
||||||
char path[PLATFORM_MAX_PATH];
|
|
||||||
g_pSM->BuildPath(Path_SM, path, sizeof(path), "configs/languages.cfg");
|
|
||||||
|
|
||||||
SMCError err;
|
SMCError err;
|
||||||
SMCStates states;
|
SMCStates states;
|
||||||
if ((err=textparsers->ParseFile_SMC(path, this, &states)) != SMCError_Okay)
|
if ((err=textparsers->ParseFile_SMC(lang_header_file, this, &states)) != SMCError_Okay)
|
||||||
{
|
{
|
||||||
const char *str_err = textparsers->GetSMCErrorString(err);
|
const char *str_err = textparsers->GetSMCErrorString(err);
|
||||||
if (!str_err)
|
if (!str_err)
|
||||||
@@ -831,17 +852,23 @@ void Translator::RebuildLanguageDatabase()
|
|||||||
str_err = m_CustomError.c_str();
|
str_err = m_CustomError.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
smcore.LogError("[SM] Failed to parse language header file: \"%s\"", path);
|
smcore.LogError("[SM] Failed to parse language header file: \"%s\"", lang_header_file);
|
||||||
smcore.LogError("[SM] Parse error (line %d, column %d): %s", states.line, states.col, str_err);
|
smcore.LogError("[SM] Parse error (line %d, column %d): %s", states.line, states.col, str_err);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_LCodeLookup.retrieve(m_InitialLang, &m_ServerLang))
|
unsigned int *pServerLang;
|
||||||
|
|
||||||
|
if ((pServerLang = m_LCodeLookup.retrieve(m_InitialLang)) == NULL)
|
||||||
{
|
{
|
||||||
smcore.LogError("Server language was set to bad language \"%s\" -- reverting to English", m_InitialLang);
|
smcore.LogError("Server language was set to bad language \"%s\" -- reverting to English", m_InitialLang);
|
||||||
|
|
||||||
smcore.strncopy(m_InitialLang, "en", sizeof(m_InitialLang));
|
smcore.strncopy(m_InitialLang, "en", sizeof(m_InitialLang));
|
||||||
m_ServerLang = SOURCEMOD_LANGUAGE_ENGLISH;
|
m_ServerLang = SOURCEMOD_LANGUAGE_ENGLISH;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_ServerLang = *pServerLang;
|
||||||
|
}
|
||||||
|
|
||||||
if (!m_Languages.size())
|
if (!m_Languages.size())
|
||||||
{
|
{
|
||||||
@@ -887,14 +914,6 @@ SMCResult Translator::ReadSMC_LeavingSection(const SMCStates *states)
|
|||||||
|
|
||||||
SMCResult Translator::ReadSMC_KeyValue(const SMCStates *states, const char *key, const char *value)
|
SMCResult Translator::ReadSMC_KeyValue(const SMCStates *states, const char *key, const char *value)
|
||||||
{
|
{
|
||||||
size_t len = strlen(key);
|
|
||||||
|
|
||||||
if (len >= sizeof(((Language *)0)->m_code2))
|
|
||||||
{
|
|
||||||
smcore.LogError("[SM] Warning encountered parsing languages.cfg file.");
|
|
||||||
smcore.LogError("[SM] Invalid language code \"%s\" is too long.", key);
|
|
||||||
}
|
|
||||||
|
|
||||||
AddLanguage(key, value);
|
AddLanguage(key, value);
|
||||||
|
|
||||||
return SMCResult_Continue;
|
return SMCResult_Continue;
|
||||||
@@ -914,11 +933,15 @@ bool Translator::AddLanguage(const char *langcode, const char *description)
|
|||||||
}
|
}
|
||||||
lower[len] = '\0';
|
lower[len] = '\0';
|
||||||
|
|
||||||
if (m_LAliases.contains(lower))
|
if (m_LAliases.retrieve(lower))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
unsigned int idx;
|
unsigned int idx;
|
||||||
if (!m_LCodeLookup.retrieve(langcode, &idx))
|
if (unsigned int *pIdx = m_LCodeLookup.retrieve(langcode))
|
||||||
|
{
|
||||||
|
idx = *pIdx;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
Language *pLanguage = new Language;
|
Language *pLanguage = new Language;
|
||||||
idx = m_Languages.size();
|
idx = m_Languages.size();
|
||||||
|
|||||||
@@ -33,7 +33,7 @@
|
|||||||
#define _INCLUDE_SOURCEMOD_TRANSLATOR_H_
|
#define _INCLUDE_SOURCEMOD_TRANSLATOR_H_
|
||||||
|
|
||||||
#include "common_logic.h"
|
#include "common_logic.h"
|
||||||
#include <sm_stringhashmap.h>
|
#include <sm_trie_tpl.h>
|
||||||
#include <sh_string.h>
|
#include <sh_string.h>
|
||||||
#include <sh_vector.h>
|
#include <sh_vector.h>
|
||||||
#include "sm_memtable.h"
|
#include "sm_memtable.h"
|
||||||
@@ -54,7 +54,7 @@ enum PhraseParseState
|
|||||||
|
|
||||||
struct Language
|
struct Language
|
||||||
{
|
{
|
||||||
char m_code2[32];
|
char m_code2[4];
|
||||||
int m_CanonicalName;
|
int m_CanonicalName;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -79,7 +79,7 @@ private:
|
|||||||
void ParseError(const char *message, ...);
|
void ParseError(const char *message, ...);
|
||||||
void ParseWarning(const char *message, ...);
|
void ParseWarning(const char *message, ...);
|
||||||
private:
|
private:
|
||||||
StringHashMap<int> m_PhraseLookup;
|
KTrie<int> m_PhraseLookup;
|
||||||
String m_File;
|
String m_File;
|
||||||
Translator *m_pTranslator;
|
Translator *m_pTranslator;
|
||||||
PhraseParseState m_ParseState;
|
PhraseParseState m_ParseState;
|
||||||
@@ -115,6 +115,7 @@ public: // ITextListener_SMC
|
|||||||
SMCResult ReadSMC_KeyValue(const SMCStates *states, const char *key, const char *value);
|
SMCResult ReadSMC_KeyValue(const SMCStates *states, const char *key, const char *value);
|
||||||
SMCResult ReadSMC_LeavingSection(const SMCStates *states);
|
SMCResult ReadSMC_LeavingSection(const SMCStates *states);
|
||||||
public:
|
public:
|
||||||
|
void RebuildLanguageDatabase(const char *lang_header_file);
|
||||||
unsigned int FindOrAddPhraseFile(const char *phrase_file);
|
unsigned int FindOrAddPhraseFile(const char *phrase_file);
|
||||||
BaseStringTable *GetStringTable();
|
BaseStringTable *GetStringTable();
|
||||||
unsigned int GetLanguageCount();
|
unsigned int GetLanguageCount();
|
||||||
@@ -145,15 +146,14 @@ public: //ITranslator
|
|||||||
size_t *pOutLength,
|
size_t *pOutLength,
|
||||||
const char **pFailPhrase);
|
const char **pFailPhrase);
|
||||||
bool GetLanguageInfo(unsigned int number, const char **code, const char **name);
|
bool GetLanguageInfo(unsigned int number, const char **code, const char **name);
|
||||||
void RebuildLanguageDatabase();
|
|
||||||
private:
|
private:
|
||||||
bool AddLanguage(const char *langcode, const char *description);
|
bool AddLanguage(const char *langcode, const char *description);
|
||||||
private:
|
private:
|
||||||
CVector<Language *> m_Languages;
|
CVector<Language *> m_Languages;
|
||||||
CVector<CPhraseFile *> m_Files;
|
CVector<CPhraseFile *> m_Files;
|
||||||
BaseStringTable *m_pStringTab;
|
BaseStringTable *m_pStringTab;
|
||||||
StringHashMap<unsigned int> m_LCodeLookup;
|
KTrie<unsigned int> m_LCodeLookup;
|
||||||
StringHashMap<unsigned int> m_LAliases;
|
KTrie<unsigned int> m_LAliases;
|
||||||
bool m_InLanguageSection;
|
bool m_InLanguageSection;
|
||||||
String m_CustomError;
|
String m_CustomError;
|
||||||
unsigned int m_ServerLang;
|
unsigned int m_ServerLang;
|
||||||
|
|||||||
+14
-69
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* vim: set ts=4 sw=4 tw=99 noet:
|
* vim: set ts=4 sw=4 :
|
||||||
* =============================================================================
|
* =============================================================================
|
||||||
* SourceMod
|
* SourceMod
|
||||||
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
||||||
@@ -32,7 +32,6 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sm_platform.h>
|
#include <sm_platform.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdarg.h>
|
|
||||||
#include "common_logic.h"
|
#include "common_logic.h"
|
||||||
#include "TextParsers.h"
|
#include "TextParsers.h"
|
||||||
#include "Profiler.h"
|
#include "Profiler.h"
|
||||||
@@ -42,36 +41,24 @@
|
|||||||
#include "ThreadSupport.h"
|
#include "ThreadSupport.h"
|
||||||
#include "Translator.h"
|
#include "Translator.h"
|
||||||
#include "GameConfigs.h"
|
#include "GameConfigs.h"
|
||||||
#include "DebugReporter.h"
|
|
||||||
#include "PluginSys.h"
|
|
||||||
#include "ShareSys.h"
|
|
||||||
#include "NativeOwner.h"
|
|
||||||
#include "HandleSys.h"
|
|
||||||
#include "ExtensionSys.h"
|
|
||||||
#include "ForwardSys.h"
|
|
||||||
#include "AdminCache.h"
|
|
||||||
|
|
||||||
sm_core_t smcore;
|
sm_core_t smcore;
|
||||||
IHandleSys *handlesys = &g_HandleSys;
|
IHandleSys *handlesys;
|
||||||
IdentityToken_t *g_pCoreIdent;
|
IdentityToken_t *g_pCoreIdent;
|
||||||
SMGlobalClass *SMGlobalClass::head = NULL;
|
SMGlobalClass *SMGlobalClass::head = NULL;
|
||||||
ISourceMod *g_pSM;
|
ISourceMod *g_pSM;
|
||||||
ILibrarySys *libsys;
|
ILibrarySys *libsys;
|
||||||
ITextParsers *textparser = &g_TextParser;
|
ITextParsers *textparser = &g_TextParser;
|
||||||
IVEngineServer *engine;
|
IVEngineServer *engine;
|
||||||
IShareSys *sharesys = &g_ShareSys;
|
IShareSys *sharesys;
|
||||||
IRootConsole *rootmenu;
|
IRootConsole *rootmenu;
|
||||||
IPluginManager *pluginsys = g_PluginSys.GetOldAPI();
|
IPluginManager *pluginsys;
|
||||||
IForwardManager *forwardsys = &g_Forwards;
|
IForwardManager *forwardsys;
|
||||||
ITimerSystem *timersys;
|
ITimerSystem *timersys;
|
||||||
ServerGlobals serverGlobals;
|
ServerGlobals serverGlobals;
|
||||||
IPlayerManager *playerhelpers;
|
IPlayerManager *playerhelpers;
|
||||||
IAdminSystem *adminsys = &g_Admins;
|
IAdminSystem *adminsys;
|
||||||
IGameHelpers *gamehelpers;
|
IGameHelpers *gamehelpers;
|
||||||
ISourcePawnEngine *g_pSourcePawn;
|
|
||||||
ISourcePawnEngine2 *g_pSourcePawn2;
|
|
||||||
CNativeOwner g_CoreNatives;
|
|
||||||
IScriptManager *scripts = &g_PluginSys;
|
|
||||||
|
|
||||||
static void AddCorePhraseFile(const char *filename)
|
static void AddCorePhraseFile(const char *filename)
|
||||||
{
|
{
|
||||||
@@ -83,32 +70,6 @@ static IGameConfig *GetCoreGameConfig()
|
|||||||
return g_pGameConf;
|
return g_pGameConf;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Defined in smn_filesystem.cpp.
|
|
||||||
extern bool OnLogPrint(const char *msg);
|
|
||||||
|
|
||||||
static void GenerateError(IPluginContext *ctx, cell_t idx, int err, const char *msg, ...)
|
|
||||||
{
|
|
||||||
va_list ap;
|
|
||||||
va_start(ap, msg);
|
|
||||||
g_DbgReporter.GenerateErrorVA(ctx, idx, err, msg, ap);
|
|
||||||
va_end(ap);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void AddNatives(sp_nativeinfo_t *natives)
|
|
||||||
{
|
|
||||||
g_CoreNatives.AddNatives(natives);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void DumpHandles(void (*dumpfn)(const char *fmt, ...))
|
|
||||||
{
|
|
||||||
g_HandleSys.Dump(dumpfn);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void DumpAdminCache(FILE *f)
|
|
||||||
{
|
|
||||||
g_Admins.DumpCache(f);
|
|
||||||
}
|
|
||||||
|
|
||||||
static sm_logic_t logic =
|
static sm_logic_t logic =
|
||||||
{
|
{
|
||||||
NULL,
|
NULL,
|
||||||
@@ -121,21 +82,7 @@ static sm_logic_t logic =
|
|||||||
UTIL_ReplaceAll,
|
UTIL_ReplaceAll,
|
||||||
UTIL_ReplaceEx,
|
UTIL_ReplaceEx,
|
||||||
UTIL_DecodeHexString,
|
UTIL_DecodeHexString,
|
||||||
GetCoreGameConfig,
|
GetCoreGameConfig
|
||||||
OnLogPrint,
|
|
||||||
&g_DbgReporter,
|
|
||||||
GenerateError,
|
|
||||||
AddNatives,
|
|
||||||
DumpHandles,
|
|
||||||
DumpAdminCache,
|
|
||||||
&g_PluginSys,
|
|
||||||
&g_ShareSys,
|
|
||||||
&g_Extensions,
|
|
||||||
&g_HandleSys,
|
|
||||||
&g_Forwards,
|
|
||||||
&g_Admins,
|
|
||||||
NULL,
|
|
||||||
-1.0f
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void logic_init(const sm_core_t* core, sm_logic_t* _logic)
|
static void logic_init(const sm_core_t* core, sm_logic_t* _logic)
|
||||||
@@ -146,21 +93,19 @@ static void logic_init(const sm_core_t* core, sm_logic_t* _logic)
|
|||||||
memcpy(_logic, &logic, sizeof(sm_logic_t));
|
memcpy(_logic, &logic, sizeof(sm_logic_t));
|
||||||
memcpy(&serverGlobals, core->serverGlobals, sizeof(ServerGlobals));
|
memcpy(&serverGlobals, core->serverGlobals, sizeof(ServerGlobals));
|
||||||
|
|
||||||
|
handlesys = core->handlesys;
|
||||||
libsys = core->libsys;
|
libsys = core->libsys;
|
||||||
engine = core->engine;
|
engine = core->engine;
|
||||||
|
g_pCoreIdent = core->core_ident;
|
||||||
g_pSM = core->sm;
|
g_pSM = core->sm;
|
||||||
|
sharesys = core->sharesys;
|
||||||
rootmenu = core->rootmenu;
|
rootmenu = core->rootmenu;
|
||||||
|
pluginsys = core->pluginsys;
|
||||||
|
forwardsys = core->forwardsys;
|
||||||
timersys = core->timersys;
|
timersys = core->timersys;
|
||||||
playerhelpers = core->playerhelpers;
|
playerhelpers = core->playerhelpers;
|
||||||
|
adminsys = core->adminsys;
|
||||||
gamehelpers = core->gamehelpers;
|
gamehelpers = core->gamehelpers;
|
||||||
g_pSourcePawn = *core->spe1;
|
|
||||||
g_pSourcePawn2 = *core->spe2;
|
|
||||||
SMGlobalClass::head = core->listeners;
|
|
||||||
|
|
||||||
g_ShareSys.Initialize();
|
|
||||||
g_pCoreIdent = g_ShareSys.CreateCoreIdentity();
|
|
||||||
|
|
||||||
_logic->core_ident = g_pCoreIdent;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PLATFORM_EXTERN_C ITextParsers *get_textparsers()
|
PLATFORM_EXTERN_C ITextParsers *get_textparsers()
|
||||||
@@ -180,7 +125,7 @@ PLATFORM_EXTERN_C LogicInitFunction logic_load(uint32_t magic)
|
|||||||
|
|
||||||
void CoreNativesToAdd::OnSourceModAllInitialized()
|
void CoreNativesToAdd::OnSourceModAllInitialized()
|
||||||
{
|
{
|
||||||
g_CoreNatives.AddNatives(m_NativeList);
|
smcore.AddNatives(m_NativeList);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Overload a few things to prevent libstdc++ linking */
|
/* Overload a few things to prevent libstdc++ linking */
|
||||||
|
|||||||
@@ -52,7 +52,6 @@ extern ServerGlobals serverGlobals;
|
|||||||
extern IPlayerManager *playerhelpers;
|
extern IPlayerManager *playerhelpers;
|
||||||
extern IAdminSystem *adminsys;
|
extern IAdminSystem *adminsys;
|
||||||
extern IGameHelpers *gamehelpers;
|
extern IGameHelpers *gamehelpers;
|
||||||
extern IScriptManager *scripts;
|
|
||||||
|
|
||||||
#endif /* _INCLUDE_SOURCEMOD_COMMON_LOGIC_H_ */
|
#endif /* _INCLUDE_SOURCEMOD_COMMON_LOGIC_H_ */
|
||||||
|
|
||||||
|
|||||||
+14
-201
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* vim: set ts=4 sw=4 tw=99 noet:
|
* vim: set ts=4 :
|
||||||
* =============================================================================
|
* =============================================================================
|
||||||
* SourceMod
|
* SourceMod
|
||||||
* Copyright (C) 2004-2009 AlliedModders LLC. All rights reserved.
|
* Copyright (C) 2004-2009 AlliedModders LLC. All rights reserved.
|
||||||
@@ -29,30 +29,20 @@
|
|||||||
* Version: $Id$
|
* Version: $Id$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _INCLUDE_SOURCEMOD_INTERCOM_H_
|
|
||||||
#define _INCLUDE_SOURCEMOD_INTERCOM_H_
|
|
||||||
|
|
||||||
#include <sp_vm_api.h>
|
#include <sp_vm_api.h>
|
||||||
#include <IHandleSys.h>
|
#include <IHandleSys.h>
|
||||||
#include <IShareSys.h>
|
#include <IShareSys.h>
|
||||||
#include <IPluginSys.h>
|
|
||||||
#include <IDBDriver.h>
|
#ifndef _INCLUDE_SOURCEMOD_INTERCOM_H_
|
||||||
#include <sh_string.h>
|
#define _INCLUDE_SOURCEMOD_INTERCOM_H_
|
||||||
#include <sp_vm_api.h>
|
|
||||||
#include <sh_vector.h>
|
|
||||||
#include <IExtensionSys.h>
|
|
||||||
#include <IForwardSys.h>
|
|
||||||
#include <IAdminSystem.h>
|
|
||||||
|
|
||||||
using namespace SourceMod;
|
using namespace SourceMod;
|
||||||
using namespace SourcePawn;
|
|
||||||
using namespace SourceHook;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add 1 to the RHS of this expression to bump the intercom file
|
* Add 1 to the RHS of this expression to bump the intercom file
|
||||||
* This is to prevent mismatching core/logic binaries
|
* This is to prevent mismatching core/logic binaries
|
||||||
*/
|
*/
|
||||||
#define SM_LOGIC_MAGIC (0x0F47C0DE - 28)
|
#define SM_LOGIC_MAGIC (0x0F47C0DE - 18)
|
||||||
|
|
||||||
#if defined SM_LOGIC
|
#if defined SM_LOGIC
|
||||||
class IVEngineServer
|
class IVEngineServer
|
||||||
@@ -62,16 +52,9 @@ class IVEngineServer_Logic
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual bool IsMapValid(const char *map) = 0;
|
virtual bool IsMapValid(const char *map) = 0;
|
||||||
virtual bool IsDedicatedServer() = 0;
|
|
||||||
virtual void InsertServerCommand(const char *cmd) = 0;
|
|
||||||
virtual void ServerCommand(const char *cmd) = 0;
|
virtual void ServerCommand(const char *cmd) = 0;
|
||||||
virtual void ServerExecute() = 0;
|
|
||||||
virtual const char *GetClientConVarValue(int clientIndex, const char *name) = 0;
|
|
||||||
virtual void ClientCommand(edict_t *pEdict, const char *szCommand) = 0;
|
|
||||||
virtual void FakeClientCommand(edict_t *pEdict, const char *szCommand) = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef void * FileHandle_t;
|
|
||||||
typedef int FileFindHandle_t;
|
typedef int FileFindHandle_t;
|
||||||
|
|
||||||
#if defined SM_LOGIC
|
#if defined SM_LOGIC
|
||||||
@@ -84,12 +67,6 @@ public:
|
|||||||
virtual const char *FindFirstEx(const char *pWildCard, const char *pPathID, FileFindHandle_t *pHandle) = 0;
|
virtual const char *FindFirstEx(const char *pWildCard, const char *pPathID, FileFindHandle_t *pHandle) = 0;
|
||||||
virtual const char *FindNext(FileFindHandle_t handle) = 0;
|
virtual const char *FindNext(FileFindHandle_t handle) = 0;
|
||||||
virtual void FindClose(FileFindHandle_t handle) = 0;
|
virtual void FindClose(FileFindHandle_t handle) = 0;
|
||||||
virtual FileHandle_t Open(const char *pFileName, const char *pOptions, const char *pathID = 0) = 0;
|
|
||||||
virtual void Close(FileHandle_t file) = 0;
|
|
||||||
virtual char *ReadLine(char *pOutput, int maxChars, FileHandle_t file) = 0;
|
|
||||||
virtual bool EndOfFile(FileHandle_t file) = 0;
|
|
||||||
virtual bool FileExists(const char *pFileName, const char *pPathID = 0) = 0;
|
|
||||||
virtual unsigned int Size(const char *pFileName, const char *pPathID = 0) = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace SourceMod
|
namespace SourceMod
|
||||||
@@ -113,32 +90,6 @@ namespace SourceMod
|
|||||||
class IVEngineServer;
|
class IVEngineServer;
|
||||||
class IFileSystem;
|
class IFileSystem;
|
||||||
class ConVar;
|
class ConVar;
|
||||||
class KeyValues;
|
|
||||||
class SMGlobalClass;
|
|
||||||
class IPlayerInfo;
|
|
||||||
|
|
||||||
class IPlayerInfo_Logic
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual bool IsObserver(IPlayerInfo *pInfo) = 0;
|
|
||||||
virtual int GetTeamIndex(IPlayerInfo *pInfo) = 0;
|
|
||||||
virtual int GetFragCount(IPlayerInfo *pInfo) = 0;
|
|
||||||
virtual int GetDeathCount(IPlayerInfo *pInfo) = 0;
|
|
||||||
virtual int GetArmorValue(IPlayerInfo *pInfo) = 0;
|
|
||||||
virtual void GetAbsOrigin(IPlayerInfo *pInfo, float *x, float *y, float *z) = 0;
|
|
||||||
virtual void GetAbsAngles(IPlayerInfo *pInfo, float *x, float *y, float *z) = 0;
|
|
||||||
virtual void GetPlayerMins(IPlayerInfo *pInfo, float *x, float *y, float *z) = 0;
|
|
||||||
virtual void GetPlayerMaxs(IPlayerInfo *pInfo, float *x, float *y, float *z) = 0;
|
|
||||||
virtual const char *GetWeaponName(IPlayerInfo *pInfo) = 0;
|
|
||||||
virtual const char *GetModelName(IPlayerInfo *pInfo) = 0;
|
|
||||||
virtual int GetHealth(IPlayerInfo *pInfo) = 0;
|
|
||||||
virtual void ChangeTeam(IPlayerInfo *pInfo, int iTeamNum) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace SourceMod
|
|
||||||
{
|
|
||||||
class IChangeableForward;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ServerGlobals
|
struct ServerGlobals
|
||||||
{
|
{
|
||||||
@@ -147,141 +98,32 @@ struct ServerGlobals
|
|||||||
float *frametime;
|
float *frametime;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AutoConfig
|
|
||||||
{
|
|
||||||
SourceHook::String autocfg;
|
|
||||||
SourceHook::String folder;
|
|
||||||
bool create;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum LibraryAction
|
|
||||||
{
|
|
||||||
LibraryAction_Removed,
|
|
||||||
LibraryAction_Added
|
|
||||||
};
|
|
||||||
|
|
||||||
class CNativeOwner;
|
|
||||||
|
|
||||||
class SMPlugin : public IPlugin
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual size_t GetConfigCount() = 0;
|
|
||||||
virtual AutoConfig *GetConfig(size_t i) = 0;
|
|
||||||
virtual void AddLibrary(const char *name) = 0;
|
|
||||||
virtual void AddConfig(bool create, const char *cfg, const char *folder) = 0;
|
|
||||||
virtual void SetErrorState(PluginStatus status, const char *fmt, ...) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
class IScriptManager
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual void LoadAll(const char *config_path, const char *plugins_path) = 0;
|
|
||||||
virtual void RefreshAll() = 0;
|
|
||||||
virtual void Shutdown() = 0;
|
|
||||||
virtual IdentityToken_t *GetIdentity() = 0;
|
|
||||||
virtual void SyncMaxClients(int maxClients) = 0;
|
|
||||||
virtual void AddPluginsListener(IPluginsListener *listener) = 0;
|
|
||||||
virtual void RemovePluginsListener(IPluginsListener *listener) = 0;
|
|
||||||
virtual IPluginIterator *GetPluginIterator() = 0;
|
|
||||||
virtual void OnLibraryAction(const char *name, LibraryAction action) = 0;
|
|
||||||
virtual bool LibraryExists(const char *name) = 0;
|
|
||||||
virtual SMPlugin *FindPluginByOrder(unsigned num) = 0;
|
|
||||||
virtual SMPlugin *FindPluginByIdentity(IdentityToken_t *ident) = 0;
|
|
||||||
virtual SMPlugin *FindPluginByContext(IPluginContext *ctx) = 0;
|
|
||||||
virtual SMPlugin *FindPluginByContext(sp_context_t *ctx) = 0;
|
|
||||||
virtual SMPlugin *FindPluginByConsoleArg(const char *text) = 0;
|
|
||||||
virtual SMPlugin *FindPluginByHandle(Handle_t hndl, HandleError *errp) = 0;
|
|
||||||
virtual bool UnloadPlugin(IPlugin *plugin) = 0;
|
|
||||||
virtual const CVector<SMPlugin *> *ListPlugins() = 0;
|
|
||||||
virtual void FreePluginList(const CVector<SMPlugin *> *list) = 0;
|
|
||||||
virtual void AddFunctionsToForward(const char *name, IChangeableForward *fwd) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
class IExtensionSys : public IExtensionManager
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual IExtension *LoadAutoExtension(const char *name, bool bErrorOnMissing=true) = 0;
|
|
||||||
virtual void TryAutoload() = 0;
|
|
||||||
virtual void Shutdown() = 0;
|
|
||||||
virtual IExtension *FindExtensionByFile(const char *name) = 0;
|
|
||||||
virtual bool LibraryExists(const char *name) = 0;
|
|
||||||
virtual void CallOnCoreMapStart(edict_t *edictList, int edictCount, int maxClients) = 0;
|
|
||||||
virtual IExtension *GetExtensionFromIdent(IdentityToken_t *token) = 0;
|
|
||||||
virtual void BindChildPlugin(IExtension *ext, SMPlugin *plugin) = 0;
|
|
||||||
virtual void AddRawDependency(IExtension *myself, IdentityToken_t *token, void *iface) = 0;
|
|
||||||
virtual const CVector<IExtension *> *ListExtensions() = 0;
|
|
||||||
virtual void FreeExtensionList(const CVector<IExtension *> *list) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
class AutoPluginList
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
AutoPluginList(IScriptManager *scripts)
|
|
||||||
: scripts_(scripts), list_(scripts->ListPlugins())
|
|
||||||
{
|
|
||||||
}
|
|
||||||
~AutoPluginList()
|
|
||||||
{
|
|
||||||
scripts_->FreePluginList(list_);
|
|
||||||
}
|
|
||||||
const CVector<SMPlugin *> *operator ->()
|
|
||||||
{
|
|
||||||
return list_;
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
IScriptManager *scripts_;
|
|
||||||
const CVector<SMPlugin *> *list_;
|
|
||||||
};
|
|
||||||
|
|
||||||
class AutoExtensionList
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
AutoExtensionList(IExtensionSys *extensions)
|
|
||||||
: extensions_(extensions), list_(extensions_->ListExtensions())
|
|
||||||
{
|
|
||||||
}
|
|
||||||
~AutoExtensionList()
|
|
||||||
{
|
|
||||||
extensions_->FreeExtensionList(list_);
|
|
||||||
}
|
|
||||||
const CVector<IExtension *> *operator ->()
|
|
||||||
{
|
|
||||||
return list_;
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
IExtensionSys *extensions_;
|
|
||||||
const CVector<IExtension *> *list_;
|
|
||||||
};
|
|
||||||
|
|
||||||
class CCommand;
|
|
||||||
|
|
||||||
struct sm_core_t
|
struct sm_core_t
|
||||||
{
|
{
|
||||||
/* Objects */
|
/* Objects */
|
||||||
|
IHandleSys *handlesys;
|
||||||
|
IdentityToken_t *core_ident;
|
||||||
ISourceMod *sm;
|
ISourceMod *sm;
|
||||||
ILibrarySys *libsys;
|
ILibrarySys *libsys;
|
||||||
IVEngineServer *engine;
|
IVEngineServer *engine;
|
||||||
IFileSystem *filesystem;
|
IFileSystem *filesystem;
|
||||||
IPlayerInfo_Logic *playerInfo;
|
IShareSys *sharesys;
|
||||||
IRootConsole *rootmenu;
|
IRootConsole *rootmenu;
|
||||||
|
IPluginManager *pluginsys;
|
||||||
|
IForwardManager *forwardsys;
|
||||||
ITimerSystem *timersys;
|
ITimerSystem *timersys;
|
||||||
IPlayerManager *playerhelpers;
|
IPlayerManager *playerhelpers;
|
||||||
|
IAdminSystem *adminsys;
|
||||||
IGameHelpers *gamehelpers;
|
IGameHelpers *gamehelpers;
|
||||||
ISourcePawnEngine **spe1;
|
|
||||||
ISourcePawnEngine2 **spe2;
|
|
||||||
/* Functions */
|
/* Functions */
|
||||||
|
void (*AddNatives)(sp_nativeinfo_t* nlist);
|
||||||
ConVar * (*FindConVar)(const char*);
|
ConVar * (*FindConVar)(const char*);
|
||||||
unsigned int (*strncopy)(char*, const char*, size_t);
|
unsigned int (*strncopy)(char*, const char*, size_t);
|
||||||
char * (*TrimWhitespace)(char *, size_t &);
|
char * (*TrimWhitespace)(char *, size_t &);
|
||||||
void (*LogError)(const char*, ...);
|
void (*LogError)(const char*, ...);
|
||||||
void (*LogFatal)(const char*, ...);
|
|
||||||
void (*Log)(const char*, ...);
|
|
||||||
void (*LogToFile)(FILE *fp, const char*, ...);
|
|
||||||
void (*LogToGame)(const char *message);
|
|
||||||
void (*ConPrint)(const char *message);
|
|
||||||
const char * (*GetCvarString)(ConVar*);
|
const char * (*GetCvarString)(ConVar*);
|
||||||
size_t (*Format)(char*, size_t, const char*, ...);
|
size_t (*Format)(char*, size_t, const char*, ...);
|
||||||
size_t (*FormatArgs)(char*, size_t, const char*,va_list ap);
|
void (*GenerateError)(IPluginContext *, cell_t, int, const char *, ...);
|
||||||
bool (*gnprintf)(char *, size_t, const char *, IPhraseCollection *, void **,
|
bool (*gnprintf)(char *, size_t, const char *, IPhraseCollection *, void **,
|
||||||
unsigned int, unsigned int &, size_t *, const char **);
|
unsigned int, unsigned int &, size_t *, const char **);
|
||||||
size_t (*atcprintf)(char *, size_t, const char *, IPluginContext *, const cell_t *, int *);
|
size_t (*atcprintf)(char *, size_t, const char *, IPluginContext *, const cell_t *, int *);
|
||||||
@@ -290,27 +132,11 @@ struct sm_core_t
|
|||||||
const char * (*GetSourceEngineName)();
|
const char * (*GetSourceEngineName)();
|
||||||
bool (*SymbolsAreHidden)();
|
bool (*SymbolsAreHidden)();
|
||||||
const char * (*GetCoreConfigValue)(const char*);
|
const char * (*GetCoreConfigValue)(const char*);
|
||||||
bool (*IsMapLoading)();
|
|
||||||
bool (*IsMapRunning)();
|
|
||||||
int (*Argc)(const CCommand &args);
|
|
||||||
const char * (*Arg)(const CCommand &args, int arg);
|
|
||||||
int (*LoadMMSPlugin)(const char *file, bool *ok, char *error, size_t maxlength);
|
|
||||||
void (*UnloadMMSPlugin)(int id);
|
|
||||||
void (*DoGlobalPluginLoads)();
|
|
||||||
bool (*AreConfigsExecuted)();
|
|
||||||
void (*ExecuteConfigs)(IPluginContext *ctx);
|
|
||||||
DatabaseInfo (*GetDBInfoFromKeyValues)(KeyValues *);
|
|
||||||
int (*GetActivityFlags)();
|
|
||||||
int (*GetImmunityMode)();
|
|
||||||
void (*UpdateAdminCmdFlags)(const char *cmd, OverrideType type, FlagBits bits, bool remove);
|
|
||||||
bool (*LookForCommandAdminFlags)(const char *cmd, FlagBits *pFlags);
|
|
||||||
const char *gamesuffix;
|
|
||||||
/* Data */
|
/* Data */
|
||||||
ServerGlobals *serverGlobals;
|
ServerGlobals *serverGlobals;
|
||||||
void * serverFactory;
|
void * serverFactory;
|
||||||
void * engineFactory;
|
void * engineFactory;
|
||||||
void * matchmakingDSFactory;
|
void * matchmakingDSFactory;
|
||||||
SMGlobalClass * listeners;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sm_logic_t
|
struct sm_logic_t
|
||||||
@@ -326,20 +152,6 @@ struct sm_logic_t
|
|||||||
char *(*ReplaceEx)(char *, size_t, const char *, size_t, const char *, size_t, bool);
|
char *(*ReplaceEx)(char *, size_t, const char *, size_t, const char *, size_t, bool);
|
||||||
size_t (*DecodeHexString)(unsigned char *, size_t, const char *);
|
size_t (*DecodeHexString)(unsigned char *, size_t, const char *);
|
||||||
IGameConfig * (*GetCoreGameConfig)();
|
IGameConfig * (*GetCoreGameConfig)();
|
||||||
bool (*OnLogPrint)(const char *msg); // true to supercede
|
|
||||||
IDebugListener *debugger;
|
|
||||||
void (*GenerateError)(IPluginContext *, cell_t, int, const char *, ...);
|
|
||||||
void (*AddNatives)(sp_nativeinfo_t *natives);
|
|
||||||
void (*DumpHandles)(void (*dumpfn)(const char *fmt, ...));
|
|
||||||
void (*DumpAdminCache)(FILE *);
|
|
||||||
IScriptManager *scripts;
|
|
||||||
IShareSys *sharesys;
|
|
||||||
IExtensionSys *extsys;
|
|
||||||
IHandleSys *handlesys;
|
|
||||||
IForwardManager *forwardsys;
|
|
||||||
IAdminSystem *adminsys;
|
|
||||||
IdentityToken_t *core_ident;
|
|
||||||
float sentinel;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef void (*LogicInitFunction)(const sm_core_t *core, sm_logic_t *logic);
|
typedef void (*LogicInitFunction)(const sm_core_t *core, sm_logic_t *logic);
|
||||||
@@ -347,3 +159,4 @@ typedef LogicInitFunction (*LogicLoadFunction)(uint32_t magic);
|
|||||||
typedef ITextParsers *(*GetITextParsers)();
|
typedef ITextParsers *(*GetITextParsers)();
|
||||||
|
|
||||||
#endif /* _INCLUDE_SOURCEMOD_INTERCOM_H_ */
|
#endif /* _INCLUDE_SOURCEMOD_INTERCOM_H_ */
|
||||||
|
|
||||||
|
|||||||
@@ -112,19 +112,10 @@
|
|||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="..\common_logic.cpp" />
|
<ClCompile Include="..\common_logic.cpp" />
|
||||||
<ClCompile Include="..\DebugReporter.cpp" />
|
|
||||||
<ClCompile Include="..\ExtensionSys.cpp" />
|
|
||||||
<ClCompile Include="..\GameConfigs.cpp" />
|
<ClCompile Include="..\GameConfigs.cpp" />
|
||||||
<ClCompile Include="..\HandleSys.cpp" />
|
|
||||||
<ClCompile Include="..\MemoryUtils.cpp" />
|
<ClCompile Include="..\MemoryUtils.cpp" />
|
||||||
<ClCompile Include="..\NativeInvoker.cpp" />
|
|
||||||
<ClCompile Include="..\NativeOwner.cpp" />
|
|
||||||
<ClCompile Include="..\PhraseCollection.cpp" />
|
<ClCompile Include="..\PhraseCollection.cpp" />
|
||||||
<ClCompile Include="..\PluginSys.cpp" />
|
|
||||||
<ClCompile Include="..\Profiler.cpp" />
|
<ClCompile Include="..\Profiler.cpp" />
|
||||||
<ClCompile Include="..\ShareSys.cpp" />
|
|
||||||
<ClCompile Include="..\smn_fakenatives.cpp" />
|
|
||||||
<ClCompile Include="..\smn_filesystem.cpp" />
|
|
||||||
<ClCompile Include="..\sm_crc32.cpp" />
|
<ClCompile Include="..\sm_crc32.cpp" />
|
||||||
<ClCompile Include="..\smn_admin.cpp" />
|
<ClCompile Include="..\smn_admin.cpp" />
|
||||||
<ClCompile Include="..\smn_adt_array.cpp" />
|
<ClCompile Include="..\smn_adt_array.cpp" />
|
||||||
@@ -158,17 +149,12 @@
|
|||||||
<ClInclude Include="..\AutoHandleRooter.h" />
|
<ClInclude Include="..\AutoHandleRooter.h" />
|
||||||
<ClInclude Include="..\CellArray.h" />
|
<ClInclude Include="..\CellArray.h" />
|
||||||
<ClInclude Include="..\common_logic.h" />
|
<ClInclude Include="..\common_logic.h" />
|
||||||
<ClInclude Include="..\ExtensionSys.h" />
|
|
||||||
<ClInclude Include="..\GameConfigs.h" />
|
<ClInclude Include="..\GameConfigs.h" />
|
||||||
<ClInclude Include="..\intercom.h" />
|
<ClInclude Include="..\intercom.h" />
|
||||||
<ClInclude Include="..\MemoryUtils.h" />
|
<ClInclude Include="..\MemoryUtils.h" />
|
||||||
<ClInclude Include="..\MersenneTwister.h" />
|
<ClInclude Include="..\MersenneTwister.h" />
|
||||||
<ClInclude Include="..\NativeInvoker.h" />
|
|
||||||
<ClInclude Include="..\NativeOwner.h" />
|
|
||||||
<ClInclude Include="..\PhraseCollection.h" />
|
<ClInclude Include="..\PhraseCollection.h" />
|
||||||
<ClInclude Include="..\PluginSys.h" />
|
|
||||||
<ClInclude Include="..\Profiler.h" />
|
<ClInclude Include="..\Profiler.h" />
|
||||||
<ClInclude Include="..\ShareSys.h" />
|
|
||||||
<ClInclude Include="..\sm_crc32.h" />
|
<ClInclude Include="..\sm_crc32.h" />
|
||||||
<ClInclude Include="..\sm_memtable.h" />
|
<ClInclude Include="..\sm_memtable.h" />
|
||||||
<ClInclude Include="..\sm_symtable.h" />
|
<ClInclude Include="..\sm_symtable.h" />
|
||||||
@@ -180,6 +166,9 @@
|
|||||||
<ClInclude Include="..\thread\WinThreads.h" />
|
<ClInclude Include="..\thread\WinThreads.h" />
|
||||||
<ClInclude Include="..\Translator.h" />
|
<ClInclude Include="..\Translator.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ResourceCompile Include="..\version.rc" />
|
||||||
|
</ItemGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Label="ExtensionTargets">
|
<ImportGroup Label="ExtensionTargets">
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
|
|||||||
@@ -117,33 +117,6 @@
|
|||||||
<ClCompile Include="..\smn_textparse.cpp">
|
<ClCompile Include="..\smn_textparse.cpp">
|
||||||
<Filter>Natives</Filter>
|
<Filter>Natives</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\DebugReporter.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\smn_filesystem.cpp">
|
|
||||||
<Filter>Natives</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\smn_fakenatives.cpp">
|
|
||||||
<Filter>Natives</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\ExtensionSys.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\ShareSys.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\PluginSys.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\NativeInvoker.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\NativeOwner.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\HandleSys.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\CellArray.h">
|
<ClInclude Include="..\CellArray.h">
|
||||||
@@ -212,20 +185,10 @@
|
|||||||
<ClInclude Include="..\..\..\public\sm_platform.h">
|
<ClInclude Include="..\..\..\public\sm_platform.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\ExtensionSys.h">
|
</ItemGroup>
|
||||||
<Filter>Header Files</Filter>
|
<ItemGroup>
|
||||||
</ClInclude>
|
<ResourceCompile Include="..\version.rc">
|
||||||
<ClInclude Include="..\NativeInvoker.h">
|
<Filter>Resource Files</Filter>
|
||||||
<Filter>Header Files</Filter>
|
</ResourceCompile>
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\NativeOwner.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\PluginSys.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\ShareSys.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* vim: set ts=4 sw=4 tw=99 noet :
|
* vim: set ts=4 :
|
||||||
* =============================================================================
|
* =============================================================================
|
||||||
* SourceMod
|
* SourceMod
|
||||||
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
||||||
@@ -120,20 +120,13 @@ public:
|
|||||||
*/
|
*/
|
||||||
int AddString(const char *string)
|
int AddString(const char *string)
|
||||||
{
|
{
|
||||||
return AddString(string, strlen(string));
|
size_t len = strlen(string) + 1;
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds a string to the string table and returns its index.
|
|
||||||
*/
|
|
||||||
int AddString(const char *string, size_t length)
|
|
||||||
{
|
|
||||||
size_t len = length + 1;
|
|
||||||
int idx;
|
int idx;
|
||||||
char *addr;
|
char *addr;
|
||||||
|
|
||||||
idx = m_table.CreateMem(len, (void **)&addr);
|
idx = m_table.CreateMem(len, (void **)&addr);
|
||||||
memcpy(addr, string, length + 1);
|
strcpy(addr, string);
|
||||||
|
|
||||||
return idx;
|
return idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -146,7 +139,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Scraps the string table. For caching purposes, the memory
|
* Scraps the string table. For caching purposes, the memory
|
||||||
* is not freed, however subsequent calls to AddString() will
|
* is not freed, however subsequent calls to AddString() will
|
||||||
* begin at the first index again.
|
* begin at the first index again.
|
||||||
*/
|
*/
|
||||||
+186
-187
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* vim: set ts=4 sw=4 tw=99 noet :
|
* vim: set ts=4 :
|
||||||
* =============================================================================
|
* =============================================================================
|
||||||
* SourceMod
|
* SourceMod
|
||||||
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
||||||
@@ -31,140 +31,49 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "common_logic.h"
|
#include "common_logic.h"
|
||||||
#include <am-moveable.h>
|
#include <sm_trie_tpl.h>
|
||||||
#include <am-refcounting.h>
|
|
||||||
#include <sm_stringhashmap.h>
|
|
||||||
#include "sm_memtable.h"
|
|
||||||
|
|
||||||
HandleType_t htCellTrie;
|
HandleType_t htCellTrie;
|
||||||
|
|
||||||
enum EntryType
|
enum TrieNodeType
|
||||||
{
|
{
|
||||||
EntryType_Cell,
|
TrieNode_Cell,
|
||||||
EntryType_CellArray,
|
TrieNode_CellArray,
|
||||||
EntryType_String,
|
TrieNode_String,
|
||||||
};
|
};
|
||||||
|
|
||||||
class Entry
|
struct SmartTrieNode
|
||||||
{
|
{
|
||||||
struct ArrayInfo
|
SmartTrieNode()
|
||||||
{
|
{
|
||||||
size_t length;
|
ptr = NULL;
|
||||||
size_t maxbytes;
|
type = TrieNode_Cell;
|
||||||
|
}
|
||||||
void *base() {
|
SmartTrieNode(const SmartTrieNode &obj)
|
||||||
return this + 1;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
|
||||||
Entry()
|
|
||||||
: control_(0)
|
|
||||||
{
|
{
|
||||||
|
type = obj.type;
|
||||||
|
ptr = obj.ptr;
|
||||||
|
data = obj.data;
|
||||||
|
data_len = obj.data_len;
|
||||||
}
|
}
|
||||||
Entry(ke::Moveable<Entry> other)
|
SmartTrieNode & operator =(const SmartTrieNode &src)
|
||||||
{
|
{
|
||||||
control_ = other->control_;
|
type = src.type;
|
||||||
data_ = other->data_;
|
ptr = src.ptr;
|
||||||
other->control_ = 0;
|
data = src.data;
|
||||||
|
data_len = src.data_len;
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
|
TrieNodeType type;
|
||||||
~Entry()
|
cell_t *ptr;
|
||||||
{
|
cell_t data;
|
||||||
free(raw());
|
cell_t data_len;
|
||||||
}
|
|
||||||
|
|
||||||
void setCell(cell_t value) {
|
|
||||||
setType(EntryType_Cell);
|
|
||||||
data_ = value;
|
|
||||||
}
|
|
||||||
void setArray(cell_t *cells, size_t length) {
|
|
||||||
ArrayInfo *array = ensureArray(length * sizeof(cell_t));
|
|
||||||
array->length = length;
|
|
||||||
memcpy(array->base(), cells, length * sizeof(cell_t));
|
|
||||||
setTypeAndPointer(EntryType_CellArray, array);
|
|
||||||
}
|
|
||||||
void setString(const char *str) {
|
|
||||||
size_t length = strlen(str);
|
|
||||||
ArrayInfo *array = ensureArray(length + 1);
|
|
||||||
array->length = length;
|
|
||||||
strcpy((char *)array->base(), str);
|
|
||||||
setTypeAndPointer(EntryType_String, array);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t arrayLength() const {
|
|
||||||
assert(isArray());
|
|
||||||
return raw()->length;
|
|
||||||
}
|
|
||||||
cell_t *array() const {
|
|
||||||
assert(isArray());
|
|
||||||
return reinterpret_cast<cell_t *>(raw()->base());
|
|
||||||
}
|
|
||||||
char *chars() const {
|
|
||||||
assert(isString());
|
|
||||||
return reinterpret_cast<char *>(raw()->base());
|
|
||||||
}
|
|
||||||
cell_t cell() const {
|
|
||||||
assert(isCell());
|
|
||||||
return data_;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isCell() const {
|
|
||||||
return type() == EntryType_Cell;
|
|
||||||
}
|
|
||||||
bool isArray() const {
|
|
||||||
return type() == EntryType_CellArray;
|
|
||||||
}
|
|
||||||
bool isString() const {
|
|
||||||
return type() == EntryType_String;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
Entry(const Entry &other) KE_DELETE;
|
|
||||||
|
|
||||||
ArrayInfo *ensureArray(size_t bytes) {
|
|
||||||
ArrayInfo *array = raw();
|
|
||||||
if (array && array->maxbytes >= bytes)
|
|
||||||
return array;
|
|
||||||
array = (ArrayInfo *)realloc(array, bytes + sizeof(ArrayInfo));
|
|
||||||
if (!array)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Out of memory!\n");
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
array->maxbytes = bytes;
|
|
||||||
return array;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pointer and type are overlaid, so we have some accessors.
|
|
||||||
ArrayInfo *raw() const {
|
|
||||||
return reinterpret_cast<ArrayInfo *>(control_ & ~uintptr_t(0x3));
|
|
||||||
}
|
|
||||||
void setType(EntryType aType) {
|
|
||||||
control_ = uintptr_t(raw()) | uintptr_t(aType);
|
|
||||||
assert(type() == aType);
|
|
||||||
}
|
|
||||||
void setTypeAndPointer(EntryType aType, ArrayInfo *ptr) {
|
|
||||||
// malloc() should guarantee 8-byte alignment at worst
|
|
||||||
assert((uintptr_t(ptr) & 0x3) == 0);
|
|
||||||
control_ = uintptr_t(ptr) | uintptr_t(aType);
|
|
||||||
assert(type() == aType);
|
|
||||||
}
|
|
||||||
EntryType type() const {
|
|
||||||
return (EntryType)(control_ & 0x3);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
// Contains the bits for the type, and an array pointer, if one is set.
|
|
||||||
uintptr_t control_;
|
|
||||||
|
|
||||||
// Contains data for cell-only entries.
|
|
||||||
cell_t data_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CellTrie : public ke::Refcounted<CellTrie>
|
struct CellTrie
|
||||||
{
|
{
|
||||||
StringHashMap<Entry> map;
|
KTrie<SmartTrieNode> trie;
|
||||||
|
cell_t mem_usage;
|
||||||
};
|
};
|
||||||
|
|
||||||
class TrieHelpers :
|
class TrieHelpers :
|
||||||
@@ -181,21 +90,22 @@ public: //SMGlobalClass
|
|||||||
handlesys->RemoveType(htCellTrie, g_pCoreIdent);
|
handlesys->RemoveType(htCellTrie, g_pCoreIdent);
|
||||||
}
|
}
|
||||||
public: //IHandleTypeDispatch
|
public: //IHandleTypeDispatch
|
||||||
|
static void DestroySmartTrieNode(SmartTrieNode *pNode)
|
||||||
|
{
|
||||||
|
free(pNode->ptr);
|
||||||
|
}
|
||||||
void OnHandleDestroy(HandleType_t type, void *object)
|
void OnHandleDestroy(HandleType_t type, void *object)
|
||||||
{
|
{
|
||||||
if (type == htCellTrie)
|
CellTrie *pTrie = (CellTrie *)object;
|
||||||
{
|
|
||||||
CellTrie *pTrie = (CellTrie *)object;
|
pTrie->trie.run_destructor(DestroySmartTrieNode);
|
||||||
pTrie->Release();
|
|
||||||
}
|
delete pTrie;
|
||||||
}
|
}
|
||||||
bool GetHandleApproxSize(HandleType_t type, void *object, unsigned int *pSize)
|
bool GetHandleApproxSize(HandleType_t type, void *object, unsigned int *pSize)
|
||||||
{
|
{
|
||||||
if (type == htCellTrie)
|
CellTrie *pArray = (CellTrie *)object;
|
||||||
{
|
*pSize = sizeof(CellTrie) + pArray->mem_usage + pArray->trie.mem_usage();
|
||||||
CellTrie *pArray = (CellTrie *)object;
|
|
||||||
*pSize = sizeof(CellTrie) + pArray->map.mem_usage();
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} s_CellTrieHelpers;
|
} s_CellTrieHelpers;
|
||||||
@@ -205,6 +115,8 @@ static cell_t CreateTrie(IPluginContext *pContext, const cell_t *params)
|
|||||||
CellTrie *pTrie = new CellTrie;
|
CellTrie *pTrie = new CellTrie;
|
||||||
Handle_t hndl;
|
Handle_t hndl;
|
||||||
|
|
||||||
|
pTrie->mem_usage = 0;
|
||||||
|
|
||||||
if ((hndl = handlesys->CreateHandle(htCellTrie, pTrie, pContext->GetIdentity(), g_pCoreIdent, NULL))
|
if ((hndl = handlesys->CreateHandle(htCellTrie, pTrie, pContext->GetIdentity(), g_pCoreIdent, NULL))
|
||||||
== BAD_HANDLE)
|
== BAD_HANDLE)
|
||||||
{
|
{
|
||||||
@@ -215,13 +127,67 @@ static cell_t CreateTrie(IPluginContext *pContext, const cell_t *params)
|
|||||||
return hndl;
|
return hndl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void UpdateNodeCells(CellTrie *pTrie, SmartTrieNode *pData, const cell_t *cells, cell_t num_cells)
|
||||||
|
{
|
||||||
|
if (num_cells == 1)
|
||||||
|
{
|
||||||
|
pData->data = *cells;
|
||||||
|
pData->type = TrieNode_Cell;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pData->type = TrieNode_CellArray;
|
||||||
|
if (pData->ptr == NULL)
|
||||||
|
{
|
||||||
|
pData->ptr = (cell_t *)malloc(num_cells * sizeof(cell_t));
|
||||||
|
pData->data_len = num_cells;
|
||||||
|
pTrie->mem_usage += (pData->data_len * sizeof(cell_t));
|
||||||
|
}
|
||||||
|
else if (pData->data_len < num_cells)
|
||||||
|
{
|
||||||
|
pData->ptr = (cell_t *)realloc(pData->ptr, num_cells * sizeof(cell_t));
|
||||||
|
pTrie->mem_usage += (num_cells - pData->data_len) * sizeof(cell_t);
|
||||||
|
pData->data_len = num_cells;
|
||||||
|
}
|
||||||
|
if (num_cells != 0)
|
||||||
|
{
|
||||||
|
memcpy(pData->ptr, cells, sizeof(cell_t) * num_cells);
|
||||||
|
}
|
||||||
|
pData->data = num_cells;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void UpdateNodeString(CellTrie *pTrie, SmartTrieNode *pData, const char *str)
|
||||||
|
{
|
||||||
|
size_t len = strlen(str);
|
||||||
|
cell_t num_cells = (len + sizeof(cell_t)) / sizeof(cell_t);
|
||||||
|
|
||||||
|
if (pData->ptr == NULL)
|
||||||
|
{
|
||||||
|
pData->ptr = (cell_t *)malloc(num_cells * sizeof(cell_t));
|
||||||
|
pData->data_len = num_cells;
|
||||||
|
pTrie->mem_usage += (pData->data_len * sizeof(cell_t));
|
||||||
|
}
|
||||||
|
else if (pData->data_len < num_cells)
|
||||||
|
{
|
||||||
|
pData->ptr = (cell_t *)realloc(pData->ptr, num_cells * sizeof(cell_t));
|
||||||
|
pTrie->mem_usage += (num_cells - pData->data_len) * sizeof(cell_t);
|
||||||
|
pData->data_len = num_cells;
|
||||||
|
}
|
||||||
|
|
||||||
|
strcpy((char *)pData->ptr, str);
|
||||||
|
pData->data = len;
|
||||||
|
pData->type = TrieNode_String;
|
||||||
|
}
|
||||||
|
|
||||||
static cell_t SetTrieValue(IPluginContext *pContext, const cell_t *params)
|
static cell_t SetTrieValue(IPluginContext *pContext, const cell_t *params)
|
||||||
{
|
{
|
||||||
|
Handle_t hndl;
|
||||||
CellTrie *pTrie;
|
CellTrie *pTrie;
|
||||||
HandleError err;
|
HandleError err;
|
||||||
HandleSecurity sec = HandleSecurity(pContext->GetIdentity(), g_pCoreIdent);
|
HandleSecurity sec = HandleSecurity(pContext->GetIdentity(), g_pCoreIdent);
|
||||||
|
|
||||||
Handle_t hndl = params[1];
|
hndl = params[1];
|
||||||
|
|
||||||
if ((err = handlesys->ReadHandle(hndl, htCellTrie, &sec, (void **)&pTrie))
|
if ((err = handlesys->ReadHandle(hndl, htCellTrie, &sec, (void **)&pTrie))
|
||||||
!= HandleError_None)
|
!= HandleError_None)
|
||||||
@@ -232,29 +198,32 @@ static cell_t SetTrieValue(IPluginContext *pContext, const cell_t *params)
|
|||||||
char *key;
|
char *key;
|
||||||
pContext->LocalToString(params[2], &key);
|
pContext->LocalToString(params[2], &key);
|
||||||
|
|
||||||
StringHashMap<Entry>::Insert i = pTrie->map.findForAdd(key);
|
SmartTrieNode *pNode;
|
||||||
if (!i.found())
|
if ((pNode = pTrie->trie.retrieve(key)) == NULL)
|
||||||
{
|
{
|
||||||
if (!pTrie->map.add(i, key))
|
SmartTrieNode node;
|
||||||
return 0;
|
UpdateNodeCells(pTrie, &node, ¶ms[3], 1);
|
||||||
i->value.setCell(params[3]);
|
return pTrie->trie.insert(key, node) ? 1 : 0;
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!params[4])
|
if (!params[4])
|
||||||
|
{
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateNodeCells(pTrie, pNode, ¶ms[3], 1);
|
||||||
|
|
||||||
i->value.setCell(params[3]);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static cell_t SetTrieArray(IPluginContext *pContext, const cell_t *params)
|
static cell_t SetTrieArray(IPluginContext *pContext, const cell_t *params)
|
||||||
{
|
{
|
||||||
|
Handle_t hndl;
|
||||||
CellTrie *pTrie;
|
CellTrie *pTrie;
|
||||||
HandleError err;
|
HandleError err;
|
||||||
HandleSecurity sec = HandleSecurity(pContext->GetIdentity(), g_pCoreIdent);
|
HandleSecurity sec = HandleSecurity(pContext->GetIdentity(), g_pCoreIdent);
|
||||||
|
|
||||||
Handle_t hndl = params[1];
|
hndl = params[1];
|
||||||
|
|
||||||
if ((err = handlesys->ReadHandle(hndl, htCellTrie, &sec, (void **)&pTrie))
|
if ((err = handlesys->ReadHandle(hndl, htCellTrie, &sec, (void **)&pTrie))
|
||||||
!= HandleError_None)
|
!= HandleError_None)
|
||||||
@@ -272,30 +241,37 @@ static cell_t SetTrieArray(IPluginContext *pContext, const cell_t *params)
|
|||||||
pContext->LocalToString(params[2], &key);
|
pContext->LocalToString(params[2], &key);
|
||||||
pContext->LocalToPhysAddr(params[3], &array);
|
pContext->LocalToPhysAddr(params[3], &array);
|
||||||
|
|
||||||
StringHashMap<Entry>::Insert i = pTrie->map.findForAdd(key);
|
SmartTrieNode *pNode;
|
||||||
if (!i.found())
|
if ((pNode = pTrie->trie.retrieve(key)) == NULL)
|
||||||
{
|
{
|
||||||
if (!pTrie->map.add(i, key))
|
SmartTrieNode node;
|
||||||
|
UpdateNodeCells(pTrie, &node, array, params[4]);
|
||||||
|
if (!pTrie->trie.insert(key, node))
|
||||||
|
{
|
||||||
|
free(node.ptr);
|
||||||
return 0;
|
return 0;
|
||||||
i->key = key;
|
}
|
||||||
i->value.setArray(array, params[4]);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!params[5])
|
if (!params[4])
|
||||||
|
{
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateNodeCells(pTrie, pNode, array, params[4]);
|
||||||
|
|
||||||
i->value.setArray(array, params[4]);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static cell_t SetTrieString(IPluginContext *pContext, const cell_t *params)
|
static cell_t SetTrieString(IPluginContext *pContext, const cell_t *params)
|
||||||
{
|
{
|
||||||
|
Handle_t hndl;
|
||||||
CellTrie *pTrie;
|
CellTrie *pTrie;
|
||||||
HandleError err;
|
HandleError err;
|
||||||
HandleSecurity sec = HandleSecurity(pContext->GetIdentity(), g_pCoreIdent);
|
HandleSecurity sec = HandleSecurity(pContext->GetIdentity(), g_pCoreIdent);
|
||||||
|
|
||||||
Handle_t hndl = params[1];
|
hndl = params[1];
|
||||||
|
|
||||||
if ((err = handlesys->ReadHandle(hndl, htCellTrie, &sec, (void **)&pTrie))
|
if ((err = handlesys->ReadHandle(hndl, htCellTrie, &sec, (void **)&pTrie))
|
||||||
!= HandleError_None)
|
!= HandleError_None)
|
||||||
@@ -307,29 +283,37 @@ static cell_t SetTrieString(IPluginContext *pContext, const cell_t *params)
|
|||||||
pContext->LocalToString(params[2], &key);
|
pContext->LocalToString(params[2], &key);
|
||||||
pContext->LocalToString(params[3], &val);
|
pContext->LocalToString(params[3], &val);
|
||||||
|
|
||||||
StringHashMap<Entry>::Insert i = pTrie->map.findForAdd(key);
|
SmartTrieNode *pNode;
|
||||||
if (!i.found())
|
if ((pNode = pTrie->trie.retrieve(key)) == NULL)
|
||||||
{
|
{
|
||||||
if (!pTrie->map.add(i, key))
|
SmartTrieNode node;
|
||||||
|
UpdateNodeString(pTrie, &node, val);
|
||||||
|
if (!pTrie->trie.insert(key, node))
|
||||||
|
{
|
||||||
|
free(node.ptr);
|
||||||
return 0;
|
return 0;
|
||||||
i->value.setString(val);
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!params[4])
|
if (!params[4])
|
||||||
|
{
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateNodeString(pTrie, pNode, val);
|
||||||
|
|
||||||
i->value.setString(val);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static cell_t RemoveFromTrie(IPluginContext *pContext, const cell_t *params)
|
static cell_t RemoveFromTrie(IPluginContext *pContext, const cell_t *params)
|
||||||
{
|
{
|
||||||
|
Handle_t hndl;
|
||||||
CellTrie *pTrie;
|
CellTrie *pTrie;
|
||||||
HandleError err;
|
HandleError err;
|
||||||
HandleSecurity sec = HandleSecurity(pContext->GetIdentity(), g_pCoreIdent);
|
HandleSecurity sec = HandleSecurity(pContext->GetIdentity(), g_pCoreIdent);
|
||||||
|
|
||||||
Handle_t hndl = params[1];
|
hndl = params[1];
|
||||||
|
|
||||||
if ((err = handlesys->ReadHandle(hndl, htCellTrie, &sec, (void **)&pTrie))
|
if ((err = handlesys->ReadHandle(hndl, htCellTrie, &sec, (void **)&pTrie))
|
||||||
!= HandleError_None)
|
!= HandleError_None)
|
||||||
@@ -340,12 +324,16 @@ static cell_t RemoveFromTrie(IPluginContext *pContext, const cell_t *params)
|
|||||||
char *key;
|
char *key;
|
||||||
pContext->LocalToString(params[2], &key);
|
pContext->LocalToString(params[2], &key);
|
||||||
|
|
||||||
StringHashMap<Entry>::Result r = pTrie->map.find(key);
|
SmartTrieNode *pNode;
|
||||||
if (!r.found())
|
if ((pNode = pTrie->trie.retrieve(key)) == NULL)
|
||||||
|
{
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
pTrie->map.remove(r);
|
free(pNode->ptr);
|
||||||
return 1;
|
pNode->ptr = NULL;
|
||||||
|
|
||||||
|
return pTrie->trie.remove(key) ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static cell_t ClearTrie(IPluginContext *pContext, const cell_t *params)
|
static cell_t ClearTrie(IPluginContext *pContext, const cell_t *params)
|
||||||
@@ -363,7 +351,9 @@ static cell_t ClearTrie(IPluginContext *pContext, const cell_t *params)
|
|||||||
return pContext->ThrowNativeError("Invalid Handle %x (error %d)", hndl, err);
|
return pContext->ThrowNativeError("Invalid Handle %x (error %d)", hndl, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
pTrie->map.clear();
|
pTrie->trie.run_destructor(TrieHelpers::DestroySmartTrieNode);
|
||||||
|
pTrie->trie.clear();
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -387,22 +377,15 @@ static cell_t GetTrieValue(IPluginContext *pContext, const cell_t *params)
|
|||||||
pContext->LocalToString(params[2], &key);
|
pContext->LocalToString(params[2], &key);
|
||||||
pContext->LocalToPhysAddr(params[3], &pValue);
|
pContext->LocalToPhysAddr(params[3], &pValue);
|
||||||
|
|
||||||
StringHashMap<Entry>::Result r = pTrie->map.find(key);
|
SmartTrieNode *pNode;
|
||||||
if (!r.found())
|
if ((pNode = pTrie->trie.retrieve(key)) == NULL)
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (r->value.isCell())
|
|
||||||
{
|
{
|
||||||
*pValue = r->value.cell();
|
return 0;
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Maintain compatibility with an old bug. If an array was set with one
|
if (pNode->type == TrieNode_Cell)
|
||||||
// cell, it was stored internally as a single cell. We now store as an
|
|
||||||
// actual array, but we make GetTrieValue() still work for this case.
|
|
||||||
if (r->value.isArray() && r->value.arrayLength() == 1)
|
|
||||||
{
|
{
|
||||||
*pValue = r->value.array()[0];
|
*pValue = pNode->data;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -435,29 +418,34 @@ static cell_t GetTrieArray(IPluginContext *pContext, const cell_t *params)
|
|||||||
pContext->LocalToPhysAddr(params[3], &pValue);
|
pContext->LocalToPhysAddr(params[3], &pValue);
|
||||||
pContext->LocalToPhysAddr(params[5], &pSize);
|
pContext->LocalToPhysAddr(params[5], &pSize);
|
||||||
|
|
||||||
|
SmartTrieNode *pNode;
|
||||||
StringHashMap<Entry>::Result r = pTrie->map.find(key);
|
if ((pNode = pTrie->trie.retrieve(key)) == NULL
|
||||||
if (!r.found() || !r->value.isArray())
|
|| pNode->type != TrieNode_CellArray)
|
||||||
|
{
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (!r->value.array())
|
if (pNode->ptr == NULL)
|
||||||
{
|
{
|
||||||
*pSize = 0;
|
*pSize = 0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!params[4])
|
if (pNode->data > params[4])
|
||||||
return 1;
|
{
|
||||||
|
|
||||||
size_t length = r->value.arrayLength();
|
|
||||||
cell_t *base = r->value.array();
|
|
||||||
|
|
||||||
if (length > size_t(params[4]))
|
|
||||||
*pSize = params[4];
|
*pSize = params[4];
|
||||||
|
}
|
||||||
|
else if (params[4] != 0)
|
||||||
|
{
|
||||||
|
*pSize = pNode->data;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
*pSize = length;
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(pValue, pNode->ptr, sizeof(cell_t) * pSize[0]);
|
||||||
|
|
||||||
memcpy(pValue, base, sizeof(cell_t) * pSize[0]);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -486,14 +474,25 @@ static cell_t GetTrieString(IPluginContext *pContext, const cell_t *params)
|
|||||||
pContext->LocalToString(params[2], &key);
|
pContext->LocalToString(params[2], &key);
|
||||||
pContext->LocalToPhysAddr(params[5], &pSize);
|
pContext->LocalToPhysAddr(params[5], &pSize);
|
||||||
|
|
||||||
StringHashMap<Entry>::Result r = pTrie->map.find(key);
|
SmartTrieNode *pNode;
|
||||||
if (!r.found() || !r->value.isString())
|
if ((pNode = pTrie->trie.retrieve(key)) == NULL
|
||||||
|
|| pNode->type != TrieNode_String)
|
||||||
|
{
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pNode->ptr == NULL)
|
||||||
|
{
|
||||||
|
*pSize = 0;
|
||||||
|
pContext->StringToLocal(params[3], params[4], "");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
size_t written;
|
size_t written;
|
||||||
pContext->StringToLocalUTF8(params[3], params[4], r->value.chars(), &written);
|
pContext->StringToLocalUTF8(params[3], params[4], (char *)pNode->ptr, &written);
|
||||||
|
|
||||||
*pSize = (cell_t)written;
|
*pSize = (cell_t)written;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -512,7 +511,7 @@ static cell_t GetTrieSize(IPluginContext *pContext, const cell_t *params)
|
|||||||
return pContext->ThrowNativeError("Invalid Handle %x (error %d)", hndl, err);
|
return pContext->ThrowNativeError("Invalid Handle %x (error %d)", hndl, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
return pTrie->map.elements();
|
return pTrie->trie.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
REGISTER_NATIVES(trieNatives)
|
REGISTER_NATIVES(trieNatives)
|
||||||
|
|||||||
@@ -1,347 +0,0 @@
|
|||||||
/**
|
|
||||||
* vim: set ts=4 sw=4 tw=99 noet :
|
|
||||||
* =============================================================================
|
|
||||||
* SourceMod
|
|
||||||
* Copyright (C) 2004-2010 AlliedModders LLC. All rights reserved.
|
|
||||||
* =============================================================================
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify it under
|
|
||||||
* the terms of the GNU General Public License, version 3.0, as published by the
|
|
||||||
* Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
||||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
||||||
* details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along with
|
|
||||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* As a special exception, AlliedModders LLC gives you permission to link the
|
|
||||||
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
|
||||||
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
|
||||||
* by the Valve Corporation. You must obey the GNU General Public License in
|
|
||||||
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
|
||||||
* this exception to all derivative works. AlliedModders LLC defines further
|
|
||||||
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
|
||||||
* or <http://www.sourcemod.net/license.php>.
|
|
||||||
*
|
|
||||||
* Version: $Id$
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "common_logic.h"
|
|
||||||
#include "AdminCache.h"
|
|
||||||
#include <IGameHelpers.h>
|
|
||||||
#include <IPlayerHelpers.h>
|
|
||||||
#include <ISourceMod.h>
|
|
||||||
#include <ITranslator.h>
|
|
||||||
|
|
||||||
static cell_t CheckCommandAccess(IPluginContext *pContext, const cell_t *params)
|
|
||||||
{
|
|
||||||
if (params[1] == 0)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *cmd;
|
|
||||||
pContext->LocalToString(params[2], &cmd);
|
|
||||||
|
|
||||||
/* Match up with an admin command if possible */
|
|
||||||
FlagBits bits = params[3];
|
|
||||||
bool found_command = false;
|
|
||||||
if (params[0] < 4 || !params[4])
|
|
||||||
{
|
|
||||||
found_command = smcore.LookForCommandAdminFlags(cmd, &bits);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!found_command)
|
|
||||||
{
|
|
||||||
adminsys->GetCommandOverride(cmd, Override_Command, &bits);
|
|
||||||
}
|
|
||||||
|
|
||||||
return adminsys->CheckClientCommandAccess(params[1], cmd, bits) ? 1 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell_t CheckAccess(IPluginContext *pContext, const cell_t *params)
|
|
||||||
{
|
|
||||||
char *cmd;
|
|
||||||
pContext->LocalToString(params[2], &cmd);
|
|
||||||
|
|
||||||
/* Match up with an admin command if possible */
|
|
||||||
FlagBits bits = params[3];
|
|
||||||
bool found_command = false;
|
|
||||||
if (params[0] < 4 || !params[4])
|
|
||||||
{
|
|
||||||
found_command = smcore.LookForCommandAdminFlags(cmd, &bits);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!found_command)
|
|
||||||
{
|
|
||||||
adminsys->GetCommandOverride(cmd, Override_Command, &bits);
|
|
||||||
}
|
|
||||||
|
|
||||||
return g_Admins.CheckAdminCommandAccess(params[1], cmd, bits) ? 1 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell_t sm_PrintToServer(IPluginContext *pCtx, const cell_t *params)
|
|
||||||
{
|
|
||||||
char buffer[1024];
|
|
||||||
char *fmt;
|
|
||||||
int arg = 2;
|
|
||||||
|
|
||||||
pCtx->LocalToString(params[1], &fmt);
|
|
||||||
size_t res = smcore.atcprintf(buffer, sizeof(buffer) - 2, fmt, pCtx, params, &arg);
|
|
||||||
|
|
||||||
buffer[res++] = '\n';
|
|
||||||
buffer[res] = '\0';
|
|
||||||
|
|
||||||
smcore.ConPrint(buffer);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell_t sm_PrintToConsole(IPluginContext *pCtx, const cell_t *params)
|
|
||||||
{
|
|
||||||
int index = params[1];
|
|
||||||
if ((index < 0) || (index > playerhelpers->GetMaxClients()))
|
|
||||||
{
|
|
||||||
return pCtx->ThrowNativeError("Client index %d is invalid", index);
|
|
||||||
}
|
|
||||||
|
|
||||||
IGamePlayer *pPlayer = NULL;
|
|
||||||
if (index != 0)
|
|
||||||
{
|
|
||||||
pPlayer = playerhelpers->GetGamePlayer(index);
|
|
||||||
if (!pPlayer->IsInGame())
|
|
||||||
{
|
|
||||||
return pCtx->ThrowNativeError("Client %d is not in game", index);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Silent fail on bots, engine will crash */
|
|
||||||
if (pPlayer->IsFakeClient())
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
char buffer[1024];
|
|
||||||
char *fmt;
|
|
||||||
int arg = 3;
|
|
||||||
|
|
||||||
pCtx->LocalToString(params[2], &fmt);
|
|
||||||
size_t res = smcore.atcprintf(buffer, sizeof(buffer) - 2, fmt, pCtx, params, &arg);
|
|
||||||
|
|
||||||
buffer[res++] = '\n';
|
|
||||||
buffer[res] = '\0';
|
|
||||||
|
|
||||||
if (index != 0)
|
|
||||||
{
|
|
||||||
pPlayer->PrintToConsole(buffer);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
smcore.ConPrint(buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell_t sm_ServerCommand(IPluginContext *pContext, const cell_t *params)
|
|
||||||
{
|
|
||||||
g_pSM->SetGlobalTarget(SOURCEMOD_SERVER_LANGUAGE);
|
|
||||||
|
|
||||||
char buffer[1024];
|
|
||||||
size_t len = g_pSM->FormatString(buffer, sizeof(buffer) - 2, pContext, params, 1);
|
|
||||||
|
|
||||||
if (pContext->GetLastNativeError() != SP_ERROR_NONE)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* One byte for null terminator, one for newline */
|
|
||||||
buffer[len++] = '\n';
|
|
||||||
buffer[len] = '\0';
|
|
||||||
|
|
||||||
engine->ServerCommand(buffer);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell_t sm_InsertServerCommand(IPluginContext *pContext, const cell_t *params)
|
|
||||||
{
|
|
||||||
g_pSM->SetGlobalTarget(SOURCEMOD_SERVER_LANGUAGE);
|
|
||||||
|
|
||||||
char buffer[1024];
|
|
||||||
size_t len = g_pSM->FormatString(buffer, sizeof(buffer) - 2, pContext, params, 1);
|
|
||||||
|
|
||||||
if (pContext->GetLastNativeError() != SP_ERROR_NONE)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* One byte for null terminator, one for newline */
|
|
||||||
buffer[len++] = '\n';
|
|
||||||
buffer[len] = '\0';
|
|
||||||
|
|
||||||
engine->InsertServerCommand(buffer);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell_t sm_ServerExecute(IPluginContext *pContext, const cell_t *params)
|
|
||||||
{
|
|
||||||
engine->ServerExecute();
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell_t sm_ClientCommand(IPluginContext *pContext, const cell_t *params)
|
|
||||||
{
|
|
||||||
IGamePlayer *pPlayer = playerhelpers->GetGamePlayer(params[1]);
|
|
||||||
|
|
||||||
if (!pPlayer)
|
|
||||||
{
|
|
||||||
return pContext->ThrowNativeError("Client index %d is invalid", params[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!pPlayer->IsConnected())
|
|
||||||
{
|
|
||||||
return pContext->ThrowNativeError("Client %d is not connected", params[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
g_pSM->SetGlobalTarget(params[1]);
|
|
||||||
|
|
||||||
char buffer[256];
|
|
||||||
g_pSM->FormatString(buffer, sizeof(buffer), pContext, params, 2);
|
|
||||||
|
|
||||||
if (pContext->GetLastNativeError() != SP_ERROR_NONE)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
engine->ClientCommand(pPlayer->GetEdict(), buffer);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell_t FakeClientCommand(IPluginContext *pContext, const cell_t *params)
|
|
||||||
{
|
|
||||||
IGamePlayer *pPlayer = playerhelpers->GetGamePlayer(params[1]);
|
|
||||||
|
|
||||||
if (!pPlayer)
|
|
||||||
{
|
|
||||||
return pContext->ThrowNativeError("Client index %d is invalid", params[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!pPlayer->IsConnected())
|
|
||||||
{
|
|
||||||
return pContext->ThrowNativeError("Client %d is not connected", params[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
g_pSM->SetGlobalTarget(params[1]);
|
|
||||||
|
|
||||||
char buffer[256];
|
|
||||||
g_pSM->FormatString(buffer, sizeof(buffer), pContext, params, 2);
|
|
||||||
|
|
||||||
if (pContext->GetLastNativeError() != SP_ERROR_NONE)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
engine->FakeClientCommand(pPlayer->GetEdict(), buffer);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell_t ReplyToCommand(IPluginContext *pContext, const cell_t *params)
|
|
||||||
{
|
|
||||||
g_pSM->SetGlobalTarget(params[1]);
|
|
||||||
|
|
||||||
/* Build the format string */
|
|
||||||
char buffer[1024];
|
|
||||||
size_t len = g_pSM->FormatString(buffer, sizeof(buffer) - 2, pContext, params, 2);
|
|
||||||
|
|
||||||
if (pContext->GetLastNativeError() != SP_ERROR_NONE)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If we're printing to the server, shortcut out */
|
|
||||||
if (params[1] == 0)
|
|
||||||
{
|
|
||||||
/* Print */
|
|
||||||
buffer[len++] = '\n';
|
|
||||||
buffer[len] = '\0';
|
|
||||||
smcore.ConPrint(buffer);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
IGamePlayer *pPlayer = playerhelpers->GetGamePlayer(params[1]);
|
|
||||||
|
|
||||||
if (!pPlayer)
|
|
||||||
{
|
|
||||||
return pContext->ThrowNativeError("Client index %d is invalid", params[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!pPlayer->IsConnected())
|
|
||||||
{
|
|
||||||
return pContext->ThrowNativeError("Client %d is not connected", params[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int replyto = playerhelpers->GetReplyTo();
|
|
||||||
if (replyto == SM_REPLY_CONSOLE)
|
|
||||||
{
|
|
||||||
buffer[len++] = '\n';
|
|
||||||
buffer[len] = '\0';
|
|
||||||
pPlayer->PrintToConsole(buffer);
|
|
||||||
}
|
|
||||||
else if (replyto == SM_REPLY_CHAT) {
|
|
||||||
if (len >= 191)
|
|
||||||
{
|
|
||||||
len = 191;
|
|
||||||
}
|
|
||||||
buffer[len] = '\0';
|
|
||||||
gamehelpers->TextMsg(params[1], TEXTMSG_DEST_CHAT, buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell_t GetCmdReplyTarget(IPluginContext *pContext, const cell_t *params)
|
|
||||||
{
|
|
||||||
return playerhelpers->GetReplyTo();
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell_t SetCmdReplyTarget(IPluginContext *pContext, const cell_t *params)
|
|
||||||
{
|
|
||||||
return playerhelpers->SetReplyTo(params[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell_t AddServerTag(IPluginContext *pContext, const cell_t *params)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell_t RemoveServerTag(IPluginContext *pContext, const cell_t *params)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
REGISTER_NATIVES(consoleNatives)
|
|
||||||
{
|
|
||||||
{"CheckCommandAccess", CheckCommandAccess},
|
|
||||||
{"CheckAccess", CheckAccess},
|
|
||||||
{"PrintToServer", sm_PrintToServer},
|
|
||||||
{"PrintToConsole", sm_PrintToConsole},
|
|
||||||
{"ServerCommand", sm_ServerCommand},
|
|
||||||
{"InsertServerCommand", sm_InsertServerCommand},
|
|
||||||
{"ServerExecute", sm_ServerExecute},
|
|
||||||
{"ClientCommand", sm_ClientCommand},
|
|
||||||
{"FakeClientCommand", FakeClientCommand},
|
|
||||||
{"ReplyToCommand", ReplyToCommand},
|
|
||||||
{"GetCmdReplySource", GetCmdReplyTarget},
|
|
||||||
{"SetCmdReplySource", SetCmdReplyTarget},
|
|
||||||
{"AddServerTag", AddServerTag},
|
|
||||||
{"RemoveServerTag", RemoveServerTag},
|
|
||||||
{NULL, NULL}
|
|
||||||
};
|
|
||||||
@@ -35,7 +35,6 @@
|
|||||||
#include "common_logic.h"
|
#include "common_logic.h"
|
||||||
#include "MersenneTwister.h"
|
#include "MersenneTwister.h"
|
||||||
#include <IPluginSys.h>
|
#include <IPluginSys.h>
|
||||||
#include <am-utility.h>
|
|
||||||
|
|
||||||
/****************************************
|
/****************************************
|
||||||
* *
|
* *
|
||||||
@@ -87,44 +86,6 @@ static cell_t sm_FloatDiv(IPluginContext *pCtx, const cell_t *params)
|
|||||||
return sp_ftoc(val);
|
return sp_ftoc(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
static cell_t sm_FloatGt(IPluginContext *pCtx, const cell_t *params)
|
|
||||||
{
|
|
||||||
return !!(sp_ctof(params[1]) > sp_ctof(params[2]));
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell_t sm_FloatGe(IPluginContext *pCtx, const cell_t *params)
|
|
||||||
{
|
|
||||||
return !!(sp_ctof(params[1]) >= sp_ctof(params[2]));
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell_t sm_FloatLt(IPluginContext *pCtx, const cell_t *params)
|
|
||||||
{
|
|
||||||
return !!(sp_ctof(params[1]) < sp_ctof(params[2]));
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell_t sm_FloatLe(IPluginContext *pCtx, const cell_t *params)
|
|
||||||
{
|
|
||||||
return !!(sp_ctof(params[1]) <= sp_ctof(params[2]));
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell_t sm_FloatEq(IPluginContext *pCtx, const cell_t *params)
|
|
||||||
{
|
|
||||||
return !!(sp_ctof(params[1]) == sp_ctof(params[2]));
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell_t sm_FloatNe(IPluginContext *pCtx, const cell_t *params)
|
|
||||||
{
|
|
||||||
return !!(sp_ctof(params[1]) != sp_ctof(params[2]));
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell_t sm_FloatNot(IPluginContext *pCtx, const cell_t *params)
|
|
||||||
{
|
|
||||||
float val = sp_ctof(params[1]);
|
|
||||||
if (ke::IsNaN(val))
|
|
||||||
return 1;
|
|
||||||
return val ? 0 : 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell_t sm_FloatCompare(IPluginContext *pCtx, const cell_t *params)
|
static cell_t sm_FloatCompare(IPluginContext *pCtx, const cell_t *params)
|
||||||
{
|
{
|
||||||
float val1 = sp_ctof(params[1]);
|
float val1 = sp_ctof(params[1]);
|
||||||
@@ -400,13 +361,6 @@ REGISTER_NATIVES(floatnatives)
|
|||||||
{"RoundToCeil", sm_RoundToCeil},
|
{"RoundToCeil", sm_RoundToCeil},
|
||||||
{"RoundToFloor", sm_RoundToFloor},
|
{"RoundToFloor", sm_RoundToFloor},
|
||||||
{"RoundToNearest", sm_RoundToNearest},
|
{"RoundToNearest", sm_RoundToNearest},
|
||||||
{"__FLOAT_GT__", sm_FloatGt},
|
|
||||||
{"__FLOAT_GE__", sm_FloatGe},
|
|
||||||
{"__FLOAT_LT__", sm_FloatLt},
|
|
||||||
{"__FLOAT_LE__", sm_FloatLe},
|
|
||||||
{"__FLOAT_EQ__", sm_FloatEq},
|
|
||||||
{"__FLOAT_NE__", sm_FloatNe},
|
|
||||||
{"__FLOAT_NOT__", sm_FloatNot},
|
|
||||||
{"FloatCompare", sm_FloatCompare},
|
{"FloatCompare", sm_FloatCompare},
|
||||||
{"SquareRoot", sm_SquareRoot},
|
{"SquareRoot", sm_SquareRoot},
|
||||||
{"Pow", sm_Pow},
|
{"Pow", sm_Pow},
|
||||||
|
|||||||
@@ -33,8 +33,6 @@
|
|||||||
#include <IPluginSys.h>
|
#include <IPluginSys.h>
|
||||||
#include <IHandleSys.h>
|
#include <IHandleSys.h>
|
||||||
#include <IForwardSys.h>
|
#include <IForwardSys.h>
|
||||||
#include <ISourceMod.h>
|
|
||||||
#include <am-utility.h>
|
|
||||||
|
|
||||||
HandleType_t g_GlobalFwdType = 0;
|
HandleType_t g_GlobalFwdType = 0;
|
||||||
HandleType_t g_PrivateFwdType = 0;
|
HandleType_t g_PrivateFwdType = 0;
|
||||||
@@ -189,9 +187,8 @@ static cell_t sm_GetForwardFunctionCount(IPluginContext *pContext, const cell_t
|
|||||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||||
HandleError err;
|
HandleError err;
|
||||||
IForward *pForward;
|
IForward *pForward;
|
||||||
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
|
|
||||||
|
|
||||||
if ((err=handlesys->ReadHandle(hndl, g_GlobalFwdType, &sec, (void **)&pForward))
|
if ((err=handlesys->ReadHandle(hndl, g_GlobalFwdType, NULL, (void **)&pForward))
|
||||||
!= HandleError_None)
|
!= HandleError_None)
|
||||||
{
|
{
|
||||||
return pContext->ThrowNativeError("Invalid forward handle %x (error %d)", hndl, err);
|
return pContext->ThrowNativeError("Invalid forward handle %x (error %d)", hndl, err);
|
||||||
@@ -207,9 +204,8 @@ static cell_t sm_AddToForward(IPluginContext *pContext, const cell_t *params)
|
|||||||
HandleError err;
|
HandleError err;
|
||||||
IChangeableForward *pForward;
|
IChangeableForward *pForward;
|
||||||
IPlugin *pPlugin;
|
IPlugin *pPlugin;
|
||||||
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
|
|
||||||
|
|
||||||
if ((err=handlesys->ReadHandle(fwdHandle, g_PrivateFwdType, &sec, (void **)&pForward))
|
if ((err=handlesys->ReadHandle(fwdHandle, g_PrivateFwdType, NULL, (void **)&pForward))
|
||||||
!= HandleError_None)
|
!= HandleError_None)
|
||||||
{
|
{
|
||||||
return pContext->ThrowNativeError("Invalid private forward handle %x (error %d)", fwdHandle, err);
|
return pContext->ThrowNativeError("Invalid private forward handle %x (error %d)", fwdHandle, err);
|
||||||
@@ -244,9 +240,8 @@ static cell_t sm_RemoveFromForward(IPluginContext *pContext, const cell_t *param
|
|||||||
HandleError err;
|
HandleError err;
|
||||||
IChangeableForward *pForward;
|
IChangeableForward *pForward;
|
||||||
IPlugin *pPlugin;
|
IPlugin *pPlugin;
|
||||||
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
|
|
||||||
|
|
||||||
if ((err=handlesys->ReadHandle(fwdHandle, g_PrivateFwdType, &sec, (void **)&pForward))
|
if ((err=handlesys->ReadHandle(fwdHandle, g_PrivateFwdType, NULL, (void **)&pForward))
|
||||||
!= HandleError_None)
|
!= HandleError_None)
|
||||||
{
|
{
|
||||||
return pContext->ThrowNativeError("Invalid private forward handle %x (error %d)", fwdHandle, err);
|
return pContext->ThrowNativeError("Invalid private forward handle %x (error %d)", fwdHandle, err);
|
||||||
@@ -281,9 +276,8 @@ static cell_t sm_RemoveAllFromForward(IPluginContext *pContext, const cell_t *pa
|
|||||||
HandleError err;
|
HandleError err;
|
||||||
IChangeableForward *pForward;
|
IChangeableForward *pForward;
|
||||||
IPlugin *pPlugin;
|
IPlugin *pPlugin;
|
||||||
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
|
|
||||||
|
|
||||||
if ((err=handlesys->ReadHandle(fwdHandle, g_PrivateFwdType, &sec, (void **)&pForward))
|
if ((err=handlesys->ReadHandle(fwdHandle, g_PrivateFwdType, NULL, (void **)&pForward))
|
||||||
!= HandleError_None)
|
!= HandleError_None)
|
||||||
{
|
{
|
||||||
return pContext->ThrowNativeError("Invalid private forward handle %x (error %d)", fwdHandle, err);
|
return pContext->ThrowNativeError("Invalid private forward handle %x (error %d)", fwdHandle, err);
|
||||||
@@ -345,13 +339,12 @@ static cell_t sm_CallStartForward(IPluginContext *pContext, const cell_t *params
|
|||||||
Handle_t hndl;
|
Handle_t hndl;
|
||||||
HandleError err;
|
HandleError err;
|
||||||
IForward *pForward;
|
IForward *pForward;
|
||||||
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
|
|
||||||
|
|
||||||
ResetCall();
|
ResetCall();
|
||||||
|
|
||||||
hndl = static_cast<Handle_t>(params[1]);
|
hndl = static_cast<Handle_t>(params[1]);
|
||||||
|
|
||||||
if ((err=handlesys->ReadHandle(hndl, g_GlobalFwdType, &sec, (void **)&pForward))
|
if ((err=handlesys->ReadHandle(hndl, g_GlobalFwdType, NULL, (void **)&pForward))
|
||||||
!= HandleError_None)
|
!= HandleError_None)
|
||||||
{
|
{
|
||||||
return pContext->ThrowNativeError("Invalid forward handle %x (error %d)", hndl, err);
|
return pContext->ThrowNativeError("Invalid forward handle %x (error %d)", hndl, err);
|
||||||
@@ -591,63 +584,6 @@ static cell_t sm_CallCancel(IPluginContext *pContext, const cell_t *params)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SMFrameActionData
|
|
||||||
{
|
|
||||||
SMFrameActionData(Handle_t handle, Handle_t ownerhandle, cell_t data) : handle(handle), ownerhandle(ownerhandle), data(data)
|
|
||||||
{
|
|
||||||
};
|
|
||||||
Handle_t handle;
|
|
||||||
Handle_t ownerhandle;
|
|
||||||
cell_t data;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void PawnFrameAction(void *pData)
|
|
||||||
{
|
|
||||||
ke::AutoPtr<SMFrameActionData> frame(reinterpret_cast<SMFrameActionData *>(pData));
|
|
||||||
IPlugin *pPlugin = pluginsys->PluginFromHandle(frame->ownerhandle, NULL);
|
|
||||||
if (!pPlugin)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
IChangeableForward *pForward;
|
|
||||||
HandleSecurity sec(pPlugin->GetIdentity(), g_pCoreIdent);
|
|
||||||
if (handlesys->ReadHandle(frame->handle, g_PrivateFwdType, &sec, (void **)&pForward) != HandleError_None)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
pForward->PushCell(frame->data);
|
|
||||||
pForward->Execute(NULL);
|
|
||||||
|
|
||||||
handlesys->FreeHandle(frame->handle, &sec);
|
|
||||||
}
|
|
||||||
|
|
||||||
static cell_t sm_AddFrameAction(IPluginContext *pContext, const cell_t *params)
|
|
||||||
{
|
|
||||||
IPlugin *pPlugin = pluginsys->FindPluginByContext(pContext->GetContext());
|
|
||||||
IPluginFunction *pFunction = pPlugin->GetBaseContext()->GetFunctionById(params[1]);
|
|
||||||
if (!pFunction)
|
|
||||||
{
|
|
||||||
return pContext->ThrowNativeError("Invalid function id (%X)", params[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
IChangeableForward *pForward = forwardsys->CreateForwardEx(NULL, ET_Ignore, 1, NULL, Param_Cell);
|
|
||||||
IdentityToken_t *pIdentity = pContext->GetIdentity();
|
|
||||||
Handle_t Handle = handlesys->CreateHandle(g_PrivateFwdType, pForward, pIdentity, g_pCoreIdent, NULL);
|
|
||||||
if (Handle == BAD_HANDLE)
|
|
||||||
{
|
|
||||||
forwardsys->ReleaseForward(pForward);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
pForward->AddFunction(pFunction);
|
|
||||||
|
|
||||||
SMFrameActionData *pData = new SMFrameActionData(Handle, pPlugin->GetMyHandle(), params[2]);
|
|
||||||
g_pSM->AddFrameAction(PawnFrameAction, pData);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
REGISTER_NATIVES(functionNatives)
|
REGISTER_NATIVES(functionNatives)
|
||||||
{
|
{
|
||||||
{"GetFunctionByName", sm_GetFunctionByName},
|
{"GetFunctionByName", sm_GetFunctionByName},
|
||||||
@@ -669,6 +605,5 @@ REGISTER_NATIVES(functionNatives)
|
|||||||
{"Call_PushStringEx", sm_CallPushStringEx},
|
{"Call_PushStringEx", sm_CallPushStringEx},
|
||||||
{"Call_Finish", sm_CallFinish},
|
{"Call_Finish", sm_CallFinish},
|
||||||
{"Call_Cancel", sm_CallCancel},
|
{"Call_Cancel", sm_CallCancel},
|
||||||
{"RequestFrame", sm_AddFrameAction},
|
|
||||||
{NULL, NULL},
|
{NULL, NULL},
|
||||||
};
|
};
|
||||||
|
|||||||
+53
-45
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* vim: set ts=4 sw=4 tw=99 noet :
|
* vim: set ts=4 :
|
||||||
* =============================================================================
|
* =============================================================================
|
||||||
* SourceMod
|
* SourceMod
|
||||||
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
||||||
@@ -30,7 +30,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sh_list.h>
|
#include <sh_list.h>
|
||||||
#include <sm_namehashset.h>
|
#include <sm_trie_tpl.h>
|
||||||
#include "common_logic.h"
|
#include "common_logic.h"
|
||||||
#include "CellArray.h"
|
#include "CellArray.h"
|
||||||
#include <IGameHelpers.h>
|
#include <IGameHelpers.h>
|
||||||
@@ -50,11 +50,6 @@ struct maplist_info_t
|
|||||||
time_t last_modified_time;
|
time_t last_modified_time;
|
||||||
CellArray *pArray;
|
CellArray *pArray;
|
||||||
int serial;
|
int serial;
|
||||||
|
|
||||||
static inline bool matches(const char *key, const maplist_info_t *value)
|
|
||||||
{
|
|
||||||
return strcmp(value->name, key) == 0;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MAPLIST_FLAG_MAPSFOLDER (1<<0) /**< On failure, use all maps in the maps folder. */
|
#define MAPLIST_FLAG_MAPSFOLDER (1<<0) /**< On failure, use all maps in the maps folder. */
|
||||||
@@ -94,29 +89,44 @@ public:
|
|||||||
|| strcmp(pEngineName, "dods") == 0 || strcmp(pEngineName, "hl2dm") == 0)
|
|| strcmp(pEngineName, "dods") == 0 || strcmp(pEngineName, "hl2dm") == 0)
|
||||||
{
|
{
|
||||||
// These four games and Source SDK 2013 do a lookup in this order; so shall we.
|
// These four games and Source SDK 2013 do a lookup in this order; so shall we.
|
||||||
g_pSM->Format(pBuffer, maxlen, "cfg/%s", pMapCycleFileName);
|
g_pSM->BuildPath(Path_Game,
|
||||||
|
pBuffer,
|
||||||
|
maxlen,
|
||||||
|
"cfg/%s",
|
||||||
|
pMapCycleFileName);
|
||||||
|
|
||||||
if (!smcore.filesystem->FileExists(pBuffer, "GAME"))
|
if (!libsys->PathExists(pBuffer))
|
||||||
{
|
{
|
||||||
g_pSM->Format(pBuffer, maxlen, "%s", pMapCycleFileName);
|
g_pSM->BuildPath(Path_Game,
|
||||||
|
pBuffer,
|
||||||
|
maxlen,
|
||||||
|
"%s",
|
||||||
|
pMapCycleFileName);
|
||||||
|
|
||||||
if (!smcore.filesystem->FileExists(pBuffer, "GAME"))
|
if (!libsys->PathExists(pBuffer))
|
||||||
{
|
{
|
||||||
g_pSM->Format(pBuffer, maxlen, "cfg/mapcycle_default.txt");
|
g_pSM->BuildPath(Path_Game,
|
||||||
|
pBuffer,
|
||||||
|
maxlen,
|
||||||
|
"cfg/mapcycle_default.txt");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
g_pSM->Format(pBuffer, maxlen, "%s", pMapCycleFileName);
|
g_pSM->BuildPath(Path_Game,
|
||||||
|
pBuffer,
|
||||||
|
maxlen,
|
||||||
|
"%s",
|
||||||
|
pMapCycleFileName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void AddOrUpdateDefault(const char *name, const char *file)
|
void AddOrUpdateDefault(const char *name, const char *file)
|
||||||
{
|
{
|
||||||
char path[PLATFORM_MAX_PATH];
|
char path[PLATFORM_MAX_PATH];
|
||||||
maplist_info_t *pMapList;
|
maplist_info_t *pMapList, **ppMapList;
|
||||||
|
|
||||||
if (!m_ListLookup.retrieve(name, &pMapList))
|
if ((ppMapList = m_ListLookup.retrieve(name)) == NULL)
|
||||||
{
|
{
|
||||||
pMapList = new maplist_info_t;
|
pMapList = new maplist_info_t;
|
||||||
pMapList->bIsCompat = true;
|
pMapList->bIsCompat = true;
|
||||||
@@ -124,22 +134,28 @@ public:
|
|||||||
pMapList->last_modified_time = 0;
|
pMapList->last_modified_time = 0;
|
||||||
smcore.strncopy(pMapList->name, name, sizeof(pMapList->name));
|
smcore.strncopy(pMapList->name, name, sizeof(pMapList->name));
|
||||||
pMapList->pArray = NULL;
|
pMapList->pArray = NULL;
|
||||||
smcore.strncopy(pMapList->path, file, sizeof(pMapList->path));
|
g_pSM->BuildPath(Path_Game, pMapList->path, sizeof(pMapList->path), "%s", file);
|
||||||
pMapList->serial = 0;
|
pMapList->serial = 0;
|
||||||
m_ListLookup.insert(name, pMapList);
|
m_ListLookup.insert(name, pMapList);
|
||||||
m_MapLists.push_back(pMapList);
|
m_MapLists.push_back(pMapList);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pMapList = *ppMapList;
|
||||||
|
|
||||||
/* Don't modify if it's from the config file */
|
/* Don't modify if it's from the config file */
|
||||||
if (!pMapList->bIsCompat)
|
if (!pMapList->bIsCompat)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
smcore.strncopy(path, file, sizeof(path));
|
g_pSM->BuildPath(Path_Game, path, sizeof(path), "%s", file);
|
||||||
|
|
||||||
/* If the path matches, don't reset the serial/time */
|
/* If the path matches, don't reset the serial/time */
|
||||||
if (strcmp(path, pMapList->path) == 0)
|
if (strcmp(path, pMapList->path) == 0)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
smcore.strncopy(pMapList->path, path, sizeof(pMapList->path));
|
smcore.strncopy(pMapList->path, path, sizeof(pMapList->path));
|
||||||
pMapList->bIsPath = true;
|
pMapList->bIsPath = true;
|
||||||
@@ -214,7 +230,7 @@ public:
|
|||||||
List<maplist_info_t *>::iterator iter = compat.begin();
|
List<maplist_info_t *>::iterator iter = compat.begin();
|
||||||
while (iter != compat.end())
|
while (iter != compat.end())
|
||||||
{
|
{
|
||||||
if (m_ListLookup.contains((*iter)->name))
|
if (m_ListLookup.retrieve((*iter)->name) != NULL)
|
||||||
{
|
{
|
||||||
/* The compatibility shim is no longer needed. */
|
/* The compatibility shim is no longer needed. */
|
||||||
delete (*iter)->pArray;
|
delete (*iter)->pArray;
|
||||||
@@ -278,7 +294,11 @@ public:
|
|||||||
|
|
||||||
if (strcmp(key, "file") == 0)
|
if (strcmp(key, "file") == 0)
|
||||||
{
|
{
|
||||||
smcore.strncopy(m_pCurMapList->path, value, sizeof(m_pCurMapList->path));
|
g_pSM->BuildPath(Path_Game,
|
||||||
|
m_pCurMapList->path,
|
||||||
|
sizeof(m_pCurMapList->path),
|
||||||
|
"%s",
|
||||||
|
value);
|
||||||
m_pCurMapList->bIsPath = true;
|
m_pCurMapList->bIsPath = true;
|
||||||
}
|
}
|
||||||
else if (strcmp(key, "target") == 0)
|
else if (strcmp(key, "target") == 0)
|
||||||
@@ -301,7 +321,7 @@ public:
|
|||||||
{
|
{
|
||||||
if (m_pCurMapList != NULL
|
if (m_pCurMapList != NULL
|
||||||
&& m_pCurMapList->path[0] != '\0'
|
&& m_pCurMapList->path[0] != '\0'
|
||||||
&& !m_ListLookup.contains(m_pCurMapList->name))
|
&& m_ListLookup.retrieve(m_pCurMapList->name) == NULL)
|
||||||
{
|
{
|
||||||
m_ListLookup.insert(m_pCurMapList->name, m_pCurMapList);
|
m_ListLookup.insert(m_pCurMapList->name, m_pCurMapList);
|
||||||
m_MapLists.push_back(m_pCurMapList);
|
m_MapLists.push_back(m_pCurMapList);
|
||||||
@@ -470,13 +490,19 @@ private:
|
|||||||
bool GetMapList(CellArray **ppArray, const char *name, int *pSerial)
|
bool GetMapList(CellArray **ppArray, const char *name, int *pSerial)
|
||||||
{
|
{
|
||||||
time_t last_time;
|
time_t last_time;
|
||||||
maplist_info_t *pMapList;
|
maplist_info_t *pMapList, **ppMapList;
|
||||||
|
|
||||||
if (!m_ListLookup.retrieve(name, &pMapList))
|
if ((ppMapList = m_ListLookup.retrieve(name)) == NULL)
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
pMapList = *ppMapList;
|
||||||
|
|
||||||
if (!pMapList->bIsPath)
|
if (!pMapList->bIsPath)
|
||||||
|
{
|
||||||
return GetMapList(ppArray, pMapList->path, pSerial);
|
return GetMapList(ppArray, pMapList->path, pSerial);
|
||||||
|
}
|
||||||
|
|
||||||
/* If it is a path, and the path is "*", assume all files must be used. */
|
/* If it is a path, and the path is "*", assume all files must be used. */
|
||||||
if (strcmp(pMapList->path, "*") == 0)
|
if (strcmp(pMapList->path, "*") == 0)
|
||||||
@@ -501,11 +527,11 @@ private:
|
|||||||
|| last_time > pMapList->last_modified_time)
|
|| last_time > pMapList->last_modified_time)
|
||||||
{
|
{
|
||||||
/* Reparse */
|
/* Reparse */
|
||||||
FileHandle_t fp;
|
FILE *fp;
|
||||||
cell_t *blk;
|
cell_t *blk;
|
||||||
char buffer[255];
|
char buffer[255];
|
||||||
|
|
||||||
if ((fp = smcore.filesystem->Open(pMapList->path, "rt", "GAME")) == NULL)
|
if ((fp = fopen(pMapList->path, "rt")) == NULL)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -513,7 +539,7 @@ private:
|
|||||||
delete pMapList->pArray;
|
delete pMapList->pArray;
|
||||||
pMapList->pArray = new CellArray(64);
|
pMapList->pArray = new CellArray(64);
|
||||||
|
|
||||||
while (!smcore.filesystem->EndOfFile(fp) && smcore.filesystem->ReadLine(buffer, sizeof(buffer), fp) != NULL)
|
while (!feof(fp) && fgets(buffer, sizeof(buffer), fp) != NULL)
|
||||||
{
|
{
|
||||||
size_t len = strlen(buffer);
|
size_t len = strlen(buffer);
|
||||||
char *ptr = smcore.TrimWhitespace(buffer, len);
|
char *ptr = smcore.TrimWhitespace(buffer, len);
|
||||||
@@ -523,35 +549,17 @@ private:
|
|||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(smcore.GetSourceEngineName(), "insurgency") == 0)
|
|
||||||
{
|
|
||||||
// Insurgency (presumably?) doesn't allow spaces in map names
|
|
||||||
// and does use a space to delimit the map name from the map mode
|
|
||||||
int i = 0;
|
|
||||||
while (ptr[i] != 0)
|
|
||||||
{
|
|
||||||
if (ptr[i] == ' ')
|
|
||||||
{
|
|
||||||
ptr[i] = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!gamehelpers->IsMapValid(ptr))
|
if (!gamehelpers->IsMapValid(ptr))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((blk = pMapList->pArray->push()) != NULL)
|
if ((blk = pMapList->pArray->push()) != NULL)
|
||||||
{
|
{
|
||||||
smcore.strncopy((char *)blk, ptr, 255);
|
smcore.strncopy((char *)blk, ptr, 255);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
smcore.filesystem->Close(fp);
|
fclose(fp);
|
||||||
|
|
||||||
pMapList->last_modified_time = last_time;
|
pMapList->last_modified_time = last_time;
|
||||||
pMapList->serial = ++m_nSerialChange;
|
pMapList->serial = ++m_nSerialChange;
|
||||||
@@ -590,7 +598,7 @@ private:
|
|||||||
char m_ConfigFile[PLATFORM_MAX_PATH];
|
char m_ConfigFile[PLATFORM_MAX_PATH];
|
||||||
time_t m_ConfigLastChanged;
|
time_t m_ConfigLastChanged;
|
||||||
ConVar *m_pMapCycleFile;
|
ConVar *m_pMapCycleFile;
|
||||||
NameHashSet<maplist_info_t *> m_ListLookup;
|
KTrie<maplist_info_t *> m_ListLookup;
|
||||||
List<maplist_info_t *> m_MapLists;
|
List<maplist_info_t *> m_MapLists;
|
||||||
MapListState m_CurState;
|
MapListState m_CurState;
|
||||||
unsigned int m_IgnoreLevel;
|
unsigned int m_IgnoreLevel;
|
||||||
|
|||||||
+1
-1353
File diff suppressed because it is too large
Load Diff
@@ -122,7 +122,7 @@ static cell_t sm_strconvint(IPluginContext *pCtx, const cell_t *params)
|
|||||||
char *str, *dummy;
|
char *str, *dummy;
|
||||||
pCtx->LocalToString(params[1], &str);
|
pCtx->LocalToString(params[1], &str);
|
||||||
|
|
||||||
return static_cast<cell_t>(strtoul(str, &dummy, params[2]));
|
return static_cast<cell_t>(strtol(str, &dummy, params[2]));
|
||||||
}
|
}
|
||||||
|
|
||||||
static cell_t StringToIntEx(IPluginContext *pCtx, const cell_t *params)
|
static cell_t StringToIntEx(IPluginContext *pCtx, const cell_t *params)
|
||||||
@@ -132,7 +132,7 @@ static cell_t StringToIntEx(IPluginContext *pCtx, const cell_t *params)
|
|||||||
pCtx->LocalToString(params[1], &str);
|
pCtx->LocalToString(params[1], &str);
|
||||||
pCtx->LocalToPhysAddr(params[2], &addr);
|
pCtx->LocalToPhysAddr(params[2], &addr);
|
||||||
|
|
||||||
*addr = static_cast<cell_t>(strtoul(str, &dummy, params[3]));
|
*addr = static_cast<cell_t>(strtol(str, &dummy, params[3]));
|
||||||
|
|
||||||
return dummy - str;
|
return dummy - str;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -202,9 +202,8 @@ static cell_t SMC_SetParseStart(IPluginContext *pContext, const cell_t *params)
|
|||||||
Handle_t hndl = (Handle_t)params[1];
|
Handle_t hndl = (Handle_t)params[1];
|
||||||
HandleError err;
|
HandleError err;
|
||||||
ParseInfo *parse;
|
ParseInfo *parse;
|
||||||
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
|
|
||||||
|
|
||||||
if ((err=handlesys->ReadHandle(hndl, g_TypeSMC, &sec, (void **)&parse))
|
if ((err=handlesys->ReadHandle(hndl, g_TypeSMC, NULL, (void **)&parse))
|
||||||
!= HandleError_None)
|
!= HandleError_None)
|
||||||
{
|
{
|
||||||
return pContext->ThrowNativeError("Invalid SMC Parse Handle %x (error %d)", hndl, err);
|
return pContext->ThrowNativeError("Invalid SMC Parse Handle %x (error %d)", hndl, err);
|
||||||
@@ -220,9 +219,8 @@ static cell_t SMC_SetParseEnd(IPluginContext *pContext, const cell_t *params)
|
|||||||
Handle_t hndl = (Handle_t)params[1];
|
Handle_t hndl = (Handle_t)params[1];
|
||||||
HandleError err;
|
HandleError err;
|
||||||
ParseInfo *parse;
|
ParseInfo *parse;
|
||||||
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
|
|
||||||
|
|
||||||
if ((err=handlesys->ReadHandle(hndl, g_TypeSMC, &sec, (void **)&parse))
|
if ((err=handlesys->ReadHandle(hndl, g_TypeSMC, NULL, (void **)&parse))
|
||||||
!= HandleError_None)
|
!= HandleError_None)
|
||||||
{
|
{
|
||||||
return pContext->ThrowNativeError("Invalid SMC Parse Handle %x (error %d)", hndl, err);
|
return pContext->ThrowNativeError("Invalid SMC Parse Handle %x (error %d)", hndl, err);
|
||||||
@@ -238,9 +236,8 @@ static cell_t SMC_SetReaders(IPluginContext *pContext, const cell_t *params)
|
|||||||
Handle_t hndl = (Handle_t)params[1];
|
Handle_t hndl = (Handle_t)params[1];
|
||||||
HandleError err;
|
HandleError err;
|
||||||
ParseInfo *parse;
|
ParseInfo *parse;
|
||||||
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
|
|
||||||
|
|
||||||
if ((err=handlesys->ReadHandle(hndl, g_TypeSMC, &sec, (void **)&parse))
|
if ((err=handlesys->ReadHandle(hndl, g_TypeSMC, NULL, (void **)&parse))
|
||||||
!= HandleError_None)
|
!= HandleError_None)
|
||||||
{
|
{
|
||||||
return pContext->ThrowNativeError("Invalid SMC Parse Handle %x (error %d)", hndl, err);
|
return pContext->ThrowNativeError("Invalid SMC Parse Handle %x (error %d)", hndl, err);
|
||||||
@@ -258,9 +255,8 @@ static cell_t SMC_SetRawLine(IPluginContext *pContext, const cell_t *params)
|
|||||||
Handle_t hndl = (Handle_t)params[1];
|
Handle_t hndl = (Handle_t)params[1];
|
||||||
HandleError err;
|
HandleError err;
|
||||||
ParseInfo *parse;
|
ParseInfo *parse;
|
||||||
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
|
|
||||||
|
|
||||||
if ((err=handlesys->ReadHandle(hndl, g_TypeSMC, &sec, (void **)&parse))
|
if ((err=handlesys->ReadHandle(hndl, g_TypeSMC, NULL, (void **)&parse))
|
||||||
!= HandleError_None)
|
!= HandleError_None)
|
||||||
{
|
{
|
||||||
return pContext->ThrowNativeError("Invalid SMC Parse Handle %x (error %d)", hndl, err);
|
return pContext->ThrowNativeError("Invalid SMC Parse Handle %x (error %d)", hndl, err);
|
||||||
@@ -276,9 +272,8 @@ static cell_t SMC_ParseFile(IPluginContext *pContext, const cell_t *params)
|
|||||||
Handle_t hndl = (Handle_t)params[1];
|
Handle_t hndl = (Handle_t)params[1];
|
||||||
HandleError err;
|
HandleError err;
|
||||||
ParseInfo *parse;
|
ParseInfo *parse;
|
||||||
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
|
|
||||||
|
|
||||||
if ((err=handlesys->ReadHandle(hndl, g_TypeSMC, &sec, (void **)&parse))
|
if ((err=handlesys->ReadHandle(hndl, g_TypeSMC, NULL, (void **)&parse))
|
||||||
!= HandleError_None)
|
!= HandleError_None)
|
||||||
{
|
{
|
||||||
return pContext->ThrowNativeError("Invalid SMC Parse Handle %x (error %d)", hndl, err);
|
return pContext->ThrowNativeError("Invalid SMC Parse Handle %x (error %d)", hndl, err);
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user