987 Commits

Author SHA1 Message Date
16b7c37d24 Tagged 1.75 2006-07-19 09:23:18 +00:00
0c668753fb fixed bug where indenter unindented the entire code
menu generator: now checks for bad menu keys (simple menu, old style)
2006-06-30 21:25:26 +00:00
2edbf72391 fixed bug where indenter unindented the entire code 2006-06-30 21:23:26 +00:00
e1caa575e7 now checks for bad menu keys (simple menu, old style) 2006-06-30 21:22:46 +00:00
9dcdba439a added fix for binlog bug with failed plugins
added experimental emsg natives
fixed target's velbyaim bug find
added native for setting player curweapon
2006-06-28 10:07:20 +00:00
d3af14c957 experimental emsg natives 2006-06-28 10:01:55 +00:00
f08bbbc45f dep recompile 2006-06-28 02:31:07 +00:00
99a2b54530 fixed small bug in the documents bar 2006-06-15 00:43:09 +00:00
6f20664140 Wow 2006-06-12 21:08:29 +00:00
06fbff7042 fixed floattocell bug, omg 2006-06-12 17:37:09 +00:00
bb609123fb Fixed comment next to zoom type enum 2006-06-12 10:08:54 +00:00
d832eb8fef fixed this up 2006-06-12 08:20:35 +00:00
fd67b07530 whoa, changes from twisty-san 2006-06-12 06:14:35 +00:00
c0396bf140 updated for another test 2006-06-12 06:12:46 +00:00
d55542aa8d fourth time's a charm 2006-06-11 22:04:10 +00:00
2e86f51cfe fixed this 2006-06-11 21:50:19 +00:00
Zor
84ec8ef007 - Added new forwards as well as new stocks 2006-06-11 21:47:11 +00:00
07e55f3b71 whoa 2006-06-11 09:01:30 +00:00
50311d14fb fixed bug at31100 (belsebub) 2006-06-11 08:58:15 +00:00
1088b209d9 added belsebub's test 2006-06-11 08:57:39 +00:00
63ec26f8c0 committed menu tester 2006-06-11 07:59:07 +00:00
07b5a819bf fixed more amx_ftoc errors that wouldn't occur in modules 2006-06-11 07:32:18 +00:00
8e03e67a8f fixed a menu exit calculation bug in newmenus (omg) 2006-06-10 22:12:46 +00:00
66d04f8def fixed another possible amx_ftoc() misusage 2006-06-10 21:00:33 +00:00
bce69e7116 fixed pcvar bug (thanks niluje) 2006-06-10 20:57:52 +00:00
d4bfddc034 added 2 new natives 2006-06-10 20:46:12 +00:00
373d25b0ce Removed some unnecessary code at31046 2006-06-10 14:38:04 +00:00
deb1b00416 synced fix 2006-06-10 01:34:27 +00:00
6b80e9e8d2 fixed a silly row bug 2006-06-09 08:47:52 +00:00
a19b00fd2f moved some hud messages to avoid more overlapping 2006-06-07 23:22:43 +00:00
8f2c9e9452 moved up imessage a bit 2006-06-07 23:11:45 +00:00
5463a84c12 fixed another stupid path bug
fixed more module loading bugs
2006-06-07 19:09:48 +00:00
68e1937a5c got rid of debug msg 2006-06-07 06:28:32 +00:00
d05c34b73c fixed a bug causing failed modules to register as successes. this also blocked handlers from being called. 2006-06-07 05:21:03 +00:00
c69777d8cc fixed stupid path bugs! 2006-06-07 04:44:03 +00:00
b3b9e72b01 fixed another newmenu calc bug 2006-06-06 17:59:38 +00:00
7f57e8377a oh, compiles now 2006-06-06 10:49:33 +00:00
036ab78828 added plugin semi-auto-loading shut it 2006-06-06 09:03:07 +00:00
e0f1a93d6e fixed a bug where an empty modules file would crash
fixed a bug where newmenu with default exit and a single page would not return MENU_EXIT on exit
2006-06-06 07:00:27 +00:00
eba189e2b9 fixed erroneous error message 2006-06-06 00:29:05 +00:00
5748ed84a2 oh, updated 2006-06-05 23:28:28 +00:00
9eb0d50f4c yams 2006-06-05 23:22:57 +00:00
24c5c10a31 oh, hello 2006-06-05 23:22:45 +00:00
c91f712363 some bugfixes and changes for the ftp panel 2006-06-05 23:20:59 +00:00
f6c9263940 Argh, did it again didn't I 2006-06-05 22:33:22 +00:00
ba87258a3d Added admin indentifier (red asterisk) to all menus that contain a user list at30358 2006-06-05 22:32:00 +00:00
011c9fa45c fixed "ghost module" problem 2006-06-05 19:19:43 +00:00
2c7ca33bf1 fixed a bug where HandleModule() took the mangled name instead of the demangled 2006-06-05 19:08:01 +00:00
2ece53fa38 fixed a bug where plmenu autoloaded cstrike 2006-06-05 19:07:19 +00:00
36ec7bc818 fixed a very minor parsing bug in plugins.ini 2006-06-05 18:48:01 +00:00
b4450bbee5 synced this change 2006-06-05 18:43:01 +00:00
c92145ee88 backwards compat fixes -
dbi_close() must return 0 on failure (not that it matters)
dbi_nextrow() must return 0 on RESULT_NONE
2006-06-05 08:21:28 +00:00
3fbf65103a fixed a crash bug 2006-06-05 08:06:57 +00:00
e7858b4cd7 Oops, guess I forgot this one 2006-06-05 07:52:21 +00:00
ad495cef13 Updated for vector.inc 2006-06-05 07:50:42 +00:00
17fb06f7bb Moved vector natives from engine to core at29896
Moved precache_generic from engine to core at30469
2006-06-05 07:48:54 +00:00
7d3ddf502c Synced MSVC8 project file 2006-06-05 05:29:26 +00:00
5940b4a6ca MSVC8 warning fix 2006-06-05 05:24:59 +00:00
9edf20866b Synced MSVC8 project file 2006-06-05 05:18:27 +00:00
30495aa34e Linking to zlib isn't necessary 2006-06-05 05:07:52 +00:00
45b8383eb9 lang sync (added bulgarian and l33t) 2006-06-04 23:49:47 +00:00
56e97a2b60 updated this t00 2006-06-04 19:42:08 +00:00
9857731dff removed x from sql names 2006-06-04 19:41:37 +00:00
915c3d244c merged in mysqlx fixes 2006-06-04 19:40:34 +00:00
24cdcde968 fixed heap corruption
improved memory usage
removed useless stringpooler
2006-06-04 19:26:43 +00:00
cef005317b wow I'm tired 2006-06-04 09:28:45 +00:00
1035c35c03 *** empty log message *** 2006-06-04 08:57:52 +00:00
2210c54d68 fixed 64bit bugz 2006-06-04 08:57:20 +00:00
e546c69041 fixed linux bug 2006-06-04 08:40:27 +00:00
36268f04d9 latest compiler builds 2006-06-04 08:10:14 +00:00
3fe24d8793 fixed some build problems 2006-06-04 07:49:07 +00:00
b3a91bc496 fixed a build error on gcc 2006-06-04 07:44:55 +00:00
8a529b100c or this 2006-06-04 07:42:46 +00:00
f1f683dca7 gcc didn't like this 2006-06-04 07:42:10 +00:00
afb8fb0019 fixed linux build 2006-06-04 07:37:44 +00:00
fb904f6e40 Linux build works now 2006-06-04 07:35:33 +00:00
73858b0fcd removed packing stuff 2006-06-04 06:43:48 +00:00
a5bd69ac4a MSVC8 project file fixed and updated 2006-06-04 04:35:53 +00:00
c6e17539ca zomg fixed warnings again o_O 2006-06-04 04:29:46 +00:00
e0b05c0b83 Yeah another possible warning fix perhaps 2006-06-04 03:59:14 +00:00
a44eb16360 MSVC8 fixes again, what the heck did I do before? o_O 2006-06-04 03:57:45 +00:00
fc429213d3 whoabug 2006-06-04 02:10:04 +00:00
80cbaa8217 updated these, reorg'd a tad 2006-06-04 01:55:47 +00:00
170dbcaaa9 whoa 2006-06-04 01:54:07 +00:00
7c1da54412 omgcommitted 2006-06-04 01:46:24 +00:00
c508f17bfe added sqlite3 db binary 2006-06-04 01:43:58 +00:00
1cdbfb50ad my test sql file 2006-06-04 01:40:42 +00:00
579cc83d54 this was broken too. make sure it builds next time ;) 2006-06-04 01:36:18 +00:00
be7bf671af sooomeooone broke the geoip build. 2006-06-04 01:31:31 +00:00
e1b9543d10 added these k 2006-06-04 01:22:10 +00:00
af8dea753e removed this SUCKA 2006-06-04 01:14:33 +00:00
d0d08800ef what 2006-06-04 01:05:20 +00:00
dafc10d878 added some more sqlx stocks
upgraded admin.sma to sqlx
fixed various amx_Addadmin bugs
2006-06-04 00:58:17 +00:00
ad0eafe66a fix for memory leak[?] 2006-06-04 00:29:27 +00:00
5ffb38b5bc fixed invalid pathnames passed to CacheAndLoadModules causing auto load not to work 2006-06-04 00:22:59 +00:00
b363b16d61 Added test suite, included sqlxtests 2006-06-03 23:51:11 +00:00
5522778aed fixed registerfuncex never actually registering
fixed requestfunc returning null when not querying
2006-06-03 23:14:09 +00:00
3a7d291513 fixed wrong aff ret val
updated sdk
2006-06-03 23:13:22 +00:00
fe603c29f0 fixed wrong aff return val 2006-06-03 23:13:02 +00:00
27ba10c8a0 fixed a reporting bug 2006-06-03 23:02:18 +00:00
34f5b3257d attempted some thread improvements[?]
fixed moduleconf bug
what
2006-06-03 22:26:43 +00:00
7367f29cb4 fixed a bug where defclasslib would search for lib instead of class 2006-06-03 21:44:35 +00:00
fc5e049e4a expanded MF_OverrideNatives API function a bit, to exclude named module(s) 2006-06-03 21:34:43 +00:00
1c2749fdf6 removed old sdk 2006-06-03 19:52:49 +00:00
aa1308e32e initial import of sqlitex 2006-06-03 19:52:21 +00:00
3cde89bc74 Don't look please 2006-06-03 19:45:03 +00:00
75b6aa192d Wowzers, fixed :\ 2006-06-03 19:41:36 +00:00
43ecf97f99 fixed spelling mistake 2006-06-03 19:29:29 +00:00
4ca564540e bumped version number to 1.75 2006-06-03 13:17:48 +00:00
c8d543929a Updated to June 2006-06-03 08:33:30 +00:00
e7e87ff040 updated to sqlite-3.3.5 2006-06-02 21:29:25 +00:00
ab40f426c6 Added missing colon at30601 2006-06-02 02:18:15 +00:00
7ecdf75d0d fixed typo 2006-05-26 22:08:52 +00:00
e6064af9fb added request at30290 (VEN)
fixed cs_get_user_buyzone returning true when user was in bombtarget zone or other specific areas
2006-05-26 18:26:59 +00:00
44a7b62963 possible fix at29931 2006-05-23 19:35:40 +00:00
ac1e3a9001 Added ClientPrintf engine function (request at30137) 2006-05-23 03:26:26 +00:00
7e36a19590 committed fix for bug atDIVINE (kami no buggu) 2006-05-22 00:00:11 +00:00
6af5516005 added request at26380 (KWo) 2006-05-21 22:02:22 +00:00
444e2caa68 fixed yet another bug 2006-05-19 22:09:43 +00:00
3d932c8a36 Removed take_damage at29909 2006-05-19 19:00:35 +00:00
2e63e1316c fixed bug at29945 2006-05-19 18:40:17 +00:00
b4a77512ae Fixed bug that didn't allow users to use "non-email accounts" for listen+dedicated server installations 2006-05-19 18:37:03 +00:00
b40f5e6637 request at29928
New callable engine function: AlertMessage
2006-05-19 06:01:55 +00:00
e0bed163ac added affinity stuff 2006-05-19 02:04:09 +00:00
bce3bce586 Added amx_ReRegister() and MNF_RegisterFunctionEx() 2006-05-19 01:54:51 +00:00
f9c9088303 added affinity implementation 2006-05-19 01:54:28 +00:00
9bbb0df492 fixed bug at29731 2006-05-18 16:18:14 +00:00
eafd402ead fixed *slaps himself* 2006-05-18 15:55:21 +00:00
cf9cdaa3d6 zomg, I guess I should move these too 2006-05-17 20:23:36 +00:00
a993ba159a Updated for message_const.inc 2006-05-17 20:14:36 +00:00
2d75dfe865 Even more include file changes...
1) Moved message_begin, message_end, and write_ natives to messages.inc
2) Moved MSG constants to message_const.inc
All completely backwards compatible with compiling older plugins of course :)
2006-05-17 20:08:04 +00:00
635b681825 Gah, nothing to say about this one 2006-05-17 19:37:34 +00:00
ef1347cb6c Oh, hello, one more constant 2006-05-17 19:36:42 +00:00
c0334deae1 Added a whole bunch of constants at29843
Some minor changes to some other inc files that aren't even worth mentioning
2006-05-17 19:33:45 +00:00
39a22813cb updated comment 2006-05-17 14:03:59 +00:00
d01d6b06fa little fix 2006-05-17 13:44:58 +00:00
6cb6ef9c84 updated for hlsdk_const 2006-05-16 21:45:33 +00:00
b953f285d0 Tended to request at29593 2006-05-16 21:42:06 +00:00
dc785a4369 Fixed bug at29628 2006-05-16 21:20:14 +00:00
a7de50a4bb fixed problem at29669 2006-05-16 21:15:41 +00:00
00fd007e7a fixed bug at29654 2006-05-16 21:08:19 +00:00
b6007e8223 Modified get_brush_entity_origin and ViewContents as per at29759 (Orangutanz) 2006-05-15 13:52:38 +00:00
25a2b11198 oh hello PM, here is another optimization 2006-05-14 15:59:28 +00:00
a0923e21ed improved using pm's magic (patent pending) 2006-05-14 15:20:25 +00:00
f51620c2d7 fixed worst bug ever 2006-05-13 20:49:37 +00:00
1370305fb0 Exactly why was all that old stuff there? o_O
(Hope I did the right thing, as I usually do the wrong thing here, err)
2006-05-13 15:57:33 +00:00
f7805623b0 added request at29591 2006-05-13 14:59:24 +00:00
9a34c7931a fixed bug at29636 2006-05-13 12:15:16 +00:00
b67e6c5269 Hello MSVC8 project. I'm just removing some files from you this time. Won't hurt one bit. 2006-05-12 04:55:54 +00:00
5e4d5a2c8f Hello MSVC8 project, may I update you? 2006-05-12 04:52:36 +00:00
567044c381 fixed indenter bug (I swear I fixed this bug years ago!) 2006-05-11 16:03:18 +00:00
b2b001c9e4 added M_ in front to match HLSDK and other things 2006-05-11 13:12:41 +00:00
793de6d8d2 added PI define (at29548) 2006-05-11 13:10:29 +00:00
d862f23929 Attempt for fix of bug at28381 2006-05-11 13:04:37 +00:00
f8809e2663 Fixed a backwards compatibility issue with free result 2006-05-11 12:11:42 +00:00
19f2be0c96 updated 2006-05-11 10:22:18 +00:00
6995b182c1 failsafe autoloading of libraries for 1.71- plugins 2006-05-11 10:19:09 +00:00
79f86bfabd updated comment 2006-05-11 10:07:32 +00:00
035c54350e module filter is expanded a tiny bit 2006-05-11 10:05:42 +00:00
d0a61ef581 Added request at28865 2006-05-11 08:55:29 +00:00
123215a53c removed these, no longer needed 2006-05-11 08:47:53 +00:00
9b68c0678a merged register_message into core
request at29428
2006-05-11 08:45:06 +00:00
e0fa5227d6 merged register_message into core 2006-05-11 08:36:20 +00:00
441ab14d3b moved register_message into core, yay 2006-05-11 08:35:21 +00:00
ed6e28c1d4 removed message functions from engine [!] 2006-05-11 07:49:45 +00:00
77f0e526bf Whoa. SetClientKeyValue fixed :\ 2006-05-11 03:34:13 +00:00
30ce0d9f1b Another pointless typo fix 2006-05-11 02:29:08 +00:00
8920a05bba mov gah, [newline_fix] 2006-05-10 14:38:11 +00:00
061da07af8 Yet another wondeful typo fix 2006-05-10 13:26:36 +00:00
da757b6c62 Um, ignore me please. Nothing to see here. Move along. 2006-05-10 13:25:29 +00:00
880b83a10b Typo fix! :o 2006-05-10 13:24:31 +00:00
76c1c78b5b up up and awayyy 2006-05-10 13:02:37 +00:00
afe19411b2 oh I forgot to commit this, basic-master-san 2006-05-10 12:40:44 +00:00
b2aff10e46 Added some comments to benefit all mankind :o 2006-05-10 12:35:21 +00:00
4e1123730c fixed lib class 2006-05-10 12:29:37 +00:00
8e3a5e6d58 sdk v4 2006-05-10 12:00:22 +00:00
beb975bdbf ohmygod like the modules are synced and updated for sdk v4 2006-05-10 11:53:22 +00:00
302b759fc8 oops :( 2006-05-10 11:31:17 +00:00
c6e8a356ee Added request at29487
1) New hookable Engine func: GetInfoKeyBuffer
2) New GameDLL func that can be called via engfunc: GetInfoKeyBuffer
3) New native: copy_infokey_buffer that copies data out of the specified info key buffer
4) EngFunc_InfoKeyValue, EngFunc_SetKeyValue, and EngFunc_SetClientKeyValue have been reworked
    so that they expect pointers to an info key buffer in order to work properly o_O
2006-05-10 11:28:00 +00:00
b12025093b added ability to override natives (someone shoot me) 2006-05-10 11:23:08 +00:00
de1f1eef8d Added request at29487
1) New hookable Engine func: GetInfoKeyBuffer
2) New GameDLL func that can be called via engfunc: GetInfoKeyBuffer
3) New native: copy_infokey_buffer that copies data out of the specified info key buffer
4) EngFunc_InfoKeyValue, EngFunc_SetKeyValue, and EngFunc_SetClientKeyValue have been reworked
    so that they expect pointers to an info key buffer in order to work properly o_O
5) Added some error messages to get_tr
2006-05-10 11:19:24 +00:00
25d4b6aea3 added these include files k 2006-05-10 10:42:49 +00:00
f9fd83b42e test commit of new sdk 2006-05-10 07:49:05 +00:00
1e6ba05ec9 corrected some changes for inclusion into base 2006-05-10 07:42:35 +00:00
dd7529b42c Fixed a bug where three of the new pragmas parsed spaces wrong 2006-05-10 04:51:07 +00:00
cfb36025b5 builds of latest compiler sources, and version bumped 2006-05-10 04:48:19 +00:00
f5cabb4bea fixed infinite loop (oops) 2006-05-10 04:44:07 +00:00
58209dfb37 Added fix for __DATE__, added __TIME__
Added tag table crap for new autoloading feature
Version bump
2006-05-10 03:44:35 +00:00
a29f8d0651 Cleaned up error reporting a bit 2006-05-10 03:43:53 +00:00
f600a96657 Initial massive import of the new code module auto-loading code
Important difference - pubtags table is used instead of library table!
2006-05-10 02:32:34 +00:00
d8c8e72745 Committed fix for bug at29456 2006-05-09 23:43:06 +00:00
9a34213992 Committed rebuild of ASM stuff for bug at29456 2006-05-09 23:43:05 +00:00
67d4c5ccad bumped version 2006-05-09 22:47:16 +00:00
6b794d4a9d Version bump 2006-05-08 04:37:15 +00:00
ca3e8582e3 Added missing files to MSVC8 project (libraries.h and libraries.cpp)
Fixed some MSVC8 errors with new files
Bumped version
2006-05-08 04:13:37 +00:00
7669ab02f6 fixed prototype error 2006-05-08 00:26:32 +00:00
c6f8749242 real fix for memleak 2006-05-07 22:21:06 +00:00
6ee7930a46 experimental fix for memleak 2006-05-07 21:59:57 +00:00
f2c5a2b85b updated to new module API 2006-05-07 21:40:12 +00:00
37151d361f added layout for "plugin cache"
dynamic natives that are paused now pause parent plugin with an error
added catch for a potentially serious bug?
2006-05-07 21:16:00 +00:00
974e8882b9 detach zOMG 2006-05-07 20:07:57 +00:00
9b9f0d0e27 fixed small typo 2006-05-07 17:27:24 +00:00
0a4a209f94 corrected commit 2006-05-07 17:11:17 +00:00
603be35426 test of new module API, should work though 2006-05-07 10:10:44 +00:00
92645db291 Synced in new modules.ini format 2006-05-07 10:09:04 +00:00
00e32aca97 added a little more flexibility to modules.ini
fixed bug where unloading was never called
2006-05-07 10:05:04 +00:00
dad00a2eb6 Initial import of replacement Library system - Backwards compat tested!
Updated new SDK (bumped vers number, kept backwards compat)
Improved module path resolving
2006-05-07 09:56:06 +00:00
576680eaf9 Added vformat() native 2006-05-07 00:25:43 +00:00
7a533c7be5 Added vformat() 2006-05-07 00:25:30 +00:00
4e5ada6ad1 added request at28200 2006-05-06 22:49:38 +00:00
a9f300bca9 Version bumpage for every module except MySQL/MySQLX (as I'm unsure of the status of those at the moment) 2006-05-06 04:57:10 +00:00
8fec829c63 Version bump in AMX_VERSION define (since version.rc was bumped) 2006-05-06 04:49:36 +00:00
f3fe58809d changes so forward ids can be mapped back to names 2006-05-06 02:03:25 +00:00
c6d16eac7a version bump 2006-05-05 18:31:27 +00:00
d7e53d7a81 Err, more descriptive param names? 2006-05-05 08:30:16 +00:00
26ee3955b6 Another one of my stupid clarifications that shouldn't break anything (I hope...) 2006-05-05 08:27:58 +00:00
21ffd88bdd More bugs?
1) FM_CreateInstancedBaselines has been renamed to FM_CreateInstBaselines
2) DLLFunc_CreateInstancedBaseline has been renamed to DLLFunc_CreateInstBaselines
(I'd be extremely surprised if someone complained about the above 2 changes)
3) New hookable GameDLL func: FM_CreateBaseline
4) New hookable Engine func: FM_CreateInstBaseline
5) New GameDLL func that can be called via dllfunc: CreateBaseline
6) New GameDLL func that can be called via engfunc: CreateInstancedBaseline
7) Added some comments to each member of various enums that correspond to special structs in the engine and/or game dll
2006-05-05 08:07:31 +00:00
ed19c53552 More bugs?
1) New hookable GameDLL func: CreateBaseline
2) New hookable Engine func: CreateInstancedBaseline
3) New GameDLL func that can be called via dllfunc: CreateBaseline
4) New GameDLL func that can be called via engfunc: CreateInstancedBaseline
2006-05-05 08:04:19 +00:00
133c7d6815 Fixed possible crash bug in get_tr2 at29250 (Orangutanz) 2006-05-05 05:11:17 +00:00
7cd10e4796 Another param change that I seemed to have missed... should be no problem 2006-05-04 22:39:23 +00:00
ecd2d913e4 Err, gah... native one being changed didn't really matter 2006-05-04 22:12:16 +00:00
53e84a13be gah 2006-05-04 22:10:23 +00:00
eb55e1f4aa i prefix changed to ent because it looks nicer indeed 2006-05-04 19:59:05 +00:00
dc063594de Not sure why I decided to potentially crash the server with cs_set_user_vip o_O
Stayed tuned for another episode of "What Was DS Thinking?"
2006-05-04 05:32:45 +00:00
f26d208c38 Updated to May 2006-05-03 07:12:01 +00:00
6cc239c66f Two extra params in cs_set_user_vip for determining whether or not model and scoreboard are updated at28699
Version bumpage
2006-05-02 21:49:17 +00:00
6733ef9a79 Two extra params in cs_set_user_vip for determining whether or not model and scoreboard are updated at28699 2006-05-02 21:48:26 +00:00
7dc4beae63 Removed set_user_deaths from inc file at29080
(Doesn't seem to be any easy general way to implement it)
2006-05-01 05:25:28 +00:00
de33bb6a1d Oh goodness, let the bugs begin...
1) New hookable GameDLL funcs: UpdateClientData, AddToFullPack, CmdStart, CmdEnd (at28754)
2) New GameDLL funcs that can be called via dllfunc: UpdateClientData, AddToFullPack, CmdStart, CmdEnd
3) New natives to read/write special data structures associated with the above GameDLL funcs:
   get/set_cd (ClientData), get/set_es (EntityState), get/set_uc (UserCmd)
2006-04-30 07:37:31 +00:00
7883710bf6 Added pm_shared to include directories so this can compile on Linux again 2006-04-30 07:28:39 +00:00
0071d73e25 Oh goodness, let the bugs begin...
1) Fixed getting incorrect value of the entity index when using ClientUserInfoChanged via dllfunc
2) New hookable GameDLL funcs: UpdateClientData, AddToFullPack, CmdStart, CmdEnd (at28754)
3) New GameDLL funcs that can be called via dllfunc: UpdateClientData, AddToFullPack, CmdStart, CmdEnd
4) New natives to read/write special data structures associated with the above GameDLL funcs
2006-04-30 07:27:14 +00:00
0555e7aa63 fixed MM warning 2006-04-29 13:51:52 +00:00
ddda9c9118 Fixed weird close bug 2006-04-29 10:20:41 +00:00
d2b57d29fb untested fix for issue where hooks were not released on server deactivate - only on plugin load 2006-04-29 07:23:23 +00:00
d78ec24679 fixed bug when registering plugin_(un)pause forward 2006-04-28 22:51:40 +00:00
e5057d7191 cell upcasting (second revision) 2006-04-28 21:30:17 +00:00
f10ecbb239 Small bug fix and tiny optimizations in xs_get_maxmessages and xs_is_msg_valid
Added xs_vec_maked2d (at28754)
2006-04-28 21:10:29 +00:00
229b149247 cell upcasting (second revision) 2006-04-28 20:14:08 +00:00
1f8b9a8cd9 Renamed FM_ClientInfoChanged to FM_ClientUserInfoChanged for consistency with DLLFunc_ClientUserInfoChanged
(Also goes along with fix made in FakeMeta module itself, sort of :|)
2006-04-28 20:10:42 +00:00
6000fe43d1 Fixed ClientUserInfoChanged forward not being reset on mapchange 2006-04-28 20:07:53 +00:00
5a2e35c1bf Fixed is_in_viewcone always returning 0
Fixed is_visible causing a crash when a non-player entity was passed and also made it quite a bit more accurate
(at28936)
2006-04-28 19:19:24 +00:00
62c096d7d3 updated comment as per at28188 2006-04-27 17:41:41 +00:00
f6cb8ab3bb fixed typo (at28930) 2006-04-27 17:31:55 +00:00
8da4987895 implemented request at28875 2006-04-27 17:31:38 +00:00
38cb60c60b Eh hem. This shouldn't have been bumped quite yet :( 2006-04-27 03:57:33 +00:00
a87966cde3 Oops (again) 2006-04-27 00:07:36 +00:00
9b252fa919 Oops :( 2006-04-27 00:04:52 +00:00
760514a1fe Makefile now in sync with the others (I think)
(This is mostly for cleaning fixes. Please give me a better idea)
2006-04-27 00:02:54 +00:00
2ca42b7b21 MSVC8 Project File + SDK Update 2006-04-26 23:54:12 +00:00
b65b8a1cf0 request at28581 2006-04-26 05:21:29 +00:00
e96eaa6174 Fixed small error 2006-04-26 05:18:26 +00:00
2a74d2229f commit for fix to a deadlock which would occur when stopping a live, queue'd thread worker 2006-04-25 20:41:18 +00:00
3f5bae615b added request at28199 2006-04-25 17:19:58 +00:00
96854aefa7 now allows you to teleport yourself (request by jpt10181) 2006-04-25 15:14:54 +00:00
697f63f2e9 fixed small modified bug
fixed another tiny bug (default author+default name weren't equal if you created a new plugin if the settings.ini wasn't found)
2006-04-25 14:51:13 +00:00
98a1d2b3da added fast read+write
fixed modified bug for the notes
2006-04-25 14:24:21 +00:00
2c541f338c Now shows if a document has been modified in the documents tab bar 2006-04-25 13:16:43 +00:00
9dccde4567 Fixed bug with ClientUserInfoChanged forward at28782
Also bumped version
2006-04-25 09:08:11 +00:00
47408443f7 Fixed bug with ClientUserInfoChanged forward at28782 (Orangutanz)
Also bumped version
2006-04-25 09:08:11 +00:00
f673e641f3 Fixed issue where hostname could be retrieved too early if it was set in server.cfg;
thereby having an incorrect hostname if %hostname% was used in the message

Also, if the hostname cvar changes at any time before a map change occurs, then %hostname% should be replaced with the new value
2006-04-25 07:35:02 +00:00
1f44f5f481 fixed some return stuff 2006-04-24 15:14:34 +00:00
94d4380f39 renamed logtag to deal with stupid system 2006-04-24 11:59:22 +00:00
5adc7021e4 fixed project for release builds 2006-04-24 11:22:24 +00:00
14db579540 added more tests 2006-04-24 11:13:17 +00:00
3aebbd7173 Restored linux compat 2006-04-24 10:31:37 +00:00
1c5b8670d9 added backwards compat layer to old mysql module 2006-04-24 10:27:25 +00:00
768880fa92 leprechaun ! 2006-04-24 07:33:09 +00:00
114a6fe19d added linux support [untested] 2006-04-24 07:19:15 +00:00
0d3e657e1a added pragma library 2006-04-24 07:08:05 +00:00
880ec0572f fixed some bugs in result stuff 2006-04-24 02:09:27 +00:00
eba3f39d88 fixed some corruption bugs, hopefully improved memory management 2006-04-23 23:17:20 +00:00
58ed3067ed Fixed search bug
Fixed print bug
Bumped version number to 1.4.2
2006-04-23 20:46:52 +00:00
fce58de726 *** empty log message *** 2006-04-23 04:24:46 +00:00
3677bc15ad *** empty log message *** 2006-04-23 01:36:33 +00:00
27d8cde394 initial import 2006-04-23 01:10:06 +00:00
3ba923e4c0 Works on t3h linux 2006-04-22 19:50:51 +00:00
07b1f0ea87 Added to allow Linux compilations. 2006-04-22 19:44:37 +00:00
769485ce29 fixed 2 memory leaks in the debugger 2006-04-21 02:45:57 +00:00
1d6becf3b5 hi, dont look 2006-04-21 02:18:34 +00:00
761e1f6fe1 Reverted a CreateInstancedBaselines change due to a 31 character limit to enum symbols that causes a compiler warning
(Real function that FM uses is called CreateInstancedBaselines and is different from CreateInstancedBaseline...
So something should be done, but I'm not sure what yet)
2006-04-20 08:49:49 +00:00
b34557b839 fixed bug at27878 2006-04-19 02:52:39 +00:00
a265189efa Modified param names for touch native and forward to correct values... makes it more clear to someone looking at it 2006-04-17 22:29:18 +00:00
4101eea5e8 Oh dear, lots of changes:
1) Added get_orig_retval for retrieving the original return value of an engine function
2) Fixed engfunc being called with EngFunc_CheckVisibility so that it now works as intended
3) Hooks should now also work with FM_WalkMove, FM_TraceToss, FM_TraceMonsterHull, FM_TraceHull,
   FM_TraceModel, FM_TraceTexture, FM_TraceSphere, FM_GetBonePosition, FM_GetAttachment, FM_RunPlayerMove,
   FM_StaticDecal, FM_BuildSoundMsg and FM_CheckVisibility
4) Reformatted comments in some header files so they look a bit neater
2006-04-17 17:02:57 +00:00
b57c752b1c Added get_orig_retval for retrieving the original return value of an engine function
Reformatted comments in fakemeta include files so they look a bit neater
2006-04-17 16:59:37 +00:00
82a739a95e register_plugin returns id 2006-04-17 12:57:52 +00:00
0a66780727 bugfix for HLDM (listen server) 2006-04-16 00:54:16 +00:00
cb92e45712 Small design changes
Added multi-account support to the local install functions (experimental!)
2006-04-16 00:25:49 +00:00
28b04878ce Added visual style support :o 2006-04-14 15:55:25 +00:00
a5df31570e added request at28068 (split log files)
fixed all native debug errors in core
2006-04-13 16:29:01 +00:00
ed1b2914be Oops, forgot some directories for clean 2006-04-12 17:05:05 +00:00
41214cc461 Makefile changes to fix the clean option 2006-04-12 16:55:09 +00:00
c371684e5e Makefile changes to fix the clean option
Changed arch from 686 to 586
2006-04-12 16:54:17 +00:00
c1866f8156 Makefile changes to fix the clean option
Removed unnecessary geoip files from CVS :o
2006-04-12 16:52:28 +00:00
0939c54048 Makefile changes to fix the clean option
Changed arch from 686 to 586
2006-04-12 16:48:47 +00:00
d9e2166e97 bumped version number to 1.72 2006-04-12 16:18:46 +00:00
17d5e7f0ca Renamed SUFFIX_x to BIN_SUFFIX_x because it more clearly shows the meaning of the variable :\ 2006-04-12 16:00:12 +00:00
564a5484f7 Some changes to the makefile:
1) Fixed clean not removing amd64 binaries
2) Removed seemingly broken mmgr builds (just like MSVC now)
3) Added binlog options for creating BinLog binaries
4) Fixed amd64 build from dynamically linking to zlib
2006-04-12 15:42:18 +00:00
8a732c7e14 For some reason libz64.a was not recognized as a binary file in CVS. Hopefully fixed now. 2006-04-12 15:37:00 +00:00
998208ef20 *** empty log message *** 2006-04-12 15:36:07 +00:00
a2082bac93 Don't include unnecessary headers when BINLOG_ENABLED isn't defined - whoa 2006-04-12 13:01:15 +00:00
3dacc60073 Minor MSVC Project Changes:
1) Automatically add "bl" to binary name on BinLog builds
2) Exclude binlog.cpp from non-BinLog builds
2006-04-12 12:56:58 +00:00
a5dc3fe777 changed a few captions 2006-04-12 12:08:52 +00:00
5c55eae9a6 fixed a bug for metamod's plugins.ini
simplified the install method page a bit
2006-04-12 10:26:19 +00:00
63aef3bcee added debug msgs 2006-04-12 02:25:31 +00:00
deeb2f3cf9 added some debug msgs 2006-04-12 02:12:03 +00:00
59098d703e added debug msgs 2006-04-12 02:00:08 +00:00
662289eb28 added some debug msgs 2006-04-12 01:51:23 +00:00
392b7d9fdf Removed tclsqlite.c from MSVC project files (it's really not needed, I swear) 2006-04-11 16:11:42 +00:00
db9fcc28d6 fixed bug at27729 (HS and announcements overlapping) 2006-04-11 13:26:50 +00:00
63d4d6591b fixed typo at28092 2006-04-11 12:41:29 +00:00
9ef9e3755a Fixed bug at28087 2006-04-11 06:34:17 +00:00
b8ddd281aa hack fix for at28078 2006-04-11 06:30:59 +00:00
363d95f68c fixed bug at27832(jtp10181) 2006-04-10 22:14:42 +00:00
da6b71a677 Changed default caption of the documents tabbar
Changed default theme to Xito
2006-04-10 18:25:54 +00:00
c9765e50c8 Replaced Documents tabbar (means two bugs are fixed now)
Removed Projects tabbar and added a new item to the statusbar
2006-04-10 18:05:08 +00:00
cd7f15f112 Reverted one of my "fixes." Apparently this is intended functionality. Sorry :( 2006-04-10 16:13:02 +00:00
4fb001ce50 Whoa, whoa, whoa. Three "bugs"
1) Fixed tag mismatches with fprintf when not using Float, Sql, or Result (comma was missing :o)
2) Fixed unlink from taking more than one argument o_O
3) Fixed filesize from taking more than one argument o_O
2006-04-10 14:02:37 +00:00
e49365755d MSVC8 Project File + SDK Update + Some Newline Fixes 2006-04-07 12:05:08 +00:00
9baab16682 MSVC8 Project File + SDK Update 2006-04-07 11:56:28 +00:00
dfcd83ffa3 Redefined some missing preprocessor macros that should have been present in the release build configs 2006-04-07 11:42:50 +00:00
8238741f39 MSVC8 Project File + SDK Update + Some Newline Fixes 2006-04-07 11:32:45 +00:00
a595557e2d MSVC8 Project File + SDK Update
Update to SQLite 3.3.5
2006-04-07 11:18:17 +00:00
070d8177c5 MSVC8 Project File + SDK Update 2006-04-07 11:04:28 +00:00
9eb3cd1793 Readded libpcre 6.4 binary for x86 Linux module 2006-04-07 10:52:39 +00:00
2f6fe9fac4 MSVC8 Project Files + SDK Update
Also updated to pcre 6.4
Added lib_linux64/pcrelib - should fix issue with module requiring libpcre as external dependency on AMD64
2006-04-07 10:51:09 +00:00
3bf5fb612f Oops, disable RTTI. 2006-04-07 10:27:49 +00:00
62b28e7033 MSVC8 Project File + SDK Update 2006-04-07 10:25:45 +00:00
860a4ca50e MSVC8 Project File + SDK Update + Some Newline Fixes 2006-04-07 10:12:56 +00:00
26a0767737 MSVC8 Warning Fixes 2006-04-07 10:02:13 +00:00
4eccad2c27 MSVC8 Project File + SDK Update 2006-04-07 10:00:04 +00:00
3966f79324 MSVC8 Project File + SDK Update 2006-04-07 09:41:31 +00:00
38305fdd4f MSVC8 Project File + SDK Update + Some Newline Fixes 2006-04-07 09:24:27 +00:00
9c2f98e1eb MSVC8 Project File + SDK Update + Some Newline Fixes 2006-04-07 09:09:48 +00:00
971c5ffbb5 Oops. Put no RTTI on debug build as well. 2006-04-07 08:58:37 +00:00
c1edaa83bd MSVC8 Project Files + SDK Update 2006-04-07 08:48:01 +00:00
795e23dd09 natives-amd64.o fixed? 2006-04-07 07:18:52 +00:00
93ff6d5c67 *** empty log message *** 2006-04-07 07:18:23 +00:00
0dc594f5e1 Weirdness in libz.a hopefully fixed? 2006-04-07 07:14:56 +00:00
fad03b546a *** empty log message *** 2006-04-07 07:14:15 +00:00
39f4a2bc13 fixed bug at27770 2006-04-06 23:36:22 +00:00
3cb91fec58 MSVC8 Project File + SDK Update 2006-04-06 14:33:15 +00:00
8276223e68 Compile with no RTTI 2006-04-06 14:27:50 +00:00
2da45cfd1c MSVC8 Project File + SDK Update 2006-04-06 14:17:39 +00:00
82b0128308 MSVC8 Project File + SDK Update 2006-04-06 13:58:06 +00:00
550c505813 Removed no longer supported DB modules from modules.ini :o 2006-04-06 13:14:45 +00:00
d50d6b0334 For some strange reason natives-amd64.o and libz.a were not valid files before and core would not compile on Linux. Now they should work. 2006-04-06 13:06:48 +00:00
f2d21c410b MSVC8/VS2005 Compiling Fixes - 0 errors, 0 warnings. Hurray! 2006-04-06 12:56:45 +00:00
ec51566abe Remove cruft from MSVC 7.1 project files so that JITDebug, JITDebugBinLog, JITRelease, and JITReleaseBinLog are the only build configs 2006-04-06 12:14:59 +00:00
8a2d750970 removed some amd64 files :o 2006-04-03 02:42:20 +00:00
46b70bdfba updated to April 2006-04-02 19:27:18 +00:00
15e137e266 time test 2006-04-02 18:50:35 +00:00
93c8bd0253 fixed potential exploit (thanks twisted) 2006-04-01 05:50:33 +00:00
10a935790c a clean yam is a happy yam. 2006-03-31 21:59:52 +00:00
68208d73d7 made sure vars are reset 2006-03-30 20:45:22 +00:00
b57367dd30 abort() now cancels a callfunc 2006-03-30 20:42:11 +00:00
9eb9839a46 bumped version numbers 2006-03-30 04:25:57 +00:00
deccf7816c added rmdir() 2006-03-30 00:48:58 +00:00
fe971497cc synced to dll 2006-03-30 00:31:45 +00:00
8c2be55233 added ClientUserInfoChanged forward 2006-03-30 00:31:33 +00:00
ab443e8254 fixed a few buffer overflow errors 2006-03-30 00:13:38 +00:00
16e53eded8 synced to dll 2006-03-29 23:57:54 +00:00
a7acf05bfc added more strings 2006-03-29 23:57:42 +00:00
5e22cd5f0a Fixed bug at27323 (AndraX2000) 2006-03-29 23:33:38 +00:00
92be7f6791 synced to core 2006-03-29 22:58:11 +00:00
94c449936d added getc,ungetc,putc 2006-03-29 22:56:18 +00:00
89c58265aa page numbering does not appear with no pages 2006-03-29 22:48:45 +00:00
3783e34a70 Fixed a bug where handlers wouldn't work if they were in the 0th slot 2006-03-29 22:42:03 +00:00
414ecdfffa fixed crash when creating a new binlog file 2006-03-24 19:29:49 +00:00
76afa40270 fixed bug 2006-03-23 15:01:15 +00:00
17bbc37638 fixed binlog max size name 2006-03-23 10:11:09 +00:00
4b0b3c0c7c bumped version 2006-03-20 22:58:27 +00:00
006b4bd49a added syncpoints to all stats scripts 2006-03-20 19:40:58 +00:00
5395fc1280 updated constants 2006-03-20 19:36:57 +00:00
a293e23fe2 renamed time to gl_time
updated makefile
2006-03-20 18:45:53 +00:00
68e729721d ~(, ,)o <-- wtf another turtle?! 2006-03-20 18:38:29 +00:00
4f5c16c278 added support for new tr and kvd hooking/calling 2006-03-20 18:23:03 +00:00
c15a86b454 added new TR/KVD stuffs 2006-03-20 18:08:51 +00:00
51c8724cff added more hud syncpoints 2006-03-20 01:43:44 +00:00
ccb3b4fbb3 experimental fix for improving hud sync 2006-03-20 01:03:30 +00:00
83bf0d7b2a ~(, ,)o <-- turtle 2006-03-19 21:52:25 +00:00
f55a8c54cc binlog reader no longer logs plugin database in a separate file 2006-03-19 21:41:11 +00:00
dc9350fcc5 committed changes for new file format 2006-03-19 21:40:24 +00:00
ef5437fec3 a working adminslots 2006-03-19 21:25:18 +00:00
0999db0203 fixed bug at26073 2006-03-19 20:48:37 +00:00
d84ef62e6c little optimization from PM 2006-03-19 20:39:25 +00:00
b5e8bc9ec1 fixed bug at26868 2006-03-19 20:14:24 +00:00
ccaa4434ad committed new language code 2006-03-19 19:26:29 +00:00
555ac1c7f3 fixed corrupt file loads smashing the stack
added compile of support code
2006-03-18 22:10:05 +00:00
b9788b7e1b *** empty log message *** 2006-03-18 21:38:28 +00:00
c6e332a0f5 linux+amd64 compat 2006-03-18 20:59:38 +00:00
007d41b5af Bumped version number to 1.71
Added a hint concerning binary logging to metamod's plugins.ini
2006-03-18 20:03:34 +00:00
a1956bc83b added cpuid helper func 2006-03-18 08:56:58 +00:00
ff61158491 fix for binary db not being created on maxsize overflow 2006-03-17 23:29:33 +00:00
2c5520cad0 added optimization tweaker
added binary log maxsize support
2006-03-17 22:50:13 +00:00
4bcb0fcb13 new localinfo crap 2006-03-17 22:10:16 +00:00
6ef670878d committed binary 2006-03-17 18:26:21 +00:00
89e13334ae uses stringbuilder instead of alloc+concat for speed now 2006-03-16 19:29:46 +00:00
82fe1e10d9 Fleshed out log and database readers, began basics of GUI 2006-03-16 06:40:18 +00:00
e067a980be implemented a lot more binary opcodes
bumped versions
2006-03-16 06:36:01 +00:00
e98fbc47e8 added new binary logging option 2006-03-16 04:36:55 +00:00
b6fa60b0bd Modified to fix memory leaks and improve speed 2006-03-16 02:11:48 +00:00
7e97156fc4 added arrayset native 2006-03-16 00:13:13 +00:00
7190d933b4 fixed bug at26204 2006-03-15 16:14:32 +00:00
3699796bc6 finalized file format
added register op (working)
added msvc8 stuff (4better || 4worse)
2006-03-15 13:43:06 +00:00
e208ff0664 quick import of file structure 2006-03-15 13:42:25 +00:00
adc2a7d169 initial import of binary logger support code 2006-03-14 19:36:18 +00:00
dc8e162e26 added menu_cancel 2006-03-14 17:50:38 +00:00
522511d059 implemented menu_cancel 2006-03-14 17:49:29 +00:00
d5152fedc4 added glb.cpp 2006-03-14 17:21:35 +00:00
d7bef2ae4b added get_global() 2006-03-14 17:15:52 +00:00
9283cbe1c2 added request at26450 2006-03-14 16:55:06 +00:00
7dae023a98 fixed bug at26580 2006-03-14 10:01:35 +00:00
9c88ce1394 fixed bug at26581 2006-03-14 09:59:28 +00:00
4cb8d4adc7 *** empty log message *** 2006-03-14 02:54:54 +00:00
5c88803942 New update! 3.1 is liiiive!
Error handling:
Array now has sufficiently advanced error handling to remove most, if not all, disable_checks.

Extention:
With the metaprogramming techniques, new types can be added easily.

Speed:
With the new changes I've made to Judy, the Array module has far exceeded the speed of any traditional datatype
2006-03-14 02:54:24 +00:00
4457b0d879 Obsolete due to update 2006-03-14 02:50:30 +00:00
58415dcfb9 Obsolete due to new updates 2006-03-14 02:49:02 +00:00
76c216d07e added request at26533 (Brad) 2006-03-13 22:43:55 +00:00
aa3582a2f3 removed patch for autochanneler (bug at26176) 2006-03-13 14:37:23 +00:00
d80b59e639 vers bump 2006-03-13 14:35:46 +00:00
880cb401fb fixed bug at26340 (NiLuJe) 2006-03-13 14:35:26 +00:00
2e0dcb860a fixed dynamic ExecuteForward not returning a valid result and patching the forward id 2006-03-10 19:04:04 +00:00
a9684fb81d fixed bug at26189 2006-03-07 12:58:39 +00:00
f2b8b82515 Component update (whoa I hate delphi reinstallations)
Added another feature for the Code-Explorer
2006-03-06 19:47:22 +00:00
eb7a49f6d4 fixed awful cvar bug, amx_reservedslots (which wasn't registered by the plugin) was used in the code instead of amx_reservation 2006-03-06 15:27:30 +00:00
982b22ab20 fixed bug in split() 2006-03-06 14:54:12 +00:00
38acf132c8 new installer for added files, removed files, that stuff... yams 2006-03-04 11:12:17 +00:00
f25824a1aa added in two old natives again
fixed a native spelling mistake
2006-03-04 11:06:19 +00:00
446c5523f8 added back in two more old natives 2006-03-04 11:05:59 +00:00
7bcdc4be44 new info files for vers bump 2006-03-04 09:46:32 +00:00
6c6389ba65 oh, last credits bit. wee <-- gaben? 2006-03-04 08:52:08 +00:00
0898418cf3 what... oh 2006-03-04 08:40:27 +00:00
943b902e23 fixed the cursed bug of throwing knives 2006-03-04 08:16:00 +00:00
74cd310504 bumped version 2006-03-04 06:53:06 +00:00
44979f2b07 bumped versions 2006-03-04 06:51:59 +00:00
a3142a520f bumped versSIIOOON 2006-03-04 06:48:44 +00:00
372a01e6da committed fakemeta optimizations 2006-03-04 06:34:28 +00:00
3b4cd21835 NL and SV fixes (Lt Llama) 2006-03-03 22:31:55 +00:00
2d6c06b82f fixed fclose bug (NiLuJe) 2006-03-01 20:59:08 +00:00
a9cdb2b48e new binary 2006-03-01 02:50:28 +00:00
60b411757d latest compiler build 2006-03-01 02:48:40 +00:00
19b5835ae4 added ClearSyncHud() 2006-03-01 02:20:44 +00:00
48377168b2 Added ClearSyncHud() 2006-03-01 02:17:20 +00:00
d89f216682 added more syncing 2006-03-01 00:10:35 +00:00
62489d05cc fixed hud message syncing 2006-03-01 00:10:23 +00:00
84b09301e6 fixed display bug 2006-02-28 23:43:22 +00:00
3c1b564956 wrapped a few more things around HudSyncObjs 2006-02-28 10:46:22 +00:00
f7d4c6fe34 fixed the final bug in this I think 2006-02-28 10:42:52 +00:00
d2cc14fa18 crraaaaap 2006-02-28 10:10:44 +00:00
51b2cf120e fixed valve_id_lan bug 2006-02-28 10:03:13 +00:00
dc5506efe3 added experimental callback for modules to get authorization 2006-02-28 09:59:03 +00:00
628d38df7a experimental fix for new stats sync code 2006-02-28 09:43:20 +00:00
d4c2bf154f experimental fix for hud sync issue 2006-02-28 09:42:56 +00:00
a504caac62 resync 2006-02-28 05:15:40 +00:00
2653f88b73 bumped vers on this early 2006-02-28 05:15:29 +00:00
f853f8f8cd added amxx to vers string 2006-02-28 05:14:36 +00:00
b2437451e3 implemented __DATE__ 2006-02-28 05:14:20 +00:00
c49bff54b1 fixed bug at25751 (zor) 2006-02-27 20:31:50 +00:00
b9ed05f38b fixed bug at25751 (zor) 2006-02-27 20:30:07 +00:00
4aaa2f8e0f fixed memory leak 2006-02-27 10:10:52 +00:00
85c37c6a39 merged in marticus's changes 2006-02-27 09:22:03 +00:00
ed4d8f9e26 added missing flags (NiLuJe) 2006-02-26 20:38:36 +00:00
1a03391347 omg updated these for sure. 2006-02-26 08:15:12 +00:00
0999ad32e3 makefile 2006-02-26 08:13:56 +00:00
f62933efd4 makeile 2006-02-26 08:13:15 +00:00
b968f437ca phew... updated to include old tsfun stuffs 2006-02-26 08:11:25 +00:00
d9f9c5256a more revert to 1.00-era code 2006-02-26 06:54:23 +00:00
0da49cfc45 reduced this module to a wrapper 2006-02-26 06:45:44 +00:00
8735bf3df3 initial revert to 1.00-era code 2006-02-26 06:42:48 +00:00
4db61f243a what 2006-02-26 06:40:47 +00:00
a43a3b0803 committed patch for correct typecasting 2006-02-26 05:03:05 +00:00
bf8cf574e0 updated to 3.3.4 2006-02-25 01:37:50 +00:00
4fed42b5c7 gah >_< recompiled with -O1 -DWIN32 2006-02-24 15:47:40 +00:00
1f2d9c8a92 typos, made language harsher 2006-02-24 10:12:55 +00:00
8502fb51b3 fixed bug where deleting oldmenus would make the next key non-unique 2006-02-24 08:34:37 +00:00
1d30d0831b i have a hat 2006-02-24 07:49:08 +00:00
0520c606ec fixed possible overrun bug 2006-02-24 00:11:37 +00:00
6997c780d9 fixed bug where format() on copy-back would not null terminate 2006-02-24 00:09:33 +00:00
631e709471 fixed bug where the string lenght wasnt decreased on some cases 2006-02-23 22:55:43 +00:00
1d508c0e04 Updated version to 1.70 2006-02-23 10:54:15 +00:00
28ca230a53 Fixed another bug, installer didn't register the right mm version in the liblist.gam for AMD64 servers 2006-02-23 10:51:35 +00:00
01b58a4635 Fixed dictionary parsing not obeying the carat backtick
Fixed failed translations crashing
Added formatex()
Fixed buffer copyback problems in old usages
2006-02-23 00:02:33 +00:00
0852dfa112 added missing pcvar natives 2006-02-22 20:32:59 +00:00
7362cd0621 sup twisty 2006-02-22 01:41:28 +00:00
635d18de92 tiny optimizations from evilspy 2006-02-22 01:36:29 +00:00
484014e2db fixed translate concat bug 2006-02-22 01:05:09 +00:00
2ba0b079ab initial import of new format zomg 2006-02-22 00:33:19 +00:00
2843c333aa Fixed bug at25472 2006-02-20 03:24:45 +00:00
4369023394 Added a few edit functions to the notes richedit 2006-02-17 20:25:25 +00:00
dc97e18955 fixes for % stuff in statsx and its lang file 2006-02-15 19:44:34 +00:00
c31e2be46f added backward compatibility for % mistakes 2006-02-15 17:31:30 +00:00
7539751fc6 added pcvar funcs 2006-02-15 16:05:20 +00:00
8a8b91998a fixed typo 2006-02-15 10:45:05 +00:00
c7fbc7f55e more gaben 2006-02-14 23:59:24 +00:00
ea5c9f0af4 gaben 2006-02-14 23:56:55 +00:00
76609e2a4a fixed bug with translator cvar not being registered by core 2006-02-14 22:14:12 +00:00
1923d42c5f fixed old fmt bug 2006-02-14 20:28:52 +00:00
13360bec73 reformatted file a bit 2006-02-14 16:57:44 +00:00
f1a4cfee61 compilable now o_O 2006-02-14 15:13:26 +00:00
ac5d87b2c2 commited binaries + project file 2006-02-14 13:42:25 +00:00
bf0c1990dd committed new format() code 2006-02-14 12:01:22 +00:00
a8c01e4865 fixed forwards passing floats as cells to the core
fixed pfn_playbackevent missing a parameter
2006-02-13 20:03:39 +00:00
472613d973 Fixed engine and dll bases screwing up. 2006-02-13 19:31:46 +00:00
323341f67a added request at22274 2006-02-13 14:23:43 +00:00
71c023f485 added CS_TEAM_UNASSIGNED at vittu's request 2006-02-11 22:57:34 +00:00
48d3b6e952 bad ptr checks for strings 2006-02-11 22:56:55 +00:00
2c8808aaff fixed formatter bug on bad control code 2006-02-11 22:48:29 +00:00
82693ccae6 fixed serious OP_FLOAT_CMP bug (boy I was tired) 2006-02-11 21:51:28 +00:00
e74ff6a5a4 committed OP_FLOAT_CMP 2006-02-11 07:06:35 +00:00
eba5b1a920 Fixed 2006-02-11 03:04:45 +00:00
a93001a68b Fixed Null Error 2006-02-11 00:41:28 +00:00
d548457c30 Fixed stupid NULL error 2006-02-11 00:41:11 +00:00
be1bc6f75c removed debug log for float testings 2006-02-10 19:47:09 +00:00
76358f4289 updated makefile 2006-02-10 15:53:13 +00:00
652f8b9f74 commited builds of latest asm stuff 2006-02-10 15:51:37 +00:00
dcaf3066bf experimental optimizer for float ops 2006-02-10 15:43:27 +00:00
b527efde41 fixed bug where showmenus didn't properly clear newmenu bit 2006-02-10 14:16:00 +00:00
a195a0af30 fixed a re-entrancy bug 2006-02-09 12:04:35 +00:00
52aa992a2f fixed recursion problem
fixed handle leak
fixed player defaults
2006-02-09 11:53:22 +00:00
c602308acb fixed bug where exit wasn't guaranteed
fixed menu destroy bug at25132
2006-02-09 11:19:57 +00:00
5a0b3b0f9f added a memcpy for MM 2006-02-09 11:17:22 +00:00
750b098e02 sigh... 2006-02-08 22:59:58 +00:00
2a13d923fa committed menu padding and title setting 2006-02-08 22:09:31 +00:00
3507155189 removed MM-1.18 compat 2006-02-08 21:59:02 +00:00
1e4c71e8e3 fixed blank items destroying menus 2006-02-08 05:39:03 +00:00
8d0a3ac9ae another sync 2006-02-08 04:11:14 +00:00
fb0febb50e Updated to remove unnessasary stocks 2006-02-08 02:17:45 +00:00
60586fdda4 Working at time of commission 2006-02-08 02:14:15 +00:00
b381fc9141 Working at time of commision. 2006-02-08 02:13:58 +00:00
33da5f3737 quick patch for dynamic native issues 2006-02-07 14:23:09 +00:00
3dcaa5742d bumped vers 2006-02-07 13:06:19 +00:00
e59d7c2f01 bumped version 2006-02-07 13:04:01 +00:00
9946a6892c wtfversion 2006-02-07 13:03:06 +00:00
9a5b855e2d fixed bug at25040 2006-02-07 12:43:40 +00:00
a43f62615b stupid typo 2006-02-07 12:19:37 +00:00
459f91af24 optimized this further 2006-02-07 09:02:08 +00:00
29f46a56d9 got rid of stupid "buffor" 2006-02-07 08:57:34 +00:00
a2bd08cf64 fixed bug at16664 2006-02-07 08:56:36 +00:00
208a57eaf8 added menu padding 2006-02-06 15:27:02 +00:00
2879c86d79 added more exit props 2006-02-06 13:24:26 +00:00
506a6e0465 added never display exit option to newmenus 2006-02-06 13:22:33 +00:00
53c029471f removed usage of CVAR_GET_STRING 2006-02-06 13:10:23 +00:00
cc32f33815 lang debugger uses now make_string for THash 2006-02-06 12:57:14 +00:00
e2c1b8c178 Fixed bug where invalid keys were saved as blank translations
Fixed bug where dictionary caches were invalidated before being used
Loads with MM 5:11 now
2006-02-06 11:13:27 +00:00
458f2acfe7 fixed bug at25056 2006-02-06 04:29:50 +00:00
e929dc55bd synced CString.h 2006-02-05 19:16:16 +00:00
b5b42c675d updated to February 2006-02-05 19:14:19 +00:00
278e267690 Fixed potential crash bug in the plugins unit 2006-02-05 13:59:41 +00:00
93ad26fb2a oops, forgot there was a sep. def for this 2006-02-05 08:25:45 +00:00
f8d0e4b90d fixed bug at25028 (teame06) 2006-02-05 08:06:50 +00:00
35e8a67a48 *** empty log message *** 2006-02-05 04:20:30 +00:00
0df187edcd merged lang stuff 2006-02-05 03:41:30 +00:00
2cfebb0234 fixed typo 2006-02-05 02:26:00 +00:00
8edd843f4b removed CDataBuffer reliance 2006-02-05 02:20:45 +00:00
6324161b98 what 2006-02-05 01:00:28 +00:00
f0f8b78df9 added server_changelevel back
fixed bug where NULL FP_STRING could crash forwards
2006-02-05 00:32:20 +00:00
e0d4ad0a06 merged in random changes from twilight 2006-02-04 23:21:03 +00:00
815afdcd11 what 2006-02-03 05:48:55 +00:00
88d2b393d8 cvar queries actually run now
removed old fakemeta code
2006-02-03 04:19:18 +00:00
07affb56f2 works with post now 2006-02-03 03:28:43 +00:00
2ad9a320de added unregister_forward() 2006-02-03 03:27:03 +00:00
df082de817 committed newmenu api, take two 2006-02-03 03:00:48 +00:00
3027b732a5 added player_menu_info 2006-02-03 03:00:27 +00:00
af939f4e8d new menu API 2006-02-03 02:55:27 +00:00
2ab9fce457 Added an information to the welcome page 2006-02-02 10:07:00 +00:00
63b10cfaf5 Fixed DEP bug 2006-02-02 09:34:06 +00:00
dcae78a389 final fixes for strip weapons 2006-02-02 00:45:56 +00:00
ea34df433a patched cvar change exploit (target) 2006-02-01 13:07:36 +00:00
0e3727573e added get_user_footsteps 2006-02-01 13:04:24 +00:00
f40ae48849 removed server_changelevel (at24675 - oneyed) 2006-02-01 12:33:31 +00:00
7070273616 patch at24690 (karlos) 2006-02-01 12:23:30 +00:00
923ecaa0e5 added pev_valid 2006-02-01 12:17:40 +00:00
53d9274b45 added pev_valid() 2006-02-01 12:16:33 +00:00
4426910b9a made find plugin fast inline for speed 2006-02-01 12:10:52 +00:00
eb010688af optimized + fixed parsing in strbreak() 2006-02-01 12:10:26 +00:00
314392bffe removed old cvarquery stuff, added support for queryclientcvarvalue2 2006-02-01 12:09:43 +00:00
28ede82f91 added cell list registering 2006-02-01 12:09:19 +00:00
a5819d8cf8 added create forward natives 2006-02-01 12:08:42 +00:00
2d0e12363f added include defs for new forward creation 2006-02-01 11:54:57 +00:00
cb291dbdd5 sync 2006-01-30 21:40:10 +00:00
44db80bc75 Added madExcept
Updated some captions
Improved the "Cancel" button
2006-01-29 17:24:49 +00:00
bc5445d255 Added madExcept settings 2006-01-29 17:23:19 +00:00
55613eb882 fixed bug at24752 2006-01-27 22:43:51 +00:00
04c54128af fixed case 2006-01-27 09:07:37 +00:00
82cb94ab56 removed old fakemeta #defines
added better mm version handling
2006-01-27 09:07:04 +00:00
82653094fb another synce with SH 2006-01-24 22:51:29 +00:00
7c7422a553 added language debug 2006-01-24 18:47:08 +00:00
018b4645e8 *** empty log message *** 2006-01-24 15:43:49 +00:00
6cec38a329 committed latest compiler 2006-01-24 15:09:27 +00:00
8cc73227c7 removed changelevel forward 2006-01-24 15:02:11 +00:00
93ce1ac470 fixed a forward bug causing client_death to pass weapindex as the damage 2006-01-23 07:27:58 +00:00
bd1999cdfb added amx_mldebug cvar 2006-01-23 00:21:35 +00:00
8d9ad2ce06 fixed bug for checking colored menus in TFC and other mods 2006-01-20 23:24:36 +00:00
8ee50cee1b Commited to show new natives 2006-01-14 03:16:25 +00:00
7183954b08 Fixed a bug in the Code-Inspector
Added madExcept again
2006-01-12 19:14:56 +00:00
564dfbf329 Part of the madExcept component 2006-01-12 19:12:33 +00:00
ab5c11f876 Finally done!!! I finished what DS started:
AMXx Mods may now patch/retreive memory of several varieties directly from the game .dll, mod .dll, or can go free and patch/retreive any peice of memory.

I salute you DS.
2006-01-12 03:55:49 +00:00
73ba5d1644 Updated some captions
Updated the Autocomplete-Check function
Prepared AMXX-Studio for release
2006-01-11 18:02:42 +00:00
fd7f4441fb final version I hope 2006-01-07 06:17:16 +00:00
636f1141e4 removed test code 2006-01-07 06:16:52 +00:00
2eac69e9b4 *** empty log message *** 2006-01-07 05:40:57 +00:00
3b79a063b6 finally, a correct fix 2006-01-07 05:39:40 +00:00
69b6ed5f56 *** empty log message *** 2006-01-07 04:48:02 +00:00
07b9bb9987 okay, works 2006-01-07 04:47:49 +00:00
9578e8ac3d *** empty log message *** 2006-01-07 04:44:36 +00:00
39fd00c5be real fix this time 2006-01-07 04:43:01 +00:00
a3572f7206 Added and working! Array module 1.65 is a go for release! 2006-01-07 04:36:12 +00:00
e8a4b46cc5 removed 4 cmds from statsx, and implemented currentmap and FF status in nextmap (at22858) 2006-01-07 03:26:50 +00:00
6a59d8cd07 patch of compiler binaries 2006-01-07 02:24:58 +00:00
a4db0d927a Fixed bug at22981 2006-01-07 02:20:54 +00:00
bec98dcddd added new cvar for adminslots plugin 2006-01-07 01:04:07 +00:00
e27c0b205f (Marticus)
-Added documentation and cleaned up the code
-Created amx_hideslots cvar to replace #define HIDE_RESERVED_SLOTS
-Removed ackSignal *sigh* and the horribly coded setVisibleSlots function
-Removed client disconnect
-Created global variable gPlayerLimit to be used in both functions
-Moved set cvar sv_visiblemaxplayers to plugin_init
2006-01-07 00:54:40 +00:00
85f14422cb re-added file natives 2006-01-06 22:49:42 +00:00
66c278c64b wrong handle, oops 2006-01-06 21:05:48 +00:00
04113f8a02 merged changes from SH:TinyHash 2006-01-06 18:52:12 +00:00
86c033a922 gab gab 2006-01-06 14:47:59 +00:00
91c082878c wa 2006-01-06 14:44:32 +00:00
3d00b8c545 Merged changes from SH:List
Fixed bug where natives did not use the debugger (experimental)
Removed array size detection :(
2006-01-06 14:37:58 +00:00
0c745590ec Added functions for smashing the stack and memory :) 2006-01-06 14:22:12 +00:00
b46ee941d4 reverted tasks to v1.60 2006-01-06 05:10:17 +00:00
0d3055e505 partial fix for dynamic natives when running on debug mode 2006-01-06 04:59:39 +00:00
4b51565e3b hello my name is pm and i just fixed the bug described in 23888 2006-01-04 23:23:52 +00:00
c9e84c563d Updated to include additional protection for PDATA. 2006-01-03 21:48:59 +00:00
60716cd346 *** empty log message *** 2006-01-03 21:19:11 +00:00
531cc5f2c1 Added some returns in engfunc() and in dllfunc() 2005-12-31 15:09:14 +00:00
d1b290c7a4 Fixed bug at23454 (DeciusMagnus) 2005-12-26 14:38:14 +00:00
8aaa2d859f Modified something in the About dialog 2005-12-24 02:20:08 +00:00
0c6d606fea Added an Auto-Setup feature 2005-12-23 13:19:21 +00:00
8a5806cd25 Added a small hint to the compiler page in the settings dialog 2005-12-18 19:31:50 +00:00
40ca5f8002 *** empty log message *** 2005-12-17 02:16:01 +00:00
e50151343b *** empty log message *** 2005-12-11 18:42:19 +00:00
6aaf11f2a3 updated version number to 1.65 2005-12-11 18:30:52 +00:00
9d480b05af updated a few things in the plugin system 2005-12-11 17:55:35 +00:00
3f36b51f6c Added the plugins directory to CVS and updated the files 2005-12-11 17:31:06 +00:00
7cc586bd0c removed old forward class 2005-12-11 17:11:21 +00:00
b6d6be3c27 Changed a few captions in the about dialog 2005-12-11 16:45:02 +00:00
0b834a3f9b communicate core when setting a new team or deaths 2005-12-08 20:00:43 +00:00
5d5d1e1a7c added request at19456 2005-12-07 00:13:13 +00:00
d55bffede6 *** empty log message *** 2005-12-06 22:47:02 +00:00
806895ebd8 fixed bug when voting multiple maps voting would always fail 2005-12-06 19:06:05 +00:00
914b53933b nothing 2005-12-05 02:28:24 +00:00
402236e51e fixed bug at22532 2005-12-05 02:07:22 +00:00
2ebf822dea added new socket send native 2005-12-05 01:49:16 +00:00
389f470662 format fixes^2 2005-12-03 16:24:27 +00:00
522dccef76 hello 2005-12-03 00:54:26 +00:00
186728053a added autohud
format fixes
2005-12-02 23:34:11 +00:00
507a901a9e Changed a few language strings (again) to English
Fixed bug in the replace system
Fixed bug in the Autcomplete Check
Changed version number to 1.4
2005-12-01 16:30:26 +00:00
83d2e1a510 *** empty log message *** 2005-12-01 13:45:30 +00:00
f336585d4f Fixed GCC compatibility for now.
Removed ps_locked and replaced with ps_error.
Added set_fail_state.
Fixed md5_file.
2005-12-01 13:42:28 +00:00
80fdb2cdb2 Removed ps_locked flag 2005-11-29 21:59:21 +00:00
8251ffd25f Fixed bug at22273 (karlos) 2005-11-29 21:54:43 +00:00
5ad341edd7 EXPERIMENTAL BTree+DL ADT for Tasks (USE AT RISK) 2005-11-29 00:52:35 +00:00
2f8939967e fixed but at22303 (VEN) 2005-11-28 16:22:12 +00:00
6d84dff2b0 tiny optimization 2005-11-26 20:59:47 +00:00
8112fbe161 fixed bug at21983 2005-11-26 20:38:58 +00:00
e9db0c8c76 again bugfixes 2005-11-25 21:44:18 +00:00
cbcc91cc09 BETA optimizations 2005-11-22 04:14:07 +00:00
7ed757dc0d added autohud support
format fixes
2005-11-21 22:30:32 +00:00
8196ddd0b3 added replace_all stock (by jtp10181) 2005-11-21 21:47:54 +00:00
1a48ebb345 format fixes 2005-11-21 20:31:18 +00:00
c6fc34a64d Rewrote format() parser to be re-entrant and easier to read
Added various optimizations
Fixed memory leak in sh_tinyhash
2005-11-21 10:04:43 +00:00
f13599177f Rewrote language backend for integrity checking and optimization
Replaced CRC32 system with real hash-map
2005-11-21 01:35:37 +00:00
bb292d13ad added remove_filepath stock 2005-11-20 23:45:53 +00:00
6f2121cd4d Fixed bug in prune()
Synced changes from SourceHook
2005-11-20 20:54:20 +00:00
3324d65f3f fixed amx_restrict off and related cmds not working as they should (jtp10181) 2005-11-20 20:44:12 +00:00
5c5ca9251e New offsets from karlos 2005-11-20 20:01:03 +00:00
30f7f6d51f Fixed typo in SDK 2005-11-20 20:00:31 +00:00
922a2f6006 bumped version numbers 2005-11-20 19:47:49 +00:00
54f3bba89d Bump of versions+SDKs 2005-11-20 19:45:59 +00:00
5d8150637b Bump of version+SDK 2005-11-20 19:42:14 +00:00
3938933384 added new time include file
added get_time_length stock (Brad)
2005-11-20 19:27:07 +00:00
0482883a8a Resync of compiler build 2005-11-20 19:18:40 +00:00
9e4b1661e3 Fixed bug at21914 (faluco) 2005-11-20 19:10:13 +00:00
4040410c97 first attempt on lang error logging 2005-11-20 03:47:47 +00:00
8edf4d674f removed a native 2005-11-20 03:10:02 +00:00
847158f400 what 2005-11-20 02:36:52 +00:00
6ca3edad0c added GetFilename function 2005-11-20 00:00:33 +00:00
0551b46c8b gcc4 compatibility (Nijule) 2005-11-19 22:44:17 +00:00
e5a798357c Patch at21699 (Nijule) 2005-11-19 21:52:56 +00:00
c051c7f5b7 *** empty log message *** 2005-11-19 21:48:27 +00:00
322ad6fd68 New versions of compiler for at21691 2005-11-19 21:43:55 +00:00
a5bd8463e8 Fixed bug at21691 (Podunk) 2005-11-19 21:38:50 +00:00
71926e6d03 get_user_attacker fixes
version bump
2005-11-19 21:24:49 +00:00
803852ee0c small bug fix 2005-11-19 20:37:44 +00:00
fc6a193765 new hudchanneler 2005-11-19 20:31:11 +00:00
db0dd03128 Added new function to calltips: opens include file on click
Fixed some bugs in the menu generator
2005-11-19 19:46:29 +00:00
429798ae35 *** empty log message *** 2005-11-19 18:57:05 +00:00
4cc1218391 channels should clear again 2005-11-19 18:55:29 +00:00
83ea8b82b9 Fixed issue at19616 2005-11-19 09:26:30 +00:00
32cd6be7f5 Fix for issue at19616 2005-11-19 09:26:06 +00:00
4d9f2ded74 Fix for issue at19199 2005-11-19 09:16:27 +00:00
6163e25d7d *** empty log message *** 2005-11-19 09:07:28 +00:00
a3d0767b22 potential fix for bugs related to TSFUN 2005-11-19 01:36:58 +00:00
62e7e22a93 Added functionality for the auto-channeler 2005-11-19 01:25:34 +00:00
694d7c118c Merged in karlos's code, fixed potential get_user_weapon problem 2005-11-19 00:34:25 +00:00
a8bb28caa4 Committed new SDK function for player property mappings 2005-11-19 00:33:51 +00:00
23fb93a3cc - Updated Calltips
- Fixed bugs in register plugin function
- Added "Autocomplete Check", allows you to customize autocomplete items
- Added a new dialog (the parameter info dialog) to the loadinfo record/struct
- Added a new unit called UnitACCheck.pas
2005-11-18 23:35:58 +00:00
778c2080b0 zomg fix for oldmenus^2 2005-11-17 23:04:43 +00:00
94308b208a fixed bug at19374 2005-11-17 21:12:50 +00:00
b00d313ee8 fixed but at21777 2005-11-17 18:52:35 +00:00
4e497d9737 fix for autobuy cmd being used if the restrictions where set after cl_setautobuy (thanks jtp10181) 2005-11-17 18:23:48 +00:00
8cc10bdb3d patch for old showmenus 2005-11-15 21:58:47 +00:00
e816c86d7a synced with sh_sting.h 2005-11-15 20:48:11 +00:00
db77e12615 synced with sh_string.h 2005-11-15 20:21:29 +00:00
79c4d0ca5c added linux compat 2005-11-13 22:34:32 +00:00
34f12e76c4 added request at20855 2005-11-13 22:21:15 +00:00
2ac00713a7 fixed a menu bug at19364 2005-11-13 20:33:30 +00:00
c5761610b8 Small bugfixes 2005-11-13 10:40:59 +00:00
d09a8e1aac added checks for the executeforwards 2005-11-13 00:52:49 +00:00
16f402ae49 fixed a forward bug that made this module a surprise box 2005-11-13 00:45:45 +00:00
1e5c9b5ed7 added a new stock by Suicid3 (at20399) 2005-11-12 22:43:55 +00:00
3125630b21 Partial fix for bug at19662 2005-11-12 18:55:37 +00:00
32fd0f9e93 Fixed small bug in the indent function 2005-11-12 15:11:14 +00:00
4165548661 fixed bug at21142 2005-11-12 01:22:01 +00:00
31b71760e4 strip_user_weapons should reset now the weapon status 2005-11-12 00:47:34 +00:00
18bf26efb6 fixed but at20584 2005-11-12 00:46:26 +00:00
d190b207b4 linux fix 2005-11-09 22:36:52 +00:00
c4d120082b just another bug fix (or two) 2005-11-09 16:48:21 +00:00
38178ea9fa Important bug fix and updated the MOTD generator 2005-11-09 14:32:07 +00:00
0dd88dccbd fixed and improved function at20081 2005-11-07 16:37:47 +00:00
78b35d80ee Fixed some bugs in the menu generator
Fixed bug in the AutoUpdate function
2005-11-06 14:52:50 +00:00
a66f13fc91 Small bugfix, added another feature (saves now the last keywords) 2005-11-05 17:39:12 +00:00
1cb99082e2 Fixed a small output bug 2005-11-05 11:20:52 +00:00
6ea52a9a08 Added new feature: Auto Disable (disable auto-update if plugin has more than xxx lines, should prevent lags) 2005-11-02 15:36:24 +00:00
efe4b674e2 Fixed another bug (I had fixed it once but removed the fix accidentally) 2005-11-02 14:17:00 +00:00
8016d02319 Fixed addon bug 2005-11-02 13:42:05 +00:00
67c0230a62 Fixed bugs 2005-11-01 03:07:47 +00:00
d5c75fd6a5 What... 2005-10-30 14:17:32 +00:00
fc9e39a021 Updated components, added 2 new units 2005-10-30 10:33:16 +00:00
be1475b732 fixed bug at20181 ( why was an #if 0 in the function :o ) 2005-10-29 18:27:24 +00:00
2931247559 fixed bug at19476 2005-10-29 18:19:23 +00:00
9657430ef7 fixed bug at20423 2005-10-29 02:13:29 +00:00
d5cfb53cf8 added request at20845 (azrael) 2005-10-28 12:30:11 +00:00
10a64737b5 Added optimizations to the task system
Added optimizations to the forward system
Fixed some debugger errors
2005-10-25 20:38:00 +00:00
0be7540637 added a space :o 2005-10-25 16:55:16 +00:00
3ced207dd3 Fixed forward bugs 2005-10-18 21:29:51 +00:00
d2fb486e70 Upcasting args to cell before passing to MF_ExecuteForward 2005-10-18 21:17:12 +00:00
c8d69c41bc Hello quickfix 64bit negative values to executeForwards -> now upcasting everything 32bit to cell before passing to executeForwards 2005-10-18 21:05:52 +00:00
3d59eabdc5 Graaght. Typing. 2005-10-18 21:05:15 +00:00
e8a6126473 fixed but at20342 (jtp10181) 2005-10-16 00:28:20 +00:00
62e1856229 Added 3 more plugin messages (SCM_PAWN_FILECOUNT, SCM_CPP_FILECOUNT, SCM_OTHER_FILECOUNT)
Fixed load bug (if you loaded a textfile and the tab "Other projects" wasn't active you got an error message)
2005-10-13 14:49:40 +00:00
21caa9a0de Really fixed callfunc this time (debugger invocation error) 2005-10-13 05:27:13 +00:00
a46ec5357e Am I wrong or should this be this way to prevent security bugs? 2005-10-09 15:39:20 +00:00
ca70678155 fixed bug at19895 2005-10-08 01:35:11 +00:00
c3450df360 - Upgraded Code-Inspector
- Now checks language strings
  - New design
  - Better parsing
  - Displays actions
- Added function: can't load files twice
- Updated Code-Explorer
  - now faster
  - fixed a few small bugs
  - now keeps selection
- Updated Settings-Dialog
- Fixed output bug (showed sometimes huge numbers as line numbers)
- Fixed design bug (displayed wrong plugin data on start)
- Fixed small bug in the color dialog
- Fixed small start bug (didn't show real plugin data on startup)
- Added restore function
- Fixed code-explorer bug (didn't recognize @-functions)
- Fixed highlight bug (had problems with ^" and ^ in strings)
- Fixed potential crash bug
- Fixed another highlight bug
- Fixed aother code-explorer bug...
- Added 2 settings (for auto-complete and calltips)
- Added SCM_SETTINGS_REMOVEPAGE-message
- Fixed SCM_SETTINGS_CREATEPAGE bug
2005-10-07 21:52:48 +00:00
76b6510a27 686->586 2005-10-02 20:15:52 +00:00
a75feafc4f Downgraded compile time flags to 586 2005-10-02 20:12:48 +00:00
86c2c2db02 Fixed bug where core isn't notified of a team change 2005-10-02 09:57:25 +00:00
21d13507b1 fixed an error output msg 2005-09-28 22:10:11 +00:00
adfe7de08e callfunc_begin_i should not take -1 2005-09-27 19:51:23 +00:00
116536fe36 Fix for bug 19453 (karlos) 2005-09-26 22:11:44 +00:00
f7dbc25461 fixed a small typo 2005-09-23 13:01:33 +00:00
30736ebb53 Updated SciLexer 2005-09-22 11:51:01 +00:00
dc5e458d9e Updated installer script to 1.60 2005-09-22 07:06:28 +00:00
4feaa1449f Fixed bug in Makefile 2005-09-22 06:34:58 +00:00
25002f559a Fixed bad compiler build (oh my god, linux sucks) 2005-09-22 06:16:45 +00:00
41f38424ee Fix for linux 64bit filenames 2005-09-22 05:12:23 +00:00
862ee2029a Bumped version 2005-09-22 03:42:43 +00:00
cd30fb0c1c Bumped version numbers 2005-09-22 02:23:13 +00:00
59ad6c49e3 Bumped version 2005-09-22 02:14:21 +00:00
2d255829a6 bumped version 2005-09-22 02:13:45 +00:00
be762580b7 Bumped versions 2005-09-22 02:13:23 +00:00
ae8bf10746 Fixed bug at18021 (hondaman)
Fixed bug at18924 (Arnold)
2005-09-18 03:26:26 +00:00
324f4c58a8 cleaned revision for cstrike plugins 2005-09-18 03:19:34 +00:00
a816767abb Fixed bug at18919 2005-09-18 02:59:36 +00:00
164a47bde4 Import of windows version 2005-09-18 01:25:22 +00:00
545769e241 Bumped version number 2005-09-18 01:15:03 +00:00
dcf39196d5 Ugly hack to get around ELF garbage 2005-09-18 01:14:44 +00:00
58dd553d00 Loads from non-cwd now 2005-09-18 01:14:23 +00:00
f64ca6a827 Stupid ugly hack to get around ELF's garbage
Import of newer compiler
2005-09-18 01:13:18 +00:00
ebd4974c75 final cleaned revision (I hope) 2005-09-16 23:48:51 +00:00
4b1769f457 Added feature request at18988 2005-09-15 17:53:02 +00:00
f58c0f4508 added request for EKS at18961 2005-09-15 00:51:27 +00:00
4d7bdcde47 Fixed configs not being copied on Linux 2005-09-14 03:41:20 +00:00
c7a620424e *** empty log message *** 2005-09-14 02:38:19 +00:00
24260137ec hope to have fixed the spacings finally 2005-09-14 01:40:48 +00:00
315e69797d more fixes 2005-09-14 00:42:56 +00:00
dddc693369 Fixed spacing 2005-09-14 00:38:48 +00:00
13e654aafe small format changes 2005-09-13 16:05:57 +00:00
f02c73f94c Correct spacing! 2005-09-13 07:37:50 +00:00
92f79ffe88 left debug stuff in 2005-09-13 07:36:01 +00:00
db33e50f92 Fixed a bug where stocks using native names crashed 2005-09-13 07:32:07 +00:00
2ad557024e more cleanups 2005-09-13 01:00:19 +00:00
ddf3b6df32 new cleaned-up version of the plugins (no more OLOcode :D) 2005-09-12 21:06:24 +00:00
12bf140931 Fixed a small save bug 2005-09-12 16:08:45 +00:00
0d65bb64f9 Updated for latest version 2005-09-11 20:54:03 +00:00
c6e265b414 little changes 2005-09-11 20:35:35 +00:00
9ba597b5c1 Fixed bug at18791 (Maddo) 2005-09-11 19:15:49 +00:00
b6a4514bd0 Fixed bug at18763 (karlos) 2005-09-11 18:57:33 +00:00
a6daebe7d4 Made SQL changes by Lazarus Long 2005-09-11 18:37:55 +00:00
471ba0adbf Updated FTP function (now handles misunderstood SITE CHMOD commands) 2005-09-11 15:45:42 +00:00
7225aa3cc0 Fixed font bug 2005-09-11 14:32:16 +00:00
88b833f879 Updated version to 1.60 2005-09-11 11:52:19 +00:00
6f8816c13f Fixed another shortcut bug
Released 1.2
2005-09-11 11:15:22 +00:00
95ccd6078c Fixed bug at18607 (lantz69) 2005-09-11 07:19:06 +00:00
2e5c71f771 Fixed bug at18607 (lantz69) 2005-09-11 07:17:31 +00:00
eeb77395cd Fixed bug at18615 (Lazarus Long) 2005-09-11 07:13:44 +00:00
e3afe22a48 Fixed initialization bug in native filters
Fixed bug where address boundaries were not checked on arrays
2005-09-11 05:43:17 +00:00
73d70aff29 added module_exists 2005-09-11 04:43:40 +00:00
120c849e4b Added native filter 2005-09-11 04:32:40 +00:00
138b732e75 New plmenu 2005-09-11 04:31:13 +00:00
760e29e531 Finalized new debugging system 2005-09-11 03:58:38 +00:00
401ee3c97f Added another function or something 2005-09-11 03:55:48 +00:00
6e52ce7678 New natives 2005-09-11 03:13:45 +00:00
89aab62549 Removed them from AMXX-Studio 2005-09-10 21:58:40 +00:00
468d99ff70 Updated about dialog
Updated a few plugin commands
Removed splashscreen
Added some themes
Updated some captions
2005-09-10 21:55:22 +00:00
2d787f43de updated version of CString.h 2005-09-10 21:04:05 +00:00
f0c5e44985 fixed plugin location comments on stat plugins
replaced 0.20 with AMXX_VERSION_STR
removed all require_modules
2005-09-10 20:51:49 +00:00
76760b221d more cleaned-up code 2005-09-10 20:09:14 +00:00
612a86dbef Added new debugging functions 2005-09-10 18:26:13 +00:00
369ece2d56 ----------------------------------------------------------------------
Linux compatibility problem in debugger.cpp, made Makefile also compile
debugger.cpp
2005-09-10 18:19:02 +00:00
cc37f479aa Added Phase 3 of the debugger (debug tracing from plugins) 2005-09-10 07:24:26 +00:00
deaaf20713 Fixed preproc bugs 2005-09-10 05:30:24 +00:00
e566413224 Fixed MORE lines 2005-09-10 05:23:30 +00:00
368856f122 Fixed lines 2005-09-10 05:22:06 +00:00
52cc204787 Fixed numerous bugs in preprocessor (string literals being parsed, mismatched args being wiped) 2005-09-10 05:04:23 +00:00
52b1d67ca2 latest cleaned files for today (i cant read more :o ) 2005-09-10 03:39:23 +00:00
16ad8739e7 started the clean-up of cpp files 2005-09-10 00:59:24 +00:00
e67457440d cleaned-up versions of header files 2005-09-10 00:38:42 +00:00
fc955009da cleaned-up version of ccmd.h 2005-09-09 23:54:15 +00:00
0dc2ba85e8 Added set_error_filter() 2005-09-09 23:13:34 +00:00
de65e65854 added set_error_filter 2005-09-09 23:03:26 +00:00
d95f2cba37 Fixed another small shortcut bug
Updated "Select color" dialog
Removed "Do not restore caret" property, not useful
2005-09-09 23:01:09 +00:00
e2a521583a Fixed shortcut bugs
Fixed include bug
Changed a few small things in the core
2005-09-09 16:49:41 +00:00
f8aac5e88d Reworked code to support error handling, LogError() is separate from DisplayTrace() implementation 2005-09-09 16:04:44 +00:00
4738c92b8e Committed new debugger with AMX fixes 2005-09-09 03:23:31 +00:00
7ce59966fc Replaced with faluco's cleaned-up version of meta_api.cpp 2005-09-08 22:20:27 +00:00
afa1337e62 because gabe doesn't rollover, he just expands 2005-09-08 15:29:31 +00:00
cc34f468f0 Added a new math stock function. 2005-09-08 15:24:28 +00:00
3f9598fcbb Changed .amx in examples for pause() and callfunc_begin() to .amxx (as requested by XxAvalanchexX on the forums) 2005-09-08 13:05:44 +00:00
97b5391118 Logs the map name on mapchange (as requested by lantz69 on forums) 2005-09-08 13:03:38 +00:00
227c13d12c Added abs(x) stock 2005-09-08 12:58:17 +00:00
729932476b Fixed memory leak
Updated Modified-Event (now only one parameter [the modified text])
2005-09-07 22:31:31 +00:00
7c21deb0f2 Fixed memory leak
Updated Modified-Event (now only one parameter [the modified text])
2005-09-07 22:20:28 +00:00
80048eba61 Fixed memory leak
Updated Modified-Event (now only one parameter [the modified text])
2005-09-07 22:10:21 +00:00
0552e5ef58 Deprecated jghg2 include 2005-09-07 15:40:46 +00:00
ce881a7d30 Fixed bug at18558 (Nijule) 2005-09-07 00:11:10 +00:00
80dd7f034d version bump 2005-09-06 22:28:47 +00:00
5fac746feb compiler fix merge 2005-09-06 22:28:32 +00:00
67f012b74a Fixed bug where static declarations would crash 2005-09-06 21:34:33 +00:00
5705e69abb Fixed bug where level>1 arrays were walked incorrectly 2005-09-06 20:36:02 +00:00
bece1e6d0c Added float_to_str and str_to_float natives 2005-09-06 16:34:17 +00:00
f2527ecc86 The query_client_cvar native now checks for a non-zero g_engfuncs.pfnQueryClientCvarValue before proceeding 2005-09-06 16:31:54 +00:00
66b95f64a5 Now checks whether there is a non-zero g_engfuncs.pfnQueryClientCvarValue before setting newdll's pfnCvarValue function pointer 2005-09-06 16:31:07 +00:00
af79fe8e20 Added natives str_to_float and float_to_str; indents are now tabs 2005-09-06 16:29:27 +00:00
d3e2bad4e7 Added query_client_cvar native 2005-09-06 10:14:32 +00:00
6bebf37f1a An optional array parameter (LIKE TEH TASKS ONE) can be now passed to cvar query handlers 2005-09-06 10:12:02 +00:00
2f27b7da8d zomg! updated teh vectorz codeses a bit! Hopefully didn't break anything 2005-09-06 09:34:13 +00:00
824caab2c5 Fixed bug p1123143748 (Twilight Suzuka) 2005-09-06 03:00:01 +00:00
a105bc7402 Fixed bug at18003 (Geesu)
Fixed bug p1123149221 (Twilight Suzuka)
2005-09-06 01:55:41 +00:00
81ab33d794 Fixed shortcut bug in the settings dialog (couldn't set hotkeys to BkSp etc.)
Added "Reset" button to shortcuts page
2005-09-05 22:33:45 +00:00
e90364c17b Fixed bug at18525 (twistedeuphoria). 2005-09-05 22:05:23 +00:00
ac4014ff5a Fixed bug at18473 (Greenberet). 2005-09-05 21:59:44 +00:00
ad634924fa Fixed two bugs from at18519 (Lord of Destruction) 2005-09-05 21:43:05 +00:00
2d5f9ba181 Using the (*g_engfuncs.pfnQueryClientCvarValue) directlty instead of the macro so that it compiles on both metamod and metamod-p 2005-09-05 20:51:24 +00:00
aa0e4e121e Now properly cleaning up pending client cvar queries in the queue on client disconnect 2005-09-05 19:56:40 +00:00
f8227a09b4 updated to September 2005-09-04 22:40:43 +00:00
46130a6754 *** empty log message *** 2005-09-04 13:25:24 +00:00
58c006a9c8 Ready for release (1.1) 2005-09-04 13:03:34 +00:00
ea1d72401c Fixed switch bug, now even (much) faster
Updated aboutbox
2005-09-03 23:47:40 +00:00
fdbe0e2064 Upgraded plugin-system (other command call and now 93 commands)
Customizable IRC Paster
Updated version number from 1.01 to 1.1
2005-09-03 20:00:46 +00:00
e239801671 fixed get_map_info function 2005-09-03 13:59:33 +00:00
4be88a5015 version bump 2005-09-02 07:10:56 +00:00
ee02d0b13d this must be off! 2005-09-02 04:07:49 +00:00
2ec084ffa3 Patch for bug at18251 2005-09-02 04:06:47 +00:00
6636c20336 Fixed bug at18250 2005-09-02 03:44:15 +00:00
27c80b00f8 Fix for bug at18293. 2005-09-02 03:28:44 +00:00
6bcb72952c Applied patch for bug at18341 (jtp10181) 2005-09-02 02:46:42 +00:00
8c17be27dd Updated AMXx version 1.56 2005-09-01 17:11:48 +00:00
0232b0abee Bumped versions 2005-08-31 20:36:41 +00:00
12fd7a9f0d Added new DBI functions
Fixed bugs in field getting
2005-08-31 20:32:29 +00:00
71c6e70706 Updated for new API 2005-08-31 20:08:12 +00:00
c5cc94ba98 Added new natives 2005-08-31 04:36:25 +00:00
8220cc4c01 is_in_viewcone from in_view_cone 2005-08-30 23:22:27 +00:00
57ce74c4c7 Bumped version, lowered -O flag 2005-08-30 18:43:11 +00:00
5d6c72bf42 Patch for pausing issues 2005-08-30 07:18:47 +00:00
63b2bbc67e Made more de-allocation safety precautions 2005-08-30 07:15:27 +00:00
12f628e3d7 Fixed bug at18162 (vittu) 2005-08-30 07:00:49 +00:00
cd8d800eb7 Fixed bug at17920 (Grasshoper) 2005-08-30 06:59:50 +00:00
160ab3572b Fixed typo at18108 (FireStorm) 2005-08-30 06:57:41 +00:00
dc57ef1e0c Simple implementation for cvar queries 2005-08-27 23:00:44 +00:00
ca1544564c Upped to 3.2.5. 2005-08-27 21:27:35 +00:00
462916d00f Got rid of many annoying warnings MSVC7.1 was reporting 2005-08-27 09:55:32 +00:00
e15761b79a Updated plugin system 2005-08-27 01:47:15 +00:00
270d898f82 Fixed shortcut bug 2005-08-26 23:22:30 +00:00
2a2d5697b8 Fixed some bugs
Upgraded exception handler, now using madCollection
2005-08-26 22:59:25 +00:00
b17f277a1b Added AMXX-Studio to CVS 2005-08-26 19:07:54 +00:00
c15ed5741a Added AMXX-Studio to CVS 2005-08-26 18:53:19 +00:00
9e035dc744 Added AMXX-Studio to CVS 2005-08-26 18:29:39 +00:00
ac279b37e4 Removed old Makefile 2005-08-26 15:57:50 +00:00
974fdc950e Added new standard makefile 2005-08-26 15:54:42 +00:00
8bb01423b9 Updated api 2005-08-25 09:40:29 +00:00
401a23a298 Updated install script 2005-08-25 09:34:31 +00:00
7ac9ed4b80 *** empty log message *** 2005-08-25 09:27:32 +00:00
6fdcd8ffae Fixed NS build 2005-08-25 09:20:10 +00:00
d50a6302e0 ugh 2005-08-25 09:09:35 +00:00
5fd891bc32 Fixed version # 2005-08-25 08:34:26 +00:00
864f7c268e Fixed module for AMD64 2005-08-25 08:34:09 +00:00
4770f28a18 *** empty log message *** 2005-08-25 08:26:28 +00:00
51a4e2bf4e *** empty log message *** 2005-08-25 08:21:07 +00:00
c213c771d2 Fixed compression on Linux 2005-08-25 08:20:11 +00:00
0176d3a2ae Actual fix for compression! 2005-08-25 08:02:48 +00:00
92653ceebc Fixes for compression 2005-08-25 07:50:21 +00:00
c9051ad364 Fixed includes 2005-08-25 07:34:47 +00:00
94d350118d *** empty log message *** 2005-08-25 07:30:34 +00:00
2e22dde409 Removed extra forwards 2005-08-25 07:16:17 +00:00
4dad81af30 Merged in new ts includes 2005-08-25 07:13:48 +00:00
b271b01b13 Synced to Twilight's stuff 2005-08-25 07:12:52 +00:00
a17b879380 Merged in original TSFun 2005-08-25 07:09:16 +00:00
ea05af9fe8 updated to August 2005-08-25 01:15:30 +00:00
d661196429 Fixed bug at17860 2005-08-25 00:19:39 +00:00
1114443a43 Fixed for AMD64 compatibility 2005-08-24 18:13:40 +00:00
d802a3c961 gcc-3. compat 2005-08-24 07:32:01 +00:00
e2226ae809 Fixed linux compiling 2005-08-24 07:16:45 +00:00
fd8a27013b CVS Cleanup 2005-08-24 07:07:34 +00:00
b12224eabd CVS Cleanup 2005-08-24 07:01:02 +00:00
c30c3cf35c CVS cleanup 2005-08-24 06:57:32 +00:00
f828cde999 Updated ESF and CS 2005-08-24 06:56:02 +00:00
d05c381789 Added cstrike specific switch 2005-08-24 06:39:52 +00:00
245054cf48 Fixed bug at17739 (mysticssjgoku4) 2005-08-24 06:29:12 +00:00
da82ce757f Defaulted engine+fm on 2005-08-24 06:19:41 +00:00
4d74743138 Removed esf module 2005-08-24 06:15:41 +00:00
c1db39d086 Added Corona Byte's EvolutionX core 2005-08-24 06:13:55 +00:00
d516824936 Add copy exclusion filters
Repaired windows builder
Fixed /build to be /rebuild
2005-08-24 05:19:23 +00:00
10328f5f81 fixes 2005-08-24 05:08:05 +00:00
d4f09aac74 Wrong, look at the distro. And in the future change for all mod config sets if you do 2005-08-24 03:20:09 +00:00
8f97ed7934 Deleted bad file 2005-08-24 03:14:13 +00:00
1fcf7628a3 Added in real file 2005-08-24 03:13:57 +00:00
bdd740f8ab Added makefile 2005-08-24 02:54:39 +00:00
82fed37247 Updated to work on Linux, redesigned core 2005-08-24 02:53:38 +00:00
5b208eb9f5 gcc-3 compat 2005-08-24 02:36:05 +00:00
9be88ffa42 Linux compat, cleaned up newdll 2005-08-23 23:54:54 +00:00
f54d112bbb Language sync 2005-08-23 01:24:42 +00:00
96c4d33da4 - Updated to Sqlite 3.2.3. See sqlite.org for details about new stuff.
- Base dir for db files is now changed to the game mod dir. Update your config files!
2005-08-22 10:12:22 +00:00
bad4c02647 This file copied from mysql module... I assume this was forgotten during the last commit of amxxmodule.cpp... 2005-08-22 09:18:55 +00:00
70140ffc8f Fixed team menu. Should now work 100% to switch players between teams. However when client uses VGUI menus I haven't been able to close the class selecting window. It is (should be) only a cosmetic flaw though. 2005-08-22 08:01:01 +00:00
53e6bb6b50 No default sql 2005-08-22 01:04:41 +00:00
4cb7986426 admin.sma was "slightly" incompatible for people using sqlite. This version is courtesy of Lazarus Long who fixed this. Thanks. 2005-08-22 00:26:18 +00:00
18ba13be84 Removed the admin_sql.amxx line. It's all in admin.sma now, isn't it??? 2005-08-22 00:21:49 +00:00
dd371c4dbe no idea, I changed something though 2005-08-21 22:48:22 +00:00
7ea47c5a96 Fixed a deallocation mismatch with debug plugins in linux 2005-08-21 21:54:14 +00:00
5693d2629e Attempted fix at DEP 2005-08-21 19:30:27 +00:00
24d9e3266e wrong include, added pdata 2005-08-21 16:38:45 +00:00
b3b3ce4c2d added more pdata funcs 2005-08-21 16:36:40 +00:00
5882802a3e Added set/get pdata string 2005-08-21 16:33:38 +00:00
94e19aae0c Removed newdllfunc() and related NEWDLLFunc_* stuff. :-P (yes I finally read Alfred's post through) 2005-08-18 20:51:41 +00:00
7d51404aeb What!!! 2005-08-18 15:47:28 +00:00
1cdb12c4e4 Added NEW_DLL_FUNCTIONS to FM_* and a newdllfunc() native to call these... Although I'm not sure there is a reason to call those?
Anyway it will be needed later when client cvar query function is implemented.
2005-08-18 09:33:51 +00:00
e9993cce25 amd64 == no more libstdc++ 2005-08-18 08:44:01 +00:00
80bd845182 *** empty log message *** 2005-08-18 08:36:48 +00:00
f986202b06 AMD64 no stdc++ support 2005-08-18 08:33:21 +00:00
a4168a2096 version bump 2005-08-18 07:53:14 +00:00
3e85589930 Fix for bug at16876 (TheRising) 2005-08-18 07:05:33 +00:00
b5a57da29c Fixed linux build (I think) 2005-08-18 07:03:43 +00:00
58fec512e5 Now requires GCC-3 to compile, fixes retarded linking problem 2005-08-18 07:01:47 +00:00
a6ca045086 More SDK syncs 2005-08-18 06:41:59 +00:00
e401231d25 *** empty log message *** 2005-08-18 06:40:24 +00:00
9ddc24898f same win32 fix 2005-08-18 06:37:50 +00:00
f5350c0e0e fix for win32 2005-08-18 06:37:05 +00:00
fa64bef511 New SDK for gcc-3 compilations 2005-08-18 06:34:34 +00:00
29bfd81b36 New SDK for gcc-3 compilation 2005-08-18 06:32:59 +00:00
2d2506f1c4 Added memalign include 2005-08-18 01:04:52 +00:00
f334fec0a3 Added linux compile of altered JIT 2005-08-18 00:32:08 +00:00
03b6d3e77d Fixed alloc/dealloc mismatches 2005-08-18 00:29:43 +00:00
661f6c9851 Fixed bug at17357 (FireStorm) 2005-08-17 18:16:26 +00:00
593e013572 fixed typo 2005-08-17 17:53:11 +00:00
b04498cddb Experimental fix for bug at16815 (karlos) 2005-08-17 17:32:51 +00:00
8648bf32a3 Improved error reporting a bit 2005-08-17 17:21:57 +00:00
1768ae4b23 Fixed bug at17117 (Twilight Suzuka) 2005-08-17 17:07:41 +00:00
80e6d31998 updated sdks 2005-08-17 16:52:12 +00:00
381e331dda updated sdk 2005-08-17 16:50:01 +00:00
13c65f006b SDK no longer manages memory by default 2005-08-17 16:48:31 +00:00
4e8eff3e04 Fixed bug at17021. 2005-08-17 16:41:38 +00:00
572ad38366 Quick fix for bug at16854 (twistedeuphoria) 2005-08-17 16:16:56 +00:00
b2ade117ec Added bug fix at17218 (Freecode) 2005-08-17 16:12:45 +00:00
9eb36bd2bb Fixed bug where first call had wrong stack alignment
Tiny optimizations
2005-08-17 15:57:11 +00:00
85b7ac740b Experimental JIT fixes for linux crashing (no more xchg of esp) 2005-08-16 23:09:55 +00:00
98d3fb79d7 Fixed some mmgr bugs 2005-08-15 21:38:03 +00:00
bf092b4f95 Updated to Sqlite 3.2.2. 2005-08-11 19:06:54 +00:00
a4a9613f5b *** empty log message *** 2005-08-11 02:49:58 +00:00
ad86bf636f enabled statsx by default 2005-08-10 18:37:02 +00:00
d0b5886d7d Added cs_get_armoury_type and cs_set_armoury_type 2005-08-07 20:43:29 +00:00
aa75a143fc This should fix the problem where bots can't hit players using weapons other than the knife. 2005-08-07 13:38:34 +00:00
7144f5c794 updated error handler 2005-08-04 23:46:22 +00:00
befb651268 fixed design bug (adds now Skipped when file is skipped)
fixed ESF install bug (didn't install, invalid pathes)
2005-08-03 18:45:16 +00:00
c8fdea6216 Fixed bug found by T(+)rget 2005-08-03 16:33:52 +00:00
4a6a16c627 NADE_CATCHED changed to NADE_CAUGHT 2005-08-03 15:01:54 +00:00
881 changed files with 196851 additions and 45844 deletions

View File

@ -35,8 +35,10 @@
// *****************************************************
// class CmdMngr
// *****************************************************
CmdMngr::CmdMngr() {
memset(sortedlists,0,sizeof(sortedlists));
CmdMngr::CmdMngr()
{
memset(sortedlists, 0, sizeof(sortedlists));
srvcmdlist = 0;
clcmdlist = 0;
prefixHead = 0;
@ -49,13 +51,12 @@ CmdMngr::CmdMngr() {
}
CmdMngr::Command::Command( CPluginMngr::CPlugin* pplugin,const char* pcmd,
const char* pinfo , int pflags , int pfunc,
bool pviewable, CmdMngr* pparent ) : commandline(pcmd) , info(pinfo) {
CmdMngr::Command::Command(CPluginMngr::CPlugin* pplugin, const char* pcmd, const char* pinfo, int pflags,
int pfunc, bool pviewable, CmdMngr* pparent) : commandline(pcmd), info(pinfo)
{
char szCmd[64], szArg[64];
*szCmd = 0; *szArg=0;
sscanf(pcmd,"%s %s",szCmd,szArg);
*szCmd = 0; *szArg = 0;
sscanf(pcmd, "%s %s", szCmd, szArg);
command.assign(szCmd);
argument.assign(szArg);
plugin = pplugin;
@ -73,75 +74,68 @@ CmdMngr::Command::~Command()
++uniqueid;
}
CmdMngr::Command* CmdMngr::registerCommand( CPluginMngr::CPlugin* plugin , int func , char* cmd , char* info , int level , bool listable )
CmdMngr::Command* CmdMngr::registerCommand(CPluginMngr::CPlugin* plugin, int func, char* cmd, char* info, int level, bool listable)
{
Command* b = new Command( plugin , cmd , info , level , func , listable, this );
if ( b == 0 ) return 0;
setCmdLink( &sortedlists[0] , b );
Command* b = new Command(plugin, cmd, info, level, func, listable, this);
if (b == 0) return 0;
setCmdLink(&sortedlists[0], b);
return b;
}
CmdMngr::Command* CmdMngr::getCmd( long int id ,int type, int access )
CmdMngr::Command* CmdMngr::getCmd(long int id, int type, int access)
{
//if ( id >= 1024 || id < 0 ) return (Command*)id;
if ( id < 0 ){
for (CmdMngr::iterator a = begin( type ); a ; ++a){
if ( (*a).id == id )
//if (id >= 1024 || id < 0) return (Command*)id;
if (id < 0)
{
for (CmdMngr::iterator a = begin(type); a ; ++a)
{
if ((*a).id == id)
return &(*a);
}
return 0;
}
if ( (id < buf_cmdid) || (access != buf_cmdaccess) || (type != buf_cmdtype) )
if ((id < buf_cmdid) || (access != buf_cmdaccess) || (type != buf_cmdtype))
{
buf_cmdptr = begin( type );
buf_cmdptr = begin(type);
buf_cmdaccess = access;
buf_cmdtype = type;
buf_cmdid = id;
}
else
{
} else {
int a = id;
id -= buf_cmdid;
buf_cmdid = a;
}
while ( buf_cmdptr )
while (buf_cmdptr)
{
if ( (*buf_cmdptr).gotAccess( access ) &&
(*buf_cmdptr).getPlugin()->isExecutable( (*buf_cmdptr).getFunction() )
&& (*buf_cmdptr).isViewable() )
if ((*buf_cmdptr).gotAccess(access) && (*buf_cmdptr).getPlugin()->isExecutable((*buf_cmdptr).getFunction()) && (*buf_cmdptr).isViewable())
{
if ( id-- == 0 )
if (id-- == 0)
return &(*buf_cmdptr);
}
++buf_cmdptr;
}
return 0;
}
int CmdMngr::getCmdNum( int type, int access )
int CmdMngr::getCmdNum(int type, int access)
{
if ( (access == buf_access) && (type == buf_type) )
if ((access == buf_access) && (type == buf_type))
return buf_num; // once calculated don't have to be done again
buf_access = access;
buf_type = type;
buf_num = 0;
CmdMngr::iterator a = begin( type );
CmdMngr::iterator a = begin(type);
while ( a )
while (a)
{
if ( (*a).gotAccess( access ) &&
(*a).getPlugin()->isExecutable( (*a).getFunction() )
&& (*a).isViewable() )
if ((*a).gotAccess(access) && (*a).getPlugin()->isExecutable((*a).getFunction()) && (*a).isViewable())
++buf_num;
++a;
}
@ -149,19 +143,19 @@ int CmdMngr::getCmdNum( int type, int access )
return buf_num;
}
void CmdMngr::setCmdLink( CmdLink** a , Command* c, bool sorted )
void CmdMngr::setCmdLink(CmdLink** a, Command* c, bool sorted)
{
CmdLink* np = new CmdLink( c );
CmdLink* np = new CmdLink(c);
if ( np == 0 ) return;
if (np == 0) return;
if ( sorted )
if (sorted)
{
while( *a )
while (*a)
{
int i = strcmp(c->getCommand(),(*a)->cmd->getCommand() );
int i = strcmp(c->getCommand(), (*a)->cmd->getCommand());
if ( (i<0) || (i==0) && ( strcmp( c->getArgument() , (*a)->cmd->getArgument() ) < 0 ) )
if ((i < 0) || (i == 0) && (strcmp(c->getArgument(), (*a)->cmd->getArgument()) < 0))
break;
a = &(*a)->next;
@ -169,84 +163,101 @@ void CmdMngr::setCmdLink( CmdLink** a , Command* c, bool sorted )
np->next = *a;
*a = np;
}
else
{
while ( *a ) a = &(*a)->next;
} else {
while (*a) a = &(*a)->next;
*a = np;
}
}
void CmdMngr::clearCmdLink( CmdLink** phead, bool pclear )
void CmdMngr::clearCmdLink(CmdLink** phead, bool pclear)
{
while( *phead ){
while (*phead)
{
CmdLink* pp = (*phead)->next;
if ( pclear ) delete (*phead)->cmd;
if (pclear) delete (*phead)->cmd;
delete *phead;
*phead = pp;
}
}
void CmdMngr::Command::setCmdType( int a )
void CmdMngr::Command::setCmdType(int a)
{
switch(a){
switch (a)
{
case CMD_ConsoleCommand: cmdtype |= 3; break;
case CMD_ClientCommand: cmdtype |= 1; break;
case CMD_ServerCommand: cmdtype |= 2; break;
}
if ( cmdtype & 1 ) { // ClientCommand
parent->setCmdLink( &parent->sortedlists[1] , this );
if ( !parent->registerCmdPrefix( this ) )
parent->setCmdLink( &parent->clcmdlist , this , false );
if (cmdtype & 1) // ClientCommand
{
parent->setCmdLink(&parent->sortedlists[1], this);
if (!parent->registerCmdPrefix(this))
parent->setCmdLink(&parent->clcmdlist, this, false);
}
if ( cmdtype & 2 ) { // ServerCommand
parent->setCmdLink( &parent->sortedlists[2] , this );
parent->setCmdLink( &parent->srvcmdlist , this , false );
if (cmdtype & 2) // ServerCommand
{
parent->setCmdLink(&parent->sortedlists[2], this);
parent->setCmdLink(&parent->srvcmdlist, this, false);
}
}
const char* CmdMngr::Command::getCmdType() const {
switch( cmdtype ){
case 1: return"client";
const char* CmdMngr::Command::getCmdType() const
{
switch (cmdtype)
{
case 1: return "client";
case 2: return "server";
case 3: return "console";
}
return "unknown";
}
bool CmdMngr::registerCmdPrefix( Command* cc )
bool CmdMngr::registerCmdPrefix(Command* cc)
{
CmdPrefix** b = findPrefix( cc->getCommand() );
if (*b){
setCmdLink( &(*b)->list , cc , false );
CmdPrefix** b = findPrefix(cc->getCommand());
if (*b)
{
setCmdLink(&(*b)->list, cc, false);
cc->prefix = (*b)->name.size();
return true;
}
return false;
}
void CmdMngr::registerPrefix( const char* nn )
void CmdMngr::registerPrefix(const char* nn)
{
if ( *nn == 0 ) return;
CmdPrefix** b = findPrefix( nn );
if (*nn == 0) return;
CmdPrefix** b = findPrefix(nn);
if (*b) return;
*b = new CmdPrefix( nn , this );
*b = new CmdPrefix(nn, this);
}
CmdMngr::CmdPrefix** CmdMngr::findPrefix( const char* nn ){
CmdMngr::CmdPrefix** CmdMngr::findPrefix(const char* nn)
{
CmdPrefix** aa = &prefixHead;
while(*aa){
if ( !strncmp( (*aa)->name.c_str(), nn, (*aa)->name.size() ) )
while (*aa)
{
if (!strncmp((*aa)->name.c_str(), nn, (*aa)->name.size()))
break;
aa=&(*aa)->next;
aa = &(*aa)->next;
}
return aa;
}
void CmdMngr::clearPrefix(){
while(prefixHead){
void CmdMngr::clearPrefix()
{
while (prefixHead)
{
CmdPrefix* a = prefixHead->next;
delete prefixHead;
prefixHead = a;
@ -264,7 +275,8 @@ void CmdMngr::clear()
clearBufforedInfo();
}
void CmdMngr::clearBufforedInfo() {
void CmdMngr::clearBufforedInfo()
{
buf_type = -1;
buf_access = 0;
buf_id = -1;

View File

@ -36,7 +36,8 @@
// class CmdMngr
// *****************************************************
enum {
enum
{
CMD_ConsoleCommand,
CMD_ClientCommand,
CMD_ServerCommand
@ -48,14 +49,17 @@ public:
class Command;
friend class Command;
class Command {
class Command
{
friend class CmdMngr;
CPluginMngr::CPlugin* plugin;
CmdMngr* parent;
String command;
String argument;
String commandline;
String info;
bool listable;
int function;
int flags;
@ -63,33 +67,33 @@ public:
int cmdtype;
int prefix;
static int uniqueid;
Command( CPluginMngr::CPlugin* pplugin,const char* pcmd, const char* pinfo , int pflags , int pfunc, bool pviewable, CmdMngr* pparent );
Command(CPluginMngr::CPlugin* pplugin, const char* pcmd, const char* pinfo, int pflags, int pfunc, bool pviewable, CmdMngr* pparent);
~Command();
public:
inline const char* getCommand() { return command.c_str(); }
inline const char* getArgument() { return argument.c_str(); }
inline const char* getCmdInfo() { return info.c_str(); }
inline const char* getCmdLine() { return commandline.c_str(); }
inline bool matchCommandLine(const char* cmd, const char* arg) { return (!stricmp(command.c_str()+prefix, cmd+prefix ) && (argument.empty() || !stricmp(argument.c_str() , arg ))); }
inline bool matchCommand(const char* cmd) { return (!strcmp(command.c_str(), cmd )); }
inline bool matchCommandLine(const char* cmd, const char* arg) { return (!stricmp(command.c_str() + prefix, cmd + prefix) && (argument.empty() || !stricmp(argument.c_str(), arg))); }
inline bool matchCommand(const char* cmd) { return (!strcmp(command.c_str(), cmd)); }
inline int getFunction() const { return function; }
inline bool gotAccess(int f) const { return (!flags||((flags & f)==flags)); }
inline bool gotAccess(int f) const { return (!flags || ((flags & f) == flags)); }
inline CPluginMngr::CPlugin* getPlugin() { return plugin; }
inline bool isViewable() const { return listable; }
inline int getFlags() const { return flags; }
inline long int getId() const { return (long int)id; }
const char* getCmdType() const;
void setCmdType( int a );
const char* getCmdType() const;
void setCmdType(int a);
};
private:
struct CmdPrefix;
friend struct CmdPrefix;
struct CmdLink {
struct CmdLink
{
Command* cmd;
CmdLink* next;
CmdLink(Command* c): cmd(c), next(0) {}
@ -99,36 +103,40 @@ private:
CmdLink* srvcmdlist;
CmdLink* clcmdlist;
struct CmdPrefix {
struct CmdPrefix
{
String name;
CmdMngr* parent;
CmdLink* list;
CmdPrefix* next;
CmdPrefix( const char* nn , CmdMngr* pp) : name(nn),parent(pp),list(0),next(0){}
~CmdPrefix(){ parent->clearCmdLink(&list); }
CmdPrefix(const char* nn, CmdMngr* pp): name(nn), parent(pp), list(0), next(0) {}
~CmdPrefix() { parent->clearCmdLink(&list); }
} *prefixHead;
bool registerCmdPrefix( Command* cc );
CmdPrefix** findPrefix( const char* nn );
bool registerCmdPrefix(Command* cc);
CmdPrefix** findPrefix(const char* nn);
void clearPrefix();
void setCmdLink( CmdLink** a , Command* c, bool sorted = true );
void clearCmdLink( CmdLink** phead, bool pclear = false );
void setCmdLink(CmdLink** a, Command* c, bool sorted = true);
void clearCmdLink(CmdLink** phead, bool pclear = false);
public:
CmdMngr();
~CmdMngr() {clear();}
~CmdMngr() { clear(); }
// Interface
void registerPrefix( const char* nn );
Command* registerCommand( CPluginMngr::CPlugin* plugin , int func , char* cmd , char* info , int level , bool listable );
Command* getCmd( long int id ,int type, int access);
int getCmdNum( int type, int access );
void registerPrefix(const char* nn);
Command* registerCommand(CPluginMngr::CPlugin* plugin, int func, char* cmd, char* info, int level, bool listable);
Command* getCmd(long int id, int type, int access);
int getCmdNum(int type, int access);
void clearBufforedInfo();
void clear();
class iterator {
class iterator
{
CmdLink *a;
public:
iterator(CmdLink*aa = 0) : a(aa) {}
@ -138,28 +146,30 @@ public:
operator bool () const { return a ? true : false; }
Command& operator*() { return *a->cmd; }
};
inline iterator clcmdprefixbegin(const char* nn){
inline iterator clcmdprefixbegin(const char* nn)
{
CmdPrefix* a = *findPrefix(nn);
return iterator( a ? a->list : 0 );
return iterator(a ? a->list : 0);
}
inline iterator clcmdbegin() const {return iterator(clcmdlist);}
inline iterator srvcmdbegin() const {return iterator(srvcmdlist);}
inline iterator begin( int type ) const { return iterator(sortedlists[type]); }
inline iterator clcmdbegin() const { return iterator(clcmdlist); }
inline iterator srvcmdbegin() const { return iterator(srvcmdlist); }
inline iterator begin(int type) const { return iterator(sortedlists[type]); }
inline iterator end() const { return iterator(0); }
private:
int buf_cmdid;
int buf_cmdtype;
int buf_cmdaccess;
iterator buf_cmdptr;
int buf_id;
int buf_type;
int buf_access;
int buf_num;
};
#endif
#endif //COMMANDS_H

View File

@ -48,6 +48,7 @@ EventsMngr::ClEvent::ClEvent(CPluginMngr::CPlugin* plugin, int func, int flags)
m_FlagWorld = (flags & 1) ? true : false; // flag a
m_FlagPlayer = (flags & 2) ? true : false; // flag b
m_FlagOnce = (flags & 4) ? true : false; // flag c
if (flags & 24)
{
m_FlagAlive = (flags & 16) ? true : false; // flag e
@ -64,12 +65,14 @@ EventsMngr::ClEvent::~ClEvent()
{
cond_t *tmp1 = m_Conditions;
cond_t *tmp2 = NULL;
while (tmp1)
{
tmp2 = tmp1->next;
delete tmp1;
tmp1 = tmp2;
}
m_Conditions = NULL;
}
@ -82,14 +85,17 @@ void EventsMngr::NextParam()
MsgDataEntry *tmp = NULL;
int tmpSize = 0;
if (m_ParseVault)
{
// copy to tmp
tmp = new MsgDataEntry[m_ParseVaultSize];
if (!tmp)
{
return; // :TODO: Error report !!
}
memcpy(tmp, m_ParseVault, m_ParseVaultSize * sizeof(MsgDataEntry));
tmpSize = m_ParseVaultSize;
delete [] m_ParseVault;
@ -102,6 +108,7 @@ void EventsMngr::NextParam()
m_ParseVaultSize = INITIAL_PARSEVAULT_SIZE;
m_ParseVault = new MsgDataEntry[m_ParseVaultSize];
if (tmp)
{
memcpy(m_ParseVault, tmp, tmpSize * sizeof(MsgDataEntry));
@ -128,7 +135,6 @@ EventsMngr::~EventsMngr()
clearEvents();
}
CPluginMngr::CPlugin * EventsMngr::ClEvent::getPlugin()
{
return m_Plugin;
@ -170,7 +176,7 @@ void EventsMngr::ClEvent::registerFilter(char *filter)
// rest of line
tmpCond->sValue.assign(value);
tmpCond->fValue = atof(value);
tmpCond->fValue = static_cast<float>(atof(value));
tmpCond->iValue = atoi(value);
tmpCond->next = NULL;
@ -178,10 +184,11 @@ void EventsMngr::ClEvent::registerFilter(char *filter)
if (m_Conditions)
{
cond_t *tmp = m_Conditions;
while (tmp->next)
tmp = tmp->next;
tmp->next = tmpCond;
tmp->next = tmpCond;
}
else
m_Conditions = tmpCond;
@ -194,6 +201,7 @@ EventsMngr::ClEvent* EventsMngr::registerEvent(CPluginMngr::CPlugin* plugin, int
return NULL;
ClEvent *event = new ClEvent(plugin, func, flags);
if (!event)
return NULL;
@ -216,12 +224,11 @@ void EventsMngr::parserInit(int msg_type, float* timer, CPlayer* pPlayer, int in
if (!m_Events[msg_type].size())
return;
for(ClEventVecIter iter = m_Events[msg_type].begin(); iter; ++iter)
for (ClEventVecIter iter = m_Events[msg_type].begin(); iter; ++iter)
{
if ((*iter).m_Done)
continue;
if (!(*iter).m_Plugin->isExecutable((*iter).m_Func))
{
(*iter).m_Done = true;
@ -230,7 +237,7 @@ void EventsMngr::parserInit(int msg_type, float* timer, CPlayer* pPlayer, int in
if (pPlayer)
{
if (!(*iter).m_FlagPlayer || (pPlayer->IsAlive() ? !(*iter).m_FlagAlive : !(*iter).m_FlagDead ) )
if (!(*iter).m_FlagPlayer || (pPlayer->IsAlive() ? !(*iter).m_FlagAlive : !(*iter).m_FlagDead))
{
(*iter).m_Done = true;
continue;
@ -247,6 +254,7 @@ void EventsMngr::parserInit(int msg_type, float* timer, CPlayer* pPlayer, int in
(*iter).m_Done = true;
continue;
}
m_ParseNotDone = true;
}
@ -257,6 +265,7 @@ void EventsMngr::parserInit(int msg_type, float* timer, CPlayer* pPlayer, int in
m_ParseVault[0].type = MSG_INTEGER;
m_ParseVault[0].iValue = index;
}
m_ParseFun = &m_Events[msg_type];
}
@ -266,7 +275,6 @@ void EventsMngr::parseValue(int iValue)
if (!m_ParseNotDone || !m_ParseFun)
return;
// grow if needed
++m_ParsePos;
NextParam();
@ -284,23 +292,25 @@ void EventsMngr::parseValue(int iValue)
// loop through conditions
bool execute = false;
bool anyConditions = false;
for (ClEvent::cond_t *condIter = (*iter).m_Conditions; condIter; condIter = condIter->next)
{
if (condIter->paramId == m_ParsePos)
{
anyConditions = true;
switch(condIter->type)
switch (condIter->type)
{
case '=': if (condIter->iValue == iValue) execute=true; break;
case '!': if (condIter->iValue != iValue) execute=true; break;
case '&': if (iValue & condIter->iValue) execute=true; break;
case '<': if (iValue < condIter->iValue) execute=true; break;
case '>': if (iValue > condIter->iValue) execute=true; break;
case '=': if (condIter->iValue == iValue) execute = true; break;
case '!': if (condIter->iValue != iValue) execute = true; break;
case '&': if (iValue & condIter->iValue) execute = true; break;
case '<': if (iValue < condIter->iValue) execute = true; break;
case '>': if (iValue > condIter->iValue) execute = true; break;
}
if (execute)
break;
}
}
if (anyConditions && !execute)
(*iter).m_Done = true; // don't execute
}
@ -312,7 +322,6 @@ void EventsMngr::parseValue(float fValue)
if (!m_ParseNotDone || !m_ParseFun)
return;
// grow if needed
++m_ParsePos;
NextParam();
@ -330,22 +339,25 @@ void EventsMngr::parseValue(float fValue)
// loop through conditions
bool execute = false;
bool anyConditions = false;
for (ClEvent::cond_t *condIter = (*iter).m_Conditions; condIter; condIter = condIter->next)
{
if (condIter->paramId == m_ParsePos)
{
anyConditions = true;
switch(condIter->type)
switch (condIter->type)
{
case '=': if (condIter->fValue == fValue) execute=true; break;
case '!': if (condIter->fValue != fValue) execute=true; break;
case '<': if (fValue < condIter->fValue) execute=true; break;
case '>': if (fValue > condIter->fValue) execute=true; break;
case '=': if (condIter->fValue == fValue) execute = true; break;
case '!': if (condIter->fValue != fValue) execute = true; break;
case '<': if (fValue < condIter->fValue) execute = true; break;
case '>': if (fValue > condIter->fValue) execute = true; break;
}
if (execute)
break;
}
}
if (anyConditions && !execute)
(*iter).m_Done = true; // don't execute
}
@ -374,21 +386,24 @@ void EventsMngr::parseValue(const char *sz)
// loop through conditions
bool execute = false;
bool anyConditions = false;
for (ClEvent::cond_t *condIter = (*iter).m_Conditions; condIter; condIter = condIter->next)
{
if (condIter->paramId == m_ParsePos)
{
anyConditions = true;
switch(condIter->type)
switch (condIter->type)
{
case '=': if (!strcmp(sz, condIter->sValue.c_str())) execute=true; break;
case '!': if (strcmp(sz, condIter->sValue.c_str())) execute=true; break;
case '&': if (strstr(sz, condIter->sValue.c_str())) execute=true; break;
case '=': if (!strcmp(sz, condIter->sValue.c_str())) execute = true; break;
case '!': if (strcmp(sz, condIter->sValue.c_str())) execute = true; break;
case '&': if (strstr(sz, condIter->sValue.c_str())) execute = true; break;
}
if (execute)
break;
}
}
if (anyConditions && !execute)
(*iter).m_Done = true; // don't execute
}
@ -403,13 +418,14 @@ void EventsMngr::executeEvents()
for (ClEventVecIter iter = m_ParseFun->begin(); iter; ++iter)
{
if ( (*iter).m_Done )
if ((*iter).m_Done)
{
(*iter).m_Done = false;
continue;
}
(*iter).m_Stamp = (float)*m_Timer;
executeForwards((*iter).m_Func, m_ParseVault ? m_ParseVault[0].iValue : 0);
executeForwards((*iter).m_Func, static_cast<cell>(m_ParseVault ? m_ParseVault[0].iValue : 0));
}
m_CurrentMsgType = -1;
@ -423,30 +439,30 @@ int EventsMngr::getArgNum() const
const char* EventsMngr::getArgString(int a) const
{
if ( a < 0 || a > m_ParsePos )
if (a < 0 || a > m_ParsePos)
return "";
static char var[32];
switch(m_ParseVault[a].type)
switch (m_ParseVault[a].type)
{
case MSG_INTEGER:
sprintf( var, "%d", m_ParseVault[a].iValue );
sprintf(var, "%d", m_ParseVault[a].iValue);
return var;
case MSG_STRING:
return m_ParseVault[a].sValue;
default:
sprintf( var, "%g", m_ParseVault[a].fValue );
sprintf(var, "%g", m_ParseVault[a].fValue);
return var;
}
}
int EventsMngr::getArgInteger(int a) const
{
if ( a < 0 || a > m_ParsePos )
if (a < 0 || a > m_ParsePos)
return 0;
switch(m_ParseVault[a].type)
switch (m_ParseVault[a].type)
{
case MSG_INTEGER:
return m_ParseVault[a].iValue;
@ -459,15 +475,15 @@ int EventsMngr::getArgInteger(int a) const
float EventsMngr::getArgFloat(int a) const
{
if ( a < 0 || a > m_ParsePos )
if (a < 0 || a > m_ParsePos)
return 0.0f;
switch(m_ParseVault[a].type)
switch (m_ParseVault[a].type)
{
case MSG_INTEGER:
return m_ParseVault[a].iValue;
return static_cast<float>(m_ParseVault[a].iValue);
case MSG_STRING:
return atof(m_ParseVault[a].sValue);
return static_cast<float>(atof(m_ParseVault[a].sValue));
default:
return m_ParseVault[a].fValue;
}
@ -479,6 +495,7 @@ void EventsMngr::clearEvents(void)
{
m_Events[i].clear();
}
// delete parsevault
if (m_ParseVault)
{
@ -497,25 +514,26 @@ int EventsMngr::getEventId(const char* msg)
CS_EventsIds id;
} table[] =
{
{ "CS_DeathMsg" , CS_DeathMsg },
// { "CS_RoundEnd" , CS_RoundEnd },
// { "CS_RoundStart" , CS_RoundStart },
// { "CS_Restart" , CS_Restart },
{ "" , CS_Null }
{"CS_DeathMsg", CS_DeathMsg},
// {"CS_RoundEnd", CS_RoundEnd},
// {"CS_RoundStart", CS_RoundStart},
// {"CS_Restart", CS_Restart},
{"", CS_Null}
};
// if msg is a number, return it
int pos = atoi(msg);
if (pos != 0)
return pos;
// try to find in table first
for (pos = 0; table[ pos ].id != CS_Null; ++pos )
if ( !strcmp( table[ pos ].name , msg ) )
return table[ pos ].id;
for (pos = 0; table[pos].id != CS_Null; ++pos)
if (!strcmp(table[pos].name, msg))
return table[pos].id;
// find the id of the message
return pos = GET_USER_MSG_ID(PLID, msg , 0 );
return pos = GET_USER_MSG_ID(PLID, msg, 0);
}
int EventsMngr::getCurrentMsgType()

View File

@ -32,9 +32,10 @@
#ifndef __CEVENTS_H__
#define __CEVENTS_H__
#define MAX_AMX_REG_MSG MAX_REG_MSGS+16
#define MAX_AMX_REG_MSG MAX_REG_MSGS + 16
enum {
enum
{
CS_DEATHMSG = MAX_REG_MSGS,
// CS_ROUNDEND,
// CS_ROUNDSTART,
@ -116,6 +117,7 @@ private:
const char* sValue;
MsgParamType type;
};
MsgDataEntry *m_ParseVault;
int m_ParseVaultSize;
void NextParam(); // make sure a new parameter can be added
@ -130,7 +132,7 @@ private:
int m_ParsePos; // is args. num. - 1
float* m_Timer;
ClEvent* getValidEvent(ClEvent* a );
ClEvent* getValidEvent(ClEvent* a);
int m_CurrentMsgType;
public:
@ -140,20 +142,20 @@ public:
// Interface
ClEvent* registerEvent(CPluginMngr::CPlugin* plugin, int func, int flags, int msgid);
void parserInit(int msg_type, float* timer, CPlayer* pPlayer, int index);
void parseValue(int iValue);
void parseValue(float fValue);
void parseValue(const char *sz);
void executeEvents();
int getArgNum() const; //{ return (parsePos+1); }
int getArgNum() const; //{ return (parsePos + 1); }
const char* getArgString(int a) const;
int getArgInteger(int a) const;
float getArgFloat(int a) const;
void clearEvents(void);
static int getEventId( const char* msg );
static int getEventId(const char* msg);
int getCurrentMsgType();
};
#endif // #ifdef __CEVENTS_H__
#endif //__CEVENTS_H__

View File

@ -36,70 +36,71 @@
// *****************************************************
// class File
// *****************************************************
File::File( const char* n, const char* m )
File::File(const char* n, const char* m)
{
fp = fopen( n , m );
fp = fopen(n, m);
}
File::~File( )
File::~File()
{
if ( fp )
fclose( fp );
if (fp)
fclose(fp);
}
File::operator bool ( ) const
File::operator bool () const
{
return fp && !feof(fp);
}
File& operator<<( File& f, const String& n )
File& operator<<(File& f, const String& n)
{
if ( f ) fputs( n.c_str() , f.fp ) ;
if (f) fputs(n.c_str(), f.fp);
return f;
}
File& operator<<( File& f, const char* n )
File& operator<<(File& f, const char* n)
{
if ( f ) fputs( n , f.fp ) ;
if (f) fputs(n, f.fp);
return f;
}
File& operator<<( File& f, int n )
File& operator<<(File& f, int n)
{
if ( f ) fprintf( f.fp , "%d" , n ) ;
if (f) fprintf(f.fp, "%d", n);
return f;
}
File& operator<<( File& f, const char& c )
File& operator<<(File& f, const char& c)
{
if ( f ) fputc( c , f.fp ) ;
if (f) fputc(c, f.fp);
return f;
}
File& operator>>( File& f, String& n )
File& operator>>(File& f, String& n)
{
if ( !f ) return f;
if (!f) return f;
char temp[1024];
fscanf( f.fp , "%s", temp );
fscanf(f.fp, "%s", temp);
n.assign(temp);
return f;
}
File& operator>>( File& f, char* n )
File& operator>>(File& f, char* n)
{
if ( f ) fscanf( f.fp , "%s", n );
if (f) fscanf(f.fp, "%s", n);
return f;
}
int File::getline( char* buf, int sz )
int File::getline(char* buf, int sz)
{
int a = sz;
char *origBuf = buf;
if ( *this )
if (*this)
{
int c;
while ( sz-- && (c = getc( (*this).fp)) && c != EOF && c != '\n' )
while (sz-- && (c = getc((*this).fp)) && c != EOF && c != '\n')
*buf++ = c;
*buf = 0;
}
@ -115,12 +116,11 @@ int File::getline( char* buf, int sz )
return a - sz;
}
File& File::skipWs( )
File& File::skipWs()
{
if ( !*this ) return *this;
if (!*this) return *this;
int c;
while( isspace( c = getc( fp ) ) ){};
ungetc( c , fp );
while (isspace(c = getc(fp))) {};
ungetc(c, fp);
return *this;
}

View File

@ -41,18 +41,19 @@ class File
FILE* fp;
public:
File( const char* n, const char* m );
~File( );
operator bool ( ) const;
friend File& operator<<( File& f, const String& n );
friend File& operator<<( File& f, const char* n );
friend File& operator<<( File& f, const char& c );
friend File& operator<<( File& f, int n );
friend File& operator>>( File& f, String& n );
friend File& operator>>( File& f, char* n );
int getline( char* buf, int sz );
File& skipWs( );
File(const char* n, const char* m);
~File();
operator bool () const;
friend File& operator<<(File& f, const String& n);
friend File& operator<<(File& f, const char* n);
friend File& operator<<(File& f, const char& c);
friend File& operator<<(File& f, int n);
friend File& operator>>(File& f, String& n);
friend File& operator>>(File& f, char* n);
int getline(char* buf, int sz);
File& skipWs();
};

View File

@ -30,19 +30,22 @@
*/
#include "amxmodx.h"
void AMXAPI amxx_InvalidateTrace(AMX *amx);
#include "debugger.h"
#include "binlog.h"
CForward::CForward(const char *name, ForwardExecType et, int numParams, const ForwardParam *paramTypes)
{
m_FuncName = name;
m_ExecType = et;
m_NumParams = numParams;
memcpy((void *)m_ParamTypes, paramTypes, numParams * sizeof(ForwardParam));
// find funcs
int func;
AMXForward *tmp = NULL;
m_Funcs.clear();
for (CPluginMngr::iterator iter = g_plugins.begin(); iter; ++iter)
{
if ((*iter).isValid() && amx_FindPublic((*iter).getAMX(), name, &func) == AMX_ERR_NONE)
@ -53,6 +56,8 @@ CForward::CForward(const char *name, ForwardExecType et, int numParams, const Fo
m_Funcs.push_back(tmp);
}
}
m_Name.assign(name);
}
cell CForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
@ -74,67 +79,79 @@ cell CForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
{
// Get debug info
AMX *amx = (*iter).pPlugin->getAMX();
AMX_DBGINFO *pInfo = (AMX_DBGINFO *)(amx->userdata[2]);
if (pInfo)
pInfo->error = AMX_ERR_NONE;
Debugger *pDebugger = (Debugger *)amx->userdata[UD_DEBUGGER];
if (pDebugger)
pDebugger->BeginExec();
// handle strings & arrays
int i, ax=0;
int i, ax = 0;
for (i = 0; i < m_NumParams; ++i)
{
if (m_ParamTypes[i] == FP_STRING || m_ParamTypes[i] == FP_STRINGEX)
{
const char *str = reinterpret_cast<const char*>(params[i]);
cell *tmp;
amx_Allot(iter->pPlugin->getAMX(),
(m_ParamTypes[i] == FP_STRING) ? strlen(reinterpret_cast<const char*>(params[i]))+1 : STRINGEX_MAXLENGTH,
&realParams[i], &tmp);
amx_SetStringOld(tmp, (const char *)(params[i]), 0, 0);
if (!str)
str = "";
amx_Allot(iter->pPlugin->getAMX(), (m_ParamTypes[i] == FP_STRING) ? strlen(str) + 1 : STRINGEX_MAXLENGTH, &realParams[i], &tmp);
amx_SetStringOld(tmp, str, 0, 0);
physAddrs[i] = tmp;
}
else if (m_ParamTypes[i] == FP_ARRAY)
{
cell *tmp;
amx_Allot(amx, preparedArrays[params[i]].size,
&realParams[i], &tmp);
amx_Allot(amx, preparedArrays[params[i]].size, &realParams[i], &tmp);
physAddrs[i] = tmp;
if (preparedArrays[params[i]].type == Type_Cell)
{
memcpy(tmp, preparedArrays[params[i]].ptr, preparedArrays[params[i]].size * sizeof(cell));
}
else
{
} else {
char *data = (char*)preparedArrays[params[i]].ptr;
for (unsigned int j = 0; j < preparedArrays[params[i]].size; ++j)
*tmp++ = (static_cast<cell>(*data++)) & 0xFF;
}
}
else
{
} else {
realParams[i] = params[i];
}
}
//Push the parameters in reverse order. Weird, unfriendly part of Small 3.0!
for (i=m_NumParams-1; i>=0; i--)
for (i = m_NumParams-1; i >= 0; i--)
{
amx_Push(amx, realParams[i]);
}
// exec
cell retVal;
#if defined BINLOG_ENABLED
g_BinLog.WriteOp(BinLog_CallPubFunc, (*iter).pPlugin->getId(), iter->func);
#endif
int err = amx_Exec(amx, &retVal, iter->func);
// log runtime error, if any
if (err != AMX_ERR_NONE)
{
//Did something else set an error?
if (pInfo && pInfo->error != AMX_ERR_NONE)
if (pDebugger && pDebugger->ErrorExists())
{
//we don't care, something else logged the error.
} else {
}
else if (err != -1)
{
//nothing logged the error so spit it out anyway
LogError(amx, err, "");
LogError(amx, err, NULL);
}
}
amxx_InvalidateTrace(amx);
amx->error = AMX_ERR_NONE;
if (pDebugger)
pDebugger->EndExec();
// cleanup strings & arrays
for (i = 0; i < m_NumParams; ++i)
{
@ -157,10 +174,9 @@ cell CForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
if (preparedArrays[params[i]].type == Type_Cell)
{
memcpy(preparedArrays[params[i]].ptr, tmp, preparedArrays[params[i]].size * sizeof(cell));
}
else
{
} else {
char *data = (char*)preparedArrays[params[i]].ptr;
for (unsigned int j = 0; j < preparedArrays[params[i]].size; ++j)
*data++ = static_cast<char>(*tmp++ & 0xFF);
}
@ -190,17 +206,22 @@ cell CForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
}
}
}
return globRetVal;
}
void CSPForward::Set(int func, AMX *amx, int numParams, const ForwardParam *paramTypes)
{
char name[sNAMEMAX];
m_Func = func;
m_Amx = amx;
m_NumParams = numParams;
memcpy((void *)m_ParamTypes, paramTypes, numParams * sizeof(ForwardParam));
m_HasFunc = true;
isFree = false;
name[0] = '\0';
amx_GetPublic(amx, func, name);
m_Name.assign(name);
}
void CSPForward::Set(const char *funcName, AMX *amx, int numParams, const ForwardParam *paramTypes)
@ -210,6 +231,7 @@ void CSPForward::Set(const char *funcName, AMX *amx, int numParams, const Forwar
memcpy((void *)m_ParamTypes, paramTypes, numParams * sizeof(ForwardParam));
m_HasFunc = (amx_FindPublic(amx, funcName, &m_Func) == AMX_ERR_NONE);
isFree = false;
m_Name.assign(funcName);
}
cell CSPForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
@ -229,62 +251,72 @@ cell CSPForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
if (!pPlugin->isExecutable(m_Func))
return 0;
AMX_DBGINFO *pInfo = (AMX_DBGINFO *)(m_Amx->userdata[2]);
if (pInfo)
pInfo->error = AMX_ERR_NONE;
Debugger *pDebugger = (Debugger *)m_Amx->userdata[UD_DEBUGGER];
if (pDebugger)
pDebugger->BeginExec();
// handle strings & arrays
int i;
for (i = 0; i < m_NumParams; ++i)
{
if (m_ParamTypes[i] == FP_STRING || m_ParamTypes[i] == FP_STRINGEX)
{
const char *str = reinterpret_cast<const char*>(params[i]);
if (!str)
str = "";
cell *tmp;
amx_Allot(m_Amx,
(m_ParamTypes[i] == FP_STRING) ? strlen(reinterpret_cast<const char*>(params[i]))+1 : STRINGEX_MAXLENGTH,
&realParams[i], &tmp);
amx_SetStringOld(tmp, (const char *)(params[i]), 0, 0);
amx_Allot(m_Amx, (m_ParamTypes[i] == FP_STRING) ? strlen(str) + 1 : STRINGEX_MAXLENGTH, &realParams[i], &tmp);
amx_SetStringOld(tmp, str, 0, 0);
physAddrs[i] = tmp;
}
else if (m_ParamTypes[i] == FP_ARRAY)
{
cell *tmp;
amx_Allot(m_Amx, preparedArrays[params[i]].size,
&realParams[i], &tmp);
amx_Allot(m_Amx, preparedArrays[params[i]].size, &realParams[i], &tmp);
physAddrs[i] = tmp;
if (preparedArrays[params[i]].type == Type_Cell)
{
memcpy(tmp, preparedArrays[params[i]].ptr, preparedArrays[params[i]].size * sizeof(cell));
}
else
{
} else {
char *data = (char*)preparedArrays[params[i]].ptr;
for (unsigned int j = 0; j < preparedArrays[params[i]].size; ++j)
*tmp++ = (static_cast<cell>(*data++)) & 0xFF;
}
}
else
{
} else {
realParams[i] = params[i];
}
}
for (i=m_NumParams-1; i>=0; i--)
for (i = m_NumParams - 1; i >= 0; i--)
amx_Push(m_Amx, realParams[i]);
// exec
cell retVal;
#if defined BINLOG_ENABLED
g_BinLog.WriteOp(BinLog_CallPubFunc, pPlugin->getId(), m_Func);
#endif
int err = amx_Exec(m_Amx, &retVal, m_Func);
if (err != AMX_ERR_NONE)
{
//Did something else set an error?
if (pInfo && pInfo->error != AMX_ERR_NONE)
if (pDebugger && pDebugger->ErrorExists())
{
//we don't care, something else logged the error.
} else {
}
else if (err != -1)
{
//nothing logged the error so spit it out anyway
LogError(m_Amx, err, "");
LogError(m_Amx, err, NULL);
}
}
amxx_InvalidateTrace(m_Amx);
if (pDebugger)
pDebugger->EndExec();
m_Amx->error = AMX_ERR_NONE;
// cleanup strings & arrays
@ -309,10 +341,9 @@ cell CSPForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
if (preparedArrays[params[i]].type == Type_Cell)
{
memcpy(preparedArrays[params[i]].ptr, tmp, preparedArrays[params[i]].size * sizeof(cell));
}
else
{
} else {
char *data = (char*)preparedArrays[params[i]].ptr;
for (unsigned int j = 0; j < preparedArrays[params[i]].size; ++j)
*data++ = static_cast<char>(*tmp++ & 0xFF);
}
@ -328,9 +359,12 @@ int CForwardMngr::registerForward(const char *funcName, ForwardExecType et, int
{
int retVal = m_Forwards.size() << 1;
CForward *tmp = new CForward(funcName, et, numParams, paramTypes);
if (!tmp)
return -1; // should be invalid
m_Forwards.push_back(tmp);
return retVal;
}
@ -338,22 +372,26 @@ int CForwardMngr::registerSPForward(int func, AMX *amx, int numParams, const For
{
int retVal = -1;
CSPForward *pForward;
if (!m_FreeSPForwards.empty())
{
retVal = m_FreeSPForwards.front();
pForward = m_SPForwards[retVal >> 1];
pForward->Set(func, amx, numParams, paramTypes);
if (pForward->getFuncsNum() == 0)
return -1;
m_FreeSPForwards.pop();
}
else
{
} else {
retVal = (m_SPForwards.size() << 1) | 1;
pForward = new CSPForward();
if (!pForward)
return -1;
pForward->Set(func, amx, numParams, paramTypes);
if (pForward->getFuncsNum() == 0)
{
return -1;
@ -362,6 +400,7 @@ int CForwardMngr::registerSPForward(int func, AMX *amx, int numParams, const For
m_SPForwards.push_back(pForward);
}
return retVal;
}
@ -369,56 +408,63 @@ int CForwardMngr::registerSPForward(const char *funcName, AMX *amx, int numParam
{
int retVal = (m_SPForwards.size() << 1) | 1;
CSPForward *pForward;
if (!m_FreeSPForwards.empty())
{
retVal = m_FreeSPForwards.front();
pForward = m_SPForwards[retVal>>1]; // >>1 because unregisterSPForward pushes the id which contains the sp flag
pForward->Set(funcName, amx, numParams, paramTypes);
if (pForward->getFuncsNum() == 0)
return -1;
m_FreeSPForwards.pop();
}
else
{
} else {
pForward = new CSPForward();
if (!pForward)
return -1;
pForward->Set(funcName, amx, numParams, paramTypes);
if (pForward->getFuncsNum() == 0)
{
delete pForward;
return -1;
}
m_SPForwards.push_back(pForward);
}
return retVal;
}
bool CForwardMngr::isIdValid(int id) const
{
return (id >= 0) && ((id & 1) ?
(static_cast<size_t>(id >> 1) < m_SPForwards.size()) :
(static_cast<size_t>(id >> 1) < m_Forwards.size()));
return (id >= 0) && ((id & 1) ? (static_cast<size_t>(id >> 1) < m_SPForwards.size()) : (static_cast<size_t>(id >> 1) < m_Forwards.size()));
}
cell CForwardMngr::executeForwards(int id, cell *params)
{
int retVal = (id & 1) ? m_SPForwards[id >> 1]->execute(params, m_TmpArrays) :
m_Forwards[id >> 1]->execute(params, m_TmpArrays);
int retVal = (id & 1) ? m_SPForwards[id >> 1]->execute(params, m_TmpArrays) : m_Forwards[id >> 1]->execute(params, m_TmpArrays);
m_TmpArraysNum = 0;
return retVal;
}
const char *CForwardMngr::getFuncName(int id) const
{
return (id & 1) ? m_SPForwards[id >> 1]->getFuncName() : m_Forwards[id >> 1]->getFuncName();
}
int CForwardMngr::getParamsNum(int id) const
{
return (id & 1) ? m_SPForwards[id >> 1]->getParamsNum() :
m_Forwards[id >> 1]->getParamsNum();
return (id & 1) ? m_SPForwards[id >> 1]->getParamsNum() : m_Forwards[id >> 1]->getParamsNum();
}
ForwardParam CForwardMngr::getParamType(int id, int paramNum) const
{
return (id & 1) ? m_SPForwards[id >> 1]->getParamType(paramNum) :
m_Forwards[id >> 1]->getParamType(paramNum);
return (id & 1) ? m_SPForwards[id >> 1]->getParamType(paramNum) : m_Forwards[id >> 1]->getParamType(paramNum);
}
void CForwardMngr::clear()
@ -427,7 +473,9 @@ void CForwardMngr::clear()
{
delete *iter;
}
SPForwardVec::iterator spIter;
for (spIter = m_SPForwards.begin(); spIter != m_SPForwards.end(); ++spIter)
{
delete (*spIter);
@ -435,8 +483,10 @@ void CForwardMngr::clear()
m_Forwards.clear();
m_SPForwards.clear();
while (!m_FreeSPForwards.empty())
m_FreeSPForwards.pop();
m_TmpArraysNum = 0;
}
@ -448,74 +498,117 @@ bool CForwardMngr::isSPForward(int id) const
void CForwardMngr::unregisterSPForward(int id)
{
//make sure the id is valid
if ( !isIdValid(id) || m_SPForwards.at(id >> 1)->isFree )
if (!isIdValid(id) || m_SPForwards.at(id >> 1)->isFree)
return;
m_SPForwards.at(id >> 1)->isFree = true;
m_FreeSPForwards.push(id);
}
int registerForwardC(const char *funcName, ForwardExecType et, cell *list, size_t num)
{
ForwardParam params[FORWARD_MAX_PARAMS];
for (size_t i=0; i<num; i++)
params[i] = static_cast<ForwardParam>(list[i]);
return g_forwards.registerForward(funcName, et, num, params);
}
int registerForward(const char *funcName, ForwardExecType et, ...)
{
int curParam = 0;
va_list argptr;
va_start(argptr, et);
ForwardParam params[FORWARD_MAX_PARAMS];
ForwardParam tmp;
while (true)
{
if (curParam == FORWARD_MAX_PARAMS)
break;
tmp = (ForwardParam)va_arg(argptr, int);
if (tmp == FP_DONE)
break;
params[curParam] = tmp;
++curParam;
}
va_end(argptr);
return g_forwards.registerForward(funcName, et, curParam, params);
}
int registerSPForwardByNameC(AMX *amx, const char *funcName, cell *list, size_t num)
{
ForwardParam params[FORWARD_MAX_PARAMS];
for (size_t i=0; i<num; i++)
params[i] = static_cast<ForwardParam>(list[i]);
return g_forwards.registerSPForward(funcName, amx, num, params);
}
int registerSPForwardByName(AMX *amx, const char *funcName, ...)
{
int curParam = 0;
va_list argptr;
va_start(argptr, funcName);
ForwardParam params[FORWARD_MAX_PARAMS];
ForwardParam tmp;
while (true)
{
if (curParam == FORWARD_MAX_PARAMS)
break;
tmp = (ForwardParam)va_arg(argptr, int);
if (tmp == FP_DONE)
break;
params[curParam] = tmp;
++curParam;
}
va_end(argptr);
return g_forwards.registerSPForward(funcName, amx, curParam, params);
}
int registerSPForward(AMX *amx, int func, ...)
{
int curParam = 0;
va_list argptr;
va_start(argptr, func);
ForwardParam params[FORWARD_MAX_PARAMS];
ForwardParam tmp;
while (true)
{
if (curParam == FORWARD_MAX_PARAMS)
break;
tmp = (ForwardParam)va_arg(argptr, int);
if (tmp == FP_DONE)
break;
params[curParam] = tmp;
++curParam;
}
va_end(argptr);
return g_forwards.registerSPForward(func, amx, curParam, params);
}
@ -525,9 +618,12 @@ cell executeForwards(int id, ...)
return -1;
cell params[FORWARD_MAX_PARAMS];
int paramsNum = g_forwards.getParamsNum(id);
va_list argptr;
va_start(argptr, id);
for (int i = 0; i < paramsNum && i < FORWARD_MAX_PARAMS; ++i)
{
if (g_forwards.getParamType(id, i) == FP_FLOAT)
@ -538,7 +634,9 @@ cell executeForwards(int id, ...)
else
params[i] = (cell)va_arg(argptr, cell);
}
va_end(argptr);
return g_forwards.executeForwards(id, params);
}
@ -546,13 +644,16 @@ cell CForwardMngr::prepareArray(void *ptr, unsigned int size, ForwardArrayElemTy
{
if (m_TmpArraysNum >= FORWARD_MAX_PARAMS)
{
#ifdef MEMORY_TEST
#ifdef MEMORY_TEST
m_validateAllAllocUnits();
#endif // MEMORY_TEST
#endif // MEMORY_TEST
AMXXLOG_Log("[AMXX] Forwards with more than 32 parameters are not supported (tried to prepare array # %d).", m_TmpArraysNum + 1);
m_TmpArraysNum = 0;
return -1;
}
m_TmpArrays[m_TmpArraysNum].ptr = ptr;
m_TmpArrays[m_TmpArraysNum].size = size;
m_TmpArrays[m_TmpArraysNum].type = type;

View File

@ -46,6 +46,9 @@
#ifndef FORWARD_H
#define FORWARD_H
#include <stdarg.h>
#include "sh_stack.h"
const int FORWARD_MAX_PARAMS = 32;
enum ForwardExecType
@ -77,7 +80,9 @@ enum ForwardArrayElemType
struct ForwardPreparedArray
{
void *ptr;
ForwardArrayElemType type;
unsigned int size;
bool copyBack;
};
@ -88,31 +93,45 @@ class CForward
const char *m_FuncName;
ForwardExecType m_ExecType;
int m_NumParams;
String m_Name;
struct AMXForward
{
CPluginMngr::CPlugin *pPlugin;
int func;
};
typedef CVector<AMXForward> AMXForwardList;
AMXForwardList m_Funcs;
ForwardParam m_ParamTypes[FORWARD_MAX_PARAMS];
public:
CForward(const char *name, ForwardExecType et, int numParams, const ForwardParam * paramTypes);
CForward()
{ } // leaves everything unitialized'
CForward() {} // leaves everything unitialized'
cell execute(cell *params, ForwardPreparedArray *preparedArrays);
int getParamsNum() const
{
return m_NumParams;
}
int getFuncsNum() const
{
return m_Funcs.size();
}
const char *getFuncName() const
{
return m_Name.c_str();
}
ForwardParam getParamType(int paramId) const
{
if (paramId < 0 || paramId >= m_NumParams)
return FP_DONE;
return m_ParamTypes[paramId];
}
};
@ -122,10 +141,14 @@ class CSPForward
{
const char *m_FuncName;
int m_NumParams;
ForwardParam m_ParamTypes[FORWARD_MAX_PARAMS];
AMX *m_Amx;
int m_Func;
bool m_HasFunc;
String m_Name;
public:
bool isFree;
public:
@ -134,18 +157,27 @@ public:
void Set(int func, AMX *amx, int numParams, const ForwardParam * paramTypes);
cell execute(cell *params, ForwardPreparedArray *preparedArrays);
int getParamsNum() const
{
return m_NumParams;
}
int getFuncsNum() const
{
return (m_HasFunc) ? 1 : 0;
}
const char *getFuncName() const
{
return m_Name.c_str();
}
ForwardParam getParamType(int paramId) const
{
if (paramId < 0 || paramId >= m_NumParams)
return FP_DONE;
return m_ParamTypes[paramId];
}
};
@ -154,7 +186,7 @@ class CForwardMngr
{
typedef CVector<CForward*> ForwardVec;
typedef CVector<CSPForward*> SPForwardVec;
typedef CQueue<int> FreeSPVec; // Free SP Forwards
typedef CStack<int> FreeSPVec; // Free SP Forwards
ForwardVec m_Forwards;
@ -167,8 +199,7 @@ public:
CForwardMngr()
{ m_TmpArraysNum = 0; }
~CForwardMngr()
{ }
~CForwardMngr() {}
// Interface
// Register normal forward
@ -176,23 +207,29 @@ public:
// Register single plugin forward
int registerSPForward(const char *funcName, AMX *amx, int numParams, const ForwardParam * paramTypes);
int registerSPForward(int func, AMX *amx, int numParams, const ForwardParam * paramTypes);
// Unregister single plugin forward
void unregisterSPForward(int id);
// execute forward
cell executeForwards(int id, cell *params);
void clear(); // delete all forwards
bool isIdValid(int id) const; // check whether forward id is valid
bool isSPForward(int id) const; // check whether forward is single plugin
int getParamsNum(int id) const; // get num of params of a forward
int getFuncsNum(int id) const; // get num of found functions of a forward
const char *getFuncName(int id) const; // get the function name
ForwardParam getParamType(int id, int paramId) const;
cell prepareArray(void *ptr, unsigned int size, ForwardArrayElemType type,
bool copyBack); // prepare array
cell prepareArray(void *ptr, unsigned int size, ForwardArrayElemType type, bool copyBack); // prepare array
};
// (un)register forward
int registerForward(const char *funcName, ForwardExecType et, ...);
int registerForwardC(const char *funcName, ForwardExecType et, cell *list, size_t num);
int registerSPForwardByName(AMX *amx, const char *funcName, ...);
int registerSPForwardByNameC(AMX *amx, const char *funcName, cell *list, size_t num);
int registerSPForward(AMX *amx, int func, ...);
void unregisterSPForward(int id);
@ -202,5 +239,4 @@ cell executeForwards(int id, ...);
cell prepareCellArray(cell *ptr, unsigned int size, bool copyBack = false);
cell prepareCharArray(char *ptr, unsigned int size, bool copyBack = false);
#endif
#endif //FORWARD_H

File diff suppressed because it is too large Load Diff

View File

@ -32,27 +32,56 @@
#ifndef _INCLUDE_CLANG_H
#define _INCLUDE_CLANG_H
#include "sh_tinyhash.h"
#define LANG_SERVER 0
#define LANG_PLAYER -1
#define ERR_BADKEY 1 // Lang key not found
#define ERR_BADLANG 2 // Invalid lang
struct md5Pair
{
String file;
String val;
};
struct keyEntry
{
String key;
uint32_t hash;
};
struct sKeyDef
{
sKeyDef() { key = -1; def = 0; }
~sKeyDef() { if (def) delete def; }
String *definition;
int key;
String *def;
};
struct lang_err
{
lang_err() : last(0.0f)
{
};
float last;
};
class defentry
{
public:
defentry() : definition(NULL)
{
};
defentry(const defentry &src)
{
definition = src.definition;
}
~defentry()
{
}
String *definition;
};
struct keytbl_val
{
keytbl_val() : index(-1)
{
};
int index;
};
class CLangMngr
@ -68,84 +97,41 @@ class CLangMngr
~CLang();
// Get the definition
const char *GetDef(const char *key);
const char *GetDef(int key, int &status);
// Add definitions to this language
void MergeDefinitions(CQueue <sKeyDef*> & vec);
void MergeDefinitions(CQueue <sKeyDef> & vec);
// Reset this language
void Clear();
// compare this language to a language name
friend bool operator == (const CLang &left, const char *right)
{
return strcmp(left.m_LanguageName, right)==0 ? true : false;
return strcmp(left.m_LanguageName, right) == 0 ? true : false;
}
// Get language name
const char *GetName() { return m_LanguageName; }
// Save to file
bool Save(FILE *fp, int &defOffset, uint32_t &curOffset);
bool SaveDefinitions(FILE *fp, uint32_t &curOffset);
// Load
bool Load(FILE *fp);
void SetMngr(CLangMngr *l) { m_LMan = l; }
// Get number of entries
int Entries() { return m_LookUpTable.size(); }
// Make a hash from a string; convert to lowercase first if needed
static uint32_t MakeHash(const char *src, bool makeLower = false);
int Entries();
protected:
// An entry in the language
class LangEntry
{
// the definition hash
uint32_t m_DefHash;
// index into the lookup table?
int key;
// the definition
String m_pDef;
// is this from the cache or not?
bool m_isCache;
public:
// Set
void SetKey(int key);
void SetDef(const char *pDef);
void SetCache(bool c);
// Get
uint32_t GetDefHash();
int GetKey();
const char *GetDef();
int GetDefLength();
bool GetCache();
// Constructors / destructors
LangEntry();
LangEntry(int key);
LangEntry(int key, const char *pDef);
LangEntry(const LangEntry &other);
LangEntry(int pKey, uint32_t defHash, const char *pDef);
// Reset
void Clear();
};
// Get (construct if needed) an entry
LangEntry * GetEntry(int key);
typedef CVector<LangEntry*> LookUpVec;
typedef THash<int, defentry> LookUpVec;
typedef LookUpVec::iterator LookUpVecIter;
char m_LanguageName[3];
// our lookup table
LookUpVec m_LookUpTable;
int m_entries;
CLangMngr *m_LMan;
public:
LangEntry *AddEntry(int pKey, uint32_t defHash, const char *def, bool cache);
void AddEntry(int key, const char *definition);
};
// Merge definitions into a language
void MergeDefinitions(const char *lang, CQueue <sKeyDef*> &tmpVec);
void MergeDefinitions(const char *lang, CQueue <sKeyDef> &tmpVec);
// strip lowercase; make lower if needed
static size_t strip(char *str, char *newstr, bool makelower=false);
static size_t strip(char *str, char *newstr, bool makelower = false);
typedef CVector<CLang*> LangVec;
typedef CVector<CLang*>::iterator LangVecIter;
@ -153,7 +139,8 @@ class CLangMngr
LangVec m_Languages;
CVector<md5Pair *> FileList;
CVector<keyEntry*> KeyList;
CVector<String *> KeyList;
THash<String, keytbl_val> KeyTable;
// Get a lang object (construct if needed)
CLang * GetLang(const char *name);
@ -165,30 +152,19 @@ class CLangMngr
public:
// Merge a definitions file
int MergeDefinitionFile(const char *file);
// Get a definition from a lang name and a kyer
const char *GetDef(const char *langName, const char *key);
// Format a string
const char *Format(const char *src, ...);
// Get a definition from a lang name and a key
const char *GetDef(const char *langName, const char *key, int &status);
// Format a string for an AMX plugin
char *FormatAmxString(AMX *amx, cell *params, int parm, int &len);
char *FormatString(const char *fmt, va_list &ap);
// Save
bool Save(const char *filename);
// Load
bool Load(const char *filename);
// Cache
bool LoadCache(const char *filename);
bool SaveCache(const char *filename);
void InvalidateCache();
// Get index
int GetKeyEntry(String &key);
int GetKeyEntry(const char *key);
int GetKeyHash(int key);
int GetKeyIndex(const char *key);
// Get key from index
const char *GetKey(int key);
// Add key
int AddKeyEntry(String &key);
// Make a hash from a string; convert to lowercase first if needed
uint32_t MakeHash(const char *src, bool makeLower);
// Get the number of languages
int GetLangsNum();
@ -200,6 +176,8 @@ public:
// When a language id in a format string in FormatAmxString is LANG_PLAYER, the glob id decides which language to take.
void SetDefLang(int id);
inline int GetDefLang() const { return m_CurGlobId; }
// Reset
void Clear();

View File

@ -35,6 +35,7 @@
// *****************************************************
// class CList
// *****************************************************
// Linked list
template <typename T, typename F = char* >
class CList
@ -65,8 +66,10 @@ private:
~CElement()
{
delete m_pObject;
if (m_pNext)
m_pNext->m_pPrev = m_pPrev;
if (m_pPrev)
m_pPrev->m_pNext = m_pNext;
}
@ -102,15 +105,16 @@ private:
}
};
// CList<T,F> class
// CList<T, F> class
CElement *m_pHead; // head of the linked list
CElement *m_pTail; // tail of the linked list
public:
// iterator class
class iterator
{
friend class CList<T,F>;
CList<T,F> *m_pList; // The list that created this iterator
friend class CList<T, F>;
CList<T, F> *m_pList; // The list that created this iterator
CElement *m_CurPos; // Current position in the list
public:
iterator()
@ -120,7 +124,7 @@ public:
}
// constructor based on list, element
iterator(CList<T,F> *pList, CElement *startPos)
iterator(CList<T, F> *pList, CElement *startPos)
{
m_pList = pList;
m_CurPos = startPos;
@ -147,7 +151,7 @@ public:
// validity check operator
inline operator bool () const
{
return m_pList!=NULL && m_CurPos!=NULL && m_CurPos->GetObj()!=NULL;
return m_pList != NULL && m_CurPos != NULL && m_CurPos->GetObj() != NULL;
}
// pre increment operator
@ -162,6 +166,7 @@ public:
{
iterator tmp(*this);
m_CurPos = m_CurPos->next;
return tmp;
}
@ -176,18 +181,20 @@ public:
{
return m_pList->remove(*this);
}
iterator put(T *obj)
{
return m_pList->put(obj, *this);
}
};
CList<T,F>()
CList<T, F>()
{
m_pHead = NULL;
m_pTail = NULL;
}
~CList<T,F>()
~CList<T, F>()
{
clear();
}
@ -198,12 +205,16 @@ public:
iterator remove(iterator &where)
{
iterator tmp(where.GetNext());
if (where.m_CurPos == m_pHead)
m_pHead = where.m_CurPos->GetNext();
if (where.m_CurPos == m_pTail)
m_pTail = where.m_CurPos->GetPrev();
delete where.m_CurPos;
where = tmp;
return tmp;
}
@ -212,36 +223,36 @@ public:
iterator put_back(T *pObj)
{
CElement *pTmp = new CElement(pObj);
if (!m_pHead)
{
m_pHead = pTmp;
m_pTail = pTmp;
}
else
{
} else {
pTmp->SetNext(NULL);
pTmp->SetPrev(m_pTail);
m_pTail->SetNext(pTmp);
m_pTail = pTmp;
}
return iterator(this, pTmp);
}
iterator put_front(T *pObj)
{
CElement *pTmp = new CElement(pObj);
if (!m_pHead)
{
m_pHead = pTmp;
m_pTail = pTmp;
}
else
{
} else {
pTmp->SetNext(m_pHead);
pTmp->SetPrev(NULL);
m_pHead->SetPrev(pTmp);
m_pHead = pTmp;
}
return iterator(this, pTmp);
}
@ -257,6 +268,7 @@ public:
iterator put(T *pObj, iterator &where)
{
CElement *pTmp = new CElement(pObj);
if (where.m_CurPos->GetNext())
where.m_CurPos->GetNext()->SetPrev(pTmp);
else // where = tail
@ -266,6 +278,7 @@ public:
pTmp->SetNext(where.m_CurPos->GetNext());
where.m_CurPos->SetNext(pTmp);
return ++where;
}
@ -283,12 +296,13 @@ public:
iterator find(iterator startOn, const F &desc)
{
iterator iter = startOn;
while(iter)
while (iter)
{
if (*iter == desc)
break;
++iter;
}
return iter;
}
@ -300,14 +314,16 @@ public:
int size()
{
iterator iter = begin();
int i=0;
int i = 0;
while (iter)
{
++i;
++iter;
}
return i;
}
};
#endif
#endif //CLIST_H

View File

@ -35,135 +35,192 @@
// *****************************************************
// class LogEventsMngr
// *****************************************************
LogEventsMngr::LogEventsMngr() {
LogEventsMngr::LogEventsMngr()
{
logCurrent = logCounter = 0;
logcmplist = 0;
arelogevents = false;
memset( logevents, 0, sizeof(logevents) );
memset(logevents, 0, sizeof(logevents));
}
LogEventsMngr::~LogEventsMngr() {
LogEventsMngr::~LogEventsMngr()
{
clearLogEvents();
}
int LogEventsMngr::CLogCmp::compareCondition(const char* string){
if ( logid == parent->logCounter )
int LogEventsMngr::CLogCmp::compareCondition(const char* string)
{
if (logid == parent->logCounter)
return result;
logid = parent->logCounter;
if ( in ) return result = strstr( string , text.c_str() ) ? 0 : 1;
if (in)
return result = strstr(string, text.c_str()) ? 0 : 1;
return result = strcmp(string,text.c_str());
}
LogEventsMngr::CLogCmp* LogEventsMngr::registerCondition(char* filter){
LogEventsMngr::CLogCmp* LogEventsMngr::registerCondition(char* filter)
{
char* temp = filter;
// expand "1=message"
while ( isdigit(*filter) )
while (isdigit(*filter))
++filter;
bool in = (*filter=='&');
*filter++ = 0;
int pos = atoi(temp);
if ( pos < 0 || pos >= MAX_LOGARGS) pos = 0;
if (pos < 0 || pos >= MAX_LOGARGS)
pos = 0;
CLogCmp* c = logcmplist;
while( c ) {
if ( (c->pos==pos) && (c->in==in) && !strcmp(c->text.c_str(), filter))
while (c)
{
if ((c->pos == pos) && (c->in == in) && !strcmp(c->text.c_str(), filter))
return c;
c = c->next;
}
return logcmplist = new CLogCmp( filter , in , pos , logcmplist,this );
return logcmplist = new CLogCmp(filter, in, pos, logcmplist, this);
}
void LogEventsMngr::CLogEvent::registerFilter( char* filter ){
CLogCmp *cmp = parent->registerCondition( filter );
if ( cmp == 0 ) return;
for(LogCond* c = filters; c ; c = c->next){
if ( c->argnum == cmp->pos ){
c->list = new LogCondEle( cmp , c->list );
void LogEventsMngr::CLogEvent::registerFilter(char* filter)
{
CLogCmp *cmp = parent->registerCondition(filter);
if (cmp == 0) return;
for (LogCond* c = filters; c; c = c->next)
{
if (c->argnum == cmp->pos)
{
c->list = new LogCondEle(cmp, c->list);
return;
}
}
LogCondEle* aa = new LogCondEle( cmp , 0 );
if ( aa == 0 ) return;
filters = new LogCond( cmp->pos , aa , filters );
LogCondEle* aa = new LogCondEle(cmp, 0);
if (aa == 0)
return;
filters = new LogCond(cmp->pos, aa, filters);
}
void LogEventsMngr::setLogString( char* frmt, va_list& vaptr ) {
void LogEventsMngr::setLogString(char* frmt, va_list& vaptr)
{
++logCounter;
int len = vsnprintf (logString, 255 , frmt, vaptr );
if ( len == - 1) {
int len = vsnprintf(logString, 255, frmt, vaptr);
if (len == - 1)
{
len = 255;
logString[len] = 0;
}
if ( len ) logString[--len] = 0;
if (len)
logString[--len] = 0;
logArgc = 0;
}
void LogEventsMngr::setLogString( char* frmt, ... ) {
void LogEventsMngr::setLogString(char* frmt, ...)
{
++logCounter;
va_list logArgPtr;
va_start ( logArgPtr , frmt );
int len = vsnprintf(logString, 255 , frmt, logArgPtr );
if ( len == - 1) {
va_start(logArgPtr, frmt);
int len = vsnprintf(logString, 255, frmt, logArgPtr);
if (len == - 1)
{
len = 255;
logString[len] = 0;
}
va_end ( logArgPtr );
if ( len ) logString[--len] = 0;
va_end(logArgPtr);
if (len)
logString[--len] = 0;
logArgc = 0;
}
void LogEventsMngr::parseLogString( ) {
void LogEventsMngr::parseLogString()
{
register const char* b = logString;
register int a;
while( *b && logArgc < MAX_LOGARGS ){
while (*b && logArgc < MAX_LOGARGS)
{
a = 0;
if ( *b == '"' ) {
if (*b == '"')
{
++b;
while ( *b && *b != '"' && a < 127 )
while (*b && *b != '"' && a < 127)
logArgs[logArgc][a++] = *b++;
logArgs[logArgc++][a] = 0;
if ( *b) b+=2; // thanks to double terminator
if (*b) b+=2; // thanks to double terminator
}
else if ( *b == '(' ) {
else if (*b == '(')
{
++b;
while ( *b && *b != ')' && a < 127 )
while (*b && *b != ')' && a < 127)
logArgs[logArgc][a++] = *b++;
logArgs[logArgc++][a] = 0;
if ( *b) b+=2;
}
else {
while ( *b && *b != '(' && *b != '"' && a < 127 )
if (*b) b+=2;
} else {
while (*b && *b != '(' && *b != '"' && a < 127)
logArgs[logArgc][a++] = *b++;
if ( *b ) --a;
if (*b) --a;
logArgs[logArgc++][a] = 0;
}
}
}
LogEventsMngr::CLogEvent* LogEventsMngr::registerLogEvent( CPluginMngr::CPlugin* plugin, int func, int pos )
LogEventsMngr::CLogEvent* LogEventsMngr::registerLogEvent(CPluginMngr::CPlugin* plugin, int func, int pos)
{
if ( pos < 1 || pos > MAX_LOGARGS)
if (pos < 1 || pos > MAX_LOGARGS)
return 0;
arelogevents = true;
CLogEvent** d = &logevents[pos];
while(*d) d = &(*d)->next;
return *d = new CLogEvent( plugin , func, this );
while (*d)
d = &(*d)->next;
return *d = new CLogEvent(plugin, func, this);
}
void LogEventsMngr::executeLogEvents()
{
bool valid;
for(CLogEvent* a = logevents[ logArgc ]; a ; a = a->next)
for (CLogEvent* a = logevents[logArgc]; a; a = a->next)
{
valid = true;
for( CLogEvent::LogCond* b = a->filters; b ; b = b->next)
for (CLogEvent::LogCond* b = a->filters; b; b = b->next)
{
valid = false;
for( CLogEvent::LogCondEle* c = b->list; c ; c = c->next) {
if ( c->cmp->compareCondition( logArgs[b->argnum] ) == 0 ){
for (CLogEvent::LogCondEle* c = b->list; c; c = c->next)
{
if (c->cmp->compareCondition(logArgs[b->argnum]) == 0)
{
valid = true;
break;
}
}
if (!valid)
break;
}
@ -175,64 +232,87 @@ void LogEventsMngr::executeLogEvents()
}
}
void LogEventsMngr::clearLogEvents(){
void LogEventsMngr::clearLogEvents()
{
logCurrent = logCounter = 0;
arelogevents = false;
for(int i = 0; i < MAX_LOGARGS + 1; ++i){
for (int i = 0; i < MAX_LOGARGS + 1; ++i)
{
CLogEvent **a = &logevents[i];
while(*a){
while (*a)
{
CLogEvent* bb = (*a)->next;
delete *a;
*a = bb;
}
}
clearConditions();
}
void LogEventsMngr::clearConditions() {
while (logcmplist){
void LogEventsMngr::clearConditions()
{
while (logcmplist)
{
CLogCmp* a = logcmplist->next;
delete logcmplist;
logcmplist = a;
}
}
LogEventsMngr::CLogEvent::LogCond::~LogCond() {
while( list ) {
LogEventsMngr::CLogEvent::LogCond::~LogCond()
{
while (list)
{
LogCondEle* cc = list->next;
delete list;
list = cc;
}
}
LogEventsMngr::CLogEvent::~CLogEvent() {
while( filters ) {
LogEventsMngr::CLogEvent::~CLogEvent()
{
while (filters)
{
LogCond* cc = filters->next;
delete filters;
filters = cc;
}
}
LogEventsMngr::CLogEvent *LogEventsMngr::getValidLogEvent( CLogEvent * a )
LogEventsMngr::CLogEvent *LogEventsMngr::getValidLogEvent(CLogEvent * a)
{
bool valid;
while(a){
while (a)
{
valid = true;
for( CLogEvent::LogCond* b = a->filters; b ; b = b->next){
for (CLogEvent::LogCond* b = a->filters; b; b = b->next)
{
valid = false;
for( CLogEvent::LogCondEle* c = b->list; c ; c = c->next) {
if ( c->cmp->compareCondition( logArgs[b->argnum] ) == 0 ){
for (CLogEvent::LogCondEle* c = b->list; c; c = c->next)
{
if (c->cmp->compareCondition(logArgs[b->argnum]) == 0)
{
valid = true;
break;
}
}
if (!valid) break;
}
if (!valid){
if (!valid)
{
a = a->next;
continue;
}
return a;
}
return 0;
}

View File

@ -40,8 +40,8 @@
// class LogEventsMngr
// *****************************************************
class LogEventsMngr {
class LogEventsMngr
{
char logString[256];
char logArgs[MAX_LOGARGS][128];
int logArgc;
@ -53,7 +53,6 @@ public:
class CLogCmp;
class iterator;
class CLogEvent;
friend class CLogEvent;
friend class CLogCmp;
friend class iterator;
@ -62,104 +61,118 @@ public:
{
friend class LogEventsMngr;
friend class CLogEvent;
LogEventsMngr* parent;
String text;
int logid;
int pos;
int result;
bool in;
CLogCmp *next;
CLogCmp( const char* s, bool r, int p, CLogCmp *n, LogEventsMngr* mg ) : text(s) {
CLogCmp(const char* s, bool r, int p, CLogCmp *n, LogEventsMngr* mg) : text(s)
{
logid = result = 0;
pos = p;
parent = mg;
in = r;
next = n;
}
public:
public:
int compareCondition(const char* string);
};
private:
CLogCmp *logcmplist;
public:
class CLogEvent {
class CLogEvent
{
friend class LogEventsMngr;
friend class iterator;
struct LogCondEle {
struct LogCondEle
{
CLogCmp *cmp;
LogCondEle *next;
LogCondEle(CLogCmp *c, LogCondEle *n): cmp(c) , next(n) { }
LogCondEle(CLogCmp *c, LogCondEle *n): cmp(c), next(n) {}
};
struct LogCond {
struct LogCond
{
int argnum;
LogCondEle *list;
LogCond *next;
LogCond( int a , LogCondEle* ee , LogCond* n ) : argnum(a) , list(ee), next(n) {}
LogCond(int a, LogCondEle* ee, LogCond* n) : argnum(a), list(ee), next(n) {}
~LogCond();
};
CPluginMngr::CPlugin *plugin;
int func;
LogCond *filters;
LogEventsMngr* parent;
CLogEvent *next;
CLogEvent(CPluginMngr::CPlugin *p,int f, LogEventsMngr* ppp) : plugin(p),func(f), filters(0),parent(ppp) ,next(0) { }
CLogEvent(CPluginMngr::CPlugin *p, int f, LogEventsMngr* ppp) : plugin(p), func(f), filters(0), parent(ppp), next(0) {}
~CLogEvent();
public:
inline CPluginMngr::CPlugin *getPlugin() { return plugin; }
void registerFilter( char* filter );
void registerFilter(char* filter);
inline int getFunction() { return func; }
};
private:
CLogEvent *logevents[MAX_LOGARGS+1];
CLogEvent *getValidLogEvent( CLogEvent * a );
CLogEvent *logevents[MAX_LOGARGS + 1];
CLogEvent *getValidLogEvent(CLogEvent * a);
CLogCmp* registerCondition(char* filter);
void clearConditions();
public:
LogEventsMngr();
~LogEventsMngr();
// Interface
CLogEvent* registerLogEvent( CPluginMngr::CPlugin* plugin, int func, int pos );
CLogEvent* registerLogEvent(CPluginMngr::CPlugin* plugin, int func, int pos);
inline bool logEventsExist() { return arelogevents; }
void setLogString( char* frmt, va_list& vaptr );
void setLogString( char* frmt , ... );
void parseLogString( );
void setLogString(char* frmt, va_list& vaptr);
void setLogString(char* frmt, ...);
void parseLogString();
void executeLogEvents();
inline const char* getLogString() { return logString; }
inline int getLogArgNum() { return logArgc; }
inline const char* getLogArg( int i ) { return ( i < 0 || i >= logArgc ) ? "" : logArgs[ i ]; }
inline const char* getLogArg(int i) { return (i < 0 || i >= logArgc) ? "" : logArgs[i]; }
void clearLogEvents();
class iterator {
class iterator
{
CLogEvent* a;
LogEventsMngr* b;
public:
inline iterator(CLogEvent*aa,LogEventsMngr* bb) : a(aa), b(bb) {}
inline iterator& operator++() {
a = b->getValidLogEvent( a->next );
inline iterator(CLogEvent*aa, LogEventsMngr* bb) : a(aa), b(bb) {}
inline iterator& operator++()
{
a = b->getValidLogEvent(a->next);
return *this;
}
inline bool operator==(const iterator& c) const { return a == c.a; }
inline bool operator!=(const iterator& c) const { return !operator==(c); }
inline bool operator!=(const iterator& c) const { return !operator == (c); }
CLogEvent& operator*() { return *a; }
operator bool ( ) const { return a ? true : false; }
operator bool () const { return a ? true : false; }
};
inline iterator begin() { return iterator(getValidLogEvent(logevents[ logArgc ]),this); }
inline iterator end() { return iterator(0,this); }
inline iterator begin() { return iterator(getValidLogEvent(logevents[logArgc]), this); }
inline iterator end() { return iterator(0, this); }
};
#endif
#endif //LOGEVENTS_H

View File

@ -35,7 +35,8 @@
// *****************************************************
// class MenuMngr
// *****************************************************
MenuMngr::MenuCommand::MenuCommand( CPluginMngr::CPlugin *a, int mi, int k, int f ) {
MenuMngr::MenuCommand::MenuCommand(CPluginMngr::CPlugin *a, int mi, int k, int f)
{
plugin = a;
keys = k;
menuid = mi;
@ -46,32 +47,80 @@ MenuMngr::MenuCommand::MenuCommand( CPluginMngr::CPlugin *a, int mi, int k, int
MenuMngr::~MenuMngr()
{
clear();
MenuMngr::MenuIdEle::uniqueid = 0;
}
int MenuMngr::findMenuId(const char* name, AMX* amx)
{
for( MenuIdEle* b = headid; b ; b = b->next) {
if ( (!amx || !b->amx || amx == b->amx) && strstr(name,b->name.c_str()) )
for (MenuIdEle* b = headid; b; b = b->next)
{
if ((!amx || !b->amx || amx == b->amx) && strstr(name,b->name.c_str()))
return b->id;
}
return 0;
}
int MenuMngr::registerMenuId(const char* n, AMX* a )
void MenuMngr::removeMenuId(int id)
{
int id = findMenuId( n, a );
if (id) return id;
headid = new MenuIdEle( n, a , headid );
MenuIdEle *n = headid;
MenuIdEle *l = NULL;
while (n)
{
if (n->id == id)
{
if (l)
l->next = n->next;
else
headid = n->next;
delete n;
break;
}
l = n;
n = n->next;
}
MenuCommand *c = headcmd;
MenuCommand *lc = NULL;
MenuCommand *tmp;
while (c)
{
if (c->menuid == id)
{
if (lc)
lc->next = c->next;
else
headcmd = c->next;
tmp = c->next;
delete c;
c = tmp;
} else {
lc = c;
c = c->next;
}
}
}
int MenuMngr::registerMenuId(const char* n, AMX* a)
{
int id = findMenuId(n, a);
if (id)
return id;
headid = new MenuIdEle(n, a, headid);
if (!headid)
return 0; // :TODO: Better error report
return headid->id;
}
void MenuMngr::registerMenuCmd( CPluginMngr::CPlugin *a,int mi, int k , int f )
void MenuMngr::registerMenuCmd(CPluginMngr::CPlugin *a, int mi, int k, int f)
{
MenuCommand** temp = &headcmd;
while(*temp) temp = &(*temp)->next;
*temp = new MenuCommand(a,mi, k,f);
while (*temp) temp = &(*temp)->next;
*temp = new MenuCommand(a, mi, k, f);
}
void MenuMngr::clear()

View File

@ -43,17 +43,18 @@ class MenuMngr
String name;
AMX* amx;
MenuIdEle* next;
int id;
static int uniqueid;
MenuIdEle( const char* n, AMX* a, MenuIdEle* m ) : name( n ) , amx(a) , next( m ) {
MenuIdEle(const char* n, AMX* a, MenuIdEle* m) : name(n), amx(a), next(m)
{
id = ++uniqueid;
}
~MenuIdEle() { --uniqueid; }
} *headid;
public:
class iterator;
private:
class MenuCommand
@ -65,28 +66,29 @@ private:
int menuid;
int keys;
int function;
MenuCommand* next;
MenuCommand( CPluginMngr::CPlugin *a, int mi, int k, int f );
MenuCommand(CPluginMngr::CPlugin *a, int mi, int k, int f);
public:
inline int getFunction() { return function; }
inline CPluginMngr::CPlugin* getPlugin() { return plugin; }
inline bool matchCommand( int m, int k ) { return ((m == menuid) && (keys & k)); }
inline bool matchCommand(int m, int k) { return ((m == menuid) && (keys & k)); }
} *headcmd;
public:
MenuMngr() { headid = 0; headcmd = 0; }
~MenuMngr();
// Interface
int findMenuId(const char* name, AMX* a = 0);
int registerMenuId(const char* n, AMX* a );
int registerMenuId(const char* n, AMX* a);
void removeMenuId(int id);
void registerMenuCmd(CPluginMngr::CPlugin *a, int mi, int k, int f);
void clear();
class iterator {
class iterator
{
MenuCommand* a;
public:
iterator(MenuCommand*aa) : a(aa) {}
@ -96,8 +98,9 @@ public:
operator bool () const { return a ? true : false; }
MenuCommand& operator*() { return *a; }
};
inline iterator begin() const { return iterator(headcmd); }
inline iterator end() const { return iterator(0); }
};
#endif
#endif //MENUS_H

View File

@ -29,11 +29,12 @@
* version.
*/
#include "amxmodx.h"
#include "newmenus.h"
// *****************************************************
// class CPlayer
// *****************************************************
void CPlayer::Init( edict_t* e , int i )
void CPlayer::Init(edict_t* e, int i)
{
index = i;
pEdict = e;
@ -48,6 +49,8 @@ void CPlayer::Init( edict_t* e , int i )
aiming = 0;
menu = 0;
keys = 0;
menuexpire = 0.0;
newmenu = -1;
death_weapon.clear();
name.clear();
@ -55,46 +58,107 @@ void CPlayer::Init( edict_t* e , int i )
team.clear();
}
void CPlayer::Disconnect() {
void CPlayer::Disconnect()
{
ingame = false;
initialized = false;
authorized = false;
if (newmenu != -1)
{
Menu *pMenu = g_NewMenus[newmenu];
if (pMenu)
{
//prevent recursion
newmenu = -1;
menu = 0;
executeForwards(pMenu->func,
static_cast<cell>(ENTINDEX(pEdict)),
static_cast<cell>(pMenu->thisId),
static_cast<cell>(MENU_EXIT));
}
}
List<ClientCvarQuery_Info *>::iterator iter, end=queries.end();
for (iter=queries.begin(); iter!=end; iter++)
{
unregisterSPForward((*iter)->resultFwd);
delete [] (*iter)->params;
delete (*iter);
}
queries.clear();
bot = 0;
menu = 0;
newmenu = -1;
}
void CPlayer::PutInServer() {
void CPlayer::PutInServer()
{
playtime = gpGlobals->time;
ingame = true;
}
bool CPlayer::Connect(const char* connectname,const char* ipaddress) {
int CPlayer::NextHUDChannel()
{
int ilow = 1;
for (int i=ilow+1; i<=4; i++)
{
if (channels[i] < channels[ilow])
ilow = i;
}
return ilow;
}
bool CPlayer::Connect(const char* connectname, const char* ipaddress)
{
name.assign(connectname);
ip.assign(ipaddress);
time = gpGlobals->time;
bot = IsBot();
death_killer = 0;
memset(flags,0,sizeof(flags));
memset(weapons,0,sizeof(weapons));
menu = 0;
newmenu = -1;
memset(flags, 0, sizeof(flags));
memset(weapons, 0, sizeof(weapons));
initialized = true;
authorized = false;
const char* authid = GETPLAYERAUTHID( pEdict );
for (int i=0; i<=4; i++)
{
channels[i] = 0.0f;
hudmap[i] = 0;
}
if ( (authid == 0) || (*authid == 0)
|| (strcmp( authid , "STEAM_ID_PENDING") == 0) )
List<ClientCvarQuery_Info *>::iterator iter, end=queries.end();
for (iter=queries.begin(); iter!=end; iter++)
{
unregisterSPForward((*iter)->resultFwd);
delete [] (*iter)->params;
delete (*iter);
}
queries.clear();
const char* authid = GETPLAYERAUTHID(pEdict);
if ((authid == 0) || (*authid == 0) || (strcmp(authid, "STEAM_ID_PENDING") == 0))
return true;
return false;
}
// *****************************************************
// class Grenades
// *****************************************************
void Grenades::put( edict_t* grenade, float time, int type, CPlayer* player )
void Grenades::put(edict_t* grenade, float time, int type, CPlayer* player)
{
Obj* a = new Obj;
if ( a == 0 ) return;
if (a == 0) return;
a->player = player;
a->grenade = grenade;
a->time = gpGlobals->time + time;
@ -103,34 +167,37 @@ void Grenades::put( edict_t* grenade, float time, int type, CPlayer* player )
head = a;
}
bool Grenades::find( edict_t* enemy, CPlayer** p, int& type )
bool Grenades::find(edict_t* enemy, CPlayer** p, int& type)
{
bool found = false;
Obj** a = &head;
while ( *a ){
if ( (*a)->time > gpGlobals->time ) {
if ( (*a)->grenade == enemy ) {
while (*a)
{
if ((*a)->time > gpGlobals->time)
{
if ((*a)->grenade == enemy)
{
found = true;
(*p) = (*a)->player;
type = (*a)->type;
}
}
else {
} else {
Obj* b = (*a)->next;
delete *a;
*a = b;
continue;
}
a = &(*a)->next;
}
return found;
}
void Grenades::clear()
{
while(head){
while (head)
{
Obj* a = head->next;
delete head;
head = a;
@ -140,93 +207,119 @@ void Grenades::clear()
// *****************************************************
// class XVars
// *****************************************************
void XVars::clear() {
void XVars::clear()
{
delete[] head;
head = 0;
num = 0;
size = 0;
}
int XVars::put( AMX* p, cell* v )
int XVars::put(AMX* p, cell* v)
{
for(int a = 0; a < num; ++a) {
if ( (head[a].amx == p) && (head[a].value == v) )
for (int a = 0; a < num; ++a)
{
if ((head[a].amx == p) && (head[a].value == v))
return a;
}
if ( (num >= size) && realloc_array( size ? (size * 2) : 8 ) )
if ((num >= size) && realloc_array(size ? (size * 2) : 8))
return -1;
head[num].value = v;
head[num].amx = p;
return num++;
}
int XVars::realloc_array( int nsize )
int XVars::realloc_array(int nsize)
{
XVarEle* me = new XVarEle[nsize];
if ( me ){
for(int a = 0 ; a < num; ++a)
if (me)
{
for (int a = 0 ; a < num; ++a)
me[a] = head[a];
delete[] head;
head = me;
size = nsize;
return 0;
}
return 1;
}
// *****************************************************
// class TeamIds
// *****************************************************
TeamIds::TeamIds() { head = 0; newTeam = 0; }
TeamIds::~TeamIds() {
while( head ) {
TeamIds::~TeamIds()
{
while (head)
{
TeamEle* a = head->next;
delete head;
head = a;
}
}
void TeamIds::registerTeam( const char* n ,int s )
void TeamIds::registerTeam(const char* n, int s)
{
TeamEle** a = &head;
while( *a ){
if ( strcmp((*a)->name.c_str(),n) == 0 ){
if (s != -1){
while (*a)
{
if (strcmp((*a)->name.c_str(),n) == 0)
{
if (s != -1)
{
(*a)->id = s;
newTeam &= ~(1<<(*a)->tid);
}
return;
}
a = &(*a)->next;
}
*a = new TeamEle( n , s );
if ( *a == 0 ) return;
*a = new TeamEle(n, s);
if (*a == 0)
return;
newTeam |= (1<<(*a)->tid);
}
int TeamIds::findTeamId( const char* n )
int TeamIds::findTeamId(const char* n)
{
TeamEle* a = head;
while( a ){
if ( !stricmp(a->name.c_str(),n) )
while (a)
{
if (!stricmp(a->name.c_str(), n))
return a->id;
a = a->next;
}
return -1;
}
int TeamIds::findTeamIdCase( const char* n)
int TeamIds::findTeamIdCase(const char* n)
{
TeamEle* a = head;
while( a ){
if ( !strcmp(a->name.c_str(), n) )
while (a)
{
if (!strcmp(a->name.c_str(), n))
return a->id;
a = a->next;
}
return -1;
}
char TeamIds::TeamEle::uid = 0;

View File

@ -33,38 +33,47 @@
#define CMISC_H
#include "CList.h"
#include "sh_list.h"
// *****************************************************
// class CCVar
// *****************************************************
class CCVar
{
cvar_t cvar;
String name;
String plugin;
public:
CCVar( const char* pname, const char* pplugin,
int pflags, float pvalue ) : name(pname) , plugin(pplugin ) {
CCVar(const char* pname, const char* pplugin, int pflags, float pvalue) : name(pname), plugin(pplugin)
{
cvar.name = (char*)name.c_str();
cvar.flags = pflags;
cvar.string = "";
cvar.value = pvalue;
}
inline cvar_t* getCvar() { return &cvar; }
inline const char* getPluginName() { return plugin.c_str(); }
inline const char* getName() { return name.c_str(); }
inline bool operator == ( const char* string ) { return (strcmp(name.c_str(),string)==0); }
inline bool operator == (const char* string) { return (strcmp(name.c_str(), string) == 0); }
};
// *****************************************************
// class CPlayer
// *****************************************************
struct ClientCvarQuery_Info
{
int resultFwd;
int requestId;
int paramLen;
cell *params;
};
class CPlayer
{
public:
edict_t* pEdict;
@ -76,11 +85,14 @@ public:
bool ingame;
bool bot;
bool authorized;
bool vgui;
float time;
float playtime;
float menuexpire;
struct {
struct
{
int ammo;
int clip;
} weapons[MAX_WEAPONS];
@ -102,25 +114,35 @@ public:
int newmenu;
int page;
float channels[5];
cell hudmap[5];
Vector lastTrace;
Vector thisTrace;
Vector lastHit;
void Init( edict_t* e , int i );
List<ClientCvarQuery_Info *> queries;
void Init(edict_t* e, int i);
void Disconnect();
void PutInServer();
bool Connect(const char* connectname,const char* ipaddress);
inline bool IsBot(){
return ((pEdict->v.flags & FL_FAKECLIENT)?true:false);
bool Connect(const char* connectname, const char* ipaddress);
inline bool IsBot()
{
return ((pEdict->v.flags & FL_FAKECLIENT) ? true : false);
}
inline bool IsAlive(){
return ((pEdict->v.deadflag==DEAD_NO)&&(pEdict->v.health>0));
inline bool IsAlive()
{
return ((pEdict->v.deadflag == DEAD_NO) && (pEdict->v.health > 0));
}
inline void Authorize() { authorized = true; }
int NextHUDChannel();
};
// *****************************************************
@ -138,31 +160,35 @@ class Grenades
Obj* next;
} *head;
public:
Grenades() { head = 0; }
~Grenades() { clear(); }
void put( edict_t* grenade, float time, int type, CPlayer* player );
bool find( edict_t* enemy, CPlayer** p, int& type );
void put(edict_t* grenade, float time, int type, CPlayer* player);
bool find(edict_t* enemy, CPlayer** p, int& type);
void clear();
};
// *****************************************************
// class ForceObject
// *****************************************************
class ForceObject {
class ForceObject
{
String filename;
FORCE_TYPE type;
Vector mins;
Vector maxs;
AMX* amx;
public:
ForceObject(const char* n, FORCE_TYPE c,Vector& mi, Vector& ma, AMX* a) :
filename(n) , type(c), mins(mi), maxs(ma), amx(a) {}
ForceObject(const char* n, FORCE_TYPE c, Vector& mi, Vector& ma, AMX* a) : filename(n), type(c), mins(mi), maxs(ma), amx(a) {}
inline const char* getFilename() { return filename.c_str(); }
inline AMX* getAMX() { return amx; }
Vector& getMin() { return mins; }
Vector& getMax() { return maxs; }
inline FORCE_TYPE getForceType() { return type; }
};
@ -172,30 +198,38 @@ public:
class XVars
{
struct XVarEle {
struct XVarEle
{
AMX* amx;
cell* value;
};
XVarEle* head;
int size;
int num;
int realloc_array( int nsize );
int realloc_array(int nsize);
public:
XVars() { num = 0; size = 0; head = 0; }
~XVars() { clear(); }
void clear();
int put( AMX* a, cell* v );
inline cell getValue( int a ) {
return ( a >= 0 && a < num ) ? *(head[a].value) : 0;
int put(AMX* a, cell* v);
inline cell getValue(int a)
{
return (a >= 0 && a < num) ? *(head[a].value) : 0;
}
inline int setValue( int a, cell v ) {
if ( a >= 0 && a < num ){
inline int setValue(int a, cell v)
{
if (a >= 0 && a < num)
{
*(head[a].value) = v;
return 0;
}
return 1;
}
};
@ -203,34 +237,41 @@ public:
// *****************************************************
// class CScript
// *****************************************************
class CScript
{
String filename;
AMX* amx;
void* code;
public:
CScript(AMX* aa, void* cc,const char* ff):filename(ff),amx(aa),code(cc){}
CScript(AMX* aa, void* cc, const char* ff) : filename(ff), amx(aa), code(cc) {}
inline AMX* getAMX() { return amx; }
inline const char* getName() { return filename.c_str(); }
inline bool operator==( void* a ) { return (amx == (AMX*)a); }
inline bool operator==(void* a) { return (amx == (AMX*)a); }
inline void* getCode() { return code; }
};
// *****************************************************
// class TeamIds
// *****************************************************
class TeamIds
{
struct TeamEle {
struct TeamEle
{
String name;
int id;
char tid;
static char uid;
TeamEle* next;
TeamEle(const char* n, int& i) : name(n) , id(i) , next(0) {
TeamEle(const char* n, int& i) : name(n), id(i), next(0)
{
tid = uid++;
};
~TeamEle(){ --uid; }
}
~TeamEle() { --uid; }
} *head;
int newTeam;
@ -238,15 +279,11 @@ class TeamIds
public:
TeamIds();
~TeamIds();
void registerTeam( const char* n ,int s );
int findTeamId( const char* n);
int findTeamIdCase( const char* n);
void registerTeam(const char* n, int s);
int findTeamId(const char* n);
int findTeamIdCase(const char* n);
inline bool isNewTeam() { return newTeam ? true : false; }
};
#endif
#endif //CMISC_H

View File

@ -30,9 +30,10 @@
*/
#include "amxmodx.h"
#include "libraries.h"
#ifndef FAR
#define FAR
#define FAR
#endif
// New
@ -41,6 +42,8 @@ typedef int (FAR *QUERYMOD_NEW)(int * /*ifvers*/, amxx_module_info_s * /*modInfo
typedef int (FAR *ATTACHMOD_NEW)(PFN_REQ_FNPTR /*reqFnptrFunc*/);
typedef int (FAR *DETACHMOD_NEW)(void);
typedef void (FAR *PLUGINSLOADED_NEW)(void);
typedef void (*PLUGINSUNLOADED_NEW)(void);
typedef void (*PLUGINSUNLOADING_NEW)(void);
// *****************************************************
// class CModule
@ -55,7 +58,7 @@ CModule::CModule(const char* fname)
CModule::~CModule()
{
// old & new
if ( m_Handle )
if (m_Handle)
DLFREE(m_Handle);
clear();
@ -67,6 +70,7 @@ void CModule::clear(bool clearFilename)
m_Metamod = false;
m_Handle = NULL;
m_Status = MODULE_NONE;
if (clearFilename)
m_Filename.assign("unknown");
@ -78,6 +82,12 @@ void CModule::clear(bool clearFilename)
m_InfoNew.reload = 0;
m_MissingFunc = NULL;
for (size_t i=0; i<m_DestroyableIndexes.size(); i++)
{
delete [] m_Natives[m_DestroyableIndexes[i]];
}
m_DestroyableIndexes.clear();
m_Natives.clear();
}
@ -101,6 +111,53 @@ bool CModule::attachMetamod(const char *mmfile, PLUG_LOADTIME now)
return true;
}
//this ugly function is ultimately something like O(n^4).
//sigh. it shouldn't be needed.
void CModule::rewriteNativeLists(AMX_NATIVE_INFO *list)
{
AMX_NATIVE_INFO *curlist;
for (size_t i=0; i<m_Natives.size(); i++)
{
curlist = m_Natives[i];
bool changed = false;
bool found = false;
CVector<size_t> newlist;
for (size_t j=0; curlist[j].func != NULL; j++)
{
found = false;
for (size_t k=0; list[k].func != NULL; k++)
{
if (strcmp(curlist[j].name, list[k].name) == 0)
{
found = true;
break;
}
}
if (found)
{
changed = true;
//don't break, we have to search it all
} else {
newlist.push_back(j);
}
}
if (changed)
{
//now build the new list
AMX_NATIVE_INFO *rlist = new AMX_NATIVE_INFO[newlist.size()+1];
for (size_t j=0; j<newlist.size(); j++)
{
rlist[j].func = curlist[newlist[j]].func;
rlist[j].name = curlist[newlist[j]].name;
}
rlist[newlist.size()].func = NULL;
rlist[newlist.size()].name = NULL;
m_Natives[i] = rlist;
m_DestroyableIndexes.push_back(i);
}
}
}
bool CModule::attachModule()
{
// old & new
@ -114,6 +171,7 @@ bool CModule::attachModule()
if (!AttachFunc_New)
return false;
g_ModuleCallReason = ModuleCall_Attach;
g_CurrentlyCalledModule = this;
int retVal = (*AttachFunc_New)(Module_ReqFnptr);
@ -124,7 +182,7 @@ bool CModule::attachModule()
{
case AMXX_OK:
m_Status = MODULE_LOADED;
return true;
break;
case AMXX_PARAM:
AMXXLOG_Log("[AMXX] Internal Error: Module \"%s\" (version \"%s\") retured \"Invalid parameter\" from Attach func.", m_Filename.c_str(), getVersion());
m_Status = MODULE_INTERROR;
@ -142,6 +200,13 @@ bool CModule::attachModule()
m_Status = MODULE_BADLOAD;
}
if (m_Status == MODULE_LOADED)
{
AddLibrariesFromString(m_InfoNew.library, LibType_Library, LibSource_Module, this);
AddLibrariesFromString(m_InfoNew.libclass, LibType_Class, LibSource_Module, this);
return true;
}
return false;
}
@ -163,6 +228,7 @@ bool CModule::queryModule()
// Try new interface first
QUERYMOD_NEW queryFunc_New = (QUERYMOD_NEW)DLPROC(m_Handle, "AMXX_Query");
if (queryFunc_New)
{
m_Amxx = true;
@ -172,6 +238,7 @@ bool CModule::queryModule()
int retVal = (*queryFunc_New)(&ifVers, &m_InfoNew);
g_CurrentlyCalledModule = NULL;
g_ModuleCallReason = ModuleCall_NotCalled;
switch (retVal)
{
case AMXX_PARAM:
@ -180,10 +247,36 @@ bool CModule::queryModule()
return false;
case AMXX_IFVERS:
if (ifVers < AMXX_INTERFACE_VERSION)
{
//backwards compat for new defs
if (ifVers == 3)
{
g_ModuleCallReason = ModuleCall_Query;
g_CurrentlyCalledModule = this;
retVal = (*queryFunc_New)(&ifVers, &m_InfoNew);
g_CurrentlyCalledModule = NULL;
g_ModuleCallReason = ModuleCall_NotCalled;
if (retVal == AMXX_OK)
{
m_InfoNew.library = m_InfoNew.logtag;
if (StrCaseStr(m_InfoNew.library, "sql")
|| StrCaseStr(m_InfoNew.library, "dbi"))
{
m_InfoNew.libclass = "DBI";
} else {
m_InfoNew.libclass = "";
}
break;
}
return false;
} else {
m_Status = MODULE_OLD;
else
return false;
}
} else {
m_Status = MODULE_NEWER;
return false;
}
case AMXX_OK:
break;
default:
@ -201,9 +294,7 @@ bool CModule::queryModule()
m_Status = MODULE_QUERY;
return true;
}
else
{
} else {
m_Status = MODULE_NOQUERY;
m_Amxx = false;
return false;
@ -215,9 +306,12 @@ bool CModule::detachModule()
if (m_Status != MODULE_LOADED)
return false;
RemoveLibraries(this);
if (m_Amxx)
{
DETACHMOD_NEW detachFunc_New = (DETACHMOD_NEW)DLPROC(m_Handle, "AMXX_Detach");
if (detachFunc_New)
{
g_ModuleCallReason = ModuleCall_Detach;
@ -227,17 +321,52 @@ bool CModule::detachModule()
g_ModuleCallReason = ModuleCall_NotCalled;
}
}
#ifndef FAKEMETA
if (IsMetamod())
{
UnloadMetamodPlugin(m_Handle);
}
#endif
DLFREE(m_Handle);
clear();
return true;
}
void CModule::CallPluginsUnloaded()
{
if (m_Status != MODULE_LOADED)
return;
if (!m_Handle)
return;
PLUGINSUNLOADED_NEW func = (PLUGINSUNLOADED_NEW)DLPROC(m_Handle, "AMXX_PluginsUnloaded");
if (!func)
return;
func();
}
void CModule::CallPluginsUnloading()
{
if (m_Status != MODULE_LOADED)
return;
if (!m_Handle)
return;
PLUGINSUNLOADING_NEW func = (PLUGINSUNLOADING_NEW)DLPROC(m_Handle, "AMXX_PluginsUnloading");
if (!func)
return;
func();
}
void CModule::CallPluginsLoaded()
{
if (m_Status != MODULE_LOADED)
@ -247,14 +376,16 @@ void CModule::CallPluginsLoaded()
return;
PLUGINSLOADED_NEW func = (PLUGINSLOADED_NEW)DLPROC(m_Handle, "AMXX_PluginsLoaded");
if (!func)
return;
func();
}
const char* CModule::getStatus() const
{
switch(m_Status)
switch (m_Status)
{
case MODULE_NONE: return "error";
case MODULE_QUERY: return "pending";
@ -270,5 +401,6 @@ const char* CModule::getStatus() const
case MODULE_NOT64BIT: return "not 64bit";
default: break;
}
return "unknown";
}

View File

@ -36,7 +36,8 @@
#ifndef CMODULE_H
#define CMODULE_H
enum MODULE_STATUS {
enum MODULE_STATUS
{
MODULE_NONE, // No module loaded
MODULE_QUERY, // Query failed
MODULE_BADLOAD, // Bad file or the module writer messed something up ;]
@ -58,21 +59,24 @@ struct amxx_module_info_s
const char *version;
int reload; // reload on mapchange when nonzero
const char *logtag; //added in version 2
const char *library; // added in version 4
const char *libclass; // added in version 4
};
#define AMXX_OK 0 /* no error */
#define AMXX_IFVERS 1 /* interface version */
#define AMXX_PARAM 2 /* Invalid parameter */
#define AMXX_FUNC_NOT_PRESENT 3 /* Function not present */
#define AMXX_INTERFACE_VERSION 3
#define AMXX_INTERFACE_VERSION 4
class CModule
{
String m_Filename; // Filename
bool m_Metamod; // Using metamod?
bool m_Amxx; // Using new module interface?
amxx_module_info_s m_InfoNew; // module info (new module interface)
DLHANDLE m_Handle; // handle
MODULE_STATUS m_Status; // status
@ -84,12 +88,16 @@ public:
~CModule();
// Interface
bool attachModule();
bool queryModule();
bool detachModule();
void rewriteNativeLists(AMX_NATIVE_INFO *list);
#ifndef FAKEMETA
bool attachMetamod(const char *mmfile, PLUG_LOADTIME now);
#endif
const char* getStatus() const;
inline const char* getType() const { return m_Amxx ? "amxx" : (m_Metamod ? "amx&mm" : "amx"); }
inline const char* getAuthor() const { return m_InfoNew.author; }
@ -97,18 +105,19 @@ public:
inline const char* getName() const { return m_InfoNew.name; }
inline const amxx_module_info_s* getInfoNew() const { return &m_InfoNew; } // new
inline int getStatusValue() { return m_Status; }
inline bool operator==( const char* fname ) { return !strcmp( m_Filename.c_str() , fname ); }
inline bool operator==(const char* fname) { return !strcmp(m_Filename.c_str(), fname); }
inline bool isReloadable() { return ((m_Status == MODULE_LOADED) && (m_InfoNew.reload != 0)); }
inline bool isAmxx() const { return m_Amxx; }
inline const char *getMissingFunc() const { return m_MissingFunc; }
inline const char *getFilename() { return m_Filename.c_str(); }
inline bool IsMetamod() { return m_Metamod; }
void CModule::CallPluginsLoaded();
CList<AMX_NATIVE_INFO*> m_Natives;
void CallPluginsLoaded();
void CallPluginsUnloaded();
void CallPluginsUnloading();
CVector<AMX_NATIVE_INFO*> m_Natives;
CVector<size_t> m_DestroyableIndexes;
};
#endif
#endif //CMODULE_H

View File

@ -35,17 +35,25 @@
#include "CFile.h"
#include "amx.h"
#include "natives.h"
#include "debugger.h"
#include "libraries.h"
extern const char *no_function;
CPluginMngr::CPlugin* CPluginMngr::loadPlugin(const char* path, const char* name, char* error, int debug) {
CPluginMngr::CPlugin* CPluginMngr::loadPlugin(const char* path, const char* name, char* error, int debug)
{
CPlugin** a = &head;
while( *a ) a = &(*a)->next;
*a = new CPlugin( pCounter++ ,path,name,error, debug);
while (*a)
a = &(*a)->next;
*a = new CPlugin(pCounter++, path, name, error, debug);
return (*a);
}
void CPluginMngr::unloadPlugin( CPlugin** a ) {
void CPluginMngr::unloadPlugin(CPlugin** a)
{
CPlugin* next = (*a)->next;
delete *a;
*a = next;
@ -56,9 +64,10 @@ void CPluginMngr::Finalize()
{
if (m_Finalized)
return;
pNatives = BuildNativeTable();
pNatives = BuildNativeTable();
CPlugin *a = head;
while (a)
{
if (a->getStatusCode() == ps_running)
@ -66,19 +75,20 @@ void CPluginMngr::Finalize()
amx_Register(a->getAMX(), pNatives, -1);
a->Finalize();
}
a=a->next;
a = a->next;
}
m_Finalized = true;
}
int CPluginMngr::loadPluginsFromFile( const char* filename )
int CPluginMngr::loadPluginsFromFile(const char* filename)
{
char file[256];
FILE *fp = fopen(build_pathname_r(file, sizeof(file)-1, "%s",filename) , "rt");
FILE *fp = fopen(build_pathname_r(file, sizeof(file) - 1, "%s", filename), "rt");
if ( !fp )
if (!fp)
{
AMXXLOG_Log( "[AMXX] Plugins list not found (file \"%s\")",filename);
AMXXLOG_Log("[AMXX] Plugins list not found (file \"%s\")", filename);
return 1;
}
@ -89,22 +99,37 @@ int CPluginMngr::loadPluginsFromFile( const char* filename )
String line;
while ( !feof(fp) )
while (!feof(fp))
{
pluginName[0] = '\0';
debug[0] = '\0';
debugFlag = 0;
line.clear();
line._fread(fp);
sscanf(line.c_str(),"%s %s",pluginName, debug);
if (!isalnum(*pluginName)) continue;
/** quick hack */
char *ptr = const_cast<char *>(line.c_str());
while (*ptr)
{
if (*ptr == ';')
{
*ptr = '\0';
} else {
ptr++;
}
}
sscanf(line.c_str(), "%s %s", pluginName, debug);
if (!isalnum(*pluginName))
continue;
if (isalnum(*debug) && strcmp(debug, "debug") == 0)
{
debugFlag = 1;
}
CPlugin* plugin = loadPlugin( pluginsDir , pluginName , error, debugFlag);
CPlugin* plugin = loadPlugin(pluginsDir, pluginName, error, debugFlag);
if (plugin->getStatusCode() == ps_bad_load)
{
@ -117,14 +142,20 @@ int CPluginMngr::loadPluginsFromFile( const char* filename )
fclose(fp);
InvalidateCache();
return pCounter;
}
void CPluginMngr::clear() {
void CPluginMngr::clear()
{
CPlugin**a = &head;
while ( *a )
while (*a)
unloadPlugin(a);
m_Finalized = false;
if (pNatives)
{
delete [] pNatives;
@ -132,37 +163,48 @@ void CPluginMngr::clear() {
}
}
CPluginMngr::CPlugin* CPluginMngr::findPluginFast(AMX *amx)
CPluginMngr::CPlugin* CPluginMngr::findPlugin(AMX *amx)
{
return (CPlugin*)(amx->userdata[3]);
}
CPluginMngr::CPlugin* CPluginMngr::findPlugin(AMX *amx) {
CPlugin*a = head;
while ( a && &a->amx != amx )
a=a->next;
while (a && &a->amx != amx)
a = a->next;
return a;
}
CPluginMngr::CPlugin* CPluginMngr::findPlugin(int index){
CPluginMngr::CPlugin* CPluginMngr::findPlugin(int index)
{
CPlugin*a = head;
while ( a && index--)
a=a->next;
while (a && index--)
a = a->next;
return a;
}
CPluginMngr::CPlugin* CPluginMngr::findPlugin(const char* name) {
if (!name) return 0;
CPluginMngr::CPlugin* CPluginMngr::findPlugin(const char* name)
{
if (!name)
return 0;
int len = strlen(name);
if (!len) return 0;
if (!len)
return 0;
CPlugin*a = head;
while( a && strncmp(a->name.c_str(), name,len) )
a=a->next;
while (a && strncmp(a->name.c_str(), name, len))
a = a->next;
return a;
}
const char* CPluginMngr::CPlugin::getStatus() const {
switch(status){
const char* CPluginMngr::CPlugin::getStatus() const
{
switch (status)
{
case ps_running:
{
if (m_Debug)
@ -178,33 +220,41 @@ const char* CPluginMngr::CPlugin::getStatus() const {
case ps_stopped: return "stopped";
case ps_locked: return "locked";
}
return "error";
}
CPluginMngr::CPlugin::CPlugin(int i, const char* p,const char* n, char* e, int d) : name(n), title(n) {
CPluginMngr::CPlugin::CPlugin(int i, const char* p, const char* n, char* e, int d) : name(n), title(n)
{
const char* unk = "unknown";
title.assign(unk);
author.assign(unk);
version.assign(unk);
char file[256];
char* path = build_pathname_r(file, sizeof(file)-1, "%s/%s",p,n);
char* path = build_pathname_r(file, sizeof(file) - 1, "%s/%s", p, n);
code = 0;
memset(&amx, 0, sizeof(AMX));
int err = load_amxscript(&amx,&code,path,e, d);
if ( err == AMX_ERR_NONE )
int err = load_amxscript(&amx, &code, path, e, d);
if (err == AMX_ERR_NONE)
{
status = ps_running;
} else {
status = ps_bad_load;
}
amx.userdata[3] = this;
amx.userdata[UD_FINDPLUGIN] = this;
paused_fun = 0;
next = 0;
id = i;
if (status == ps_running)
{
m_PauseFwd = registerSPForwardByName(&amx, "plugin_pause");
m_UnpauseFwd = registerSPForwardByName(&amx, "plugin_unpause");
m_PauseFwd = registerSPForwardByName(&amx, "plugin_pause", FP_DONE);
m_UnpauseFwd = registerSPForwardByName(&amx, "plugin_unpause", FP_DONE);
if (amx.flags & AMX_FLAG_DEBUG)
{
m_Debug = true;
@ -214,51 +264,109 @@ CPluginMngr::CPlugin::CPlugin(int i, const char* p,const char* n, char* e, int d
}
}
CPluginMngr::CPlugin::~CPlugin( )
CPluginMngr::CPlugin::~CPlugin()
{
unload_amxscript( &amx, &code );
unload_amxscript(&amx, &code);
}
int AMXAPI native_handler(AMX *amx, int index)
{
Handler *pHandler = (Handler *)amx->userdata[UD_HANDLER];
char name[sNAMEMAX + 1];
amx_GetNative(amx, index, name);
return pHandler->HandleNative(name, index, 0);
}
static cell AMX_NATIVE_CALL invalid_native(AMX *amx, cell *params)
{
//A script has accidentally called an invalid native! give them a
// first chance to block the resulting error.
Handler *pHandler = (Handler *)amx->userdata[UD_HANDLER];
//this should never happen
if (!pHandler)
{
LogError(amx, AMX_ERR_INVNATIVE, "Invalid native attempt");
return 0;
}
//this should never happen because this native won't be called
// if the plugin isn't filtering.
if (!pHandler->IsNativeFiltering())
{
LogError(amx, AMX_ERR_INVNATIVE, "Invalid native attempt");
return 0;
}
char name[sNAMEMAX + 1];
int native = (int)(_INT_PTR)(amx->usertags[UT_NATIVE]);
int err = amx_GetNative(amx, native, name);
if (err != AMX_ERR_NONE)
name[0] = '\0';
//1 - because we're trapping usage
if (!pHandler->HandleNative(name, native, 1))
{
amx->usertags[UT_NATIVE] = (void *)native;
LogError(amx, AMX_ERR_INVNATIVE, NULL);
return 0;
}
//Someday maybe allow native filters to write their own return value?
return 0;
}
void CPluginMngr::CPlugin::Finalize()
{
char buffer[128];
int old_status = status;
if (CheckModules(&amx, buffer))
{
if ( amx_Register(&amx, core_Natives, -1) != AMX_ERR_NONE )
if (amx_Register(&amx, core_Natives, -1) != AMX_ERR_NONE)
{
Handler *pHandler = (Handler *)amx.userdata[UD_HANDLER];
int res = 0;
if (pHandler->IsNativeFiltering())
res = amx_CheckNatives(&amx, native_handler);
if (!res)
{
status = ps_bad_load;
sprintf(buffer, "Plugin uses an unknown function (name \"%s\") - check your modules.ini.", no_function);
errorMsg.assign(buffer);
amx.error = AMX_ERR_NOTFOUND;
} else {
amx_RegisterToAny(&amx, invalid_native);
}
}
} else {
status = ps_bad_load;
errorMsg.assign(buffer);
amx.error = AMX_ERR_NOTFOUND;
}
if (old_status != status)
{
AMXXLOG_Log("[AMXX] Plugin \"%s\" failed to load: %s", name.c_str(), errorMsg.c_str());
}
}
void CPluginMngr::CPlugin::pauseFunction( int id ) {
if (isValid()){
paused_fun |= (1<<id);
g_commands.clearBufforedInfo();
}
void CPluginMngr::CPlugin::pauseFunction(int id)
{
}
void CPluginMngr::CPlugin::unpauseFunction( int id ) {
if (isValid()) {
paused_fun &= ~(1<<id);
g_commands.clearBufforedInfo();
}
void CPluginMngr::CPlugin::unpauseFunction(int id)
{
}
void CPluginMngr::CPlugin::setStatus( int a ) {
void CPluginMngr::CPlugin::setStatus(int a)
{
status = a;
g_commands.clearBufforedInfo(); // ugly way
}
@ -282,10 +390,258 @@ void CPluginMngr::CPlugin::unpausePlugin()
if (isValid())
{
// set status first so the function will be marked executable
setStatus(ps_running);
// call plugin_unpause if provided
if (m_UnpauseFwd != -1)
executeForwards(m_UnpauseFwd);
}
}
char *CPluginMngr::ReadIntoOrFromCache(const char *file, size_t &bufsize)
{
List<plcache_entry *>::iterator iter;
plcache_entry *pl;
for (iter=m_plcache.begin(); iter!=m_plcache.end(); iter++)
{
pl = (*iter);
if (pl->path.compare(file) == 0)
{
bufsize = pl->bufsize;
return pl->buffer;
}
}
pl = new plcache_entry;
pl->file = new CAmxxReader(file, sizeof(cell));
pl->buffer = NULL;
if (pl->file->GetStatus() != CAmxxReader::Err_None)
{
delete pl->file;
delete pl;
return NULL;
}
pl->bufsize = pl->file->GetBufferSize();
if (pl->bufsize)
{
pl->buffer = new char[pl->bufsize];
pl->file->GetSection(pl->buffer);
}
if (!pl->buffer || pl->file->GetStatus() != CAmxxReader::Err_None)
{
delete [] pl->buffer;
delete pl->file;
delete pl;
return NULL;
}
pl->path.assign(file);
bufsize = pl->bufsize;
m_plcache.push_back(pl);
return pl->buffer;
}
void CPluginMngr::InvalidateCache()
{
List<plcache_entry *>::iterator iter;
plcache_entry *pl;
for (iter=m_plcache.begin(); iter!=m_plcache.end(); iter++)
{
pl = (*iter);
delete [] pl->buffer;
delete pl->file;
delete pl;
}
m_plcache.clear();
}
void CPluginMngr::InvalidateFileInCache(const char *file, bool freebuf)
{
List<plcache_entry *>::iterator iter;
plcache_entry *pl;
for (iter=m_plcache.begin(); iter!=m_plcache.end(); iter++)
{
pl = (*iter);
if (pl->path.compare(file) == 0)
{
if (freebuf)
delete [] pl->buffer;
delete pl->file;
delete pl;
m_plcache.erase(iter);
return;
}
}
}
void CPluginMngr::CacheAndLoadModules(const char *plugin)
{
size_t progsize;
char *prog = ReadIntoOrFromCache(plugin, progsize);
if (!prog)
return;
AMX_HEADER hdr;
memcpy(&hdr, prog, sizeof(AMX_HEADER));
uint16_t magic = hdr.magic;
amx_Align16(&magic);
if (magic != AMX_MAGIC)
{
return;
}
if (hdr.file_version < MIN_FILE_VERSION ||
hdr.file_version > CUR_FILE_VERSION)
{
return;
}
if ((hdr.defsize != sizeof(AMX_FUNCSTUB)) &&
(hdr.defsize != sizeof(AMX_FUNCSTUBNT)))
{
return;
}
amx_Align32((uint32_t*)&hdr.nametable);
uint16_t *namelength=(uint16_t*)((unsigned char*)prog + (unsigned)hdr.nametable);
amx_Align16(namelength);
if (*namelength>sNAMEMAX)
{
return;
}
if (hdr.stp <= 0)
{
return;
}
AMX amx;
memset(&amx, 0, sizeof(AMX));
amx.base = (unsigned char *)prog;
int num;
char name[sNAMEMAX+1];
num = amx_GetLibraries(&amx);
for (int i=0; i<num; i++)
{
amx_GetLibrary(&amx, i, name, sNAMEMAX);
if (stricmp(name, "Float")==0)
continue;
//awful backwards compat hack
if (stricmp(name, "socket")==0)
strcpy(name, "sockets");
//we don't want to report failed modules here...
LoadModule(name, PT_ANYTIME, true, true);
}
cell tag_id;
amx_NumTags(&amx, &num);
CVector<LibDecoder *> expects;
CVector<LibDecoder *> defaults;
CStack<LibDecoder *> delstack;
for (int i=0; i<num; i++)
{
amx_GetTag(&amx, i, name, &tag_id);
if (name[0] == '?')
{
LibDecoder *dc = new LibDecoder;
delstack.push(dc);
if (DecodeLibCmdString(name, dc))
{
if (dc->cmd == LibCmd_ForceLib)
{
RunLibCommand(dc);
} else if ( (dc->cmd == LibCmd_ExpectClass) ||
(dc->cmd == LibCmd_ExpectLib) )
{
expects.push_back(dc);
} else if (dc->cmd == LibCmd_DefaultLib) {
defaults.push_back(dc);
}
}
}
}
for (size_t i=0; i<expects.size(); i++)
{
RunLibCommand(expects[i]);
}
for (size_t i=0; i<defaults.size(); i++)
{
RunLibCommand(defaults[i]);
}
expects.clear();
defaults.clear();
while (!delstack.empty())
{
delete delstack.front();
delstack.pop();
}
return;
}
void CPluginMngr::CALMFromFile(const char *file)
{
char filename[256];
FILE *fp = fopen(build_pathname_r(filename, sizeof(filename) - 1, "%s", file), "rt");
if (!fp)
{
return;
}
// Find now folder
char pluginName[256];
char line[256];
String rline;
while (!feof(fp))
{
fgets(line, sizeof(line)-1, fp);
if (line[0] == ';' || line[0] == '\n' || line[0] == '\0')
continue;
/** quick hack */
char *ptr = line;
while (*ptr)
{
if (*ptr == ';')
{
*ptr = '\0';
} else {
ptr++;
}
}
rline.assign(line);
rline.trim();
pluginName[0] = '\0';
sscanf(rline.c_str(), "%s", pluginName);
if (!isalnum(*pluginName))
continue;
build_pathname_r(filename, sizeof(filename)-1, "%s/%s", get_localinfo("amxx_pluginsdir", "addons/amxmodx/plugins"), pluginName);
CacheAndLoadModules(filename);
}
fclose(fp);
}

View File

@ -32,22 +32,27 @@
#ifndef PLUGIN_H
#define PLUGIN_H
#include "CString.h"
#include "sh_list.h"
#include "amx.h"
#include "amxxfile.h"
// *****************************************************
// class CPluginMngr
// *****************************************************
enum {
ps_bad_load,
ps_error,
ps_paused,
ps_running,
ps_stopped,
ps_locked,
enum
{
ps_bad_load, //Load failed
ps_error, //Erroneous state
ps_locked, //UNUSED
ps_paused, //Plugin is temporarily paused
ps_stopped, //Plugin is ... more temporarily paused
ps_running, //Plugin is running
};
class CPluginMngr
{
public:
class iterator;
@ -59,23 +64,25 @@ public:
AMX amx;
void* code;
String name;
String version;
String title;
String author;
String errorMsg;
int m_PauseFwd;
int m_UnpauseFwd;
int paused_fun;
int status;
CPlugin* next;
int id;
CPlugin(int i , const char* p,const char* n, char* e, int d);
~CPlugin( );
CPlugin(int i, const char* p, const char* n, char* e, int d);
~CPlugin();
bool m_Debug;
public:
inline const char* getName() { return name.c_str();}
inline const char* getVersion() { return version.c_str();}
inline const char* getTitle() { return title.c_str();}
@ -85,20 +92,21 @@ public:
inline int getId() const { return id; }
inline AMX* getAMX() { return &amx; }
inline const AMX* getAMX() const { return &amx; }
inline void setTitle( const char* n ) { title.assign(n); }
inline void setAuthor( const char* n ) { author.assign(n); }
inline void setVersion( const char* n ) { version.assign(n); }
inline void setError( const char* n ) { errorMsg.assign(n); }
inline bool isValid() const { return ((status == ps_running) && (status != ps_locked)); }
inline bool isPaused() const { return ( (status == ps_paused) ); }
//inline bool isFunctionPaused( int id ) const { return (paused_fun & (1<<id)) ? true : false; }
inline void setTitle(const char* n) { title.assign(n); }
inline void setAuthor(const char* n) { author.assign(n); }
inline void setVersion(const char* n) { version.assign(n); }
inline void setError(const char* n) { errorMsg.assign(n); }
inline bool isValid() const { return (status >= ps_paused); }
inline bool isPaused() const { return ((status == ps_paused) || (status == ps_stopped)); }
inline bool isExecutable(int id) const { return (isValid() && !isPaused()); }
void Finalize();
void pausePlugin();
void unpausePlugin();
void pauseFunction( int id );
void unpauseFunction( int id );
void setStatus( int a );
void pauseFunction(int id);
void unpauseFunction(int id);
void setStatus(int a);
const char* getStatus() const;
inline bool isDebug() const { return m_Debug; }
};
@ -106,11 +114,9 @@ public:
private:
CPlugin *head;
int pCounter;
public:
CPluginMngr() { head = 0; pCounter = 0; pNatives = NULL; m_Finalized=false;}
~CPluginMngr() { clear(); }
~CPluginMngr() { clear(); InvalidateCache(); }
bool m_Finalized;
AMX_NATIVE_INFO *pNatives;
@ -118,17 +124,20 @@ public:
// Interface
CPlugin* loadPlugin(const char* path, const char* name, char* error, int debug);
void unloadPlugin( CPlugin** a );
int loadPluginsFromFile( const char* filename );
CPlugin* findPluginFast(AMX *amx);
void unloadPlugin(CPlugin** a);
int loadPluginsFromFile(const char* filename);
inline CPlugin* findPluginFast(AMX *amx) { return (CPlugin*)(amx->userdata[UD_FINDPLUGIN]); }
CPlugin* findPlugin(AMX *amx);
CPlugin* findPlugin(int index);
CPlugin* findPlugin(const char* name);
inline int getPluginsNum() const { return pCounter; }
void Finalize();
void clear();
class iterator {
class iterator
{
CPlugin *a;
public:
iterator(CPlugin*aa) : a(aa) {}
@ -138,10 +147,24 @@ public:
operator bool () const { return a ? true : false; }
CPlugin& operator*() { return *a; }
};
inline iterator begin() const { return iterator(head); }
inline iterator end() const { return iterator(0); }
public:
struct plcache_entry
{
CAmxxReader *file;
size_t bufsize;
char *buffer;
String path;
};
char *ReadIntoOrFromCache(const char *file, size_t &bufsize);
void InvalidateCache();
void InvalidateFileInCache(const char *file, bool freebuf);
void CacheAndLoadModules(const char *plugin);
void CALMFromFile(const char *file);
private:
List<plcache_entry *> m_plcache;
};
#endif
#endif //PLUGIN_H

View File

@ -45,14 +45,17 @@ public:
item = i;
next = n;
}
CQueueItem *GetNext()
{
return next;
}
T & GetItem()
{
return item;
}
void SetNext(CQueueItem *n)
{
next = n;
@ -71,7 +74,7 @@ public:
bool empty()
{
return ((mSize==0)?true:false);
return ((mSize == 0) ? true : false);
}
void push(const T &v)
@ -119,8 +122,8 @@ public:
private:
CQueueItem *mFirst;
CQueueItem *mLast;
unsigned int mSize;
};
#endif //_INCLUDE_CQUEUE_H

View File

@ -1,101 +0,0 @@
/* AMX Mod X
*
* by the AMX Mod X Development Team
* originally developed by OLO
*
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* 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, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* In addition, as a special exception, the author gives permission to
* link the code of this program with the Half-Life Game Engine ("HL
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
* L.L.C ("Valve"). You must obey the GNU General Public License in all
* respects for all of the code used other than the HL Engine and MODs
* from Valve. If you modify this file, you may extend this exception
* to your version of the file, but you are not obligated to do so. If
* you do not wish to do so, delete this exception statement from your
* version.
*/
//by David "BAILOPAN" Anderson
#ifndef _INCLUDE_CSTACK_H
#define _INCLUDE_CSTACK_H
template <class T>
class CStack
{
public:
struct CStackItem
{
public:
T item;
CStackItem *prev;
};
public:
CStack()
{
mSize = 0;
mStack = NULL;
}
~CStack()
{
CStackItem *p, *t;
p = mStack;
while (p)
{
t = p->prev;
delete p;
p = t;
}
mStack = NULL;
}
bool empty()
{
return (mSize==0);
}
void push(const T & v)
{
CStackItem *p = new CStackItem;
p->item = v;
p->prev = mStack;
mStack = p;
mSize++;
}
void pop()
{
CStackItem *p = mStack;
mStack = p->prev;
delete p;
mSize--;
}
T & top()
{
return mStack->item;
}
size_t size()
{
return mSize;
}
private:
CStackItem *mStack;
size_t mSize;
};
#endif //_INCLUDE_CQUEUE_H

View File

@ -66,7 +66,7 @@ public:
return ret;
}
String(String &src)
String(const String &src)
{
v = NULL;
a_size = 0;
@ -107,8 +107,10 @@ public:
{
clear();
} else {
Grow(strlen(d) + 1, false);
strcpy(v, d);
size_t len = strlen(d);
Grow(len + 1, false);
memcpy(v, d, len);
v[len] = '\0';
}
}
@ -118,7 +120,7 @@ public:
v[0] = '\0';
}
int compare (const char *d)
int compare (const char *d) const
{
if (!v)
return strcmp("", d);
@ -148,13 +150,13 @@ public:
int find(const char c, int index = 0)
{
size_t len = size();
int len = static_cast<int>(size());
if (len < 1)
return npos;
if (index >= (int)len || index < 0)
if (index >= len || index < 0)
return npos;
unsigned int i = 0;
for (i=index; i<(int)len; i++)
int i = 0;
for (i=index; i<len; i++)
{
if (v[i] == c)
{
@ -177,6 +179,30 @@ public:
return false;
}
void reparse_newlines()
{
size_t len = size();
int offs = 0;
char c;
if (!len)
return;
for (size_t i=0; i<len; i++)
{
c = v[i];
if (c == '^' && (i != len-1))
{
c = v[++i];
if (c == 'n')
c = '\n';
else if (c == 't')
c = '\t';
offs++;
}
v[i-offs] = c;
}
v[len-offs] = '\0';
}
void trim()
{
if (!v)
@ -247,7 +273,7 @@ public:
unsigned int i = 0;
size_t len = size();
//check for bounds
if (num == npos || start+num > len-num+1)
if (num == npos || start+num > len-start)
num = len - start;
//do the erasing
bool copyflag = false;
@ -297,7 +323,7 @@ public:
num = len - index;
}
unsigned int i = 0, j=0;
unsigned int i = 0;
unsigned int nslen = num + 2;
ns.Grow(nslen);

View File

@ -33,17 +33,8 @@
#include "CTask.h"
/*********************** CTask ***********************/
int CTaskMngr::CTask::getTaskId() const
{
return m_iId;
}
CPluginMngr::CPlugin *CTaskMngr::CTask::getPlugin() const
{
return m_pPlugin;
}
void CTaskMngr::CTask::set(CPluginMngr::CPlugin *pPlugin, int iFunc, int iFlags, int iId, float fBase, int iParamsLen, const cell *pParams, int iRepeat, float fCurrentTime)
void CTaskMngr::CTask::set(CPluginMngr::CPlugin *pPlugin, int iFunc, int iFlags, cell iId, float fBase, int iParamsLen, const cell *pParams, int iRepeat, float fCurrentTime)
{
clear();
m_bFree = false;
@ -52,9 +43,19 @@ void CTaskMngr::CTask::set(CPluginMngr::CPlugin *pPlugin, int iFunc, int iFlags,
m_iFunc = iFunc;
m_iId = iId;
m_fBase = fBase;
m_bInExecute = false;
if (iFlags & 2)
{
m_bLoop = true;
m_iRepeat = -1;
}
else if (iFlags & 1)
{
m_bLoop = true;
m_iRepeat = iRepeat;
}
m_iRepeat = (iFlags & 1) ? iRepeat : 0;
m_bLoop = (iFlags & 2) ? true : false;
m_bAfterStart = (iFlags & 4) ? true : false;
m_bBeforeEnd = (iFlags & 8) ? true : false;
@ -117,7 +118,9 @@ void CTaskMngr::CTask::resetNextExecTime(float fCurrentTime)
void CTaskMngr::CTask::executeIfRequired(float fCurrentTime, float fTimeLimit, float fTimeLeft)
{
bool execute=false;
bool execute = false;
bool done = false;
if (m_bAfterStart)
{
if (fCurrentTime - fTimeLeft + 1.0f >= m_fBase)
@ -129,10 +132,16 @@ void CTaskMngr::CTask::executeIfRequired(float fCurrentTime, float fTimeLimit, f
execute = true;
}
else if (m_fNextExecTime <= fCurrentTime)
{
execute = true;
}
if (execute)
{
//only bother calling if we have something to call
if (!(m_bLoop && !m_iRepeat))
{
m_bInExecute = true;
if (m_iParamLen) // call with parameters
{
cell arr = prepareCellArray(m_pParams, m_iParamLen);
@ -140,18 +149,26 @@ void CTaskMngr::CTask::executeIfRequired(float fCurrentTime, float fTimeLimit, f
} else {
executeForwards(m_iFunc, m_iId);
}
m_bInExecute = false;
}
if (isFree())
return;
// set new exec time OR remove the task if needed
if (m_bLoop || (m_iRepeat-- > 0))
if (m_bLoop)
{
m_fNextExecTime += m_fBase;
if (m_iRepeat != -1 && --m_iRepeat <= 0)
done = true;
} else {
done = true;
}
else
if (done)
{
clear(); // hamster
clear();
} else {
m_fNextExecTime += m_fBase;
}
}
}
@ -169,6 +186,7 @@ CTaskMngr::CTask::CTask()
m_bLoop = false;
m_bAfterStart = false;
m_bBeforeEnd = false;
m_bInExecute = false;
m_fNextExecTime = 0.0f;
@ -182,6 +200,7 @@ CTaskMngr::CTask::~CTask()
}
/*********************** CTaskMngr ***********************/
CTaskMngr::CTaskMngr()
{
m_pTmr_CurrentTime = NULL;
@ -201,21 +220,22 @@ void CTaskMngr::registerTimers(float *pCurrentTime, float *pTimeLimit, float *pT
m_pTmr_TimeLeft = pTimeLeft;
}
void CTaskMngr::registerTask(CPluginMngr::CPlugin *pPlugin, int iFunc, int iFlags, int iId, float fBase, int iParamsLen, const cell *pParams, int iRepeat)
void CTaskMngr::registerTask(CPluginMngr::CPlugin *pPlugin, int iFunc, int iFlags, cell iId, float fBase, int iParamsLen, const cell *pParams, int iRepeat)
{
// first, search for free tasks
TaskListIter iter = m_Tasks.find(CTaskDescriptor(0, NULL, true));
if (iter)
{
// found: reuse it
iter->set(pPlugin, iFunc, iFlags, iId, fBase, iParamsLen, pParams, iRepeat, *m_pTmr_CurrentTime);
}
else
{
} else {
// not found: make a new one
CTask *pTmp = new CTask;
if (!pTmp)
return;
pTmp->set(pPlugin, iFunc, iFlags, iId, fBase, iParamsLen, pParams, iRepeat, *m_pTmr_CurrentTime);
m_Tasks.put(pTmp);
}
@ -225,13 +245,15 @@ int CTaskMngr::removeTasks(int iId, AMX *pAmx)
{
CTaskDescriptor descriptor(iId, pAmx);
TaskListIter iter = m_Tasks.find(descriptor);
int i=0;
int i = 0;
while (iter)
{
iter->clear();
++i;
iter = m_Tasks.find(++iter, descriptor);
}
return i;
}
@ -239,7 +261,8 @@ int CTaskMngr::changeTasks(int iId, AMX *pAmx, float fNewBase)
{
CTaskDescriptor descriptor(iId, pAmx);
TaskListIter iter = m_Tasks.find(descriptor);
int i=0;
int i = 0;
while (iter)
{
iter->changeBase(fNewBase);
@ -247,6 +270,7 @@ int CTaskMngr::changeTasks(int iId, AMX *pAmx, float fNewBase)
++i;
iter = m_Tasks.find(++iter, descriptor);
}
return i;
}

View File

@ -39,32 +39,38 @@ private:
class CTask
{
// task settings
CPluginMngr::CPlugin *m_pPlugin;
int m_iId;
cell m_iId;
int m_iFunc;
int m_iRepeat;
bool m_bInExecute;
bool m_bLoop;
bool m_bAfterStart;
bool m_bBeforeEnd;
float m_fBase; // for normal tasks, stores the interval, for the others, stores the amount of time before start / after end
int m_iParamLen;
cell *m_pParams;
bool m_bFree;
// execution
float m_fNextExecTime;
public:
void set(CPluginMngr::CPlugin *pPlugin, int iFunc, int iFlags, int iId, float fBase, int iParamsLen, const cell *pParams, int iRepeat, float fCurrentTime);
void set(CPluginMngr::CPlugin *pPlugin, int iFunc, int iFlags, cell iId, float fBase, int iParamsLen, const cell *pParams, int iRepeat, float fCurrentTime);
void clear();
bool isFree() const;
CPluginMngr::CPlugin *getPlugin() const;
int getTaskId() const;
inline CPluginMngr::CPlugin *getPlugin() const { return m_pPlugin; }
inline AMX *getAMX() const { return m_pPlugin->getAMX(); }
inline int getTaskId() const { return m_iId; }
void executeIfRequired(float fCurrentTime, float fTimeLimit, float fTimeLeft); // also removes the task if needed
void changeBase(float fNewBase);
void resetNextExecTime(float fCurrentTime);
inline bool inExecute() const { return m_bInExecute; }
bool shouldRepeat();
@ -75,7 +81,7 @@ private:
class CTaskDescriptor
{
public:
int m_iId;
cell m_iId;
AMX *m_pAmx;
bool m_bFree;
@ -89,18 +95,20 @@ private:
friend bool operator == (const CTask &left, const CTaskDescriptor &right)
{
if (right.m_bFree)
return left.isFree();
return (left.isFree() && !left.inExecute());
return !left.isFree() &&
(right.m_pAmx ? left.getPlugin()->getAMX() == right.m_pAmx : true) &&
left.getTaskId() == right.m_iId;
return (!left.isFree()) &&
(right.m_pAmx ? left.getAMX() == right.m_pAmx : true) &&
(left.getTaskId() == right.m_iId);
}
};
/*** CTaskMngr priv members ***/
typedef CList<CTask, CTaskDescriptor> TaskList;
typedef TaskList::iterator TaskListIter;
TaskList m_Tasks;
float *m_pTmr_CurrentTime;
float *m_pTmr_TimeLimit;
float *m_pTmr_TimeLeft;
@ -109,14 +117,14 @@ public:
~CTaskMngr();
void registerTimers(float *pCurrentTime, float *pTimeLimit, float *pTimeLeft); // The timers will always point to the right value
void registerTask(CPluginMngr::CPlugin *pPlugin, int iFunc, int iFlags, int iId, float fBase, int iParamsLen, const cell *pParams, int iRepeat);
void registerTask(CPluginMngr::CPlugin *pPlugin, int iFunc, int iFlags, cell iId, float fBase, int iParamsLen, const cell *pParams, int iRepeat);
int removeTasks(int iId, AMX *pAmx); // remove all tasks that match the id and amx
int changeTasks(int iId, AMX *pAmx, float fNewBase); // change all tasks that match the id and amx
bool taskExists(int iId, AMX *pAmx);
void startFrame();
void clear();
};
#endif
#endif //CTASK_H

View File

@ -39,46 +39,47 @@
// *****************************************************
// class Vault
// *****************************************************
bool Vault::exists( const char* k )
{
if ( *k == 0 ) return false;
return *find( k ) != 0;
bool Vault::exists(const char* k)
{
if (*k == 0) return false;
return *find(k) != 0;
}
void Vault::put( const char* k, const char* v )
void Vault::put(const char* k, const char* v)
{
if ( *k == 0 ) return;
if (*k == 0) return;
if ( *v == 0 )
if (*v == 0)
{
remove( k );
remove(k);
return;
}
Obj** a = find( k );
Obj** a = find(k);
if ( *a )
if (*a)
{
(*a)->value.assign(v);
(*a)->number = atoi( v );
(*a)->number = atoi(v);
}
else
*a = new Obj( k , v );
*a = new Obj(k, v);
}
Vault::Obj::Obj( const char* k, const char* v): key(k) , value(v) , next(0) {
Vault::Obj::Obj(const char* k, const char* v): key(k), value(v), next(0)
{
number = atoi(v);
}
Vault::Obj** Vault::find( const char* n )
Vault::Obj** Vault::find(const char* n)
{
Obj** a = &head;
while( *a )
while (*a)
{
if ( strcmp((*a)->key.c_str(), n) == 0 )
if (strcmp((*a)->key.c_str(), n) == 0)
return a;
a = &(*a)->next;
@ -88,31 +89,31 @@ Vault::Obj** Vault::find( const char* n )
}
int Vault::get_number( const char* n )
int Vault::get_number(const char* n)
{
if ( *n == 0 ) return 0;
if (*n == 0) return 0;
Obj* b = *find( n );
Obj* b = *find(n);
if ( b == 0 ) return 0;
if (b == 0) return 0;
return b->number;
}
const char* Vault::get( const char* n )
const char* Vault::get(const char* n)
{
if ( *n == 0 ) return "";
if (*n == 0) return "";
Obj* b = *find( n );
Obj* b = *find(n);
if ( b == 0 ) return "";
if (b == 0) return "";
return b->value.c_str();
}
void Vault::clear()
{
while ( head )
while (head)
{
Obj* a = head->next;
delete head;
@ -120,58 +121,57 @@ void Vault::clear()
}
}
void Vault::remove( const char* n )
void Vault::remove(const char* n)
{
Obj** b = find( n );
Obj** b = find(n);
if ( *b == 0 ) return;
if (*b == 0) return;
Obj* a = (*b)->next;
delete *b;
*b = a;
}
void Vault::setSource( const char* n )
void Vault::setSource(const char* n)
{
path.assign(n);
}
bool Vault::loadVault( )
bool Vault::loadVault()
{
if ( path.empty() ) return false;
if (path.empty()) return false;
clear();
File a( path.c_str() , "r" );
File a(path.c_str(), "r");
if ( !a ) return false;
if (!a) return false;
const int sz = 512;
char value[sz+1];
char key[sz+1];
char value[sz + 1];
char key[sz + 1];
while ( a >> key && a.skipWs() && a.getline( value , sz ) )
while (a >> key && a.skipWs() && a.getline(value, sz))
{
if ( isalpha ( *key ) )
put( key, value );
if (isalpha(*key))
put(key, value);
}
return true;
}
bool Vault::saveVault( )
bool Vault::saveVault()
{
if ( path.empty() ) return false;
if (path.empty()) return false;
File a( path.c_str() , "w" );
File a(path.c_str(), "w");
if ( !a ) return false;
if (!a) return false;
a << "; Don't modify!" << '\n';
for (Obj* b = head; b ;b = b->next)
for (Obj* b = head; b; b = b->next)
a << b->key << '\t' << b->value << '\n';
return true;

View File

@ -45,38 +45,43 @@ class Vault
{
String key;
String value;
int number;
Obj *next;
Obj( const char* k, const char* v);
Obj(const char* k, const char* v);
} *head;
String path;
Obj** find( const char* n );
Obj** find(const char* n);
public:
Vault() {head=0;}
~Vault() { clear();}
Vault() { head = 0; }
~Vault() { clear(); }
// Interface
bool exists( const char* k );
bool exists(const char* k);
void put(const char* k, const char* v);
void remove( const char* k );
const char* get( const char* n );
int get_number( const char* n );
void setSource( const char* n );
bool loadVault( );
bool saveVault( );
void remove(const char* k);
const char* get(const char* n);
int get_number(const char* n);
void setSource(const char* n);
bool loadVault();
bool saveVault();
void clear();
class iterator {
class iterator
{
Obj * a;
public:
iterator(Obj*aa) : a(aa) {}
iterator& operator++() { if ( a ) a = a->next; return *this; }
iterator(Obj* aa) : a(aa) {}
iterator& operator++() { if (a) a = a->next; return *this; }
bool operator==(const iterator& b) const { return a == b.a; }
bool operator!=(const iterator& b) const { return !operator==(b); }
String& key() const { return a->key; }
@ -87,7 +92,4 @@ public:
inline iterator end() const { return iterator(0); }
};
#endif
#endif //VAULT_CUSTOM_H

View File

@ -70,32 +70,58 @@ template <class T> class CVector
// change size
if (size == m_Size)
return true;
if (!size)
{
if (m_Data)
{
delete [] m_Data;
m_Data = NULL;
m_Size = 0;
}
return true;
}
T *newData = new T[size];
if (!newData)
return false;
if (m_Data)
{
size_t end = (m_Size < size) ? (m_Size) : size;
size_t end = (m_CurrentUsedSize < size) ? (m_CurrentUsedSize) : size;
for (size_t i=0; i<end; i++)
newData[i] = m_Data[i];
delete [] m_Data;
}
if (m_Size < size)
m_CurrentSize = size;
m_Data = newData;
m_Size = size;
if (m_CurrentUsedSize > m_Size)
m_CurrentUsedSize = m_Size;
return true;
}
void FreeMemIfPossible()
{
if (!m_Data)
return;
if (!m_CurrentUsedSize)
{
ChangeSize(0);
return;
}
size_t newSize = m_Size;
while (m_CurrentUsedSize <= newSize / 2)
newSize /= 2;
if (newSize != m_Size)
ChangeSize(newSize);
}
protected:
T *m_Data;
size_t m_Size;
size_t m_CurrentUsedSize;
size_t m_CurrentSize;
public:
class iterator
{
@ -189,7 +215,7 @@ public:
iterator & operator-=(size_t offset)
{
m_Ptr += offset;
m_Ptr -= offset;
return (*this);
}
@ -203,7 +229,7 @@ public:
iterator operator-(size_t offset) const
{
iterator tmp(*this);
tmp.m_Ptr += offset;
tmp.m_Ptr -= offset;
return tmp;
}
@ -277,12 +303,12 @@ public:
return m_Size;
}
iterator begin()
iterator begin() const
{
return iterator(m_Data);
}
iterator end()
iterator end() const
{
return iterator(m_Data + m_CurrentUsedSize);
}
@ -296,7 +322,9 @@ public:
bool reserve(size_t newSize)
{
if (newSize > m_Size)
return ChangeSize(newSize);
return true;
}
bool push_back(const T & elem)
@ -317,14 +345,15 @@ public:
--m_CurrentUsedSize;
if (m_CurrentUsedSize < 0)
m_CurrentUsedSize = 0;
// :TODO: free memory sometimes
FreeMemIfPossible();
}
bool resize(size_t newSize)
{
if (!ChangeSize(newSize))
return false;
FreeMemIfPossible();
m_CurrentUsedSize = newSize;
return true;
}
@ -397,15 +426,13 @@ public:
return m_Data[m_CurrentUsedSize - 1];
}
bool insert(iterator where, const T & value)
iterator insert(iterator where, const T & value)
{
// we have to insert before
// if it is begin, don't decrement
if (where != m_Data)
--where;
// validate iter
if (where < m_Data || where >= (m_Data + m_CurrentUsedSize))
return false;
if (where < m_Data || where > (m_Data + m_CurrentUsedSize))
return iterator(0);
size_t ofs = where - begin();
++m_CurrentUsedSize;
if (!GrowIfNeeded())
@ -414,34 +441,50 @@ public:
return false;
}
memmove(where.base() + 1, where.base(), m_CurrentUsedSize - (where - m_Data));
memcpy(where.base(), &value, sizeof(T));
return true;
where = begin() + ofs;
// Move subsequent entries
for (T *ptr = m_Data + m_CurrentUsedSize - 2; ptr >= where.base(); --ptr)
*(ptr + 1) = *ptr;
*where.base() = value;
return where;
}
void erase(iterator where)
iterator erase(iterator where)
{
// validate iter
if (where < m_Data || where >= (m_Data + m_CurrentUsedSize))
return false;
return iterator(0);
size_t ofs = where - begin();
if (m_CurrentUsedSize > 1)
{
// move
memmove(where.base(), where.base() + 1, m_CurrentUsedSize - 1);
T *theend = m_Data + m_CurrentUsedSize;
for (T *ptr = where.base() + 1; ptr < theend; ++ptr)
*(ptr - 1) = *ptr;
}
--m_CurrentUsedSize;
// :TODO: free memory sometimes
FreeMemIfPossible();
return begin() + ofs;
}
void clear()
{
m_Size = 0;
m_CurrentUsedSize = 0;
if (m_Data)
{
delete [] m_Data;
m_Data = NULL;
}
}
};
#endif // __CVECTOR_H__

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
amxmodx/JIT/helpers-x86.o Normal file

Binary file not shown.

BIN
amxmodx/JIT/helpers-x86.obj Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -6,18 +6,22 @@ MM_ROOT = ../metamod/metamod
### EDIT BELOW FOR OTHER PROJECTS ###
OPT_FLAGS = -O3 -fno-rtti -funroll-loops -s -pipe
OPT_FLAGS = -O2 -funroll-loops -s -fomit-frame-pointer -pipe
DEBUG_FLAGS = -g -ggdb3
CPP = gcc
NAME = amxmodx_mm
NAME = amxmodx
BIN_SUFFIX_32 = mm_i386.so
BIN_SUFFIX_64 = mm_amd64.so
OBJECTS = meta_api.cpp CFile.cpp CVault.cpp vault.cpp float.cpp file.cpp modules.cpp \
CMisc.cpp CTask.cpp string.cpp amxmodx.cpp CEvent.cpp CCmd.cpp CLogEvent.cpp \
srvcmd.cpp strptime.cpp amxcore.cpp amxtime.cpp power.cpp amxxlog.cpp fakemeta.cpp \
amxxfile.cpp CLang.cpp md5.cpp emsg.cpp CForward.cpp CPlugin.cpp CModule.cpp \
CMenu.cpp util.cpp amx.cpp amxdbg.cpp natives.cpp newmenus.cpp \
CMenu.cpp util.cpp amx.cpp amxdbg.cpp natives.cpp newmenus.cpp debugger.cpp \
optimizer.cpp format.cpp messages.cpp libraries.cpp vector.cpp
LINK = -lz
LINK = /lib/libstdc++.a
INCLUDE = -I. -I$(HLSDK) -I$(HLSDK)/dlls -I$(HLSDK)/engine -I$(HLSDK)/game_shared -I$(HLSDK)/game_shared \
-I$(MM_ROOT) -Lzlib -I$(HLSDK)/common
@ -30,22 +34,27 @@ else
CFLAGS = $(OPT_FLAGS)
endif
ifeq "$(MMGR)" "true"
OBJECTS += MMGR/MMGR.CPP
ifeq "$(BINLOG)" "true"
NAME := $(NAME)_bl
BIN_DIR := $(BIN_DIR)BinLog
OBJECTS += binlog.cpp
CFLAGS += -DBINLOG_ENABLED
endif
CFLAGS += -DLINUX -DNDEBUG -fPIC -Wno-deprecated -fno-exceptions -DHAVE_STDINT_H
CFLAGS += -DLINUX -DNDEBUG -fPIC -Wno-deprecated -DHAVE_STDINT_H -static-libgcc -fno-rtti -fno-exceptions
ifeq "$(AMD64)" "true"
BINARY = $(NAME)_amd64.so
CFLAGS += -DPAWN_CELL_SIZE=64 -DHAVE_I64 -m64
BINARY = $(NAME)_$(BIN_SUFFIX_64)
CFLAGS += -DPAWN_CELL_SIZE=64 -DHAVE_I64 -DAMD64 -m64
LINK += -lz64
OBJECTS += JIT/natives-amd64.o
LINK += -lstdc++
else
BINARY = $(NAME)_i386.so
BINARY = $(NAME)_$(BIN_SUFFIX_32)
OBJECTS += JIT/amxexecn.o JIT/amxjitsn.o JIT/natives-x86.o
OBJECTS += JIT/helpers-x86.o
CFLAGS += -DPAWN_CELL_SIZE=32 -DJIT -DASM32
OPT_FLAGS += -march=i686
LINK += -lz
OPT_FLAGS += -march=i586
endif
OBJ_LINUX := $(OBJECTS:%.cpp=$(BIN_DIR)/%.o)
@ -61,23 +70,23 @@ amd64:
rm -f zlib/libz.a
$(MAKE) all AMD64=true
amd64_mmgr:
rm -f zlib/libz.a
$(MAKE) all AMD64=true MMGR=true
amd64_debug_mmgr:
rm -f zlib/libz.a
$(MAKE) all AMD64=true DEBUG=true MMGR=true
amd64_debug:
rm -f zlib/libz.a
$(MAKE) all AMD64=true DEBUG=true
mmgr:
$(MAKE) all MMGR=true
amd64_binlog:
rm -f zlib/libz.a
$(MAKE) all AMD64=true BINLOG=true
debug_mmgr:
$(MAKE) all MMGR=true DEBUG=true
amd64_binlog_debug:
rm -f zlib/libz.a
$(MAKE) all AMD64=true BINLOG=true DEBUG=true
binlog:
$(MAKE) all BINLOG=true
binlog_debug:
$(MAKE) all BINLOG=true DEBUG=true
amxmodx: $(OBJ_LINUX)
$(CPP) $(INCLUDE) $(CFLAGS) $(OBJ_LINUX) $(LINK) -shared -ldl -lm -o$(BIN_DIR)/$(BINARY)
@ -89,7 +98,14 @@ default: all
clean:
rm -rf Release/*.o
rm -rf Release/$(BINARY)
rm -rf Release/$(NAME)_$(BIN_SUFFIX_32)
rm -rf Release/$(NAME)_$(BIN_SUFFIX_64)
rm -rf ReleaseBinLog/*.o
rm -rf ReleaseBinLog/$(NAME)_bl_$(BIN_SUFFIX_32)
rm -rf ReleaseBinLog/$(NAME)_bl_$(BIN_SUFFIX_64)
rm -rf Debug/*.o
rm -rf Debug/$(BINARY)
rm -rf Debug/$(NAME)_$(BIN_SUFFIX_32)
rm -rf Debug/$(NAME)_$(BIN_SUFFIX_64)
rm -rf DebugBinLog/*.o
rm -rf DebugBinLog/$(NAME)_bl_$(BIN_SUFFIX_32)
rm -rf DebugBinLog/$(NAME)_bl_$(BIN_SUFFIX_64)

View File

@ -10,7 +10,7 @@
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* 1. The origin of this software must not be misreprfesented; you must not
* claim that you wrote the original software. If you use this software in
* a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
@ -46,6 +46,7 @@
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "osdefs.h"
#if defined LINUX || defined __FreeBSD__ || defined __OpenBSD__
#include <sclinux.h>
@ -265,6 +266,13 @@ typedef enum {
OP_SYSREQ_D,
OP_SYMTAG, /* obsolete */
OP_BREAK,
OP_FLOAT_MUL,
OP_FLOAT_DIV,
OP_FLOAT_ADD,
OP_FLOAT_SUB,
OP_FLOAT_TO,
OP_FLOAT_ROUND,
OP_FLOAT_CMP,
/* ----- */
OP_NUM_OPCODES
} OPCODE;
@ -425,10 +433,7 @@ int AMXAPI amx_Callback(AMX *amx, cell index, cell *result, cell *params)
AMX_FUNCSTUB *func;
AMX_NATIVE f;
assert(amx!=NULL);
hdr=(AMX_HEADER *)amx->base;
assert(hdr!=NULL);
assert(hdr->magic==AMX_MAGIC);
assert(hdr->natives<=hdr->libraries);
#if defined AMX_NATIVETABLE
if (index<NULL) {
@ -444,34 +449,10 @@ int AMXAPI amx_Callback(AMX *amx, cell index, cell *result, cell *params)
#endif
assert(f!=NULL);
/* Now that we have found the function, patch the program so that any
* subsequent call will call the function directly (bypassing this
* callback).
* This trick cannot work in the JIT, because the program would need to
* be re-JIT-compiled after patching a P-code instruction.
/* As of AMX Mod X 1.56, we don't patch sysreq.c to sysreq.d anymore.
* Otherwise, we'd have no way of knowing the last native to be used.
*/
#if defined JIT && !defined NDEBUG
if ((amx->flags & AMX_FLAG_JITC)!=0)
assert(amx->sysreq_d==0);
#endif
if (amx->sysreq_d!=0) {
/* at the point of the call, the CIP pseudo-register points directly
* behind the SYSREQ instruction and its parameter.
*/
unsigned char *code=amx->base+(int)hdr->cod+(int)amx->cip-4;
assert(amx->cip >= 4 && amx->cip < (hdr->dat - hdr->cod));
assert(sizeof(f)<=sizeof(cell)); /* function pointer must fit in a cell */
#if defined __GNUC__ || defined ASM32
if (*(cell*)code==index) {
#else
if (*(cell*)code!=OP_SYSREQ_PRI) {
assert(*(cell*)(code-sizeof(cell))==OP_SYSREQ_C);
assert(*(cell*)code==index);
#endif
*(cell*)(code-sizeof(cell))=amx->sysreq_d;
*(cell*)code=(cell)f;
} /* if */
} /* if */
amx->usertags[UT_NATIVE] = (void *)index;
/* Note:
* params[0] == number of bytes for the additional parameters passed to the native function
@ -480,7 +461,25 @@ int AMXAPI amx_Callback(AMX *amx, cell index, cell *result, cell *params)
*/
amx->error=AMX_ERR_NONE;
#if defined BINLOG_ENABLED
binlogfuncs_t *logfuncs = (binlogfuncs_t *)amx->usertags[UT_BINLOGS];
if (logfuncs)
{
logfuncs->pfnLogNative(amx, index, (int)(params[0] / sizeof(cell)));
logfuncs->pfnLogParams(amx, params);
}
#endif //BINLOG_ENABLED
*result = f(amx,params);
#if defined BINLOG_ENABLED
if (logfuncs)
{
logfuncs->pfnLogReturn(amx, *result);
}
#endif
return amx->error;
}
#endif /* defined AMX_INIT */
@ -512,6 +511,7 @@ static int amx_BrowseRelocate(AMX *amx)
cell cip;
long codesize;
OPCODE op;
BROWSEHOOK hook = NULL;
#if defined __GNUC__ || defined ASM32 || defined JIT
cell *opcode_list;
#endif
@ -527,6 +527,7 @@ static int amx_BrowseRelocate(AMX *amx)
code=amx->base+(int)hdr->cod;
codesize=hdr->dat - hdr->cod;
amx->flags|=AMX_FLAG_BROWSE;
hook = (BROWSEHOOK)amx->usertags[UT_BROWSEHOOK];
/* sanity checks */
assert(OP_PUSH_PRI==36);
@ -547,6 +548,7 @@ static int amx_BrowseRelocate(AMX *amx)
*/
if ((amx->flags & AMX_FLAG_JITC)==0 && sizeof(AMX_NATIVE)<=sizeof(cell))
amx->sysreq_d=opcode_list[OP_SYSREQ_D];
amx->userdata[UD_OPCODELIST] = (void *)opcode_list;
#else
/* ANSI C
* to use direct system requests, a function pointer must fit in a cell;
@ -554,6 +556,7 @@ static int amx_BrowseRelocate(AMX *amx)
*/
if (sizeof(AMX_NATIVE)<=sizeof(cell))
amx->sysreq_d=OP_SYSREQ_D;
amx->userdata[UD_OPCODELIST] = (long)NULL;
#endif
/* start browsing code */
@ -630,11 +633,22 @@ static int amx_BrowseRelocate(AMX *amx)
case OP_FILL:
case OP_HALT:
case OP_BOUNDS:
case OP_SYSREQ_C:
case OP_PUSHADDR:
case OP_SYSREQ_D:
cip+=sizeof(cell);
break;
case OP_SYSREQ_C:
{
if (hook)
#if defined __GNUC__ || defined ASM32 || defined JIT
hook(amx, opcode_list, &cip);
#else
hook(amx, NULL, &cip);
#endif
else
cip+=sizeof(cell);
break;
}
case OP_LOAD_I: /* instructions without parameters */
case OP_STOR_I:
@ -695,6 +709,13 @@ static int amx_BrowseRelocate(AMX *amx)
case OP_SWAP_ALT:
case OP_NOP:
case OP_BREAK:
case OP_FLOAT_MUL:
case OP_FLOAT_DIV:
case OP_FLOAT_ADD:
case OP_FLOAT_SUB:
case OP_FLOAT_TO:
case OP_FLOAT_ROUND:
case OP_FLOAT_CMP:
break;
case OP_CALL: /* opcodes that need relocation */
@ -819,22 +840,10 @@ static void expand(unsigned char *code, long codesize, long memsize)
}
#endif /* defined AMX_INIT */
int AMXAPI amx_Init(AMX *amx,void *program)
int AMXAPI amx_Init(AMX *amx, void *program)
{
AMX_HEADER *hdr;
#if (defined _Windows || defined LINUX || defined __FreeBSD__ || defined __OpenBSD__) && !defined AMX_NODYNALOAD
char libname[sNAMEMAX+8]; /* +1 for '\0', +3 for 'amx' prefix, +4 for extension */
#if defined _Windows
typedef int (FAR WINAPI *AMX_ENTRY)(AMX _FAR *amx);
HINSTANCE hlib;
#elif defined LINUX || defined __FreeBSD__ || defined __OpenBSD__
typedef int (*AMX_ENTRY)(AMX *amx);
void *hlib;
#endif
int numlibraries,i;
AMX_FUNCSTUB *lib;
AMX_ENTRY libinit;
#endif
BROWSEHOOK hook = NULL;
if ((amx->flags & AMX_FLAG_RELOC)!=0)
return AMX_ERR_INIT; /* already initialized (may not do so twice) */
@ -844,22 +853,6 @@ int AMXAPI amx_Init(AMX *amx,void *program)
* multi-byte words
*/
assert(check_endian());
#if BYTE_ORDER==BIG_ENDIAN
amx_Align32((uint32_t*)&hdr->size);
amx_Align16(&hdr->magic);
amx_Align16((uint16_t*)&hdr->flags);
amx_Align16((uint16_t*)&hdr->defsize);
amx_Align32((uint32_t*)&hdr->cod);
amx_Align32((uint32_t*)&hdr->dat);
amx_Align32((uint32_t*)&hdr->hea);
amx_Align32((uint32_t*)&hdr->stp);
amx_Align32((uint32_t*)&hdr->cip);
amx_Align32((uint32_t*)&hdr->publics);
amx_Align32((uint32_t*)&hdr->natives);
amx_Align32((uint32_t*)&hdr->libraries);
amx_Align32((uint32_t*)&hdr->pubvars);
amx_Align32((uint32_t*)&hdr->tags);
#endif
if (hdr->magic!=AMX_MAGIC)
return AMX_ERR_FORMAT;
@ -880,13 +873,7 @@ int AMXAPI amx_Init(AMX *amx,void *program)
} /* if */
if (hdr->stp<=0)
return AMX_ERR_FORMAT;
#if BYTE_ORDER==BIG_ENDIAN
if ((hdr->flags & AMX_FLAG_COMPACT)==0) {
ucell *code=(ucell *)((unsigned char *)program+(int)hdr->cod);
while (code<(ucell *)((unsigned char *)program+(int)hdr->hea))
swapcell(code++);
} /* if */
#endif
assert((hdr->flags & AMX_FLAG_COMPACT)!=0 || hdr->hea == hdr->size);
if ((hdr->flags & AMX_FLAG_COMPACT)!=0) {
#if AMX_COMPACTMARGIN > 2
@ -913,111 +900,18 @@ int AMXAPI amx_Init(AMX *amx,void *program)
amx->callback=amx_Callback;
amx->data=NULL;
/* also align all addresses in the public function, public variable,
* public tag and native function tables --offsets into the name table
* (if present) must also be swapped.
*/
#if BYTE_ORDER==BIG_ENDIAN
{ /* local */
AMX_FUNCSTUB *fs;
int i,num;
fs=GETENTRY(hdr,natives,0);
num=NUMENTRIES(hdr,natives,libraries);
for (i=0; i<num; i++) {
amx_AlignCell(&fs->address); /* redundant, because it should be zero */
if (USENAMETABLE(hdr))
amx_AlignCell(&((AMX_FUNCSTUBNT*)fs)->nameofs);
fs=(AMX_FUNCSTUB*)((unsigned char *)fs+hdr->defsize);
} /* for */
fs=GETENTRY(hdr,publics,0);
assert(hdr->publics<=hdr->natives);
num=NUMENTRIES(hdr,publics,natives);
for (i=0; i<num; i++) {
amx_AlignCell(&fs->address);
if (USENAMETABLE(hdr))
amx_AlignCell(&((AMX_FUNCSTUBNT*)fs)->nameofs);
fs=(AMX_FUNCSTUB*)((unsigned char *)fs+hdr->defsize);
} /* for */
fs=GETENTRY(hdr,pubvars,0);
assert(hdr->pubvars<=hdr->tags);
num=NUMENTRIES(hdr,pubvars,tags);
for (i=0; i<num; i++) {
amx_AlignCell(&fs->address);
if (USENAMETABLE(hdr))
amx_AlignCell(&((AMX_FUNCSTUBNT*)fs)->nameofs);
fs=(AMX_FUNCSTUB*)((unsigned char *)fs+hdr->defsize);
} /* for */
fs=GETENTRY(hdr,tags,0);
if (hdr->file_version<7) {
assert(hdr->tags<=hdr->cod);
num=NUMENTRIES(hdr,tags,cod);
} else {
assert(hdr->tags<=hdr->nametable);
num=NUMENTRIES(hdr,tags,nametable);
} /* if */
for (i=0; i<num; i++) {
amx_AlignCell(&fs->address);
if (USENAMETABLE(hdr))
amx_AlignCell(&((AMX_FUNCSTUBNT*)fs)->nameofs);
fs=(AMX_FUNCSTUB*)((unsigned char *)fs+hdr->defsize);
} /* for */
} /* local */
#endif
/* relocate call and jump instructions */
hook = (BROWSEHOOK)amx->usertags[UT_BROWSEHOOK];
if (hook)
hook(amx, NULL, NULL);
amx_BrowseRelocate(amx);
/* load any extension modules that the AMX refers to */
#if (defined _Windows || defined LINUX || defined __FreeBSD__ || defined __OpenBSD__) && !defined AMX_NODYNALOAD
hdr=(AMX_HEADER *)amx->base;
numlibraries=NUMENTRIES(hdr,libraries,pubvars);
for (i=0; i<numlibraries; i++) {
lib=GETENTRY(hdr,libraries,i);
strcpy(libname,"amx");
strcat(libname,GETENTRYNAME(hdr,lib));
#if defined _Windows
strcat(libname,".dll");
#if defined __WIN32__
hlib=LoadLibraryA(libname);
#else
hlib=LoadLibrary(libname);
if (hlib<=HINSTANCE_ERROR)
hlib=NULL;
#endif
#elif defined LINUX || defined __FreeBSD__ || defined __OpenBSD__
strcat(libname,".so");
hlib=dlopen(libname,RTLD_NOW);
#endif
if (hlib!=NULL) {
/* a library that cannot be loaded or that does not have the required
* initialization function is simply ignored
*/
char funcname[sNAMEMAX+9]; /* +1 for '\0', +4 for 'amx_', +4 for 'Init' */
strcpy(funcname,"amx_");
strcat(funcname,GETENTRYNAME(hdr,lib));
strcat(funcname,"Init");
#if defined _Windows
libinit=(AMX_ENTRY)GetProcAddress(hlib,funcname);
#elif defined LINUX || defined __FreeBSD__ || defined __OpenBSD__
libinit=(AMX_ENTRY)dlsym(hlib,funcname);
#endif
if (libinit!=NULL)
libinit(amx);
} /* if */
lib->address=(ucell)hlib;
} /* for */
#endif
return AMX_ERR_NONE;
}
#if defined JIT
#define CODESIZE_JIT 8192 /* approximate size of the code for the JIT */
#define CODESIZE_JIT 65536 /* approximate size of the code for the JIT */
#if defined __WIN32__ /* this also applies to Win32 "console" applications */
@ -1081,7 +975,9 @@ int AMXAPI amx_InitJIT(AMX *amx, void *reloc_table, void *native_code)
/* JIT rulz! (TM) */
/* MP: added check for correct compilation */
if ((res = asm_runJIT(amx->base, reloc_table, native_code)) != 0) {
//Fixed bug (thanks T(+)rget)
if ((res = asm_runJIT(amx->base, reloc_table, native_code)) == 0)
{
/* update the required memory size (the previous value was a
* conservative estimate, now we know the exact size)
*/
@ -1280,27 +1176,22 @@ int AMXAPI amx_GetNative(AMX *amx, int index, char *funcname)
int AMXAPI amx_FindNative(AMX *amx, const char *name, int *index)
{
int first,last,mid,result;
int first,last,mid;
char pname[sNAMEMAX+1];
amx_NumNatives(amx, &last);
last--; /* last valid index is 1 less than the number of functions */
first=0;
/* binary search */
while (first<=last) {
mid=(first+last)/2;
/* normal search */
for (mid=0; mid<=last; mid++)
{
amx_GetNative(amx, mid, pname);
result=strcmp(pname,name);
if (result>0) {
last=mid-1;
} else if (result<0) {
first=mid+1;
} else {
*index=mid;
if (strcmp(pname, name)==0)
{
*index = mid;
return AMX_ERR_NONE;
} /* if */
} /* while */
/* not found, set to an invalid index, so amx_Exec() will fail */
} /* for */
*index=INT_MAX;
return AMX_ERR_NOTFOUND;
}
@ -1513,37 +1404,11 @@ int AMXAPI amx_FindTagId(AMX *amx, cell tag_id, char *tagname)
#if defined AMX_XXXUSERDATA
int AMXAPI amx_GetUserData(AMX *amx, long tag, void **ptr)
{
int index;
assert(amx!=NULL);
assert(tag!=0);
for (index=0; index<AMX_USERNUM && amx->usertags[index]!=tag; index++)
/* nothing */;
if (index>=AMX_USERNUM)
return AMX_ERR_USERDATA;
*ptr=amx->userdata[index];
return AMX_ERR_NONE;
}
int AMXAPI amx_SetUserData(AMX *amx, long tag, void *ptr)
{
int index;
assert(amx!=NULL);
assert(tag!=0);
/* try to find existing tag */
for (index=0; index<AMX_USERNUM && amx->usertags[index]!=tag; index++)
/* nothing */;
/* if not found, try to find empty tag */
if (index>=AMX_USERNUM)
for (index=0; index<AMX_USERNUM && amx->usertags[index]!=0; index++)
/* nothing */;
/* if still not found, quit with error */
if (index>=AMX_USERNUM)
return AMX_ERR_INDEX;
/* set the tag and the value */
amx->usertags[index]=tag;
amx->userdata[index]=ptr;
return AMX_ERR_NONE;
}
#endif /* AMX_XXXUSERDATA */
@ -1561,6 +1426,91 @@ static AMX_NATIVE findfunction(const char *name, const AMX_NATIVE_INFO *list, in
}
const char *no_function;
int AMXAPI amx_CheckNatives(AMX *amx, AMX_NATIVE_FILTER nf)
{
AMX_FUNCSTUB *func;
AMX_HEADER *hdr;
int i,numnatives,res=0;
hdr=(AMX_HEADER *)amx->base;
assert(hdr!=NULL);
assert(hdr->magic==AMX_MAGIC);
assert(hdr->natives<=hdr->libraries);
numnatives=NUMENTRIES(hdr,natives,libraries);
func=GETENTRY(hdr,natives,0);
for (i=0; i<numnatives; i++) {
if (func->address==0) {
/* this function is not yet located */
res=nf(amx,i);
if (!res)
{
no_function = GETENTRYNAME(hdr,func);
return 0;
}
} /* if */
func=(AMX_FUNCSTUB*)((unsigned char*)func+hdr->defsize);
} /* for */
return 1;
}
int AMXAPI amx_RegisterToAny(AMX *amx, AMX_NATIVE f)
{
AMX_FUNCSTUB *func;
AMX_HEADER *hdr;
int i,numnatives,err;
hdr=(AMX_HEADER *)amx->base;
assert(hdr!=NULL);
assert(hdr->magic==AMX_MAGIC);
assert(hdr->natives<=hdr->libraries);
numnatives=NUMENTRIES(hdr,natives,libraries);
err=AMX_ERR_NONE;
func=GETENTRY(hdr,natives,0);
for (i=0; i<numnatives; i++) {
if (func->address==0) {
/* this function is not yet located */
func->address=(ucell)f;
} /* if */
func=(AMX_FUNCSTUB*)((unsigned char*)func+hdr->defsize);
} /* for */
if (err==AMX_ERR_NONE)
amx->flags|=AMX_FLAG_NTVREG;
return err;
}
int AMXAPI amx_Reregister(AMX *amx, const AMX_NATIVE_INFO *list, int number)
{
AMX_FUNCSTUB *func;
AMX_HEADER *hdr;
int i,numnatives,count=0;
AMX_NATIVE funcptr;
hdr=(AMX_HEADER *)amx->base;
assert(hdr!=NULL);
assert(hdr->magic==AMX_MAGIC);
assert(hdr->natives<=hdr->libraries);
numnatives=NUMENTRIES(hdr,natives,libraries);
count=0;
func=GETENTRY(hdr,natives,0);
for (i=0; i<numnatives; i++) {
if (func->address!=0) {
/* this function is located */
funcptr=(list!=NULL) ? findfunction(GETENTRYNAME(hdr,func),list,number) : NULL;
if (funcptr!=NULL)
{
func->address=(ucell)funcptr;
count++;
}
} /* if */
func=(AMX_FUNCSTUB*)((unsigned char*)func+hdr->defsize);
} /* for */
return count;
}
int AMXAPI amx_Register(AMX *amx, const AMX_NATIVE_INFO *list, int number)
{
AMX_FUNCSTUB *func;
@ -1674,7 +1624,13 @@ int AMXAPI amx_PushString(AMX *amx, cell *amx_addr, cell **phys_addr, const char
#define SKIPPARAM(n) ( cip=(cell *)cip+(n) )
#define PUSH(v) ( stk-=sizeof(cell), *(cell *)(data+(int)stk)=v )
#define POP(v) ( v=*(cell *)(data+(int)stk), stk+=sizeof(cell) )
#define ABORT(amx,v) { (amx)->stk=reset_stk; (amx)->hea=reset_hea; return v; }
#define ABORT(amx,v) { (amx)->stk=reset_stk; \
(amx)->hea=reset_hea; \
(amx)->cip=(cell)cip; \
(amx)->pri=pri; \
(amx)->alt=alt; \
return v; \
}
#define CHKMARGIN() if (hea+STKMARGIN>stk) return AMX_ERR_STACKERR
#define CHKSTACK() if (stk>amx->stp) return AMX_ERR_STACKLOW
@ -1724,13 +1680,16 @@ static const void * const amx_opcodelist[] = {
&&op_file, &&op_line, &&op_symbol, &&op_srange,
&&op_jump_pri, &&op_switch, &&op_casetbl, &&op_swap_pri,
&&op_swap_alt, &&op_pushaddr, &&op_nop, &&op_sysreq_d,
&&op_symtag, &&op_break };
&&op_symtag, &&op_break, &&op_float_mul, &&op_float_div,
&&op_float_add, &&op_float_sub, &&op_float_to, &&op_float_round,
&&op_float_cmp};
AMX_HEADER *hdr;
AMX_FUNCSTUB *func;
unsigned char *code, *data;
cell pri,alt,stk,frm,hea;
cell reset_stk, reset_hea, *cip;
cell offs;
cell offs, offs2;
REAL fnum, fnum2;
ucell codesize;
int num,i;
@ -2469,6 +2428,8 @@ static const void * const amx_opcodelist[] = {
amx->hea=hea;
amx->frm=frm;
amx->stk=stk;
amx->pri=pri;
amx->alt=alt;
num=amx->callback(amx,pri,&pri,(cell *)(data+(int)stk));
if (num!=AMX_ERR_NONE) {
if (num==AMX_ERR_SLEEP) {
@ -2488,6 +2449,8 @@ static const void * const amx_opcodelist[] = {
amx->hea=hea;
amx->frm=frm;
amx->stk=stk;
amx->pri=pri;
amx->alt=alt;
num=amx->callback(amx,offs,&pri,(cell *)(data+(int)stk));
if (num!=AMX_ERR_NONE) {
if (num==AMX_ERR_SLEEP) {
@ -2507,6 +2470,8 @@ static const void * const amx_opcodelist[] = {
amx->hea=hea;
amx->frm=frm;
amx->stk=stk;
amx->pri=pri;
amx->alt=alt;
pri=((AMX_NATIVE)offs)(amx,(cell *)(data+(int)stk));
if (amx->error!=AMX_ERR_NONE) {
if (amx->error==AMX_ERR_SLEEP) {
@ -2570,12 +2535,67 @@ static const void * const amx_opcodelist[] = {
NEXT(cip);
op_nop:
NEXT(cip);
op_break:
op_float_mul:
offs = *(cell *)(data + (int)stk + sizeof(cell)*1);
offs2 = *(cell *)(data + (int)stk + sizeof(cell)*2);
fnum = amx_ctof(offs) * amx_ctof(offs2);
pri = amx_ftoc(fnum);
NEXT(cip);
op_float_add:
offs = *(cell *)(data + (int)stk + sizeof(cell)*1);
offs2 = *(cell *)(data + (int)stk + sizeof(cell)*2);
fnum = amx_ctof(offs) + amx_ctof(offs2);
pri = amx_ftoc(fnum);
NEXT(cip);
op_float_sub:
offs = *(cell *)(data + (int)stk + sizeof(cell)*1);
offs2 = *(cell *)(data + (int)stk + sizeof(cell)*2);
fnum = amx_ctof(offs) - amx_ctof(offs2);
pri = amx_ftoc(fnum);
NEXT(cip);
op_float_div:
offs = *(cell *)(data + (int)stk + sizeof(cell)*1);
offs2 = *(cell *)(data + (int)stk + sizeof(cell)*2);
fnum = amx_ctof(offs) / amx_ctof(offs2);
pri = amx_ftoc(fnum);
NEXT(cip);
op_float_to:
offs = *(cell *)(data + (int)stk + sizeof(cell)*1);
fnum = (REAL)offs;
pri = amx_ftoc(fnum);
NEXT(cip);
op_float_round:
offs = *(cell *)(data + (int)stk + sizeof(cell)*1);
offs2 = *(cell *)(data + (int)stk + sizeof(cell)*2);
fnum = amx_ctof(offs);
if (!offs2)
fnum = floor(fnum + 0.5);
else if (offs2 == 1)
fnum = floor(fnum);
else
fnum = ceil(fnum);
pri = (cell)fnum;
NEXT(cip);
op_float_cmp:
offs = *(cell *)(data + (int)stk + sizeof(cell)*1);
offs2 = *(cell *)(data + (int)stk + sizeof(cell)*2);
fnum = amx_ctof(offs);
fnum2 = amx_ctof(offs2);
if (fnum == fnum2)
pri = 0;
else if (fnum > fnum2)
pri = 1;
else
pri = -1;
NEXT(cip);
op_break:
if (amx->debug!=NULL) {
/* store status */
amx->frm=frm;
amx->stk=stk;
amx->hea=hea;
amx->pri=pri;
amx->alt=alt;
amx->cip=(cell)((unsigned char*)cip-code);
num=amx->debug(amx);
if (num!=AMX_ERR_NONE) {
@ -2652,7 +2672,8 @@ int AMXAPI amx_Exec(AMX *amx, cell *retval, int index)
cell parms[9]; /* registers and parameters for assembler AMX */
#else
OPCODE op;
cell offs;
cell offs, offs2;
REAL fnum, fnum2;
int num;
#endif
assert(amx!=NULL);
@ -3443,6 +3464,8 @@ int AMXAPI amx_Exec(AMX *amx, cell *retval, int index)
amx->hea=hea;
amx->frm=frm;
amx->stk=stk;
amx->pri=pri;
amx->alt=alt;
num=amx->callback(amx,pri,&pri,(cell *)(data+(int)stk));
if (num!=AMX_ERR_NONE) {
if (num==AMX_ERR_SLEEP) {
@ -3462,6 +3485,8 @@ int AMXAPI amx_Exec(AMX *amx, cell *retval, int index)
amx->hea=hea;
amx->frm=frm;
amx->stk=stk;
amx->pri=pri;
amx->alt=alt;
num=amx->callback(amx,offs,&pri,(cell *)(data+(int)stk));
if (num!=AMX_ERR_NONE) {
if (num==AMX_ERR_SLEEP) {
@ -3481,6 +3506,8 @@ int AMXAPI amx_Exec(AMX *amx, cell *retval, int index)
amx->hea=hea;
amx->frm=frm;
amx->stk=stk;
amx->pri=pri;
amx->alt=alt;
pri=((AMX_NATIVE)offs)(amx,(cell *)(data+(int)stk));
if (amx->error!=AMX_ERR_NONE) {
if (amx->error==AMX_ERR_SLEEP) {
@ -3537,6 +3564,59 @@ int AMXAPI amx_Exec(AMX *amx, cell *retval, int index)
break;
case OP_NOP:
break;
case OP_FLOAT_MUL:
offs = *(cell *)(data + (int)stk + sizeof(cell)*1);
offs2 = *(cell *)(data + (int)stk + sizeof(cell)*2);
fnum = amx_ctof(offs) * amx_ctof(offs2);
pri = amx_ftoc(fnum);
break;
case OP_FLOAT_ADD:
offs = *(cell *)(data + (int)stk + sizeof(cell)*1);
offs2 = *(cell *)(data + (int)stk + sizeof(cell)*2);
fnum = amx_ctof(offs) + amx_ctof(offs2);
pri = amx_ftoc(fnum);
break;
case OP_FLOAT_SUB:
offs = *(cell *)(data + (int)stk + sizeof(cell)*1);
offs2 = *(cell *)(data + (int)stk + sizeof(cell)*2);
fnum = amx_ctof(offs) - amx_ctof(offs2);
pri = amx_ftoc(fnum);
break;
case OP_FLOAT_DIV:
offs = *(cell *)(data + (int)stk + sizeof(cell)*1);
offs2 = *(cell *)(data + (int)stk + sizeof(cell)*2);
fnum = amx_ctof(offs) / amx_ctof(offs2);
pri = amx_ftoc(fnum);
break;
case OP_FLOAT_TO:
offs = *(cell *)(data + (int)stk + sizeof(cell)*1);
fnum = (float)offs;
pri = amx_ftoc(fnum);
break;
case OP_FLOAT_ROUND:
offs = *(cell *)(data + (int)stk + sizeof(cell)*1);
offs2 = *(cell *)(data + (int)stk + sizeof(cell)*2);
fnum = amx_ctof(offs);
if (!offs2)
fnum = (REAL)floor(fnum + 0.5);
else if (offs2 == 1)
fnum = floor(fnum);
else
fnum = ceil(fnum);
pri = (cell)fnum;
break;
case OP_FLOAT_CMP:
offs = *(cell *)(data + (int)stk + sizeof(cell)*1);
offs2 = *(cell *)(data + (int)stk + sizeof(cell)*2);
fnum = amx_ctof(offs);
fnum2 = amx_ctof(offs2);
if (fnum == fnum2)
pri = 0;
else if (fnum > fnum2)
pri = 1;
else
pri = -1;
break;
case OP_BREAK:
assert((amx->flags & AMX_FLAG_BROWSE)==0);
if (amx->debug!=NULL) {
@ -3544,6 +3624,8 @@ int AMXAPI amx_Exec(AMX *amx, cell *retval, int index)
amx->frm=frm;
amx->stk=stk;
amx->hea=hea;
amx->pri=pri;
amx->alt=alt;
amx->cip=(cell)((unsigned char*)cip-code);
num=amx->debug(amx);
if (num!=AMX_ERR_NONE) {

View File

@ -79,15 +79,6 @@
#endif
#endif
#if HAVE_ALLOCA_H
#include <alloca.h>
#endif
#if defined __WIN32__ || defined _WIN32 || defined WIN32 /* || defined __MSDOS__ */
#if !defined alloca
#define alloca(n) _alloca(n)
#endif
#endif
#if !defined arraysize
#define arraysize(array) (sizeof(array) / sizeof((array)[0]))
#endif
@ -166,6 +157,7 @@ typedef cell (AMX_NATIVE_CALL *AMX_NATIVE)(struct tagAMX *amx, cell *params);
typedef int (AMXAPI *AMX_CALLBACK)(struct tagAMX *amx, cell index,
cell *result, cell *params);
typedef int (AMXAPI *AMX_DEBUG)(struct tagAMX *amx);
typedef int (AMXAPI *AMX_NATIVE_FILTER)(struct tagAMX *amx, int index);
#if !defined _FAR
#define _FAR
#endif
@ -174,6 +166,14 @@ typedef int (AMXAPI *AMX_DEBUG)(struct tagAMX *amx);
#pragma warning(disable:4103) /* disable warning message 4103 that complains
* about pragma pack in a header file */
#pragma warning(disable:4100) /* "'%$S' : unreferenced formal parameter" */
#if _MSC_VER >= 1400
// MSVC8 - Replace POSIX stricmp with ISO C++ conformant one as it is deprecated
#define stricmp _stricmp
// Need this because of some stupid bug
#pragma warning (disable : 4996)
#endif
#endif
/* Some compilers do not support the #pragma align, which should be fine. Some
@ -239,9 +239,10 @@ typedef struct tagAMX {
cell stp PACKED; /* top of the stack: relative to base + amxhdr->dat */
int flags PACKED; /* current status, see amx_Flags() */
/* user data */
long usertags[AMX_USERNUM] PACKED;
void _FAR *usertags[AMX_USERNUM] PACKED;
//okay userdata[3] in AMX Mod X is for the CPlugin * pointer
//we're also gonna set userdata[2] to a special debug structure
//lastly, userdata[1] is for opcode_list from amx_BrowseRelocate
void _FAR *userdata[AMX_USERNUM] PACKED;
/* native functions can raise an error */
int error PACKED;
@ -300,6 +301,7 @@ enum {
AMX_ERR_DIVIDE, /* divide by zero */
AMX_ERR_SLEEP, /* go into sleepmode - code can be restarted */
AMX_ERR_INVSTATE, /* invalid state for this access */
AMX_ERR_INVNATIVE, /* invalid native was used */
AMX_ERR_MEMORY = 16, /* out of memory */
AMX_ERR_FORMAT, /* invalid file format */
@ -335,23 +337,16 @@ enum {
#define AMX_COMPACTMARGIN 64
#endif
struct amx_trace
{
cell frm;
amx_trace *prev;
amx_trace *next;
bool used;
};
#define UD_FINDPLUGIN 3
#define UD_DEBUGGER 2
#define UD_OPCODELIST 1
#define UD_HANDLER 0
#define UT_NATIVE 3
#define UT_OPTIMIZER 2
#define UT_BROWSEHOOK 1
#define UT_BINLOGS 0
struct AMX_DBGINFO
{
void *pDebug; //Pointer to debug data
int error; //non-amx_Exec() error setting
amx_trace *pTrace; //Pointer to stack trace
amx_trace *pTraceFrm;
amx_trace *pTraceEnd;
cell frm;
};
typedef void (*BROWSEHOOK)(AMX *amx, cell *oplist, cell *cip);
/* for native functions that use floating point parameters, the following
* two macros are convenient for casting a "cell" into a "float" type _without_
@ -385,6 +380,7 @@ uint32_t * AMXAPI amx_Align32(uint32_t *v);
#endif
int AMXAPI amx_Allot(AMX *amx, int cells, cell *amx_addr, cell **phys_addr);
int AMXAPI amx_Callback(AMX *amx, cell index, cell *result, cell *params);
int AMXAPI amx_CheckNatives(AMX *amx, AMX_NATIVE_FILTER nf);
int AMXAPI amx_Cleanup(AMX *amx);
int AMXAPI amx_Clone(AMX *amxClone, AMX *amxSource, void *data);
int AMXAPI amx_Exec(AMX *amx, cell *retval, int index);
@ -414,6 +410,8 @@ int AMXAPI amx_PushArray(AMX *amx, cell *amx_addr, cell **phys_addr, const cell
int AMXAPI amx_PushString(AMX *amx, cell *amx_addr, cell **phys_addr, const char *string, int pack, int use_wchar);
int AMXAPI amx_RaiseError(AMX *amx, int error);
int AMXAPI amx_Register(AMX *amx, const AMX_NATIVE_INFO *nativelist, int number);
int AMXAPI amx_Reregister(AMX *amx, const AMX_NATIVE_INFO *nativelist, int number);
int AMXAPI amx_RegisterToAny(AMX *amx, AMX_NATIVE f);
int AMXAPI amx_Release(AMX *amx, cell amx_addr);
int AMXAPI amx_SetCallback(AMX *amx, AMX_CALLBACK callback);
int AMXAPI amx_SetDebugHook(AMX *amx, AMX_DEBUG debug);
@ -452,6 +450,15 @@ int AMXAPI amx_GetStringOld(char *dest,const cell *source,int use_wchar);
#endif
#endif
#if defined BINLOG_ENABLED
typedef struct tagBINLOG
{
void (*pfnLogNative)(AMX *amx, int native, int params);
void (*pfnLogReturn)(AMX *amx, cell retval);
void (*pfnLogParams)(AMX *amx, cell *params);
} binlogfuncs_t;
#endif
#ifdef __cplusplus
}
#endif

View File

@ -56,6 +56,8 @@
;
;History (list of changes)
;-------------------------
; 10 february 2006 by David Anderson
; Addition of float opcodes
; 17 february 2005 by Thiadmer Riemersms
; Addition of the BREAK opcode, removal of the older debugging opcode table.
; 6 march 2004 by Thiadmer Riemersma
@ -129,6 +131,28 @@
jg near err_stack
%endmacro
;Normal abort, saves pri/alt
%macro _ABORT 1
mov ebp,amx
mov [ebp+_pri], dword eax ; store values in AMX structure (PRI, ALT)
mov [ebp+_alt], dword edx ; store values in AMX structure (PRI, ALT)
mov [ebp+_error], dword %1
jmp _return
%endmacro
;Checked abort, saves nothing and uses a conditional
%macro _CHKABORT 1
mov ebp,amx
mov [ebp+_error], %1
cmp %1, AMX_ERR_NONE
jne _return
%endmacro
;Fast abort, only aborts, nothing else
%macro _FASTABORT 0
jmp _return
%endmacro
%macro _CHKHEAP 0
mov ebp,amx
mov ebp,[ebp+_hlw]
@ -1196,8 +1220,7 @@ OP_HALT:
mov eax,esi ; EAX=CIP
sub eax,code
mov [ebp+_cip],eax
mov eax,ebx ; return the parameter of the HALT opcode
jmp _return
_ABORT ebx
OP_BOUNDS:
@ -1221,6 +1244,7 @@ OP_SYSREQ_PRI:
mov alt,edx ; save ALT
mov [ebp+_stk],ecx ; store values in AMX structure (STK, HEA, FRM)
;we don't save regs since they're useless after this
mov ecx,hea
mov ebx,frm
mov [ebp+_hea],ecx
@ -1251,8 +1275,7 @@ OP_SYSREQ_PRI:
pop edi ; restore saved registers
pop esi
pop ebp
cmp eax,AMX_ERR_NONE
jne near _return ; return error code, if any
_CHKABORT eax ; if result was invalid, leave
mov eax,pri ; get retval into eax (PRI)
mov edx,alt ; restore ALT
@ -1293,8 +1316,8 @@ OP_SYSREQ_D: ; (TR)
pop edi ; restore saved registers
pop esi
pop ebp
cmp DWORD [ebp+_error],AMX_ERR_NONE
jne near _return ; return error code, if any
mov eax,[ebp+_error]
_CHKABORT eax
; function result is in eax (PRI)
mov edx,alt ; restore ALT
@ -1385,6 +1408,108 @@ OP_NOP:
add esi,4
GO_ON
OP_FLOAT_MUL:
add esi,4
fld dword [edi+ecx+4]
fmul dword [edi+ecx+8]
sub esp,4
fstp dword [esp]
pop eax
GO_ON
OP_FLOAT_DIV:
add esi,4
fld dword [edi+ecx+4]
fdiv dword [edi+ecx+8]
sub esp,4
fstp dword [esp]
pop eax
GO_ON
OP_FLOAT_ADD:
add esi,4
fld dword [edi+ecx+4]
fadd dword [edi+ecx+8]
sub esp,4
fstp dword [esp]
pop eax
GO_ON
OP_FLOAT_SUB:
add esi,4
fld dword [edi+ecx+4]
fsub dword [edi+ecx+8]
sub esp, 4
fstp dword [esp]
pop eax
GO_ON
OP_FLOAT_TO:
add esi,4
fild dword [edi+ecx+4]
sub esp,4
fstp dword [esp]
pop eax
GO_ON
OP_FLOAT_ROUND:
add esi,4
;get the float control word
push 0
mov ebp,esp
fstcw [ebp]
mov eax,[ebp]
push eax
;clear the top bits
xor ah,ah
;get the control method
push edx
mov edx,[edi+ecx+8]
and edx,3 ;sanity check
shl edx,2 ;shift it to right position
;set the bits
or ah,dl ;set bits 15,14 of FCW to rounding method
or ah,3 ;set precision to 64bit
mov [ebp], eax
fldcw [ebp]
;calculate
sub esp,4
fld dword [edi+ecx+4]
test edx,edx
jz .correct
jmp .skip_correct
.correct:
fadd st0
fadd dword [g_round_nearest]
fistp dword [esp]
pop eax
sar eax,1
jmp .done
.skip_correct:
frndint
fistp dword [esp]
pop eax
.done:
pop edx
;restore bits
pop ebp
mov [esp], ebp
fldcw [esp]
pop ebp
GO_ON
OP_FLOAT_CMP:
add esi, 4
fld dword [edi+ecx+8]
fld dword [edi+ecx+4]
fucompp
fnstsw ax
fwait
sahf
cmovz eax, [g_flags+4]
cmova eax, [g_flags+8]
cmovb eax, [g_flags+0]
GO_ON
OP_BREAK:
mov ebp,amx ; get amx into ebp
@ -1416,7 +1541,7 @@ OP_BREAK:
mov [ebp+_error],eax ; save EAX (error code) before restoring all regs
_RESTOREREGS ; abort run, but restore stack first
mov eax,[ebp+_error] ; get error code in EAX back again
jmp _return ; return error code
_FASTABORT
break_noabort:
_RESTOREREGS
mov eax,[ebp+_pri] ; restore PRI and ALT
@ -1425,43 +1550,34 @@ OP_BREAK:
OP_INVALID:
mov eax,AMX_ERR_INVINSTR
jmp _return
_ABORT AMX_ERR_INVINSTR
err_call:
mov eax,AMX_ERR_CALLBACK
jmp _return
_ABORT AMX_ERR_CALLBACK
err_stack:
mov eax,AMX_ERR_STACKERR
jmp _return
_ABORT AMX_ERR_STACKERR
err_stacklow:
mov eax,AMX_ERR_STACKLOW
jmp _return
_ABORT AMX_ERR_STACKLOW
err_memaccess:
mov eax,AMX_ERR_MEMACCESS
jmp _return
_ABORT AMX_ERR_MEMACCESS
err_bounds:
mov eax,AMX_ERR_BOUNDS
jmp _return
_ABORT AMX_ERR_BOUNDS
err_heaplow:
mov eax,AMX_ERR_HEAPLOW
jmp _return
_ABORT AMX_ERR_HEAPLOW
err_divide:
mov eax,AMX_ERR_DIVIDE
jmp _return
_ABORT AMX_ERR_DIVIDE
_return:
; save a few parameters, mostly for the "sleep"function
mov ebp,amx ; get amx into ebp
mov [ebp+_pri],eax ; store values in AMX structure (PRI, ALT)
mov [ebp+_alt],edx ; store values in AMX structure (PRI, ALT)
mov [ebp+_cip],esi ; get corrected cip for amxmodx
mov eax,[ebp+_error]; get error code
pop esi ; remove FRM from stack
@ -1489,6 +1605,14 @@ Start_DATA
lodb_and DD 0ffh, 0ffffh, 0, 0ffffffffh
g_round_nearest DD 0.5
GLOBAL g_flags
g_flags:
DD -1
DD 0
DD 1
GLOBAL amx_opcodelist
GLOBAL _amx_opcodelist
amx_opcodelist:
@ -1630,4 +1754,10 @@ _amx_opcodelist DD OP_INVALID
DD OP_SYSREQ_D
DD OP_SYMTAG
DD OP_BREAK
DD OP_FLOAT_MUL
DD OP_FLOAT_DIV
DD OP_FLOAT_ADD
DD OP_FLOAT_SUB
DD OP_FLOAT_TO
DD OP_FLOAT_ROUND
DD OP_FLOAT_CMP

View File

@ -21,17 +21,26 @@
; step.
; NOTE 3:
; During execution of the compiled code with amx_exec_jit() the x86 processor's
; stack is switched into the data section of the abstract machine. This means
; that there should always be enough memory left between HEA and STK to provide
; stack space for occurring interrupts! (see the STACKRESERVE variable)
; NOTE 4:
; Although the Pawn compiler doesn't generate the LCTRL, SCTRL and CALL.I
; instructions, I have to tell that they don't work as expected in a JIT
; compiled program, because there is no easy way of transforming AMX code
; addresses and JIT translated ones. This might be fixed in a future version.
; NOTE 4:
; Stack Pointer issues (by David Anderson)
; The JIT was changed recently so it no longer uses ESP as a general purpose
; register (GRP), because it can conflict with threading/signal systems which
; rely on the stack pointer being in-tact to find thread-ids. My fix for this
; was to keep esp safe, but save the stack pointer in 'ecx'. As such, ecx is no
; longer the CIP or scratch register, it is the save point for pieces of the AMX
; structure on the x86 stack.
; This means that the optimization of the JIT has changed, as every amx stack
; push call now takes two operations instead of one (same for pop), and pushing
; addresses is 4 instructions instead of 1.
; As of this moment I don't see a better way around it, but the sacrifice for
; having pthread-safe code was deemed to be necessary.
; NOTE 5:
; NX ("No eXecute") and XD (eXecution Denied) bits
; (by Thiadmer Riemersma)
;
@ -65,7 +74,8 @@
; segment: the JIT-compiler patches P-code parameters into its own code segment
; during compilation. This is handled in the support code for amx_InitJIT.
;
;
; NOTE 6:
; CALLING CONVENTIONS
; (by Thiadmer Riemersma)
;
@ -77,9 +87,16 @@
; a reserved word on the assembler, I had to choose a different name for the
; macro, hence STDECL.)
; Revision History
; ----------------
; 26 july 2005 by David "BAILOPAN" Anderson
; 16 august 2005 by David "BAILOPAN" Anderson (DA)
; Changed JIT to not swap stack pointer during execution. This
; is playing with fire, especially with pthreads and signals on linux,
; where the stack pointer is used to find the current thread id. If
; the stack pointer is altered during a thread/signal switch/interrupt
; unexpected behaviour can occur (crashes).
; 26 july 2005 by David "BAILOPAN" Anderson (DA)
; Fixed a bug where zero casetbl entries would crash the JIT.
; 17 february 2005 by Thiadmer Riemersms
; Addition of the BREAK opcode, removal of the older debugging opcode
@ -165,15 +182,6 @@
;
%define FORCERELOCATABLE
;
; Determines how much memory should be reserved for occurring interrupts.
; (If my memory serves me right, DOS4/G(W) provides a stack of 512 bytes
; for interrupts that occur in real mode and are promoted to protected mode.)
; This value _MUST_ be greater than 64 (for AMX needs) and should be at least
; 128 (to serve interrupts).
;
%define STACKRESERVE 256
;
; This variable controls the generation of memory range checks at run-time.
; You should set this to 0, only when you are sure that there are no range
@ -186,32 +194,49 @@
%define JIT 1
%include "amxdefn.asm"
; GWMV:
; Nasm can't do the next as equivalence statements, since the value of
; esi is not determined at compile time
%define stk [esi+32] ; define some aliases to registers that will
%define alt [esi+28] ; be stored on the stack when the code is
%define pri [esi+24] ; actually beeing executed
%define code [esi+20]
%define amx [esi+16]
%define retval [esi+12]
%define stp [esi+8]
%define hea [esi+4]
%define frm [esi] ; FRM is NOT stored in ebp, FRM+DAT is being held
;Registers used for JIT during execution:
; eax - pri
; ebx - reloc frame
; ecx - info params
; edx - alt
; esi - AMX stack
; edi - DAT
; ebp - scratch
;DA:
; These are still stored in the stack, but the stack pointer
; holding them is now kept in ecx.
%define stk [ecx+32] ; define some aliases to registers that will
%define alt [ecx+28] ; be stored on the stack when the code is
%define pri [ecx+24] ; actually beeing executed
%define code [ecx+20]
%define amx [ecx+16]
%define retval [ecx+12]
%define stp [ecx+8]
%define hea [ecx+4]
%define frm [ecx] ; FRM is NOT stored in ebp, FRM+DAT is being held
; in ebx instead.
;
; #define PUSH(v) ( stk-=sizeof(cell), *(cell *)(data+(int)stk)=v )
;
%macro _PUSH 1
push dword %1
lea esi,[esi-4]
mov dword [esi], %1
%endmacro
%macro _PUSHMEM 1
lea esi,[esi-4]
mov ebp, dword %1
mov dword [esi], ebp
%endmacro
;
; #define POP(v) ( v=*(cell *)(data+(int)stk), stk+=sizeof(cell) )
;
%macro _POP 1
pop dword %1
mov %1, dword [esi]
lea esi,[esi+4]
%endmacro
@ -279,7 +304,11 @@
%endmacro
%ifdef WIN32
section .data exec
%else
section .text
%endif
global asm_runJIT, _asm_runJIT
@ -412,7 +441,9 @@ reloc_done:
; in the compiled code. This is fine, but the .text section in an ELF executable
; is usually marked read-only, that's why this code is in the .data section.
%ifndef WIN32
section .data exec
%endif
OP_LOAD_PRI:
;nop;
@ -790,7 +821,7 @@ OP_LCTRL:
jne lctrl_5
GO_ON j_lctrl_4, lctrl_5, 8
j_lctrl_4:
mov eax,esp ; 4=STK
mov eax,esi ; 4=STK
sub eax,edi
CHECKCODESIZE j_lctrl_4
lctrl_5:
@ -824,7 +855,7 @@ OP_SCTRL:
j_sctrl_4:
;mov esp,eax ; 4=STK
;add esp,edi ; relocate stack
lea esp,[eax+edi]
lea esi,[eax+edi]
CHECKCODESIZE j_sctrl_4
sctrl_5:
cmp eax,5
@ -885,14 +916,16 @@ OP_PUSH_ALT:
OP_PUSH_R_PRI:
;nop;
putval j_push_r_pri+1
putval j_push_r_pri+2
GO_ON j_push_r_pri, OP_PUSH_C, 8
j_push_r_pri:
push ecx
mov ecx,12345678h
j_push_loop:
_PUSH eax
loop j_push_loop
pop ecx
;dec ecx
;jnz j_push_loop
CHECKCODESIZE j_push_r_pri
@ -900,30 +933,33 @@ OP_PUSH_R_PRI:
;good
OP_PUSH_C:
;nop;
putval j_push_c+1
putval j_push_c_end-4
GO_ON j_push_c, OP_PUSH, 8
j_push_c:
_PUSH 12345678h
j_push_c_end:
CHECKCODESIZE j_push_c
OP_PUSH:
;nop;
putval j_push+2
putval j_push_end-6
GO_ON j_push, OP_PUSH_S, 8
j_push:
_PUSH [edi+12345678h]
_PUSHMEM [edi+12345678h]
j_push_end:
CHECKCODESIZE j_push
;good
OP_PUSH_S:
;nop;
putval j_push_s+2
putval j_push_s_end-6
GO_ON j_push_s, OP_POP_PRI, 8
j_push_s:
_PUSH [ebx+12345678h]
_PUSHMEM [ebx+12345678h]
j_push_s_end:
CHECKCODESIZE j_push_s
OP_POP_PRI:
@ -950,8 +986,8 @@ OP_STACK:
GO_ON j_stack, OP_HEAP, 8
j_stack:
mov edx,esp
add esp,12345678h
mov edx,esi
add esi,12345678h
sub edx,edi
%ifdef DORUNTIMECHECKS
call [chk_marginstack]
@ -979,9 +1015,9 @@ OP_PROC:
GO_ON j_proc, OP_RET
j_proc: ;[STK] = FRM, STK = STK - cell size, FRM = STK
_PUSH frm ; push old frame (for RET/RETN)
mov frm,esp ; get new frame
mov ebx,esp ; already relocated
_PUSHMEM frm ; push old frame (for RET/RETN)
mov frm,esi ; get new frame
mov ebx,esi ; already relocated
sub frm,edi ; relocate frame
CHECKCODESIZE j_proc
@ -991,6 +1027,7 @@ OP_RET:
j_ret:
_POP ebx ; pop frame
lea esi,[esi+4]
mov frm,ebx
add ebx,edi
ret
@ -1009,11 +1046,13 @@ OP_RETN:
;good
OP_CALL:
;nop;
RELOC 1
RELOC j_call_e8-j_call+1
GO_ON j_call, OP_CALL_I, 8
j_call:
;call 12345678h ; tasm chokes on this out of a sudden
_PUSH 0
j_call_e8
db 0e8h, 0, 0, 0, 0
CHECKCODESIZE j_call
@ -1022,6 +1061,7 @@ OP_CALL_I:
GO_ON j_call_i, OP_JUMP
j_call_i:
_PUSH 0
call eax
CHECKCODESIZE j_call_i
@ -1172,24 +1212,30 @@ OP_SHL:
;nop;
GO_ON j_shl, OP_SHR
j_shl:
mov ecx,edx ; TODO: save ECX if used as special register
push ecx
mov ecx,edx
shl eax,cl
pop ecx
CHECKCODESIZE j_shl
OP_SHR:
;nop;
GO_ON j_shr, OP_SSHR
j_shr:
mov ecx,edx ; TODO: save ECX if used as special register
push ecx
mov ecx,edx
shr eax,cl
pop ecx
CHECKCODESIZE j_shr
OP_SSHR:
;nop;
GO_ON j_sshr, OP_SHL_C_PRI
j_sshr:
mov ecx,edx ; TODO: save ECX if used as special register
push ecx
mov ecx,edx
sar eax,cl
pop ecx
CHECKCODESIZE j_sshr
OP_SHL_C_PRI:
@ -1608,29 +1654,35 @@ OP_DEC_I:
OP_MOVS:
;nop;
putval j_movs+1
putval j_movs+2
GO_ON j_movs, OP_CMPS, 8
j_movs:
mov ecx,12345678h ;TODO: save ECX if used as special register
push ecx
mov ecx,12345678h
call [jit_movs]
pop ecx
CHECKCODESIZE j_movs
OP_CMPS:
;nop;
putval j_cmps+1
putval j_cmps+2
GO_ON j_cmps, OP_FILL, 8
j_cmps:
mov ecx,12345678h ;TODO: save ECX if used as special register
push ecx
mov ecx,12345678h
call [jit_cmps]
pop ecx
CHECKCODESIZE j_cmps
OP_FILL:
;nop;
putval j_fill+1
putval j_fill+2
GO_ON j_fill, OP_HALT, 8
j_fill:
push ecx
mov ecx,12345678h ;TODO: save ECX if used as special register
call [jit_fill]
pop ecx
CHECKCODESIZE j_fill
;good
@ -1830,7 +1882,7 @@ OP_BREAK:
jae code_gen_done
jmp DWORD [ebx] ; go on with the next opcode
%else
GO_ON j_break, OP_INVALID
GO_ON j_break, OP_FLOAT_MUL
j_break:
mov ebp,amx
cmp DWORD [ebp+_debug], 0
@ -1839,6 +1891,116 @@ OP_BREAK:
CHECKCODESIZE j_break
%endif
OP_FLOAT_MUL:
GO_ON j_float_mul, OP_FLOAT_DIV
j_float_mul:
fld dword [esi+4]
fmul dword [esi+8]
sub esp, 4
fstp dword [esp]
pop eax
CHECKCODESIZE j_float_mul
OP_FLOAT_DIV:
GO_ON j_float_div, OP_FLOAT_ADD
j_float_div:
fld dword [esi+4]
fdiv dword [esi+8]
sub esp, 4
fstp dword [esp]
pop eax
CHECKCODESIZE j_float_div
OP_FLOAT_ADD:
GO_ON j_float_add, OP_FLOAT_SUB
j_float_add:
fld dword [esi+4]
fadd dword [esi+8]
sub esp, 4
fstp dword [esp]
pop eax
CHECKCODESIZE j_float_add
OP_FLOAT_SUB:
GO_ON j_float_sub, OP_FLOAT_TO
j_float_sub:
fld dword [esi+4]
fsub dword [esi+8]
sub esp, 4
fstp dword [esp]
pop eax
CHECKCODESIZE j_float_sub
OP_FLOAT_TO:
GO_ON j_float_to, OP_FLOAT_ROUND
j_float_to:
fild dword [esi+4]
sub esp, 4
fstp dword [esp]
pop eax
CHECKCODESIZE j_float_to
OP_FLOAT_ROUND:
GO_ON j_float_round, OP_FLOAT_CMP
j_float_round:
;get the float control word
push 0
mov ebp,esp
fstcw [ebp]
mov eax,[ebp]
push eax
;clear the top bits
xor ah,ah
;get the control method
push edx
mov edx,[esi+8]
and edx,3 ;sanity check
shl edx,2 ;shift it to right position
;set the bits
or ah,dl ;set bits 15,14 of FCW to rounding method
or ah,3 ;set precision to 64bit
mov [ebp], eax
fldcw [ebp]
;calculate
sub esp,4
fld dword [esi+4]
test edx,edx
jz .correct
jmp .skip_correct
.correct:
fadd st0
fadd dword [g_round_nearest]
fistp dword [esp]
pop eax
sar eax,1
jmp .done
.skip_correct:
frndint
fistp dword [esp]
pop eax
.done:
pop edx
;restore bits
pop ebp
mov [esp], ebp
fldcw [esp]
pop ebp
CHECKCODESIZE j_float_round
OP_FLOAT_CMP:
GO_ON j_float_cmp, OP_INVALID
j_float_cmp:
fld dword [esi+8]
fld dword [esi+4]
fucompp
fnstsw ax
fwait
sahf
cmovz eax, [g_flagsjit+4]
cmova eax, [g_flagsjit+8]
cmovb eax, [g_flagsjit+0]
CHECKCODESIZE j_float_cmp
OP_INVALID: ; break from the compiler with an error code
mov eax,AMX_ERR_INVINSTR
pop esi
@ -1879,7 +2041,7 @@ _amx_exec_jit:
push dword [eax+20]; store FRM
mov edx,[eax+4] ; get ALT
mov ecx,[eax+8] ; get CIP
mov ebp,[eax+8] ; get CIP
mov edi,[eax+12] ; get pointer to data segment
mov esi,[eax+16] ; get STK !!changed, now ECX free as counter!!
mov ebx,[eax+20] ; get FRM
@ -1887,13 +2049,14 @@ _amx_exec_jit:
add ebx,edi ; relocate frame
add esi,edi ; ESP will contain DAT+STK
xchg esp,esi ; switch to AMX stack
add stp,edi ; make STP absolute address for run-time checks
add [esp+8],edi ; make STP absolute address for run-time checks
_POP ebp ; AMX pseudo-return address, ignored
mov dword [esi], 0 ; zero this out, but we need to keep it so
; the stack frame is in tact
mov ecx,esp ; copy stack pointer
; Call compiled code via CALL NEAR <address>
call ecx
call ebp
return_to_caller:
cmp dword retval,0
@ -1906,15 +2069,17 @@ return_to_caller:
jmp _return
_return_popstack:
add esp,4 ; Correct ESP, because we just come from a
; runtime error checking routine.
mov esp,ecx ; get our old stack pointer
_return:
; store machine state
mov ecx,esp ; get STK into ECX
push ecx
push ecx
mov ebp,amx ; get amx into EBP
mov ecx,esi ; get STK into ECX
sub ecx,edi ; correct STK
mov [ebp+_stk],ecx ; store values in AMX structure: STK, ...
pop ecx ; get orig value
mov ecx,hea ; ... HEA, ...
mov [ebp+_hea],ecx
mov ecx,ebx ; ... and FRM
@ -1924,8 +2089,8 @@ _return:
mov [ebp+_alt],edx ; ... and ALT
; return
pop ecx
sub stp,edi ; make STP relative to DAT again
xchg esp,esi ; switch back to caller's stack
add esp,4*9 ; remove temporary data
@ -1946,12 +2111,8 @@ err_stacklow:
jmp _return_popstack
_CHKMARGIN_STACK: ; some run-time check routines
cmp esp,stp
lea ebp,[esp-STACKRESERVE]
cmp esi,stp
jg err_stacklow
sub ebp,edi
cmp hea,ebp
jg err_stack
ret
err_heaplow:
@ -1959,7 +2120,7 @@ err_heaplow:
jmp _return_popstack
_CHKMARGIN_HEAP:
cmp esp,stp
cmp esi,stp
jg err_stacklow
cmp dword hea,0
jl err_heaplow
@ -1975,7 +2136,7 @@ _VERIFYADDRESS_eax: ; used in load.i, store.i & lidx
cmp eax,hea
jb veax1
lea ebp,[eax+edi]
cmp ebp,esp
cmp ebp,esi
jb err_memaccess
veax1:
ret
@ -1986,7 +2147,7 @@ _VERIFYADDRESS_edx: ; used in load.i, store.i & lidx
cmp edx,hea
jb vedx1
lea ebp,[edx+edi]
cmp ebp,esp
cmp ebp,esi
jb err_memaccess
vedx1:
ret
@ -2018,15 +2179,15 @@ JIT_OP_SDIV:
JIT_OP_RETN:
_POP ebx ; pop frame
_POP ecx ; get return address
add esi,4 ; get rid of the extra parameter from call
mov frm,ebx
_POP ebp
add ebx,edi
add esp,ebp ; remove data from stack
add esi,ebp ; remove data from stack
jmp ecx
ret
JIT_OP_MOVS: ;length of block to copy is already in ECX
@ -2092,34 +2253,33 @@ err_divide:
jmp _return_popstack
JIT_OP_SYSREQ:
mov ecx,esp ; get STK into ECX
push ecx
push esi
mov ebp,amx ; get amx into EBP
sub ecx,edi ; correct STK
sub esi,edi ; correct STK
mov alt,edx ; save ALT
mov [ebp+_stk],ecx ; store values in AMX structure: STK,
mov ecx,hea ; HEA,
mov [ebp+_stk],esi ; store values in AMX structure: STK,
mov esi,hea ; HEA,
mov ebx,frm ; and FRM
mov [ebp+_hea],ecx
mov [ebp+_hea],esi
mov [ebp+_frm],ebx
lea ebx,pri ; 3rd param: addr. of retval
lea ecx,[esp+4] ; 4th param: parameter array
xchg esp,esi ; switch to caller stack
push ecx
;Our original esi is still pushed!
push ebx
push eax ; 2nd param: function number
push ebp ; 1st param: amx
call [ebp+_callback]
_DROPARGS 16 ; remove args from stack
_DROPARGS 12 ; remove args from stack
xchg esp,esi ; switch back to AMX stack
pop esi
pop ecx
cmp eax,AMX_ERR_NONE
jne _return_popstack; return error code, if any
jne _return_popstack
.continue:
mov eax,pri ; get retval into eax (PRI)
mov edx,alt ; restore ALT
mov ebx,frm ; restore FRM
@ -2128,25 +2288,25 @@ JIT_OP_SYSREQ:
JIT_OP_SYSREQ_D: ; (TR)
mov ecx,esp ; get STK into ECX
push ecx
push esi
mov ebp,amx ; get amx into EBP
sub ecx,edi ; correct STK
sub esi,edi ; correct STK
mov alt,edx ; save ALT
mov [ebp+_stk],ecx ; store values in AMX structure: STK,
mov ecx,hea ; HEA,
mov [ebp+_stk],esi ; store values in AMX structure: STK,
mov esi,hea ; HEA,
mov eax,frm ; and FRM
mov [ebp+_hea],ecx
mov [ebp+_hea],esi
mov [ebp+_frm],eax ; eax & ecx are invalid by now
lea edx,[esp+4] ; 2nd param: parameter array
xchg esp,esi ; switch to caller stack
push edx
;esi is still pushed!
push ebp ; 1st param: amx
call ebx ; direct call
_DROPARGS 8 ; remove args from stack
xchg esp,esi ; switch back to AMX stack
pop ecx
mov ebp,amx ; get amx into EBP
cmp dword [ebp+_error],AMX_ERR_NONE
jne _return_popstack; return error code, if any
@ -2160,25 +2320,27 @@ JIT_OP_SYSREQ_D: ; (TR)
JIT_OP_BREAK:
%ifdef DEBUGSUPPORT
mov ecx,esp ; get STK into ECX
push ecx
push esi
mov ebp,amx ; get amx into EBP
sub ecx,edi ; correct STK
sub esi,edi ; correct STK
mov [ebp+_pri],eax ; store values in AMX structure: PRI,
mov [ebp+_alt],edx ; ALT,
mov [ebp+_stk],ecx ; STK,
mov ecx,hea ; HEA,
mov [ebp+_stk],esi ; STK,
mov esi,hea ; HEA,
mov ebx,frm ; and FRM
mov [ebp+_hea],ecx
mov [ebp+_hea],esi
mov [ebp+_frm],ebx ; EBX & ECX are invalid by now
;??? storing CIP is not very useful, because the code changed (during JIT compile)
xchg esp,esi ; switch to caller stack
push ebp ; 1st param: amx
call [ebp+_debug]
_DROPARGS 4 ; remove args from stack
xchg esp,esi ; switch back to AMX stack
pop esi
pop ecx
cmp eax,AMX_ERR_NONE
jne _return_popstack; return error code, if any
@ -2194,6 +2356,7 @@ JIT_OP_BREAK:
JIT_OP_SWITCH:
pop ebp ; pop return address = table address
push ecx
mov ecx,[ebp] ; ECX = number of records
lea ebp,[ebp+ecx*8+8] ; set pointer _after_ LAST case
;if there are zero cases we should just skip this -- bail
@ -2205,6 +2368,7 @@ JIT_OP_SWITCH:
sub ebp,8 ; position to preceding case
loop op_switch_loop ; check next case, or fall through
op_switch_jump:
pop ecx
%ifndef FORCERELOCATABLE
jmp [ebp-4] ; jump to the case instructions
%else
@ -2265,6 +2429,16 @@ jit_switch DD JIT_OP_SWITCH
; The table for the browser/relocator function.
;
global g_flagsjit
g_flagsjit:
DD -1
DD 0
DD 1
global g_round_nearest
g_round_nearest:
DD 0.5
global amx_opcodelist_jit, _amx_opcodelist_jit
amx_opcodelist_jit:
@ -2407,5 +2581,12 @@ _amx_opcodelist_jit:
DD OP_SYSREQ_D ; TR
DD OP_SYMTAG ; TR
DD OP_BREAK ; TR
DD OP_FLOAT_MUL ; DA
DD OP_FLOAT_DIV ; DA
DD OP_FLOAT_ADD ; DA
DD OP_FLOAT_SUB ; DA
DD OP_FLOAT_TO ; DA
DD OP_FLOAT_ROUND ; DA
DD OP_FLOAT_CMP ; DA
END

File diff suppressed because it is too large Load Diff

View File

@ -32,7 +32,6 @@
#ifndef AMXMODX_H
#define AMXMODX_H
#ifdef __linux__
#include <unistd.h>
#include <stdlib.h>
@ -42,10 +41,14 @@
#include "string.h"
#include <extdll.h>
#include <meta_api.h>
#include "mm_pextensions.h" // metamod-p extensions
#ifdef MEMORY_TEST
#include "mmgr/mmgr.h"
#ifdef _MSC_VER
// MSVC8 - replace POSIX functions with ISO C++ conformant ones as they are deprecated
#if _MSC_VER >= 1400
#define unlink _unlink
#define mkdir _mkdir
#define strdup _strdup
#endif
#endif
#include "md5.h"
@ -69,32 +72,46 @@
#include "amxxlog.h"
#define AMXXLOG_Log g_log.Log
#define AMX_VERSION "1.50"
#define AMXXLOG_Error g_log.LogError
#define AMX_VERSION "1.75"
extern AMX_NATIVE_INFO core_Natives[];
extern AMX_NATIVE_INFO time_Natives[];
extern AMX_NATIVE_INFO power_Natives[];
extern AMX_NATIVE_INFO amxmod_Natives[];
extern AMX_NATIVE_INFO amxmodx_Natives[];
extern AMX_NATIVE_INFO file_Natives[];
extern AMX_NATIVE_INFO float_Natives[];
extern AMX_NATIVE_INFO string_Natives[];
extern AMX_NATIVE_INFO vault_Natives[];
extern AMX_NATIVE_INFO msg_Natives[];
extern AMX_NATIVE_INFO vector_Natives[];
#ifndef __linux__
#define DLLOAD(path) (DLHANDLE)LoadLibrary(path)
#define DLPROC(m,func) GetProcAddress(m,func)
#define DLPROC(m, func) GetProcAddress(m, func)
#define DLFREE(m) FreeLibrary(m)
#else
#define DLLOAD(path) (DLHANDLE)dlopen(path, RTLD_NOW)
#define DLPROC(m,func) dlsym(m,func)
#define DLPROC(m, func) dlsym(m, func)
#define DLFREE(m) dlclose(m)
#endif
#ifndef __linux__
typedef HINSTANCE DLHANDLE;
#if defined __GNUC__
#include <stdint.h>
typedef intptr_t _INT_PTR;
#else
typedef void* DLHANDLE;
#if defined AMD64
typedef __int64 _INT_PTR;
#else
typedef __int32 _INT_PTR;
#endif
#endif
#ifndef __linux__
typedef HINSTANCE DLHANDLE;
#else
typedef void* DLHANDLE;
#define INFINITE 0xFFFFFFFF
#endif
#ifndef GETPLAYERAUTHID
@ -110,36 +127,37 @@ typedef void* DLHANDLE;
char* UTIL_SplitHudMessage(register const char *src);
int UTIL_ReadFlags(const char* c);
void UTIL_ClientPrint( edict_t *pEntity, int msg_dest, char *msg );
void UTIL_ClientPrint(edict_t *pEntity, int msg_dest, char *msg);
void UTIL_FakeClientCommand(edict_t *pEdict, const char *cmd, const char *arg1 = NULL, const char *arg2 = NULL);
void UTIL_GetFlags(char* flags,int flag);
void UTIL_GetFlags(char* flags, int flag);
void UTIL_HudMessage(edict_t *pEntity, const hudtextparms_t &textparms, char *pMessage);
void UTIL_IntToString(int value, char *output);
void UTIL_ShowMOTD( edict_t *client , char *motd, int mlen, const char *name);
void UTIL_ShowMenu( edict_t* pEntity, int slots, int time, char *menu, int mlen );
void UTIL_ShowMOTD(edict_t *client, char *motd, int mlen, const char *name);
void UTIL_ShowMenu(edict_t* pEntity, int slots, int time, char *menu, int mlen);
char *UTIL_VarArgs(const char *fmt, ...);
#define GET_PLAYER_POINTER(e) (&g_players[ENTINDEX(e)])
//#define GET_PLAYER_POINTER(e) (&g_players[(((int)e-g_edict_point)/sizeof(edict_t ))])
//#define GET_PLAYER_POINTER(e) (&g_players[(((int)e-g_edict_point)/sizeof(edict_t))])
#define GET_PLAYER_POINTER_I(i) (&g_players[i])
struct WeaponsVault {
struct WeaponsVault
{
String fullName;
short int iId;
short int ammoSlot;
};
struct fakecmd_t {
struct fakecmd_t
{
char args[256];
const char *argv[3];
//char argv[3][128];
int argc;
bool fake;
};
extern bool g_IsNewMM;
extern pextension_funcs_t *gpMetaPExtFuncs;
extern CLog g_log;
extern CPluginMngr g_plugins;
extern CTaskMngr g_tasksMngr;
@ -150,7 +168,8 @@ extern CList<CCVar> g_cvars;
extern CList<ForceObject> g_forcemodels;
extern CList<ForceObject> g_forcesounds;
extern CList<ForceObject> g_forcegeneric;
extern CList<CModule,const char *> g_modules;
extern CList<CModule, const char *> g_modules;
extern CList<CScript, AMX*> g_loadedscripts;
extern CList<CPlayer*> g_auth;
extern EventsMngr g_events;
extern Grenades g_grenades;
@ -176,6 +195,7 @@ extern float g_game_restarting;
extern float g_game_timeleft;
extern float g_task_time;
extern float g_auth_time;
extern bool g_NewDLL_Available;
extern hudtextparms_t g_hudset;
//extern int g_edict_point;
extern int g_players_num;
@ -224,14 +244,15 @@ void Client_DeathMsg(void*);
void amx_command();
void plugin_srvcmd();
const char* stristr(const char* a,const char* b);
const char* stristr(const char* a, const char* b);
char *strptime(const char *buf, const char *fmt, struct tm *tm, short addthem);
int loadModules(const char* filename, PLUG_LOADTIME now);
void detachModules();
void detachReloadModules();
#ifdef FAKEMETA
void attachModules();
void attachModules();
#endif
// Count modules
@ -244,29 +265,34 @@ enum CountModulesMode
int countModules(CountModulesMode mode);
void modules_callPluginsLoaded();
void modules_callPluginsUnloaded();
void modules_callPluginsUnloading();
cell* get_amxaddr(AMX *amx,cell amx_addr);
char* build_pathname(char *fmt, ... );
cell* get_amxaddr(AMX *amx, cell amx_addr);
char* build_pathname(char *fmt, ...);
char* build_pathname_r(char *buffer, size_t maxlen, char *fmt, ...);
char* format_amxstring(AMX *amx, cell *params, int parm,int& len);
AMX* get_amxscript(int, void**,const char**);
char* format_amxstring(AMX *amx, cell *params, int parm, int& len);
AMX* get_amxscript(int, void**, const char**);
const char* get_amxscriptname(AMX* amx);
char* get_amxstring(AMX *amx,cell amx_addr,int id,int& len);
char* get_amxstring(AMX *amx, cell amx_addr, int id, int& len);
extern "C" size_t get_amxstring_r(AMX *amx, cell amx_addr, char *destination, int maxlen);
int amxstring_len(cell* cstr);
int load_amxscript(AMX* amx, void** program, const char* path, char error[64], int debug);
int set_amxnatives(AMX* amx,char error[64]);
int set_amxstring(AMX *amx,cell amx_addr,const char *source,int max);
int unload_amxscript(AMX* amx,void** program);
void copy_amxmemory(cell* dest,cell* src,int len);
int set_amxnatives(AMX* amx, char error[64]);
int set_amxstring(AMX *amx, cell amx_addr, const char *source, int max);
int unload_amxscript(AMX* amx, void** program);
void copy_amxmemory(cell* dest, cell* src, int len);
void get_modname(char*);
void print_srvconsole( char *fmt, ... );
void report_error( int code, char* fmt, ... );
void print_srvconsole(char *fmt, ...);
void report_error(int code, char* fmt, ...);
void* alloc_amxmemory(void**, int size);
void free_amxmemory(void **ptr);
// get_localinfo
const char* get_localinfo( const char* name , const char* def );
const char* get_localinfo(const char* name, const char* def);
cell AMX_NATIVE_CALL require_module(AMX *amx, cell *params);
void LogError(AMX *amx, int err, const char *fmt, ...);
extern "C" void LogError(AMX *amx, int err, const char *fmt, ...);
enum ModuleCallReason
{
@ -279,6 +305,7 @@ enum ModuleCallReason
extern ModuleCallReason g_ModuleCallReason; // modules.cpp
extern CModule *g_CurrentlyCalledModule; // modules.cpp
extern const char *g_LastRequestedFunc; // modules.cpp
void Module_CacheFunctions();
void Module_UncacheFunctions();
@ -298,11 +325,12 @@ extern int FF_PluginLog;
extern int FF_PluginEnd;
extern int FF_InconsistentFile;
extern int FF_ClientAuthorized;
extern int FF_ChangeLevel;
extern bool g_coloredmenus;
#ifdef FAKEMETA
extern CFakeMeta g_FakeMeta;
#endif
typedef void (*AUTHORIZEFUNC)(int player, const char *authstring);
#define MM_CVAR2_VERS 13
struct func_s
{
@ -310,5 +338,6 @@ struct func_s
const char *desc;
};
#endif // AMXMODX_H
extern enginefuncs_t *g_pEngTable;
#endif // AMXMODX_H

View File

@ -54,7 +54,7 @@ static cell AMX_NATIVE_CALL _time(AMX *amx, cell *params)
/* the time() function returns the number of seconds since January 1 1970
* in Universal Coordinated Time (the successor to Greenwich Mean Time)
*/
return sec1970;
return (cell)sec1970;
}
#if defined __BORLANDC__ || defined __WATCOMC__

View File

@ -35,6 +35,7 @@
/**********************
****** AMXXFILE ******
**********************/
#if defined __GNUC__
#define PACKED __attribute__((packed))
#else
@ -73,6 +74,7 @@ CAmxxReader::CAmxxReader(const char *filename, int cellsize)
{
m_Bh.plugins = NULL;
m_AmxxFile = false;
if (!filename)
{
m_Status = Err_InvalidParam;
@ -81,8 +83,8 @@ CAmxxReader::CAmxxReader(const char *filename, int cellsize)
m_Status = Err_None;
m_CellSize = cellsize;
m_pFile = fopen(filename, "rb");
if (!m_pFile)
{
m_Status = Err_FileOpen;
@ -93,28 +95,37 @@ CAmxxReader::CAmxxReader(const char *filename, int cellsize)
DATAREAD(&magic, sizeof(magic), 1);
m_OldFile = false;
if ( magic == 0x524C4542 ) {
if (magic == 0x524C4542)
{
//we have an invalid, old, RLEB file
m_Status = Err_OldFile;
fclose(m_pFile);
m_pFile = NULL;
return;
} else if ( magic == MAGIC_HEADER2 ) {
}
else if (magic == MAGIC_HEADER2)
{
DATAREAD(&m_Bh.version, sizeof(int16_t), 1);
if (m_Bh.version != MAGIC_VERSION)
if (m_Bh.version > MAGIC_VERSION)
{
m_Status = Err_OldFile;
fclose(m_pFile);
m_pFile = NULL;
return;
}
m_AmxxFile = true;
DATAREAD(&m_Bh.numPlugins, sizeof(mint8_t), 1);
m_Bh.plugins = new PluginEntry[m_Bh.numPlugins];
PluginEntry *pe;
m_SectionHdrOffset = 0;
m_Entry = -1;
for (mint8_t i=0; i<m_Bh.numPlugins; i++)
for (mint8_t i = 0; i < m_Bh.numPlugins; i++)
{
pe = &(m_Bh.plugins[i]);
DATAREAD(&pe->cellsize, sizeof(mint8_t), 1);
@ -123,26 +134,32 @@ CAmxxReader::CAmxxReader(const char *filename, int cellsize)
DATAREAD(&pe->memsize, sizeof(int32_t), 1);
DATAREAD(&pe->offs, sizeof(int32_t), 1);
}
for (mint8_t i=0; i<m_Bh.numPlugins; i++)
for (mint8_t i = 0; i < m_Bh.numPlugins; i++)
{
pe = &(m_Bh.plugins[i]);
if (pe->cellsize == m_CellSize)
{
m_Entry = i;
break;
}
}
if (m_Entry == -1)
{
m_Status = Err_SectionNotFound;
fclose(m_pFile);
m_pFile = NULL;
return;
}
pe = &(m_Bh.plugins[m_Entry]);
m_SectionLength = pe->disksize;
} else if (magic == MAGIC_HEADER) {
}
else if (magic == MAGIC_HEADER)
{
// try to find the section
mint8_t numOfPlugins;
DATAREAD(&numOfPlugins, sizeof(numOfPlugins), 1);
@ -151,6 +168,7 @@ CAmxxReader::CAmxxReader(const char *filename, int cellsize)
m_SectionHdrOffset = 0;
int i = 0;
for (i = 0; i < static_cast<int>(numOfPlugins); ++i)
{
DATAREAD(&entry, sizeof(entry), 1);
@ -160,6 +178,7 @@ CAmxxReader::CAmxxReader(const char *filename, int cellsize)
break;
}
}
if (!m_SectionHdrOffset)
{
m_Status = Err_SectionNotFound;
@ -169,15 +188,13 @@ CAmxxReader::CAmxxReader(const char *filename, int cellsize)
}
// compute section length
if ((i+1) < static_cast<int>(numOfPlugins))
if ((i + 1) < static_cast<int>(numOfPlugins))
{
// there is a next section
TableEntry nextEntry;
DATAREAD(&nextEntry, sizeof(nextEntry), 1);
m_SectionLength = nextEntry.offset - entry.offset;
}
else
{
} else {
fseek(m_pFile, 0, SEEK_END);
m_SectionLength = ftell(m_pFile) - (long)entry.offset;
}
@ -187,6 +204,7 @@ CAmxxReader::CAmxxReader(const char *filename, int cellsize)
rewind(m_pFile);
fread(&hdr, sizeof(hdr), 1, m_pFile);
amx_Align16(&hdr.magic);
if (hdr.magic == AMX_MAGIC)
{
if (cellsize != 4)
@ -194,18 +212,19 @@ CAmxxReader::CAmxxReader(const char *filename, int cellsize)
m_Status = Err_SectionNotFound;
fclose(m_pFile);
m_pFile = NULL;
return;
}
m_OldFile = true;
return;
}
else
{
} else {
// no known file format
m_Status = Err_FileInvalid;
fclose(m_pFile);
m_pFile = NULL;
return;
}
}
@ -218,9 +237,10 @@ CAmxxReader::~CAmxxReader()
fclose(m_pFile);
m_pFile = NULL;
}
if (m_Bh.plugins)
{
delete m_Bh.plugins;
delete [] m_Bh.plugins;
m_Bh.plugins = NULL;
}
}
@ -256,11 +276,16 @@ size_t CAmxxReader::GetBufferSize()
AMX_HEADER hdr;
DATAREAD(&hdr, sizeof(hdr), 1);
fseek(m_pFile, save, SEEK_SET);
return hdr.stp;
} else if (m_AmxxFile) {
}
else if (m_AmxxFile)
{
PluginEntry *pe = &(m_Bh.plugins[m_Entry]);
if (pe->imagesize > pe->memsize)
return pe->imagesize + 1;
return pe->memsize + 1;
}
@ -269,6 +294,7 @@ size_t CAmxxReader::GetBufferSize()
TableEntry entry;
DATAREAD(&entry, sizeof(entry), 1);
fseek(m_pFile, save, SEEK_SET);
return entry.origSize + 1; // +1 : safe
}
@ -298,22 +324,26 @@ CAmxxReader::Error CAmxxReader::GetSection(void *buffer)
rewind(m_pFile);
DATAREAD(buffer, 1, filesize);
m_Status = Err_None;
return m_Status;
} else if (m_AmxxFile) {
}
else if (m_AmxxFile)
{
PluginEntry *pe = &(m_Bh.plugins[m_Entry]);
char *tempBuffer = new char[m_SectionLength + 1];
fseek(m_pFile, pe->offs, SEEK_SET);
DATAREAD((void *)tempBuffer, 1, m_SectionLength);
uLongf destLen = GetBufferSize();
int result = uncompress((Bytef *)buffer, &destLen,
(Bytef *)tempBuffer, m_SectionLength);
int result = uncompress((Bytef *)buffer, &destLen, (Bytef *)tempBuffer, m_SectionLength);
delete [] tempBuffer;
if (result != Z_OK)
{
AMXXLOG_Log("[AMXX] Zlib error encountered: %d(%d)", result, m_SectionLength);
m_Status = Err_Decompress;
return Err_Decompress;
}
return Err_None;
} else {
// new file type: go to the section table entry
@ -328,15 +358,17 @@ CAmxxReader::Error CAmxxReader::GetSection(void *buffer)
//fread(tempBuffer, sizeof(char), m_SectionLength, m_pFile);
DATAREAD((void*)tempBuffer, 1, m_SectionLength);
// decompress
int result = uncompress((Bytef *)buffer, &destLen,
(Bytef *)tempBuffer, m_SectionLength);
int result = uncompress((Bytef *)buffer, &destLen, (Bytef *)tempBuffer, m_SectionLength);
delete [] tempBuffer;
if (result != Z_OK)
{
AMXXLOG_Log("[AMXX] Zlib error encountered: %d(%d)", result, m_SectionLength);
m_Status = Err_Decompress;
return Err_Decompress;
}
return Err_None;
}
}

View File

@ -95,4 +95,3 @@ public:
};
#endif // __AMXXFILE_H__

View File

@ -36,18 +36,19 @@
#include <time.h>
#ifndef __linux__
#include <io.h>
#include <io.h>
#endif
#include "amxmodx.h"
#ifndef __linux__
#define vsnprintf _vsnprintf
#define vsnprintf _vsnprintf
#endif
CLog::CLog()
{
m_LogType = 0;
m_LogFile.clear();
m_FoundError = false;
}
CLog::~CLog()
@ -61,6 +62,7 @@ void CLog::CloseFile()
if (!m_LogFile.empty())
{
FILE *fp = fopen(m_LogFile.c_str(), "r");
if (fp)
{
fclose(fp);
@ -77,6 +79,7 @@ void CLog::CloseFile()
fprintf(fp, "L %s: %s\n", date, "Log file closed.");
fclose(fp);
}
m_LogFile.clear();
}
}
@ -84,29 +87,36 @@ void CLog::CloseFile()
void CLog::CreateNewFile()
{
CloseFile();
// build filename
time_t td;
time(&td);
tm *curTime = localtime(&td);
char file[256];
int i = 0;
while (true)
{
FILE *pTmpFile = fopen(m_LogFile.c_str(), "r"); // open for reading to check whether the file exists
build_pathname_r(file, sizeof(file)-1, "%s/L%02d%02d%03d.log", g_log_dir.c_str(), curTime->tm_mon + 1, curTime->tm_mday, i);
FILE *pTmpFile = fopen(file, "r"); // open for reading to check whether the file exists
if (!pTmpFile)
break;
fclose(pTmpFile);
++i;
}
m_LogFile.assign(file);
// Log logfile start
FILE *fp = fopen(m_LogFile.c_str(), "w");
if (!fp)
{
ALERT(at_logged, "[AMXX] Unexpected fatal logging error. AMXX Logging disabled.\n");
SET_LOCALINFO("amxx_logging", "0");
}
else
{
} else {
fprintf(fp, "AMX Mod X log file started (file \"%s/L%02d%02d%03d.log\") (version \"%s\")\n", g_log_dir.c_str(), curTime->tm_mon + 1, curTime->tm_mday, i, AMX_VERSION);
fclose(fp);
}
@ -123,12 +133,13 @@ void CLog::MapChange()
// create dir if not existing
char file[256];
#ifdef __linux
mkdir(build_pathname_r(file, sizeof(file)-1,"%s", g_log_dir.c_str()), 0700);
mkdir(build_pathname_r(file, sizeof(file)-1, "%s", g_log_dir.c_str()), 0700);
#else
mkdir(build_pathname_r(file, sizeof(file)-1,"%s", g_log_dir.c_str()));
mkdir(build_pathname_r(file, sizeof(file)-1, "%s", g_log_dir.c_str()));
#endif
m_LogType = atoi(get_localinfo("amxx_logging", "1"));
if (m_LogType < 0 || m_LogType > 3)
{
SET_LOCALINFO("amxx_logging", "1");
@ -143,7 +154,7 @@ void CLog::MapChange()
}
else if (m_LogType == 1)
{
Log("-------- Mapchange --------");
Log("-------- Mapchange to %s --------", STRING(gpGlobals->mapname));
}
else
return;
@ -152,6 +163,7 @@ void CLog::MapChange()
void CLog::Log(const char *fmt, ...)
{
static char file[256];
if (m_LogType == 1 || m_LogType == 2)
{
// get time
@ -178,6 +190,7 @@ void CLog::Log(const char *fmt, ...)
{
CreateNewFile();
pF = fopen(m_LogFile.c_str(), "a+");
if (!pF)
{
ALERT(at_logged, "[AMXX] Unexpected fatal logging error (couldn't open %s for a+). AMXX Logging disabled for this map.\n", m_LogFile.c_str());
@ -185,19 +198,16 @@ void CLog::Log(const char *fmt, ...)
return;
}
}
}
else
{
} else {
build_pathname_r(file, sizeof(file)-1, "%s/L%02d%02d.log", g_log_dir.c_str(), curTime->tm_mon + 1, curTime->tm_mday);
pF = fopen(file, "a+");
}
if (pF)
{
fprintf(pF, "L %s: %s\n", date, msg);
fclose(pF);
}
else
{
} else {
ALERT(at_logged, "[AMXX] Unexpected fatal logging error (couldn't open %s for a+). AMXX Logging disabled for this map.\n", file);
m_LogType = 0;
return;
@ -217,3 +227,45 @@ void CLog::Log(const char *fmt, ...)
ALERT(at_logged, "%s\n", msg_);
}
}
void CLog::LogError(const char *fmt, ...)
{
static char file[256];
if (m_FoundError)
return;
// get time
time_t td;
time(&td);
tm *curTime = localtime(&td);
char date[32];
strftime(date, 31, "%m/%d/%Y - %H:%M:%S", curTime);
// msg
static char msg[3072];
va_list arglst;
va_start(arglst, fmt);
vsnprintf(msg, 3071, fmt, arglst);
va_end(arglst);
FILE *pF = NULL;
build_pathname_r(file, sizeof(file)-1, "%s/error_%02d%02d%02d.log", g_log_dir.c_str(), curTime->tm_mon + 1, curTime->tm_mday, curTime->tm_year - 100);
pF = fopen(file, "a+");
if (pF)
{
fprintf(pF, "L %s: %s\n", date, msg);
fclose(pF);
} else {
ALERT(at_logged, "[AMXX] Unexpected fatal logging error (couldn't open %s for a+). AMXX Error Logging disabled for this map.\n", file);
m_FoundError = true;
return;
}
// print on server console
print_srvconsole("L %s: %s\n", date, msg);
}

View File

@ -36,17 +36,19 @@ class CLog
private:
String m_LogFile;
int m_LogType;
bool m_FoundError;
void GetLastFile(int &outMonth, int &outDay, String &outFilename);
void UseFile(const String &fileName);
public:
CLog();
~CLog();
void CreateNewFile();
void CloseFile();
void MapChange();
void Log(const char *fmt, ...);
void LogError(const char *fmt, ...);
};
#endif // __AMXXLOG_H__

271
amxmodx/binlog.cpp Normal file
View File

@ -0,0 +1,271 @@
#if defined BINLOG_ENABLED
#include <time.h>
#include "amxmodx.h"
#include "binlog.h"
BinLog g_BinLog;
int g_binlog_level = 0;
int g_binlog_maxsize = 0;
bool BinLog::Open()
{
const char *data = get_localinfo("amxmodx_datadir", "addons/amxmodx/data");
char path[255];
build_pathname_r(path, sizeof(path)-1, "%s/binlogs", data);
if (!DirExists(path))
{
mkdir(path
#if defined __linux__
, 0755
#endif
);
if (!DirExists(path))
return false;
}
char file[255];
build_pathname_r(file, sizeof(file)-1, "%s/binlogs/lastlog", data);
unsigned int lastcntr = 0;
FILE *lastlog = fopen(file, "rb");
if (lastlog)
{
if (fread(&lastcntr, sizeof(int), 1, lastlog) != 1)
lastcntr = 0;
fclose(lastlog);
}
lastlog = fopen(file, "wb");
if (lastlog)
{
lastcntr++;
fwrite(&lastcntr, sizeof(int), 1, lastlog);
fclose(lastlog);
}
build_pathname_r(file, sizeof(file)-1, "%s/binlogs/binlog%04d.blg", data, lastcntr);
m_logfile.assign(file);
/**
* it's now safe to create the binary log
*/
FILE *fp = fopen(m_logfile.c_str(), "wb");
if (!fp)
return false;
int magic = BINLOG_MAGIC;
short vers = BINLOG_VERSION;
char c = sizeof(time_t);
fwrite(&magic, sizeof(int), 1, fp);
fwrite(&vers, sizeof(short), 1, fp);
fwrite(&c, sizeof(char), 1, fp);
WritePluginDB(fp);
fclose(fp);
m_state = true;
WriteOp(BinLog_Start, -1);
return true;
}
void BinLog::Close()
{
WriteOp(BinLog_End, -1);
m_state = false;
}
void BinLog::WriteOp(BinLogOp op, int plug, ...)
{
if (!m_state)
return;
FILE *fp = fopen(m_logfile.c_str(), "ab");
if (!fp)
return;
if (g_binlog_maxsize && op != BinLog_End)
{
fseek(fp, 0, SEEK_END);
if (ftell(fp) > (g_binlog_maxsize * (1024 * 1024)))
{
fclose(fp);
Close();
Open();
fp = fopen(m_logfile.c_str(), "ab");
if (!fp)
return;
}
}
unsigned char c = static_cast<char>(op);
time_t t = time(NULL);
float gt = gpGlobals->time;
fwrite(&c, sizeof(char), 1, fp);
fwrite(&t, sizeof(time_t), 1, fp);
fwrite(&gt, sizeof(float), 1, fp);
fwrite(&plug, sizeof(int), 1, fp);
va_list ap;
va_start(ap, plug);
switch (c)
{
case BinLog_Registered:
{
const char *title = va_arg(ap, const char *);
const char *vers = va_arg(ap, const char *);
c = (char)strlen(title);
fwrite(&c, sizeof(char), 1, fp);
fwrite(title, sizeof(char), c+1, fp);
c = (char)strlen(vers);
fwrite(&c, sizeof(char), 1 ,fp);
fwrite(vers, sizeof(char), c+1, fp);
break;
}
case BinLog_NativeCall:
{
int native = va_arg(ap, int);
int params = va_arg(ap, int);
fwrite(&native, sizeof(int), 1, fp);
fwrite(&params, sizeof(int), 1, fp);
break;
}
case BinLog_NativeRet:
{
cell retval = va_arg(ap, cell);
fwrite(&retval, sizeof(cell), 1, fp);
break;
}
case BinLog_NativeError:
{
int err = va_arg(ap, int);
const char *msg = va_arg(ap, const char *);
short len = (short)strlen(msg);
fwrite(&err, sizeof(int), 1, fp);
fwrite(&len, sizeof(short), 1, fp);
fwrite(msg, sizeof(char), len+1, fp);
break;
}
case BinLog_CallPubFunc:
{
int num = va_arg(ap, int);
fwrite(&num, sizeof(int), 1, fp);
break;
}
case BinLog_SetLine:
{
int line = va_arg(ap, int);
fwrite(&line, sizeof(int), 1, fp);
break;
}
case BinLog_FormatString:
{
int param = va_arg(ap, int);
int maxlen = va_arg(ap, int);
const char *str = va_arg(ap, const char *);
short len = (short)strlen(str);
fwrite(&param, sizeof(int), 1, fp);
fwrite(&maxlen, sizeof(int), 1, fp);
fwrite(&len, sizeof(short), 1, fp);
fwrite(str, sizeof(char), len+1, fp);
break;
}
case BinLog_NativeParams:
{
cell *params = va_arg(ap, cell *);
cell num = params[0] / sizeof(cell);
fwrite(&num, sizeof(cell), 1, fp);
for (cell i=1; i<=num; i++)
fwrite(&(params[i]), sizeof(cell), 1, fp);
break;
}
case BinLog_GetString:
{
cell addr = va_arg(ap, cell);
const char *str = va_arg(ap, const char *);
short len = (short)strlen(str);
fwrite(&addr, sizeof(cell), 1, fp);
fwrite(&len, sizeof(short), 1, fp);
fwrite(str, sizeof(char), len+1, fp);
break;
}
case BinLog_SetString:
{
cell addr = va_arg(ap, cell);
int maxlen = va_arg(ap, int);
const char *str = va_arg(ap, const char *);
short len = (short)strlen(str);
fwrite(&addr, sizeof(cell), 1, fp);
fwrite(&maxlen, sizeof(int), 1, fp);
fwrite(&len, sizeof(short), 1, fp);
fwrite(str, sizeof(char), len+1, fp);
break;
}
};
va_end(ap);
fclose(fp);
}
void BinLog::WritePluginDB(FILE *fp)
{
int num = g_plugins.getPluginsNum();
fwrite(&num, sizeof(int), 1, fp);
CPluginMngr::CPlugin *pl;
char c;
unsigned char len;
for (CPluginMngr::iterator iter = g_plugins.begin(); iter; ++iter)
{
pl = &(*iter);
if (pl->isValid())
c = 1;
else
c = 0;
if (c && pl->isDebug())
c = 2;
fwrite(&c, sizeof(char), 1, fp);
if (c)
{
len = (char)strlen(pl->getName());
fwrite(&len, sizeof(char), 1, fp);
len++;
fwrite(pl->getName(), sizeof(char), len, fp);
int natives, publics;
AMX *amx = pl->getAMX();
amx_NumNatives(amx, &natives);
amx_NumPublics(amx, &publics);
fwrite(&natives, sizeof(int), 1, fp);
fwrite(&publics, sizeof(int), 1, fp);
char name[34];
for (int i=0; i<natives; i++)
{
amx_GetNative(amx, i, name);
len = (char)strlen(name);
fwrite(&len, sizeof(char), 1, fp);
len++;
fwrite(name, sizeof(char), len, fp);
}
for (int i=0; i<publics; i++)
{
amx_GetPublic(amx, i, name);
len = (char)strlen(name);
fwrite(&len, sizeof(char), 1, fp);
len++;
fwrite(name, sizeof(char), len, fp);
}
} else {
char empty[] = " ";
len = 1;
fwrite(&len, sizeof(char), 1, fp);
fwrite(empty, sizeof(char), len, fp);
int no = 0;
fwrite(&no, sizeof(int), 1, fp);
fwrite(&no, sizeof(int), 1, fp);
}
}
}
#endif //BINLOG_ENABLED

77
amxmodx/binlog.h Normal file
View File

@ -0,0 +1,77 @@
#ifndef _INCLUDE_BINLOG_H
#define _INCLUDE_BINLOG_H
#if defined BINLOG_ENABLED
#include "CString.h"
#define BINLOG_MAGIC 0x414D424C
#define BINLOG_VERSION 0x0200
/**
* Format of binlog:
* uint32 magic
* uint16 version
* uint8 sizeof(time_t)
* uint32 num plugins
* [
* uint8 status codes
* str[int8] filename
* uint32 num natives
* uint32 num publics
* [
* str[uint8] native name
* ]
* [
* str[uint8] public name
* ]
* ]
* [
* uint8 operation code
* time_t realtime
* float gametime
* int32 plugin id
* <extra info>
* ]
*/
enum BinLogOp
{
BinLog_Start=1,
BinLog_End,
BinLog_NativeCall, //<int32 native id> <int32_t num_params>
BinLog_NativeError, //<int32 errornum> <str[int16] string>
BinLog_NativeRet, //<cell value>
BinLog_CallPubFunc, //<int32 public id>
BinLog_SetLine, //<int32 line no#>
BinLog_Registered, //<string title> <string version>
BinLog_FormatString, //<int32 param#> <int32 maxlen> <str[int16] string>
BinLog_NativeParams, //<int32 num> <cell ...>
BinLog_GetString, //<cell addr> <string[int16]>
BinLog_SetString, //<cell addr> <int maxlen> <string[int16]>
};
class BinLog
{
public:
BinLog() : m_state(false)
{
};
public:
bool Open();
void Close();
void WriteOp(BinLogOp op, int plug, ...);
private:
void WritePluginDB(FILE *fp);
private:
String m_logfile;
bool m_state;
};
extern BinLog g_BinLog;
extern int g_binlog_level;
extern int g_binlog_maxsize;
#endif //BINLOG_ENABLED
#endif //_INCLUDE_BINLOG_H

1010
amxmodx/debugger.cpp Executable file

File diff suppressed because it is too large Load Diff

201
amxmodx/debugger.h Executable file
View File

@ -0,0 +1,201 @@
/* AMX Mod X
*
* by the AMX Mod X Development Team
* originally developed by OLO
*
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* 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, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* In addition, as a special exception, the author gives permission to
* link the code of this program with the Half-Life Game Engine ("HL
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
* L.L.C ("Valve"). You must obey the GNU General Public License in all
* respects for all of the code used other than the HL Engine and MODs
* from Valve. If you modify this file, you may extend this exception
* to your version of the file, but you are not obligated to do so. If
* you do not wish to do so, delete this exception statement from your
* version.
*/
#ifndef _INCLUDE_DEBUGGER_H_
#define _INCLUDE_DEBUGGER_H_
#include "CVector.h"
#include "amxdbg.h"
/**
* Third revision of the AMX Mod X Plugin Debugger.
* This final, object oriented version is safe for multiple calls and lets you
* fine-tune error handling.
* -BAILOPAN
*/
class Debugger
{
public:
class Tracer
{
public:
struct trace_info
{
trace_info() : cip(0), frm(0), used(false), next(NULL), prev(NULL) {};
cell cip;
cell frm;
trace_info *next;
trace_info *prev;
bool used;
};
public:
Tracer() : m_Error(0), m_pStart(NULL), m_pEnd(NULL), m_Reset(true) {};
~Tracer();
public:
void StepI(cell frm, cell cip);
void Reset();
void Clear();
Debugger::Tracer::trace_info *GetStart() const;
Debugger::Tracer::trace_info *GetEnd() const;
public:
int m_Error;
private:
trace_info *m_pStart;
trace_info *m_pEnd;
bool m_Reset;
};
public:
Debugger(AMX *pAmx, AMX_DBG *pAmxDbg) : m_pAmx(pAmx), m_pAmxDbg(pAmxDbg), m_Top(-1)
{
_CacheAmxOpcodeList();
};
~Debugger();
public:
//Begin a trace for a function
void BeginExec();
//Step through one instruction
void StepI();
//Get/set the last traced error
int GetTracedError();
void SetTracedError(int error);
//Get the first trace info of the call stack
Debugger::Tracer::trace_info *GetTraceStart() const;
//Get extra info about the call stack
bool GetTraceInfo(Debugger::Tracer::trace_info *pTraceInfo, long &line, const char *&function, const char *&file);
//Get the next trace in the call stack, NULL if none
Debugger::Tracer::trace_info *GetNextTrace(Debugger::Tracer::trace_info *pTraceInfo);
//Returns true if an error exists
bool ErrorExists();
//Formats the error message into a buffer.
//returns length of data copied, or -1 if there is no error.
int FormatError(char *buffer, size_t maxLength);
//End a trace
void EndExec();
//Reset the internal states as if the debugger was inactive
void Reset();
//Destroy internal states for shutdown
void Clear();
void DisplayTrace(const char *message);
AMX *GetAMX() const { return m_pAmx; }
public:
//generic static opcode breaker
static int AMXAPI DebugHook(AMX *amx);
static void FmtGenericMsg(AMX *amx, int error, char buffer[], size_t maxLength);
static void GenericMessage(AMX *amx, int error);
private:
void _CacheAmxOpcodeList();
int _GetOpcodeFromCip(cell cip, cell *&addr);
cell _CipAsVa(cell cip);
const char *_GetFilename();
public:
AMX *m_pAmx;
AMX_DBG *m_pAmxDbg;
int m_Top;
cell *m_pOpcodeList;
String m_FileName;
CVector<Tracer *> m_pCalls;
};
typedef Debugger::Tracer::trace_info trace_info_t;
/**
* Error handler for plugins
*/
class Handler
{
public:
Handler(AMX *pAmx) : m_pAmx(pAmx), m_iErrFunc(-1), m_iModFunc(-1), m_iNatFunc(-1), m_Handling(false), m_InNativeFilter(false) {};
~Handler() {};
public:
int SetErrorHandler(const char *function);
int SetNativeFilter(const char *function);
int SetModuleFilter(const char *function);
public:
int HandleError(const char *msg);
int HandleNative(const char *native, int index, int trap);
int HandleModule(const char *module, bool isClass=false);
public:
bool IsHandling() const { return m_Handling; }
void SetErrorMsg(const char *msg);
const char *GetLastMsg();
trace_info_t *GetTrace() const { return m_pTrace; }
const char *GetFmtCache() { return m_FmtCache.c_str(); }
bool IsNativeFiltering() { return (m_iNatFunc > 0); }
bool InNativeFilter() { return m_InNativeFilter; }
private:
AMX *m_pAmx;
int m_iErrFunc;
int m_iModFunc;
int m_iNatFunc;
bool m_Handling;
//in the future, make this a stack!
bool m_InNativeFilter;
String m_MsgCache;
String m_FmtCache;
trace_info_t *m_pTrace;
};
extern AMX_NATIVE_INFO g_DebugNatives[];
#endif //_INCLUDE_DEBUGGER_H_

View File

@ -58,9 +58,14 @@ WeaponsVault g_weaponsData[MAX_WEAPONS];
void Client_VGUIMenu(void* mValue)
{
if (!mPlayer) return;
switch (mState++){
mPlayer->vgui = true;
switch (mState++)
{
case 0:
mPlayer->menu = -(*(int*)mValue);
mPlayer->newmenu = -1;
break;
case 1:
mPlayer->keys = *(int*)mValue;
@ -70,12 +75,20 @@ void Client_VGUIMenu(void* mValue)
void Client_ShowMenu(void* mValue)
{
if (!mPlayer) return;
switch (mState++){
mPlayer->vgui = true;
switch (mState++)
{
case 0:
mPlayer->keys = *(int*)mValue;
break;
case 3:
mPlayer->menu = g_menucmds.findMenuId( (char*)mValue );
{
mPlayer->menu = g_menucmds.findMenuId((char*)mValue);
mPlayer->newmenu = -1;
break;
}
}
}
@ -83,59 +96,74 @@ void Client_TeamInfo(void* mValue)
{
if (mPlayer) return;
static int index;
switch (mState++) {
switch (mState++)
{
case 0:
index = *(int*)mValue;
break;
case 1:
if ( index < 1 || index > gpGlobals->maxClients ) break;
if (index < 1 || index > gpGlobals->maxClients) break;
char* msg = (char*)mValue;
g_players[ index ].team.assign( msg );
g_teamsIds.registerTeam( msg , -1 );
g_players[index].team.assign(msg);
g_teamsIds.registerTeam(msg, -1);
}
}
void Client_TextMsg(void* mValue)
{
if ( mPlayer ) return;
switch (mState++) {
case 1:{
if (mPlayer) return;
switch (mState++)
{
case 1:
{
char * msg = (char*)mValue;
if (!msg) break;
if ( !strncmp("#Game_C", msg , 7) ) {
if (!strncmp("#Game_C", msg, 7))
{
g_game_timeleft = g_game_restarting = gpGlobals->time + 3;
// g_endround_time = gpGlobals->time;
// g_newround_time = gpGlobals->time + CVAR_GET_FLOAT("mp_freezetime") + 3;
//g_endround_time = gpGlobals->time;
//g_newround_time = gpGlobals->time + CVAR_GET_FLOAT("mp_freezetime") + 3;
}
else if (!strncmp("#Game_w", msg , 7) ) {
else if (!strncmp("#Game_w", msg, 7))
{
g_game_timeleft = -2;
}
else if ( !strncmp("#game_clan_s", msg , 12) ){
else if (!strncmp("#game_clan_s", msg, 12))
{
g_game_timeleft = -3;
}
break;
}
case 2:{
char * msg = (char*)mValue;
if (!msg) break;
if (g_game_timeleft == -2 ){
g_game_timeleft = g_game_restarting = gpGlobals->time + atoi( msg );
// g_newround_time = g_game_timeleft + CVAR_GET_FLOAT("mp_freezetime");
}
else if ( g_game_timeleft == -3 )
g_game_restarting = atoi( msg ) * 60;
break;
}
case 3:{
char * msg = (char*)mValue;
if (!msg) break;
if ( g_game_timeleft != -3 ) break;
g_game_restarting += atoi( msg );
g_game_timeleft = g_game_restarting = gpGlobals->time + g_game_restarting;
break;
}
}
break;
}
case 2:
{
char * msg = (char*)mValue;
if (!msg) break;
if (g_game_timeleft == -2)
{
g_game_timeleft = g_game_restarting = gpGlobals->time + atoi(msg);
//g_newround_time = g_game_timeleft + CVAR_GET_FLOAT("mp_freezetime");
}
else if (g_game_timeleft == -3)
g_game_restarting = atoi(msg) * 60.0f;
break;
}
case 3:
{
char * msg = (char*)mValue;
if (!msg) break;
if (g_game_timeleft != -3) break;
g_game_restarting += atoi(msg);
g_game_timeleft = g_game_restarting = gpGlobals->time + g_game_restarting;
break;
}
}
}
void Client_WeaponList(void* mValue)
@ -144,7 +172,9 @@ void Client_WeaponList(void* mValue)
//static int wpnList2;
static int iSlot;
static const char* wpnName;
switch (mState++) {
switch (mState++)
{
case 0:
wpnName = (char*)mValue;
break;
@ -153,24 +183,12 @@ void Client_WeaponList(void* mValue)
break;
case 7:
int iId = *(int*)mValue;
/*int* blocker;
int iwpn = iId;
if (iId > 31) {
iwpn -= 31;
blocker = &wpnList2;
}
else
blocker = &wpnList;*/
if ( (iId < 0 || iId >= MAX_WEAPONS ) || (wpnList & (1<<iId)) )
if ((iId < 0 || iId >= MAX_WEAPONS) || (wpnList & (1<<iId)))
break;
wpnList |= (1<<iId);
g_weaponsData[iId].iId = iId;
g_weaponsData[iId].ammoSlot = iSlot;
g_weaponsData[iId].fullName.assign(wpnName);
}
}
@ -178,7 +196,9 @@ void Client_CurWeapon(void* mValue)
{
static int iState;
static int iId;
switch (mState++){
switch (mState++)
{
case 0:
iState = *(int*)mValue;
break;
@ -188,7 +208,7 @@ void Client_CurWeapon(void* mValue)
break;
case 2:
if (!mPlayer) return;
if (!iState || (iId < 1 || iId >= MAX_WEAPONS ) ) break;
if (!iState || (iId < 1 || iId >= MAX_WEAPONS)) break;
mPlayer->weapons[iId].clip = *(int*)mValue;
mPlayer->current = iId;
mPlayer->lastHit = mPlayer->lastTrace;
@ -197,15 +217,16 @@ void Client_CurWeapon(void* mValue)
void Client_AmmoX(void* mValue)
{
static int iAmmo;
switch (mState++){
switch (mState++)
{
case 0:
iAmmo = *(int*)mValue;
break;
case 1:
if (!mPlayer) return;
for(int i=1;i<MAX_WEAPONS;++i)
for (int i = 1; i < MAX_WEAPONS; ++i)
if (iAmmo == g_weaponsData[i].ammoSlot)
mPlayer->weapons[i].ammo = *(int*)mValue;
}
@ -214,13 +235,15 @@ void Client_AmmoX(void* mValue)
void Client_AmmoPickup(void* mValue)
{
static int iSlot;
switch (mState++){
switch (mState++)
{
case 0:
iSlot = *(int*)mValue;
break;
case 1:
if (!mPlayer) return;
for(int i=1;i<MAX_WEAPONS;++i)
for (int i = 1; i < MAX_WEAPONS; ++i)
if (g_weaponsData[i].ammoSlot==iSlot)
mPlayer->weapons[i].ammo += *(int*)mValue;
}
@ -230,7 +253,9 @@ void Client_ScoreInfo(void* mValue)
{
static int index;
static int deaths;
switch (mState++){
switch (mState++)
{
case 0:
index = *(int*)mValue;
break;
@ -238,12 +263,12 @@ void Client_ScoreInfo(void* mValue)
deaths = *(int*)mValue;
break;
case 4:
if ( index < 1 || index > gpGlobals->maxClients ) break;
CPlayer*pPlayer = GET_PLAYER_POINTER_I( index );
if (index < 1 || index > gpGlobals->maxClients) break;
CPlayer*pPlayer = GET_PLAYER_POINTER_I(index);
pPlayer->deaths = deaths;
pPlayer->teamId = *(int*)mValue;
if ( g_teamsIds.isNewTeam() )
g_teamsIds.registerTeam( pPlayer->team.c_str() , pPlayer->teamId );
if (g_teamsIds.isNewTeam())
g_teamsIds.registerTeam(pPlayer->team.c_str(), pPlayer->teamId);
}
}
@ -251,14 +276,14 @@ void Client_DamageEnd(void* mValue)
{
CPlayer* dead = mPlayer;
if ( dead && dead->death_killer )
if (dead && dead->death_killer)
{
g_events.parserInit( CS_DEATHMSG , &gpGlobals->time , mPlayer = 0, mPlayerIndex = 0 );
g_events.parseValue( dead->death_killer );
g_events.parseValue( dead->index );
g_events.parseValue( dead->death_headshot );
g_events.parseValue( dead->death_weapon.c_str() );
g_events.parseValue( dead->death_tk ? 1 : 0 );
g_events.parserInit(CS_DEATHMSG, &gpGlobals->time, mPlayer = 0, mPlayerIndex = 0);
g_events.parseValue(dead->death_killer);
g_events.parseValue(dead->index);
g_events.parseValue(dead->death_headshot);
g_events.parseValue(dead->death_weapon.c_str());
g_events.parseValue(dead->death_tk ? 1 : 0);
g_events.executeEvents();
dead->death_killer = 0;
}
@ -272,24 +297,21 @@ void Client_DeathMsg(void* mValue)
static int victim_id;
static int hs;
switch (mState++){
switch (mState++)
{
case 0:
killer_id = *(int*)mValue;
killer = (killer_id > 0 && killer_id < 33) ?
GET_PLAYER_POINTER_I(killer_id) : 0;
killer = (killer_id > 0 && killer_id < 33) ? GET_PLAYER_POINTER_I(killer_id) : 0;
break;
case 1:
victim_id = *(int*)mValue;
victim = (victim_id > 0 && victim_id < 33) ?
GET_PLAYER_POINTER_I(victim_id) : 0;
victim = (victim_id > 0 && victim_id < 33) ? GET_PLAYER_POINTER_I(victim_id) : 0;
break;
case 2:
hs = *(int*)mValue;
break;
case 3:
if ( !killer || !victim ) break;
if (!killer || !victim) break;
victim->death_killer = killer_id;
victim->death_weapon.assign((char*)mValue);
victim->death_headshot = hs;

File diff suppressed because it is too large Load Diff

View File

@ -31,205 +31,7 @@
#ifndef __FAKEMETA_H__
#define __FAKEMETA_H__
#ifndef FAKEMETA
int UnloadMetamodPlugin(void *handle);
int LoadMetamodPlugin(const char *path, void **handle, PLUG_LOADTIME now);
#else
// Fake metamod api for modules
#include "CList.h"
// from mplugin.h (metamod)
// Flags to indicate current "load" state of plugin.
// NOTE: order is important, as greater/less comparisons are made.
typedef enum {
PL_EMPTY = 0, // empty slot
PL_VALID, // has valid info in it
PL_BADFILE, // nonexistent file (open failed),
// or not a valid plugin file (query failed)
PL_OPENED, // dlopened and queried
PL_FAILED, // opened, but failed to attach or unattach
PL_RUNNING, // attached and running
PL_PAUSED, // attached but paused
} PLUG_STATUS;
// from h_export.h (metamod)
// Our GiveFnptrsToDll, called by engine.
typedef void (WINAPI *GIVE_ENGINE_FUNCTIONS_FN) (enginefuncs_t
*pengfuncsFromEngine, globalvars_t *pGlobals);
// *** CFakeMeta
class CFakeMeta
{
private:
// Core tables
/* DLL_FUNCTIONS m_CoreDllFuncTable;
enginefuncs_t m_CoreEngineFuncTable;
NEW_DLL_FUNCTIONS m_CoreNewDllFuncTable;
DLL_FUNCTIONS m_CoreDllFuncTable_Post;
enginefuncs_t m_CoreEngineFuncTable_Post;
NEW_DLL_FUNCTIONS m_CoreNewDllFuncTable_Post; */
bool AddCorePlugin(); // Adds the core plugin if needed
public:
class CFakeMetaPlugin
{
private:
// plugin info
String m_Path;
PLUG_STATUS m_Status;
plugin_info_t *m_Info;
// Function tables
META_FUNCTIONS m_MetaFuncTable;
DLL_FUNCTIONS m_DllFuncTable;
enginefuncs_t m_EngineFuncTable;
NEW_DLL_FUNCTIONS m_NewDllFuncTable;
DLL_FUNCTIONS m_DllFuncTable_Post;
enginefuncs_t m_EngineFuncTable_Post;
NEW_DLL_FUNCTIONS m_NewDllFuncTable_Post;
// OS dep handle
DLHANDLE m_Handle;
public:
inline PLUG_STATUS GetStatus() const
{ return m_Status; }
inline void SetStatus(PLUG_STATUS newStatus)
{ m_Status = newStatus; }
inline plugin_info_t * GetInfo()
{ return m_Info; }
inline const plugin_info_t * GetInfo() const
{ return m_Info; }
inline void SetInfo(plugin_info_t *newInfo)
{ m_Info = newInfo; }
inline const char * GetPath()
{ return m_Path.c_str(); }
inline const META_FUNCTIONS &GetMetaFunctions() const
{ return m_MetaFuncTable; }
// Get
inline DLL_FUNCTIONS &GetDllFuncTable()
{ return m_DllFuncTable; }
inline enginefuncs_t &GetEngineFuncTable()
{ return m_EngineFuncTable; }
inline NEW_DLL_FUNCTIONS &GetNewDllFuncTable()
{ return m_NewDllFuncTable; }
// Get const
inline const DLL_FUNCTIONS &GetDllFuncTable() const
{ return m_DllFuncTable; }
inline const enginefuncs_t &GetEngineFuncTable() const
{ return m_EngineFuncTable; }
inline const NEW_DLL_FUNCTIONS &GetNewDllFuncTable() const
{ return m_NewDllFuncTable; }
// Get post
inline DLL_FUNCTIONS &GetDllFuncTable_Post()
{ return m_DllFuncTable_Post; }
inline enginefuncs_t &GetEngineFuncTable_Post()
{ return m_EngineFuncTable_Post; }
inline NEW_DLL_FUNCTIONS &GetNewDllFuncTable_Post()
{ return m_NewDllFuncTable_Post; }
// Get post const
inline const DLL_FUNCTIONS &GetDllFuncTable_Post() const
{ return m_DllFuncTable_Post; }
inline const enginefuncs_t &GetEngineFuncTable_Post() const
{ return m_EngineFuncTable_Post; }
inline const NEW_DLL_FUNCTIONS &GetNewDllFuncTable_Post() const
{ return m_NewDllFuncTable_Post; }
int Query(mutil_funcs_t *pMetaUtilFuncs); // Also calls GiveFnPtrsToDll
int Attach(PLUG_LOADTIME now, meta_globals_t *pMGlobals, gamedll_funcs_t *pGameDllFuncs);
int Detach(PLUG_LOADTIME now, PL_UNLOAD_REASON reason);
int GetEntityAPI2(int interfaceVersion);
int GetEntityAPI2_Post(int interfaceVersion);
int GetEngineFunctions(int interfaceVersion);
int GetEngineFunctions_Post(int interfaceVersion);
int GetNewDLLFunctions(int interfaceVersion);
int GetNewDLLFunctions_Post(int interfaceVersion);
CFakeMetaPlugin(const char *path);
~CFakeMetaPlugin();
}; // CFakeMetaPlugin
CFakeMeta();
~CFakeMeta();
bool AddPlugin(const char *path /*path relative to moddir*/);
void ReleasePlugins();
// This is public because i don't want to declare all the functions as friends :)
// :NOTE: The core is now a special, first plugin!
CList<CFakeMetaPlugin> m_Plugins;
// ****** Meta functions ******
// Query all added plugins
void Meta_Query(mutil_funcs_t *pMetaUtilFuncs);
// Attach all added plugins
void Meta_Attach(PLUG_LOADTIME now, meta_globals_t *pMGlobals, gamedll_funcs_t *pGamedllFuncs);
// Detach all added plugins
void Meta_Detach(PLUG_LOADTIME now, PL_UNLOAD_REASON reason);
// :NOTE: Meta_Init currently not supported
int GetEntityAPI2(DLL_FUNCTIONS *pFunctionTable /*from metamod*/, int *interfaceVersion /*from metamod*/,
DLL_FUNCTIONS *pAMXXFunctionTable /*Functions amxx needs*/);
int GetEntityAPI2_Post(DLL_FUNCTIONS *pFunctionTable /*from metamod*/, int *interfaceVersion /*from metamod*/,
DLL_FUNCTIONS *pAMXXFunctionTable /*Functions amxx needs*/);
int GetEngineFunctions(enginefuncs_t *pengfuncsFromEngine, int *interfaceVersion,
enginefuncs_t *pAMXXFunctionTable /*Fucntions amxx needs*/);
int GetEngineFunctions_Post(enginefuncs_t *pengfuncsFromEngine, int *interfaceVersion,
enginefuncs_t *pAMXXFunctionTable /*Fucntions amxx needs*/);
int GetNewDLLFunctions(NEW_DLL_FUNCTIONS *pNewFunctionTable, int *interfaceVersion,
NEW_DLL_FUNCTIONS *pAMXXFunctionTable);
int GetNewDLLFunctions_Post(NEW_DLL_FUNCTIONS *pNewFunctionTable, int *interfaceVersion,
NEW_DLL_FUNCTIONS *pAMXXFunctionTable);
// Get
/*inline DLL_FUNCTIONS &GetDllFuncTable()
{ return m_CoreDllFuncTable; }
inline enginefuncs_t &GetEngineFuncTable()
{ return m_CoreEngineFuncTable; }
inline NEW_DLL_FUNCTIONS &GetNewDllFuncTable()
{ return m_CoreNewDllFuncTable; }
// Get const
inline const DLL_FUNCTIONS &GetDllFuncTable() const
{ return m_CoreDllFuncTable; }
inline const enginefuncs_t &GetEngineFuncTable() const
{ return m_CoreEngineFuncTable; }
inline const NEW_DLL_FUNCTIONS &GetNewDllFuncTable() const
{ return m_CoreNewDllFuncTable; }
// Get post
inline DLL_FUNCTIONS &GetDllFuncTable_Post()
{ return m_CoreDllFuncTable_Post; }
inline enginefuncs_t &GetEngineFuncTable_Post()
{ return m_CoreEngineFuncTable_Post; }
inline NEW_DLL_FUNCTIONS &GetNewDllFuncTable_Post()
{ return m_CoreNewDllFuncTable_Post; }
// Get post const
inline const DLL_FUNCTIONS &GetDllFuncTable_Post() const
{ return m_CoreDllFuncTable_Post; }
inline const enginefuncs_t &GetEngineFuncTable_Post() const
{ return m_CoreEngineFuncTable_Post; }
inline const NEW_DLL_FUNCTIONS &GetNewDllFuncTable_Post() const
{ return m_CoreNewDllFuncTable_Post; } */
}; // CFakeMeta
// Fake Metamod
// defined in meta_api.cpp
extern CFakeMeta g_FakeMeta;
#endif //FAKEMETA
#endif // #ifndef __FAKEMETA_H__

File diff suppressed because it is too large Load Diff

434
amxmodx/format.cpp Normal file
View File

@ -0,0 +1,434 @@
#include "amxmodx.h"
#include "format.h"
//Adapted from Quake3's vsprintf
// thanks to cybermind for linking me to this :)
//I made the following changes:
// - Fixed spacing to be AMX Mod X standard
// - Added 'n' support, no buffer overflows
// - Templatized input/output buffers
#define ALT 0x00000001 /* alternate form */
#define HEXPREFIX 0x00000002 /* add 0x or 0X prefix */
#define LADJUST 0x00000004 /* left adjustment */
#define LONGDBL 0x00000008 /* long double */
#define LONGINT 0x00000010 /* long integer */
#define QUADINT 0x00000020 /* quad integer */
#define SHORTINT 0x00000040 /* short integer */
#define ZEROPAD 0x00000080 /* zero (as opposed to blank) pad */
#define FPT 0x00000100 /* floating point number */
#define to_digit(c) ((c) - '0')
#define is_digit(c) ((unsigned)to_digit(c) <= 9)
#define to_char(n) ((n) + '0')
#define CHECK_ARGS(n) \
if ((arg+n) > args) { \
LogError(amx, AMX_ERR_PARAMS, "String formatted incorrectly - parameter %d (total %d)", arg, args); \
return 0; \
}
THash<String, lang_err> BadLang_Table;
static cvar_t *amx_mldebug = NULL;
static cvar_t *amx_cl_langs = NULL;
const char *translate(AMX *amx, cell amxaddr, const char *key)
{
const char *pLangName = NULL;
const char *def = NULL;
int status;
cell *addr = get_amxaddr(amx, amxaddr);
char name[4];
if (addr[0] == LANG_PLAYER)
{
if (!amx_cl_langs)
amx_cl_langs = CVAR_GET_POINTER("amx_client_languages");
if ( (int)amx_cl_langs->value == 0 )
{
pLangName = g_vault.get("server_language");
} else {
pLangName = ENTITY_KEYVALUE(GET_PLAYER_POINTER_I(g_langMngr.GetDefLang())->pEdict, "lang");
}
} else if (addr[0] == LANG_SERVER) {
pLangName = g_vault.get("server_language");
} else if (addr[0] >= 1 && addr[0] <= gpGlobals->maxClients) {
if (!amx_cl_langs)
amx_cl_langs = CVAR_GET_POINTER("amx_client_languages");
if ( (int)amx_cl_langs->value == 0 )
{
pLangName = g_vault.get("server_language");
} else {
pLangName = ENTITY_KEYVALUE(GET_PLAYER_POINTER_I(addr[0])->pEdict, "lang");
}
} else {
get_amxstring_r(amx, amxaddr, name, 3);
pLangName = name;
}
if (!pLangName || !isalpha(pLangName[0]))
pLangName = "en";
//next parameter!
def = g_langMngr.GetDef(pLangName, key, status);
if (!amx_mldebug)
amx_mldebug = CVAR_GET_POINTER("amx_mldebug");
bool debug = (amx_mldebug && amx_mldebug->string && (amx_mldebug->string[0] != '\0'));
if (debug)
{
int debug_status;
bool validlang = true;
const char *testlang = amx_mldebug->string;
if (!g_langMngr.LangExists(testlang))
{
AMXXLOG_Error("[AMXX] \"%s\" is an invalid debug language", testlang);
validlang = false;
}
g_langMngr.GetDef(testlang, key, debug_status);
if (validlang && debug_status == ERR_BADKEY)
AMXXLOG_Error("[AMXX] Language key \"%s\" not found for language \"%s\", check \"%s\"", key, testlang, GetFileName(amx));
}
if (def == NULL)
{
if (debug)
{
if (status == ERR_BADLANG && (BadLang_Table.AltFindOrInsert(pLangName).last + 120.0f < gpGlobals->time))
{
AMXXLOG_Error("[AMXX] Language \"%s\" not found", pLangName);
BadLang_Table.AltFindOrInsert(pLangName).last = gpGlobals->time;
}
}
if (addr[0] != LANG_SERVER)
def = g_langMngr.GetDef(g_vault.get("server_language"), key, status);
if (!def && (strcmp(pLangName, "en") != 0 && strcmp(g_vault.get("server_language"), "en") != 0))
def = g_langMngr.GetDef("en", key, status);
}
return def;
}
template <typename U>
void AddString(U **buf_p, size_t &maxlen, const cell *string, int width, int prec)
{
int size = 0;
U *buf;
static cell nlstr[] = {'(','n','u','l','l',')','\0'};
buf = *buf_p;
if (string == NULL)
{
string = nlstr;
prec = -1;
}
if (prec >= 0)
{
for (size = 0; size < prec; size++)
{
if (string[size] == '\0')
break;
}
} else {
while (string[size++]) ;
size--;
}
if (size > (int)maxlen)
size = maxlen;
maxlen -= size;
width -= size;
while (size--)
*buf++ = static_cast<U>(*string++);
while (width-- > 0 && maxlen)
{
*buf++ = ' ';
maxlen--;
}
*buf_p = buf;
}
template <typename U>
void AddFloat(U **buf_p, size_t &maxlen, double fval, int width, int prec)
{
U text[32];
int digits;
double signedVal;
U *buf;
int val;
// get the sign
signedVal = fval;
if (fval < 0)
fval = -fval;
// write the float number
digits = 0;
val = (int)fval;
do {
text[digits++] = '0' + val % 10;
val /= 10;
} while (val);
if (signedVal < 0)
text[digits++] = '-';
buf = *buf_p;
while (digits < width && maxlen)
{
*buf++ = ' ';
width--;
maxlen--;
}
while (digits-- && maxlen)
{
*buf++ = text[digits];
maxlen--;
}
*buf_p = buf;
if (prec < 0)
prec = 6;
// write the fraction
digits = 0;
while (digits < prec)
{
fval -= (int) fval;
fval *= 10.0;
val = (int) fval;
text[digits++] = '0' + val % 10;
}
if (digits > 0 && maxlen)
{
buf = *buf_p;
*buf++ = '.';
maxlen--;
for (prec = 0; maxlen && prec < digits; prec++)
{
*buf++ = text[prec];
maxlen--;
}
*buf_p = buf;
}
}
template <typename U>
void AddInt(U **buf_p, size_t &maxlen, int val, int width, int flags)
{
U text[32];
int digits;
int signedVal;
U *buf;
digits = 0;
signedVal = val;
if (val < 0)
val = -val;
do {
text[digits++] = '0' + val % 10;
val /= 10;
} while (val);
if (signedVal < 0)
text[digits++] = '-';
buf = *buf_p;
if( !(flags & LADJUST) )
{
while (digits < width && maxlen)
{
*buf++ = (flags & ZEROPAD) ? '0' : ' ';
width--;
maxlen--;
}
}
while (digits-- && maxlen)
{
*buf++ = text[digits];
width--;
maxlen--;
}
if (flags & LADJUST)
{
while (width-- && maxlen)
{
*buf++ = (flags & ZEROPAD) ? '0' : ' ';
maxlen--;
}
}
*buf_p = buf;
}
template <typename D, typename S>
size_t atcprintf(D *buffer, size_t maxlen, const S *format, AMX *amx, cell *params, int *param)
{
int arg;
int args = params[0] / sizeof(cell);
D *buf_p;
D ch;
int flags;
int width;
int prec;
int n;
char sign;
const S *fmt;
size_t llen = maxlen;
buf_p = buffer;
arg = *param;
fmt = format;
while (true)
{
// run through the format string until we hit a '%' or '\0'
for (ch = static_cast<D>(*fmt);
llen && ((ch = static_cast<D>(*fmt)) != '\0' && ch != '%');
fmt++)
{
*buf_p++ = static_cast<D>(ch);
llen--;
}
if (ch == '\0' || llen <= 0)
goto done;
// skip over the '%'
fmt++;
// reset formatting state
flags = 0;
width = 0;
prec = -1;
sign = '\0';
rflag:
ch = static_cast<D>(*fmt++);
reswitch:
switch(ch)
{
case '-':
flags |= LADJUST;
goto rflag;
case '.':
n = 0;
while( is_digit( ( ch = static_cast<D>(*fmt++)) ) )
n = 10 * n + ( ch - '0' );
prec = n < 0 ? -1 : n;
goto reswitch;
case '0':
flags |= ZEROPAD;
goto rflag;
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
n = 0;
do {
n = 10 * n + ( ch - '0' );
ch = static_cast<D>(*fmt++);
} while( is_digit( ch ) );
width = n;
goto reswitch;
case 'c':
CHECK_ARGS(0);
*buf_p++ = static_cast<D>(*get_amxaddr(amx, params[arg]));
arg++;
break;
case 'd':
case 'i':
CHECK_ARGS(0);
AddInt(&buf_p, llen, *get_amxaddr(amx, params[arg]), width, flags);
arg++;
break;
case 'f':
CHECK_ARGS(0);
AddFloat(&buf_p, llen, amx_ctof(*get_amxaddr(amx, params[arg])), width, prec);
arg++;
break;
case 's':
CHECK_ARGS(0);
AddString(&buf_p, llen, get_amxaddr(amx, params[arg]), width, prec);
arg++;
break;
case 'L':
{
CHECK_ARGS(1);
cell addr = params[arg++];
int len;
const char *key = get_amxstring(amx, params[arg++], 3, len);
const char *def = translate(amx, addr, key);
if (!def)
{
static char buf[255];
snprintf(buf, sizeof(buf)-1, "ML_NOTFOUND: %s", key);
def = buf;
}
size_t written = atcprintf(buf_p, llen, def, amx, params, &arg);
buf_p += written;
llen -= written;
break;
}
case '%':
*buf_p++ = static_cast<D>(ch);
if (!llen)
goto done;
llen--;
break;
case '\0':
*buf_p++ = static_cast<D>('%');
if (!llen)
goto done;
llen--;
goto done;
break;
default:
*buf_p++ = static_cast<D>(ch);
if (!llen)
goto done;
llen--;
break;
}
}
done:
*buf_p = static_cast<D>(0);
*param = arg;
return maxlen-llen;
}
/**
* HACKHACK: The compiler will generate code for each case we need.
* Don't remove this, otherwise files that use certain code generations
* will have extern problems. For each case you need, add dummy code
* here.
*/
void __WHOA_DONT_CALL_ME_PLZ_K_lol_o_O()
{
//acsprintf
atcprintf((cell *)NULL, 0, (const char *)NULL, NULL, NULL, NULL);
//accprintf
atcprintf((cell *)NULL, 0, (cell *)NULL, NULL, NULL, NULL);
//ascprintf
atcprintf((char *)NULL, 0, (cell *)NULL, NULL, NULL, NULL);
}

8
amxmodx/format.h Normal file
View File

@ -0,0 +1,8 @@
#ifndef _INCLUDE_FORMATTING_H
#define _INCLUDE_FORMATTING_H
//Amx Templatized Cell Printf
template <typename D, typename S>
size_t atcprintf(D *buffer, size_t maxlen, const S *format, AMX *amx, cell *params, int *param);
#endif //_INCLUDE_FORMATTING_H

51
amxmodx/helpers-x86.asm Normal file
View File

@ -0,0 +1,51 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; (C)2006 by David "BAILOPAN" Anderson ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;Licensed under the GNU General Public License, version 2
;;This is a portion of AMX Mod X
;; and is maintained by the AMX Mod X development team.
section .text
global amxx_CpuSupport, _amxx_CpuSupport
amxx_CpuSupport:
_amxx_CpuSupport:
push ebp
mov ebp, esp
push ebx
mov eax, 0
cpuid
cmp eax, 1
jl .fail
mov eax, 1
cpuid
;check if family == 5 or 4
and eax, 0780h ;family mask
shr eax, 7 ;family shift
cmp eax, 5
je .fail
cmp eax, 4
je .fail
;check if CMOV exists
shr edx, 15
and edx, 1
cmp edx, 0
je .fail
mov eax, 1
jmp .end
.fail:
xor eax, eax
.end
pop ebx
pop ebp
ret

243
amxmodx/libraries.cpp Normal file
View File

@ -0,0 +1,243 @@
#include "libraries.h"
#include "sh_list.h"
List<Library *> g_libraries;
bool AddLibrary(const char *name, LibType type, LibSource src, void *parent)
{
if (FindLibrary(name, type))
return false;
Library *lib = new Library;
lib->name.assign(name);
lib->type = type;
lib->src = src;
lib->parent = parent;
g_libraries.push_back(lib);
return true;
}
bool DecodeLibCmdString(const char *str, LibDecoder *dec)
{
if (dec->buffer)
{
free(dec->buffer);
dec->buffer = NULL;
}
if (str[0] != '?')
{
return false;
} else {
str++;
if (*str == 'r')
{
str++;
if (*str == 'c')
dec->cmd = LibCmd_ReqClass;
else if (*str == 'l')
dec->cmd = LibCmd_ReqLib;
else
return false;
str++;
} else if (*str == 'f') {
str++;
dec->cmd = LibCmd_ForceLib;
} else if (*str == 'e') {
str++;
if (*str == 'c')
dec->cmd = LibCmd_ExpectClass;
else if (*str == 'l')
dec->cmd = LibCmd_ExpectLib;
else
return false;
str++;
} else if (*str == 'd') {
str++;
dec->cmd = LibCmd_DefaultLib;
}
if (*str != '_')
return false;
str++;
if (dec->cmd < LibCmd_ExpectLib)
{
dec->buffer = strdup(str);
dec->param1 = dec->buffer;
dec->param2 = NULL;
} else {
dec->buffer = strdup(str);
char *p = strchr(dec->buffer, '_');
while (p && (*(p+1) == '_'))
p = strchr(p+2, '_');
if (!p || !*(p+1))
return false;
*p = '\0';
dec->param1 = dec->buffer;
dec->param2 = p+1;
}
}
return true;
}
size_t AddLibrariesFromString(const char *name, LibType type, LibSource src, void *parent)
{
char buffer[255];
char *ptr, *p, s;
size_t count = 0;
snprintf(buffer, sizeof(buffer)-1, "%s", name);
ptr = buffer;
p = buffer;
while (*p)
{
while (*p && (*p != ','))
p++;
s = *p;
*p = '\0';
if (AddLibrary(ptr, type, src, parent))
count++;
if (!s)
break;
p++;
while (*p && (*p == ','))
p++;
ptr = p;
}
return count;
}
size_t ClearLibraries(LibSource src)
{
List<Library *>::iterator iter;
size_t count = 0;
iter = g_libraries.begin();
while (iter != g_libraries.end())
{
if ( (*iter)->src == src )
{
delete (*iter);
iter = g_libraries.erase(iter);
count++;
} else {
iter++;
}
}
return count;
}
size_t RemoveLibraries(void *parent)
{
List<Library *>::iterator iter;
Library *lib;
size_t count = 0;
iter = g_libraries.begin();
while (iter != g_libraries.end())
{
lib = (*iter);
if (lib->parent == parent)
{
delete (*iter);
iter = g_libraries.erase(iter);
count++;
} else {
iter++;
}
}
return count;
}
bool FindLibrary(const char *name, LibType type)
{
List<Library *>::iterator iter;
Library *lib;
for (iter = g_libraries.begin(); iter != g_libraries.end(); iter++)
{
lib = (*iter);
if (lib->type != type)
continue;
if (strcasecmp(lib->name.c_str(), name) == 0)
{
return true;
}
}
return false;
}
LibError RunLibCommand(const LibDecoder *enc)
{
List<Library *>::iterator iter,end;
Library *lib;
iter = g_libraries.begin();
end = g_libraries.end();
if ( (enc->cmd == LibCmd_ReqLib) || (enc->cmd == LibCmd_ReqClass) )
{
LibType expect;
if (enc->cmd == LibCmd_ReqLib)
expect = LibType_Library;
else if (enc->cmd == LibCmd_ReqClass)
expect = LibType_Class;
/** see if it exists */
for (; iter != end; iter++)
{
lib = (*iter);
if (lib->type != expect)
continue;
if (strcasecmp(lib->name.c_str(), enc->param1) == 0)
return LibErr_None;
}
if (expect == LibType_Library)
return LibErr_NoLibrary;
else if (expect = LibType_Class)
return LibErr_NoClass;
return LibErr_NoLibrary;
} else if (enc->cmd == LibCmd_ForceLib) {
if (!LoadModule(enc->param1, PT_ANYTIME, true, true))
{
return LibErr_NoLibrary;
}
} else if ( (enc->cmd == LibCmd_DefaultLib) ||
((enc->cmd == LibCmd_ExpectLib) || (enc->cmd == LibCmd_ExpectClass)) )
{
LibType expect;
if (enc->cmd == LibCmd_ExpectLib)
expect = LibType_Library;
else
expect = LibType_Class;
/** see if it exists */
for (; iter != end; iter++)
{
lib = (*iter);
if (lib->type != expect)
continue;
if (strcasecmp(lib->name.c_str(), enc->param1) == 0)
return LibErr_None;
}
if (!LoadModule(enc->param2, PT_ANYTIME, true, true))
{
return LibErr_NoLibrary;
}
return LibErr_None;
}
return LibErr_None;
}

73
amxmodx/libraries.h Normal file
View File

@ -0,0 +1,73 @@
#ifndef _INCLUDE_LIBRARIES_H
#define _INCLUDE_LIBRARIES_H
#include <string.h>
#include "amxmodx.h"
#include "CString.h"
enum LibSource
{
LibSource_Plugin,
LibSource_Module
};
enum LibType
{
LibType_Library,
LibType_Class
};
struct Library
{
String name;
LibSource src;
LibType type;
void *parent;
};
enum LibCmd
{
LibCmd_ReqLib,
LibCmd_ReqClass,
LibCmd_ForceLib,
LibCmd_ExpectLib,
LibCmd_ExpectClass,
LibCmd_DefaultLib,
};
enum LibError
{
LibErr_None = 0,
LibErr_NoLibrary,
LibErr_NoClass,
};
class LibDecoder
{
public:
LibDecoder() : buffer(NULL)
{
}
~LibDecoder()
{
free(buffer);
buffer = NULL;
param1 = NULL;
param2 = NULL;
}
char *buffer;
char *param1;
char *param2;
LibCmd cmd;
};
bool AddLibrary(const char *name, LibType type, LibSource src, void *parent=NULL);
bool DecodeLibCmdString(const char *str, LibDecoder *cmd);
size_t AddLibrariesFromString(const char *name, LibType type, LibSource src, void *parent=NULL);
size_t ClearLibraries(LibSource src);
LibError RunLibCommand(const LibDecoder *enc);
size_t RemoveLibraries(void *parent);
bool FindLibrary(const char *name, LibType type);
#endif //_INCLUDE_LIBRARIES_H

805
amxmodx/messages.cpp Executable file
View File

@ -0,0 +1,805 @@
#include "amxmodx.h"
#include "messages.h"
Message Msg;
CVector<int> msgHooks[256];
int msgBlocks[256] = {BLOCK_NOT};
int msgDest;
int msgType;
float *msgOrigin;
edict_t *msgpEntity;
bool inhook = false;
bool inblock = false;
enginefuncs_t *g_pEngTable = NULL;
void ClearMessages()
{
for (size_t i=0; i<MAX_MESSAGES; i++)
{
msgHooks[i].clear();
msgBlocks[i] = BLOCK_NOT;
}
}
Message::Message()
{
m_CurParam = 0;
}
bool Message::Ready()
{
if (!m_Params.size())
return false;
return true;
}
void Message::Init()
{
if (!Ready())
{
msgparam *p = new msgparam;
m_Params.push_back(p);
}
m_CurParam = 0;
}
Message::~Message()
{
for (size_t i=0; i<m_Params.size(); i++)
delete m_Params[i];
m_Params.clear();
}
msgparam *Message::AdvPtr()
{
msgparam *pParam = NULL;
if (++m_CurParam >= m_Params.size())
{
pParam = new msgparam;
m_Params.push_back(pParam);
} else {
pParam = m_Params[m_CurParam];
}
return pParam;
}
void Message::AddParam(const char *data, msgtype type)
{
msgparam *pParam = AdvPtr();
pParam->szData.assign(data);
pParam->type = type;
}
void Message::AddParam(int data, msgtype type)
{
msgparam *pParam = AdvPtr();
pParam->v.iData = data;
pParam->type = type;
}
void Message::AddParam(float data, msgtype type)
{
msgparam *pParam = AdvPtr();
pParam->v.fData = data;
pParam->type = type;
}
msgtype Message::GetParamType(size_t index)
{
if (index < 1 || index > m_CurParam)
return static_cast<msgtype>(0);
return m_Params[index]->type;
}
float Message::GetParamFloat(size_t index)
{
if (index < 1 || index > m_CurParam)
return 0;
return m_Params[index]->v.fData;
}
const char *Message::GetParamString(size_t index)
{
if (index < 1 || index > m_CurParam)
return 0;
return m_Params[index]->szData.c_str();
}
int Message::GetParamInt(size_t index)
{
if (index < 1 || index > m_CurParam)
return 0;
return m_Params[index]->v.iData;
}
void Message::SetParam(size_t index, float data)
{
if (index < 1 || index > m_CurParam)
return;
m_Params[index]->v.fData = data;
}
void Message::SetParam(size_t index, int data)
{
if (index < 1 || index > m_CurParam)
return;
m_Params[index]->v.iData = data;
}
void Message::SetParam(size_t index, const char *data)
{
if (index < 1 || index > m_CurParam)
return;
m_Params[index]->szData.assign(data);
}
void Message::Reset()
{
m_CurParam = 0;
}
size_t Message::Params()
{
return m_CurParam;
}
void Message::Send()
{
msgparam *pParam = NULL;
for (size_t i=1; i<=m_CurParam; i++)
{
pParam = m_Params[i];
switch (pParam->type)
{
case arg_byte:
WRITE_BYTE(pParam->v.iData);
break;
case arg_char:
WRITE_CHAR(pParam->v.iData);
break;
case arg_short:
WRITE_SHORT(pParam->v.iData);
break;
case arg_long:
WRITE_LONG(pParam->v.iData);
break;
case arg_angle:
WRITE_ANGLE(pParam->v.fData);
break;
case arg_coord:
WRITE_COORD(pParam->v.fData);
break;
case arg_string:
WRITE_STRING(pParam->szData.c_str());
break;
case arg_entity:
WRITE_ENTITY(pParam->v.iData);
break;
}
}
}
void C_MessageBegin(int msg_dest, int msg_type, const float *pOrigin, edict_t *ed)
{
if (msgBlocks[msg_type])
{
inblock = true;
msgType = msg_type;
RETURN_META(MRES_SUPERCEDE);
} else if (msgHooks[msg_type].size()) {
inhook = true;
msgDest = msg_dest;
msgType = msg_type;
msgOrigin = (float *)pOrigin;
msgpEntity = ed;
RETURN_META(MRES_SUPERCEDE);
}
RETURN_META(MRES_IGNORED);
}
void C_WriteByte(int iValue)
{
if (inblock)
{
RETURN_META(MRES_SUPERCEDE);
} else if (inhook) {
Msg.AddParam(iValue, arg_byte);
RETURN_META(MRES_SUPERCEDE);
}
RETURN_META(MRES_IGNORED);
}
void C_WriteChar(int iValue)
{
if (inblock)
{
RETURN_META(MRES_SUPERCEDE);
} else if (inhook) {
Msg.AddParam(iValue, arg_char);
RETURN_META(MRES_SUPERCEDE);
}
RETURN_META(MRES_IGNORED);
}
void C_WriteShort(int iValue)
{
if (inblock)
{
RETURN_META(MRES_SUPERCEDE);
} else if (inhook) {
Msg.AddParam(iValue, arg_short);
RETURN_META(MRES_SUPERCEDE);
}
RETURN_META(MRES_IGNORED);
}
void C_WriteLong(int iValue)
{
if (inblock)
{
RETURN_META(MRES_SUPERCEDE);
} else if (inhook) {
Msg.AddParam(iValue, arg_long);
RETURN_META(MRES_SUPERCEDE);
}
RETURN_META(MRES_IGNORED);
}
void C_WriteAngle(float flValue)
{
if (inblock)
{
RETURN_META(MRES_SUPERCEDE);
} else if (inhook) {
Msg.AddParam(flValue, arg_angle);
RETURN_META(MRES_SUPERCEDE);
}
RETURN_META(MRES_IGNORED);
}
void C_WriteCoord(float flValue)
{
if (inblock)
{
RETURN_META(MRES_SUPERCEDE);
} else if (inhook) {
Msg.AddParam(flValue, arg_coord);
RETURN_META(MRES_SUPERCEDE);
}
RETURN_META(MRES_IGNORED);
}
void C_WriteString(const char *sz)
{
if (inblock)
{
RETURN_META(MRES_SUPERCEDE);
} else if (inhook) {
Msg.AddParam(sz, arg_string);
RETURN_META(MRES_SUPERCEDE);
}
RETURN_META(MRES_IGNORED);
}
void C_WriteEntity(int iValue)
{
if (inblock)
{
RETURN_META(MRES_SUPERCEDE);
} else if (inhook) {
Msg.AddParam(iValue, arg_entity);
RETURN_META(MRES_SUPERCEDE);
}
RETURN_META(MRES_IGNORED);
}
void C_MessageEnd(void)
{
int mres = 0, mresB = 0;
unsigned int i = 0;
if (inblock)
{
inblock = false;
if (msgBlocks[msgType] == BLOCK_ONCE)
{
msgBlocks[msgType] = BLOCK_NOT;
}
RETURN_META(MRES_SUPERCEDE);
} else if (inhook) {
for (i=0; i<msgHooks[msgType].size(); i++)
{
mresB = executeForwards(msgHooks[msgType].at(i), (cell)msgType, (cell)msgDest, (cell)ENTINDEX(msgpEntity));
if (mresB > mres)
mres = mresB;
}
inhook = false;
if (mres & 1)
{
Msg.Reset();
RETURN_META(MRES_SUPERCEDE);
}
/* send the real message */
MESSAGE_BEGIN(msgDest, msgType, msgOrigin, msgpEntity);
Msg.Send();
MESSAGE_END();
/* reset */
Msg.Reset();
RETURN_META(MRES_SUPERCEDE);
}
RETURN_META(MRES_IGNORED);
}
static cell AMX_NATIVE_CALL message_begin(AMX *amx, cell *params) /* 4 param */
{
int numparam = *params / sizeof(cell);
float vecOrigin[3];
cell *cpOrigin;
if (params[2] < 1 || ((params[2] > 63) // maximal number of engine messages
&& !GET_USER_MSG_NAME(PLID, params[2], NULL)))
{
LogError(amx, AMX_ERR_NATIVE, "Plugin called message_begin with an invalid message id (%d).", params[2]);
return 0;
}
switch (params[1])
{
case MSG_BROADCAST:
case MSG_ALL:
case MSG_SPEC:
MESSAGE_BEGIN(params[1], params[2], NULL);
break;
case MSG_PVS: case MSG_PAS:
case MSG_PVS_R: case MSG_PAS_R:
if (numparam < 3)
{
LogError(amx, AMX_ERR_NATIVE, "Invalid number of parameters passed");
return 0;
}
cpOrigin = get_amxaddr(amx, params[3]);
vecOrigin[0] = static_cast<float>(*cpOrigin);
vecOrigin[1] = static_cast<float>(*(cpOrigin + 1));
vecOrigin[2] = static_cast<float>(*(cpOrigin + 2));
MESSAGE_BEGIN(params[1], params[2], vecOrigin);
break;
case MSG_ONE_UNRELIABLE:
case MSG_ONE:
if (numparam < 4)
{
LogError(amx, AMX_ERR_NATIVE, "Invalid number of parameters passed");
return 0;
}
MESSAGE_BEGIN(params[1], params[2], NULL, INDEXENT(params[4]));
break;
}
return 1;
}
static cell AMX_NATIVE_CALL message_end(AMX *amx, cell *params)
{
MESSAGE_END();
return 1;
}
static cell AMX_NATIVE_CALL write_byte(AMX *amx, cell *params) /* 1 param */
{
WRITE_BYTE(params[1]);
return 1;
}
static cell AMX_NATIVE_CALL write_char(AMX *amx, cell *params) /* 1 param */
{
WRITE_CHAR(params[1]);
return 1;
}
static cell AMX_NATIVE_CALL write_short(AMX *amx, cell *params) /* 1 param */
{
WRITE_SHORT(params[1]);
return 1;
}
static cell AMX_NATIVE_CALL write_long(AMX *amx, cell *params) /* 1 param */
{
WRITE_LONG(params[1]);
return 1;
}
static cell AMX_NATIVE_CALL write_entity(AMX *amx, cell *params) /* 1 param */
{
WRITE_ENTITY(params[1]);
return 1;
}
static cell AMX_NATIVE_CALL write_angle(AMX *amx, cell *params) /* 1 param */
{
WRITE_ANGLE(static_cast<float>(params[1]));
return 1;
}
static cell AMX_NATIVE_CALL write_coord(AMX *amx, cell *params) /* 1 param */
{
WRITE_COORD(static_cast<float>(params[1]));
return 1;
}
static cell AMX_NATIVE_CALL write_string(AMX *amx, cell *params) /* 1 param */
{
int a;
WRITE_STRING(get_amxstring(amx, params[1], 3, a));
return 1;
}
static cell AMX_NATIVE_CALL register_message(AMX *amx, cell *params)
{
int len;
char *name = get_amxstring(amx, params[2], 0, len);
if (!Msg.Ready())
Msg.Init();
if (params[1]>0 && params[1] < 256)
{
int id = registerSPForwardByName(amx, name, FP_CELL, FP_CELL, FP_CELL, FP_CELL, FP_DONE);
if (id != -1)
{
msgHooks[params[1]].push_back(id);
return id;
} else {
LogError(amx, AMX_ERR_NOTFOUND, "Could not find function \"%s\"", name);
return -1;
}
}
return 0;
}
static cell AMX_NATIVE_CALL set_msg_block(AMX *amx, cell *params)
{
int msgid = params[1];
int block = params[2];
if (msgid < 1 || msgid > 255)
{
LogError(amx, AMX_ERR_NATIVE, "Invalid message id");
return 0;
}
msgBlocks[msgid] = block;
return 1;
}
static cell AMX_NATIVE_CALL get_msg_block(AMX *amx, cell *params)
{
int msgid = params[1];
if (msgid < 1 || msgid > 255)
{
LogError(amx, AMX_ERR_NATIVE, "Invalid message id");
return 0;
}
return msgBlocks[msgid];
}
static cell AMX_NATIVE_CALL get_msg_args(AMX *amx, cell *params)
{
return Msg.Params();
}
static cell AMX_NATIVE_CALL get_msg_argtype(AMX *amx, cell *params)
{
size_t argn = static_cast<size_t>(params[1]);
if (!inhook || argn > Msg.Params())
{
LogError(amx, AMX_ERR_NATIVE, "Invalid message argument %d", argn);
return 0;
}
return Msg.GetParamType(argn);
}
static cell AMX_NATIVE_CALL get_msg_arg_int(AMX *amx, cell *params)
{
size_t argn = static_cast<size_t>(params[1]);
if (!inhook || argn > Msg.Params())
{
LogError(amx, AMX_ERR_NATIVE, "Invalid message argument %d", argn);
return 0;
}
return Msg.GetParamInt(argn);
}
static cell AMX_NATIVE_CALL set_msg_arg_int(AMX *amx, cell *params)
{
size_t argn = static_cast<size_t>(params[1]);
if (!inhook || argn > Msg.Params())
{
LogError(amx, AMX_ERR_NATIVE, "Invalid message argument %d", argn);
return 0;
}
Msg.SetParam(argn, (int)params[3]);
return 1;
}
static cell AMX_NATIVE_CALL get_msg_arg_float(AMX *amx, cell *params)
{
size_t argn = static_cast<size_t>(params[1]);
if (!inhook || argn > Msg.Params())
{
LogError(amx, AMX_ERR_NATIVE, "Invalid message argument %d", argn);
return 0;
}
REAL f = (REAL)Msg.GetParamFloat(argn);
return amx_ftoc(f);
}
static cell AMX_NATIVE_CALL set_msg_arg_float(AMX *amx, cell *params)
{
size_t argn = static_cast<size_t>(params[1]);
if (!inhook || argn > Msg.Params())
{
LogError(amx, AMX_ERR_NATIVE, "Invalid message argument %d", argn);
return 0;
}
REAL fVal = amx_ctof(params[3]);
Msg.SetParam(argn, (float)fVal);
return 1;
}
static cell AMX_NATIVE_CALL get_msg_arg_string(AMX *amx, cell *params)
{
size_t argn = static_cast<size_t>(params[1]);
if (!inhook || argn > Msg.Params())
{
LogError(amx, AMX_ERR_NATIVE, "Invalid message argument %d", argn);
return 0;
}
const char *szVal = Msg.GetParamString(argn);
return set_amxstring(amx, params[2], szVal, params[3]);
}
static cell AMX_NATIVE_CALL set_msg_arg_string(AMX *amx, cell *params)
{
size_t argn = static_cast<size_t>(params[1]);
int iLen;
if (!inhook || argn > Msg.Params())
{
LogError(amx, AMX_ERR_NATIVE, "Invalid message argument %d", argn);
return 0;
}
char *szVal = get_amxstring(amx, params[2], 0, iLen);
Msg.SetParam(argn, szVal);
return 1;
}
static cell AMX_NATIVE_CALL get_msg_origin(AMX *amx, cell *params)
{
if (!inhook)
{
LogError(amx, AMX_ERR_NATIVE, "Not in a message hook");
return 0;
}
cell *cAddr = get_amxaddr(amx, params[1]);
if (msgDest >= MSG_PVS && msgDest <= MSG_PAS_R)
{
vec3_t vRet = (Vector)msgOrigin;
cAddr[0] = FloatToCell(vRet.x);
cAddr[1] = FloatToCell(vRet.y);
cAddr[2] = FloatToCell(vRet.z);
} else {
cAddr[0] = 0;
cAddr[1] = 0;
cAddr[2] = 0;
}
return 1;
}
static cell AMX_NATIVE_CALL emessage_begin(AMX *amx, cell *params) /* 4 param */
{
int numparam = *params / sizeof(cell);
float vecOrigin[3];
cell *cpOrigin;
if (params[2] < 1 || ((params[2] > 63) // maximal number of engine messages
&& !GET_USER_MSG_NAME(PLID, params[2], NULL)))
{
LogError(amx, AMX_ERR_NATIVE, "Plugin called message_begin with an invalid message id (%d).", params[2]);
return 0;
}
switch (params[1])
{
case MSG_BROADCAST:
case MSG_ALL:
case MSG_SPEC:
g_pEngTable->pfnMessageBegin(params[1], params[2], NULL, NULL);
break;
case MSG_PVS: case MSG_PAS:
case MSG_PVS_R: case MSG_PAS_R:
if (numparam < 3)
{
LogError(amx, AMX_ERR_NATIVE, "Invalid number of parameters passed");
return 0;
}
cpOrigin = get_amxaddr(amx, params[3]);
vecOrigin[0] = static_cast<float>(*cpOrigin);
vecOrigin[1] = static_cast<float>(*(cpOrigin + 1));
vecOrigin[2] = static_cast<float>(*(cpOrigin + 2));
g_pEngTable->pfnMessageBegin(params[1], params[2], vecOrigin, NULL);
break;
case MSG_ONE_UNRELIABLE:
case MSG_ONE:
if (numparam < 4)
{
LogError(amx, AMX_ERR_NATIVE, "Invalid number of parameters passed");
return 0;
}
g_pEngTable->pfnMessageBegin(params[1], params[2], NULL, INDEXENT(params[4]));
break;
}
return 1;
}
static cell AMX_NATIVE_CALL emessage_end(AMX *amx, cell *params)
{
g_pEngTable->pfnMessageEnd();
return 1;
}
static cell AMX_NATIVE_CALL ewrite_byte(AMX *amx, cell *params) /* 1 param */
{
g_pEngTable->pfnWriteByte(params[1]);
return 1;
}
static cell AMX_NATIVE_CALL ewrite_char(AMX *amx, cell *params) /* 1 param */
{
g_pEngTable->pfnWriteChar(params[1]);
return 1;
}
static cell AMX_NATIVE_CALL ewrite_short(AMX *amx, cell *params) /* 1 param */
{
g_pEngTable->pfnWriteShort(params[1]);
return 1;
}
static cell AMX_NATIVE_CALL ewrite_long(AMX *amx, cell *params) /* 1 param */
{
g_pEngTable->pfnWriteLong(params[1]);
return 1;
}
static cell AMX_NATIVE_CALL ewrite_entity(AMX *amx, cell *params) /* 1 param */
{
g_pEngTable->pfnWriteEntity(params[1]);
return 1;
}
static cell AMX_NATIVE_CALL ewrite_angle(AMX *amx, cell *params) /* 1 param */
{
g_pEngTable->pfnWriteAngle(static_cast<float>(params[1]));
return 1;
}
static cell AMX_NATIVE_CALL ewrite_coord(AMX *amx, cell *params) /* 1 param */
{
g_pEngTable->pfnWriteCoord(static_cast<float>(params[1]));
return 1;
}
static cell AMX_NATIVE_CALL ewrite_string(AMX *amx, cell *params) /* 1 param */
{
int a;
g_pEngTable->pfnWriteString(get_amxstring(amx, params[1], 3, a));
return 1;
}
AMX_NATIVE_INFO msg_Natives[] =
{
{"message_begin", message_begin},
{"message_end", message_end},
{"write_angle", write_angle},
{"write_byte", write_byte},
{"write_char", write_char},
{"write_coord", write_coord},
{"write_entity", write_entity},
{"write_long", write_long},
{"write_short", write_short},
{"write_string", write_string},
{"register_message", register_message},
{"set_msg_block", set_msg_block},
{"get_msg_block", get_msg_block},
{"get_msg_args", get_msg_args},
{"get_msg_argtype", get_msg_argtype},
{"get_msg_arg_int", get_msg_arg_int},
{"set_msg_arg_int", set_msg_arg_int},
{"get_msg_arg_float", get_msg_arg_float},
{"set_msg_arg_float", set_msg_arg_float},
{"get_msg_arg_string", get_msg_arg_string},
{"set_msg_arg_string", set_msg_arg_string},
{"get_msg_origin", get_msg_origin},
{"emessage_begin", emessage_begin},
{"emessage_end", emessage_end},
{"ewrite_angle", ewrite_angle},
{"ewrite_byte", ewrite_byte},
{"ewrite_char", ewrite_char},
{"ewrite_coord", ewrite_coord},
{"ewrite_entity", ewrite_entity},
{"ewrite_long", ewrite_long},
{"ewrite_short", ewrite_short},
{"ewrite_string", ewrite_string},
{NULL, NULL},
};

View File

@ -1,7 +1,11 @@
#ifndef _MSGS_INCLUDE_H
#define _MSGS_INCLUDE_H
#include "engine.h"
#include <extdll.h>
#include <meta_api.h>
#include "amx.h"
#include "CVector.h"
#include "CString.h"
#define MAX_MESSAGES 255
@ -59,9 +63,21 @@ private:
size_t m_CurParam;
};
extern AMX_NATIVE_INFO msg_Natives[];
void C_MessageBegin(int msg_dest, int msg_type, const float *pOrigin, edict_t *ed);
void C_WriteByte(int iValue);
void C_WriteChar(int iValue);
void C_WriteShort(int iValue);
void C_WriteLong(int iValue);
void C_WriteAngle(float flValue);
void C_WriteCoord(float flValue);
void C_WriteString(const char *sz);
void C_WriteEntity(int iValue);
void C_MessageEnd(void);
extern CVector<int> msgHooks[256];
extern int msgBlocks[256];
void ClearMessages();
#endif //_MSGS_INCLUDE_H

File diff suppressed because it is too large Load Diff

View File

@ -1,116 +0,0 @@
/*
* Copyright (c) 2004 Jussi Kivilinna
*
* This file is part of "Metamod All-Mod-Support"-patch for Metamod.
*
* Metamod is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* Metamod 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 Metamod; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* In addition, as a special exception, the author gives permission to
* link the code of this program with the Half-Life Game Engine ("HL
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
* L.L.C ("Valve"). You must obey the GNU General Public License in all
* respects for all of the code used other than the HL Engine and MODs
* from Valve. If you modify this file, you may extend this exception
* to your version of the file, but you are not obligated to do so. If
* you do not wish to do so, delete this exception statement from your
* version.
*
*/
#ifndef MM_PEXTENSIONS_H
#define MM_PEXTENSIONS_H
#include "plinfo.h" // plid_t
#include "meta_api.h" // PLUG_LOADTIME
/*
How to use:
1. Add new export function 'Meta_PExtGiveFnptrs' to your plugin file.
'Meta_PExtGiveFnptrs' will be called right after 'Meta_Query' call.
2. Meta_PExtGiveFnptrs is called with interface version 'META_PEXT_VERSION'
and pointer to extension function table.
3. Meta_PExtGiveFnptrs should return plugin's interface version.
4. !NOTE! Metamod will not stop loading plugin even if plugin returns
interface version greater than current. Plugin should disable itself in
this kind of situation.
Example:
#include "mm_pextensions.h"
pextension_funcs_t *gpMetaPExtFuncs;
int Meta_PExtGiveFnptrs(int interfaceVersion, pextension_funcs_t *pMetaPExtFuncs) {
if(interfaceVersion < META_PEXT_VERSION) {
LOG_DEVELOPER(PLID, "Error! Metamod is too old, please update!");
gpMetaPExtFuncs = NULL;
return(META_PEXT_VERSION);
}
gpMetaPExtFuncs = pMetaPExtFuncs;
return(META_PEXT_VERSION);
}
Callback functions:
- int PEXT_LOAD_PLUGIN_BY_NAME(PLID, const char *cmdline, PLUG_LOADTIME now, void **plugin_handle);
Parses 'cmdline' as metamod would parse 'meta load <cmdline>' and loads found
plugin. If 'plugin_handle' is set, metamod writes module handle of loaded
plugin at it.
Returns zero on success.
For error codes see 'META_ERRNO' in 'types_meta.h'.
- int PEXT_UNLOAD_PLUGIN_BY_NAME(PLID, const char *cmdline, PLUG_LOADTIME now, PL_UNLOAD_REASON reason);
Parses 'cmdline' as metamod would parse 'meta unload <cmdline>' and
unloads found plugin.
Returns zero on success.
For error codes see 'META_ERRNO' in 'types_meta.h'.
- int PEXT_UNLOAD_PLUGIN_BY_HANDLE(PLID, void *plugin_handle, PLUG_LOADTIME now, PL_UNLOAD_REASON reason);
Unloads plugin with 'plugin_handle'.
Returns zero on success.
For error codes see 'META_ERRNO' in 'types_meta.h'.
!NOTE! Plugin cannot unload itself!
*/
// Interface version
// 1: first version. Used in p13
// 2: Complete remake (p14):
// pfnLoadMetaPluginByName
// pfnUnloadMetaPluginByName
// pfnUnloadMetaPluginByHandle
// v2 is locked now. Don't modify old functions. If you add new functions, increase META_PEXT_VERSION.
#define META_PEXT_VERSION 2
// Meta PExtension Function table type.
typedef struct pextension_funcs_s {
int (*pfnLoadMetaPluginByName)(plid_t plid, const char *cmdline, PLUG_LOADTIME now, void **plugin_handle);
int (*pfnUnloadMetaPluginByName)(plid_t plid, const char *cmdline, PLUG_LOADTIME now, PL_UNLOAD_REASON reason);
int (*pfnUnloadMetaPluginByHandle)(plid_t plid, void *plugin_handle, PLUG_LOADTIME now, PL_UNLOAD_REASON reason);
} pextension_funcs_t;
// Convenience macros for MetaPExtension functions.
#define PEXT_LOAD_PLUGIN_BY_NAME (*gpMetaPExtFuncs->pfnLoadMetaPluginByName)
#define PEXT_UNLOAD_PLUGIN_BY_NAME (*gpMetaPExtFuncs->pfnUnloadMetaPluginByName)
#define PEXT_UNLOAD_PLUGIN_BY_HANDLE (*gpMetaPExtFuncs->pfnUnloadMetaPluginByHandle)
// Give plugin extension function table.
C_DLLEXPORT int Meta_PExtGiveFnptrs(int interfaceVersion,
pextension_funcs_t *pMetaPExtFuncs);
typedef int (*META_GIVE_PEXT_FUNCTIONS_FN) (int interfaceVersion,
pextension_funcs_t *pMetaPExtFuncs);
#endif /* MM_PEXTENSIONS_H */

File diff suppressed because it is too large Load Diff

View File

@ -48,6 +48,44 @@
#define RELOAD_MODULE 0
#define STATIC_MODULE 1
typedef enum
{
Player_Name, //String
Player_Ip, //String
Player_Team, //String
Player_Ingame, //bool
Player_Authorized, //bool
Player_Vgui, //bool
Player_Time, //float
Player_Playtime, //float
Player_MenuExpire, //float
Player_Weapons, //struct{int,int}[32]
Player_CurrentWeapon, //int
Player_TeamID, //int
Player_Deaths, //int
Player_Aiming, //int
Player_Menu, //int
Player_Keys, //int
Player_Flags, //int[32]
Player_Newmenu, //int
Player_NewmenuPage, //int
} PlayerProp;
int CheckModules(AMX *amx, char error[128]);
bool LoadModule(const char *shortname, PLUG_LOADTIME now, bool simplify=true, bool noFileBail=false);
const char *StrCaseStr(const char *as, const char *bs);
class Debugger;
Debugger *DisableDebugHandler(AMX *amx);
void EnableDebugHandler(AMX *amx, Debugger *pd);
bool DirExists(const char *dir);
const char* GetFileName(AMX *amx);
inline cell FloatToCell(float input)
{
REAL output = input;
return *(cell *)&output;
}
#endif // __MODULES_H__

View File

@ -1,6 +0,0 @@
LIBRARY amxx_mm
EXPORTS
GiveFnptrsToDll @1
SECTIONS
.data READ WRITE

View File

@ -5,32 +5,20 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "amxmodx", "amxmodx_mm.vcpro
EndProject
Global
GlobalSection(SolutionConfiguration) = preSolution
Debug = Debug
JITDebug = JITDebug
JITMemtestRelease = JITMemtestRelease
JITDebugBinLog = JITDebugBinLog
JITRelease = JITRelease
MaximalSpeed = MaximalSpeed
MemtestDebug = MemtestDebug
MemtestRelease = MemtestRelease
Release = Release
JITReleaseBinLog = JITReleaseBinLog
EndGlobalSection
GlobalSection(ProjectConfiguration) = postSolution
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.Debug.ActiveCfg = Debug|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.Debug.Build.0 = Debug|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITDebug.ActiveCfg = JITDebug|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITDebug.Build.0 = JITDebug|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITMemtestRelease.ActiveCfg = JITMemtestRelease|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITMemtestRelease.Build.0 = JITMemtestRelease|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITDebugBinLog.ActiveCfg = JITDebugBinLog|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITDebugBinLog.Build.0 = JITDebugBinLog|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITRelease.ActiveCfg = JITRelease|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITRelease.Build.0 = JITRelease|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.MaximalSpeed.ActiveCfg = MaximalSpeed|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.MaximalSpeed.Build.0 = MaximalSpeed|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.MemtestDebug.ActiveCfg = MemtestDebug|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.MemtestDebug.Build.0 = MemtestDebug|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.MemtestRelease.ActiveCfg = MemtestRelease|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.MemtestRelease.Build.0 = MemtestRelease|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.Release.ActiveCfg = Release|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.Release.Build.0 = Release|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITReleaseBinLog.ActiveCfg = JITReleaseBinLog|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITReleaseBinLog.Build.0 = JITReleaseBinLog|Win32
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
EndGlobalSection

View File

@ -4,6 +4,7 @@
Version="7.10"
Name="amxmodx"
ProjectGUID="{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}"
RootNamespace="amxmodx"
SccProjectName=""
SccLocalPath="">
<Platforms>
@ -11,283 +12,6 @@
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\Debug"
IntermediateDirectory=".\Debug"
ConfigurationType="2"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="&quot;C:\Hry\Half-Life\SDK\Multiplayer Source\pm_shared&quot;;&quot;C:\Hry\Half-Life\SDK\Multiplayer Source\dlls&quot;;&quot;C:\Hry\Half-Life\SDK\Multiplayer Source\engine&quot;;&quot;C:\Hry\Half-Life\SDK\Multiplayer Source\common&quot;;C:\Files\Programming\metamod\metamod"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS"
BasicRuntimeChecks="3"
RuntimeLibrary="5"
StructMemberAlignment="3"
UsePrecompiledHeader="2"
PrecompiledHeaderThrough="amxmodx.h"
PrecompiledHeaderFile=".\debug/amxmodx.pch"
AssemblerListingLocation=".\debug/"
ObjectFile=".\debug/"
ProgramDataBaseFileName=".\debug/"
WarningLevel="3"
SuppressStartupBanner="TRUE"
DebugInformationFormat="4"
CompileAs="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386"
AdditionalDependencies="odbc32.lib odbccp32.lib ..\zlib\zlib.lib"
OutputFile="debug/amxmodx_mm.dll"
Version="0.1"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
AdditionalLibraryDirectories="..\extra\lib_win32"
ModuleDefinitionFile=""
GenerateDebugInformation="TRUE"
ProgramDatabaseFile=".\debug/amxx_mm.pdb"
ImportLibrary=".\debug/amxx_mm.lib"/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="_DEBUG"
MkTypLibCompatible="TRUE"
SuppressStartupBanner="TRUE"
TargetEnvironment="1"
TypeLibraryName=".\debug/amxmodx.tlb"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1033"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory=".\Release"
IntermediateDirectory=".\Release"
ConfigurationType="2"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
GlobalOptimizations="TRUE"
InlineFunctionExpansion="1"
FavorSizeOrSpeed="1"
AdditionalIncludeDirectories="..\..\metamod\metamod,..\..\hlsdk\sourcecode\common,..\..\hlsdk\sourcecode\engine,..\..\hlsdk\sourcecode\dlls,..\..\hlsdk\sourcecode\pm_shared,..\extra\include"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS"
StringPooling="TRUE"
RuntimeLibrary="4"
EnableFunctionLevelLinking="TRUE"
UsePrecompiledHeader="2"
PrecompiledHeaderThrough="amxmodx.h"
PrecompiledHeaderFile=".\release/amxmodx.pch"
AssemblerListingLocation=".\release/"
ObjectFile=".\release/"
ProgramDataBaseFileName=".\release/"
WarningLevel="3"
SuppressStartupBanner="TRUE"
CompileAs="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386"
AdditionalDependencies="odbc32.lib odbccp32.lib ..\zlib\zlib.lib"
OutputFile="release/amxmodx_mm.dll"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
AdditionalLibraryDirectories="..\extra\lib_win32"
ModuleDefinitionFile=""
ProgramDatabaseFile=".\release/amxx_mm.pdb"
ImportLibrary=".\release/amxx_mm.lib"/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="NDEBUG"
MkTypLibCompatible="TRUE"
SuppressStartupBanner="TRUE"
TargetEnvironment="1"
TypeLibraryName=".\release/amxmodx.tlb"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1033"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="MemtestDebug|Win32"
OutputDirectory="MemtestDebug"
IntermediateDirectory="MemtestDebug"
ConfigurationType="2"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="&quot;C:\Hry\Half-Life\SDK\Multiplayer Source\pm_shared&quot;;&quot;C:\Hry\Half-Life\SDK\Multiplayer Source\dlls&quot;;&quot;C:\Hry\Half-Life\SDK\Multiplayer Source\engine&quot;;&quot;C:\Hry\Half-Life\SDK\Multiplayer Source\common&quot;;C:\Files\Programming\metamod\metamod"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;MEMORY_TEST"
BasicRuntimeChecks="3"
RuntimeLibrary="5"
StructMemberAlignment="3"
UsePrecompiledHeader="2"
PrecompiledHeaderThrough="amxmodx.h"
PrecompiledHeaderFile=".\memtestdebug/amxmodx.pch"
AssemblerListingLocation=".\memtestdebug/"
ObjectFile=".\memtestdebug/"
ProgramDataBaseFileName=".\memtestdebug/"
WarningLevel="3"
SuppressStartupBanner="TRUE"
DebugInformationFormat="4"
CompileAs="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386"
AdditionalDependencies="odbc32.lib odbccp32.lib ..\zlib\zlib.lib"
OutputFile="memtestdebug/amxmodx_mm.dll"
Version="0.1"
LinkIncremental="2"
SuppressStartupBanner="TRUE"
AdditionalLibraryDirectories="..\extra\lib_win32"
ModuleDefinitionFile=""
GenerateDebugInformation="TRUE"
ProgramDatabaseFile=".\memtestdebug/amxx_mm.pdb"
ImportLibrary=".\memtestdebug/amxx_mm.lib"/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="_DEBUG"
MkTypLibCompatible="TRUE"
SuppressStartupBanner="TRUE"
TargetEnvironment="1"
TypeLibraryName=".\debug/amxmodx.tlb"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1033"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="MemtestRelease|Win32"
OutputDirectory="MemtestRelease"
IntermediateDirectory="MemtestRelease"
ConfigurationType="2"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
GlobalOptimizations="TRUE"
InlineFunctionExpansion="1"
FavorSizeOrSpeed="1"
AdditionalIncludeDirectories="..\..\metamod\metamod,..\..\hlsdk\sourcecode\common,..\..\hlsdk\sourcecode\engine,..\..\hlsdk\sourcecode\dlls,..\..\hlsdk\sourcecode\pm_shared,..\extra\include"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;MEMORY_TEST"
StringPooling="TRUE"
RuntimeLibrary="4"
EnableFunctionLevelLinking="TRUE"
UsePrecompiledHeader="2"
PrecompiledHeaderThrough="amxmodx.h"
PrecompiledHeaderFile=".\memtestrelease/amxmodx.pch"
AssemblerListingLocation=".\memtestrelease/"
ObjectFile=".\memtestrelease/"
ProgramDataBaseFileName=".\memtestrelease/"
WarningLevel="3"
SuppressStartupBanner="TRUE"
CompileAs="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386"
AdditionalDependencies="odbc32.lib odbccp32.lib ..\zlib\zlib.lib"
OutputFile="memtestrelease/amxmodx_mm.dll"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
AdditionalLibraryDirectories="..\extra\lib_win32"
ModuleDefinitionFile=""
GenerateDebugInformation="TRUE"
ProgramDatabaseFile=".\memtestrelease/amxx_mm.pdb"
GenerateMapFile="TRUE"
MapExports="TRUE"
ImportLibrary=".\memtestrelease/amxx_mm.lib"/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="NDEBUG"
MkTypLibCompatible="TRUE"
SuppressStartupBanner="TRUE"
TargetEnvironment="1"
TypeLibraryName=".\release/amxmodx.tlb"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1033"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="JITDebug|Win32"
OutputDirectory="JITDebug"
@ -299,7 +23,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="&quot;C:\Hry\Half-Life\SDK\Multiplayer Source\pm_shared&quot;;&quot;C:\Hry\Half-Life\SDK\Multiplayer Source\dlls&quot;;&quot;C:\Hry\Half-Life\SDK\Multiplayer Source\engine&quot;;&quot;C:\Hry\Half-Life\SDK\Multiplayer Source\common&quot;;C:\Files\Programming\metamod\metamod"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;PAWN_CELL_SIZE=32;ASM32;JIT"
BasicRuntimeChecks="3"
RuntimeLibrary="5"
@ -322,14 +46,14 @@
AdditionalDependencies="..\zlib\zlib.lib ..\JIT\amxjitsn.obj ..\JIT\amxexecn.obj ..\JIT\natives-x86.obj"
OutputFile="jitdebug/amxmodx_mm.dll"
Version="0.1"
LinkIncremental="1"
LinkIncremental="2"
SuppressStartupBanner="TRUE"
AdditionalLibraryDirectories="..\extra\lib_win32"
IgnoreDefaultLibraryNames="MSVCRT"
IgnoreDefaultLibraryNames="MSVCRT;LIBC"
ModuleDefinitionFile=""
GenerateDebugInformation="TRUE"
ProgramDatabaseFile=".\jitdebug/amxx_mm.pdb"
ImportLibrary=".\jitdebug/amxx_mm.lib"/>
ProgramDatabaseFile=".\jitdebug/amxmodx_mm.pdb"
ImportLibrary=".\jitdebug/amxmodx_mm.lib"/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="_DEBUG"
@ -368,9 +92,13 @@
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
GlobalOptimizations="TRUE"
InlineFunctionExpansion="1"
EnableIntrinsicFunctions="TRUE"
FavorSizeOrSpeed="1"
OmitFramePointers="TRUE"
OptimizeForProcessor="0"
AdditionalIncludeDirectories="..\..\metamod\metamod,..\..\hlsdk\sourcecode\common,..\..\hlsdk\sourcecode\engine,..\..\hlsdk\sourcecode\dlls,..\..\hlsdk\sourcecode\pm_shared,..\extra\include"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;JIT;ASM32;PAWN_CELL_SIZE=32"
IgnoreStandardIncludePath="FALSE"
@ -385,6 +113,7 @@
ProgramDataBaseFileName=".\jitrelease/"
WarningLevel="3"
SuppressStartupBanner="TRUE"
DebugInformationFormat="3"
CompileAs="0"/>
<Tool
Name="VCCustomBuildTool"/>
@ -399,9 +128,9 @@
IgnoreDefaultLibraryNames="MSVCRT"
ModuleDefinitionFile=""
GenerateDebugInformation="TRUE"
ProgramDatabaseFile=".\jitrelease/amxx_mm.pdb"
GenerateMapFile="FALSE"
ImportLibrary=".\jitrelease/amxx_mm.lib"/>
ProgramDatabaseFile=".\jitrelease/amxmodx_mm.pdb"
GenerateMapFile="TRUE"
ImportLibrary=".\jitrelease/amxmodx_mm.lib"/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="NDEBUG"
@ -431,53 +160,54 @@
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="JITMemtestRelease|Win32"
OutputDirectory="JITMemtestRelease"
IntermediateDirectory="JITMemtestRelease"
Name="JITDebugBinLog|Win32"
OutputDirectory="$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="2"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
GlobalOptimizations="TRUE"
InlineFunctionExpansion="1"
FavorSizeOrSpeed="1"
AdditionalIncludeDirectories="..\..\metamod\metamod,..\..\hlsdk\sourcecode\common,..\..\hlsdk\sourcecode\engine,..\..\hlsdk\sourcecode\dlls,..\..\hlsdk\sourcecode\pm_shared,..\extra\include"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;MEMORY_TEST;JIT;ASM32;PAWN_CELL_SIZE=32"
StringPooling="TRUE"
RuntimeLibrary="4"
EnableFunctionLevelLinking="TRUE"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;PAWN_CELL_SIZE=32;ASM32;JIT;BINLOG_ENABLED"
BasicRuntimeChecks="3"
RuntimeLibrary="5"
StructMemberAlignment="3"
UsePrecompiledHeader="2"
PrecompiledHeaderThrough="amxmodx.h"
PrecompiledHeaderFile=".\jitmemtestrelease/amxmodx.pch"
AssemblerListingLocation=".\jitmemtestrelease/"
ObjectFile=".\jitmemtestrelease/"
ProgramDataBaseFileName=".\jitmemtestrelease/"
PrecompiledHeaderFile=".\jitdebugbinlog/amxmodx.pch"
AssemblerListingLocation=".\jitdebugbinlog/"
ObjectFile=".\jitdebugbinlog/"
ProgramDataBaseFileName=".\jitdebugbinlog/"
WarningLevel="3"
SuppressStartupBanner="TRUE"
DebugInformationFormat="4"
CompileAs="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386"
AdditionalDependencies="..\zlib\zlib.lib ..\JIT\amxjitsn.obj ..\JIT\amxexecn.obj"
OutputFile="jitmemtestrelease/amxmodx_mm.dll"
LinkIncremental="1"
AdditionalDependencies="..\zlib\zlib.lib ..\JIT\amxjitsn.obj ..\JIT\amxexecn.obj ..\JIT\natives-x86.obj"
OutputFile="jitdebugbinlog/amxmodx_bl_mm.dll"
Version="0.1"
LinkIncremental="2"
SuppressStartupBanner="TRUE"
AdditionalLibraryDirectories="..\extra\lib_win32"
IgnoreDefaultLibraryNames="MSVCRT;LIBC"
ModuleDefinitionFile=""
GenerateDebugInformation="TRUE"
ProgramDatabaseFile=".\jitmemtestrelease/amxx_mm.pdb"
ImportLibrary=".\jitmemtestrelease/amxx_mm.lib"/>
ProgramDatabaseFile=".\jitdebugbinlog/amxmodx_bl_mm.pdb"
ImportLibrary=".\jitdebugbinlog/amxmodx_bl_mm.lib"/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="NDEBUG"
PreprocessorDefinitions="_DEBUG"
MkTypLibCompatible="TRUE"
SuppressStartupBanner="TRUE"
TargetEnvironment="1"
TypeLibraryName=".\release/amxmodx.tlb"/>
TypeLibraryName=".\debug/amxmodx.tlb"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
@ -486,7 +216,7 @@
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
PreprocessorDefinitions="_DEBUG"
Culture="1033"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
@ -500,48 +230,54 @@
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="MaximalSpeed|Win32"
OutputDirectory="MaximalSpeed"
IntermediateDirectory="MaximalSpeed"
Name="JITReleaseBinLog|Win32"
OutputDirectory="$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="2"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
GlobalOptimizations="TRUE"
InlineFunctionExpansion="1"
EnableIntrinsicFunctions="TRUE"
FavorSizeOrSpeed="1"
OptimizeForProcessor="2"
OptimizeForWindowsApplication="TRUE"
OmitFramePointers="TRUE"
OptimizeForProcessor="0"
AdditionalIncludeDirectories="..\..\metamod\metamod,..\..\hlsdk\sourcecode\common,..\..\hlsdk\sourcecode\engine,..\..\hlsdk\sourcecode\dlls,..\..\hlsdk\sourcecode\pm_shared,..\extra\include"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;JIT"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;JIT;ASM32;PAWN_CELL_SIZE=32;BINLOG_ENABLED"
IgnoreStandardIncludePath="FALSE"
StringPooling="TRUE"
RuntimeLibrary="4"
EnableFunctionLevelLinking="TRUE"
UsePrecompiledHeader="2"
PrecompiledHeaderThrough="amxmodx.h"
PrecompiledHeaderFile=".\MaximalSpeed/amxmodx.pch"
AssemblerListingLocation=".\MaximalSpeed/"
ObjectFile=".\MaximalSpeed/"
ProgramDataBaseFileName=".\MaximalSpeed/"
PrecompiledHeaderFile=".\jitreleasebinlog/amxmodx.pch"
AssemblerListingLocation=".\jitreleasebinlog/"
ObjectFile=".\jitreleasebinlog/"
ProgramDataBaseFileName=".\jitreleasebinlog/"
WarningLevel="3"
SuppressStartupBanner="TRUE"
DebugInformationFormat="3"
CompileAs="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386"
AdditionalDependencies="odbc32.lib odbccp32.lib ..\jit\jits.lib ..\zlib\zlib.lib"
OutputFile="MaximalSpeed/amxmodx_mm.dll"
AdditionalDependencies="..\zlib\zlib.lib ..\JIT\amxjitsn.obj ..\JIT\amxexecn.obj ..\JIT\natives-x86.obj"
OutputFile="jitreleasebinlog/amxmodx_bl_mm.dll"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
AdditionalLibraryDirectories="..\extra\lib_win32"
IgnoreDefaultLibraryNames="MSVCRT"
ModuleDefinitionFile=""
ProgramDatabaseFile=".\MaximalSpeede/amxx_mm.pdb"
ImportLibrary=".\jitrelease/amxx_mm.lib"/>
GenerateDebugInformation="TRUE"
ProgramDatabaseFile=".\jitreleasebinlog/amxmodx_bl_mm.pdb"
GenerateMapFile="TRUE"
ImportLibrary=".\jitreleasebinlog/amxmodx_bl_mm.lib"/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="NDEBUG"
@ -598,6 +334,21 @@
<File
RelativePath="..\amxxlog.cpp">
</File>
<File
RelativePath="..\binlog.cpp">
<FileConfiguration
Name="JITDebug|Win32"
ExcludedFromBuild="TRUE">
<Tool
Name="VCCLCompilerTool"/>
</FileConfiguration>
<FileConfiguration
Name="JITRelease|Win32"
ExcludedFromBuild="TRUE">
<Tool
Name="VCCLCompilerTool"/>
</FileConfiguration>
</File>
<File
RelativePath="..\CCmd.cpp">
</File>
@ -634,17 +385,14 @@
<File
RelativePath="..\CVault.cpp">
</File>
<File
RelativePath="..\debugger.cpp">
</File>
<File
RelativePath="..\emsg.cpp">
</File>
<File
RelativePath="..\fakemeta.cpp">
<FileConfiguration
Name="MemtestDebug|Win32">
<Tool
Name="VCCLCompilerTool"
GeneratePreprocessedFile="0"/>
</FileConfiguration>
</File>
<File
RelativePath="..\file.cpp">
@ -652,9 +400,30 @@
<File
RelativePath="..\float.cpp">
</File>
<File
RelativePath="..\format.cpp">
<FileConfiguration
Name="JITRelease|Win32">
<Tool
Name="VCCLCompilerTool"
AssemblerOutput="4"/>
</FileConfiguration>
<FileConfiguration
Name="JITReleaseBinLog|Win32">
<Tool
Name="VCCLCompilerTool"
AssemblerOutput="4"/>
</FileConfiguration>
</File>
<File
RelativePath="..\libraries.cpp">
</File>
<File
RelativePath="..\md5.cpp">
</File>
<File
RelativePath="..\messages.cpp">
</File>
<File
RelativePath="..\meta_api.cpp">
</File>
@ -667,6 +436,9 @@
<File
RelativePath="..\newmenus.cpp">
</File>
<File
RelativePath="..\optimizer.cpp">
</File>
<File
RelativePath="..\power.cpp">
</File>
@ -675,6 +447,18 @@
</File>
<File
RelativePath="..\string.cpp">
<FileConfiguration
Name="JITRelease|Win32">
<Tool
Name="VCCLCompilerTool"
AssemblerOutput="2"/>
</FileConfiguration>
<FileConfiguration
Name="JITReleaseBinLog|Win32">
<Tool
Name="VCCLCompilerTool"
AssemblerOutput="2"/>
</FileConfiguration>
</File>
<File
RelativePath="..\strptime.cpp">
@ -685,44 +469,10 @@
<File
RelativePath="..\vault.cpp">
</File>
<Filter
Name="mmgr"
Filter="">
<File
RelativePath="..\mmgr\mmgr.cpp">
<FileConfiguration
Name="Debug|Win32"
ExcludedFromBuild="TRUE">
<Tool
Name="VCCLCompilerTool"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
ExcludedFromBuild="TRUE">
<Tool
Name="VCCLCompilerTool"/>
</FileConfiguration>
<FileConfiguration
Name="JITDebug|Win32"
ExcludedFromBuild="TRUE">
<Tool
Name="VCCLCompilerTool"/>
</FileConfiguration>
<FileConfiguration
Name="JITRelease|Win32"
ExcludedFromBuild="TRUE">
<Tool
Name="VCCLCompilerTool"/>
</FileConfiguration>
<FileConfiguration
Name="MaximalSpeed|Win32"
ExcludedFromBuild="TRUE">
<Tool
Name="VCCLCompilerTool"/>
</FileConfiguration>
RelativePath="..\vector.cpp">
</File>
</Filter>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl">
@ -741,6 +491,9 @@
<File
RelativePath="..\amxxlog.h">
</File>
<File
RelativePath="..\binlog.h">
</File>
<File
RelativePath="..\CCmd.h">
</File>
@ -777,9 +530,6 @@
<File
RelativePath="..\CQueue.h">
</File>
<File
RelativePath="..\CStack.h">
</File>
<File
RelativePath="..\CString.h">
</File>
@ -792,15 +542,27 @@
<File
RelativePath="..\CVector.h">
</File>
<File
RelativePath="..\debugger.h">
</File>
<File
RelativePath="..\fakemeta.h">
</File>
<File
RelativePath="..\format.h">
</File>
<File
RelativePath="..\libraries.h">
</File>
<File
RelativePath="..\md5.h">
</File>
<File
RelativePath="..\menus.h">
</File>
<File
RelativePath="..\messages.h">
</File>
<File
RelativePath="..\modules.h">
</File>
@ -810,25 +572,27 @@
<File
RelativePath="..\newmenus.h">
</File>
<File
RelativePath="..\optimizer.h">
</File>
<File
RelativePath="..\resource.h">
</File>
<File
RelativePath="..\sh_list.h">
</File>
<File
RelativePath="..\sh_stack.h">
</File>
<File
RelativePath="..\sh_tinyhash.h">
</File>
<File
RelativePath="..\zlib\zconf.h">
</File>
<File
RelativePath="..\zlib\zlib.h">
</File>
<Filter
Name="mmgr"
Filter="">
<File
RelativePath="..\mmgr\mmgr.h">
</File>
<File
RelativePath="..\mmgr\nommgr.h">
</File>
</Filter>
</Filter>
<Filter
Name="Resource Files"
@ -837,6 +601,72 @@
RelativePath="..\version.rc">
</File>
</Filter>
<Filter
Name="Assembly"
Filter="">
<File
RelativePath="..\amxdefn.asm">
</File>
<File
RelativePath="..\amxexecn.asm">
</File>
<File
RelativePath="..\amxjitsn.asm">
</File>
<File
RelativePath="..\helpers-x86.asm">
</File>
<File
RelativePath="..\natives-amd64.asm">
</File>
<File
RelativePath="..\natives-x86.asm">
</File>
<Filter
Name="Builds"
Filter="">
<File
RelativePath="..\Jit\helpers-x86.obj">
</File>
</Filter>
</Filter>
<Filter
Name="SDK"
Filter="">
<File
RelativePath="..\sdk\amxxmodule.cpp">
<FileConfiguration
Name="JITDebug|Win32"
ExcludedFromBuild="TRUE">
<Tool
Name="VCCLCompilerTool"/>
</FileConfiguration>
<FileConfiguration
Name="JITRelease|Win32"
ExcludedFromBuild="TRUE">
<Tool
Name="VCCLCompilerTool"/>
</FileConfiguration>
<FileConfiguration
Name="JITDebugBinLog|Win32"
ExcludedFromBuild="TRUE">
<Tool
Name="VCCLCompilerTool"/>
</FileConfiguration>
<FileConfiguration
Name="JITReleaseBinLog|Win32"
ExcludedFromBuild="TRUE">
<Tool
Name="VCCLCompilerTool"/>
</FileConfiguration>
</File>
<File
RelativePath="..\sdk\amxxmodule.h">
</File>
<File
RelativePath="..\sdk\moduleconfig.h">
</File>
</Filter>
</Files>
<Globals>
</Globals>

View File

@ -0,0 +1,26 @@

Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "amxmodx_mm", "amxmodx_mm.vcproj", "{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
JITDebug|Win32 = JITDebug|Win32
JITDebugBinLog|Win32 = JITDebugBinLog|Win32
JITRelease|Win32 = JITRelease|Win32
JITReleaseBinLog|Win32 = JITReleaseBinLog|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITDebug|Win32.ActiveCfg = JITDebug|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITDebug|Win32.Build.0 = JITDebug|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITDebugBinLog|Win32.ActiveCfg = JITDebugBinLog|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITDebugBinLog|Win32.Build.0 = JITDebugBinLog|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITRelease|Win32.ActiveCfg = JITRelease|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITRelease|Win32.Build.0 = JITRelease|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITReleaseBinLog|Win32.ActiveCfg = JITReleaseBinLog|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITReleaseBinLog|Win32.Build.0 = JITReleaseBinLog|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,914 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="amxmodx_mm"
ProjectGUID="{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}"
RootNamespace="amxmodx"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="JITDebug|Win32"
OutputDirectory="JITDebug"
IntermediateDirectory="JITDebug"
ConfigurationType="2"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="_DEBUG"
MkTypLibCompatible="true"
SuppressStartupBanner="true"
TargetEnvironment="1"
TypeLibraryName=".\debug/amxmodx.tlb"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;PAWN_CELL_SIZE=32;ASM32;JIT;_CRT_SECURE_NO_DEPRECATE"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
StructMemberAlignment="3"
TreatWChar_tAsBuiltInType="true"
RuntimeTypeInfo="false"
UsePrecompiledHeader="0"
PrecompiledHeaderThrough="amxmodx.h"
PrecompiledHeaderFile=".\jitdebug/amxmodx.pch"
AssemblerListingLocation=".\jitdebug/"
ObjectFile=".\jitdebug/"
ProgramDataBaseFileName=".\jitdebug/"
WarningLevel="3"
SuppressStartupBanner="true"
DebugInformationFormat="4"
CompileAs="0"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386"
AdditionalDependencies="..\zlib\zlib.lib ..\JIT\amxjitsn.obj ..\JIT\amxexecn.obj ..\JIT\natives-x86.obj"
OutputFile="jitdebug/amxmodx_mm.dll"
Version="0.1"
LinkIncremental="2"
SuppressStartupBanner="true"
AdditionalLibraryDirectories="..\extra\lib_win32"
IgnoreDefaultLibraryNames="MSVCRT;LIBC"
ModuleDefinitionFile=""
GenerateDebugInformation="true"
ProgramDatabaseFile=".\jitdebug/amxx_mm.pdb"
ImportLibrary=".\jitdebug/amxmodx_mm.lib"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="JITRelease|Win32"
OutputDirectory="JITRelease"
IntermediateDirectory="JITRelease"
ConfigurationType="2"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="NDEBUG"
MkTypLibCompatible="true"
SuppressStartupBanner="true"
TargetEnvironment="1"
TypeLibraryName=".\release/amxmodx.tlb"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
EnableIntrinsicFunctions="true"
FavorSizeOrSpeed="1"
OmitFramePointers="true"
AdditionalIncludeDirectories="..\..\metamod\metamod,..\..\hlsdk\sourcecode\common,..\..\hlsdk\sourcecode\engine,..\..\hlsdk\sourcecode\dlls,..\..\hlsdk\sourcecode\pm_shared,..\extra\include"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;JIT;ASM32;PAWN_CELL_SIZE=32;_CRT_SECURE_NO_DEPRECATE"
IgnoreStandardIncludePath="false"
StringPooling="true"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
TreatWChar_tAsBuiltInType="true"
RuntimeTypeInfo="false"
UsePrecompiledHeader="0"
PrecompiledHeaderThrough="amxmodx.h"
PrecompiledHeaderFile=".\jitrelease/amxmodx.pch"
AssemblerListingLocation=".\jitrelease/"
ObjectFile=".\jitrelease/"
ProgramDataBaseFileName=".\jitrelease/"
WarningLevel="3"
SuppressStartupBanner="true"
DebugInformationFormat="3"
CompileAs="0"
ShowIncludes="false"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386"
AdditionalDependencies="..\zlib\zlib.lib ..\JIT\amxjitsn.obj ..\JIT\amxexecn.obj ..\JIT\natives-x86.obj"
OutputFile="jitrelease/amxmodx_mm.dll"
LinkIncremental="1"
SuppressStartupBanner="true"
AdditionalLibraryDirectories="..\extra\lib_win32"
IgnoreDefaultLibraryNames="MSVCRT;LIBC"
ModuleDefinitionFile=""
GenerateDebugInformation="true"
ProgramDatabaseFile=".\jitrelease/amxmodx_mm.pdb"
GenerateMapFile="true"
ImportLibrary=".\jitrelease/amxmodx_mm.lib"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="JITDebugBinLog|Win32"
OutputDirectory="$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="2"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="_DEBUG"
MkTypLibCompatible="true"
SuppressStartupBanner="true"
TargetEnvironment="1"
TypeLibraryName=".\debug/amxmodx.tlb"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;PAWN_CELL_SIZE=32;ASM32;JIT;BINLOG_ENABLED;_CRT_SECURE_NO_DEPRECATE"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
StructMemberAlignment="3"
TreatWChar_tAsBuiltInType="true"
RuntimeTypeInfo="false"
UsePrecompiledHeader="0"
PrecompiledHeaderThrough="amxmodx.h"
PrecompiledHeaderFile=".\jitdebugbinlog/amxmodx.pch"
AssemblerListingLocation=".\jitdebugbinlog/"
ObjectFile=".\jitdebugbinlog/"
ProgramDataBaseFileName=".\jitdebugbinlog/"
WarningLevel="3"
SuppressStartupBanner="true"
DebugInformationFormat="4"
CompileAs="0"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386"
AdditionalDependencies="..\zlib\zlib.lib ..\JIT\amxjitsn.obj ..\JIT\amxexecn.obj ..\JIT\natives-x86.obj"
OutputFile="jitdebugbinlog/amxmodx_bl_mm.dll"
Version="0.1"
LinkIncremental="2"
SuppressStartupBanner="true"
AdditionalLibraryDirectories="..\extra\lib_win32"
IgnoreDefaultLibraryNames="MSVCRT;LIBC"
ModuleDefinitionFile=""
GenerateDebugInformation="true"
ProgramDatabaseFile=".\jitdebugbinlog/amxmodx_bl_mm.pdb"
ImportLibrary=".\jitdebugbinlog/amxmodx_bl_mm.lib"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="JITReleaseBinLog|Win32"
OutputDirectory="$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="2"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="NDEBUG"
MkTypLibCompatible="true"
SuppressStartupBanner="true"
TargetEnvironment="1"
TypeLibraryName=".\release/amxmodx.tlb"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
EnableIntrinsicFunctions="true"
FavorSizeOrSpeed="1"
OmitFramePointers="true"
AdditionalIncludeDirectories="..\..\metamod\metamod,..\..\hlsdk\sourcecode\common,..\..\hlsdk\sourcecode\engine,..\..\hlsdk\sourcecode\dlls,..\..\hlsdk\sourcecode\pm_shared,..\extra\include"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;JIT;ASM32;PAWN_CELL_SIZE=32;BINLOG_ENABLED;_CRT_SECURE_NO_DEPRECATE"
IgnoreStandardIncludePath="false"
StringPooling="true"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
TreatWChar_tAsBuiltInType="true"
RuntimeTypeInfo="false"
UsePrecompiledHeader="0"
PrecompiledHeaderThrough="amxmodx.h"
PrecompiledHeaderFile=".\jitreleasebinlog/amxmodx.pch"
AssemblerListingLocation=".\jitreleasebinlog/"
ObjectFile=".\jitreleasebinlog/"
ProgramDataBaseFileName=".\jitreleasebinlog/"
WarningLevel="3"
SuppressStartupBanner="true"
DebugInformationFormat="3"
CompileAs="0"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386"
AdditionalDependencies="..\zlib\zlib.lib ..\JIT\amxjitsn.obj ..\JIT\amxexecn.obj ..\JIT\natives-x86.obj"
OutputFile="jitreleasebinlog/amxmodx_bl_mm.dll"
LinkIncremental="1"
SuppressStartupBanner="true"
AdditionalLibraryDirectories="..\extra\lib_win32"
IgnoreDefaultLibraryNames="MSVCRT;LIBC"
ModuleDefinitionFile=""
GenerateDebugInformation="true"
ProgramDatabaseFile=".\jitreleasebinlog/amxmodx_bl_mm.pdb"
GenerateMapFile="true"
ImportLibrary=".\jitreleasebinlog/amxmodx_bl_mm.lib"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
>
<File
RelativePath="..\amx.cpp"
>
</File>
<File
RelativePath="..\amxcore.cpp"
>
</File>
<File
RelativePath="..\amxdbg.cpp"
>
</File>
<File
RelativePath="..\amxmodx.cpp"
>
</File>
<File
RelativePath="..\amxtime.cpp"
>
</File>
<File
RelativePath="..\amxxfile.cpp"
>
</File>
<File
RelativePath="..\amxxlog.cpp"
>
</File>
<File
RelativePath="..\binlog.cpp"
>
<FileConfiguration
Name="JITDebug|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="JITRelease|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\CCmd.cpp"
>
</File>
<File
RelativePath="..\CEvent.cpp"
>
</File>
<File
RelativePath="..\CFile.cpp"
>
</File>
<File
RelativePath="..\CForward.cpp"
>
</File>
<File
RelativePath="..\CLang.cpp"
>
</File>
<File
RelativePath="..\CLogEvent.cpp"
>
</File>
<File
RelativePath="..\CMenu.cpp"
>
</File>
<File
RelativePath="..\CMisc.cpp"
>
</File>
<File
RelativePath="..\CModule.cpp"
>
</File>
<File
RelativePath="..\CPlugin.cpp"
>
</File>
<File
RelativePath="..\CTask.cpp"
>
</File>
<File
RelativePath="..\CVault.cpp"
>
</File>
<File
RelativePath="..\debugger.cpp"
>
</File>
<File
RelativePath="..\emsg.cpp"
>
</File>
<File
RelativePath="..\fakemeta.cpp"
>
</File>
<File
RelativePath="..\file.cpp"
>
</File>
<File
RelativePath="..\float.cpp"
>
</File>
<File
RelativePath="..\format.cpp"
>
<FileConfiguration
Name="JITRelease|Win32"
>
<Tool
Name="VCCLCompilerTool"
AssemblerOutput="4"
/>
</FileConfiguration>
<FileConfiguration
Name="JITReleaseBinLog|Win32"
>
<Tool
Name="VCCLCompilerTool"
AssemblerOutput="4"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\libraries.cpp"
>
</File>
<File
RelativePath="..\md5.cpp"
>
</File>
<File
RelativePath="..\messages.cpp"
>
</File>
<File
RelativePath="..\meta_api.cpp"
>
</File>
<File
RelativePath="..\modules.cpp"
>
</File>
<File
RelativePath="..\natives.cpp"
>
</File>
<File
RelativePath="..\newmenus.cpp"
>
</File>
<File
RelativePath="..\optimizer.cpp"
>
</File>
<File
RelativePath="..\power.cpp"
>
</File>
<File
RelativePath="..\srvcmd.cpp"
>
</File>
<File
RelativePath="..\string.cpp"
>
<FileConfiguration
Name="JITRelease|Win32"
>
<Tool
Name="VCCLCompilerTool"
AssemblerOutput="2"
/>
</FileConfiguration>
<FileConfiguration
Name="JITReleaseBinLog|Win32"
>
<Tool
Name="VCCLCompilerTool"
AssemblerOutput="2"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\strptime.cpp"
>
</File>
<File
RelativePath="..\util.cpp"
>
</File>
<File
RelativePath="..\vault.cpp"
>
</File>
<File
RelativePath="..\vector.cpp"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl"
>
<File
RelativePath="..\amx.h"
>
</File>
<File
RelativePath="..\amxdbg.h"
>
</File>
<File
RelativePath="..\amxmodx.h"
>
</File>
<File
RelativePath="..\amxxfile.h"
>
</File>
<File
RelativePath="..\amxxlog.h"
>
</File>
<File
RelativePath="..\binlog.h"
>
</File>
<File
RelativePath="..\CCmd.h"
>
</File>
<File
RelativePath="..\CEvent.h"
>
</File>
<File
RelativePath="..\CFile.h"
>
</File>
<File
RelativePath="..\CForward.h"
>
</File>
<File
RelativePath="..\CLang.h"
>
</File>
<File
RelativePath="..\CList.h"
>
</File>
<File
RelativePath="..\CLogEvent.h"
>
</File>
<File
RelativePath="..\CMenu.h"
>
</File>
<File
RelativePath="..\CMisc.h"
>
</File>
<File
RelativePath="..\CModule.h"
>
</File>
<File
RelativePath="..\CPlugin.h"
>
</File>
<File
RelativePath="..\CQueue.h"
>
</File>
<File
RelativePath="..\CString.h"
>
</File>
<File
RelativePath="..\CTask.h"
>
</File>
<File
RelativePath="..\CVault.h"
>
</File>
<File
RelativePath="..\CVector.h"
>
</File>
<File
RelativePath="..\debugger.h"
>
</File>
<File
RelativePath="..\fakemeta.h"
>
</File>
<File
RelativePath="..\format.h"
>
</File>
<File
RelativePath="..\libraries.h"
>
</File>
<File
RelativePath="..\md5.h"
>
</File>
<File
RelativePath="..\menus.h"
>
</File>
<File
RelativePath="..\messages.h"
>
</File>
<File
RelativePath="..\modules.h"
>
</File>
<File
RelativePath="..\natives.h"
>
</File>
<File
RelativePath="..\newmenus.h"
>
</File>
<File
RelativePath="..\optimizer.h"
>
</File>
<File
RelativePath="..\resource.h"
>
</File>
<File
RelativePath="..\sh_list.h"
>
</File>
<File
RelativePath="..\sh_stack.h"
>
</File>
<File
RelativePath="..\sh_tinyhash.h"
>
</File>
<File
RelativePath="..\zlib\zconf.h"
>
</File>
<File
RelativePath="..\zlib\zlib.h"
>
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="rc"
>
<File
RelativePath="..\version.rc"
>
</File>
</Filter>
<Filter
Name="Assembly"
>
<File
RelativePath="..\amxdefn.asm"
>
</File>
<File
RelativePath="..\amxexecn.asm"
>
</File>
<File
RelativePath="..\amxjitsn.asm"
>
</File>
<File
RelativePath="..\helpers-x86.asm"
>
</File>
<File
RelativePath="..\natives-amd64.asm"
>
</File>
<File
RelativePath="..\natives-x86.asm"
>
</File>
<Filter
Name="Builds"
>
<File
RelativePath="..\Jit\helpers-x86.obj"
>
</File>
</Filter>
</Filter>
<Filter
Name="SDK"
>
<File
RelativePath="..\sdk\amxxmodule.cpp"
>
<FileConfiguration
Name="JITDebug|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="JITRelease|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="JITDebugBinLog|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="JITReleaseBinLog|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\sdk\amxxmodule.h"
>
</File>
<File
RelativePath="..\sdk\moduleconfig.h"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -95,4 +95,6 @@ _amxx_DynaCodesize:
pop ebp
ret
section .data
GLOBAL_GATE DD 0

View File

@ -29,24 +29,26 @@
*/
#include "amxmodx.h"
#include <malloc.h>
#include <stdlib.h>
#include "CStack.h"
#include "sh_stack.h"
#include "natives.h"
#include "debugger.h"
#include "libraries.h"
#ifdef __linux__
#include <malloc.h>
#include <stdlib.h>
#include <sys/mman.h>
#include "sclinux.h"
#endif
//Written by David "BAILOPAN" Anderson
//With the exception for param_convert, which was written by
// Julien "dJeyL" Laurent
CStack<int> g_ErrorStk;
CVector<regnative *> g_RegNatives;
CStack<regnative *> g_NativeStack;
CVector<String> g_Libraries;
static char g_errorStr[512] = {0};
static int g_errorNum = 0;
bool g_Initialized = false;
int amxx_DynaCallback(int idx, AMX *amx, cell *params)
@ -66,14 +68,31 @@ int amxx_DynaCallback(int idx, AMX *amx, cell *params)
return 0;
}
//parameter stack
pNative->caller = amx;
CPluginMngr::CPlugin *pPlugin = g_plugins.findPluginFast(amx);
CPluginMngr::CPlugin *pNativePlugin = g_plugins.findPluginFast(pNative->amx);
if (!pNativePlugin->isExecutable(pNative->func))
{
LogError(amx, AMX_ERR_NATIVE, "Called dynanative into a paused plugin.");
pPlugin->setStatus(ps_paused);
return 0;
}
if (pNative->caller)
{
LogError(amx, AMX_ERR_NATIVE, "Bug caught! Please contact the AMX Mod X Dev Team.");
return 0;
}
//parameter stack
//NOTE: it is possible that recursive register native calling
// could potentially be somehow damaged here.
//so, a :TODO: - make the stack unique, rather than a known ptr
pNative->caller = amx;
int err = 0;
cell ret = 0;
g_errorNum = 0;
g_ErrorStk.push(0);
g_NativeStack.push(pNative);
if (pNative->style == 0)
{
@ -86,19 +105,31 @@ int amxx_DynaCallback(int idx, AMX *amx, cell *params)
for (int i=numParams; i>=1; i--)
amx_Push(pNative->amx, params[i]);
}
if ( (err=amx_Exec(pNative->amx, &ret, pNative->func)) != AMX_ERR_NONE)
Debugger *pDebugger = (Debugger *)pNative->amx->userdata[UD_DEBUGGER];
if (pDebugger)
pDebugger->BeginExec();
err=amx_Exec(pNative->amx, &ret, pNative->func);
if (err != AMX_ERR_NONE)
{
g_NativeStack.pop();
LogError(pNative->amx, err, "");
return 0;
}
if (g_errorNum)
if (pDebugger && pDebugger->ErrorExists())
{
g_NativeStack.pop();
LogError(amx, g_errorNum, g_errorStr);
return ret;
//don't care
} else if (err != -1) {
//nothing logged the error
LogError(pNative->amx, err, NULL);
}
pNative->amx->error = AMX_ERR_NONE;
//furthermore, log an error in the parent plugin.
LogError(amx, AMX_ERR_NATIVE, "Unhandled dynamic native error");
} else if (g_ErrorStk.front()) {
LogError(amx, g_ErrorStk.front(), g_errorStr);
}
if (pDebugger)
pDebugger->EndExec();
g_NativeStack.pop();
g_ErrorStk.pop();
pNative->caller = NULL;
return ret;
}
@ -132,7 +163,8 @@ static cell AMX_NATIVE_CALL log_error(AMX *amx, cell *params)
char *err = format_amxstring(amx, params, 2, len);
_snprintf(g_errorStr, sizeof(g_errorStr), "%s", err);
g_errorNum = params[1];
g_ErrorStk.pop();
g_ErrorStk.push(params[1]);
return 1;
}
@ -145,7 +177,7 @@ static cell AMX_NATIVE_CALL get_string(AMX *amx, cell *params)
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
return 0;
}
regnative *pNative = g_NativeStack.top();
regnative *pNative = g_NativeStack.front();
if (pNative->style)
{
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
@ -166,7 +198,7 @@ static cell AMX_NATIVE_CALL set_string(AMX *amx, cell *params)
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
return 0;
}
regnative *pNative = g_NativeStack.top();
regnative *pNative = g_NativeStack.front();
if (pNative->style)
{
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
@ -189,7 +221,7 @@ static cell AMX_NATIVE_CALL get_param(AMX *amx, cell *params)
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
return 0;
}
regnative *pNative = g_NativeStack.top();
regnative *pNative = g_NativeStack.front();
if (pNative->style)
{
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
@ -208,7 +240,7 @@ static cell AMX_NATIVE_CALL get_param_byref(AMX *amx, cell *params)
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
return 0;
}
regnative *pNative = g_NativeStack.top();
regnative *pNative = g_NativeStack.front();
if (pNative->style)
{
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
@ -229,7 +261,7 @@ static cell AMX_NATIVE_CALL set_param_byref(AMX *amx, cell *params)
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
return 0;
}
regnative *pNative = g_NativeStack.top();
regnative *pNative = g_NativeStack.front();
if (pNative->style)
{
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
@ -252,7 +284,7 @@ static cell AMX_NATIVE_CALL get_array(AMX *amx, cell *params)
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
return 0;
}
regnative *pNative = g_NativeStack.top();
regnative *pNative = g_NativeStack.front();
if (pNative->style)
{
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
@ -265,8 +297,7 @@ static cell AMX_NATIVE_CALL get_array(AMX *amx, cell *params)
int size = params[3];
while (size-->0)
*dest = *source;
memcpy(dest, source, size * sizeof(cell));
return 1;
}
@ -279,7 +310,7 @@ static cell AMX_NATIVE_CALL set_array(AMX *amx, cell *params)
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
return 0;
}
regnative *pNative = g_NativeStack.top();
regnative *pNative = g_NativeStack.front();
if (pNative->style)
{
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
@ -292,8 +323,7 @@ static cell AMX_NATIVE_CALL set_array(AMX *amx, cell *params)
int size = params[3];
while (size-->0)
*dest = *source;
memcpy(dest, source, size * sizeof(cell));
return 1;
}
@ -309,7 +339,7 @@ static cell AMX_NATIVE_CALL param_convert(AMX *amx, cell *params)
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
return 0;
}
regnative *pNative = g_NativeStack.top();
regnative *pNative = g_NativeStack.front();
if (pNative->style != 1)
{
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
@ -332,7 +362,7 @@ static cell AMX_NATIVE_CALL register_library(AMX *amx, cell *params)
int len;
char *lib = get_amxstring(amx, params[1], 0, len);
AddPluginLibrary(lib);
AddLibrary(lib, LibType_Library, LibSource_Plugin, g_plugins.findPluginFast(amx));
return 1;
}
@ -359,6 +389,7 @@ static cell AMX_NATIVE_CALL register_native(AMX *amx, cell *params)
regnative *pNative = new regnative;
pNative->amx = amx;
pNative->func = idx;
pNative->caller = NULL;
//we'll apply a safety buffer too
//make our function
@ -385,30 +416,12 @@ static cell AMX_NATIVE_CALL register_native(AMX *amx, cell *params)
return 1;
}
bool LibraryExists(const char *name)
{
for (size_t i=0; i<g_Libraries.size(); i++)
{
if (stricmp(g_Libraries[i].c_str(), name)==0)
return true;
}
return false;
}
void AddPluginLibrary(const char *name)
{
String f(name);
g_Libraries.push_back(f);
}
void ClearPluginLibraries()
{
g_Libraries.clear();
ClearLibraries(LibSource_Plugin);
for (size_t i=0; i<g_RegNatives.size(); i++)
{
delete g_RegNatives[i]->pfn;
delete [] g_RegNatives[i]->pfn;
delete g_RegNatives[i];
}
g_RegNatives.clear();
@ -423,7 +436,7 @@ AMX_NATIVE_INFO g_NativeNatives[] = {
{"get_param", get_param},
{"get_param_byref", get_param_byref},
{"set_param_byref", set_param_byref},
{"get_array", set_array},
{"get_array", get_array},
{"set_array", set_array},
//these are dummy functions for floats ;p
{"get_param_f", get_param},

View File

@ -32,7 +32,9 @@
#define _INCLUDE_NATIVES_H
//only 16 for now sorry
#if !defined CALLFUNC_MAXPARAMS
#define CALLFUNC_MAXPARAMS 16
#endif
#define CALLFUNC_FLAG_BYREF 1
#define CALLFUNC_FLAG_BYREF_REUSED 2
@ -59,9 +61,7 @@ extern "C" int amxx_DynaFunc(AMX *amx, cell *params);
extern "C" int amxx_DynaCodesize();
AMX_NATIVE_INFO *BuildNativeTable();
void AddPluginLibrary(const char *name);
void ClearPluginLibraries();
bool LibraryExists(const char *name);
//I couldn't resist :)
extern AMX_NATIVE_INFO g_NativeNatives[];

View File

@ -1,13 +1,75 @@
/* AMX Mod X
*
* by the AMX Mod X Development Team
* originally developed by OLO
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* 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, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* In addition, as a special exception, the author gives permission to
* link the code of this program with the Half-Life Game Engine ("HL
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
* L.L.C ("Valve"). You must obey the GNU General Public License in all
* respects for all of the code used other than the HL Engine and MODs
* from Valve. If you modify this file, you may extend this exception
* to your version of the file, but you are not obligated to do so. If
* you do not wish to do so, delete this exception statement from your
* version.
*/
#include "amxmodx.h"
#include "newmenus.h"
CVector<Menu *> g_NewMenus;
CStack<int> g_MenuFreeStack;
void ClearMenus()
{
for (size_t i=0; i<g_NewMenus.size(); i++)
for (size_t i = 0; i < g_NewMenus.size(); i++)
delete g_NewMenus[i];
g_NewMenus.clear();
while (!g_MenuFreeStack.empty())
g_MenuFreeStack.pop();
}
void validate_menu_text(char *str)
{
if (!g_coloredmenus)
{
size_t offs = 0;
while (*str)
{
if (*str == '\\')
{
str++;
char c = tolower(*str);
if (c == 'r' || c == 'w'
|| c== 'w' || c == 'd')
{
str++;
offs += 2;
continue;
}
}
if (offs)
*(str-offs) = *str;
str++;
}
if (offs)
*(str-offs) = '\0';
}
}
Menu::Menu(const char *title, int mid, int tid)
@ -15,12 +77,32 @@ Menu::Menu(const char *title, int mid, int tid)
m_Title.assign(title);
menuId = mid;
thisId = tid;
m_OptNames[abs(MENU_BACK)].assign("Back");
m_OptNames[abs(MENU_MORE)].assign("More");
m_OptNames[abs(MENU_EXIT)].assign("Exit");
m_OptOrders[0] = MENU_BACK;
m_OptOrders[1] = MENU_MORE;
m_OptOrders[2] = MENU_EXIT;
m_AlwaysExit = false;
m_NeverExit = false;
m_AutoColors = g_coloredmenus;
items_per_page = 7;
func = 0;
padding = 0;
isDestroying = false;
}
Menu::~Menu()
{
for (size_t i=0; i<m_Items.size(); i++)
for (size_t i = 0; i < m_Items.size(); i++)
delete m_Items[i];
unregisterSPForward(this->func);
m_Items.clear();
}
@ -56,60 +138,53 @@ size_t Menu::GetItemCount()
size_t Menu::GetPageCount()
{
size_t items = GetItemCount();
page_t numPages = (items / MENUITEMS) + 1;
if (items_per_page == 0)
return 1;
if (!items)
return 0;
if (numPages % MENUITEMS == 0)
numPages--;
return numPages;
return ((items/items_per_page) + ((items % items_per_page) ? 1 : 0));
}
int Menu::PagekeyToItem(page_t page, item_t key)
{
page_t pages = GetPageCount();
item_t numItems = GetItemCount();
size_t start = page * items_per_page;
size_t num_pages = GetPageCount();
if (page >= pages)
if (num_pages == 1 || !items_per_page)
{
if (key > m_Items.size())
return MENU_EXIT;
item_t start = page * 7;
else
return key-1;
} else {
//first page
if (page == 0)
{
item_t rem = numItems >= 7 ? 7 : numItems;
if (key == rem)
{
if (pages > 1)
if (key == items_per_page + 1)
return MENU_MORE;
else if (key == items_per_page + 2)
return MENU_EXIT;
else
return MENU_EXIT;
} else if (key == rem+1) {
return MENU_EXIT;
}
} else if (page == pages - 1) {
//find number of remaining items
//for example, 11 items on page 1... means start=7, 11-7=4
item_t rem = numItems - start;
//however, the last item is actually this -1, so...
if (key == rem)
return (start + key - 1);
} else if (page == num_pages - 1) {
//last page
size_t remaining = m_Items.size() - start;
if (key == remaining + 1)
{
return MENU_EXIT;
} else if (key == rem+1) {
return MENU_BACK;
} else if (key == remaining + 2) {
return MENU_EXIT;
} else {
return (start + key - 1);
}
} else {
if (key == 7)
if (key > items_per_page && (key-items_per_page<=3))
{
return MENU_MORE;
} else if (key == 8) {
return MENU_BACK;
return m_OptOrders[key-items_per_page-1];
} else {
return (start + key - 1);
}
}
}
return (start + key);
}
bool Menu::Display(int player, page_t page)
@ -146,39 +221,76 @@ const char *Menu::GetTextString(int player, page_t page, int &keys)
m_Text.clear();
char buffer[255];
if (g_coloredmenus)
_snprintf(buffer, sizeof(buffer)-1, "\\y%s %d/%d\n\\w\n", m_Title.c_str(), page+1, pages);
else
_snprintf(buffer, sizeof(buffer)-1, "%s %d/%d\n\n", m_Title.c_str(), page+1, pages);
m_Text.append(buffer);
item_t start = page * 7;
item_t end = 0;
if (start + 7 <= numItems)
if (items_per_page && (pages != 1))
{
end = start + 7;
if (m_AutoColors)
_snprintf(buffer, sizeof(buffer)-1, "\\y%s %d/%d\n\\w\n", m_Title.c_str(), page + 1, pages);
else
_snprintf(buffer, sizeof(buffer)-1, "%s %d/%d\n\n", m_Title.c_str(), page + 1, pages);
} else {
end = numItems;
if (m_AutoColors)
_snprintf(buffer, sizeof(buffer)-1, "\\y%s\n\\w\n", m_Title.c_str());
else
_snprintf(buffer, sizeof(buffer)-1, "%s\n\n", m_Title.c_str());
}
m_Text.append(buffer);
enum
{
Display_Back = (1<<0),
Display_Next = (1<<1),
Display_Exit = (1<<2),
};
int flags = Display_Back|Display_Next;
item_t start = page * items_per_page;
item_t end = 0;
if (items_per_page)
{
if (start + items_per_page >= numItems)
{
end = numItems - 1;
flags &= ~Display_Next;
} else {
end = start + items_per_page - 1;
}
if (!m_NeverExit && (m_AlwaysExit || (page == 0 || page == pages-1)))
flags |= Display_Exit;
} else {
end = numItems - 1;
if (end > 10)
end = 10;
flags = 0;
}
if (page == 0)
flags &= ~Display_Back;
menuitem *pItem = NULL;
int option = 0;
keys = 0;
bool enabled = true;
int ret = 0;
for (item_t i=start; i<end; i++)
int slots = 0;
for (item_t i = start; i <= end; i++)
{
pItem = m_Items[i];
if (pItem->access && !(pItem->access & g_players[player].flags[0]))
enabled = false;
if (pItem->handler != -1)
{
ret = executeForwards(pItem->handler, player, thisId, i);
ret = executeForwards(pItem->handler, static_cast<cell>(player), static_cast<cell>(thisId), static_cast<cell>(i));
if (ret == ITEM_ENABLED)
enabled = true;
else if (ret == ITEM_DISABLED)
enabled = false;
}
if (pItem->pfn)
{
ret = (pItem->pfn)(player, thisId, i);
@ -187,12 +299,16 @@ const char *Menu::GetTextString(int player, page_t page, int &keys)
else if (ret == ITEM_DISABLED)
enabled = false;
}
if (enabled)
{
keys |= (1<<option);
if (m_AutoColors)
_snprintf(buffer, sizeof(buffer)-1, "\\r%d.\\w %s\n", ++option, pItem->name.c_str());
else
_snprintf(buffer, sizeof(buffer)-1, "%d. %s\n", ++option, pItem->name.c_str());
} else {
if (g_coloredmenus)
if (m_AutoColors)
{
_snprintf(buffer, sizeof(buffer)-1, "\\d%d. %s\n\\w", ++option, pItem->name.c_str());
} else {
@ -200,35 +316,96 @@ const char *Menu::GetTextString(int player, page_t page, int &keys)
option++;
}
}
slots++;
m_Text.append(buffer);
}
//now for a weird part >:o
//this will either be MORE or BACK..
keys |= (1<<option++);
if ((page < pages - 1) && (pages > 1))
//attach blanks
if (pItem->blanks.size())
{
_snprintf(buffer, sizeof(buffer)-1, "%d. %s\n", option, "More");
} else {
_snprintf(buffer, sizeof(buffer)-1, "%d. %s\n", option, "Exit");
for (size_t j=0; j<pItem->blanks.size(); j++)
{
if (pItem->blanks[j] == 1)
option++;
m_Text.append("\n");
slots++;
}
m_Text.append(buffer);
if (pages > 1)
}
}
if (padding == 1 && items_per_page)
{
int pad = items_per_page;
if (flags & Display_Back)
pad--;
if (flags & Display_Next)
pad--;
if (flags & Display_Exit)
pad--;
for (int i=slots+1; i<=pad; i++)
{
m_Text.append("\n");
option++;
}
}
for (int i=0; i<3; i++)
{
switch (m_OptOrders[i])
{
case MENU_BACK:
{
if (flags & Display_Back)
{
keys |= (1<<option++);
if (pages == 0)
{
_snprintf(buffer, sizeof(buffer)-1, "%d. %s\n", option, "Exit");
} else {
_snprintf(buffer, sizeof(buffer)-1, "%d. %s\n", option, "Back");
}
_snprintf(buffer,
sizeof(buffer)-1,
m_AutoColors ? "\\r%d. \\w%s\n" : "%d. %s\n",
option,
m_OptNames[abs(MENU_BACK)].c_str()
);
m_Text.append(buffer);
}
break;
}
case MENU_MORE:
{
if (flags & Display_Next)
{
keys |= (1<<option++);
_snprintf(buffer,
sizeof(buffer)-1,
m_AutoColors ? "\\r%d. \\w%s\n" : "%d. %s\n",
option,
m_OptNames[abs(MENU_MORE)].c_str()
);
m_Text.append(buffer);
}
break;
}
case MENU_EXIT:
{
if (flags & Display_Exit)
{
keys |= (1<<option++);
_snprintf(buffer,
sizeof(buffer)-1,
m_AutoColors ? "\\r%d. \\w%s\n" : "%d. %s\n",
option,
m_OptNames[abs(MENU_EXIT)].c_str()
);
m_Text.append(buffer);
}
break;
}
}
}
return m_Text.c_str();
}
#define GETMENU(p) if (p >= (int)g_NewMenus.size() || p < 0) { \
LogError(amx, AMX_ERR_NATIVE, "Invalid menu id %d", p); \
#define GETMENU(p) if (p >= (int)g_NewMenus.size() || p < 0 || !g_NewMenus[p] || g_NewMenus[p]->isDestroying) { \
LogError(amx, AMX_ERR_NATIVE, "Invalid menu id %d(%d)", p, g_NewMenus.size()); \
return 0; } \
Menu *pMenu = g_NewMenus[p];
@ -238,9 +415,11 @@ static cell AMX_NATIVE_CALL menu_create(AMX *amx, cell *params)
{
int len;
char *title = get_amxstring(amx, params[1], 0, len);
validate_menu_text(title);
char *handler = get_amxstring(amx, params[2], 1, len);
int func = registerSPForwardByName(amx, handler, FP_CELL, FP_CELL, FP_CELL, FP_DONE);
if (func == -1)
{
LogError(amx, AMX_ERR_NOTFOUND, "Invalid function \"%s\"", handler);
@ -248,12 +427,46 @@ static cell AMX_NATIVE_CALL menu_create(AMX *amx, cell *params)
}
int id = g_menucmds.registerMenuId(title, amx);
g_menucmds.registerMenuCmd( g_plugins.findPluginFast(amx), id, 1023, func );
g_menucmds.registerMenuCmd(g_plugins.findPluginFast(amx), id, 1023, func);
Menu *pMenu = new Menu(title, id, (int)g_NewMenus.size());
Menu *pMenu = new Menu(title, id, 0);
pMenu->func = func;
if (g_MenuFreeStack.empty())
{
g_NewMenus.push_back(pMenu);
pMenu->thisId = (int)g_NewMenus.size() - 1;
return (int)g_NewMenus.size() - 1;
} else {
int pos = g_MenuFreeStack.front();
g_MenuFreeStack.pop();
g_NewMenus[pos] = pMenu;
pMenu->thisId = pos;
return pos;
}
}
static cell AMX_NATIVE_CALL menu_addblank(AMX *amx, cell *params)
{
GETMENU(params[1]);
if (params[2] && (!pMenu->items_per_page && pMenu->GetItemCount() >= 10))
{
LogError(amx, AMX_ERR_NATIVE, "Non-paginated menus are limited to 10 items.");
return 0;
}
if (!pMenu->m_Items.size())
{
LogError(amx, AMX_ERR_NATIVE, "Blanks can only be added after items.");
return 0;
}
menuitem *item = pMenu->m_Items[pMenu->m_Items.size() - 1];
item->blanks.push_back(params[2]);
return 1;
}
//Adds an item to the menu (returns current item count - 1)
@ -266,7 +479,14 @@ static cell AMX_NATIVE_CALL menu_additem(AMX *amx, cell *params)
GETMENU(params[1]);
if (!pMenu->items_per_page && pMenu->GetItemCount() >= 10)
{
LogError(amx, AMX_ERR_NATIVE, "Non-paginated menus are limited to 10 items.");
return 0;
}
name = get_amxstring(amx, params[2], 0, len);
validate_menu_text(name);
cmd = get_amxstring(amx, params[3], 1, len);
access = params[4];
@ -302,6 +522,10 @@ static cell AMX_NATIVE_CALL menu_display(AMX *amx, cell *params)
int player = params[1];
int page = params[3];
CPlayer* pPlayer = GET_PLAYER_POINTER_I(player);
// This will set the expire time of the menu to infinite
pPlayer->menuexpire = INFINITE;
return pMenu->Display(player, page);
}
@ -363,15 +587,285 @@ static cell AMX_NATIVE_CALL menu_makecallback(AMX *amx, cell *params)
return id;
}
static cell AMX_NATIVE_CALL menu_item_setname(AMX *amx, cell *params)
{
GETMENU(params[1]);
menuitem *pItem = pMenu->GetMenuItem(static_cast<item_t>(params[2]));
if (!pItem)
return 0;
int len;
char *name;
name = get_amxstring(amx, params[3], 0, len);
pItem->name.assign(name);
return 1;
}
static cell AMX_NATIVE_CALL menu_item_setcmd(AMX *amx, cell *params)
{
GETMENU(params[1]);
menuitem *pItem = pMenu->GetMenuItem(static_cast<item_t>(params[2]));
if (!pItem)
return 0;
int len;
char *cmd;
cmd = get_amxstring(amx, params[3], 0, len);
pItem->cmd.assign(cmd);
return 1;
}
static cell AMX_NATIVE_CALL menu_item_setcall(AMX *amx, cell *params)
{
GETMENU(params[1]);
menuitem *pItem = pMenu->GetMenuItem(static_cast<item_t>(params[2]));
if (!pItem)
return 0;
pItem->handler = params[3];
return 1;
}
static cell AMX_NATIVE_CALL menu_setprop(AMX *amx, cell *params)
{
GETMENU(params[1]);
int len = params[0] / sizeof(cell);
if (len < 3)
{
LogError(amx, AMX_ERR_NATIVE, "Expected 3 parameters");
return 0;
}
switch (params[2])
{
case MPROP_PERPAGE:
{
cell count = *get_amxaddr(amx, params[3]);
if (count < 0 || count > 7)
{
LogError(amx, AMX_ERR_NATIVE, "Cannot set %d items per page", count);
return 0;
}
pMenu->items_per_page = count;
break;
}
case MPROP_BACKNAME:
{
char *str = get_amxstring(amx, params[3], 0, len);
validate_menu_text(str);
pMenu->m_OptNames[abs(MENU_BACK)].assign(str);
break;
}
case MPROP_NEXTNAME:
{
char *str = get_amxstring(amx, params[3], 0, len);
validate_menu_text(str);
pMenu->m_OptNames[abs(MENU_MORE)].assign(str);
break;
}
case MPROP_EXITNAME:
{
char *str = get_amxstring(amx, params[3], 0, len);
validate_menu_text(str);
pMenu->m_OptNames[abs(MENU_EXIT)].assign(str);
break;
}
case MPROP_TITLE:
{
char *str = get_amxstring(amx, params[3], 0, len);
int old = pMenu->menuId;
g_menucmds.removeMenuId(old);
pMenu->m_Title.assign(str);
pMenu->menuId = g_menucmds.registerMenuId(str, amx);
g_menucmds.registerMenuCmd(
g_plugins.findPluginFast(amx),
pMenu->menuId,
1023,
pMenu->func);
CPlayer *pl;
/**
* NOTE - this is actually bogus
* the client's screen won't actually match the cmd here
* I think, this scenario needs to be tested.
*/
for (int i=1; i<=gpGlobals->maxClients; i++)
{
pl = GET_PLAYER_POINTER_I(i);
if (pl->menu == old)
pl->menu = pMenu->menuId;
}
break;
}
case MPROP_EXITALL:
{
cell ans = *get_amxaddr(amx, params[3]);
if (ans == 1)
{
pMenu->m_AlwaysExit = true;
pMenu->m_NeverExit = false;
} else if (ans == 0) {
pMenu->m_AlwaysExit = false;
pMenu->m_NeverExit = false;
} else if (ans == -1) {
pMenu->m_NeverExit = true;
pMenu->m_AlwaysExit = false;
}
break;
}
case MPROP_ORDER:
{
cell *addr = get_amxaddr(amx, params[3]);
pMenu->m_OptOrders[0] = addr[0];
pMenu->m_OptOrders[1] = addr[1];
pMenu->m_OptOrders[2] = addr[2];
break;
}
case MPROP_NOCOLORS:
{
pMenu->m_AutoColors = *get_amxaddr(amx, params[3]) ? true : false;
break;
}
case MPROP_PADMENU:
{
pMenu->padding = *get_amxaddr(amx, params[3]);
break;
}
default:
{
LogError(amx, AMX_ERR_NATIVE, "Invalid menu setting: %d", params[1]);
return 0;
}
}
return 1;
}
#define GETMENU_R(p) if (p >= (int)g_NewMenus.size() || p < 0 || !g_NewMenus[p]) { \
LogError(amx, AMX_ERR_NATIVE, "Invalid menu id %d(%d)", p, g_NewMenus.size()); \
return 0; } \
Menu *pMenu = g_NewMenus[p];
static cell AMX_NATIVE_CALL menu_cancel(AMX *amx, cell *params)
{
int index = params[1];
if (index < 1 || index > gpGlobals->maxClients)
{
LogError(amx, AMX_ERR_NATIVE, "Player %d is not valid", index);
return 0;
}
CPlayer *player = GET_PLAYER_POINTER_I(index);
if (!player->ingame)
{
LogError(amx, AMX_ERR_NATIVE, "Played %d is not in game", index);
return 0;
}
int menu = player->newmenu;
if (menu < 0 || menu >= (int)g_NewMenus.size() || !g_NewMenus[menu])
return 0;
Menu *pMenu = g_NewMenus[menu];
player->newmenu = -1;
player->menu = 0;
executeForwards(pMenu->func,
static_cast<cell>(index),
static_cast<cell>(pMenu->thisId),
static_cast<cell>(MENU_EXIT));
return 1;
}
static cell AMX_NATIVE_CALL menu_destroy(AMX *amx, cell *params)
{
GETMENU_R(params[1]);
if (pMenu->isDestroying)
return 0; //prevent infinite recursion
pMenu->isDestroying = true;
g_menucmds.removeMenuId(pMenu->menuId);
CPlayer *player;
for (int i=1; i<=gpGlobals->maxClients; i++)
{
player = GET_PLAYER_POINTER_I(i);
if (player->newmenu == pMenu->thisId)
{
player->newmenu = -1;
player->menu = 0;
executeForwards(pMenu->func,
static_cast<cell>(i),
static_cast<cell>(pMenu->thisId),
static_cast<cell>(MENU_EXIT));
}
}
g_NewMenus[params[1]] = NULL;
delete pMenu;
g_MenuFreeStack.push(params[1]);
return 1;
}
static cell AMX_NATIVE_CALL player_menu_info(AMX *amx, cell *params)
{
if (params[1] < 1 || params[1] > gpGlobals->maxClients)
{
LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", params[1]);
return 0;
}
CPlayer *player = GET_PLAYER_POINTER_I(params[1]);
if (!player->ingame)
{
LogError(amx, AMX_ERR_NATIVE, "Player %d is not ingame", params[1]);
return 0;
}
cell *m = get_amxaddr(amx, params[2]);
cell *n = get_amxaddr(amx, params[3]);
*m = player->menu;
*n = player->newmenu;
if ( (*m != 0 && *m != -1) || (*n != -1))
return 1;
return 0;
}
AMX_NATIVE_INFO g_NewMenuNatives[] =
{
{"menu_create", menu_create},
{"menu_additem", menu_additem},
{"menu_addblank", menu_addblank},
{"menu_pages", menu_pages},
{"menu_items", menu_items},
{"menu_display", menu_display},
{"menu_find_id", menu_find_id},
{"menu_item_getinfo", menu_item_getinfo},
{"menu_makecallback", menu_makecallback},
{"menu_item_setcall", menu_item_setcall},
{"menu_item_setcmd", menu_item_setcmd},
{"menu_item_setname", menu_item_setname},
{"menu_destroy", menu_destroy},
{"menu_setprop", menu_setprop},
{"menu_cancel", menu_cancel},
{"player_menu_info", player_menu_info},
{NULL, NULL},
};

View File

@ -1,3 +1,34 @@
/* AMX Mod X
*
* by the AMX Mod X Development Team
* originally developed by OLO
*
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* 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, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* In addition, as a special exception, the author gives permission to
* link the code of this program with the Half-Life Game Engine ("HL
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
* L.L.C ("Valve"). You must obey the GNU General Public License in all
* respects for all of the code used other than the HL Engine and MODs
* from Valve. If you modify this file, you may extend this exception
* to your version of the file, but you are not obligated to do so. If
* you do not wish to do so, delete this exception statement from your
* version.
*/
#ifndef _INCLUDE_NEWMENUS_H
#define _INCLUDE_NEWMENUS_H
@ -8,7 +39,16 @@
#define ITEM_ENABLED 1
#define ITEM_DISABLED 2
#define MENUITEMS 7
#define MPROP_PERPAGE 1
#define MPROP_BACKNAME 2
#define MPROP_NEXTNAME 3
#define MPROP_EXITNAME 4
#define MPROP_TITLE 5
#define MPROP_EXITALL 6
#define MPROP_ORDER 7
#define MPROP_NOCOLORS 8
#define MPROP_PADMENU 9
typedef int (*MENUITEM_CALLBACK)(int, int, int);
@ -16,10 +56,14 @@ struct menuitem
{
String name;
String cmd;
int access;
int handler;
MENUITEM_CALLBACK pfn;
size_t id;
CVector<int> blanks;
};
typedef unsigned int menu_t;
@ -31,35 +75,38 @@ class Menu
public:
Menu(const char *title, int menuId, int thisId);
~Menu();
menuitem *GetMenuItem(item_t item);
size_t GetPageCount();
size_t GetItemCount();
menuitem *AddItem(const char *name, const char *cmd, int access);
const char *GetTextString(int player, page_t page, int &keys);
bool Display(int player, page_t page);
int PagekeyToItem(page_t page, item_t key);
int GetMenuMenuid();
private:
public:
CVector<menuitem * > m_Items;
String m_Title;
String m_Text;
String m_OptNames[4];
int m_OptOrders[3];
bool m_AlwaysExit;
bool m_NeverExit;
bool m_AutoColors;
int menuId;
int thisId;
int func;
int padding;
bool isDestroying;
public:
unsigned int items_per_page;
};
/*Menu *CreateMenu(const char *title);
Menu *GetMenuById(menu_t menu);
menuitem *GetMenuItem(menu_t menu, item_t item);
size_t GetMenuPages(menu_t menu);
size_t GetMenuItems(menu_t menu);
menuitem *AddMenuItem(menu_t menu, const char *name, const char *cmd, int access);
bool DisplayMenu(menu_t menu, int player, page_t page);
int MenuPagekeyToItem(menu_t menu, page_t page, int key);
int FindByMenuid(int menuid);
int GetMenuMenuid(menu_t menu);
const char *GetItemName(menu_t menu, item_t item);
const char *GetItemCmd(menu_t menu, item_t item);*/
void ClearMenus();
extern CVector<Menu *> g_NewMenus;

123
amxmodx/optimizer.cpp Normal file
View File

@ -0,0 +1,123 @@
#include <string.h>
#include "optimizer.h"
int g_opt_level = 0;
#define OP_SYSREQ_C 123
#define OP_NOP 134
#define OP_FLOAT_MUL 138
#define OP_FLOAT_DIV 139
#define OP_FLOAT_ADD 140
#define OP_FLOAT_SUB 141
#define OP_FLOAT_TO 142
#define OP_FLOAT_ROUND 143
#define OP_FLOAT_CMP 144
cell op_trans_table[N_Total_FloatOps] =
{
OP_FLOAT_MUL,
OP_FLOAT_DIV,
OP_FLOAT_ADD,
OP_FLOAT_SUB,
OP_FLOAT_TO,
OP_FLOAT_ROUND,
OP_FLOAT_CMP
};
void OnBrowseRelocate(AMX *amx, cell *oplist, cell *cip)
{
char *codeptr = (char *)amx->base + (long)(((AMX_HEADER *)amx->base)->cod);
//jump to the parameter;
codeptr += *cip;
int native = -1;
cell n_offs = *(cell *)codeptr;
optimizer_s *opt = (optimizer_s *)amx->usertags[UT_OPTIMIZER];
for (int i=0; i<N_Total_FloatOps; i++)
{
if (opt->natives[i] == n_offs)
{
native = i;
break;
}
}
if (native != -1)
{
//we're patching this:
// 0x7B 0x?? SYSREQ.C float???
//with:
// 0x8A FLOAT.MUL
// 0x86 NOP
cell new_opcodes[2];
new_opcodes[0] = op_trans_table[native];
new_opcodes[1] = OP_NOP;
codeptr -= sizeof(cell);
#if defined __GNUC__ || defined ASM32 || defined JIT
*(cell *)codeptr = oplist[new_opcodes[0]];
*(cell *)(codeptr + sizeof(cell)) = oplist[new_opcodes[1]];
#else
*(cell *)codeptr = new_opcodes[0];
*(cell *)(codeptr + sizeof(cell)) = new_opcodes[1];
#endif
}
*cip += sizeof(cell);
return;
}
#define FIND_NATIVE(name, bind) \
if (amx_FindNative(amx, name, &index) != AMX_ERR_NOTFOUND) \
opt->natives[bind] = index;
void _Setup_Optimizer_Stage2(AMX *amx, cell *oplist, cell *cip)
{
int index;
amx->usertags[UT_BROWSEHOOK] = (void *)OnBrowseRelocate;
optimizer_s *opt = new optimizer_s;
for (int i=0; i<N_Total_FloatOps; i++)
opt->natives[i] = -1;
amx->usertags[UT_OPTIMIZER] = (void *)opt;
if (g_opt_level & 1)
{
FIND_NATIVE("floatmul", N_Float_Mul);
FIND_NATIVE("floatdiv", N_Float_Div);
FIND_NATIVE("floatadd", N_Float_Add);
FIND_NATIVE("floatsub", N_Float_Sub);
}
if (g_opt_level & 4)
{
FIND_NATIVE("float", N_Float_To);
FIND_NATIVE("floatround", N_Float_Round);
}
if (g_opt_level & 2)
{
#if !defined AMD64
if (amxx_CpuSupport())
{
#endif
FIND_NATIVE("floatcmp", N_Float_Cmp);
#if !defined AMD64
} else {
g_opt_level &= ~(2);
}
#endif
}
//we don't do these yet because of radix stuff >:\
//FIND_NATIVE("floatsin", N_Float_Sin);
//FIND_NATIVE("floatcos", N_Float_Cos);
//FIND_NATIVE("floattan", N_Float_Tan);
}
void SetupOptimizer(AMX *amx)
{
amx->usertags[UT_BROWSEHOOK] = (void *)_Setup_Optimizer_Stage2;
}

29
amxmodx/optimizer.h Normal file
View File

@ -0,0 +1,29 @@
#ifndef _INCLUDE_AMXMODX_OPTIMIZER_H
#define _INCLUDE_AMXMODX_OPTIMIZER_H
#include "amx.h"
enum
{
N_Float_Mul=0,
N_Float_Div,
N_Float_Add,
N_Float_Sub,
N_Float_To,
N_Float_Round,
N_Float_Cmp,
/* ------------ */
N_Total_FloatOps,
};
struct optimizer_s
{
int natives[N_Total_FloatOps];
};
void SetupOptimizer(AMX *amx);
extern "C" int amxx_CpuSupport();
extern int g_opt_level;
#endif //_INCLUDE_AMXMODX_OPTIMIZER_H

View File

@ -45,8 +45,6 @@
enginefuncs_t g_engfuncs;
globalvars_t *gpGlobals;
DLL_FUNCTIONS *g_pFunctionTable;
DLL_FUNCTIONS *g_pFunctionTable_Post;
enginefuncs_t *g_pengfuncsTable;
@ -54,7 +52,6 @@ enginefuncs_t *g_pengfuncsTable_Post;
NEW_DLL_FUNCTIONS *g_pNewFunctionsTable;
NEW_DLL_FUNCTIONS *g_pNewFunctionsTable_Post;
// GetEntityAPI2 functions
static DLL_FUNCTIONS g_EntityAPI_Table =
{
@ -2433,7 +2430,9 @@ static amxx_module_info_s g_ModuleInfo =
#else // MODULE_RELOAD_ON_MAPCHANGE
0,
#endif // MODULE_RELOAD_ON_MAPCHANGE
MODULE_LOGTAG
MODULE_LOGTAG,
MODULE_LIBRARY,
MODULE_LIBCLASS
};
// Storage for the requested functions
@ -2481,9 +2480,11 @@ PFN_IS_PLAYER_CONNECTING g_fn_IsPlayerConnecting;
PFN_IS_PLAYER_HLTV g_fn_IsPlayerHLTV;
PFN_GET_PLAYER_ARMOR g_fn_GetPlayerArmor;
PFN_GET_PLAYER_HEALTH g_fn_GetPlayerHealth;
#ifdef MEMORY_TEST
PFN_ALLOCATOR g_fn_Allocator;
PFN_REALLOCATOR g_fn_Reallocator;
PFN_DEALLOCATOR g_fn_Deallocator;
#endif
PFN_AMX_EXEC g_fn_AmxExec;
PFN_AMX_EXECV g_fn_AmxExecv;
PFN_AMX_ALLOT g_fn_AmxAllot;
@ -2503,6 +2504,17 @@ PFN_FORMAT g_fn_Format;
PFN_REGISTERFUNCTION g_fn_RegisterFunction;
PFN_REQ_FNPTR g_fn_RequestFunction;
PFN_AMX_PUSH g_fn_AmxPush;
PFN_SET_TEAM_INFO g_fn_SetTeamInfo;
PFN_PLAYER_PROP_ADDR g_fn_PlayerPropAddr;
PFN_REG_AUTH_FUNC g_fn_RegAuthFunc;
PFN_UNREG_AUTH_FUNC g_fn_UnregAuthFunc;
PFN_FINDLIBRARY g_fn_FindLibrary;
PFN_ADDLIBRARIES g_fn_AddLibraries;
PFN_REMOVELIBRARIES g_fn_RemoveLibraries;
PFN_OVERRIDENATIVES g_fn_OverrideNatives;
PFN_GETLOCALINFO g_fn_GetLocalInfo;
PFN_AMX_REREGISTER g_fn_AmxReRegister;
PFN_REGISTERFUNCTIONEX g_fn_RegisterFunctionEx;
// *** Exports ***
C_DLLEXPORT int AMXX_Query(int *interfaceVersion, amxx_module_info_s *moduleInfo)
@ -2553,6 +2565,7 @@ C_DLLEXPORT int AMXX_Attach(PFN_REQ_FNPTR reqFnptrFunc)
REQFUNC("MergeDefinitionFile", g_fn_MergeDefinition_File, PFN_MERGEDEFINITION_FILE);
REQFUNC("Format", g_fn_Format, PFN_FORMAT);
REQFUNC("RegisterFunction", g_fn_RegisterFunction, PFN_REGISTERFUNCTION);
REQFUNC("RegisterFunctionEx", g_fn_RegisterFunctionEx, PFN_REGISTERFUNCTIONEX);
// Amx scripts
REQFUNC("GetAmxScript", g_fn_GetAmxScript, PFN_GET_AMXSCRIPT);
@ -2612,11 +2625,25 @@ C_DLLEXPORT int AMXX_Attach(PFN_REQ_FNPTR reqFnptrFunc)
REQFUNC("GetPlayerFlags", g_fn_GetPlayerFlags, PFN_GETPLAYERFLAGS);
REQFUNC("GetPlayerEdict", g_fn_GetPlayerEdict, PFN_GET_PLAYER_EDICT);
REQFUNC("amx_Push", g_fn_AmxPush, PFN_AMX_PUSH);
REQFUNC("SetPlayerTeamInfo", g_fn_SetTeamInfo, PFN_SET_TEAM_INFO);
REQFUNC("PlayerPropAddr", g_fn_PlayerPropAddr, PFN_PLAYER_PROP_ADDR);
REQFUNC("RegAuthFunc", g_fn_RegAuthFunc, PFN_REG_AUTH_FUNC);
REQFUNC("UnregAuthFunc", g_fn_UnregAuthFunc, PFN_UNREG_AUTH_FUNC);
//Added in 1.75
REQFUNC("FindLibrary", g_fn_FindLibrary, PFN_FINDLIBRARY);
REQFUNC("AddLibraries", g_fn_AddLibraries, PFN_ADDLIBRARIES);
REQFUNC("RemoveLibraries", g_fn_RemoveLibraries, PFN_REMOVELIBRARIES);
REQFUNC("OverrideNatives", g_fn_OverrideNatives, PFN_OVERRIDENATIVES);
REQFUNC("GetLocalInfo", g_fn_GetLocalInfo, PFN_GETLOCALINFO);
REQFUNC("AmxReregister", g_fn_AmxReRegister, PFN_AMX_REREGISTER);
#ifdef MEMORY_TEST
// Memory
REQFUNC_OPT("Allocator", g_fn_Allocator, PFN_ALLOCATOR);
REQFUNC_OPT("Reallocator", g_fn_Reallocator, PFN_REALLOCATOR);
REQFUNC_OPT("Deallocator", g_fn_Deallocator, PFN_DEALLOCATOR);
#endif
REQFUNC("CellToReal", g_fn_CellToReal, PFN_CELL_TO_REAL);
REQFUNC("RealToCell", g_fn_RealToCell, PFN_REAL_TO_CELL);
@ -2645,14 +2672,27 @@ C_DLLEXPORT int AMXX_PluginsLoaded()
return AMXX_OK;
}
C_DLLEXPORT void AMXX_PluginsUnloaded()
{
#ifdef FN_AMXX_PLUGINSUNLOADED
FN_AMXX_PLUGINSUNLOADED();
#endif // FN_AMXX_PLUGINSUNLOADED
}
C_DLLEXPORT void AMXX_PluginsUnloading()
{
#ifdef FN_AMXX_PLUGINSUNLOADING
FN_AMXX_PLUGINSUNLOADING();
#endif // FN_AMXX_PLUGINSUNLOADING
}
// Advanced MF functions
void MF_Log(const char *fmt, ...)
{
// :TODO: Overflow possible here
char msg[3072];
va_list arglst;
va_start(arglst, fmt);
vsprintf(msg, fmt, arglst);
vsnprintf(msg, sizeof(msg) - 1, fmt, arglst);
va_end(arglst);
g_fn_Log("[%s] %s", MODULE_LOGTAG, msg);
@ -2660,11 +2700,10 @@ void MF_Log(const char *fmt, ...)
void MF_LogError(AMX *amx, int err, const char *fmt, ...)
{
// :TODO: Overflow possible here
char msg[3072];
va_list arglst;
va_start(arglst, fmt);
vsprintf(msg, fmt, arglst);
vsnprintf(msg, sizeof(msg) - 1, fmt, arglst);
va_end(arglst);
g_fn_LogErrorFunc(amx, err, "[%s] %s", MODULE_LOGTAG, msg);
@ -2732,9 +2771,20 @@ void ValidateMacros_DontCallThis_Smiley()
MF_GetPlayerEdict(0);
MF_Format("", 4, "str");
MF_RegisterFunction(NULL, "");
MF_RegisterFunctionEx(NULL, "");
MF_SetPlayerTeamInfo(0, 0, "");
MF_PlayerPropAddr(0, 0);
MF_RegAuthFunc(NULL);
MF_UnregAuthFunc(NULL);
MF_FindLibrary(NULL, LibType_Class);
MF_AddLibraries(NULL, LibType_Class, NULL);
MF_RemoveLibraries(NULL);
MF_OverrideNatives(NULL, NULL);
}
#endif
#ifdef MEMORY_TEST
/************* MEMORY *************/
// undef all defined macros
#undef new
@ -2906,6 +2956,30 @@ void operator delete[](void *reportedAddress)
Mem_Deallocator(g_Mem_CurrentFilename, g_Mem_CurrentLine, g_Mem_CurrentFunc, m_alloc_delete_array, reportedAddress);
}
#else
#if !defined NO_ALLOC_OVERRIDES && !defined MEMORY_TEST && !defined WIN32
void * operator new(size_t size) {
return(calloc(1, size));
}
void * operator new[](size_t size) {
return(calloc(1, size));
}
void operator delete(void * ptr) {
if(ptr)
free(ptr);
}
void operator delete[](void * ptr) {
if(ptr)
free(ptr);
}
#endif
#endif //MEMORY_TEST
/************* stuff from dlls/util.cpp *************/
// must come here because cbase.h declares it's own operator new

View File

@ -34,7 +34,8 @@
// module interface version was 1
// 2 - added logtag to struct (amxx1.1-rc1)
// 3 - added new tagAMX structure (amxx1.5)
#define AMXX_INTERFACE_VERSION 3
// 4 - added new 'library' setting for direct loading
#define AMXX_INTERFACE_VERSION 4
// amxx module info
struct amxx_module_info_s
@ -44,10 +45,10 @@ struct amxx_module_info_s
const char *version;
int reload; // reload on mapchange when nonzero
const char *logtag; // added in version 2
const char *library; // added in version 4
const char *libclass; // added in version 4
};
// return values from functions called by amxx
#define AMXX_OK 0 /* no error */
#define AMXX_IFVERS 1 /* interface version */
@ -158,6 +159,134 @@ typedef int (AMXAPI *AMX_DEBUG)(struct tagAMX *amx);
#pragma warning(disable:4103) /* disable warning message 4103 that complains
* about pragma pack in a header file */
#pragma warning(disable:4100) /* "'%$S' : unreferenced formal parameter" */
#if _MSC_VER >= 1400
#if !defined NO_MSVC8_AUTO_COMPAT
/* Disable deprecation warnings concerning unsafe CRT functions */
#if !defined _CRT_SECURE_NO_DEPRECATE
#define _CRT_SECURE_NO_DEPRECATE
#endif
/* Replace the POSIX function with ISO C++ conformant ones as they are now deprecated */
#define access _access
#define cabs _cabs
#define cgets _cgets
#define chdir _chdir
#define chmod _chmod
#define chsize _chsize
#define close _close
#define cprintf _cprintf
#define cputs _cputts
#define creat _creat
#define cscanf _cscanf
#define cwait _cwait
#define dup _dup
#define dup2 _dup2
#define ecvt _ecvt
#define eof _eof
#define execl _execl
#define execle _execle
#define execlp _execlp
#define execlpe _execlpe
#define execv _execv
#define execve _execv
#define execvp _execvp
#define execvpe _execvpe
#define fcloseall _fcloseall
#define fcvt _fcvt
#define fdopen _fdopen
#define fgetchar _fgetchar
#define filelength _filelength
#define fileno _fileno
#define flushall _flushall
#define fputchar _fputchar
#define gcvt _gcvt
#define getch _getch
#define getche _getche
#define getcwd _getcwd
#define getpid _getpid
#define getw _getw
#define hypot _hypot
#define inp _inp
#define inpw _inpw
#define isascii __isascii
#define isatty _isatty
#define iscsym __iscsym
#define iscsymf __iscsymf
#define itoa _itoa
#define j0 _j0
#define j1 _j1
#define jn _jn
#define kbhit _kbhit
#define lfind _lfind
#define locking _locking
#define lsearch _lsearch
#define lseek _lseek
#define ltoa _ltoa
#define memccpy _memccpy
#define memicmp _memicmp
#define mkdir _mkdir
#define mktemp _mktemp
#define open _open
#define outp _outp
#define outpw _outpw
#define putch _putch
#define putenv _putenv
#define putw _putw
#define read _read
#define rmdir _rmdir
#define rmtmp _rmtmp
#define setmode _setmode
#define sopen _sopen
#define spawnl _spawnl
#define spawnle _spawnle
#define spawnlp _spawnlp
#define spawnlpe _spawnlpe
#define spawnv _spawnv
#define spawnve _spawnve
#define spawnvp _spawnvp
#define spawnvpe _spawnvpe
#define strcmpi _strcmpi
#define strdup _strdup
#define stricmp _stricmp
#define strlwr _strlwr
#define strnicmp _strnicmp
#define strnset _strnset
#define strrev _strrev
#define strset _strset
#define strupr _strupr
#define swab _swab
#define tell _tell
#define tempnam _tempnam
#define toascii __toascii
#define tzset _tzset
#define ultoa _ultoa
#define umask _umask
#define ungetch _ungetch
#define unlink _unlink
#define wcsdup _wcsdup
#define wcsicmp _wcsicmp
#define wcsicoll _wcsicoll
#define wcslwr _wcslwr
#define wcsnicmp _wcsnicmp
#define wcsnset _wcsnset
#define wcsrev _wcsrev
#define wcsset _wcsset
#define wcsupr _wcsupr
#define write _write
#define y0 _y0
#define y1 _y1
#define yn _yn
/* Disable deprecation warnings because MSVC8 seemingly thinks the ISO C++ conformant
* functions above are deprecated. */
#pragma warning (disable:4996)
#endif
#else
#define vsnprintf _vsnprintf
#endif
#endif
@ -1906,6 +2035,14 @@ void FN_AMXX_DETACH(void);
void FN_AMXX_PLUGINSLOADED(void);
#endif // FN_AMXX_PLUGINSLOADED
#ifdef FN_AMXX_PLUGINSUNLOADING
void FN_AMXX_PLUGINSUNLOADING(void);
#endif // FN_AMXX_PLUGINSUNLOADING
#ifdef FN_AMXX_PLUGINSUNLOADED
void FN_AMXX_PLUGINSUNLOADED(void);
#endif // FN_AMXX_PLUGINSUNLOADED
// *** Types ***
typedef void* (*PFN_REQ_FNPTR)(const char * /*name*/);
@ -1929,6 +2066,36 @@ enum ForwardParam
FP_ARRAY, // array; use the return value of prepareArray.
};
enum PlayerProp
{
Player_Name, //String
Player_Ip, //String
Player_Team, //String
Player_Ingame, //bool
Player_Authorized, //bool
Player_Vgui, //bool
Player_Time, //float
Player_Playtime, //float
Player_MenuExpire, //float
Player_Weapons, //struct{int,int}[32]
Player_CurrentWeapon, //int
Player_TeamID, //int
Player_Deaths, //int
Player_Aiming, //int
Player_Menu, //int
Player_Keys, //int
Player_Flags, //int[32]
Player_Newmenu, //int
Player_NewmenuPage, //int
};
enum LibType
{
LibType_Library,
LibType_Class
};
typedef void (*AUTHORIZEFUNC)(int player, const char *authstring);
typedef int (*PFN_ADD_NATIVES) (const AMX_NATIVE_INFO * /*list*/);
typedef char * (*PFN_BUILD_PATHNAME) (const char * /*format*/, ...);
@ -1980,13 +2147,16 @@ typedef edict_t * (*PFN_GET_PLAYER_EDICT) (int /*id*/);
#else
typedef void * (*PFN_GET_PLAYER_EDICT) (int /*id*/);
#endif
typedef void * (*PFN_PLAYER_PROP_ADDR) (int /*id*/, int /*prop*/);
#ifdef MEMORY_TEST
typedef void * (*PFN_ALLOCATOR) (const char* /*filename*/, const unsigned int /*line*/, const char* /*func*/,
const unsigned int /*type*/, const size_t /*size*/);
typedef void * (*PFN_REALLOCATOR) (const char* /*filename*/, const unsigned int /*line*/, const char* /*func*/,
const unsigned int /*type*/, const size_t /*size*/, void* /*addr*/ );
typedef void (*PFN_DEALLOCATOR) (const char* /*filename*/, const unsigned int /*line*/, const char* /*func*/,
const unsigned int /*type*/, const void* /*addr*/ );
#endif
typedef int (*PFN_AMX_EXEC) (AMX* /*amx*/, cell* /*return val*/, int /*index*/);
typedef int (*PFN_AMX_EXECV) (AMX* /*amx*/, cell* /*return val*/, int /*index*/, int /*numparams*/, cell[] /*params*/);
typedef int (*PFN_AMX_ALLOT) (AMX* /*amx*/, int /*length*/, cell* /*amx_addr*/, cell** /*phys_addr*/);
@ -2003,6 +2173,16 @@ typedef void (*PFN_MERGEDEFINITION_FILE) (const char * /*filename*/);
typedef const char * (*PFN_FORMAT) (const char * /*fmt*/, ... /*params*/);
typedef void (*PFN_REGISTERFUNCTION) (void * /*pfn*/, const char * /*desc*/);
typedef int (*PFN_AMX_PUSH) (AMX * /*amx*/, cell /*value*/);
typedef int (*PFN_SET_TEAM_INFO) (int /*player */, int /*teamid */, const char * /*name */);
typedef void (*PFN_REG_AUTH_FUNC) (AUTHORIZEFUNC);
typedef void (*PFN_UNREG_AUTH_FUNC) (AUTHORIZEFUNC);
typedef int (*PFN_FINDLIBRARY) (const char * /*name*/, LibType /*type*/);
typedef size_t (*PFN_ADDLIBRARIES) (const char * /*name*/, LibType /*type*/, void * /*parent*/);
typedef size_t (*PFN_REMOVELIBRARIES) (void * /*parent*/);
typedef void (*PFN_OVERRIDENATIVES) (AMX_NATIVE_INFO * /*natives*/, const char * /*myname*/);
typedef const char * (*PFN_GETLOCALINFO) (const char * /*name*/, const char * /*def*/);
typedef int (*PFN_AMX_REREGISTER) (AMX * /*amx*/, AMX_NATIVE_INFO * /*list*/, int /*list*/);
typedef void * (*PFN_REGISTERFUNCTIONEX) (void * /*pfn*/, const char * /*desc*/);
extern PFN_ADD_NATIVES g_fn_AddNatives;
extern PFN_BUILD_PATHNAME g_fn_BuildPathname;
@ -2048,7 +2228,6 @@ extern PFN_IS_PLAYER_HLTV g_fn_IsPlayerHLTV;
extern PFN_GET_PLAYER_ARMOR g_fn_GetPlayerArmor;
extern PFN_GET_PLAYER_HEALTH g_fn_GetPlayerHealth;
extern PFN_AMX_EXEC g_fn_AmxExec;
extern PFN_AMX_EXECV g_fn_AmxExecv;
extern PFN_AMX_ALLOT g_fn_AmxAllot;
extern PFN_AMX_FINDPUBLIC g_fn_AmxFindPublic;
extern PFN_LOAD_AMXSCRIPT g_fn_LoadAmxScript;
@ -2067,6 +2246,17 @@ extern PFN_GET_PLAYER_TEAM g_fn_GetPlayerTeam;
extern PFN_REGISTERFUNCTION g_fn_RegisterFunction;
extern PFN_REQ_FNPTR g_fn_RequestFunction;
extern PFN_AMX_PUSH g_fn_AmxPush;
extern PFN_SET_TEAM_INFO g_fn_SetTeamInfo;
extern PFN_PLAYER_PROP_ADDR g_fn_PlayerPropAddr;
extern PFN_REG_AUTH_FUNC g_fn_RegAuthFunc;
extern PFN_UNREG_AUTH_FUNC g_fn_UnregAuthFunc;
extern PFN_FINDLIBRARY g_fn_FindLibrary;
extern PFN_ADDLIBRARIES g_fn_AddLibraries;
extern PFN_REMOVELIBRARIES g_fn_RemoveLibraries;
extern PFN_OVERRIDENATIVES g_fn_OverrideNatives;
extern PFN_GETLOCALINFO g_fn_GetLocalInfo;
extern PFN_AMX_REREGISTER g_fn_AmxReRegister;
extern PFN_REGISTERFUNCTIONEX g_fn_RegisterFunctionEx;
#ifdef MAY_NEVER_BE_DEFINED
// Function prototypes for intellisense and similar systems
@ -2127,6 +2317,17 @@ void MF_RegisterFunction (void *pfn, const char *description) { }
void * MF_RequestFunction (const char *description) { }
int MF_AmxPush (AMX *amx, cell *params) { }
int MF_AmxExec (AMX *amx, cell *retval, int idx) { }
int MF_SetPlayerTeamInfo (int id, int teamid, const char *teamname) { }
void * MF_PlayerPropAddr (int id, int prop) { }
void MF_RegAuthFunc (AUTHORIZEFUNC fn) { }
void MF_UnregAuthFunc (AUTHORIZEFUNC fn) { }
int MF_FindLibrary (const char *name, LibType type) { }
size_t MF_AddLibraries (const char *name, LibType type, void *parent) { }
size_t MF_RemoveLibraries (void *parent) { }
void MF_OverrideNatives (AMX_NATIVE_INFO *natives, const char *myname) { }
const char * MF_GetLocalInfo (const char *name, const char *def) { }
int MF_AmxReRegister (AMX *amx, AMX_NATIVE_INFO *list, int number) { return 0; }
void * MF_RegisterFunctionEx (void *pfn, const char *description) { }
#endif // MAY_NEVER_BE_DEFINED
#define MF_AddNatives g_fn_AddNatives
@ -2190,9 +2391,21 @@ void MF_LogError(AMX *amx, int err, const char *fmt, ...);
#define MF_GetPlayerEdict g_fn_GetPlayerEdict
#define MF_Format g_fn_Format
#define MF_RegisterFunction g_fn_RegisterFunction
#define MF_RequestFunction g_fn_RequestFunction;
#define MF_RequestFunction g_fn_RequestFunction
#define MF_AmxPush g_fn_AmxPush
#define MF_SetPlayerTeamInfo g_fn_SetTeamInfo
#define MF_PlayerPropAddr g_fn_PlayerPropAddr
#define MF_RegAuthFunc g_fn_RegAuthFunc
#define MF_UnregAuthFunc g_fn_UnregAuthFunc
#define MF_FindLibrary g_fn_FindLibrary
#define MF_AddLibraries g_fn_AddLibraries
#define MF_RemoveLibraries g_fn_RemoveLibraries
#define MF_OverrideNatives g_fn_OverrideNatives
#define MF_GetLocalInfo g_fn_GetLocalInfo
#define MF_AmxReRegister g_fn_AmxReRegister
#define MF_RegisterFunctionEx g_fn_RegisterFunctionEx
#ifdef MEMORY_TEST
/*** Memory ***/
void *operator new(size_t reportedSize);
void *operator new[](size_t reportedSize);
@ -2236,4 +2449,6 @@ void Mem_Deallocator(const char *sourceFile, const unsigned int sourceLine, cons
#define realloc(ptr,sz) Mem_Reallocator(__FILE__,__LINE__,__FUNCTION__,m_alloc_realloc,sz,ptr)
#define free(ptr) Mem_Deallocator(__FILE__,__LINE__,__FUNCTION__,m_alloc_free,ptr)
#endif //MEMORY_TEST
#endif // #ifndef __AMXXMODULE_H__

View File

@ -3,12 +3,24 @@
#ifndef __MODULECONFIG_H__
#define __MODULECONFIG_H__
// Module info
/** Module info
* -The logtag is the tag that the module's log messages will be
* prepended with.
* -The library is the name that the #pragma library
* message will have prepended.
* -The library class is the class of libraries that
* a module belongs to (like DBI). Keep it "" to
* ignore.
* -For both library and library class, you can use a comma
* to add multiple entries.
*/
#define MODULE_NAME "--ENTER NAME HERE--"
#define MODULE_VERSION "--ENTER VERSION HERE--"
#define MODULE_AUTHOR "--ENTER AUTHOR HERE--"
#define MODULE_URL "--ENTER URL HERE--"
#define MODULE_LOGTAG "--ENTER LOGTAG HERE--"
#define MODULE_LIBRARY "--ENTER LIBRARY HERE--"
#define MODULE_LIBCLASS ""
// If you want the module not to be reloaded on mapchange, remove / comment out the next line
#define MODULE_RELOAD_ON_MAPCHANGE
@ -21,18 +33,45 @@
// metamod plugin?
// #define USE_METAMOD
// - AMXX Init functions
// Also consider using FN_META_*
// AMXX query
// use memory manager/tester?
// note that if you use this, you cannot construct/allocate
// anything before the module attached (OnAmxxAttach).
// be careful of default constructors using new/malloc!
// #define MEMORY_TEST
// Unless you use STL or exceptions, keep this commented.
// It allows you to compile without libstdc++.so as a dependency
// #define NO_ALLOC_OVERRIDES
// Uncomment this if you are using MSVC8 or greater and want to fix some of the compatibility issues yourself
// #define NO_MSVC8_AUTO_COMPAT
/**
* AMXX Init functions
* Also consider using FN_META_*
*/
/** AMXX query */
//#define FN_AMXX_QUERY OnAmxxQuery
// AMXX attach
// Do native functions init here (MF_AddNatives)
// #define FN_AMXX_ATTACH OnAmxxAttach
// AMXX detach
/** AMXX attach
* Do native functions init here (MF_AddNatives)
*/
//#define FN_AMXX_ATTACH OnAmxxAttach
/** AMXX Detach (unload) */
//#define FN_AMXX_DETACH OnAmxxDetach
// All plugins loaded
// Do forward functions init here (MF_RegisterForward)
// #define FN_AMXX_PLUGINSLOADED OnPluginsLoaded
/** All plugins loaded
* Do forward functions init here (MF_RegisterForward)
*/
//#define FN_AMXX_PLUGINSLOADED OnPluginsLoaded
/** All plugins are about to be unloaded */
//#define FN_AMXX_PLUGINSUNLOADING OnPluginsUnloading
/** All plugins are now unloaded */
//#define FN_AMXX_PLUGINSUNLOADED OnPluginsUnloaded
/**** METAMOD ****/
// If your module doesn't use metamod, you may close the file now :)

297
amxmodx/sh_list.h Normal file
View File

@ -0,0 +1,297 @@
/* ======== SourceMM ========
* Copyright (C) 2004-2005 Metamod:Source Development Team
* No warranties of any kind
*
* License: zlib/libpng
*
* Author(s): David "BAILOPAN" Anderson
* ============================
*/
#ifndef _INCLUDE_SMM_LIST_H
#define _INCLUDE_SMM_LIST_H
// MSVC8 fix for offsetof macro redefition warnings
#ifdef _MSC_VER
#if _MSC_VER >= 1400
#undef offsetof
#endif
#endif
#include <new>
#include <malloc.h>
//namespace SourceHook
//{
//This class is from CSDM for AMX Mod X
/*
A circular, doubly-linked list with one sentinel node
Empty:
m_Head = sentinel
m_Head->next = m_Head;
m_Head->prev = m_Head;
One element:
m_Head = sentinel
m_Head->next = node1
m_Head->prev = node1
node1->next = m_Head
node1->prev = m_Head
Two elements:
m_Head = sentinel
m_Head->next = node1
m_Head->prev = node2
node1->next = node2
node1->prev = m_Head
node2->next = m_Head
node2->prev = node1
*/
template <class T>
class List
{
public:
class iterator;
friend class iterator;
class ListNode
{
public:
ListNode(const T & o) : obj(o) { };
ListNode() { };
T obj;
ListNode *next;
ListNode *prev;
};
private:
// Initializes the sentinel node.
// BAIL used malloc instead of new in order to bypass the need for a constructor.
ListNode *_Initialize()
{
ListNode *n = (ListNode *)malloc(sizeof(ListNode));
n->next = n;
n->prev = n;
return n;
}
public:
List() : m_Head(_Initialize()), m_Size(0)
{
}
List(const List &src) : m_Head(_Initialize()), m_Size(0)
{
iterator iter;
for (iter=src.begin(); iter!=src.end(); iter++)
push_back( (*iter) );
}
~List()
{
clear();
// Don't forget to free the sentinel
if (m_Head)
{
free(m_Head);
m_Head = NULL;
}
}
void push_back(const T &obj)
{
ListNode *node = new ListNode(obj);
node->prev = m_Head->prev;
node->next = m_Head;
m_Head->prev->next = node;
m_Head->prev = node;
m_Size++;
}
size_t size()
{
return m_Size;
}
void clear()
{
ListNode *node = m_Head->next;
ListNode *temp;
m_Head->next = m_Head;
m_Head->prev = m_Head;
// Iterate through the nodes until we find g_Head (the sentinel) again
while (node != m_Head)
{
temp = node->next;
delete node;
node = temp;
}
m_Size = 0;
}
bool empty()
{
return (m_Size == 0);
}
T & back()
{
return m_Head->prev->obj;
}
private:
ListNode *m_Head;
size_t m_Size;
public:
class iterator
{
friend class List;
public:
iterator()
{
m_This = NULL;
}
iterator(const List &src)
{
m_This = src.m_Head;
}
iterator(ListNode *n) : m_This(n)
{
}
iterator(const iterator &where)
{
m_This = where.m_This;
}
//pre decrement
iterator & operator--()
{
if (m_This)
m_This = m_This->prev;
return *this;
}
//post decrement
iterator operator--(int)
{
iterator old(*this);
if (m_This)
m_This = m_This->prev;
return old;
}
//pre increment
iterator & operator++()
{
if (m_This)
m_This = m_This->next;
return *this;
}
//post increment
iterator operator++(int)
{
iterator old(*this);
if (m_This)
m_This = m_This->next;
return old;
}
const T & operator * () const
{
return m_This->obj;
}
T & operator * ()
{
return m_This->obj;
}
T * operator -> ()
{
return &(m_This->obj);
}
const T * operator -> () const
{
return &(m_This->obj);
}
bool operator != (const iterator &where) const
{
return (m_This != where.m_This);
}
bool operator ==(const iterator &where) const
{
return (m_This == where.m_This);
}
private:
ListNode *m_This;
};
public:
iterator begin() const
{
return iterator(m_Head->next);
}
iterator end() const
{
return iterator(m_Head);
}
iterator erase(iterator &where)
{
ListNode *pNode = where.m_This;
iterator iter(where);
iter++;
// Works for all cases: empty list, erasing first element, erasing tail, erasing in the middle...
pNode->prev->next = pNode->next;
pNode->next->prev = pNode->prev;
delete pNode;
m_Size--;
return iter;
}
iterator insert(iterator where, const T &obj)
{
// Insert obj right before where
ListNode *node = new ListNode(obj);
ListNode *pWhereNode = where.m_This;
pWhereNode->prev->next = node;
node->prev = pWhereNode->prev;
pWhereNode->prev = node;
node->next = pWhereNode;
m_Size++;
return iterator(node);
}
public:
void remove(const T & obj)
{
iterator b;
for (b=begin(); b!=end(); b++)
{
if ( (*b) == obj )
{
erase( b );
break;
}
}
}
template <typename U>
iterator find(const U & equ)
{
iterator iter;
for (iter=begin(); iter!=end(); iter++)
{
if ( (*iter) == equ )
return iter;
}
return end();
}
List & operator =(const List &src)
{
clear();
iterator iter;
for (iter=src.begin(); iter!=src.end(); iter++)
push_back( (*iter) );
return *this;
}
};
//}; //NAMESPACE
#endif //_INCLUDE_CSDM_LIST_H

219
amxmodx/sh_stack.h Executable file
View File

@ -0,0 +1,219 @@
/* ======== SourceMM ========
* Copyright (C) 2004-2005 Metamod:Source Development Team
* No warranties of any kind
*
* License: zlib/libpng
*
* Author(s): Pavol "PM OnoTo" Marko
* ============================
*/
#ifndef __SH_STACK_H__
#define __SH_STACK_H__
#define SH_STACK_DEFAULT_SIZE 4
//namespace SourceHook
//{/
// Vector
template <class T> class CStack
{
T *m_Elements;
size_t m_AllocatedSize;
size_t m_UsedSize;
public:
friend class iterator;
class iterator
{
CStack<T> *m_pParent;
size_t m_Index;
public:
iterator(CStack<T> *pParent, size_t id) : m_pParent(pParent), m_Index(id)
{
}
iterator(CStack<T> *pParent) : m_pParent(pParent), m_Index(0)
{
}
iterator() : m_pParent(NULL), m_Index(0)
{
}
T &operator *()
{
return m_pParent->m_Elements[m_Index];
}
const T &operator *() const
{
return m_pParent->m_Elements[m_Index];
}
T * operator->()
{
return m_pParent->m_Elements + m_Index;
}
const T * operator->() const
{
return m_pParent->m_Elements + m_Index;
}
iterator & operator++() // preincrement
{
++m_Index;
return (*this);
}
iterator operator++(int) // postincrement
{
iterator tmp = *this;
++m_Index;
return tmp;
}
iterator & operator--() // predecrement
{
--m_Index;
return (*this);
}
iterator operator--(int) // postdecrememnt
{
iterator tmp = *this;
--m_Index;
return tmp;
}
bool operator==(const iterator & right) const
{
return (m_pParent == right.m_pParent && m_Index == right.m_Index);
}
bool operator!=(const iterator & right) const
{
return !(*this == right);
}
};
CStack() : m_Elements(new T[SH_STACK_DEFAULT_SIZE]),
m_AllocatedSize(SH_STACK_DEFAULT_SIZE),
m_UsedSize(0)
{
}
CStack(size_t size) : m_Elements(new T[size]),
m_AllocatedSize(size),
m_UsedSize(0)
{
}
CStack(const CStack &other) : m_Elements(NULL),
m_AllocatedSize(0),
m_UsedSize(0)
{
reserve(other.m_AllocatedSize);
m_UsedSize = other.m_UsedSize;
for (size_t i = 0; i < m_UsedSize; ++i)
m_Elements[i] = other.m_Elements[i];
}
~CStack()
{
if (m_Elements)
delete [] m_Elements;
}
void operator=(const CStack &other)
{
if (m_AllocatedSize < other.m_AllocatedSize)
{
if (m_Elements)
delete [] m_Elements;
m_Elements = new T[other.m_AllocatedSize];
m_AllocatedSize = other.m_AllocatedSize;
}
m_UsedSize = other.m_UsedSize;
for (size_t i = 0; i < m_UsedSize; ++i)
m_Elements[i] = other.m_Elements[i];
}
bool push(const T &val)
{
if (m_UsedSize + 1 == m_AllocatedSize)
{
// zOHNOES! REALLOCATE!
m_AllocatedSize *= 2;
T *newElements = new T[m_AllocatedSize];
if (!newElements)
{
m_AllocatedSize /= 2;
return false;
}
if (m_Elements)
{
for (size_t i = 0; i < m_UsedSize; ++i)
newElements[i] = m_Elements[i];
delete [] m_Elements;
}
m_Elements = newElements;
}
m_Elements[m_UsedSize++] = val;
return true;
}
void pop()
{
--m_UsedSize;
}
T &front()
{
return m_Elements[m_UsedSize - 1];
}
const T &front() const
{
return m_Elements[m_UsedSize - 1];
}
iterator begin()
{
return iterator(this, 0);
}
iterator end()
{
return iterator(this, m_UsedSize);
}
size_t size()
{
return m_UsedSize;
}
size_t capacity()
{
return m_AllocatedSize;
}
bool empty()
{
return m_UsedSize == 0 ? true : false;
}
bool reserve(size_t size)
{
if (size > m_AllocatedSize)
{
T *newElements = new T[size];
if (!newElements)
return false;
if (m_Elements)
{
for (size_t i = 0; i < m_UsedSize; ++i)
newElements[i] = m_Elements[i];
delete [] m_Elements;
}
m_Elements = newElements;
m_AllocatedSize = size;
}
return true;
}
};
//}; //namespace SourceHook
#endif

526
amxmodx/sh_tinyhash.h Normal file
View File

@ -0,0 +1,526 @@
/* ======== SourceMM ========
* Copyright (C) 2004-2005 Metamod:Source Development Team
* No warranties of any kind
*
* License: zlib/libpng
*
* Author(s): David "BAILOPAN" Anderson
* ============================
*/
#ifndef _INCLUDE_SH_TINYHASH_H_
#define _INCLUDE_SH_TINYHASH_H_
#include "sh_list.h"
#define _T_INIT_HASH_SIZE 512
//namespace SourceHook
//{
template <class K>
int HashFunction(const K & k);
template <class K>
int Compare(const K & k1, const K & k2);
template <class U, class K>
int CompareAlt(const U &k1, const K &k2);
template <class U>
int HashAlt(const U &u);
/**
* This is a tiny, growable hash class.
* Meant for quick and dirty dictionaries only!
*/
template <class K, class V>
class THash
{
public:
struct THashNode
{
THashNode(const K & k, const V & v) :
key(k), val(v)
{
};
THashNode & operator =(const THashNode &other)
{
key = other.key;
val = other.val;
}
K key;
V val;
};
typedef List<THashNode *> * NodePtr;
public:
class const_iterator;
THash() : m_Buckets(NULL), m_numBuckets(0), m_percentUsed(0.0f), m_items(0)
{
_Refactor();
}
THash(const THash &other) : m_Buckets(new NodePtr[other.m_numBuckets]),
m_numBuckets(other.m_numBuckets), m_percentUsed(other.m_percentUsed), m_items(0)
{
for (size_t i=0; i<m_numBuckets; i++)
m_Buckets[i] = NULL;
for (const_iterator iter = other.begin(); iter != other.end(); ++iter)
_FindOrInsert(iter->key)->val = iter->val;
}
void operator=(const THash &other)
{
clear();
for (const_iterator iter = other.begin(); iter != other.end(); ++iter)
_FindOrInsert(iter->key)->val = iter->val;
}
~THash()
{
_Clear();
}
void clear()
{
_Clear();
_Refactor();
}
size_t size()
{
return m_items;
}
size_t GetBuckets()
{
return m_numBuckets;
}
float PercentUsed()
{
return m_percentUsed;
}
V & operator [](const K & key)
{
THashNode *pNode = _FindOrInsert(key);
return pNode->val;
}
private:
void _Clear()
{
typename List<THashNode *>::iterator iter, end;
for (size_t i=0; i<m_numBuckets; i++)
{
if (m_Buckets[i])
{
end = m_Buckets[i]->end();
iter = m_Buckets[i]->begin();
while (iter != end)
{
delete (*iter);
iter++;
}
delete m_Buckets[i];
m_Buckets[i] = NULL;
}
}
if (m_Buckets)
delete [] m_Buckets;
m_Buckets = NULL;
m_numBuckets = 0;
m_items = 0;
}
public:
template <typename U>
V & AltFindOrInsert(const U & ukey)
{
size_t place = HashAlt(ukey) % m_numBuckets;
THashNode *pNode = NULL;
if (!m_Buckets[place])
{
m_Buckets[place] = new List<THashNode *>;
pNode = new THashNode(ukey, V());
m_Buckets[place]->push_back(pNode);
m_percentUsed += (1.0f / (float)m_numBuckets);
m_items++;
} else {
typename List<THashNode *>::iterator iter;
for (iter=m_Buckets[place]->begin(); iter!=m_Buckets[place]->end(); iter++)
{
if (CompareAlt(ukey, (*iter)->key) == 0)
return (*iter)->val;
}
pNode = new THashNode(ukey, V());
m_Buckets[place]->push_back(pNode);
m_items++;
}
if (PercentUsed() > 0.75f)
_Refactor();
return pNode->val;
}
private:
THashNode *_FindOrInsert(const K & key)
{
size_t place = HashFunction(key) % m_numBuckets;
THashNode *pNode = NULL;
if (!m_Buckets[place])
{
m_Buckets[place] = new List<THashNode *>;
pNode = new THashNode(key, V());
m_Buckets[place]->push_back(pNode);
m_percentUsed += (1.0f / (float)m_numBuckets);
m_items++;
} else {
typename List<THashNode *>::iterator iter;
for (iter=m_Buckets[place]->begin(); iter!=m_Buckets[place]->end(); iter++)
{
if (Compare((*iter)->key, key) == 0)
return (*iter);
}
//node does not exist
pNode = new THashNode(key, V());
m_Buckets[place]->push_back(pNode);
m_items++;
}
if (PercentUsed() > 0.75f)
_Refactor();
return pNode;
}
void _Refactor()
{
m_percentUsed = 0.0f;
if (!m_numBuckets)
{
m_numBuckets = _T_INIT_HASH_SIZE;
m_Buckets = new NodePtr[m_numBuckets];
for (size_t i=0; i<m_numBuckets; i++)
m_Buckets[i] = NULL;
} else {
size_t oldSize = m_numBuckets;
m_numBuckets *= 2;
typename List<THashNode *>::iterator iter;
size_t place;
THashNode *pHashNode;
NodePtr *temp = new NodePtr[m_numBuckets];
for (size_t i=0; i<m_numBuckets; i++)
temp[i] = NULL;
//look in old hash table
for (size_t i=0; i<oldSize; i++)
{
//does a bucket have anything?
if (m_Buckets[i])
{
//go through the list of items
for (iter = m_Buckets[i]->begin(); iter != m_Buckets[i]->end(); iter++)
{
pHashNode = (*iter);
//rehash it with the new bucket filter
place = HashFunction(pHashNode->key) % m_numBuckets;
//add it to the new hash table
if (!temp[place])
{
temp[place] = new List<THashNode *>;
m_percentUsed += (1.0f / (float)m_numBuckets);
}
temp[place]->push_back(pHashNode);
}
//delete that bucket!
delete m_Buckets[i];
m_Buckets[i] = NULL;
}
}
//reassign bucket table
delete [] m_Buckets;
m_Buckets = temp;
}
}
public:
friend class iterator;
friend class const_iterator;
class iterator
{
friend class THash;
public:
iterator() : curbucket(-1), hash(NULL), end(true)
{
};
iterator(THash *h) : curbucket(-1), hash(h), end(false)
{
if (!h->m_Buckets)
end = true;
else
_Inc();
};
//pre increment
iterator & operator++()
{
_Inc();
return *this;
}
//post increment
iterator operator++(int)
{
iterator old(*this);
_Inc();
return old;
}
const THashNode & operator * () const
{
return *(*iter);
}
THashNode & operator * ()
{
return *(*iter);
}
const THashNode * operator ->() const
{
return (*iter);
}
THashNode * operator ->()
{
return (*iter);
}
bool operator ==(const iterator &where) const
{
if (where.hash == this->hash
&& where.end == this->end
&&
(this->end ||
((where.curbucket == this->curbucket)
&& (where.iter == iter))
))
return true;
return false;
}
bool operator !=(const iterator &where) const
{
return !( (*this) == where );
}
void erase()
{
if (end || !hash || curbucket < 0 || curbucket >= static_cast<int>(hash->m_numBuckets))
return;
// Remove this element and move to the next one
iterator tmp = *this;
++tmp;
delete (*iter);
hash->m_Buckets[curbucket]->erase(iter);
*this = tmp;
// :TODO: Maybe refactor to a lower size if required
m_items--;
}
private:
void _Inc()
{
if (end || !hash || curbucket >= static_cast<int>(hash->m_numBuckets))
return;
if (curbucket < 0)
{
for (int i=0; i<(int)hash->m_numBuckets; i++)
{
if (hash->m_Buckets[i])
{
iter = hash->m_Buckets[i]->begin();
if (iter == hash->m_Buckets[i]->end())
continue;
curbucket = i;
break;
}
}
if (curbucket < 0)
end = true;
} else {
if (iter != hash->m_Buckets[curbucket]->end())
iter++;
if (iter == hash->m_Buckets[curbucket]->end())
{
int oldbucket = curbucket;
for (int i=curbucket+1; i<(int)hash->m_numBuckets; i++)
{
if (hash->m_Buckets[i])
{
iter = hash->m_Buckets[i]->begin();
if (iter == hash->m_Buckets[i]->end())
continue;
curbucket = i;
break;
}
}
if (curbucket == oldbucket)
end = true;
}
}
}
private:
int curbucket;
typename List<THashNode *>::iterator iter;
THash *hash;
bool end;
};
class const_iterator
{
friend class THash;
public:
const_iterator() : curbucket(-1), hash(NULL), end(true)
{
};
const_iterator(const THash *h) : curbucket(-1), hash(h), end(false)
{
if (!h->m_Buckets)
end = true;
else
_Inc();
};
//pre increment
const_iterator & operator++()
{
_Inc();
return *this;
}
//post increment
const_iterator operator++(int)
{
iterator old(*this);
_Inc();
return old;
}
const THashNode & operator * () const
{
return *(*iter);
}
const THashNode * operator ->() const
{
return (*iter);
}
bool operator ==(const const_iterator &where) const
{
if (where.hash == this->hash
&& where.end == this->end
&&
(this->end ||
((where.curbucket == this->curbucket)
&& (where.iter == iter))
))
return true;
return false;
}
bool operator !=(const const_iterator &where) const
{
return !( (*this) == where );
}
private:
void _Inc()
{
if (end || !hash || curbucket >= static_cast<int>(hash->m_numBuckets))
return;
if (curbucket < 0)
{
for (int i=0; i<(int)hash->m_numBuckets; i++)
{
if (hash->m_Buckets[i])
{
iter = hash->m_Buckets[i]->begin();
if (iter == hash->m_Buckets[i]->end())
continue;
curbucket = i;
break;
}
}
if (curbucket < 0)
end = true;
} else {
if (iter != hash->m_Buckets[curbucket]->end())
iter++;
if (iter == hash->m_Buckets[curbucket]->end())
{
int oldbucket = curbucket;
for (int i=curbucket+1; i<(int)hash->m_numBuckets; i++)
{
if (hash->m_Buckets[i])
{
iter = hash->m_Buckets[i]->begin();
if (iter == hash->m_Buckets[i]->end())
continue;
curbucket = i;
break;
}
}
if (curbucket == oldbucket)
end = true;
}
}
}
private:
int curbucket;
typename List<THashNode *>::iterator iter;
const THash *hash;
bool end;
};
public:
iterator begin()
{
return iterator(this);
}
iterator end()
{
iterator iter;
iter.hash = this;
return iter;
}
const_iterator begin() const
{
return const_iterator(this);
}
const_iterator end() const
{
const_iterator iter;
iter.hash = this;
return iter;
}
template <typename U>
iterator find(const U & u) const
{
iterator b = begin();
iterator e = end();
for (iterator iter = b; iter != e; iter++)
{
if ( (*iter).key == u )
return iter;
}
return end();
}
template <typename U>
iterator find(const U & u)
{
iterator b = begin();
iterator e = end();
for (iterator iter = b; iter != e; iter++)
{
if ( (*iter).key == u )
return iter;
}
return end();
}
iterator erase(iterator where)
{
where.erase();
return where;
}
template <typename U>
void erase(const U & u)
{
iterator iter = find(u);
if (iter == end())
return;
iter.erase();
}
private:
NodePtr *m_Buckets;
size_t m_numBuckets;
float m_percentUsed;
size_t m_items;
};
//};
#endif //_INCLUDE_SH_TINYHASH_H_

View File

@ -31,161 +31,156 @@
#include "amxmodx.h"
void amx_command(){
void amx_command()
{
const char* cmd = CMD_ARGV(1);
if (!strcmp(cmd,"plugins") || !strcmp(cmd,"list"))
if (!strcmp(cmd, "plugins") || !strcmp(cmd, "list"))
{
print_srvconsole( "Currently loaded plugins:\n");
print_srvconsole( " %-18.17s %-8.7s %-17.16s %-16.15s %-9.8s\n",
"name","version","author","file","status");
print_srvconsole("Currently loaded plugins:\n");
print_srvconsole(" %-23.22s %-8.7s %-17.16s %-16.15s %-9.8s\n", "name", "version", "author", "file", "status");
int plugins = 0;
int running = 0;
CPluginMngr::iterator a = g_plugins.begin();
while (a)
{
++plugins;
if ( (*a).isValid() && !(*a).isPaused() )
if ((*a).isValid() && !(*a).isPaused())
++running;
print_srvconsole( " [%3d] %-18.17s %-8.7s %-17.16s %-16.15s %-9.8s\n",
plugins,(*a).getTitle(),(*a).getVersion(),
(*a).getAuthor(), (*a).getName(), (*a).getStatus() );
print_srvconsole(" [%3d] %-23.22s %-8.7s %-17.16s %-16.15s %-9.8s\n", plugins, (*a).getTitle(), (*a).getVersion(), (*a).getAuthor(), (*a).getName(), (*a).getStatus());
++a;
}
a = g_plugins.begin();
int num = 0;
while (a)
{
if ( (*a).getStatusCode() == ps_bad_load )
num++;
if ((*a).getStatusCode() == ps_bad_load)
{
//error
print_srvconsole("Load fails: %s\n", (*a).getError());
print_srvconsole("(%3d) Load fails: %s\n", num, (*a).getError());
} else if ( (*a).getStatusCode() == ps_error) {
//error
print_srvconsole("(%3d) Error: %s\n", num, (*a).getError());
}
++a;
}
print_srvconsole( "%d plugins, %d running\n",plugins,running );
print_srvconsole("%d plugins, %d running\n", plugins, running);
}
else if (!strcmp(cmd,"pause") && CMD_ARGC() > 2)
else if (!strcmp(cmd, "pause") && CMD_ARGC() > 2)
{
const char* sPlugin = CMD_ARGV(2);
CPluginMngr::CPlugin *plugin = g_plugins.findPlugin(sPlugin);
if ( plugin && plugin->isValid() )
if (plugin && plugin->isValid())
{
plugin->pausePlugin();
print_srvconsole("Paused plugin \"%s\"\n",plugin->getName() );
print_srvconsole("Paused plugin \"%s\"\n", plugin->getName());
}
else print_srvconsole("Couldn't find plugin matching \"%s\"\n",sPlugin);
else
print_srvconsole("Couldn't find plugin matching \"%s\"\n", sPlugin);
}
else if (!strcmp(cmd,"unpause") && CMD_ARGC() > 2)
else if (!strcmp(cmd, "unpause") && CMD_ARGC() > 2)
{
const char* sPlugin = CMD_ARGV(2);
CPluginMngr::CPlugin *plugin = g_plugins.findPlugin(sPlugin);
if ( plugin && plugin->isValid() )
if (plugin && plugin->isValid() && plugin->isPaused())
{
plugin->unpausePlugin();
print_srvconsole("Unpaused plugin \"%s\"\n",plugin->getName() );
print_srvconsole("Unpaused plugin \"%s\"\n", plugin->getName());
}
else print_srvconsole("Couldn't find plugin matching \"%s\"\n",sPlugin);
}
else if (!strcmp(cmd,"cvars"))
else if (!plugin)
{
print_srvconsole( "Registered cvars:\n");
print_srvconsole( " %-24.23s %-24.23s %-16.15s\n",
"name","value","plugin");
print_srvconsole("Couldn't find plugin matching \"%s\"\n", sPlugin);
} else {
print_srvconsole("Plugin %s can't be unpaused right now.", sPlugin);
}
}
else if (!strcmp(cmd, "cvars"))
{
print_srvconsole("Registered cvars:\n");
print_srvconsole(" %-24.23s %-24.23s %-16.15s\n", "name", "value", "plugin");
int ammount = 0;
for( CList<CCVar>::iterator a = g_cvars.begin(); a ; ++a )
for (CList<CCVar>::iterator a = g_cvars.begin(); a; ++a)
{
print_srvconsole( " [%3d] %-24.23s %-24.23s %-16.15s\n",++ammount,
(*a).getName() ,CVAR_GET_STRING( (*a).getName() ),(*a).getPluginName() );
print_srvconsole(" [%3d] %-24.23s %-24.23s %-16.15s\n", ++ammount, (*a).getName(), CVAR_GET_STRING((*a).getName()), (*a).getPluginName());
}
print_srvconsole( "%d cvars\n",ammount);
print_srvconsole("%d cvars\n", ammount);
}
else if ( !strcmp(cmd,"cmds") )
else if (!strcmp(cmd, "cmds"))
{
print_srvconsole( "Registered commands:\n");
print_srvconsole( " %-24.23s %-16.15s %-8.7s %-16.15s\n",
"name","access" ,"type" ,"plugin");
print_srvconsole("Registered commands:\n");
print_srvconsole(" %-24.23s %-16.15s %-8.7s %-16.15s\n", "name", "access", "type", "plugin");
int ammount = 0;
char access[32];
CmdMngr::iterator a = g_commands.begin( CMD_ConsoleCommand );
CmdMngr::iterator a = g_commands.begin(CMD_ConsoleCommand);
while( a )
while (a)
{
UTIL_GetFlags( access , (*a).getFlags() );
print_srvconsole( " [%3d] %-24.23s %-16.15s %-8.7s %-16.15s\n",
++ammount,(*a).getCmdLine() , access , (*a).getCmdType() , (*a).getPlugin()->getName());
UTIL_GetFlags(access, (*a).getFlags());
print_srvconsole(" [%3d] %-24.23s %-16.15s %-8.7s %-16.15s\n", ++ammount, (*a).getCmdLine(), access, (*a).getCmdType(), (*a).getPlugin()->getName());
++a;
}
print_srvconsole( "%d commands\n",ammount);
print_srvconsole("%d commands\n",ammount);
}
else if (!strcmp(cmd,"version"))
else if (!strcmp(cmd, "version"))
{
print_srvconsole( "%s %s\n", Plugin_info.name, Plugin_info.version);
print_srvconsole( "Authors: %s (%s)\n", "Felix \"SniperBeamer\" Geyer, David \"BAILOPAN\" Anderson, Pavol \"PM OnoTo\" Marko, Jonny \"Got His Gun\" Bergstrom, and Lukasz \"SidLuke\" Wlasinski.", Plugin_info.url);
print_srvconsole( "Compiled: %s\n", __DATE__ ", " __TIME__);
print_srvconsole("%s %s (%s)\n", Plugin_info.name, Plugin_info.version, Plugin_info.url);
print_srvconsole("Authors: David \"BAILOPAN\" Anderson, Pavol \"PM OnoTo\" Marko\n");
print_srvconsole("\tFelix \"SniperBeamer\" Geyer, Jonny \"Got His Gun\" Bergstrom\n");
print_srvconsole("\tLukasz \"SidLuke\" Wlasinski, Christian \"Basic-Master\" Hammacher\n");
print_srvconsole("\tBorja \"faluco\" Ferrer\n");
print_srvconsole("Compiled: %s\n", __DATE__ ", " __TIME__);
#if defined JIT && !defined ASM32
print_srvconsole( "Core mode: JIT Only\n");
print_srvconsole("Core mode: JIT Only\n");
#elif !defined JIT && defined ASM32
print_srvconsole( "Core mode: ASM32 Only\n");
print_srvconsole("Core mode: ASM32 Only\n");
#elif defined JIT && defined ASM32
print_srvconsole( "Core mode: JIT+ASM32\n");
print_srvconsole("Core mode: JIT+ASM32\n");
#else
print_srvconsole( "Core mode: Normal\n");
print_srvconsole("Core mode: Normal\n");
#endif
}
else if (!strcmp(cmd,"modules"))
else if (!strcmp(cmd, "modules"))
{
print_srvconsole( "Currently loaded modules:\n");
print_srvconsole( " %-23.22s %-8.7s %-20.19s %-11.10s\n",
"name", "version", "author", "status");
print_srvconsole("Currently loaded modules:\n");
print_srvconsole(" %-23.22s %-8.7s %-20.19s %-11.10s\n", "name", "version", "author", "status");
int running = 0;
int modules = 0;
CList<CModule,const char *>::iterator a = g_modules.begin();
while ( a )
while (a)
{
if ( (*a).getStatusValue() == MODULE_LOADED )
if ((*a).getStatusValue() == MODULE_LOADED)
++running;
++modules;
print_srvconsole( " [%2d] %-23.22s %-8.7s %-20.19s %-11.10s\n", modules,
(*a).getName(), (*a).getVersion(), (*a).getAuthor() , (*a).getStatus() );
print_srvconsole(" [%2d] %-23.22s %-8.7s %-20.19s %-11.10s\n", modules, (*a).getName(), (*a).getVersion(), (*a).getAuthor(), (*a).getStatus());
++a;
}
print_srvconsole( "%d modules, %d correct\n",modules,running);
} else if (!strcmp(cmd, "gpl"))
print_srvconsole("%d modules, %d correct\n", modules, running);
}
else if (!strcmp(cmd, "gpl"))
{
print_srvconsole("AMX Mod X\n");
print_srvconsole("\n");
@ -242,11 +237,7 @@ void amx_command(){
print_srvconsole("\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x3A\x78\x78\x24\x40\x4E\x4E\x4D\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x5E\x3E\x3E\x3F\x3E\x3E\x3E\x3E\x3B\x3B\x3B\x3A\x3A\x3F\x3E\x3A\x2E\x2E\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x2E\x45\x4D\x40\x45\x78\x5E\x33\x68\x33\x2B\n");
print_srvconsole("\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x24\x48\x45\x48\x78\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x2B\x4E\x40\x2B\x66\x33\x78\x20\x20\n");
print_srvconsole("\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x2B\x2C\x20\x3A\x20\x20\n");
}
else
{
} else {
print_srvconsole("Usage: amxx < command > [ argument ]\n");
print_srvconsole("Commands:\n");
print_srvconsole(" version - display amxx version info\n");
@ -257,11 +248,9 @@ void amx_command(){
print_srvconsole(" cmds - list commands registered by plugins\n");
print_srvconsole(" pause < plugin > - pause a running plugin\n");
print_srvconsole(" unpause < plugin > - unpause a previously paused plugin\n");
}
}
void plugin_srvcmd()
{
cell ret = 0;
@ -269,13 +258,13 @@ void plugin_srvcmd()
CmdMngr::iterator a = g_commands.srvcmdbegin();
while ( a )
while (a)
{
if ( (*a).matchCommand( cmd ) &&
(*a).getPlugin()->isExecutable( (*a).getFunction() ) )
if ((*a).matchCommand(cmd) && (*a).getPlugin()->isExecutable((*a).getFunction()))
{
cell ret = executeForwards((*a).getFunction(), g_srvindex, (*a).getFlags(), (*a).getId());
if ( ret ) break;
cell ret = executeForwards((*a).getFunction(), static_cast<cell>(g_srvindex),
static_cast<cell>((*a).getFlags()), static_cast<cell>((*a).getId()));
if (ret) break;
}
++a;
}

File diff suppressed because it is too large Load Diff

View File

@ -14,6 +14,16 @@
#define strnicmp strncasecmp
#endif
#if _MSC_VER
#if _MSC_VER >= 1400
// MSVC8 - Replace POSIX stricmp with ISO C++ conformant one as it is deprecated
#define stricmp _stricmp
// Need this because of some stupid bug
#pragma warning (disable : 4996)
#endif
#endif
// this file does not include amxmodx.h, so we have to include the memory manager here
#ifdef MEMORY_TEST
#include "mmgr/mmgr.h"

View File

@ -30,11 +30,10 @@
*/
#include <time.h>
#include "amxmodx.h"
#ifdef __linux__
#define _vsnprintf vsnprintf
#define _vsnprintf vsnprintf
#endif
char *UTIL_VarArgs(const char *fmt, ...)
@ -52,21 +51,26 @@ char *UTIL_VarArgs(const char *fmt, ...)
int UTIL_ReadFlags(const char* c)
{
int flags = 0;
while (*c) flags |= ( 1 << ( *c++ - 'a' ) );
while (*c)
flags |= (1<<(*c++ - 'a'));
return flags;
}
void UTIL_GetFlags(char* f,int a)
void UTIL_GetFlags(char* f, int a)
{
for(int i='a';i<='z';++i){
if ( a & 1 ) *f++ = i;
for (int i = 'a'; i <= 'z'; ++i)
{
if (a & 1) *f++ = i;
a >>= 1;
}
*f = 0;
}
/* warning - don't pass here const string */
void UTIL_ShowMenu( edict_t* pEdict, int slots, int time, char *menu, int mlen )
void UTIL_ShowMenu(edict_t* pEdict, int slots, int time, char *menu, int mlen)
{
char *n = menu;
char c = 0;
@ -75,17 +79,19 @@ void UTIL_ShowMenu( edict_t* pEdict, int slots, int time, char *menu, int mlen )
if (!gmsgShowMenu)
return; // some games don't support ShowMenu (Firearms)
while ( *n ) {
while (*n)
{
a = mlen;
if ( a > 175 ) a = 175;
if (a > 175) a = 175;
mlen -= a;
c = *(n+=a);
*n = 0;
MESSAGE_BEGIN( MSG_ONE , gmsgShowMenu, NULL, pEdict );
WRITE_SHORT( slots );
WRITE_CHAR( time );
WRITE_BYTE( c ? TRUE : FALSE);
WRITE_STRING( menu );
MESSAGE_BEGIN(MSG_ONE, gmsgShowMenu, NULL, pEdict);
WRITE_SHORT(slots);
WRITE_CHAR(time);
WRITE_BYTE(c ? TRUE : FALSE);
WRITE_STRING(menu);
MESSAGE_END();
*n = c;
menu = n;
@ -93,14 +99,14 @@ void UTIL_ShowMenu( edict_t* pEdict, int slots, int time, char *menu, int mlen )
}
/* warning - don't pass here const string */
void UTIL_ShowMOTD( edict_t *client , char *motd, int mlen, const char *name)
void UTIL_ShowMOTD(edict_t *client, char *motd, int mlen, const char *name)
{
if (!gmsgMOTD)
return; // :TODO: Maybe output a warning log?
if (gmsgServerName)
{
MESSAGE_BEGIN( MSG_ONE , gmsgServerName, NULL, client );
MESSAGE_BEGIN(MSG_ONE, gmsgServerName, NULL, client);
WRITE_STRING(name);
MESSAGE_END();
}
@ -109,15 +115,17 @@ void UTIL_ShowMOTD( edict_t *client , char *motd, int mlen, const char *name)
char c = 0;
int a;
while ( *n ) {
while (*n)
{
a = mlen;
if ( a > 175 ) a = 175;
if (a > 175) a = 175;
mlen -= a;
c = *(n+=a);
c = *(n += a);
*n = 0;
MESSAGE_BEGIN( MSG_ONE , gmsgMOTD, NULL, client );
WRITE_BYTE( c ? FALSE : TRUE );
WRITE_STRING( motd );
MESSAGE_BEGIN(MSG_ONE, gmsgMOTD, NULL, client);
WRITE_BYTE(c ? FALSE : TRUE);
WRITE_STRING(motd);
MESSAGE_END();
*n = c;
motd = n;
@ -125,42 +133,52 @@ void UTIL_ShowMOTD( edict_t *client , char *motd, int mlen, const char *name)
if (gmsgServerName)
{
MESSAGE_BEGIN( MSG_ONE , gmsgServerName, NULL, client );
WRITE_STRING( hostname->string );
MESSAGE_BEGIN(MSG_ONE, gmsgServerName, NULL, client);
WRITE_STRING(hostname->string);
MESSAGE_END();
}
}
void UTIL_IntToString(int value, char *output)
{
static const char *words[] = {"zero ","one ","two ","three ","four ",
static const char *words[] =
{"zero ","one ","two ","three ","four ",
"five ", "six ","seven ","eight ","nine ","ten ",
"eleven ","twelve ","thirteen ","fourteen ","fifteen ",
"sixteen ","seventeen ","eighteen ","nineteen ",
"twenty ","thirty ","fourty ", "fifty ","sixty ",
"seventy ","eighty ","ninety ",
"hundred ","thousand "};
*output = 0;
if (value < 0) value = -value;
int tho = value / 1000;
int aaa = 0;
if (tho){
aaa += sprintf(&output[aaa], words[ tho ] );
aaa += sprintf(&output[aaa], words[29] );
if (tho)
{
aaa += sprintf(&output[aaa], words[tho]);
aaa += sprintf(&output[aaa], words[29]);
value = value % 1000;
}
int hun = value / 100;
if (hun) {
aaa += sprintf(&output[aaa], words[ hun ] );
aaa += sprintf(&output[aaa], words[28] );
if (hun)
{
aaa += sprintf(&output[aaa], words[hun]);
aaa += sprintf(&output[aaa], words[28]);
value = value % 100;
}
int ten = value / 10;
int unit = value % 10;
if ( ten )
aaa += sprintf(&output[aaa], words[ ( ten > 1 ) ? ( ten + 18 ) : ( unit + 10 ) ] );
if ( ten != 1 && ( unit || (!value && !hun && !tho) ) )
sprintf(&output[aaa], words[ unit ] );
if (ten)
aaa += sprintf(&output[aaa], words[(ten > 1) ? (ten + 18) : (unit + 10)]);
if (ten != 1 && (unit || (!value && !hun && !tho)))
sprintf(&output[aaa], words[unit]);
}
char* UTIL_SplitHudMessage(const char *src)
@ -168,50 +186,57 @@ char* UTIL_SplitHudMessage(const char *src)
static char message[512];
short b = 0, d = 0, e = 0, c = -1;
while ( src[ d ] && e < 480 ) {
if ( src[ d ] == ' ' ) {
while (src[d] && e < 480)
{
if (src[d] == ' ')
{
c = e;
}
else if ( src[ d ] == '\n' ) {
else if (src[d] == '\n')
{
c = -1;
b = 0;
}
message[ e++ ] = src[ d++ ];
if ( ++b == 69 ) {
if ( c == -1 ) {
message[ e++ ] = '\n';
message[e++] = src[d++];
if (++b == 69)
{
if (c == -1)
{
message[e++] = '\n';
b = 0;
}
else {
message[ c ] = '\n';
} else {
message[c] = '\n';
b = e - c - 1;
c = -1;
}
}
}
message[ e ] = 0;
message[e] = 0;
return message;
}
unsigned short FixedUnsigned16( float value, float scale )
unsigned short FixedUnsigned16(float value, float scale)
{
int output = (int)(value * scale);
if ( output < 0 )
if (output < 0)
output = 0;
else if ( output > 0xFFFF )
else if (output > 0xFFFF)
output = 0xFFFF;
return (unsigned short)output;
}
short FixedSigned16( float value, float scale )
short FixedSigned16(float value, float scale)
{
int output = (int)(value * scale);
if ( output > 32767 )
if (output > 32767)
output = 32767;
else if ( output < -32768 )
else if (output < -32768)
output = -32768;
return (short)output;
@ -219,15 +244,15 @@ short FixedSigned16( float value, float scale )
void UTIL_HudMessage(edict_t *pEntity, const hudtextparms_t &textparms, char *pMessage)
{
if ( pEntity )
MESSAGE_BEGIN( MSG_ONE_UNRELIABLE, SVC_TEMPENTITY, NULL, pEntity );
if (pEntity)
MESSAGE_BEGIN(MSG_ONE_UNRELIABLE, SVC_TEMPENTITY, NULL, pEntity);
else
MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY );
MESSAGE_BEGIN(MSG_BROADCAST, SVC_TEMPENTITY);
WRITE_BYTE(29);
WRITE_BYTE(textparms.channel & 0xFF);
WRITE_SHORT(FixedSigned16(textparms.x, (1<<13) ));
WRITE_SHORT(FixedSigned16(textparms.y, (1<<13) ));
WRITE_SHORT(FixedSigned16(textparms.x, (1<<13)));
WRITE_SHORT(FixedSigned16(textparms.y, (1<<13)));
WRITE_BYTE(textparms.effect);
WRITE_BYTE(textparms.r1);
WRITE_BYTE(textparms.g1);
@ -237,30 +262,34 @@ void UTIL_HudMessage(edict_t *pEntity, const hudtextparms_t &textparms, char *pM
WRITE_BYTE(255);
WRITE_BYTE(250);
WRITE_BYTE(0);
WRITE_SHORT(FixedUnsigned16(textparms.fadeinTime, (1<<8) ));
WRITE_SHORT(FixedUnsigned16(textparms.fadeoutTime, (1<<8) ));
WRITE_SHORT(FixedUnsigned16(textparms.holdTime, (1<<8) ));
if (textparms.effect==2)
WRITE_SHORT(FixedUnsigned16(textparms.fxTime, (1<<8) ) );
WRITE_SHORT(FixedUnsigned16(textparms.fadeinTime, (1<<8)));
WRITE_SHORT(FixedUnsigned16(textparms.fadeoutTime, (1<<8)));
WRITE_SHORT(FixedUnsigned16(textparms.holdTime, (1<<8)));
if (textparms.effect == 2)
WRITE_SHORT(FixedUnsigned16(textparms.fxTime, (1<<8)));
WRITE_STRING(pMessage);
MESSAGE_END();
}
/* warning - buffer of msg must be longer than 190 chars!
(here in AMX it is always longer) */
void UTIL_ClientPrint( edict_t *pEntity, int msg_dest, char *msg )
void UTIL_ClientPrint(edict_t *pEntity, int msg_dest, char *msg)
{
if (!gmsgTextMsg)
return; // :TODO: Maybe output a warning log?
char c = msg[190];
msg[190] = 0; // truncate without checking with strlen()
if ( pEntity )
MESSAGE_BEGIN( MSG_ONE, gmsgTextMsg, NULL, pEntity );
if (pEntity)
MESSAGE_BEGIN(MSG_ONE, gmsgTextMsg, NULL, pEntity);
else
MESSAGE_BEGIN( MSG_BROADCAST , gmsgTextMsg);
WRITE_BYTE( msg_dest );
WRITE_STRING( msg );
MESSAGE_BEGIN(MSG_BROADCAST, gmsgTextMsg);
WRITE_BYTE(msg_dest);
WRITE_STRING(msg);
MESSAGE_END();
msg[190] = c;
}
@ -304,7 +333,7 @@ void UTIL_FakeClientCommand(edict_t *pEdict, const char *cmd, const char *arg1,
// store argument
g_fakecmd.argv[1] = arg1;
// build argument line
snprintf( g_fakecmd.args, 255, "%s", arg1);
snprintf(g_fakecmd.args, 255, "%s", arg1);
// if snprintf reached 255 chars limit, this will make sure there will be no access violation
g_fakecmd.args[255] = 0;
}

View File

@ -34,52 +34,49 @@
Vault g_vault;
static cell AMX_NATIVE_CALL set_vaultdata(AMX *amx,cell *params)
static cell AMX_NATIVE_CALL set_vaultdata(AMX *amx, cell *params)
{
int iLen;
g_vault.put( get_amxstring(amx,params[1],0,iLen) , get_amxstring(amx,params[2],1,iLen) );
g_vault.put(get_amxstring(amx, params[1], 0, iLen), get_amxstring(amx, params[2], 1, iLen));
g_vault.saveVault();
return 1;
}
static cell AMX_NATIVE_CALL get_vaultdata(AMX *amx,cell *params)
static cell AMX_NATIVE_CALL get_vaultdata(AMX *amx, cell *params)
{
int iLen;
const char* key = get_amxstring(amx, params[1], 0, iLen);
const char* key = get_amxstring(amx,params[1],0,iLen);
if (params[3])
return set_amxstring(amx, params[2], g_vault.get(key), params[3]);
if ( params[3] )
return set_amxstring( amx , params[2] , g_vault.get( key ) , params[3] );
return g_vault.get_number( key );
return g_vault.get_number(key);
}
static cell AMX_NATIVE_CALL remove_vaultdata(AMX *amx,cell *params)
static cell AMX_NATIVE_CALL remove_vaultdata(AMX *amx, cell *params)
{
int iLen;
g_vault.remove( get_amxstring(amx,params[1],0,iLen) );
g_vault.remove(get_amxstring(amx, params[1], 0, iLen));
g_vault.saveVault();
return 1;
}
static cell AMX_NATIVE_CALL vaultdata_exists(AMX *amx,cell *params)
static cell AMX_NATIVE_CALL vaultdata_exists(AMX *amx, cell *params)
{
int iLen;
return g_vault.exists( get_amxstring(amx,params[1],0,iLen) ) ? 1 : 0;
return g_vault.exists(get_amxstring(amx, params[1], 0, iLen)) ? 1 : 0;
}
AMX_NATIVE_INFO vault_Natives[] = {
{ "set_vaultdata", set_vaultdata },
{ "get_vaultdata", get_vaultdata },
{ "remove_vaultdata", remove_vaultdata },
{ "delete_vaultdata", remove_vaultdata },
{ "vaultdata_exists", vaultdata_exists },
{ 0, 0 }
AMX_NATIVE_INFO vault_Natives[] =
{
{"set_vaultdata", set_vaultdata},
{"get_vaultdata", get_vaultdata},
{"remove_vaultdata", remove_vaultdata},
{"delete_vaultdata", remove_vaultdata},
{"vaultdata_exists", vaultdata_exists},
{0, 0}
};

202
amxmodx/vector.cpp Normal file
View File

@ -0,0 +1,202 @@
/* AMX Mod X
*
* by the AMX Mod X Development Team
* originally developed by OLO
*
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* 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, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* In addition, as a special exception, the author gives permission to
* link the code of this program with the Half-Life Game Engine ("HL
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
* L.L.C ("Valve"). You must obey the GNU General Public License in all
* respects for all of the code used other than the HL Engine and MODs
* from Valve. If you modify this file, you may extend this exception
* to your version of the file, but you are not obligated to do so. If
* you do not wish to do so, delete this exception statement from your
* version.
*/
#include "amxmodx.h"
#define ANGLEVECTORS_FORWARD 1
#define ANGLEVECTORS_RIGHT 2
#define ANGLEVECTORS_UP 3
static cell AMX_NATIVE_CALL get_distance(AMX *amx, cell *params)
{
cell *cpVec1 = get_amxaddr(amx, params[1]);
cell *cpVec2 = get_amxaddr(amx, params[2]);
Vector vec1 = Vector((float)cpVec1[0], (float)cpVec1[1], (float)cpVec1[2]);
Vector vec2 = Vector((float)cpVec2[0], (float)cpVec2[1], (float)cpVec2[2]);
int iDist = (int)((vec1 - vec2).Length());
return iDist;
}
static cell AMX_NATIVE_CALL get_distance_f(AMX *amx, cell *params)
{
cell *cpVec1 = get_amxaddr(amx, params[1]);
cell *cpVec2 = get_amxaddr(amx, params[2]);
Vector vec1 = Vector((float)amx_ctof(cpVec1[0]), (float)amx_ctof(cpVec1[1]), (float)amx_ctof(cpVec1[2]));
Vector vec2 = Vector((float)amx_ctof(cpVec2[0]), (float)amx_ctof(cpVec2[1]), (float)amx_ctof(cpVec2[2]));
REAL fDist = (REAL) (vec1 - vec2).Length();
return amx_ftoc(fDist);
}
static cell AMX_NATIVE_CALL VelocityByAim(AMX *amx, cell *params)
{
int iEnt = params[1];
int iVelocity = params[2];
cell *vRet = get_amxaddr(amx, params[3]);
Vector vVector = Vector(0, 0, 0);
edict_t *pEnt = NULL;
if (iEnt < 0 || iEnt > gpGlobals->maxEntities)
{
LogError(amx, AMX_ERR_NATIVE, "Entity out of range (%d)", iEnt);
return 0;
}
else
{
if (iEnt > 0 && iEnt <= gpGlobals->maxClients)
{
if (!GET_PLAYER_POINTER_I(iEnt)->ingame)
{
LogError(amx, AMX_ERR_NATIVE, "Invalid player %d (not ingame)", iEnt);
return 0;
}
pEnt = GET_PLAYER_POINTER_I(iEnt)->pEdict;
} else {
pEnt = INDEXENT(iEnt);
}
}
if (!pEnt)
{
LogError(amx, AMX_ERR_NATIVE, "Invalid entity %d (nullent)", iEnt);
return 0;
}
MAKE_VECTORS(pEnt->v.v_angle);
vVector = gpGlobals->v_forward * iVelocity;
vRet[0] = FloatToCell(vVector.x);
vRet[1] = FloatToCell(vVector.y);
vRet[2] = FloatToCell(vVector.z);
return 1;
}
static cell AMX_NATIVE_CALL vector_to_angle(AMX *amx, cell *params)
{
cell *cAddr = get_amxaddr(amx, params[1]);
REAL fX = amx_ctof(cAddr[0]);
REAL fY = amx_ctof(cAddr[1]);
REAL fZ = amx_ctof(cAddr[2]);
Vector vVector = Vector(fX, fY, fZ);
Vector vAngle = Vector(0, 0, 0);
VEC_TO_ANGLES(vVector, vAngle);
cell *vRet = get_amxaddr(amx, params[2]);
vRet[0] = FloatToCell(vAngle.x);
vRet[1] = FloatToCell(vAngle.y);
vRet[2] = FloatToCell(vAngle.z);
return 1;
}
static cell AMX_NATIVE_CALL angle_vector(AMX *amx, cell *params)
{
Vector v_angles, v_forward, v_right, v_up, v_return;
cell *vCell = get_amxaddr(amx, params[1]);
v_angles.x = amx_ctof(vCell[0]);
v_angles.y = amx_ctof(vCell[1]);
v_angles.z = amx_ctof(vCell[2]);
g_engfuncs.pfnAngleVectors(v_angles, v_forward, v_right, v_up);
switch (params[2])
{
case ANGLEVECTORS_FORWARD:
v_return = v_forward;
case ANGLEVECTORS_RIGHT:
v_return = v_right;
case ANGLEVECTORS_UP:
v_return = v_up;
}
vCell = get_amxaddr(amx,params[3]);
vCell[0] = FloatToCell(v_return.x);
vCell[1] = FloatToCell(v_return.y);
vCell[2] = FloatToCell(v_return.z);
return 1;
}
static cell AMX_NATIVE_CALL vector_length(AMX *amx, cell *params)
{
cell *cAddr = get_amxaddr(amx, params[1]);
REAL fX = amx_ctof(cAddr[0]);
REAL fY = amx_ctof(cAddr[1]);
REAL fZ = amx_ctof(cAddr[2]);
Vector vVector = Vector(fX, fY, fZ);
REAL fLength = vVector.Length();
return amx_ftoc(fLength);
}
static cell AMX_NATIVE_CALL vector_distance(AMX *amx, cell *params)
{
cell *cAddr = get_amxaddr(amx, params[1]);
cell *cAddr2 = get_amxaddr(amx, params[2]);
REAL fX = amx_ctof(cAddr[0]);
REAL fY = amx_ctof(cAddr[1]);
REAL fZ = amx_ctof(cAddr[2]);
REAL fX2 = amx_ctof(cAddr2[0]);
REAL fY2 = amx_ctof(cAddr2[1]);
REAL fZ2 = amx_ctof(cAddr2[2]);
Vector vVector = Vector(fX, fY, fZ);
Vector vVector2 = Vector(fX2, fY2, fZ2);
REAL fLength = (vVector - vVector2).Length();
return amx_ftoc(fLength);
}
AMX_NATIVE_INFO vector_Natives[] = {
{"get_distance", get_distance},
{"get_distance_f", get_distance_f},
{"velocity_by_aim", VelocityByAim},
{"vector_to_angle", vector_to_angle},
{"angle_vector", angle_vector},
{"vector_length", vector_length},
{"vector_distance", vector_distance},
{NULL, NULL},
};

View File

@ -1,6 +1,5 @@
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
@ -27,8 +26,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,5,0,1
PRODUCTVERSION 1,5,0,1
FILEVERSION 1,7,5,0
PRODUCTVERSION 1,7,5,0
FILEFLAGSMASK 0x17L
#ifdef _DEBUG
FILEFLAGS 0x1L
@ -45,12 +44,12 @@ BEGIN
BEGIN
VALUE "Comments", "AMX Mod X"
VALUE "FileDescription", "AMX Mod X"
VALUE "FileVersion", "1.50"
VALUE "FileVersion", "1.75"
VALUE "InternalName", "amxmodx"
VALUE "LegalCopyright", "Copyright (c) 2004-2005, AMX Mod X Dev Team"
VALUE "LegalCopyright", "Copyright (c) 2004-2006, AMX Mod X Dev Team"
VALUE "OriginalFilename", "amxmodx_mm.dll"
VALUE "ProductName", "AMX Mod X"
VALUE "ProductVersion", "1.50-RC1"
VALUE "ProductVersion", "1.75"
END
END
BLOCK "VarFileInfo"

Binary file not shown.

View File

@ -3,14 +3,14 @@
### EDIT BELOW FOR OTHER PROJECTS ###
OPT_FLAGS = -O3 -fno-rtti -funroll-loops -s -pipe
OPT_FLAGS = -O3 -funroll-loops -s -pipe
DEBUG_FLAGS = -g -ggdb3
CPP = g++
CPP = gcc
BINARY = amxxpc
OBJECTS = amx.cpp amxxpc.cpp Binary.cpp
LINK = -lz
LINK = -lz /lib/libstdc++.a
INCLUDE = -I. -L.
@ -22,7 +22,7 @@ else
CFLAGS = $(OPT_FLAGS)
endif
CFLAGS += -DLINUX -DNDEBUG -Wno-deprecated -fexceptions -DHAVE_STDINT_H -DAMX_ANSIONLY
CFLAGS += -DLINUX -DNDEBUG -Wno-deprecated -fexceptions -DHAVE_STDINT_H -DAMX_ANSIONLY -fno-rtti -static-libgcc
OBJ_LINUX := $(OBJECTS:%.cpp=$(BIN_DIR)/%.o)

View File

@ -30,7 +30,11 @@ int main(int argc, char **argv)
#endif
#ifdef __linux__
HINSTANCE lib = dlmount("./amxxpc32.so");
HINSTANCE lib = NULL;
if (FileExists("./amxxpc32.so"))
lib = dlmount("./amxxpc32.so");
else
lib = dlmount("amxxpc32.so");
#else
HINSTANCE lib = dlmount("amxxpc32.dll");
#endif
@ -58,7 +62,7 @@ int main(int argc, char **argv)
}
pc_printf("Welcome to the AMX Mod X %s Compiler.\n", VERSION_STRING);
pc_printf("Copyright (c) 1997-2005 ITB CompuPhase, AMX Mod X Team\n\n");
pc_printf("Copyright (c) 1997-2006 ITB CompuPhase, AMX Mod X Team\n\n");
if (argc < 2)
{
@ -99,17 +103,18 @@ int main(int argc, char **argv)
fclose(fp);
}
dlclose(lib);
unlink(file);
HINSTANCE lib64 = 0;
HINSTANCE lib64 = NULL;
#ifdef __linux__
if (FileExists("./amxxpc64.so"))
lib64 = dlmount("./amxxpc64.so");
else
lib64 = dlmount("amxxpc64.so");
#else
lib64 = dlmount("amxxpc64.dll");
#endif
pc_printf = (PRINTF)dlsym(lib64, "pc_printf");
if (!lib64 || !pc_printf)
if (!lib64)
{
pc_printf("64bit compiler failed to instantiate.\n");
exit(0);
@ -129,6 +134,8 @@ int main(int argc, char **argv)
sc64(argc, argv);
dlclose(lib64);
if (file == NULL)
{
pc_printf("Could not locate the output file on second pass.\n");
@ -207,7 +214,7 @@ int main(int argc, char **argv)
pc_printf("Done.\n");
dlclose(lib64);
dlclose(lib);
exit(0);
}
@ -374,3 +381,15 @@ void show_help()
printf("\t-p<name> set name of \"prefix\" file\n");
printf("\t-r[name] write cross reference report to console or to specified file\n");
}
#ifdef __linux__
bool FileExists(const char *file)
{
FILE *fp = fopen(file, "rb");
if (!fp)
return false;
fclose(fp);
return true;
}
#endif

View File

@ -1,9 +1,7 @@
#ifndef _AMXXSC_INCLUDE_H
#define _AMXXSC_INCLUDE_H
#define VERSION_STRING "1.50-300"
#define VERSION 03000
#define MAGIC_HEADER 0x414D5842
#define VERSION_STRING "1.75-300"
#define MAGIC_HEADER2 0x414D5858
#define MAGIC_VERSION 0x0300
@ -67,4 +65,8 @@ struct BinPlugin
int32_t offs; //file offset
};
#ifdef __linux__
bool FileExists(const char *file);
#endif
#endif //_AMXXSC_INCLUDE_H

View File

@ -3,7 +3,7 @@
### EDIT BELOW FOR OTHER PROJECTS ###
OPT_FLAGS = -O3 -fno-rtti -funroll-loops -s -pipe
OPT_FLAGS = -O3 -funroll-loops -s -pipe
DEBUG_FLAGS = -g -ggdb3
CPP = gcc
NAME = amxxpc
@ -18,14 +18,14 @@ INCLUDE = -I.
ifeq "$(PAWN64)" "true"
BINARY = $(NAME)64.so
BIN_DIR = Release64
CFLAGS += -DPAWN_CELL_SIZE=64 -DHAVE_I64
CFLAGS += -DPAWN_CELL_SIZE=64 -DHAVE_I64 -Dpc_printf=pc_printf64
else
BINARY = $(NAME)32.so
BIN_DIR = Release32
CFLAGS += -DPAWN_CELL_SIZE=32
endif
CFLAGS += -DLINUX -DNDEBUG -fPIC -Wno-deprecated -fno-exceptions -DHAVE_STDINT_H -DENABLE_BINRELOC -DNO_MAIN -DPAWNC_DLL
CFLAGS += -DLINUX -DNDEBUG -fPIC -DHAVE_STDINT_H -DENABLE_BINRELOC -DNO_MAIN -DPAWNC_DLL -static-libgcc
CFLAGS += $(OPT_FLAGS)
OBJ_LINUX := $(OBJECTS:%.c=$(BIN_DIR)/%.o)
@ -42,9 +42,6 @@ all:
pawn_make: $(OBJ_LINUX)
$(CPP) $(INCLUDE) $(CFLAGS) $(OBJ_LINUX) $(LINK) -shared -ldl -lm -o$(BIN_DIR)/$(BINARY)
pawn64:
$(MAKE) pawn_make PAWN64=true
debug:
$(MAKE) all DEBUG=true

View File

@ -65,12 +65,16 @@
* purpose messages; errors go through pc_error(). The function is modelled
* after printf().
*/
#if PAWN_CELL_SIZE==32
#if defined __WIN32__ || defined _WIN32 || defined WIN32
__declspec (dllexport)
int pc_printf(const char *message,...)
#else
extern int pc_printf(const char *message,...)
#endif
#else
int pc_printf(const char *message, ...)
#endif
{
#if PAWN_CELL_SIZE==32
int ret;

View File

@ -6,6 +6,8 @@ EndProject
Global
GlobalSection(SolutionConfiguration) = preSolution
Debug = Debug
Debug32 = Debug32
Debug64 = Debug64
Release = Release
Release32 = Release32
Release64 = Release64
@ -13,6 +15,10 @@ Global
GlobalSection(ProjectConfiguration) = postSolution
{19B72687-080B-437A-917A-12AEB0031635}.Debug.ActiveCfg = Release|Win32
{19B72687-080B-437A-917A-12AEB0031635}.Debug.Build.0 = Release|Win32
{19B72687-080B-437A-917A-12AEB0031635}.Debug32.ActiveCfg = Debug32|Win32
{19B72687-080B-437A-917A-12AEB0031635}.Debug32.Build.0 = Debug32|Win32
{19B72687-080B-437A-917A-12AEB0031635}.Debug64.ActiveCfg = Debug64|Win32
{19B72687-080B-437A-917A-12AEB0031635}.Debug64.Build.0 = Debug64|Win32
{19B72687-080B-437A-917A-12AEB0031635}.Release.ActiveCfg = Release|Win32
{19B72687-080B-437A-917A-12AEB0031635}.Release.Build.0 = Release|Win32
{19B72687-080B-437A-917A-12AEB0031635}.Release32.ActiveCfg = Release32|Win32

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