406 Commits

Author SHA1 Message Date
38a339fb1c Tagged 1.71 2006-07-19 20:14:28 +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
463 changed files with 53821 additions and 13654 deletions

View File

@ -425,7 +425,7 @@ void EventsMngr::executeEvents()
}
(*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;

View File

@ -31,6 +31,7 @@
#include "amxmodx.h"
#include "debugger.h"
#include "binlog.h"
CForward::CForward(const char *name, ForwardExecType et, int numParams, const ForwardParam *paramTypes)
{
@ -88,9 +89,12 @@ cell CForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
{
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)
@ -121,6 +125,9 @@ cell CForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
// 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
@ -248,9 +255,12 @@ cell CSPForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
{
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)
@ -278,6 +288,9 @@ cell CSPForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
// 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)
@ -480,6 +493,16 @@ void CForwardMngr::unregisterSPForward(int id)
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;
@ -509,6 +532,16 @@ int registerForward(const char *funcName, ForwardExecType et, ...)
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;

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
@ -171,7 +174,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;
@ -211,7 +214,9 @@ public:
// (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);

File diff suppressed because it is too large Load Diff

View File

@ -32,28 +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
@ -69,9 +97,9 @@ 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();
@ -83,69 +111,25 @@ class CLangMngr
// 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);
@ -155,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);
@ -167,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();
@ -202,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

@ -47,6 +47,7 @@ MenuMngr::MenuCommand::MenuCommand(CPluginMngr::CPlugin *a, int mi, int k, int f
MenuMngr::~MenuMngr()
{
clear();
MenuMngr::MenuIdEle::uniqueid = 0;
}
int MenuMngr::findMenuId(const char* name, AMX* amx)
@ -60,6 +61,46 @@ int MenuMngr::findMenuId(const char* name, AMX* amx)
return 0;
}
void MenuMngr::removeMenuId(int id)
{
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);

View File

@ -51,8 +51,6 @@ class MenuMngr
{
id = ++uniqueid;
}
~MenuIdEle() { --uniqueid; }
} *headid;
public:
@ -85,6 +83,7 @@ public:
int findMenuId(const char* name, AMX* a = 0);
int registerMenuId(const char* n, AMX* a);
void removeMenuId(int id);
void registerMenuCmd(CPluginMngr::CPlugin *a, int mi, int k, int f);
void clear();

View File

@ -29,6 +29,7 @@
* version.
*/
#include "amxmodx.h"
#include "newmenus.h"
// *****************************************************
// class CPlayer
// *****************************************************
@ -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();
@ -61,19 +64,33 @@ void CPlayer::Disconnect()
initialized = false;
authorized = false;
while (!cvarQueryQueue.empty())
if (newmenu != -1)
{
ClientCvarQuery_Info *pQuery = cvarQueryQueue.front();
unregisterSPForward(pQuery->resultFwd);
if (pQuery->params)
delete [] pQuery->params;
delete pQuery;
cvarQueryQueue.pop();
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()
@ -82,6 +99,19 @@ void CPlayer::PutInServer()
ingame = true;
}
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);
@ -89,6 +119,8 @@ bool CPlayer::Connect(const char* connectname, const char* ipaddress)
time = gpGlobals->time;
bot = IsBot();
death_killer = 0;
menu = 0;
newmenu = -1;
memset(flags, 0, sizeof(flags));
memset(weapons, 0, sizeof(weapons));
@ -96,6 +128,21 @@ bool CPlayer::Connect(const char* connectname, const char* ipaddress)
initialized = true;
authorized = false;
for (int i=0; i<=4; i++)
{
channels[i] = 0.0f;
hudmap[i] = 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))

View File

@ -33,6 +33,7 @@
#define CMISC_H
#include "CList.h"
#include "sh_list.h"
// *****************************************************
// class CCVar
@ -65,10 +66,8 @@ public:
struct ClientCvarQuery_Info
{
bool querying; // Are we actually waiting for a response at the moment?
String cvarName;
int resultFwd;
int requestId;
int paramLen;
cell *params;
};
@ -86,9 +85,11 @@ public:
bool ingame;
bool bot;
bool authorized;
bool vgui;
float time;
float playtime;
float menuexpire;
struct
{
@ -113,11 +114,14 @@ public:
int newmenu;
int page;
float channels[5];
cell hudmap[5];
Vector lastTrace;
Vector thisTrace;
Vector lastHit;
CQueue<ClientCvarQuery_Info*> cvarQueryQueue;
List<ClientCvarQuery_Info *> queries;
void Init(edict_t* e, int i);
void Disconnect();
@ -137,6 +141,8 @@ public:
inline void Authorize() { authorized = true; }
int NextHUDChannel();
};
// *****************************************************

View File

@ -109,7 +109,7 @@ public:
inline const char *getFilename() { return m_Filename.c_str(); }
inline bool IsMetamod() { return m_Metamod; }
void CModule::CallPluginsLoaded();
void CallPluginsLoaded();
CList<AMX_NATIVE_INFO*> m_Natives;
};

View File

@ -149,11 +149,6 @@ void CPluginMngr::clear()
}
}
CPluginMngr::CPlugin* CPluginMngr::findPluginFast(AMX *amx)
{
return (CPlugin*)(amx->userdata[UD_FINDPLUGIN]);
}
CPluginMngr::CPlugin* CPluginMngr::findPlugin(AMX *amx)
{
CPlugin*a = head;
@ -293,7 +288,7 @@ static cell AMX_NATIVE_CALL invalid_native(AMX *amx, cell *params)
}
char name[sNAMEMAX + 1];
int native = amx->usertags[UT_NATIVE];
int native = (int)(_INT_PTR)(amx->usertags[UT_NATIVE]);
int err = amx_GetNative(amx, native, name);
if (err != AMX_ERR_NONE)
@ -302,6 +297,7 @@ static cell AMX_NATIVE_CALL invalid_native(AMX *amx, cell *params)
//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;
}

View File

@ -38,12 +38,12 @@
enum
{
ps_bad_load,
ps_error,
ps_locked,
ps_paused,
ps_stopped,
ps_running,
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
@ -122,7 +122,7 @@ public:
void unloadPlugin(CPlugin** a);
int loadPluginsFromFile(const char* filename);
CPlugin* findPluginFast(AMX *amx);
inline CPlugin* findPluginFast(AMX *amx) { return (CPlugin*)(amx->userdata[UD_FINDPLUGIN]); }
CPlugin* findPlugin(AMX *amx);
CPlugin* findPlugin(int index);
CPlugin* findPlugin(const char* name);

View File

@ -1,105 +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

@ -44,7 +44,7 @@ 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;
@ -226,7 +226,7 @@ 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));

View File

@ -41,7 +41,7 @@ private:
// task settings
CPluginMngr::CPlugin *m_pPlugin;
int m_iId;
cell m_iId;
int m_iFunc;
int m_iRepeat;
@ -57,7 +57,7 @@ private:
// 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;
@ -78,7 +78,7 @@ private:
class CTaskDescriptor
{
public:
int m_iId;
cell m_iId;
AMX *m_pAmx;
bool m_bFree;
@ -112,7 +112,7 @@ 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

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.

View File

@ -6,7 +6,7 @@ MM_ROOT = ../metamod/metamod
### EDIT BELOW FOR OTHER PROJECTS ###
OPT_FLAGS = -O2 -funroll-loops -s -pipe
OPT_FLAGS = -O2 -funroll-loops -s -fomit-frame-pointer -pipe
DEBUG_FLAGS = -g -ggdb3
CPP = gcc
NAME = amxmodx_mm
@ -15,9 +15,10 @@ OBJECTS = meta_api.cpp CFile.cpp CVault.cpp vault.cpp float.cpp file.cpp modules
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 debugger.cpp
CMenu.cpp util.cpp amx.cpp amxdbg.cpp natives.cpp newmenus.cpp debugger.cpp \
optimizer.cpp format.cpp
LINK = -lz
LINK = -lz /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
@ -39,13 +40,14 @@ CFLAGS += -DLINUX -DNDEBUG -fPIC -Wno-deprecated -DHAVE_STDINT_H -static-libgcc
ifeq "$(AMD64)" "true"
BINARY = $(NAME)_amd64.so
CFLAGS += -DPAWN_CELL_SIZE=64 -DHAVE_I64 -m64
CFLAGS += -DPAWN_CELL_SIZE=64 -DHAVE_I64 -DAMD64 -m64
OBJECTS += JIT/natives-amd64.o
else
BINARY = $(NAME)_i386.so
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
OPT_FLAGS += -march=i586
endif
OBJ_LINUX := $(OBJECTS:%.cpp=$(BIN_DIR)/%.o)

View File

@ -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;
@ -444,7 +452,7 @@ int AMXAPI amx_Callback(AMX *amx, cell index, cell *result, cell *params)
/* 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.
*/
amx->usertags[UT_NATIVE] = (long)index;
amx->usertags[UT_NATIVE] = (void *)index;
/* Note:
* params[0] == number of bytes for the additional parameters passed to the native function
@ -454,8 +462,24 @@ 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 */
@ -487,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
@ -502,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);
@ -607,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:
@ -672,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 */
@ -799,6 +843,7 @@ static void expand(unsigned char *code, long codesize, long memsize)
int AMXAPI amx_Init(AMX *amx, void *program)
{
AMX_HEADER *hdr;
BROWSEHOOK hook = NULL;
#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
@ -946,6 +991,9 @@ int AMXAPI amx_Init(AMX *amx,void *program)
#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 */
@ -994,7 +1042,7 @@ int AMXAPI amx_Init(AMX *amx,void *program)
#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 */
@ -1259,27 +1307,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 {
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;
}
@ -1492,37 +1535,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 */
@ -1764,13 +1781,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;
@ -2616,6 +2636,59 @@ static const void * const amx_opcodelist[] = {
NEXT(cip);
op_nop:
NEXT(cip);
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 */
@ -2700,7 +2773,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);
@ -3591,6 +3665,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) {

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
@ -240,7 +231,7 @@ 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
@ -343,6 +334,11 @@ enum {
#define UD_OPCODELIST 1
#define UD_HANDLER 0
#define UT_NATIVE 3
#define UT_OPTIMIZER 2
#define UT_BROWSEHOOK 1
#define UT_BINLOGS 0
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_
@ -445,6 +441,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
@ -1406,6 +1408,96 @@ 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
push 0
fld dword [edi+ecx+4]
frndint
fistp dword [esp]
pop eax
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
@ -1501,6 +1593,12 @@ Start_DATA
lodb_and DD 0ffh, 0ffffh, 0, 0ffffffffh
GLOBAL g_flags
g_flags:
DD -1
DD 0
DD 1
GLOBAL amx_opcodelist
GLOBAL _amx_opcodelist
amx_opcodelist:
@ -1642,4 +1740,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

@ -304,7 +304,11 @@
%endmacro
%ifdef WIN32
section .data exec
%else
section .text
%endif
global asm_runJIT, _asm_runJIT
@ -437,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;
@ -1876,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
@ -1885,6 +1891,104 @@ 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
push 0
fld dword [esi+4]
frndint
fistp dword [esp]
pop eax
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
@ -2313,6 +2417,12 @@ 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 amx_opcodelist_jit, _amx_opcodelist_jit
amx_opcodelist_jit:
@ -2455,5 +2565,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

@ -41,7 +41,6 @@
#include "string.h"
#include <extdll.h>
#include <meta_api.h>
#include "mm_pextensions.h" // metamod-p extensions
#ifdef MEMORY_TEST
#include "mmgr/mmgr.h"
@ -68,7 +67,7 @@
#include "amxxlog.h"
#define AMXXLOG_Log g_log.Log
#define AMX_VERSION "1.60"
#define AMX_VERSION "1.71"
extern AMX_NATIVE_INFO core_Natives[];
extern AMX_NATIVE_INFO time_Natives[];
@ -89,10 +88,22 @@ extern AMX_NATIVE_INFO vault_Natives[];
#define DLFREE(m) dlclose(m)
#endif
#if defined __GNUC__
#include <stdint.h>
typedef intptr_t _INT_PTR;
#else
#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
@ -139,8 +150,6 @@ struct fakecmd_t
bool fake;
};
extern bool g_IsNewMM;
extern pextension_funcs_t *gpMetaPExtFuncs;
extern CLog g_log;
extern CPluginMngr g_plugins;
extern CTaskMngr g_tasksMngr;
@ -256,6 +265,7 @@ 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);
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);
@ -272,7 +282,7 @@ void free_amxmemory(void **ptr);
// get_localinfo
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
{
@ -305,11 +315,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
{

View File

@ -92,11 +92,13 @@ void CLog::CreateNewFile()
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;
@ -104,6 +106,7 @@ void CLog::CreateNewFile()
fclose(pTmpFile);
++i;
}
m_LogFile.assign(file);
// Log logfile start
FILE *fp = fopen(m_LogFile.c_str(), "w");

260
amxmodx/binlog.cpp Normal file
View File

@ -0,0 +1,260 @@
#include <time.h>
#include "amxmodx.h"
#include "binlog.h"
#if defined BINLOG_ENABLED
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);
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);
}
}
}
#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

View File

@ -31,6 +31,7 @@
#include "amxmodx.h"
#include "debugger.h"
#include "binlog.h"
#if !defined WIN32 && !defined _WIN32
#define _snprintf snprintf
@ -307,6 +308,19 @@ void Debugger::StepI()
{
assert(m_Top >= 0 && m_Top < (int)m_pCalls.size());
#if defined BINLOG_ENABLED
if (g_binlog_level & 32)
{
CPluginMngr::CPlugin *pl = g_plugins.findPluginFast(m_pAmx);
if (pl)
{
long line;
dbg_LookupLine(m_pAmxDbg, m_pAmx->cip, &line);
g_BinLog.WriteOp(BinLog_SetLine, pl->getId(), (int)(line + 1));
}
}
#endif
m_pCalls[m_Top]->StepI(m_pAmx->frm, m_pAmx->cip);
}
@ -363,53 +377,6 @@ bool Debugger::ErrorExists()
return (m_pCalls[m_Top]->m_Error != AMX_ERR_NONE);
}
#define FLAG_INDIRECT (1<<0)
//vaddr - the address of our current index vector
//base - the base address of which the array is offset to
//dim - the current dimension to search
//dimNum - the number of dimensions total
//sizes[] - an array containing the dimension sizes
//Indexes[] - an output array to contain each dimension's index
int WalkArray(cell *vaddr, unsigned char *base, cell *addr, int dim, int dimNum, int &flags, int sizes[], int Indexes[])
{
cell *my_addr;
int idx = 0;
//if we are the second to last walker, we only need to check the ranges of our vector.
if (dim == dimNum - 2)
{
my_addr = vaddr;
//first check the actual vectors themselves
for (int i=0; i<sizes[dim]; i++)
{
if (addr == my_addr)
return i;
my_addr++;
}
return -1;
}
//otherwise, search lower vectors!
//vaddr is the address where we can start reading vectors
flags |= FLAG_INDIRECT;
for (int i=0; i<sizes[dim]; i++)
{
//the next vector is offset from the last address!
//this is funky but that's the internal implementation
my_addr = (cell *)((char *)vaddr + i*sizeof(cell) + vaddr[i]);
idx = WalkArray(my_addr, base, addr, dim+1, dimNum, flags, sizes, Indexes);
if (idx != -1)
{
Indexes[dim+1] = idx;
return i;
}
}
return -1;
}
int Debugger::FormatError(char *buffer, size_t maxLength)
{
if (!ErrorExists())
@ -442,7 +409,7 @@ int Debugger::FormatError(char *buffer, size_t maxLength)
num = (int)*p_cip;
}*/
//New code only requires this...
num = m_pAmx->usertags[UT_NATIVE];
num = (int)(_INT_PTR)m_pAmx->usertags[UT_NATIVE];
amx_err = amx_GetNative(m_pAmx, num, native_name);
/*if (num)
amx_err = amx_GetNative(m_pAmx, (int)*p_cip, native_name);
@ -450,205 +417,6 @@ int Debugger::FormatError(char *buffer, size_t maxLength)
amx_err = AMX_ERR_NOTFOUND;*/
//if (!amx_err)
size += _snprintf(buffer, maxLength, "(native \"%s\")", native_name);
} else if (error == AMX_ERR_BOUNDS) {
tagAMX_DBG *pDbg = m_pAmxDbg;
int symbols = pDbg->hdr->symbols;
int index = 0;
tagAMX_DBG_SYMBOL **pSymbols = pDbg->symboltbl;
tagAMX_DBG_SYMBOL *pSymbol, *pLastSymbol=NULL;
const tagAMX_DBG_SYMDIM *pDims;
ucell addr = 0;
int flags = 0;
char v_class, i_dent;
cell *arr_addr=NULL, *p_addr=NULL;
unsigned char *data = m_pAmx->base + ((AMX_HEADER *)m_pAmx->base)->dat;
bool valid=false;
//we can't really browse the assembly because
// we've no idea what the peephole optimizer did.
// so we're gonna try to go out on a limb and guess.
if (m_pAmx->alt < 0)
{
//take a guess that it's local
addr = m_pAmx->alt - pTrace->frm;
v_class = 1;
} else {
//take a guess that it's a global
//it won't be global if it's passed in from the stack frame, however
// doing this with a hardcoded array size is quite rare, and is probably passed
// as iREFARRAY not iARRAY!
addr = m_pAmx->alt;
v_class = 0;
}
bool found = false;
bool _found = true;
static char _msgbuf[255];
size_t _size = 0;
//take a pre-emptive guess at the v_class!
//are we GLOBAL (0) or LOCAL (1) ?
if (m_pAmx->alt < 0)
{
v_class = 1;
i_dent = iARRAY;
arr_addr = (cell *)(data + pTrace->frm + m_pAmx->alt);
} else {
//it's greater than 0, check other things!
if (m_pAmx->alt >= m_pAmx->hlw &&
m_pAmx->alt <= m_pAmx->stp)
{
//it's in the stack somewhere... guess that it's a local!
v_class = 1;
//relocate it
m_pAmx->alt -= pTrace->frm;
//alt cannot be zero
if (m_pAmx->alt < 0)
i_dent = iARRAY;
else
i_dent = iREFARRAY;
arr_addr = (cell *)(data + pTrace->frm + m_pAmx->alt);
} else {
//guess that it's DAT
v_class = 0;
i_dent = iARRAY;
arr_addr = (cell *)(data + m_pAmx->alt);
}
}
for (index = 0; index < symbols; index++)
{
pSymbol = pSymbols[index];
if (pSymbol->codestart <= (ucell)cip &&
pSymbol->codeend >= (ucell)cip &&
(pSymbol->ident == iARRAY || pSymbol->ident == iREFARRAY))
{
amx_err = dbg_GetArrayDim(pDbg, pSymbol, &pDims);
if (amx_err != AMX_ERR_NONE)
continue;
//calculate the size of the array. this is important!
ucell size = pDims[0].size;
ucell aggre = pDims[0].size;
valid = false;
for (int16_t i=1; i<pSymbol->dim; i++)
{
aggre *= pDims[i].size;
size += aggre;
}
if (pSymbol->vclass != v_class)
continue;
if (pSymbol->ident != i_dent)
continue;
if (v_class == 1)
{
if (i_dent == iARRAY)
{
p_addr = (cell *)(data + pTrace->frm + pSymbol->address);
} else if (i_dent == iREFARRAY) {
//get the variable off the stack, by reference
ucell _addr = (ucell)*((cell *)(data + pTrace->frm + pSymbol->address));
p_addr = (cell *)(data + _addr);
}
} else if (v_class == 0) {
p_addr = (cell *)(data + pSymbol->address);
}
//make sure our address is in bounds!
if (arr_addr < p_addr || arr_addr > (p_addr + size))
continue;
int *sizes = new int[pSymbol->dim];
int *indexes = new int[pSymbol->dim];
for (int i=0; i<pSymbol->dim; i++)
{
sizes[i] = pDims[i].size;
indexes[i] = -1;
}
flags = 0;
if (pSymbol->dim >= 2)
{
int dims = pSymbol->dim;
indexes[0] = WalkArray(p_addr, data, arr_addr, 0, pSymbol->dim, flags, sizes, indexes);
if (indexes[0] == -1)
{
while (indexes[0] == -1 && --dims > 0)
{
flags = 0;
indexes[0] = WalkArray(p_addr, data, arr_addr, 0, dims, flags, sizes, indexes);
}
}
//find the last known good dimension
for (dims=pSymbol->dim-1; dims>=0; dims--)
{
if (indexes[dims] != -1)
break;
}
//check for the "impossible" case.
//if we have [X][-1], and X is zero, the array did not walk properly.
if (dims >= 0
&& indexes[dims] == 0
&& !(flags & FLAG_INDIRECT)
&& dims < pSymbol->dim - 1)
{
//here we have the dreaded MIXED CASE. we don't know whether
//[-][X] or [0][-] (where - is a bad input) was intended.
//first, we take a guess by checking the bounds.
cell *_cip = (cell *)_CipAsVa(cip);
_cip -= 1;
cell bounds = *_cip;
if (sizes[dims] != sizes[dims+1])
{
//we were checking initial bounds
if (bounds == sizes[dims] - 1)
{
indexes[dims] = m_pAmx->pri;
} else if (bounds == sizes[dims+1] - 1) {
indexes[dims + 1] = m_pAmx->pri;
indexes[dims] = 0;
} else {
//this should really never happen...
_found = false;
}
} else {
_found = false;
}
if (!_found)
{
//we still don't have a good approximation.
//the user did something like:
//new X[40][40]
//we could do some really complicated and random guesswork
// but fact is, we have no way of deterministically knowing
// what the user intended.
}
} else {
//set the last know index to our culprit
indexes[dims + 1] = m_pAmx->pri;
}
} else {
indexes[0] = m_pAmx->pri;
}
_size += _snprintf(&(_msgbuf[_size]), sizeof(_msgbuf)-_size, "(array \"%s", pSymbol->name);
for (int i=0; i<pSymbol->dim; i++)
_size += _snprintf(&(_msgbuf[_size]), sizeof(_msgbuf)-_size, "[%d]", pDims[i].size);
if (_found)
{
_size += _snprintf(&(_msgbuf[_size]), sizeof(_msgbuf)-_size, "\") (indexed \"");
for (int i=0; i<pSymbol->dim; i++)
{
if (indexes[i] == -1)
_size += _snprintf(&(_msgbuf[_size]), sizeof(_msgbuf)-_size, "[]");
else
_size += _snprintf(&(_msgbuf[_size]), sizeof(_msgbuf)-_size, "[%d]", indexes[i]);
}
_size += _snprintf(&(_msgbuf[_size]), sizeof(_msgbuf)-_size, "\")");
} else {
_size += _snprintf(&(_msgbuf[_size]), sizeof(_msgbuf)-_size, "\") (unknown index \"%d\")", m_pAmx->pri);
}
found = true;
delete [] indexes;
delete [] sizes;
break;
} /* symbol validation */
} /* is in valid ranges */
if (!found)
_msgbuf[0] = '\0';
size += _snprintf(buffer, maxLength, "%s", _msgbuf);
}
return size;
@ -879,7 +647,7 @@ int Handler::SetErrorHandler(const char *function)
error = amx_FindPublic(m_pAmx, function, &m_iErrFunc);
if (error != AMX_ERR_NONE && m_iErrFunc < 1)
if (error != AMX_ERR_NONE && m_iErrFunc < 0)
m_iErrFunc = -1;
return error;
@ -891,7 +659,7 @@ int Handler::SetModuleFilter(const char *function)
error = amx_FindPublic(m_pAmx, function, &m_iModFunc);
if (error != AMX_ERR_NONE && m_iModFunc < 1)
if (error != AMX_ERR_NONE && m_iModFunc < 0)
m_iModFunc = -1;
return error;
@ -927,7 +695,7 @@ const char *Handler::GetLastMsg()
int Handler::HandleModule(const char *module)
{
if (m_iModFunc < 1)
if (m_iModFunc < 0)
return 0;
/**
@ -935,6 +703,9 @@ int Handler::HandleModule(const char *module)
*/
cell hea_addr, *phys_addr, retval;
Debugger *pd;
pd = DisableDebugHandler(m_pAmx);
//temporarily set prenit
m_pAmx->flags |= AMX_FLAG_PRENIT;
@ -943,6 +714,8 @@ int Handler::HandleModule(const char *module)
amx_Release(m_pAmx, hea_addr);
m_pAmx->flags &= ~AMX_FLAG_PRENIT;
EnableDebugHandler(m_pAmx, pd);
if (err != AMX_ERR_NONE)
return 0;
@ -966,6 +739,8 @@ int Handler::HandleNative(const char *native, int index, int trap)
if (pDebugger && trap)
pDebugger->BeginExec();
else if (pDebugger && !trap)
DisableDebugHandler(m_pAmx);
cell hea_addr, *phys_addr, retval;
@ -1005,6 +780,8 @@ int Handler::HandleNative(const char *native, int index, int trap)
m_pAmx->flags &= ~AMX_FLAG_PRENIT;
if (pDebugger && trap)
pDebugger->EndExec();
else if (pDebugger && !trap)
EnableDebugHandler(m_pAmx, pDebugger);
amx_Release(m_pAmx, hea_addr);

View File

@ -59,10 +59,13 @@ void Client_VGUIMenu(void* mValue)
{
if (!mPlayer) return;
mPlayer->vgui = true;
switch (mState++)
{
case 0:
mPlayer->menu = -(*(int*)mValue);
mPlayer->newmenu = -1;
break;
case 1:
mPlayer->keys = *(int*)mValue;
@ -73,13 +76,19 @@ void Client_ShowMenu(void* mValue)
{
if (!mPlayer) return;
mPlayer->vgui = true;
switch (mState++)
{
case 0:
mPlayer->keys = *(int*)mValue;
break;
case 3:
{
mPlayer->menu = g_menucmds.findMenuId((char*)mValue);
mPlayer->newmenu = -1;
break;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -31,203 +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__

View File

@ -5,7 +5,7 @@
*
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public<EFBFBD> License as published by the
* 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.
*
@ -307,27 +307,7 @@ static cell AMX_NATIVE_CALL dir_exists(AMX *amx, cell *params) /* 1 param */
char *sFile = get_amxstring(amx, params[1], 0, iLen);
char *file = build_pathname("%s", sFile);
#if defined WIN32 || defined _WIN32
DWORD attr = GetFileAttributes(file);
if (attr == INVALID_FILE_ATTRIBUTES)
return 0;
if (attr == FILE_ATTRIBUTE_DIRECTORY)
return 1;
return 0;
#else
struct stat s;
if (stat(file, &s) != 0)
return 0;
if (S_ISDIR(s.st_mode))
return 1;
return 0;
#endif
return DirExists(file) ? 1 : 0;
}
static cell AMX_NATIVE_CALL file_size(AMX *amx, cell *params) /* 1 param */
@ -378,250 +358,270 @@ static cell AMX_NATIVE_CALL file_size(AMX *amx, cell *params) /* 1 param */
return -1;
}
//ported from Sanji's file access module by BAILOPAN
// Important update - now uses new handles
static cell AMX_NATIVE_CALL amx_fopen(AMX *amx, cell *params)
{
unsigned int i;
int len, j = -1;
char *file = build_pathname("%s", get_amxstring(amx, params[1], 1, len));
char *flags = get_amxstring(amx, params[2], 0, len);
FILE *fp = fopen(file, flags);
if (fp == NULL)
{
// Failed
return 0;
return (cell)fp;
}
for (i = 0; i < FileList.size(); i++)
static cell AMX_NATIVE_CALL amx_fwrite_blocks(AMX *amx, cell *params)
{
if (FileList.at(i) == NULL)
{
j = i;
break;
}
}
FILE *fp = (FILE *)params[1];
if (j == -1)
{
FileList.push_back(fp);
j = FileList.size() - 1;
} else {
FileList.at(j) = fp;
}
return j + 1;
}
static cell AMX_NATIVE_CALL amx_fclose(AMX *amx, cell *params)
{
unsigned int id = params[1] - 1;
if (id >= FileList.size() || FileList.at(id) == NULL)
if (!fp)
return 0;
FILE *fp = FileList.at(id);
if (fp)
cell *addr = get_amxaddr(amx, params[2]);
size_t blocks = params[3];
size_t btmp = blocks;
cell mode = params[4];
switch (mode)
{
return fclose(fp);
} else {
return -1;
case 1:
{
char *a = new char[blocks];
char *ptr = a;
while (btmp--)
*a++ = static_cast<char>(*addr++);
size_t res = fwrite(a, sizeof(char), blocks, fp);
delete [] a;
return res;
}
case 2:
{
short *a = new short[blocks];
short *ptr = a;
while (btmp--)
*a++ = static_cast<short>(*addr++);
size_t res = fwrite(a, sizeof(short), blocks, fp);
delete [] a;
return res;
}
case 4:
{
int *a = new int[blocks];
int *ptr = a;
while (btmp--)
*a++ = static_cast<int>(*addr++);
size_t res = fwrite(a, sizeof(int), blocks, fp);
delete [] a;
return res;
}
}
static cell AMX_NATIVE_CALL amx_fread(AMX *amx, cell *params)
{
unsigned int id = params[1] - 1;
if (id >= FileList.size() || FileList.at(id) == NULL)
return 0;
FILE *fp = FileList.at(id);
char *buffer;
if (fp)
{
buffer = new char[params[3]]; // SLOW!!! :TODO: Find a better way (auto pointers?)
fread(buffer, sizeof(char), params[3], fp);
set_amxstring(amx, params[2], buffer, params[3]);
delete [] buffer;
return 1;
}
return -1;
}
#ifdef UNUSED
static cell AMX_NATIVE_CALL amx_fgetc(AMX *amx, cell *params)
{
unsigned int id = params[1] - 1;
if (id >= FileList.size() || FileList.at(id) == NULL)
return 0;
FILE *fp = FileList.at(id);
if (fp)
{
return fgetc(fp);
} else {
return -1;
}
}
static cell AMX_NATIVE_CALL amx_fwrite(AMX *amx, cell *params)
{
unsigned int id = params[1] - 1;
FILE *fp = (FILE *)params[1];
if (id >= FileList.size() || FileList.at(id) == NULL)
if (!fp)
return 0;
FILE *fp = FileList.at(id);
char *buf;
int len;
if (fp)
size_t mode = params[3];
switch (mode)
{
buf = format_amxstring(amx, params, 2, len);
return fwrite(buf, sizeof(char), strlen(buf), fp);
case 1:
{
char a = static_cast<char>(params[2]);
return fwrite(&a, sizeof(char), 1, fp);
}
case 2:
{
short b = static_cast<short>(params[2]);
return fwrite(&b, sizeof(short), 1, fp);
}
case 4:
{
int c = static_cast<int>(params[2]);
return fwrite(&c, sizeof(short), 1, fp);
}
}
return -1;
}
static cell AMX_NATIVE_CALL amx_feof(AMX *amx, cell *params)
{
unsigned int id = params[1] - 1;
if (id >= FileList.size() || FileList.at(id) == NULL)
return 0;
FILE *fp = FileList.at(id);
if (fp)
{
if (feof(fp))
{
return 1;
}
return 0;
}
return -1;
static cell AMX_NATIVE_CALL amx_fwrite_raw(AMX *amx, cell *params)
{
FILE *fp = (FILE *)params[1];
if (!fp)
return 0;
cell *addr = get_amxaddr(amx, params[2]);
return fwrite(addr, params[3], params[4], fp);
}
static cell AMX_NATIVE_CALL amx_fread_raw(AMX *amx, cell *params)
{
FILE *fp = (FILE *)params[1];
if (!fp)
return 0;
cell *addr = get_amxaddr(amx, params[2]);
size_t size = static_cast<cell>(params[3]);
size_t blocks = static_cast<cell>(params[4]);
return fread(addr, size, blocks, fp);
}
static cell AMX_NATIVE_CALL amx_fread(AMX *amx, cell *params)
{
FILE *fp = (FILE *)params[1];
if (!fp)
return 0;
cell *addr = get_amxaddr(amx, params[2]);
switch (params[3])
{
case 1: //char
{
char a;
size_t res = fread(&a, sizeof(char), 1, fp);
*addr = static_cast<cell>(a);
return res;
}
case 2: //short
{
short a;
size_t res = fread(&a, sizeof(short), 1, fp);
*addr = static_cast<cell>(a);
return res;
}
case 4: //int
default:
{
int a;
size_t res = fread(&a, sizeof(int), 1, fp);
*addr = static_cast<cell>(a);
return res;
}
}
return 0;
}
static cell AMX_NATIVE_CALL amx_fread_blocks(AMX *amx, cell *params)
{
FILE *fp = (FILE *)params[1];
if (!fp)
return 0;
cell *addr = get_amxaddr(amx, params[2]);
size_t blocks = params[3];
switch (params[3])
{
case 1: //char
{
char *a = new char[blocks];
char *ptr = a;
size_t res = fread(a, sizeof(char), blocks, fp);
while (blocks--)
*addr++ = static_cast<cell>(*ptr++);
delete [] a;
return res;
}
case 2: //short
{
short *a = new short[blocks];
short *ptr = a;
size_t res = fread(a, sizeof(short), blocks, fp);
while (blocks--)
*addr++ = static_cast<cell>(*ptr++);
delete [] a;
return res;
}
case 4: //int
default:
{
int *a = new int[blocks];
int *ptr = a;
size_t res = fread(a, sizeof(int), blocks, fp);
while (blocks--)
*addr++ = static_cast<cell>(*ptr++);
delete [] a;
return res;
}
}
return 0;
}
static cell AMX_NATIVE_CALL amx_fgets(AMX *amx, cell *params)
{
FILE *fp = (FILE *)params[1];
if (!fp)
return 0;
static char buffer[4096];
buffer[0] = '\0';
fgets(buffer, sizeof(buffer)-1, fp);
return set_amxstring(amx, params[2], buffer, params[3]);
}
static cell AMX_NATIVE_CALL amx_fseek(AMX *amx, cell *params)
{
unsigned int id = params[1] - 1;
FILE *fp = (FILE *)params[1];
if (id >= FileList.size() || FileList.at(id) == NULL)
if (!fp)
return 0;
FILE *fp = FileList.at(id);
if (fp)
{
return fseek(fp, (long)params[2], params[3]);
}
return -1;
}
static cell AMX_NATIVE_CALL amx_fputc(AMX *amx, cell *params)
{
unsigned int id = params[1] - 1;
if (id >= FileList.size() || FileList.at(id) == NULL)
return 0;
FILE *fp = FileList.at(id);
if (fp)
{
return fputc(params[2], fp);
}
return -1;
}
static cell AMX_NATIVE_CALL amx_rewind(AMX *amx, cell *params)
{
unsigned int id = params[1] - 1;
if (id >= FileList.size() || FileList.at(id) == NULL)
return 0;
FILE *fp = FileList.at(id);
if (fp)
{
rewind(fp);
return 1;
}
return -1;
}
static cell AMX_NATIVE_CALL amx_fflush(AMX *amx, cell *params)
{
unsigned int id = params[1] - 1;
if (id >= FileList.size() || FileList.at(id) == NULL)
return 0;
FILE *fp = FileList.at(id);
if (fp)
{
return fflush(fp);
}
return -1;
}
static cell AMX_NATIVE_CALL amx_fscanf(AMX *amx, cell *params)
{
unsigned int id = params[1] - 1;
if (id >= FileList.size() || FileList.at(id) == NULL)
return 0;
FILE *fp = FileList.at(id);
char *buf;
int len;
buf = format_amxstring(amx, params, 2, len);
if (fp)
{
return fscanf(fp, "%s", buf);
}
return -1;
return fseek(fp, params[2], params[3]);
}
static cell AMX_NATIVE_CALL amx_ftell(AMX *amx, cell *params)
{
unsigned int id = params[1] - 1;
FILE *fp = (FILE *)params[1];
if (id >= FileList.size() || FileList.at(id) == NULL)
if (!fp)
return 0;
FILE *fp = FileList.at(id);
if (fp)
{
return ftell(fp);
}
return -1;
static cell AMX_NATIVE_CALL amx_fprintf(AMX *amx, cell *params)
{
FILE *fp = (FILE *)params[1];
if (!fp)
return 0;
int len;
char *str = format_amxstring(amx, params, 2, len);
return fprintf(fp, "%s", str);
}
static cell AMX_NATIVE_CALL amx_feof(AMX *amx, cell *params)
{
FILE *fp = (FILE *)params[1];
if (!fp)
return 1;
return feof(fp);
}
static cell AMX_NATIVE_CALL amx_fclose(AMX *amx, cell *params)
{
FILE *fp = (FILE *)params[1];
if (!fp)
return 1;
fclose(fp);
return 1;
}
#endif //UNUSED
static cell AMX_NATIVE_CALL amx_filesize(AMX *amx, cell *params)
{
@ -642,164 +642,6 @@ static cell AMX_NATIVE_CALL amx_filesize(AMX *amx, cell *params)
return -1;
}
#ifdef UNUSED
static cell AMX_NATIVE_CALL amx_fgetl(AMX *amx, cell *params)
{
unsigned int id = params[1] - 1;
if (id >= FileList.size() || FileList.at(id) == NULL)
return 0;
FILE *fp = FileList.at(id);
long t;
if (fp)
{
fread(&t, sizeof(long), 1, fp);
return t;
}
return -1;
}
static cell AMX_NATIVE_CALL amx_fgeti(AMX *amx, cell *params)
{
unsigned int id = params[1] - 1;
if (id >= FileList.size() || FileList.at(id) == NULL)
return 0;
FILE *fp = FileList.at(id);
int t;
if (fp)
{
fread(&t, sizeof(int), 1, fp);
return t;
}
return -1;
}
static cell AMX_NATIVE_CALL amx_fgets(AMX *amx, cell *params)
{
unsigned int id = params[1] - 1;
if (id >= FileList.size() || FileList.at(id) == NULL)
return 0;
FILE *fp = FileList.at(id);
short t;
if (fp)
{
fread(&t, sizeof(short), 1, fp);
return t;
}
return -1;
}
static cell AMX_NATIVE_CALL amx_fputs(AMX *amx, cell *params)
{
unsigned int id = params[1] - 1;
if (id >= FileList.size() || FileList.at(id) == NULL)
return 0;
FILE *fp = FileList.at(id);
short size = params[2];
if (fp)
{
return fwrite(&size, sizeof(short), 1, fp);
}
return -1;
}
static cell AMX_NATIVE_CALL amx_fputl(AMX *amx, cell *params)
{
unsigned int id = params[1] - 1;
if (id >= FileList.size() || FileList.at(id) == NULL)
return 0;
FILE *fp = FileList.at(id);
long size = params[2];
if (fp)
{
return fwrite(&size, sizeof(long), 1, fp);
}
return -1;
}
static cell AMX_NATIVE_CALL amx_fputi(AMX *amx, cell *params)
{
unsigned int id = params[1] - 1;
if (id >= FileList.size() || FileList.at(id) == NULL)
return 0;
FILE *fp = FileList.at(id);
int size = params[2];
if (fp)
{
return fwrite(&size, sizeof(int), 1, fp);
}
return -1;
}
static cell AMX_NATIVE_CALL amx_fgetf(AMX *amx, cell *params)
{
unsigned int id = params[1] - 1;
if (id >= FileList.size() || FileList.at(id) == NULL)
return 0;
FILE *fp = FileList.at(id);
float t;
if (fp)
{
fread(&t, sizeof(float), 1, fp);
return *(cell*)&t;
}
return -1;
}
static cell AMX_NATIVE_CALL amx_fputf(AMX *amx, cell *params)
{
unsigned int id = params[1] - 1;
if (id >= FileList.size() || FileList.at(id) == NULL)
return 0;
FILE *fp = FileList.at(id);
float size = *(float *)((void *)&params[2]);
if (fp)
{
return fwrite(&size, sizeof(float), 1, fp);
}
return -1;
}
#endif //UNUSED
static cell AMX_NATIVE_CALL amx_build_pathname(AMX *amx, cell *params)
{
int len;
@ -899,6 +741,54 @@ static cell AMX_NATIVE_CALL amx_get_dir(AMX *amx, cell *params)
#endif
}
//native fgetc( file );
static cell AMX_NATIVE_CALL amx_fgetc(AMX *amx, cell *params)
{
FILE *fp = (FILE *)params[1];
if (!fp)
return 0;
return fgetc(fp);
}
//native fputc( file, data );
static cell AMX_NATIVE_CALL amx_fputc(AMX *amx, cell *params)
{
FILE *fp = (FILE *)params[1];
if (!fp)
return 0;
return fputc(static_cast<int>(params[2]), fp);
}
//native ungetc( file, data );
static cell AMX_NATIVE_CALL amx_ungetc(AMX *amx, cell *params)
{
FILE *fp = (FILE *)params[1];
if (!fp)
return 0;
return ungetc(static_cast<int>(params[2]), fp);
}
#if defined __linux__
#define _rmdir rmdir
#endif
static cell AMX_NATIVE_CALL amx_rmdir(AMX *amx, cell *params)
{
int len;
char* sFile = build_pathname("%s", get_amxstring(amx, params[1], 0, len));
if (_rmdir(sFile) != 0)
return 0;
return 1;
}
AMX_NATIVE_INFO file_Natives[] =
{
{"delete_file", delete_file},
@ -907,35 +797,30 @@ AMX_NATIVE_INFO file_Natives[] =
{"read_dir", read_dir},
{"read_file", read_file},
{"write_file", write_file},
//Sanji's File Natives
//new, sane file natives
{"fopen", amx_fopen},
{"fclose", amx_fclose},
{"fread", amx_fread},
{"filesize", amx_filesize},
#ifdef UNUSED
{"fgetc", amx_fgetc},
{"fread_blocks", amx_fread_blocks},
{"fread_raw", amx_fread_raw},
{"fwrite", amx_fwrite},
{"fwrite_blocks", amx_fwrite_blocks},
{"fwrite_raw", amx_fwrite_raw},
{"feof", amx_feof},
{"fseek", amx_fseek},
{"fputc", amx_fputc},
{"rewind", amx_rewind},
{"fflush", amx_fflush},
{"fscanf", amx_fscanf},
{"ftell", amx_ftell},
{"fgetl", amx_fgetl},
{"fgeti", amx_fgeti},
{"fprintf", amx_fprintf},
{"fgets", amx_fgets},
{"fputs", amx_fputs},
{"fputl", amx_fputl},
{"fputi", amx_fputi},
{"fgetf", amx_fgetf},
{"fputf", amx_fputf},
#endif
{"fseek", amx_fseek},
{"ftell", amx_ftell},
{"filesize", amx_filesize},
{"unlink", delete_file},
{"build_pathname", amx_build_pathname},
{"dir_exists", dir_exists},
{"open_dir", amx_open_dir},
{"close_dir", amx_close_dir},
{"next_file", amx_get_dir},
{"fgetc", amx_fgetc},
{"fputc", amx_fputc},
{"fungetc", amx_ungetc},
{"rmdir", amx_rmdir},
{NULL, NULL}
};

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_Log("[AMXX] \"%s\" is an invalid debug language", testlang);
validlang = false;
}
g_langMngr.GetDef(testlang, key, debug_status);
if (validlang && debug_status == ERR_BADKEY)
AMXXLOG_Log("[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_Log("[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

View File

@ -39,6 +39,8 @@
#include "fakemeta.h"
#include "newmenus.h"
#include "natives.h"
#include "binlog.h"
#include "optimizer.h"
plugin_info_t Plugin_info =
{
@ -58,7 +60,6 @@ gamedll_funcs_t *gpGamedllFuncs;
mutil_funcs_t *gpMetaUtilFuncs;
enginefuncs_t g_engfuncs;
globalvars_t *gpGlobals;
pextension_funcs_t *gpMetaPExtFuncs;
funEventCall modMsgsEnd[MAX_REG_MSGS];
funEventCall modMsgs[MAX_REG_MSGS];
@ -66,6 +67,8 @@ funEventCall modMsgs[MAX_REG_MSGS];
void (*function)(void*);
void (*endfunction)(void*);
extern List<AUTHORIZEFUNC> g_auth_funcs;
CLog g_log;
CForwardMngr g_forwards;
CList<CPlayer*> g_auth;
@ -102,8 +105,6 @@ float g_task_time;
float g_auth_time;
bool g_initialized = false;
bool g_IsNewMM = false;
bool g_NeedsP = false;
bool g_coloredmenus;
bool g_activated = false;
bool g_NewDLL_Available = false;
@ -126,6 +127,8 @@ int g_srvindex;
cvar_t init_amxmodx_version = {"amxmodx_version", "", FCVAR_SERVER | FCVAR_SPONLY};
cvar_t init_amxmodx_modules = {"amxmodx_modules", "", FCVAR_SPONLY};
cvar_t init_amxmodx_debug = {"amx_debug", "1", FCVAR_SPONLY};
cvar_t init_amxmodx_mldebug = {"amx_mldebug", "", FCVAR_SPONLY};
cvar_t init_amxmodx_cl_langs = {"amx_client_languages", "", FCVAR_SERVER};
cvar_t* amxmodx_version = NULL;
cvar_t* amxmodx_modules = NULL;
cvar_t* hostname = NULL;
@ -146,11 +149,6 @@ int FF_InconsistentFile = -1;
int FF_ClientAuthorized = -1;
int FF_ChangeLevel = -1;
// fake metamod api
#ifdef FAKEMETA
CFakeMeta g_FakeMeta;
#endif
// Precache stuff from force consistency calls
// or check for pointed files won't be done
int C_PrecacheModel(char *s)
@ -200,7 +198,8 @@ int C_InconsistentFile(const edict_t *player, const char *filename, char *discon
{
CPlayer *pPlayer = GET_PLAYER_POINTER((edict_t *)player);
if (executeForwards(FF_InconsistentFile, pPlayer->index, filename, disconnect_message) == 1)
if (executeForwards(FF_InconsistentFile, static_cast<cell>(pPlayer->index),
filename, disconnect_message) == 1)
RETURN_META_VALUE(MRES_SUPERCEDE, FALSE);
RETURN_META_VALUE(MRES_SUPERCEDE, TRUE);
@ -245,11 +244,6 @@ int C_Spawn(edict_t *pent)
// ###### Initialize task manager
g_tasksMngr.registerTimers(&gpGlobals->time, &mp_timelimit->value, &g_game_timeleft);
// ###### Load lang
char file[256];
g_langMngr.LoadCache(build_pathname_r(file, sizeof(file) - 1, "%s/dictionary.cache", get_localinfo("amxx_datadir", "addons/amxmodx/data")));
g_langMngr.Load(build_pathname_r(file, sizeof(file) - 1, "%s/languages.dat", get_localinfo("amxmodx_datadir", "addons/amxmodx/data")));
// ###### Initialize commands prefixes
g_commands.registerPrefix("amx");
g_commands.registerPrefix("amxx");
@ -276,6 +270,7 @@ int C_Spawn(edict_t *pent)
CVAR_SET_STRING(init_amxmodx_modules.name, buffer);
// ###### Load Vault
char file[255];
g_vault.setSource(build_pathname_r(file, sizeof(file) - 1, "%s", get_localinfo("amxx_vault", "addons/amxmodx/configs/vault.ini")));
g_vault.loadVault();
@ -297,6 +292,10 @@ int C_Spawn(edict_t *pent)
// Set server flags
memset(g_players[0].flags, -1, sizeof(g_players[0].flags));
g_opt_level = atoi(get_localinfo("optimizer", "7"));
if (!g_opt_level)
g_opt_level = 7;
// ###### Load AMX scripts
g_plugins.loadPluginsFromFile(get_localinfo("amxx_plugins", "addons/amxmodx/configs/plugins.ini"));
g_plugins.Finalize();
@ -316,6 +315,15 @@ int C_Spawn(edict_t *pent)
FF_ClientAuthorized = registerForward("client_authorized", ET_IGNORE, FP_CELL, FP_DONE);
FF_ChangeLevel = registerForward("server_changelevel", ET_STOP, FP_STRING, FP_DONE);
#if defined BINLOG_ENABLED
if (!g_BinLog.Open())
{
LOG_ERROR(PLID, "Binary log failed to open.");
}
g_binlog_level = atoi(get_localinfo("bin_logging", "17"));
g_binlog_maxsize = atoi(get_localinfo("max_binlog_size", "20"));
#endif
modules_callPluginsLoaded();
// ###### Call precache forward function
@ -429,11 +437,6 @@ void C_ServerActivate_Post(edict_t *pEdictList, int edictCount, int clientMax)
executeForwards(FF_PluginInit);
executeForwards(FF_PluginCfg);
// ###### Save lang
char file[256];
g_langMngr.Save(build_pathname_r(file, sizeof(file) - 1, "%s/languages.dat", get_localinfo("amxx_datadir", "addons/amxmodx/data")));
g_langMngr.SaveCache(build_pathname_r(file, sizeof(file) - 1, "%s/dictionary.cache", get_localinfo("amxx_datadir", "addons/amxmodx/data")));
// Correct time in Counter-Strike and other mods (except DOD)
if (!g_bmod_dod)
g_game_timeleft = 0;
@ -462,7 +465,7 @@ void C_ServerDeactivate()
{
CPlayer *pPlayer = GET_PLAYER_POINTER_I(i);
if (pPlayer->initialized)
executeForwards(FF_ClientDisconnect, pPlayer->index);
executeForwards(FF_ClientDisconnect, static_cast<cell>(pPlayer->index));
if (pPlayer->ingame)
{
@ -477,6 +480,8 @@ void C_ServerDeactivate()
RETURN_META(MRES_IGNORED);
}
extern CVector<cell *> g_hudsync;
// After all clear whole AMX configuration
// However leave AMX modules which are loaded only once
void C_ServerDeactivate_Post()
@ -502,11 +507,9 @@ void C_ServerDeactivate_Post()
g_plugins.clear();
ClearPluginLibraries();
char file[256];
g_langMngr.Save(build_pathname_r(file, sizeof(file) - 1, "%s/languages.dat", get_localinfo("amxx_datadir", "addons/amxmodx/data")));
g_langMngr.SaveCache(build_pathname_r(file, sizeof(file) - 1, "%s/dictionary.cache", get_localinfo("amxx_datadir", "addons/amxmodx/data")));
g_langMngr.Clear();
for (unsigned int i=0; i<g_hudsync.size(); i++)
delete [] g_hudsync[i];
g_hudsync.clear();
// last memreport
#ifdef MEMORY_TEST
@ -562,6 +565,10 @@ void C_ServerDeactivate_Post()
}
#endif // MEMORY_TEST
#if defined BINLOG_ENABLED
g_BinLog.Close();
#endif
g_initialized = false;
RETURN_META(MRES_IGNORED);
@ -573,7 +580,7 @@ BOOL C_ClientConnect_Post(edict_t *pEntity, const char *pszName, const char *psz
if (!pPlayer->bot)
{
bool a = pPlayer->Connect(pszName, pszAddress);
executeForwards(FF_ClientConnect, pPlayer->index);
executeForwards(FF_ClientConnect, static_cast<cell>(pPlayer->index));
if (a)
{
@ -582,7 +589,18 @@ BOOL C_ClientConnect_Post(edict_t *pEntity, const char *pszName, const char *psz
g_auth.put(aa);
} else {
pPlayer->Authorize();
executeForwards(FF_ClientAuthorized, pPlayer->index);
if (g_auth_funcs.size())
{
List<AUTHORIZEFUNC>::iterator iter, end=g_auth_funcs.end();
AUTHORIZEFUNC fn;
const char* authid = GETPLAYERAUTHID(pEntity);
for (iter=g_auth_funcs.begin(); iter!=end; iter++)
{
fn = (*iter);
fn(pPlayer->index, authid);
}
}
executeForwards(FF_ClientAuthorized, static_cast<cell>(pPlayer->index));
}
}
@ -593,7 +611,7 @@ void C_ClientDisconnect(edict_t *pEntity)
{
CPlayer *pPlayer = GET_PLAYER_POINTER(pEntity);
if (pPlayer->initialized)
executeForwards(FF_ClientDisconnect, pPlayer->index);
executeForwards(FF_ClientDisconnect, static_cast<cell>(pPlayer->index));
if (pPlayer->ingame)
{
@ -611,7 +629,7 @@ void C_ClientPutInServer_Post(edict_t *pEntity)
{
pPlayer->PutInServer();
++g_players_num;
executeForwards(FF_ClientPutInServer, pPlayer->index);
executeForwards(FF_ClientPutInServer, static_cast<cell>(pPlayer->index));
}
RETURN_META(MRES_IGNORED);
@ -620,7 +638,7 @@ void C_ClientPutInServer_Post(edict_t *pEntity)
void C_ClientUserInfoChanged_Post(edict_t *pEntity, char *infobuffer)
{
CPlayer *pPlayer = GET_PLAYER_POINTER(pEntity);
executeForwards(FF_ClientInfoChanged, pPlayer->index);
executeForwards(FF_ClientInfoChanged, static_cast<cell>(pPlayer->index));
const char* name = INFOKEY_VALUE(infobuffer, "name");
// Emulate bot connection and putinserver
@ -632,15 +650,26 @@ void C_ClientUserInfoChanged_Post(edict_t *pEntity, char *infobuffer)
{
pPlayer->Connect(name, "127.0.0.1"/*CVAR_GET_STRING("net_address")*/);
executeForwards(FF_ClientConnect, pPlayer->index);
executeForwards(FF_ClientConnect, static_cast<cell>(pPlayer->index));
pPlayer->Authorize();
executeForwards(FF_ClientAuthorized, pPlayer->index);
if (g_auth_funcs.size())
{
List<AUTHORIZEFUNC>::iterator iter, end=g_auth_funcs.end();
AUTHORIZEFUNC fn;
const char* authid = GETPLAYERAUTHID(pEntity);
for (iter=g_auth_funcs.begin(); iter!=end; iter++)
{
fn = (*iter);
fn(pPlayer->index, authid);
}
}
executeForwards(FF_ClientAuthorized, static_cast<cell>(pPlayer->index));
pPlayer->PutInServer();
++g_players_num;
executeForwards(FF_ClientPutInServer, pPlayer->index);
executeForwards(FF_ClientPutInServer, static_cast<cell>(pPlayer->index));
}
RETURN_META(MRES_IGNORED);
@ -663,12 +692,15 @@ void C_ClientCommand(edict_t *pEntity)
{
// Print version
static char buf[1024];
size_t len = 0;
sprintf(buf, "%s %s\n", Plugin_info.name, Plugin_info.version);
CLIENT_PRINT(pEntity, print_console, buf);
sprintf(buf, "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);
len = sprintf(buf, "Authors: David \"BAILOPAN\" Anderson, Pavol \"PM OnoTo\" Marko, Felix \"SniperBeamer\" Geyer\n");
len += sprintf(&buf[len], "Authors: Jonny \"Got His Gun\" Bergstrom, Lukasz \"SidLuke\" Wlasinski\n");
CLIENT_PRINT(pEntity, print_console, buf);
sprintf(buf, "Compiled: %s\n", __DATE__ ", " __TIME__);
len = sprintf(buf, "Authors: Christian \"Basic-Master\" Hammacher, Borja \"faluco\" Ferrer\n");
len += sprintf(&buf[len], "Compiled: %s\nURL:http://www.amxmodx.org/\n", __DATE__ ", " __TIME__);
CLIENT_PRINT(pEntity, print_console, buf);
#ifdef JIT
sprintf(buf, "Core mode: JIT\n");
@ -684,7 +716,7 @@ void C_ClientCommand(edict_t *pEntity)
}
}
if (executeForwards(FF_ClientCommand, pPlayer->index) > 0)
if (executeForwards(FF_ClientCommand, static_cast<cell>(pPlayer->index)) > 0)
RETURN_META(MRES_SUPERCEDE);
/* check for command and if needed also for first argument and call proper function */
@ -698,7 +730,8 @@ void C_ClientCommand(edict_t *pEntity)
{
if ((*aa).matchCommandLine(cmd, arg) && (*aa).getPlugin()->isExecutable((*aa).getFunction()))
{
ret = executeForwards((*aa).getFunction(), pPlayer->index, (*aa).getFlags(), (*aa).getId());
ret = executeForwards((*aa).getFunction(), static_cast<cell>(pPlayer->index),
static_cast<cell>((*aa).getFlags()), static_cast<cell>((*aa).getId()));
if (ret & 2) result = MRES_SUPERCEDE;
if (ret & 1) RETURN_META(MRES_SUPERCEDE);
}
@ -714,6 +747,14 @@ void C_ClientCommand(edict_t *pEntity)
if (pPlayer->keys & bit_key)
{
if ((pPlayer->menu > 0 && !pPlayer->vgui) && (gpGlobals->time > pPlayer->menuexpire))
{
pPlayer->menu = 0;
pPlayer->keys = 0;
RETURN_META(MRES_SUPERCEDE);
}
int menuid = pPlayer->menu;
pPlayer->menu = 0;
@ -731,31 +772,27 @@ void C_ClientCommand(edict_t *pEntity)
if (menu >= 0 && menu < (int)g_NewMenus.size())
{
Menu *pMenu = g_NewMenus[menu];
int item = pMenu->PagekeyToItem(pPlayer->page, pressed_key);
ret = executeForwards((*a).getFunction(), pPlayer->index, menu, item);
int item = pMenu->PagekeyToItem(pPlayer->page, pressed_key+1);
if (item == MENU_BACK)
{
pMenu->Display(pPlayer->index, pPlayer->page - 1);
} else if (item == MENU_MORE) {
pMenu->Display(pPlayer->index, pPlayer->page + 1);
} else {
ret = executeForwards((*a).getFunction(), static_cast<cell>(pPlayer->index), static_cast<cell>(menu), static_cast<cell>(item));
if (ret & 2)
result = MRES_SUPERCEDE;
else if (ret & 1)
RETURN_META(MRES_SUPERCEDE);
else
{
if (item == MENU_BACK)
{
pMenu->Display(pPlayer->index, pPlayer->page - 1);
}
else if (item == MENU_MORE)
{
pMenu->Display(pPlayer->index, pPlayer->page + 1);
}
else if (item == MENU_EXIT)
{
//nothing
}
}
}
if (pPlayer->newmenu != -1)
break;
} else {
ret = executeForwards((*a).getFunction(), pPlayer->index, pressed_key, 0);
ret = executeForwards((*a).getFunction(), static_cast<cell>(pPlayer->index),
static_cast<cell>(pressed_key), 0);
if (ret & 2) result = MRES_SUPERCEDE;
if (ret & 1) RETURN_META(MRES_SUPERCEDE);
@ -790,7 +827,17 @@ void C_StartFrame_Post(void)
if (strcmp(auth, "STEAM_ID_PENDING"))
{
(*a)->Authorize();
executeForwards(FF_ClientAuthorized, (*a)->index);
if (g_auth_funcs.size())
{
List<AUTHORIZEFUNC>::iterator iter, end=g_auth_funcs.end();
AUTHORIZEFUNC fn;
for (iter=g_auth_funcs.begin(); iter!=end; iter++)
{
fn = (*iter);
fn((*a)->index, auth);
}
}
executeForwards(FF_ClientAuthorized, static_cast<cell>((*a)->index));
a.remove();
continue;
@ -860,21 +907,6 @@ void C_StartFrame_Post(void)
g_task_time = gpGlobals->time + 0.1f;
g_tasksMngr.startFrame();
// Dispatch client cvar queries
for (int i = 1; i <= gpGlobals->maxClients; ++i)
{
CPlayer* pPlayer = GET_PLAYER_POINTER_I(i);
if (pPlayer->pEdict && pPlayer->initialized && !pPlayer->cvarQueryQueue.empty())
{
if (!IS_QUERYING_CLIENT_CVAR(PLID, pPlayer->pEdict))
{
(*g_engfuncs.pfnQueryClientCvarValue)(pPlayer->pEdict, pPlayer->cvarQueryQueue.front()->cvarName.c_str());
pPlayer->cvarQueryQueue.front()->querying = true;
}
}
}
RETURN_META(MRES_IGNORED);
}
@ -987,22 +1019,6 @@ void C_MessageEnd_Post(void)
RETURN_META(MRES_IGNORED);
}
void C_ChangeLevel(char* s1, char* s2)
{
if (FF_ChangeLevel)
{
int retVal = 0;
char *map = s1;
retVal = executeForwards(FF_ChangeLevel, map);
if (retVal)
RETURN_META(MRES_SUPERCEDE);
}
RETURN_META(MRES_IGNORED);
}
const char *C_Cmd_Args(void)
{
// if the global "fake" flag is set, which means that engclient_cmd was used, supercede the function
@ -1095,124 +1111,83 @@ void C_AlertMessage_Post(ALERT_TYPE atype, char *szFmt, ...)
RETURN_META(MRES_IGNORED);
}
void C_CvarValue(const edict_t *pEdict, const char *value)
void C_ChangeLevel(char *map, char *what)
{
int ret = executeForwards(FF_ChangeLevel, map);
if (ret)
RETURN_META(MRES_SUPERCEDE);
RETURN_META(MRES_IGNORED);
}
void C_CvarValue2(const edict_t *pEdict, int requestId, const char *cvar, const char *value)
{
CPlayer *pPlayer = GET_PLAYER_POINTER(pEdict);
if (pPlayer->cvarQueryQueue.empty())
if (pPlayer->queries.empty())
RETURN_META(MRES_IGNORED);
ClientCvarQuery_Info *pQuery = pPlayer->cvarQueryQueue.front();
if (pPlayer->cvarQueryQueue.front()->querying)
List<ClientCvarQuery_Info *>::iterator iter, end=pPlayer->queries.end();
ClientCvarQuery_Info *info;
for (iter=pPlayer->queries.begin(); iter!=end; iter++)
{
if (pQuery->paramLen)
info = (*iter);
if ( info->requestId == requestId )
{
cell arr = prepareCellArray(pQuery->params, pQuery->paramLen);
executeForwards(pQuery->resultFwd, ENTINDEX(pEdict), pQuery->cvarName.c_str(), value, arr);
if (info->paramLen)
{
cell arr = prepareCellArray(info->params, info->paramLen);
executeForwards(info->resultFwd, static_cast<cell>(ENTINDEX(pEdict)),
cvar, value, arr);
} else {
executeForwards(info->resultFwd, static_cast<cell>(ENTINDEX(pEdict)),
cvar, value);
}
else
executeForwards(pQuery->resultFwd, ENTINDEX(pEdict), pQuery->cvarName.c_str(), value);
unregisterSPForward(info->resultFwd);
pPlayer->queries.erase(iter);
delete [] info->params;
delete info;
unregisterSPForward(pQuery->resultFwd);
if (pQuery->params)
delete [] pQuery->params;
delete pQuery;
pPlayer->cvarQueryQueue.pop();
break;
}
}
RETURN_META(MRES_HANDLED);
}
RETURN_META(MRES_IGNORED);
}
bool m_NeedsP = false;
C_DLLEXPORT int Meta_Query(char *ifvers, plugin_info_t **pPlugInfo, mutil_funcs_t *pMetaUtilFuncs)
{
gpMetaUtilFuncs = pMetaUtilFuncs;
*pPlugInfo = &Plugin_info;
if (strcmp(ifvers, Plugin_info.ifvers))
{
int mmajor = 0, mminor = 0, pmajor = 0, pminor = 0;
LOG_MESSAGE(PLID, "WARNING: meta-interface version mismatch; requested=%s ours=%s", Plugin_info.logtag, ifvers);
sscanf(ifvers, "%d:%d", &mmajor, &mminor);
sscanf(META_INTERFACE_VERSION, "%d:%d", &pmajor, &pminor);
sscanf(Plugin_info.ifvers, "%d:%d", &pmajor, &pminor);
if (strcmp(ifvers, Plugin_info.ifvers))
{
LOG_MESSAGE(PLID, "warning: ifvers mismatch (pl \"%s\") (mm \"%s\")", Plugin_info.ifvers, ifvers);
if (pmajor > mmajor)
{
LOG_ERROR(PLID, "metamod version is too old for this plugin; update metamod");
return (FALSE);
}
else if (pmajor < mmajor)
{
} else if (pmajor < mmajor) {
LOG_ERROR(PLID, "metamod version is incompatible with this plugin; please find a newer version of this plugin");
return (FALSE);
}
else if (pmajor == mmajor)
{
#ifdef FAKEMETA
if (mminor == 10)
{
LOG_MESSAGE(PLID, "WARNING: metamod version is older than expected; consider finding a newer version");
g_IsNewMM = false;
//hack!
Plugin_info.ifvers = "5:10";
#else
if (mminor < 11)
{
g_NeedsP = true;
#endif
}
else if (mminor >= 11)
{
g_IsNewMM = true;
}
else if (pminor > mminor)
} else if (pmajor == mmajor) {
if (pminor > mminor)
{
LOG_ERROR(PLID, "metamod version is incompatible with this plugin; please find a newer version of this plugin");
return FALSE;
} else if (pminor < mminor) {
LOG_MESSAGE(PLID, "warning: there may be a newer version of metamod available");
}
else if (pminor < mminor)
{
LOG_MESSAGE(PLID, "WARNING: metamod version is newer than expected; consider finding a newer version of this plugin");
if (mminor > 11)
g_IsNewMM = true;
}
} else {
LOG_ERROR(PLID, "unexpected version comparison; metavers=%s, mmajor=%d, mminor=%d; plugvers=%s, pmajor=%d, pminor=%d", ifvers, mmajor, mminor, META_INTERFACE_VERSION, pmajor, pminor);
}
} else {
g_IsNewMM = true;
}
// We can set this to null here because Meta_PExtGiveFnptrs is called after this
gpMetaPExtFuncs = NULL;
// :NOTE: Don't call modules query here (g_FakeMeta.Meta_Query), because we don't know modules yet. Do it in Meta_Attach
return (TRUE);
}
// evilspy's patch for mm-p ext support
// this is called right after Meta_Query
C_DLLEXPORT int Meta_PExtGiveFnptrs(int interfaceVersion, pextension_funcs_t *pMetaPExtFuncs)
{
if (interfaceVersion < META_PEXT_VERSION)
{
return (META_PEXT_VERSION);
}
gpMetaPExtFuncs = pMetaPExtFuncs;
return (META_PEXT_VERSION);
}
static META_FUNCTIONS gMetaFunctionTable;
C_DLLEXPORT int Meta_Attach(PLUG_LOADTIME now, META_FUNCTIONS *pFunctionTable, meta_globals_t *pMGlobals, gamedll_funcs_t *pGamedllFuncs)
{
@ -1222,21 +1197,13 @@ C_DLLEXPORT int Meta_Attach(PLUG_LOADTIME now, META_FUNCTIONS *pFunctionTable, m
return (FALSE);
}
if (g_NeedsP && !gpMetaPExtFuncs)
{
LOG_ERROR(PLID, "You need Metamod-P or Metamod-1.18 to use AMX Mod X %s!", AMX_VERSION);
return (FALSE);
}
gpMetaGlobals = pMGlobals;
gMetaFunctionTable.pfnGetEntityAPI2 = GetEntityAPI2;
gMetaFunctionTable.pfnGetEntityAPI2_Post = GetEntityAPI2_Post;
gMetaFunctionTable.pfnGetEngineFunctions = GetEngineFunctions;
gMetaFunctionTable.pfnGetEngineFunctions_Post = GetEngineFunctions_Post;
#if !defined AMD64
gMetaFunctionTable.pfnGetNewDLLFunctions = GetNewDLLFunctions;
#ifdef FAKEMETA
gMetaFunctionTable.pfnGetNewDLLFunctions_Post = GetNewDLLFunctions_Post;
#endif
memcpy(pFunctionTable, &gMetaFunctionTable, sizeof(META_FUNCTIONS));
@ -1247,6 +1214,8 @@ C_DLLEXPORT int Meta_Attach(PLUG_LOADTIME now, META_FUNCTIONS *pFunctionTable, m
CVAR_REGISTER(&init_amxmodx_version);
CVAR_REGISTER(&init_amxmodx_modules);
CVAR_REGISTER(&init_amxmodx_debug);
CVAR_REGISTER(&init_amxmodx_mldebug);
CVAR_REGISTER(&init_amxmodx_cl_langs);
amxmodx_version = CVAR_GET_POINTER(init_amxmodx_version.name);
@ -1269,7 +1238,7 @@ C_DLLEXPORT int Meta_Attach(PLUG_LOADTIME now, META_FUNCTIONS *pFunctionTable, m
g_coloredmenus = false;
// ###### Print short GPL
print_srvconsole("\n AMX Mod X version %s Copyright (c) 2004-2005 AMX Mod X Development Team \n"
print_srvconsole("\n AMX Mod X version %s Copyright (c) 2004-2006 AMX Mod X Development Team \n"
" AMX Mod X comes with ABSOLUTELY NO WARRANTY; for details type `amxx gpl'.\n", AMX_VERSION);
print_srvconsole(" This is free software and you are welcome to redistribute it under \n"
" certain conditions; type 'amxx gpl' for details.\n \n");
@ -1324,15 +1293,10 @@ C_DLLEXPORT int Meta_Detach(PLUG_LOADTIME now, PL_UNLOAD_REASON reason)
g_xvars.clear();
g_plugins.clear();
g_cvars.clear();
g_langMngr.Clear();
detachModules();
// ###### Now detach metamod modules
#ifdef FAKEMETA
g_FakeMeta.Meta_Detach(now, reason);
g_FakeMeta.ReleasePlugins();
#endif
g_log.CloseFile();
Module_UncacheFunctions();
@ -1420,6 +1384,8 @@ C_DLLEXPORT void __stdcall GiveFnptrsToDll(enginefuncs_t* pengfuncsFromEngine, g
DLL_FUNCTIONS gFunctionTable;
C_DLLEXPORT int GetEntityAPI2(DLL_FUNCTIONS *pFunctionTable, int *interfaceVersion)
{
memset(&gFunctionTable, 0, sizeof(DLL_FUNCTIONS));
gFunctionTable.pfnSpawn = C_Spawn;
gFunctionTable.pfnClientCommand = C_ClientCommand;
gFunctionTable.pfnServerDeactivate = C_ServerDeactivate;
@ -1427,17 +1393,16 @@ C_DLLEXPORT int GetEntityAPI2(DLL_FUNCTIONS *pFunctionTable, int *interfaceVersi
gFunctionTable.pfnInconsistentFile = C_InconsistentFile;
gFunctionTable.pfnServerActivate = C_ServerActivate;
#ifdef FAKEMETA
return g_FakeMeta.GetEntityAPI2(pFunctionTable, interfaceVersion, &gFunctionTable);
#else
memcpy(pFunctionTable, &gFunctionTable, sizeof(DLL_FUNCTIONS));
return 1;
#endif
}
DLL_FUNCTIONS gFunctionTable_Post;
C_DLLEXPORT int GetEntityAPI2_Post(DLL_FUNCTIONS *pFunctionTable, int *interfaceVersion)
{
memset(&gFunctionTable_Post, 0, sizeof(DLL_FUNCTIONS));
gFunctionTable_Post.pfnClientPutInServer = C_ClientPutInServer_Post;
gFunctionTable_Post.pfnClientUserInfoChanged = C_ClientUserInfoChanged_Post;
gFunctionTable_Post.pfnServerActivate = C_ServerActivate_Post;
@ -1445,17 +1410,16 @@ C_DLLEXPORT int GetEntityAPI2_Post(DLL_FUNCTIONS *pFunctionTable, int *interface
gFunctionTable_Post.pfnStartFrame = C_StartFrame_Post;
gFunctionTable_Post.pfnServerDeactivate = C_ServerDeactivate_Post;
#ifdef FAKEMETA
return g_FakeMeta.GetEntityAPI2_Post(pFunctionTable, interfaceVersion, &gFunctionTable_Post);
#else
memcpy(pFunctionTable, &gFunctionTable_Post, sizeof(DLL_FUNCTIONS));
return 1;
#endif
}
enginefuncs_t meta_engfuncs;
C_DLLEXPORT int GetEngineFunctions(enginefuncs_t *pengfuncsFromEngine, int *interfaceVersion)
{
memset(&meta_engfuncs, 0, sizeof(enginefuncs_t));
if (stricmp(g_mod_name.c_str(), "cstrike") == 0 || stricmp(g_mod_name.c_str(), "czero") == 0)
{
meta_engfuncs.pfnSetModel = C_SetModel;
@ -1472,17 +1436,16 @@ C_DLLEXPORT int GetEngineFunctions(enginefuncs_t *pengfuncsFromEngine, int *inte
meta_engfuncs.pfnPrecacheSound = C_PrecacheSound;
meta_engfuncs.pfnChangeLevel = C_ChangeLevel;
#ifdef FAKEMETA
return g_FakeMeta.GetEngineFunctions(pengfuncsFromEngine, interfaceVersion, &meta_engfuncs);
#else
memcpy(pengfuncsFromEngine, &meta_engfuncs, sizeof(enginefuncs_t));
return 1;
#endif
}
enginefuncs_t meta_engfuncs_post;
C_DLLEXPORT int GetEngineFunctions_Post(enginefuncs_t *pengfuncsFromEngine, int *interfaceVersion)
{
memset(&meta_engfuncs_post, 0, sizeof(enginefuncs_t));
meta_engfuncs_post.pfnTraceLine = C_TraceLine_Post;
meta_engfuncs_post.pfnMessageBegin = C_MessageBegin_Post;
meta_engfuncs_post.pfnMessageEnd = C_MessageEnd_Post;
@ -1497,39 +1460,28 @@ C_DLLEXPORT int GetEngineFunctions_Post(enginefuncs_t *pengfuncsFromEngine, int
meta_engfuncs_post.pfnAlertMessage = C_AlertMessage_Post;
meta_engfuncs_post.pfnRegUserMsg = C_RegUserMsg_Post;
#ifdef FAKEMETA
return g_FakeMeta.GetEngineFunctions_Post(pengfuncsFromEngine, interfaceVersion, &meta_engfuncs_post);
#else
memcpy(pengfuncsFromEngine, &meta_engfuncs_post, sizeof(enginefuncs_t));
return 1;
#endif
}
//quick hack - disable all newdll stuff for AMD64
// until VALVe gets their act together!
#if !defined AMD64
NEW_DLL_FUNCTIONS gNewDLLFunctionTable;
C_DLLEXPORT int GetNewDLLFunctions(NEW_DLL_FUNCTIONS *pNewFunctionTable, int *interfaceVersion)
{
memset(&gNewDLLFunctionTable, 0, sizeof(NEW_DLL_FUNCTIONS));
// default metamod does not call this if the gamedll doesn't provide it
g_NewDLL_Available = true;
// If pfnQueryClientCvarValue is not available, the newdllfunctions table will probably
// not have the pfnCvarValue member -> better don't write there to avoid corruption
if (g_engfuncs.pfnQueryClientCvarValue)
gNewDLLFunctionTable.pfnCvarValue = C_CvarValue;
#ifdef FAKEMETA
return g_FakeMeta.GetNewDLLFunctions(pNewFunctionTable, interfaceVersion, &gNewDLLFunctionTable);
#else
memcpy(pNewFunctionTable, &gNewDLLFunctionTable, sizeof(NEW_DLL_FUNCTIONS));
return 1;
#endif
}
#ifdef FAKEMETA
NEW_DLL_FUNCTIONS gNewDLLFunctionTable_Post;
C_DLLEXPORT int GetNewDLLFunctions_Post(NEW_DLL_FUNCTIONS *pNewFunctionTable, int *interfaceVersion)
if (g_engfuncs.pfnQueryClientCvarValue2)
{
return g_FakeMeta.GetNewDLLFunctions_Post(pNewFunctionTable, interfaceVersion, &gNewDLLFunctionTable_Post);
memcpy(pNewFunctionTable, &gNewDLLFunctionTable_Post, sizeof(NEW_DLL_FUNCTIONS));
gNewDLLFunctionTable.pfnCvarValue2 = C_CvarValue2;
g_NewDLL_Available = true;
}
memcpy(pNewFunctionTable, &gNewDLLFunctionTable, sizeof(NEW_DLL_FUNCTIONS));
return 1;
}
#endif

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 */

View File

@ -44,6 +44,8 @@
#include "newmenus.h"
#include "natives.h"
#include "debugger.h"
#include "optimizer.h"
#include "binlog.h"
CList<CModule, const char*> g_modules;
CList<CScript, AMX*> g_loadedscripts;
@ -56,6 +58,30 @@ ModuleCallReason g_ModuleCallReason;
extern const char* no_function; // stupid work around
bool DirExists(const char *dir)
{
#if defined WIN32 || defined _WIN32
DWORD attr = GetFileAttributes(dir);
if (attr == INVALID_FILE_ATTRIBUTES)
return false;
if (attr & FILE_ATTRIBUTE_DIRECTORY)
return true;
#else
struct stat s;
if (stat(dir, &s) != 0)
return false;
if (S_ISDIR(s.st_mode))
return true;
#endif
return false;
}
void report_error(int code, char* fmt, ...)
{
va_list argptr;
@ -100,6 +126,38 @@ void free_amxmemory(void **ptr)
*ptr = 0;
}
#if defined BINLOG_ENABLED
void BinLog_LogNative(AMX *amx, int native, int params)
{
CPluginMngr::CPlugin *pl = g_plugins.findPluginFast(amx);
if (pl)
g_BinLog.WriteOp(BinLog_NativeCall, pl->getId(), native, params);
}
void BinLog_LogReturn(AMX *amx, cell retval)
{
CPluginMngr::CPlugin *pl = g_plugins.findPluginFast(amx);
if (pl)
g_BinLog.WriteOp(BinLog_NativeRet, pl->getId(), retval);
}
void BinLog_LogParams(AMX *amx, cell *params)
{
if (g_binlog_level & 8)
{
CPluginMngr::CPlugin *pl = g_plugins.findPluginFast(amx);
if (pl)
g_BinLog.WriteOp(BinLog_NativeParams, pl->getId(), params);
}
}
static binlogfuncs_t logfuncs =
{
BinLog_LogNative,
BinLog_LogReturn,
BinLog_LogParams
};
#endif
int load_amxscript(AMX *amx, void **program, const char *filename, char error[64], int debug)
{
*error = 0;
@ -209,6 +267,11 @@ int load_amxscript(AMX *amx, void **program, const char *filename, char error[64
#endif
}
if (g_opt_level != 65536)
{
SetupOptimizer(amx);
}
if ((err = amx_Init(amx, *program)) != AMX_ERR_NONE)
{
if (pDbg)
@ -224,6 +287,10 @@ int load_amxscript(AMX *amx, void **program, const char *filename, char error[64
Handler *pHandler = new Handler(amx);
amx->userdata[UD_HANDLER] = (void *)pHandler;
#if defined BINLOG_ENABLED
amx->usertags[UT_BINLOGS] = (void *)&logfuncs;
#endif
if (will_be_debugged)
{
amx->flags |= AMX_FLAG_DEBUG;
@ -454,6 +521,9 @@ int set_amxnatives(AMX* amx, char error[128])
int idx, err;
cell retval;
Debugger *pd;
pd = DisableDebugHandler(amx);
if (amx_FindPublic(amx, "plugin_natives", &idx) == AMX_ERR_NONE)
{
if ((err = amx_Exec(amx, &retval, idx)) != AMX_ERR_NONE)
@ -463,6 +533,8 @@ int set_amxnatives(AMX* amx, char error[128])
}
}
EnableDebugHandler(amx, pd);
amx->flags &= ~(AMX_FLAG_PRENIT);
return (amx->error = AMX_ERR_NONE);
@ -480,6 +552,10 @@ int unload_amxscript(AMX* amx, void** program)
if (pHandler)
delete pHandler;
optimizer_s *opt = (optimizer_s *)amx->usertags[UT_OPTIMIZER];
if (opt)
delete opt;
CList<CScript, AMX*>::iterator a = g_loadedscripts.find(amx);
if (a)
@ -542,6 +618,23 @@ AMX* get_amxscript(int id, void** code, const char** filename)
return 0;
}
const char* GetFileName(AMX *amx)
{
const char *filename = "";
CPluginMngr::CPlugin *pl = g_plugins.findPluginFast(amx);
if (pl)
{
filename = pl->getName();
} else {
CList<CScript,AMX*>::iterator a = g_loadedscripts.find(amx);
if (a)
filename = (*a).getName();
}
return filename;
}
const char* get_amxscriptname(AMX* amx)
{
CList<CScript, AMX*>::iterator a = g_loadedscripts.find(amx);
@ -856,7 +949,6 @@ int loadModules(const char* filename, PLUG_LOADTIME now)
g_modules.put(cc);
#ifndef FAKEMETA
if (cc->IsMetamod())
{
char* mmpathname = build_pathname_addons("%s/%s", get_localinfo("amxx_modulesdir", "addons/amxmodx/modules"), line.c_str());
@ -885,7 +977,6 @@ int loadModules(const char* filename, PLUG_LOADTIME now)
break;
}
}
#endif
}
fclose(fp);
@ -910,11 +1001,7 @@ void detachReloadModules()
while (a)
{
#ifdef FAKEMETA
if ((*a).isReloadable())
#else
if ((*a).isReloadable() && !(*a).IsMetamod())
#endif
{
(*a).detachModule();
a.remove();
@ -925,38 +1012,6 @@ void detachReloadModules()
}
}
#ifdef FAKEMETA
void attachModules()
{
CList<CModule, const char *>::iterator a = g_modules.begin();
while (a)
{
bool retVal = (*a).attachModule();
if ((*a).isAmxx() && !retVal)
{
switch ((*a).getStatusValue())
{
case MODULE_FUNCNOTPRESENT:
report_error(1, "[AMXX] Module requested a not exisitng function (file \"%s\")%s%s%s", (*a).getFilename(), (*a).getMissingFunc() ? " (func \"" : "",
(*a).getMissingFunc() ? (*a).getMissingFunc() : "", (*a).getMissingFunc() ? "\")" : "");
break;
case MODULE_INTERROR:
report_error(1, "[AMXX] Internal error during module load (file \"%s\")", (*a).getFilename());
break;
case MODULE_BADLOAD:
report_error(1, "[AMXX] Module is not a valid library (file \"%s\")", (*a).getFilename());
break;
default:
break;
}
}
++a;
}
}
#endif
const char* strip_name(const char* a)
{
const char* ret = a;
@ -974,72 +1029,6 @@ const char* strip_name(const char* a)
return ret;
}
#ifdef FAKEMETA
void attachMetaModModules(PLUG_LOADTIME now, const char* filename)
{
File fp(build_pathname("%s", filename), "r");
if (!fp)
{
AMXXLOG_Log("[AMXX] Modules list not found (file \"%s\")", filename);
return;
}
char line[256], moduleName[256];
String modPath, mmPath;
DLHANDLE module;
while (fp.getline(line, 255))
{
*moduleName = 0;
sscanf(line, "%s", moduleName);
if (!isalnum(*moduleName))
continue;
char* pathname = build_pathname("%s/%s", get_localinfo("amxx_modulesdir", "addons/amxmodx/modules"), line);
char* mmpathname = build_pathname_addons("%s/%s", get_localinfo("amxx_modulesdir", "addons/amxmodx/modules"), line);
ConvertModuleName(pathname, modPath);
ConvertModuleName(mmpathname, mmPath);
CList<CFakeMeta::CFakeMetaPlugin>::iterator iter = g_FakeMeta.m_Plugins.begin();
//prevent double loading
int foundFlag = 0;
while (iter)
{
if (strcmp((*iter).GetPath(), mmPath.c_str()) == 0)
{
foundFlag = 1;
break;
}
++iter;
}
if (foundFlag)
continue;
module = DLLOAD(modPath.c_str()); // link dll
if (module)
{
int a = (int)DLPROC(module, "Meta_Attach");
DLFREE(module);
if (a)
{
g_FakeMeta.AddPlugin(mmPath.c_str());
}
}
}
g_FakeMeta.Meta_Query(gpMetaUtilFuncs);
g_FakeMeta.Meta_Attach(now, gpMetaGlobals, gpGamedllFuncs);
}
#endif
// Get the number of running modules
int countModules(CountModulesMode mode)
{
@ -1194,7 +1183,7 @@ int MNF_FindAmxScriptByAmx(const AMX *amx)
return i;
}
char *MNF_GetAmxString(AMX *amx, cell amx_addr, int bufferId, int *pLen)
extern "C" char *MNF_GetAmxString(AMX *amx, cell amx_addr, int bufferId, int *pLen)
{
int len;
char *retVal = get_amxstring(amx, amx_addr, bufferId, len);
@ -1215,6 +1204,17 @@ int MNF_GetAmxStringLen(const cell *ptr)
return c;
}
List<AUTHORIZEFUNC> g_auth_funcs;
void MNF_RegAuthorizeFunc(AUTHORIZEFUNC fn)
{
g_auth_funcs.push_back(fn);
}
void MNF_UnregAuthorizeFunc(AUTHORIZEFUNC fn)
{
g_auth_funcs.remove(fn);
}
char *MNF_FormatAmxString(AMX *amx, cell *params, int startParam, int *pLen)
{
int len;
@ -1421,7 +1421,7 @@ void MNF_Log(const char *fmt, ...)
//by BAILOPAN
// debugger engine front end
void LogError(AMX *amx, int err, const char *fmt, ...)
extern "C" void LogError(AMX *amx, int err, const char *fmt, ...)
{
Debugger *pDebugger = (Debugger *)amx->userdata[UD_DEBUGGER];
@ -1439,6 +1439,12 @@ void LogError(AMX *amx, int err, const char *fmt, ...)
va_end(ap);
}
#if defined BINLOG_ENABLED
CPluginMngr::CPlugin *pl = g_plugins.findPluginFast(amx);
if (pl)
g_BinLog.WriteOp(BinLog_NativeError, pl->getId(), err, msg_buffer);
#endif
//give the plugin first chance to handle any sort of error
Handler *pHandler = (Handler *)amx->userdata[UD_HANDLER];
@ -1497,12 +1503,7 @@ edict_t* MNF_GetPlayerEdict(int id)
const char *MNF_Format(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
const char *retVal = g_langMngr.FormatString(fmt, ap);
va_end(ap);
return retVal;
return "";
}
const char *MNF_GetPlayerTeam(int id)
@ -1573,6 +1574,77 @@ void Module_UncacheFunctions()
g_functions.clear();
}
int MNF_SetPlayerTeamInfo(int player, int teamid, const char *teamname)
{
if (player < 1 || player > gpGlobals->maxClients)
return 0;
CPlayer *pPlayer = GET_PLAYER_POINTER_I(player);
if (!pPlayer->ingame)
return 0;
pPlayer->teamId = teamid;
if (teamname != NULL)
pPlayer->team.assign(teamname);
return 1;
}
void *MNF_PlayerPropAddr(int id, int prop)
{
if (id < 1 || id > gpGlobals->maxClients)
return NULL;
CPlayer *pPlayer = GET_PLAYER_POINTER_I(id);
switch (prop)
{
case Player_Name:
return &pPlayer->name;
case Player_Ip:
return &pPlayer->ip;
case Player_Team:
return &pPlayer->team;
case Player_Ingame:
return &pPlayer->ingame;
case Player_Authorized:
return &pPlayer->authorized;
case Player_Vgui:
return &pPlayer->vgui;
case Player_Time:
return &pPlayer->time;
case Player_Playtime:
return &pPlayer->playtime;
case Player_MenuExpire:
return &pPlayer->menuexpire;
case Player_Weapons:
return &pPlayer->weapons[0];
case Player_CurrentWeapon:
return &pPlayer->current;
case Player_TeamID:
return &pPlayer->teamId;
case Player_Deaths:
return &pPlayer->deaths;
case Player_Aiming:
return &pPlayer->aiming;
case Player_Menu:
return &pPlayer->menu;
case Player_Keys:
return &pPlayer->keys;
case Player_Flags:
return &pPlayer->flags[0];
case Player_Newmenu:
return &pPlayer->newmenu;
case Player_NewmenuPage:
return &pPlayer->page;
default:
return NULL;
}
return NULL;
}
int amx_Execv()
{
return AMX_ERR_NOTFOUND;
@ -1654,6 +1726,11 @@ void Module_CacheFunctions()
REGISTER_FUNC("GetPlayerEdict", MNF_GetPlayerEdict)
REGISTER_FUNC("CellToReal", MNF_CellToReal)
REGISTER_FUNC("RealToCell", MNF_RealToCell)
REGISTER_FUNC("SetPlayerTeamInfo", MNF_SetPlayerTeamInfo)
REGISTER_FUNC("PlayerPropAddr", MNF_PlayerPropAddr)
REGISTER_FUNC("RegAuthFunc", MNF_RegAuthorizeFunc);
REGISTER_FUNC("UnregAuthFunc", MNF_UnregAuthorizeFunc);
#ifdef MEMORY_TEST
REGISTER_FUNC("Allocator", m_allocator)
@ -1689,24 +1766,44 @@ void *Module_ReqFnptr(const char *funcName)
return NULL;
}
Debugger *DisableDebugHandler(AMX *amx)
{
Debugger *pd = static_cast<Debugger *>(amx->userdata[UD_DEBUGGER]);
amx->userdata[UD_DEBUGGER] = NULL;
amx->flags &= ~(AMX_FLAG_DEBUG);
amx_SetDebugHook(amx, NULL);
return pd;
}
void EnableDebugHandler(AMX *amx, Debugger *pd)
{
if (pd)
amx->flags |= AMX_FLAG_DEBUG;
amx->userdata[UD_DEBUGGER] = pd;
amx_SetDebugHook(amx, &Debugger::DebugHook);
}
#if !defined MEMORY_TEST && !defined WIN32
void * ::operator new(size_t size)
void * operator new(size_t size)
{
return (calloc(1, size));
}
void * ::operator new[](size_t size)
void * operator new[](size_t size)
{
return (calloc(1, size));
}
void ::operator delete(void * ptr)
void operator delete(void * ptr)
{
if (ptr)
free(ptr);
}
void ::operator delete[](void * ptr)
void operator delete[](void * ptr)
{
if (ptr)
free(ptr);

View File

@ -48,7 +48,38 @@
#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]);
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);
#endif // __MODULES_H__

View File

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

View File

@ -7,8 +7,10 @@ Global
GlobalSection(SolutionConfiguration) = preSolution
Debug = Debug
JITDebug = JITDebug
JITDebugBinLog = JITDebugBinLog
JITMemtestRelease = JITMemtestRelease
JITRelease = JITRelease
JITReleaseBinLog = JITReleaseBinLog
MaximalSpeed = MaximalSpeed
MemtestDebug = MemtestDebug
MemtestRelease = MemtestRelease
@ -19,10 +21,14 @@ Global
{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}.JITDebugBinLog.ActiveCfg = JITDebugBinLog|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITDebugBinLog.Build.0 = JITDebugBinLog|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}.JITRelease.ActiveCfg = JITRelease|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITRelease.Build.0 = JITRelease|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITReleaseBinLog.ActiveCfg = JITReleaseBinLog|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITReleaseBinLog.Build.0 = JITReleaseBinLog|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

View File

@ -164,7 +164,7 @@
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"
RuntimeLibrary="3"
StructMemberAlignment="3"
UsePrecompiledHeader="2"
PrecompiledHeaderThrough="amxmodx.h"
@ -183,7 +183,7 @@
AdditionalOptions="/MACHINE:I386"
AdditionalDependencies="odbc32.lib odbccp32.lib ..\zlib\zlib.lib ..\JIT\natives-x86.obj"
OutputFile="memtestdebug/amxmodx_mm.dll"
Version="0.1"
Version="1.6.5.0"
LinkIncremental="2"
SuppressStartupBanner="TRUE"
AdditionalLibraryDirectories="..\extra\lib_win32"
@ -257,7 +257,7 @@
LinkIncremental="1"
SuppressStartupBanner="TRUE"
AdditionalLibraryDirectories="..\extra\lib_win32"
IgnoreDefaultLibraryNames="LIBC"
IgnoreDefaultLibraryNames="MSVCRT"
ModuleDefinitionFile=""
GenerateDebugInformation="TRUE"
ProgramDatabaseFile=".\memtestrelease/amxx_mm.pdb"
@ -303,7 +303,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"
@ -326,7 +326,7 @@
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"
@ -372,10 +372,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"
@ -390,6 +393,7 @@
ProgramDataBaseFileName=".\jitrelease/"
WarningLevel="3"
SuppressStartupBanner="TRUE"
DebugInformationFormat="3"
CompileAs="0"/>
<Tool
Name="VCCustomBuildTool"/>
@ -404,8 +408,8 @@
IgnoreDefaultLibraryNames="MSVCRT"
ModuleDefinitionFile=""
GenerateDebugInformation="TRUE"
ProgramDatabaseFile=".\jitrelease/amxx_mm.pdb"
GenerateMapFile="FALSE"
ProgramDatabaseFile=".\jitrelease/amxmodx_mm.pdb"
GenerateMapFile="TRUE"
ImportLibrary=".\jitrelease/amxx_mm.lib"/>
<Tool
Name="VCMIDLTool"
@ -576,6 +580,153 @@
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="JITDebugBinLog|Win32"
OutputDirectory="$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="2"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
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=".\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 ..\JIT\natives-x86.obj"
OutputFile="jitdebugbinlog/amxmodx_mm.dll"
Version="0.1"
LinkIncremental="2"
SuppressStartupBanner="TRUE"
AdditionalLibraryDirectories="..\extra\lib_win32"
IgnoreDefaultLibraryNames="MSVCRT"
ModuleDefinitionFile=""
GenerateDebugInformation="TRUE"
ProgramDatabaseFile=".\jitdebugbinlog/amxx_mm.pdb"
ImportLibrary=".\jitdebugbinlog/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="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"
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;BINLOG_ENABLED"
IgnoreStandardIncludePath="FALSE"
StringPooling="TRUE"
RuntimeLibrary="4"
EnableFunctionLevelLinking="TRUE"
UsePrecompiledHeader="2"
PrecompiledHeaderThrough="amxmodx.h"
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="..\zlib\zlib.lib ..\JIT\amxjitsn.obj ..\JIT\amxexecn.obj ..\JIT\natives-x86.obj"
OutputFile="jitreleasebinlog/amxmodx_mm.dll"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
AdditionalLibraryDirectories="..\extra\lib_win32"
IgnoreDefaultLibraryNames="MSVCRT"
ModuleDefinitionFile=""
GenerateDebugInformation="TRUE"
ProgramDatabaseFile=".\jitreleasebinlog/amxmodx_mm.pdb"
GenerateMapFile="TRUE"
ImportLibrary=".\jitreleasebinlog/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>
</Configurations>
<References>
</References>
@ -604,6 +755,9 @@
<File
RelativePath="..\amxxlog.cpp">
</File>
<File
RelativePath="..\binlog.cpp">
</File>
<File
RelativePath="..\CCmd.cpp">
</File>
@ -636,6 +790,18 @@
</File>
<File
RelativePath="..\CTask.cpp">
<FileConfiguration
Name="JITRelease|Win32">
<Tool
Name="VCCLCompilerTool"
AssemblerOutput="0"/>
</FileConfiguration>
<FileConfiguration
Name="JITReleaseBinLog|Win32">
<Tool
Name="VCCLCompilerTool"
AssemblerOutput="0"/>
</FileConfiguration>
</File>
<File
RelativePath="..\CVault.cpp">
@ -661,6 +827,21 @@
<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="..\md5.cpp">
</File>
@ -676,6 +857,9 @@
<File
RelativePath="..\newmenus.cpp">
</File>
<File
RelativePath="..\optimizer.cpp">
</File>
<File
RelativePath="..\power.cpp">
</File>
@ -684,6 +868,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">
@ -729,6 +925,18 @@
<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>
</Filter>
</Filter>
@ -750,6 +958,9 @@
<File
RelativePath="..\amxxlog.h">
</File>
<File
RelativePath="..\binlog.h">
</File>
<File
RelativePath="..\CCmd.h">
</File>
@ -786,9 +997,6 @@
<File
RelativePath="..\CQueue.h">
</File>
<File
RelativePath="..\CStack.h">
</File>
<File
RelativePath="..\CString.h">
</File>
@ -807,6 +1015,9 @@
<File
RelativePath="..\fakemeta.h">
</File>
<File
RelativePath="..\format.h">
</File>
<File
RelativePath="..\md5.h">
</File>
@ -822,9 +1033,21 @@
<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>
@ -861,12 +1084,95 @@
<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="Debug|Win32"
ExcludedFromBuild="TRUE">
<Tool
Name="VCCLCompilerTool"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
ExcludedFromBuild="TRUE">
<Tool
Name="VCCLCompilerTool"/>
</FileConfiguration>
<FileConfiguration
Name="MemtestDebug|Win32"
ExcludedFromBuild="TRUE">
<Tool
Name="VCCLCompilerTool"/>
</FileConfiguration>
<FileConfiguration
Name="MemtestRelease|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="JITMemtestRelease|Win32"
ExcludedFromBuild="TRUE">
<Tool
Name="VCCLCompilerTool"/>
</FileConfiguration>
<FileConfiguration
Name="MaximalSpeed|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>

View File

@ -0,0 +1,37 @@
Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "amxmodx", "amxmodx_mm.vcproj", "{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
JITDebug|Win32 = JITDebug|Win32
JITMemtestRelease|Win32 = JITMemtestRelease|Win32
JITRelease|Win32 = JITRelease|Win32
MaximalSpeed|Win32 = MaximalSpeed|Win32
MemtestDebug|Win32 = MemtestDebug|Win32
MemtestRelease|Win32 = MemtestRelease|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.Debug|Win32.ActiveCfg = Debug|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.Debug|Win32.Build.0 = Debug|Win32
{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}.JITMemtestRelease|Win32.ActiveCfg = JITMemtestRelease|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITMemtestRelease|Win32.Build.0 = JITMemtestRelease|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}.MaximalSpeed|Win32.ActiveCfg = MaximalSpeed|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.MaximalSpeed|Win32.Build.0 = MaximalSpeed|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.MemtestDebug|Win32.ActiveCfg = MemtestDebug|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.MemtestDebug|Win32.Build.0 = MemtestDebug|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.MemtestRelease|Win32.ActiveCfg = MemtestRelease|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.MemtestRelease|Win32.Build.0 = MemtestRelease|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.Release|Win32.ActiveCfg = Release|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

File diff suppressed because it is too large Load Diff

View File

@ -29,8 +29,9 @@
*/
#include "amxmodx.h"
#include "CStack.h"
#include "sh_stack.h"
#include "natives.h"
#include "debugger.h"
#ifdef __linux__
#include <malloc.h>
@ -43,11 +44,11 @@
//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)
@ -74,7 +75,7 @@ int amxx_DynaCallback(int idx, AMX *amx, cell *params)
int err = 0;
cell ret = 0;
g_errorNum = 0;
g_ErrorStk.push(0);
g_NativeStack.push(pNative);
if (pNative->style == 0)
{
@ -87,19 +88,29 @@ 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();
return ret;
}
@ -133,7 +144,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;
}
@ -146,7 +158,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");
@ -167,7 +179,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");
@ -190,7 +202,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");
@ -209,7 +221,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");
@ -230,7 +242,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");
@ -253,7 +265,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");
@ -279,7 +291,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");
@ -308,7 +320,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");

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

View File

@ -32,6 +32,7 @@
#include "newmenus.h"
CVector<Menu *> g_NewMenus;
CStack<int> g_MenuFreeStack;
void ClearMenus()
{
@ -39,6 +40,36 @@ void ClearMenus()
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)
@ -46,6 +77,23 @@ 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()
@ -53,6 +101,8 @@ Menu::~Menu()
for (size_t i = 0; i < m_Items.size(); i++)
delete m_Items[i];
unregisterSPForward(this->func);
m_Items.clear();
}
@ -88,69 +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 (m_AlwaysExit && 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 MENU_EXIT;
}
else if (key == rem + 1)
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_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)
@ -187,21 +221,51 @@ const char *Menu::GetTextString(int player, page_t page, int &keys)
m_Text.clear();
char buffer[255];
if (g_coloredmenus)
if (items_per_page && (pages != 1))
{
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 {
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);
item_t start = page * 7;
item_t end = 0;
if (start + 7 <= numItems)
enum
{
end = start + 7;
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 = numItems;
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;
@ -209,8 +273,9 @@ const char *Menu::GetTextString(int player, page_t page, int &keys)
keys = 0;
bool enabled = true;
int ret = 0;
int slots = 0;
for (item_t i = start; i < end; i++)
for (item_t i = start; i <= end; i++)
{
pItem = m_Items[i];
@ -219,7 +284,7 @@ const char *Menu::GetTextString(int player, page_t page, int &keys)
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)
@ -238,9 +303,12 @@ const char *Menu::GetTextString(int player, page_t page, int &keys)
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 {
@ -248,38 +316,96 @@ const char *Menu::GetTextString(int player, page_t page, int &keys)
option++;
}
}
m_Text.append(buffer);
}
slots++;
//now for a weird part >:o
//this will either be MORE or BACK..
keys |= (1<<option++);
if ((page < pages - 1) && (pages > 1))
m_Text.append(buffer);
//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 (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++;
}
}
if (pages > 1)
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];
@ -289,6 +415,7 @@ 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);
@ -302,10 +429,44 @@ 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);
Menu *pMenu = new Menu(title, id, (int)g_NewMenus.size());
g_NewMenus.push_back(pMenu);
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)
@ -318,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];
@ -354,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);
}
@ -467,10 +639,221 @@ static cell AMX_NATIVE_CALL menu_item_setcall(AMX *amx, cell *params)
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},
@ -480,5 +863,9 @@ AMX_NATIVE_INFO g_NewMenuNatives[] =
{"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

@ -39,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);
@ -53,6 +62,8 @@ struct menuitem
MENUITEM_CALLBACK pfn;
size_t id;
CVector<int> blanks;
};
typedef unsigned int menu_t;
@ -75,29 +86,27 @@ public:
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

@ -2502,6 +2502,10 @@ 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;
// *** Exports ***
C_DLLEXPORT int AMXX_Query(int *interfaceVersion, amxx_module_info_s *moduleInfo)
@ -2611,6 +2615,10 @@ 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);
#ifdef MEMORY_TEST
// Memory
@ -2733,6 +2741,10 @@ void ValidateMacros_DontCallThis_Smiley()
MF_GetPlayerEdict(0);
MF_Format("", 4, "str");
MF_RegisterFunction(NULL, "");
MF_SetPlayerTeamInfo(0, 0, "");
MF_PlayerPropAddr(0, 0);
MF_RegAuthFunc(NULL);
MF_UnregAuthFunc(NULL);
}
#endif
@ -2912,20 +2924,20 @@ void operator delete[](void *reportedAddress)
#else
#if !defined NO_ALLOC_OVERRIDES && !defined MEMORY_TEST && !defined WIN32
void * ::operator new(size_t size) {
void * operator new(size_t size) {
return(calloc(1, size));
}
void * ::operator new[](size_t size) {
void * operator new[](size_t size) {
return(calloc(1, size));
}
void ::operator delete(void * ptr) {
void operator delete(void * ptr) {
if(ptr)
free(ptr);
}
void ::operator delete[](void * ptr) {
void operator delete[](void * ptr) {
if(ptr)
free(ptr);
}

View File

@ -1927,6 +1927,30 @@ 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
};
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*/, ...);
@ -1978,6 +2002,7 @@ 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*/,
@ -2003,6 +2028,9 @@ 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);
extern PFN_ADD_NATIVES g_fn_AddNatives;
extern PFN_BUILD_PATHNAME g_fn_BuildPathname;
@ -2066,6 +2094,10 @@ 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;
#ifdef MAY_NEVER_BE_DEFINED
// Function prototypes for intellisense and similar systems
@ -2126,6 +2158,10 @@ 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) { }
#endif // MAY_NEVER_BE_DEFINED
#define MF_AddNatives g_fn_AddNatives
@ -2189,8 +2225,12 @@ 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
#ifdef MEMORY_TEST
/*** Memory ***/

290
amxmodx/sh_list.h Normal file
View File

@ -0,0 +1,290 @@
/* ======== 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
#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

@ -58,12 +58,17 @@ void amx_command()
a = g_plugins.begin();
int num = 0;
while (a)
{
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;
}
@ -137,8 +142,11 @@ void amx_command()
}
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("%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");
@ -254,7 +262,8 @@ void plugin_srvcmd()
{
if ((*a).matchCommand(cmd) && (*a).getPlugin()->isExecutable((*a).getFunction()))
{
cell ret = executeForwards((*a).getFunction(), g_srvindex, (*a).getFlags(), (*a).getId());
cell ret = executeForwards((*a).getFunction(), static_cast<cell>(g_srvindex),
static_cast<cell>((*a).getFlags()), static_cast<cell>((*a).getId()));
if (ret) break;
}
++a;

View File

@ -31,6 +31,8 @@
#include <ctype.h>
#include "amxmodx.h"
#include "format.h"
#include "binlog.h"
const char* stristr(const char* str, const char* substr)
{
@ -56,7 +58,18 @@ const char* stristr(const char* str, const char* substr)
char* format_amxstring(AMX *amx, cell *params, int parm, int& len)
{
#if !defined BINLOG_ENABLED
return g_langMngr.FormatAmxString(amx, params, parm, len);
#else
char *ans = g_langMngr.FormatAmxString(amx, params, parm, len);
if (g_binlog_level & 4)
{
CPluginMngr::CPlugin *pl = g_plugins.findPluginFast(amx);
if (pl)
g_BinLog.WriteOp(BinLog_FormatString, pl->getId(), parm, len, ans);
}
return ans;
#endif
}
int amxstring_len(cell* a)
@ -76,8 +89,17 @@ cell* get_amxaddr(AMX *amx, cell amx_addr)
int set_amxstring(AMX *amx, cell amx_addr, const char *source, int max)
{
cell* dest = (cell *)(amx->base + (int)(((AMX_HEADER *)amx->base)->dat + amx_addr));
cell* start = dest;
register cell* dest = (cell *)(amx->base + (int)(((AMX_HEADER *)amx->base)->dat + amx_addr));
register cell* start = dest;
#if defined BINLOG_ENABLED
if (g_binlog_level & 2)
{
CPluginMngr::CPlugin *pl = g_plugins.findPluginFast(amx);
if (pl)
g_BinLog.WriteOp(BinLog_SetString, pl->getId(), amx_addr, max, source);
}
#endif
while (max-- && *source)
*dest++ = (cell)*source++;
@ -87,6 +109,29 @@ int set_amxstring(AMX *amx, cell amx_addr, const char *source, int max)
return dest - start;
}
extern "C" size_t get_amxstring_r(AMX *amx, cell amx_addr, char *destination, int maxlen)
{
register cell *source = (cell *)(amx->base + (int)(((AMX_HEADER *)amx->base)->dat + amx_addr));
register char *dest = destination;
char *start = dest;
while (maxlen-- && *source)
*dest++=(char)(*source++);
*dest = '\0';
#if defined BINLOG_ENABLED
if (g_binlog_level & 2)
{
CPluginMngr::CPlugin *pl = g_plugins.findPluginFast(amx);
if (pl)
g_BinLog.WriteOp(BinLog_GetString, pl->getId(), amx_addr, destination);
}
#endif
return dest - start;
}
char* get_amxstring(AMX *amx, cell amx_addr, int id, int& len)
{
static char buffor[4][3072];
@ -98,6 +143,15 @@ char* get_amxstring(AMX *amx, cell amx_addr, int id, int& len)
len = --dest - start;
#if defined BINLOG_ENABLED
if (g_binlog_level & 2)
{
CPluginMngr::CPlugin *pl = g_plugins.findPluginFast(amx);
if (pl)
g_BinLog.WriteOp(BinLog_GetString, pl->getId(), amx_addr, start);
}
#endif
return start;
}
@ -146,62 +200,61 @@ char* parse_arg(char** line, int& state)
return arg;
}
bool fastcellcmp(cell *a, cell *b, cell len)
{
while (len--)
{
if (*a++ != *b++)
return false;
}
return true;
}
static cell AMX_NATIVE_CALL replace(AMX *amx, cell *params) /* 4 param */
{
static char buffor[3072];
cell *text = get_amxaddr(amx, params[1]);
cell len = params[2];
cell *what = get_amxaddr(amx, params[3]);
cell *with = get_amxaddr(amx, params[4]);
cell *textptr = text;
cell *a = get_amxaddr(amx, params[1]);
cell *b = get_amxaddr(amx, params[3]);
cell *c = get_amxaddr(amx, params[4]);
int withLen = amxstring_len(with);
int whatLen = amxstring_len(what);
int textLen = amxstring_len(text);
int iMain = amxstring_len(a);
int iWhat = amxstring_len(b);
int iWith = amxstring_len(c);
int iPot = iMain + iWith - iWhat;
if (whatLen > textLen)
return 0;
if (iPot >= params[2])
if (whatLen < 1)
{
amx_RaiseError(amx,AMX_ERR_NATIVE);
LogError(amx, AMX_ERR_NATIVE, "No search string specified.");
return 0;
}
char *d = buffor;
cell *x, *y, *z = a, *l = a;
int p = 0;
while (*a)
if (textLen - whatLen + withLen > len)
{
if (*a == *b)
{
x = a + 1;
y = b + 1;
p = 1;
if (!*y) break;
while (*x == *y)
{
x++; y++; p++;
if (!*y) break;
LogError(amx, AMX_ERR_NATIVE, "replace() buffer not big enough (%d>=%d)", (textLen - whatLen + withLen), len);
return 0;
}
if (!*y) break;
p = 0;
*d++ = (char)*a++;
continue;
}
*d++ = (char)*a++;
}
if (p)
cell browsed = 0;
while (*text && (browsed <= (textLen-whatLen)))
{
while (*c) *d++ = (char)*c++;
a += p;
while (*a) *d++ = (char)*a++;
*d = 0;
d = buffor;
while (*d) *z++ = *d++;
*z = 0;
return (z - l);
if (*text == *what)
{
if (fastcellcmp(text, what, whatLen))
{
cell *saveptr = text + whatLen;
cell restlen = textLen - (browsed + whatLen);
textptr = text + withLen;
memmove(textptr, saveptr, (restlen + 1) * sizeof(cell));
memcpy(text, with, withLen * sizeof(cell));
return (textLen - whatLen + withLen);
}
}
text++;
browsed++;
}
return 0;
@ -448,10 +501,54 @@ static cell AMX_NATIVE_CALL equali(AMX *amx, cell *params) /* 3 param */
return (f - l) ? 0 : 1;
}
static cell g_cpbuf[4096];
static cell AMX_NATIVE_CALL formatex(AMX *amx, cell *params)
{
cell *buf = get_amxaddr(amx, params[1]);
size_t maxlen = static_cast<size_t>(params[2]);
cell *fmt = get_amxaddr(amx, params[3]);
int param = 4;
size_t total = atcprintf(buf, maxlen, fmt, amx, params, &param);
return static_cast<cell>(total);
}
static cell AMX_NATIVE_CALL format(AMX *amx, cell *params) /* 3 param */
{
int len;
return set_amxstring(amx, params[1], format_amxstring(amx, params, 3, len), params[2]);
cell *buf = get_amxaddr(amx, params[1]);
cell *fmt = get_amxaddr(amx, params[3]);
size_t maxlen = params[2];
/**
* SPECIAL CASE - check if the buffers overlap.
* some users, for whatever reason, do things like:
* format(buf, 255, buf....
* this is considered "deprecated" but we have to support it.
* we do this by checking to see if reading from buf will overlap
*/
cell addr_start = params[1];
cell addr_end = params[1] + maxlen * sizeof(cell);
cell max = params[0] / sizeof(cell);
bool copy = false;
for (cell i = 3; i <= max; i++)
{
//does this clip the bounds?!?!? WELL, DOES IT!?!?! i am a loud dog
if (params[i] >= addr_start && params[i] <= addr_end)
{
copy = true;
break;
}
}
if (copy)
buf = g_cpbuf;
int param = 4;
size_t total = atcprintf(buf, maxlen, fmt, amx, params, &param);
if (copy)
{
/* copy back */
cell *old = get_amxaddr(amx, params[1]);
memcpy(old, g_cpbuf, (total+1) * sizeof(cell));
}
return total;
}
static cell AMX_NATIVE_CALL parse(AMX *amx, cell *params) /* 3 param */
@ -664,73 +761,66 @@ static cell AMX_NATIVE_CALL amx_strtok(AMX *amx, cell *params)
//strbreak(String[], First[], FirstLen, Rest[], RestLen)
static cell AMX_NATIVE_CALL strbreak(AMX *amx, cell *params) /* 5 param */
{
bool quote_flag = false;
bool done_flag = false;
int left_pos = 0;
int right_pos = 0;
int l = 0;
unsigned int i = 0;
char hold = '"';
int _len;
bool in_quote = false;
bool had_quotes = false;
size_t i = 0;
size_t beg = 0;
char *string = get_amxstring(amx, params[1], 0, l);
char *left = new char[strlen(string) + 1];
char *right = new char[strlen(string) + 1];
char *string = get_amxstring(amx, params[1], 0, _len);
cell *left = get_amxaddr(amx, params[2]);
cell *right = get_amxaddr(amx, params[4]);
int LeftMax = params[3];
int RightMax = params[5];
for (i = 0; i < (unsigned int)l; i++)
{
if (string[i] == '"' && !quote_flag)
{
quote_flag = true;
}
else if (string[i] == '"' && quote_flag)
{
quote_flag = false;
}
size_t len = (size_t)_len;
if (isspace(string[i]) && !quote_flag && !done_flag)
{
done_flag = true;
while (isspace(string[i]) && i<len)
i++;
}
if (!done_flag && string[i]!='"')
beg = i;
for (; i<len; i++)
{
if (left_pos < LeftMax)
if (string[i] == '"' && !in_quote)
{
left[left_pos] = string[i];
if (left[left_pos] == '\'')
{
left[left_pos] = hold;
}
left_pos++;
in_quote = (had_quotes = true);
} else if (string[i] == '"' && in_quote) {
in_quote = false;
if (i == len-1)
goto do_copy;
} else {
done_flag = true;
}
} else {
if (right_pos < RightMax && string[i]!='"')
if (isspace(string[i]) && !in_quote)
{
right[right_pos] = string[i];
if (right[right_pos] == '\'')
do_copy:
size_t pos = i;
while (isspace(string[i]))
i++;
const char *start = had_quotes ? &(string[beg+1]) : &(string[beg]);
size_t _end = had_quotes ? (i==len-1 ? 1 : 2) : 0;
size_t end = (pos - _end > (size_t)LeftMax) ? (size_t)LeftMax : pos - _end;
size_t to_go = end-beg;
if (end && to_go)
{
right[right_pos] = hold;
while (to_go--)
*left++ = (cell)*start++;
}
right_pos++;
*left = '\0';
end = (len-i+1 > (size_t)RightMax) ? (size_t)RightMax : len-i+1;
if (end)
{
start = &(string[i]);
while (end--)
*right++ = (cell)*start++;
}
*right = '\0';
return 1;
}
}
}
left[left_pos] = '\0';
right[right_pos] = '\0';
set_amxstring(amx, params[2], left, params[3]);
set_amxstring(amx, params[4], right, params[5]);
delete [] left;
delete [] right;
//if we got here, there was nothing to break
set_amxstring(amx, params[2], &(string[beg]), LeftMax);
if (RightMax)
*right = '\0';
return 1;
}
@ -841,7 +931,7 @@ static cell AMX_NATIVE_CALL n_strcmp(AMX *amx, cell *params)
char *str1 = get_amxstring(amx, params[1], 0, len);
char *str2 = get_amxstring(amx, params[2], 1, len);
if (params[1])
if (params[3])
return stricmp(str1, str2);
else
return strcmp(str1, str2);
@ -893,6 +983,7 @@ AMX_NATIVE_INFO string_Natives[] =
{"equal", equal},
{"equali", equali},
{"format", format},
{"formatex", formatex},
{"format_args", format_args},
{"isdigit", is_digit},
{"isalnum", is_alnum},

View File

@ -27,8 +27,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,6,0,0
PRODUCTVERSION 1,6,0,0
FILEVERSION 1,7,1,0
PRODUCTVERSION 1,7,1,0
FILEFLAGSMASK 0x17L
#ifdef _DEBUG
FILEFLAGS 0x1L
@ -45,12 +45,12 @@ BEGIN
BEGIN
VALUE "Comments", "AMX Mod X"
VALUE "FileDescription", "AMX Mod X"
VALUE "FileVersion", "1.60"
VALUE "FileVersion", "1.71"
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.60"
VALUE "ProductVersion", "1.71"
END
END
BLOCK "VarFileInfo"

Binary file not shown.

View File

@ -1,7 +1,7 @@
#ifndef _AMXXSC_INCLUDE_H
#define _AMXXSC_INCLUDE_H
#define VERSION_STRING "1.60-300"
#define VERSION_STRING "1.70-300"
#define VERSION 03000
#define MAGIC_HEADER 0x414D5842
#define MAGIC_HEADER2 0x414D5858

View File

@ -4,6 +4,7 @@
Version="7.10"
Name="libpc300"
ProjectGUID="{19B72687-080B-437A-917A-12AEB0031635}"
RootNamespace="libpc300"
Keyword="Win32Proj">
<Platforms>
<Platform
@ -367,6 +368,12 @@
<File
RelativePath=".\libpawnc.rc">
</File>
<File
RelativePath=".\sc5.scp">
</File>
<File
RelativePath=".\sc7.scp">
</File>
</Filter>
</Files>
<Globals>

View File

@ -62,7 +62,7 @@
#endif
#include "sc.h"
#define VERSION_STR "3.0.3367"
#define VERSION_STR "3.0.3367-amxx"
#define VERSION_INT 0x300
static void resetglobals(void);
@ -531,6 +531,7 @@ int pc_compile(int argc, char *argv[])
delete_symbols(&glbtab,0,TRUE,FALSE);
#if !defined NO_DEFINE
delete_substtable();
insert_subst("__DATE__", "\"" __DATE__ "\"", 8);
#endif
resetglobals();
sc_ctrlchar=sc_ctrlchar_org;
@ -545,7 +546,6 @@ int pc_compile(int argc, char *argv[])
fline=skipinput; /* reset line number */
sc_reparse=FALSE; /* assume no extra passes */
sc_status=statFIRST; /* resetglobals() resets it to IDLE */
if (strlen(incfname)>0) {
if (strcmp(incfname,sDEF_PREFIX)==0) {
plungefile(incfname,FALSE,TRUE); /* parse "default.inc" */
@ -595,6 +595,7 @@ int pc_compile(int argc, char *argv[])
delete_symbols(&glbtab,0,TRUE,FALSE);
#if !defined NO_DEFINE
delete_substtable();
insert_subst("__DATE__", "\"" __DATE__ "\"", 8);
#endif
resetglobals();
sc_ctrlchar=sc_ctrlchar_org;
@ -1227,7 +1228,10 @@ static void setconfig(char *root)
GetModuleFileName(NULL,path,_MAX_PATH);
#elif defined LINUX || defined __FreeBSD__ || defined __OpenBSD__
/* see www.autopackage.org for the BinReloc module */
strncpy(path,SELFPATH,sizeof path);
ptr = SELFPATH;
if (!ptr)
ptr = root;
strncpy(path,ptr,sizeof path);
#else
if (root!=NULL)
strncpy(path,root,sizeof path); /* path + filename (hopefully) */
@ -3300,9 +3304,8 @@ static int newfunc(char *firstname,int firsttag,int fpublic,int fstatic,int stoc
static int argcompare(arginfo *a1,arginfo *a2)
{
int result,level,i;
int result=1,level,i;
result= strcmp(a1->name,a2->name)==0; /* name */
if (result)
result= a1->ident==a2->ident; /* type/class */
if (result)

View File

@ -1189,6 +1189,7 @@ static int command(void)
#endif
#if !defined NO_DEFINE
case tpDEFINE: {
int flag=0;
ret=CMD_DEFINE;
if (!SKIPPING) {
char *pattern,*substitution;
@ -1200,7 +1201,13 @@ static int command(void)
lptr++;
start=lptr; /* save starting point of the match pattern */
count=0;
while (*lptr>' ' && *lptr!='\0') {
while (*lptr!='\0') {
if (*lptr=='(')
flag=1;
if (flag && *lptr==')')
flag=0;
if (!flag && *lptr<=' ')
break;
litchar(&lptr,0); /* litchar() advances "lptr" and handles escape characters */
count++;
} /* while */

View File

@ -375,7 +375,13 @@ static int skim(int *opstr,void (*testfunc)(int),int dropval,int endval,
droplab=getlabel();
} /* if */
dropout(lvalue,testfunc,droplab,lval);
if (!lvalue && sc_intest && (lval->ident==iARRAY || lval->ident==iREFARRAY)) {
error(33, lval->sym ? (lval->sym->name ? lval->sym->name : "-unknown") : "-unknown-"); /* array was not indexed in an expression */
}
} else if (hits) { /* no (more) identical operators */
if (!lvalue && sc_intest && (lval->ident==iARRAY || lval->ident==iREFARRAY)) {
error(33, lval->sym ? (lval->sym->name ? lval->sym->name : "-unknown") : "-unknown-"); /* array was not indexed in an expression */
}
dropout(lvalue,testfunc,droplab,lval); /* found at least one operator! */
ldconst(endval,sPRI);
jumplabel(endlab=getlabel());
@ -1011,10 +1017,10 @@ static int hier13(value *lval)
array1= (lval->ident==iARRAY || lval->ident==iREFARRAY);
array2= (lval2.ident==iARRAY || lval2.ident==iREFARRAY);
if (array1 && !array2) {
char *ptr=(lval->sym->name!=NULL) ? lval->sym->name : "-unknown-";
char *ptr=(lval->sym!=NULL && lval->sym->name!=NULL) ? lval->sym->name : "-unknown-";
error(33,ptr); /* array must be indexed */
} else if (!array1 && array2) {
char *ptr=(lval2.sym->name!=NULL) ? lval2.sym->name : "-unknown-";
char *ptr=(lval2.sym!=NULL && lval2.sym->name!=NULL) ? lval2.sym->name : "-unknown-";
error(33,ptr); /* array must be indexed */
} /* if */
/* ??? if both are arrays, should check dimensions */
@ -1593,7 +1599,7 @@ restart:
error(76); /* invalid function call, or syntax error */
} /* if */
return FALSE;
} /* if */
}
return lvalue;
}
@ -1896,7 +1902,7 @@ static int nesting=0;
if (matchtoken('_')) {
arglist[argpos]=ARG_IGNORED; /* flag argument as "present, but ignored" */
if (arg[argidx].ident==0 || arg[argidx].ident==iVARARGS) {
error(202); /* argument count mismatch */
error(88); /* argument count mismatch */
} else if (!arg[argidx].hasdefault) {
error(34,nargs+1); /* argument has no default value */
} /* if */
@ -1912,7 +1918,7 @@ static int nesting=0;
lvalue=hier14(&lval);
switch (arg[argidx].ident) {
case 0:
error(202); /* argument count mismatch */
error(88); /* argument count mismatch */
break;
case iVARARGS:
/* always pass by reference */
@ -1920,7 +1926,7 @@ static int nesting=0;
assert(lval.sym!=NULL);
if ((lval.sym->usage & uCONST)!=0 && (arg[argidx].usage & uCONST)==0) {
/* treat a "const" variable passed to a function with a non-const
* "variable argument list" as a constant here */
* "variable argument flist" as a constant here */
assert(lvalue);
rvalue(&lval); /* get value in PRI */
setheap_pri(); /* address of the value on the heap in PRI */
@ -2132,7 +2138,7 @@ static int nesting=0;
markexpr(sPARM,NULL,0); /* mark the end of a sub-expression */
nest_stkusage++;
} else {
error(202,argidx); /* argument count mismatch */
error(88,argidx); /* argument count mismatch */
} /* if */
if (arglist[argidx]==ARG_UNHANDLED)
nargs++;

View File

@ -125,7 +125,8 @@ static char *errmsg[] = {
/*084*/ "state conflict: one of the states is already assigned to another implementation (symbol \"%s\")\n",
/*085*/ "no states are defined for function \"%s\"\n",
/*086*/ "unknown automaton \"%s\"\n",
/*087*/ "unknown state \"%s\" for automaton \"%s\"\n"
/*087*/ "unknown state \"%s\" for automaton \"%s\"\n",
/*088*/ "number of arguments does not match definition\n"
#else
"\267pect\233\277k\210:\242\312bu\202fo\217\206\216\012",
"\201l\223\247s\203g\361\326\373\202(\254\355\201) c\350f\246\356w ea\273 \042c\342e\042\012",
@ -213,7 +214,8 @@ static char *errmsg[] = {
"\326\200\302flict: \201\200\300\266\200\326\325\274\212\222ad\223a\250gn\233\277 a\221\266\270i\357l\373\320\231\364",
"\376\326\325\204\200\323\233f\254\251\216\012",
"\217k\221w\346au\277\334\201\311",
"\217k\221w\346\326\200\216 f\254au\277\334\201\311"
"\217k\221w\346\326\200\216 f\254au\277\334\201\311",
"\374\270\300\265t\207do\325\241\334\273 \323i\213\012"
#endif
};

View File

@ -33,9 +33,12 @@ amx_freq_imessage 180
// Set in seconds how fast players can chat (chat-flood protection)
amx_flood_time 0.75
// Amount of reserved slots (for more details see comments in a plugin source)
// Amount of reserved slots, amx_hideslots must be 1 to use this cvar (for more details see comments in plugin source)
amx_reservation 0
// If you set this to 1, you can hide slots on your server
amx_hideslots 0
// Displaying of time remaining
// a - display white text on bottom
// b - use voice
@ -77,3 +80,8 @@ amx_client_languages 1
// 2 - All plugins are put in debug mode
// Note - debug mode will affect JIT performance
amx_debug 1
// Plugin MultiLingual Debug
// To debug a language put its 2 letter code between quotes ("en", "de", etc)
// "" means disabled
amx_mldebug ""

View File

@ -14,3 +14,26 @@ amxx_vault addons/amxmodx/data/vault.ini
; 2 - one logfile / map
; 3 - HL Logs
amxx_logging 1
; Binary logging level
; add these up to get what you want
; these only work with bin logging binaries
; 1 - default
; 2 - log internal string sets/gets
; 4 - log internal formats
; 8 - log all native params
; 16 - log internal function calls (only in debug mode)
; 32 - log line number accesses (only in debug mode)
bin_logging 49
; Maximum binary log size, in megs
max_binlog_size 20
; Plugin optimization flags - add these up to get what you want
; lowering these may stop crashes on very old CPUs
; set 65536 to disable optimizer, NOT 0!
;-------------
; 1 - float arithmetic
; 2 - float comparisons
; 4 - float rounding
optimizer 7

View File

@ -33,9 +33,12 @@ amx_freq_imessage 180
// Set in seconds how fast players can chat (chat-flood protection)
amx_flood_time 0.75
// Amount of reserved slots (for more details see comments in a plugin source)
// Amount of reserved slots, amx_hideslots must be 1 to use this cvar (for more details see comments in plugin source)
amx_reservation 0
// If you set this to 1, you can hide slots on your server
amx_hideslots 0
// Displaying of time remaining
// a - display white text on bottom
// b - use voice
@ -93,3 +96,8 @@ amx_client_languages 1
// 2 - All plugins are put in debug mode
// Note - debug mode will affect JIT performance
amx_debug 1
// Plugin MultiLingual Debug
// To debug a language put its 2 letter code between quotes ("en", "de", etc)
// "" means disabled
amx_mldebug ""

View File

@ -16,3 +16,26 @@ csstats addons/amxmodx/data/csstats.dat
; 2 - one logfile / map
; 3 - HL Logs
amxx_logging 1
; Binary logging level
; add these up to get what you want
; these only work with bin logging binaries
; 1 - default
; 2 - log internal string sets/gets
; 4 - log internal formats
; 8 - log all native params
; 16 - log internal function calls (only in debug mode)
; 32 - log line number accesses (only in debug mode)
bin_logging 49
; Maximum binary log size, in megs
max_binlog_size 20
; Plugin optimization flags - add these up to get what you want
; lowering these may stop crashes on very old CPUs
; set 65536 to disable optimizer, NOT 0!
;-------------
; 1 - float arithmetic
; 2 - float comparisons
; 4 - float rounding
optimizer 7

View File

@ -17,3 +17,26 @@ amxx_logging 1
dodstats_score addons/amxmodx/data/dodstats.amxx
dodstats addons/amxmodx/data/dodstats.dat
; Binary logging level
; add these up to get what you want
; these only work with bin logging binaries
; 1 - default
; 2 - log internal string sets/gets
; 4 - log internal formats
; 8 - log all native params
; 16 - log internal function calls (only in debug mode)
; 32 - log line number accesses (only in debug mode)
bin_logging 49
; Maximum binary log size, in megs
max_binlog_size 20
; Plugin optimization flags - add these up to get what you want
; lowering these may stop crashes on very old CPUs
; set 65536 to disable optimizer, NOT 0!
;-------------
; 1 - float arithmetic
; 2 - float comparisons
; 4 - float rounding
optimizer 7

View File

@ -33,9 +33,12 @@ amx_freq_imessage 180
// Set in seconds how fast players can chat (chat-flood protection)
amx_flood_time 0.75
// Amount of reserved slots (for more details see comments in a plugin source)
// Amount of reserved slots, amx_hideslots must be 1 to use this cvar (for more details see comments in plugin source)
amx_reservation 0
// If you set this to 1, you can hide slots on your server
amx_hideslots 0
// Displaying of time remaining
// a - display white text on bottom
// b - use voice
@ -88,3 +91,8 @@ amx_idle_ignore_immunity 1 // Kick idle admins with immunity?
// Change this value to alter the frequency (in seconds) players can say /stuck to free themselves.
//amx_unstuck_frequency 4
// Plugin MultiLingual Debug
// To debug a language put its 2 letter code between quotes ("en", "de", etc)
// "" means disabled
amx_mldebug ""

View File

@ -16,3 +16,26 @@ tfcstats addons/amxmodx/data/tfcstats.dat
; 2 - one logfile / map
; 3 - HL Logs
amxx_logging 1
; Binary logging level
; add these up to get what you want
; these only work with bin logging binaries
; 1 - default
; 2 - log internal string sets/gets
; 4 - log internal formats
; 8 - log all native params
; 16 - log internal function calls (only in debug mode)
; 32 - log line number accesses (only in debug mode)
bin_logging 49
; Maximum binary log size, in megs
max_binlog_size 20
; Plugin optimization flags - add these up to get what you want
; lowering these may stop crashes on very old CPUs
; set 65536 to disable optimizer, NOT 0!
;-------------
; 1 - float arithmetic
; 2 - float comparisons
; 4 - float rounding
optimizer 7

View File

@ -16,3 +16,26 @@ tsstats addons/amxmodx/data/tsstats.dat
; 2 - one logfile / map
; 3 - HL Logs
amxx_logging 1
; Binary logging level
; add these up to get what you want
; these only work with bin logging binaries
; 1 - default
; 2 - log internal string sets/gets
; 4 - log internal formats
; 8 - log all native params
; 16 - log internal function calls (only in debug mode)
; 32 - log line number accesses (only in debug mode)
bin_logging 49
; Maximum binary log size, in megs
max_binlog_size 20
; Plugin optimization flags - add these up to get what you want
; lowering these may stop crashes on very old CPUs
; set 65536 to disable optimizer, NOT 0!
;-------------
; 1 - float arithmetic
; 2 - float comparisons
; 4 - float rounding
optimizer 7

3051
dlls/BB/amxxmodule.cpp Normal file

File diff suppressed because it is too large Load Diff

2239
dlls/BB/amxxmodule.h Normal file

File diff suppressed because it is too large Load Diff

144
dlls/BB/bb.cpp Normal file
View File

@ -0,0 +1,144 @@
#include "bb.h"
static cell AMX_NATIVE_CALL get_user_exp(AMX *amx,cell *params)
{
return amx_ftoc(GetUserExp(params[1]));
}
static cell AMX_NATIVE_CALL set_user_exp(AMX *amx,cell *params)
{
float Exp = amx_ctof(params[2]);
SetUserExp(params[1], Exp );
return 1;
}
static cell AMX_NATIVE_CALL get_user_points(AMX *amx,cell *params)
{
return amx_ftoc(GetUserPoints(params[1]));
}
static cell AMX_NATIVE_CALL set_user_points(AMX *amx,cell *params)
{
float Exp = amx_ctof(params[2]);
SetUserPoints(params[1], Exp );
return 1;
}
static cell AMX_NATIVE_CALL get_user_level(AMX *amx,cell *params)
{
return GetUserLevel(params[1]);
}
static cell AMX_NATIVE_CALL set_user_level(AMX *amx,cell *params)
{
if(GetUserLevel(params[0]) > params[2])
{
MF_LogError(amx,AMX_ERR_NATIVE,"Must set to a level higher than current one!");
return 0;
}
SetUserLevel(params[1], params[2] );
return 1;
}
static cell AMX_NATIVE_CALL get_user_speed(AMX *amx,cell *params)
{
return GetUserSpeed(params[1]);
}
static cell AMX_NATIVE_CALL set_user_speed(AMX *amx,cell *params)
{
SetUserSpeed(params[1], params[2] );
return 1;
}
static cell AMX_NATIVE_CALL get_user_hitpoints(AMX *amx,cell *params)
{
return GetUserHitPoints(params[1]);
}
static cell AMX_NATIVE_CALL set_user_hitpoints(AMX *amx,cell *params)
{
SetUserHitPoints(params[1], params[2] );
return 1;
}
static cell AMX_NATIVE_CALL get_user_skill(AMX *amx,cell *params)
{
return GetUserSkill(params[1]);
}
static cell AMX_NATIVE_CALL set_user_skill(AMX *amx,cell *params)
{
SetUserSkill(params[1], params[2] );
return 1;
}
static cell AMX_NATIVE_CALL send_progress_bar(AMX *amx,cell *params)
{
int len = 0;
float time = amx_ctof(params[3]);
SendProgressBar(params[1], MF_GetAmxString( amx, params[2], 0, &len ), time );
return 1;
}
static cell AMX_NATIVE_CALL send_show_objective(AMX *amx,cell *params)
{
int len = 0;
SendShowObjective(params[1], MF_GetAmxString( amx, params[2], 0, &len ) );
return 1;
}
static cell AMX_NATIVE_CALL send_show_message(AMX *amx,cell *params)
{
int len = 0;
float time = amx_ctof(params[2]);
SendShowMessage(params[1], time, MF_GetAmxString( amx, params[2], 0, &len ), MF_GetAmxString( amx, params[3], 0, &len ) );
return 1;
}
static cell AMX_NATIVE_CALL reset_user_hud(AMX *amx,cell *params)
{
UpdateBBHud( params[1] );
return 1;
}
static cell AMX_NATIVE_CALL is_user_zombie(AMX *amx,cell *params)
{
return IsUserZombie(params[1]);
}
AMX_NATIVE_INFO bb_Exports[] =
{
{"bb_is_user_zombie",is_user_zombie},
{"bb_reset_user_hud", reset_user_hud},
{"bb_show_message",send_show_message},
{"bb_show_objective", send_show_objective},
{"bb_show_progress_bar", send_progress_bar},
{"bb_get_user_skill",get_user_skill},
{"bb_set_user_skill", set_user_skill},
{"bb_get_user_hitpoints",get_user_hitpoints},
{"bb_set_user_hitpoints", set_user_hitpoints},
{"bb_get_user_speed",get_user_speed},
{"bb_set_user_speed", set_user_speed},
{"bb_get_user_exp",get_user_exp},
{"bb_set_user_exp", set_user_exp},
{"bb_get_user_points",get_user_points},
{"bb_set_user_points", set_user_points},
{"bb_get_user_level",get_user_level},
{"bb_set_user_level", set_user_level},
{ NULL, NULL }
};
void OnAmxxAttach()
{
MF_AddNatives(bb_Exports);
}

115
dlls/BB/bb.h Normal file
View File

@ -0,0 +1,115 @@
// prevent double include
#ifndef __BB_H__
#define __BB_H__
#include "pdata.h"
#include "bb_const.h"
void UpdateBBHud( long& target);
inline float GetUserExp( long& target)
{ return GetPData(target, BB_PDATA_EXP, 100.0); }
inline void SetUserExp( long& target, float& exp)
{ SetPData(target, BB_PDATA_EXP, exp); }
inline float GetUserPoints( long& target)
{ return GetPData(target, BB_PDATA_POINT, 100.0); }
inline void SetUserPoints( long& target, float& points)
{SetPData(target, BB_PDATA_POINT, points, true);}
inline long GetUserLevel(long& target)
{ return GetPData(target,BB_PDATA_LEVEL,100); }
inline void SetUserLevel(long& target, long& level)
{
long i;
float totalxp = 0.0;
for(i=1;i<=level;i++) {
totalxp += 150.0 + ((i-1) * 300.0);
}
SetUserExp( target, totalxp );
MESSAGE_BEGIN(MSG_ONE,120, NULL, MF_GetPlayerEdict( target) );
WRITE_COORD(0);
WRITE_BYTE(level);
WRITE_BYTE( GetUserPoints(target) );
MESSAGE_END();
MESSAGE_BEGIN(MSG_ALL,81, NULL, MF_GetPlayerEdict( target ));
WRITE_BYTE( target );
WRITE_SHORT( MF_GetPlayerFrags( target ) );
WRITE_SHORT( MF_GetPlayerDeaths( target ) );
WRITE_BYTE(level);
MESSAGE_END();
SetPData(target,BB_PDATA_LEVEL,level);
SetPData(target,BB_PDATA_LEVEL - 1,level);
}
inline long GetUserSpeed(long& target)
{ return GetPData(target,BB_PDATA_SPEED,100); }
inline void SetUserSpeed(long& target, long& speed)
{ SetPData(target,BB_PDATA_SPEED,speed, true);}
inline long GetUserHitPoints(long& target)
{ return GetPData(target,BB_PDATA_HITPOINTS,100); }
inline void SetUserHitPoints(long& target, long& hitpoints)
{ SetPData(target,BB_PDATA_HITPOINTS,hitpoints, true); }
inline long GetUserSkill(long& target)
{ return GetPData(target,BB_PDATA_SKILL,100); }
inline void SetUserSkill(long& target, long& skill )
{ SetPData(target,BB_PDATA_SKILL,skill,true); }
inline bool IsUserZombie(long& target)
{
return ( (MF_GetPlayerEdict( target ))->v.team == 2);
}
inline void SendProgressBar( long& target, char* message, float& time)
{
MESSAGE_BEGIN(MSG_ONE, 122, NULL, MF_GetPlayerEdict( target));
WRITE_STRING(message);
WRITE_COORD(time);
MESSAGE_END();
}
inline void SendShowObjective( long& target, char* message)
{
MESSAGE_BEGIN(MSG_ONE, 122, NULL, MF_GetPlayerEdict( target));
WRITE_COORD(-1);
WRITE_BYTE(144);
WRITE_STRING(message);
MESSAGE_END();
}
inline void SendShowMessage( long& target, float& duration, char* message, char* message2)
{
MESSAGE_BEGIN(MSG_ONE, 122, NULL, MF_GetPlayerEdict( target));
WRITE_COORD(duration);
WRITE_BYTE(32);
WRITE_STRING(message);
WRITE_STRING(message2);
MESSAGE_END();
}
void UpdateBBHud( long& target)
{
MESSAGE_BEGIN( MSG_ONE, 113, NULL, MF_GetPlayerEdict( target) );
WRITE_BYTE( GetUserHitPoints(target) );
WRITE_BYTE( GetUserSpeed(target) );
WRITE_BYTE( GetUserSkill(target) );
WRITE_BYTE( GetUserPoints(target) );
MESSAGE_END();
}
#endif

47
dlls/BB/bb.inc Normal file
View File

@ -0,0 +1,47 @@
/* BrainBread Fun Module
*
* (c) 2005, XxAvalanchexX (converted to module by Rukia)
*
* This file is provided as is (no warranties).
*/
#if defined _brainbread_included
#endinput
#endif
#define _brainbread_included
#pragma library BBFUN
#include <bb_const>
#include <bb_stocks>
native bb_is_user_zombie(id)
native bb_reset_user_hud(id)
native bb_show_message(id,Float:time = -1,message[],message2[] = "")
native bb_show_objective(id,message[] = "")
native bb_show_progress_bar(id,message[],time = 10)
native bb_get_user_skill(id)
native bb_set_user_skill(id,skill)
stock bb_add_user_skill(id,skill) bb_set_user_skill(id,bb_get_user_skill(id) + skill)
native Float:bb_get_user_exp(id)
native bb_set_user_exp(id,Float:exp)
stock bb_add_user_exp(id,Float:exp) bb_set_user_exp(id,bb_get_user_exp(id) + exp)
native Float:bb_get_user_points(id)
native bb_set_user_points(id,Float:points)
stock bb_add_user_points(id,Float:points) bb_set_user_ponts(id,bb_get_user_points(id) + points)
native bb_get_user_level(id)
native bb_set_user_level(id,level)
stock bb_add_user_level(id,level) bb_set_user_level(id,bb_get_user_level(id) + level)
native bb_get_user_speed(id)
native bb_set_user_speed(id,speed)
stock bb_add_user_speed(id,speed) bb_set_user_speed(id,bb_get_user_speed(id) + speed)
native bb_get_user_hitpoints(id)
native bb_set_user_hitpoints(id,hitpoints)
stock bb_add_user_hitpoints(id,hitpoints) bb_set_user_hitpoints(id,bb_get_user_hitpoints(id) + hitpoints)

BIN
dlls/BB/bb.ncb Normal file

Binary file not shown.

21
dlls/BB/bb.sln Normal file
View File

@ -0,0 +1,21 @@
Microsoft Visual Studio Solution File, Format Version 8.00
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bb", "bb.vcproj", "{29798873-02F2-4075-AFE7-58CE8F9B5124}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfiguration) = preSolution
Debug = Debug
Release = Release
EndGlobalSection
GlobalSection(ProjectConfiguration) = postSolution
{29798873-02F2-4075-AFE7-58CE8F9B5124}.Debug.ActiveCfg = Debug|Win32
{29798873-02F2-4075-AFE7-58CE8F9B5124}.Debug.Build.0 = Debug|Win32
{29798873-02F2-4075-AFE7-58CE8F9B5124}.Release.ActiveCfg = Release|Win32
{29798873-02F2-4075-AFE7-58CE8F9B5124}.Release.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
EndGlobalSection
GlobalSection(ExtensibilityAddIns) = postSolution
EndGlobalSection
EndGlobal

180
dlls/BB/bb.vcproj Normal file
View File

@ -0,0 +1,180 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="bb"
ProjectGUID="{29798873-02F2-4075-AFE7-58CE8F9B5124}"
SccProjectName=""
SccLocalPath="">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Release|Win32"
OutputDirectory=".\Release"
IntermediateDirectory=".\Release"
ConfigurationType="2"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;bb_EXPORTS"
StringPooling="TRUE"
RuntimeLibrary="4"
UsePrecompiledHeader="2"
PrecompiledHeaderFile=".\Release/bb.pch"
AssemblerListingLocation=".\Release/"
ObjectFile=".\Release/"
ProgramDataBaseFileName=".\Release/"
BrowseInformation="1"
WarningLevel="3"
SuppressStartupBanner="TRUE"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile=".\Release/bb_amxx.dll"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
ModuleDefinitionFile=""
ProgramDatabaseFile=".\Release/bb.pdb"
ImportLibrary=".\Release/bb.lib"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="NDEBUG"
MkTypLibCompatible="TRUE"
SuppressStartupBanner="TRUE"
TargetEnvironment="1"
TypeLibraryName=".\Release/bb.tlb"
HeaderFileName=""/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1053"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\Debug"
IntermediateDirectory=".\Debug"
ConfigurationType="2"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;bb_EXPORTS"
BasicRuntimeChecks="3"
RuntimeLibrary="5"
UsePrecompiledHeader="2"
PrecompiledHeaderFile=".\Debug/bb.pch"
AssemblerListingLocation=".\Debug/"
ObjectFile=".\Debug/"
ProgramDataBaseFileName=".\Debug/"
BrowseInformation="1"
WarningLevel="3"
SuppressStartupBanner="TRUE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="Debug/bb_amxx.dll"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
ModuleDefinitionFile=""
GenerateDebugInformation="TRUE"
ProgramDatabaseFile=".\Debug/bb_debug.pdb"
ImportLibrary=".\Debug/bb_debug.lib"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="_DEBUG"
MkTypLibCompatible="TRUE"
SuppressStartupBanner="TRUE"
TargetEnvironment="1"
TypeLibraryName=".\Debug/bb.tlb"
HeaderFileName=""/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1053"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
<File
RelativePath=".\amxxmodule.cpp">
</File>
<File
RelativePath=".\bb.cpp">
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl">
<File
RelativePath=".\amxxmodule.h">
</File>
<File
RelativePath=".\bb.h">
</File>
<File
RelativePath=".\bb_const.h">
</File>
<File
RelativePath=".\moduleconfig.h">
</File>
<File
RelativePath=".\pdata.h">
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe">
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

12
dlls/BB/bb_const.h Normal file
View File

@ -0,0 +1,12 @@
// prevent double include
#ifndef __BB_CONST__
#define __BB_CONST__
#define BB_PDATA_LEVEL 505
#define BB_PDATA_EXP 4
#define BB_PDATA_POINT 432
#define BB_PDATA_SPEED 501
#define BB_PDATA_HITPOINTS 502
#define BB_PDATA_SKILL 503
#endif

26
dlls/BB/bb_const.inc Normal file
View File

@ -0,0 +1,26 @@
/* BrainBread Fun Module Constants
*
* (c) 2005, XxAvalanchexX (converted to module by Rukia)
*
* This file is provided as is (no warranties).
*/
#if defined _brainbread_const_included
#endinput
#endif
#define _brainbread_const_included
#define SPRAY_BSPRITZ 1
#define SPRAY_BGUSH 2
#define SPRAY_SMOKEPUFF 4
#define SPRAY_EXPLOSION 5
#define DOT_GREEN 1
#define DOT_RED 2
#define DOT_WHITE 3
#define DOT_LTBLUE 4
#define DOT_BLUE 5
#define DOT_ORANGE 6
#define DOT_FLYELLOW 7
#define DOT_FLGREEN 8

112
dlls/BB/bb_stocks.inc Normal file
View File

@ -0,0 +1,112 @@
/* BrainBread Fun Module Stocks
*
* (c) 2005, XxAvalanchexX (converted to module by Rukia)
*
* This file is provided as is (no warranties).
*/
#if defined _brainbread_stocks_included
#endinput
#endif
#define _brainbread_stocks_included
/* Used to create a spray */
stock bb_spray(type,origin[3]) {
/* type: type of spray, see below */
/* origin: origin of where spray comes from */
/* TYPES:
SPRAY_BSPRITZ (1) = Blood spritz
SPRAY_BGUSH (2) = Blood gush
SPRAY_SMOKEPUFF (4) = Smoke puffs
SPRAY_EXPLOSION (5) = Firey explosion */
message_begin(MSG_PVS,118,origin,0);
write_byte(type);
write_coord(origin[0]);
write_coord(origin[1]);
write_coord(origin[2]);
write_coord(random_num(-1,1));
write_coord(random_num(-1,1));
write_coord(random_num(-1,1));
write_coord(random_num(-1,1));
write_coord(random_num(-1,1));
write_coord(random_num(-1,1));
message_end();
return 1;
}
/* Used to create a spray, with more parameters */
stock bb_spray_adv(type,origin[3],size[3],dir[3]) {
/* type: type of spray, see below */
/* origin: origin of where spray comes from */
/* size: size of spray, in XYZ format (I think), use a small number like -1 to 1 */
/* dir: direction of spray, in XYZ format (I think), use a small number like -1 to 1 */
/* TYPES:
SPRAY_BSPRITZ (1) = Blood spritz
SPRAY_BGUSH (2) = Blood gush
SPRAY_SMOKEPUFF (4) = Smoke puffs
SPRAY_EXPLOSION (5) = Firey explosion */
message_begin(MSG_PVS,118,origin,0);
write_byte(type);
write_coord(origin[0]);
write_coord(origin[1]);
write_coord(origin[2]);
write_coord(size[0]);
write_coord(size[1]);
write_coord(size[2]);
write_coord(dir[0]);
write_coord(dir[1]);
write_coord(dir[2]);
message_end();
return 1;
}
/* Used to set dots on the radar */
stock bb_radar(id,dot_id,dot_origin[3],dot_status,dot_type) {
/* dot_id: unique ID for this dot, use same ID to modify the same dot */
/* dot_origin: the origin of where to place this dot */
/* dot_status: 0 to remove the dot, 1 to add or modify the dot */
/* dot_type: the type of dot, see below */
/* dot_origin and dot_type need not be set accurately when removing the dot */
/* TYPES:
DOT_GREEN (1) = Green Dot, used to mark teammates
DOT_RED (2) = Red Dot, used to mark enemies for zombies
DOT_WHITE (3) = White Dot, used to mark mission zones
DOT_LTBLUE (4) = Light Blue Dot, not used for BrainBread
DOT_BLUE (5) = Blue Dot, used to mark the BlackHawk
DOT_ORANGE (6) = Orange Dot, not used for BrainBread
DOT_FLYELLOW (7) = Flashing Yellow Dot, used to mark the Case or Fred
DOT_FLGREEN (8) = Flashing Green Dot, not used for BrainBread,
it stops flashing and turns to white after 3 seconds */
message_begin(MSG_ONE,93,{0,0,0},id);
write_short(dot_id);
write_byte(1);
write_coord(dot_origin[0]);
write_coord(dot_origin[1]);
write_coord(dot_origin[2]);
write_byte(1);
message_end();
message_begin(MSG_ONE,93,{0,0,0},id);
write_short(dot_id);
write_byte((dot_status > 0) ? 2 : 0);
if(dot_status > 0) {
write_byte(dot_type);
}
message_end();
return 1;
}

462
dlls/BB/moduleconfig.h Normal file
View File

@ -0,0 +1,462 @@
// Configuration
#ifndef __MODULECONFIG_H__
#define __MODULECONFIG_H__
// Module info
#define MODULE_NAME "BBFUN"
#define MODULE_VERSION "1.65"
#define MODULE_AUTHOR "Avalanche"
#define MODULE_URL "www.rcrclansite.com"
#define MODULE_LOGTAG "BB"
// If you want the module not to be reloaded on mapchange, remove / comment out the next line
#define MODULE_RELOAD_ON_MAPCHANGE
#ifdef __DATE__
#define MODULE_DATE __DATE__
#else // __DATE__
#define MODULE_DATE "Today"
#endif // __DATE__
// metamod plugin?
#define USE_METAMOD
// - 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
// #define FN_AMXX_DETACH OnAmxxDetach
// All plugins loaded
// Do forward functions init here (MF_RegisterForward)
// #define FN_AMXX_PLUGINSLOADED OnPluginsLoaded
/**** METAMOD ****/
// If your module doesn't use metamod, you may close the file now :)
#ifdef USE_METAMOD
// ----
// Hook Functions
// Uncomment these to be called
// You can also change the function name
// - Metamod init functions
// Also consider using FN_AMXX_*
// Meta query
//#define FN_META_QUERY OnMetaQuery
// Meta attach
//#define FN_META_ATTACH OnMetaAttach
// Meta detach
//#define FN_META_DETACH OnMetaDetach
// (wd) are Will Day's notes
// - GetEntityAPI2 functions
// #define FN_GameDLLInit GameDLLInit /* pfnGameInit() */
// #define FN_DispatchSpawn DispatchSpawn /* pfnSpawn() */
// #define FN_DispatchThink DispatchThink /* pfnThink() */
// #define FN_DispatchUse DispatchUse /* pfnUse() */
// #define FN_DispatchTouch DispatchTouch /* pfnTouch() */
// #define FN_DispatchBlocked DispatchBlocked /* pfnBlocked() */
// #define FN_DispatchKeyValue DispatchKeyValue /* pfnKeyValue() */
// #define FN_DispatchSave DispatchSave /* pfnSave() */
// #define FN_DispatchRestore DispatchRestore /* pfnRestore() */
// #define FN_DispatchObjectCollsionBox DispatchObjectCollsionBox /* pfnSetAbsBox() */
// #define FN_SaveWriteFields SaveWriteFields /* pfnSaveWriteFields() */
// #define FN_SaveReadFields SaveReadFields /* pfnSaveReadFields() */
// #define FN_SaveGlobalState SaveGlobalState /* pfnSaveGlobalState() */
// #define FN_RestoreGlobalState RestoreGlobalState /* pfnRestoreGlobalState() */
// #define FN_ResetGlobalState ResetGlobalState /* pfnResetGlobalState() */
// #define FN_ClientConnect ClientConnect /* pfnClientConnect() (wd) Client has connected */
// #define FN_ClientDisconnect ClientDisconnect /* pfnClientDisconnect() (wd) Player has left the game */
// #define FN_ClientKill ClientKill /* pfnClientKill() (wd) Player has typed "kill" */
// #define FN_ClientPutInServer ClientPutInServer /* pfnClientPutInServer() (wd) Client is entering the game */
// #define FN_ClientCommand ClientCommand /* pfnClientCommand() (wd) Player has sent a command (typed or from a bind) */
// #define FN_ClientUserInfoChanged ClientUserInfoChanged /* pfnClientUserInfoChanged() (wd) Client has updated their setinfo structure */
// #define FN_ServerActivate ServerActivate /* pfnServerActivate() (wd) Server is starting a new map */
// #define FN_ServerDeactivate ServerDeactivate /* pfnServerDeactivate() (wd) Server is leaving the map (shutdown or changelevel); SDK2 */
// #define FN_PlayerPreThink PlayerPreThink /* pfnPlayerPreThink() */
// #define FN_PlayerPostThink PlayerPostThink /* pfnPlayerPostThink() */
// #define FN_StartFrame StartFrame /* pfnStartFrame() */
// #define FN_ParmsNewLevel ParmsNewLevel /* pfnParmsNewLevel() */
// #define FN_ParmsChangeLevel ParmsChangeLevel /* pfnParmsChangeLevel() */
// #define FN_GetGameDescription GetGameDescription /* pfnGetGameDescription() Returns string describing current .dll. E.g. "TeamFotrress 2" "Half-Life" */
// #define FN_PlayerCustomization PlayerCustomization /* pfnPlayerCustomization() Notifies .dll of new customization for player. */
// #define FN_SpectatorConnect SpectatorConnect /* pfnSpectatorConnect() Called when spectator joins server */
// #define FN_SpectatorDisconnect SpectatorDisconnect /* pfnSpectatorDisconnect() Called when spectator leaves the server */
// #define FN_SpectatorThink SpectatorThink /* pfnSpectatorThink() Called when spectator sends a command packet (usercmd_t) */
// #define FN_Sys_Error Sys_Error /* pfnSys_Error() Notify game .dll that engine is going to shut down. Allows mod authors to set a breakpoint. SDK2 */
// #define FN_PM_Move PM_Move /* pfnPM_Move() (wd) SDK2 */
// #define FN_PM_Init PM_Init /* pfnPM_Init() Server version of player movement initialization; (wd) SDK2 */
// #define FN_PM_FindTextureType PM_FindTextureType /* pfnPM_FindTextureType() (wd) SDK2 */
// #define FN_SetupVisibility SetupVisibility /* pfnSetupVisibility() Set up PVS and PAS for networking for this client; (wd) SDK2 */
// #define FN_UpdateClientData UpdateClientData /* pfnUpdateClientData() Set up data sent only to specific client; (wd) SDK2 */
// #define FN_AddToFullPack AddToFullPack /* pfnAddToFullPack() (wd) SDK2 */
// #define FN_CreateBaseline CreateBaseline /* pfnCreateBaseline() Tweak entity baseline for network encoding allows setup of player baselines too.; (wd) SDK2 */
// #define FN_RegisterEncoders RegisterEncoders /* pfnRegisterEncoders() Callbacks for network encoding; (wd) SDK2 */
// #define FN_GetWeaponData GetWeaponData /* pfnGetWeaponData() (wd) SDK2 */
// #define FN_CmdStart CmdStart /* pfnCmdStart() (wd) SDK2 */
// #define FN_CmdEnd CmdEnd /* pfnCmdEnd() (wd) SDK2 */
// #define FN_ConnectionlessPacket ConnectionlessPacket /* pfnConnectionlessPacket() (wd) SDK2 */
// #define FN_GetHullBounds GetHullBounds /* pfnGetHullBounds() (wd) SDK2 */
// #define FN_CreateInstancedBaselines CreateInstancedBaselines /* pfnCreateInstancedBaselines() (wd) SDK2 */
// #define FN_InconsistentFile InconsistentFile /* pfnInconsistentFile() (wd) SDK2 */
// #define FN_AllowLagCompensation AllowLagCompensation /* pfnAllowLagCompensation() (wd) SDK2 */
// - GetEntityAPI2_Post functions
// #define FN_GameDLLInit_Post GameDLLInit_Post
// #define FN_DispatchSpawn_Post DispatchSpawn_Post
// #define FN_DispatchThink_Post DispatchThink_Post
// #define FN_DispatchUse_Post DispatchUse_Post
// #define FN_DispatchTouch_Post DispatchTouch_Post
// #define FN_DispatchBlocked_Post DispatchBlocked_Post
// #define FN_DispatchKeyValue_Post DispatchKeyValue_Post
// #define FN_DispatchSave_Post DispatchSave_Post
// #define FN_DispatchRestore_Post DispatchRestore_Post
// #define FN_DispatchObjectCollsionBox_Post DispatchObjectCollsionBox_Post
// #define FN_SaveWriteFields_Post SaveWriteFields_Post
// #define FN_SaveReadFields_Post SaveReadFields_Post
// #define FN_SaveGlobalState_Post SaveGlobalState_Post
// #define FN_RestoreGlobalState_Post RestoreGlobalState_Post
// #define FN_ResetGlobalState_Post ResetGlobalState_Post
// #define FN_ClientConnect_Post ClientConnect_Post
// #define FN_ClientDisconnect_Post ClientDisconnect_Post
// #define FN_ClientKill_Post ClientKill_Post
// #define FN_ClientPutInServer_Post ClientPutInServer_Post
// #define FN_ClientCommand_Post ClientCommand_Post
// #define FN_ClientUserInfoChanged_Post ClientUserInfoChanged_Post
// #define FN_ServerActivate_Post ServerActivate_Post
// #define FN_ServerDeactivate_Post ServerDeactivate_Post
// #define FN_PlayerPreThink_Post PlayerPreThink_Post
// #define FN_PlayerPostThink_Post PlayerPostThink_Post
// #define FN_StartFrame_Post StartFrame_Post
// #define FN_ParmsNewLevel_Post ParmsNewLevel_Post
// #define FN_ParmsChangeLevel_Post ParmsChangeLevel_Post
// #define FN_GetGameDescription_Post GetGameDescription_Post
// #define FN_PlayerCustomization_Post PlayerCustomization_Post
// #define FN_SpectatorConnect_Post SpectatorConnect_Post
// #define FN_SpectatorDisconnect_Post SpectatorDisconnect_Post
// #define FN_SpectatorThink_Post SpectatorThink_Post
// #define FN_Sys_Error_Post Sys_Error_Post
// #define FN_PM_Move_Post PM_Move_Post
// #define FN_PM_Init_Post PM_Init_Post
// #define FN_PM_FindTextureType_Post PM_FindTextureType_Post
// #define FN_SetupVisibility_Post SetupVisibility_Post
// #define FN_UpdateClientData_Post UpdateClientData_Post
// #define FN_AddToFullPack_Post AddToFullPack_Post
// #define FN_CreateBaseline_Post CreateBaseline_Post
// #define FN_RegisterEncoders_Post RegisterEncoders_Post
// #define FN_GetWeaponData_Post GetWeaponData_Post
// #define FN_CmdStart_Post CmdStart_Post
// #define FN_CmdEnd_Post CmdEnd_Post
// #define FN_ConnectionlessPacket_Post ConnectionlessPacket_Post
// #define FN_GetHullBounds_Post GetHullBounds_Post
// #define FN_CreateInstancedBaselines_Post CreateInstancedBaselines_Post
// #define FN_InconsistentFile_Post InconsistentFile_Post
// #define FN_AllowLagCompensation_Post AllowLagCompensation_Post
// - GetEngineAPI functions
// #define FN_PrecacheModel PrecacheModel
// #define FN_PrecacheSound PrecacheSound
// #define FN_SetModel SetModel
// #define FN_ModelIndex ModelIndex
// #define FN_ModelFrames ModelFrames
// #define FN_SetSize SetSize
// #define FN_ChangeLevel ChangeLevel
// #define FN_GetSpawnParms GetSpawnParms
// #define FN_SaveSpawnParms SaveSpawnParms
// #define FN_VecToYaw VecToYaw
// #define FN_VecToAngles VecToAngles
// #define FN_MoveToOrigin MoveToOrigin
// #define FN_ChangeYaw ChangeYaw
// #define FN_ChangePitch ChangePitch
// #define FN_FindEntityByString FindEntityByString
// #define FN_GetEntityIllum GetEntityIllum
// #define FN_FindEntityInSphere FindEntityInSphere
// #define FN_FindClientInPVS FindClientInPVS
// #define FN_EntitiesInPVS EntitiesInPVS
// #define FN_MakeVectors MakeVectors
// #define FN_AngleVectors AngleVectors
// #define FN_CreateEntity CreateEntity
// #define FN_RemoveEntity RemoveEntity
// #define FN_CreateNamedEntity CreateNamedEntity
// #define FN_MakeStatic MakeStatic
// #define FN_EntIsOnFloor EntIsOnFloor
// #define FN_DropToFloor DropToFloor
// #define FN_WalkMove WalkMove
// #define FN_SetOrigin SetOrigin
// #define FN_EmitSound EmitSound
// #define FN_EmitAmbientSound EmitAmbientSound
// #define FN_TraceLine TraceLine
// #define FN_TraceToss TraceToss
// #define FN_TraceMonsterHull TraceMonsterHull
// #define FN_TraceHull TraceHull
// #define FN_TraceModel TraceModel
// #define FN_TraceTexture TraceTexture
// #define FN_TraceSphere TraceSphere
// #define FN_GetAimVector GetAimVector
// #define FN_ServerCommand ServerCommand
// #define FN_ServerExecute ServerExecute
// #define FN_engClientCommand engClientCommand
// #define FN_ParticleEffect ParticleEffect
// #define FN_LightStyle LightStyle
// #define FN_DecalIndex DecalIndex
// #define FN_PointContents PointContents
// #define FN_MessageBegin MessageBegin
// #define FN_MessageEnd MessageEnd
// #define FN_WriteByte WriteByte
// #define FN_WriteChar WriteChar
// #define FN_WriteShort WriteShort
// #define FN_WriteLong WriteLong
// #define FN_WriteAngle WriteAngle
// #define FN_WriteCoord WriteCoord
// #define FN_WriteString WriteString
// #define FN_WriteEntity WriteEntity
// #define FN_CVarRegister CVarRegister
// #define FN_CVarGetFloat CVarGetFloat
// #define FN_CVarGetString CVarGetString
// #define FN_CVarSetFloat CVarSetFloat
// #define FN_CVarSetString CVarSetString
// #define FN_AlertMessage AlertMessage
// #define FN_EngineFprintf EngineFprintf
// #define FN_PvAllocEntPrivateData PvAllocEntPrivateData
// #define FN_PvEntPrivateData PvEntPrivateData
// #define FN_FreeEntPrivateData FreeEntPrivateData
// #define FN_SzFromIndex SzFromIndex
// #define FN_AllocString AllocString
// #define FN_GetVarsOfEnt GetVarsOfEnt
// #define FN_PEntityOfEntOffset PEntityOfEntOffset
// #define FN_EntOffsetOfPEntity EntOffsetOfPEntity
// #define FN_IndexOfEdict IndexOfEdict
// #define FN_PEntityOfEntIndex PEntityOfEntIndex
// #define FN_FindEntityByVars FindEntityByVars
// #define FN_GetModelPtr GetModelPtr
// #define FN_RegUserMsg RegUserMsg
// #define FN_AnimationAutomove AnimationAutomove
// #define FN_GetBonePosition GetBonePosition
// #define FN_FunctionFromName FunctionFromName
// #define FN_NameForFunction NameForFunction
// #define FN_ClientPrintf ClientPrintf
// #define FN_ServerPrint ServerPrint
// #define FN_Cmd_Args Cmd_Args
// #define FN_Cmd_Argv Cmd_Argv
// #define FN_Cmd_Argc Cmd_Argc
// #define FN_GetAttachment GetAttachment
// #define FN_CRC32_Init CRC32_Init
// #define FN_CRC32_ProcessBuffer CRC32_ProcessBuffer
// #define FN_CRC32_ProcessByte CRC32_ProcessByte
// #define FN_CRC32_Final CRC32_Final
// #define FN_RandomLong RandomLong
// #define FN_RandomFloat RandomFloat
// #define FN_SetView SetView
// #define FN_Time Time
// #define FN_CrosshairAngle CrosshairAngle
// #define FN_LoadFileForMe LoadFileForMe
// #define FN_FreeFile FreeFile
// #define FN_EndSection EndSection
// #define FN_CompareFileTime CompareFileTime
// #define FN_GetGameDir GetGameDir
// #define FN_Cvar_RegisterVariable Cvar_RegisterVariable
// #define FN_FadeClientVolume FadeClientVolume
// #define FN_SetClientMaxspeed SetClientMaxspeed
// #define FN_CreateFakeClient CreateFakeClient
// #define FN_RunPlayerMove RunPlayerMove
// #define FN_NumberOfEntities NumberOfEntities
// #define FN_GetInfoKeyBuffer GetInfoKeyBuffer
// #define FN_InfoKeyValue InfoKeyValue
// #define FN_SetKeyValue SetKeyValue
// #define FN_SetClientKeyValue SetClientKeyValue
// #define FN_IsMapValid IsMapValid
// #define FN_StaticDecal StaticDecal
// #define FN_PrecacheGeneric PrecacheGeneric
// #define FN_GetPlayerUserId GetPlayerUserId
// #define FN_BuildSoundMsg BuildSoundMsg
// #define FN_IsDedicatedServer IsDedicatedServer
// #define FN_CVarGetPointer CVarGetPointer
// #define FN_GetPlayerWONId GetPlayerWONId
// #define FN_Info_RemoveKey Info_RemoveKey
// #define FN_GetPhysicsKeyValue GetPhysicsKeyValue
// #define FN_SetPhysicsKeyValue SetPhysicsKeyValue
// #define FN_GetPhysicsInfoString GetPhysicsInfoString
// #define FN_PrecacheEvent PrecacheEvent
// #define FN_PlaybackEvent PlaybackEvent
// #define FN_SetFatPVS SetFatPVS
// #define FN_SetFatPAS SetFatPAS
// #define FN_CheckVisibility CheckVisibility
// #define FN_DeltaSetField DeltaSetField
// #define FN_DeltaUnsetField DeltaUnsetField
// #define FN_DeltaAddEncoder DeltaAddEncoder
// #define FN_GetCurrentPlayer GetCurrentPlayer
// #define FN_CanSkipPlayer CanSkipPlayer
// #define FN_DeltaFindField DeltaFindField
// #define FN_DeltaSetFieldByIndex DeltaSetFieldByIndex
// #define FN_DeltaUnsetFieldByIndex DeltaUnsetFieldByIndex
// #define FN_SetGroupMask SetGroupMask
// #define FN_engCreateInstancedBaseline engCreateInstancedBaseline
// #define FN_Cvar_DirectSet Cvar_DirectSet
// #define FN_ForceUnmodified ForceUnmodified
// #define FN_GetPlayerStats GetPlayerStats
// #define FN_AddServerCommand AddServerCommand
// #define FN_Voice_GetClientListening Voice_GetClientListening
// #define FN_Voice_SetClientListening Voice_SetClientListening
// #define FN_GetPlayerAuthId GetPlayerAuthId
// - GetEngineAPI_Post functions
// #define FN_PrecacheModel_Post PrecacheModel_Post
// #define FN_PrecacheSound_Post PrecacheSound_Post
// #define FN_SetModel_Post SetModel_Post
// #define FN_ModelIndex_Post ModelIndex_Post
// #define FN_ModelFrames_Post ModelFrames_Post
// #define FN_SetSize_Post SetSize_Post
// #define FN_ChangeLevel_Post ChangeLevel_Post
// #define FN_GetSpawnParms_Post GetSpawnParms_Post
// #define FN_SaveSpawnParms_Post SaveSpawnParms_Post
// #define FN_VecToYaw_Post VecToYaw_Post
// #define FN_VecToAngles_Post VecToAngles_Post
// #define FN_MoveToOrigin_Post MoveToOrigin_Post
// #define FN_ChangeYaw_Post ChangeYaw_Post
// #define FN_ChangePitch_Post ChangePitch_Post
// #define FN_FindEntityByString_Post FindEntityByString_Post
// #define FN_GetEntityIllum_Post GetEntityIllum_Post
// #define FN_FindEntityInSphere_Post FindEntityInSphere_Post
// #define FN_FindClientInPVS_Post FindClientInPVS_Post
// #define FN_EntitiesInPVS_Post EntitiesInPVS_Post
// #define FN_MakeVectors_Post MakeVectors_Post
// #define FN_AngleVectors_Post AngleVectors_Post
// #define FN_CreateEntity_Post CreateEntity_Post
// #define FN_RemoveEntity_Post RemoveEntity_Post
// #define FN_CreateNamedEntity_Post CreateNamedEntity_Post
// #define FN_MakeStatic_Post MakeStatic_Post
// #define FN_EntIsOnFloor_Post EntIsOnFloor_Post
// #define FN_DropToFloor_Post DropToFloor_Post
// #define FN_WalkMove_Post WalkMove_Post
// #define FN_SetOrigin_Post SetOrigin_Post
// #define FN_EmitSound_Post EmitSound_Post
// #define FN_EmitAmbientSound_Post EmitAmbientSound_Post
// #define FN_TraceLine_Post TraceLine_Post
// #define FN_TraceToss_Post TraceToss_Post
// #define FN_TraceMonsterHull_Post TraceMonsterHull_Post
// #define FN_TraceHull_Post TraceHull_Post
// #define FN_TraceModel_Post TraceModel_Post
// #define FN_TraceTexture_Post TraceTexture_Post
// #define FN_TraceSphere_Post TraceSphere_Post
// #define FN_GetAimVector_Post GetAimVector_Post
// #define FN_ServerCommand_Post ServerCommand_Post
// #define FN_ServerExecute_Post ServerExecute_Post
// #define FN_engClientCommand_Post engClientCommand_Post
// #define FN_ParticleEffect_Post ParticleEffect_Post
// #define FN_LightStyle_Post LightStyle_Post
// #define FN_DecalIndex_Post DecalIndex_Post
// #define FN_PointContents_Post PointContents_Post
// #define FN_MessageBegin_Post MessageBegin_Post
// #define FN_MessageEnd_Post MessageEnd_Post
// #define FN_WriteByte_Post WriteByte_Post
// #define FN_WriteChar_Post WriteChar_Post
// #define FN_WriteShort_Post WriteShort_Post
// #define FN_WriteLong_Post WriteLong_Post
// #define FN_WriteAngle_Post WriteAngle_Post
// #define FN_WriteCoord_Post WriteCoord_Post
// #define FN_WriteString_Post WriteString_Post
// #define FN_WriteEntity_Post WriteEntity_Post
// #define FN_CVarRegister_Post CVarRegister_Post
// #define FN_CVarGetFloat_Post CVarGetFloat_Post
// #define FN_CVarGetString_Post CVarGetString_Post
// #define FN_CVarSetFloat_Post CVarSetFloat_Post
// #define FN_CVarSetString_Post CVarSetString_Post
// #define FN_AlertMessage_Post AlertMessage_Post
// #define FN_EngineFprintf_Post EngineFprintf_Post
// #define FN_PvAllocEntPrivateData_Post PvAllocEntPrivateData_Post
// #define FN_PvEntPrivateData_Post PvEntPrivateData_Post
// #define FN_FreeEntPrivateData_Post FreeEntPrivateData_Post
// #define FN_SzFromIndex_Post SzFromIndex_Post
// #define FN_AllocString_Post AllocString_Post
// #define FN_GetVarsOfEnt_Post GetVarsOfEnt_Post
// #define FN_PEntityOfEntOffset_Post PEntityOfEntOffset_Post
// #define FN_EntOffsetOfPEntity_Post EntOffsetOfPEntity_Post
// #define FN_IndexOfEdict_Post IndexOfEdict_Post
// #define FN_PEntityOfEntIndex_Post PEntityOfEntIndex_Post
// #define FN_FindEntityByVars_Post FindEntityByVars_Post
// #define FN_GetModelPtr_Post GetModelPtr_Post
// #define FN_RegUserMsg_Post RegUserMsg_Post
// #define FN_AnimationAutomove_Post AnimationAutomove_Post
// #define FN_GetBonePosition_Post GetBonePosition_Post
// #define FN_FunctionFromName_Post FunctionFromName_Post
// #define FN_NameForFunction_Post NameForFunction_Post
// #define FN_ClientPrintf_Post ClientPrintf_Post
// #define FN_ServerPrint_Post ServerPrint_Post
// #define FN_Cmd_Args_Post Cmd_Args_Post
// #define FN_Cmd_Argv_Post Cmd_Argv_Post
// #define FN_Cmd_Argc_Post Cmd_Argc_Post
// #define FN_GetAttachment_Post GetAttachment_Post
// #define FN_CRC32_Init_Post CRC32_Init_Post
// #define FN_CRC32_ProcessBuffer_Post CRC32_ProcessBuffer_Post
// #define FN_CRC32_ProcessByte_Post CRC32_ProcessByte_Post
// #define FN_CRC32_Final_Post CRC32_Final_Post
// #define FN_RandomLong_Post RandomLong_Post
// #define FN_RandomFloat_Post RandomFloat_Post
// #define FN_SetView_Post SetView_Post
// #define FN_Time_Post Time_Post
// #define FN_CrosshairAngle_Post CrosshairAngle_Post
// #define FN_LoadFileForMe_Post LoadFileForMe_Post
// #define FN_FreeFile_Post FreeFile_Post
// #define FN_EndSection_Post EndSection_Post
// #define FN_CompareFileTime_Post CompareFileTime_Post
// #define FN_GetGameDir_Post GetGameDir_Post
// #define FN_Cvar_RegisterVariable_Post Cvar_RegisterVariable_Post
// #define FN_FadeClientVolume_Post FadeClientVolume_Post
// #define FN_SetClientMaxspeed_Post SetClientMaxspeed_Post
// #define FN_CreateFakeClient_Post CreateFakeClient_Post
// #define FN_RunPlayerMove_Post RunPlayerMove_Post
// #define FN_NumberOfEntities_Post NumberOfEntities_Post
// #define FN_GetInfoKeyBuffer_Post GetInfoKeyBuffer_Post
// #define FN_InfoKeyValue_Post InfoKeyValue_Post
// #define FN_SetKeyValue_Post SetKeyValue_Post
// #define FN_SetClientKeyValue_Post SetClientKeyValue_Post
// #define FN_IsMapValid_Post IsMapValid_Post
// #define FN_StaticDecal_Post StaticDecal_Post
// #define FN_PrecacheGeneric_Post PrecacheGeneric_Post
// #define FN_GetPlayerUserId_Post GetPlayerUserId_Post
// #define FN_BuildSoundMsg_Post BuildSoundMsg_Post
// #define FN_IsDedicatedServer_Post IsDedicatedServer_Post
// #define FN_CVarGetPointer_Post CVarGetPointer_Post
// #define FN_GetPlayerWONId_Post GetPlayerWONId_Post
// #define FN_Info_RemoveKey_Post Info_RemoveKey_Post
// #define FN_GetPhysicsKeyValue_Post GetPhysicsKeyValue_Post
// #define FN_SetPhysicsKeyValue_Post SetPhysicsKeyValue_Post
// #define FN_GetPhysicsInfoString_Post GetPhysicsInfoString_Post
// #define FN_PrecacheEvent_Post PrecacheEvent_Post
// #define FN_PlaybackEvent_Post PlaybackEvent_Post
// #define FN_SetFatPVS_Post SetFatPVS_Post
// #define FN_SetFatPAS_Post SetFatPAS_Post
// #define FN_CheckVisibility_Post CheckVisibility_Post
// #define FN_DeltaSetField_Post DeltaSetField_Post
// #define FN_DeltaUnsetField_Post DeltaUnsetField_Post
// #define FN_DeltaAddEncoder_Post DeltaAddEncoder_Post
// #define FN_GetCurrentPlayer_Post GetCurrentPlayer_Post
// #define FN_CanSkipPlayer_Post CanSkipPlayer_Post
// #define FN_DeltaFindField_Post DeltaFindField_Post
// #define FN_DeltaSetFieldByIndex_Post DeltaSetFieldByIndex_Post
// #define FN_DeltaUnsetFieldByIndex_Post DeltaUnsetFieldByIndex_Post
// #define FN_SetGroupMask_Post SetGroupMask_Post
// #define FN_engCreateInstancedBaseline_Post engCreateInstancedBaseline_Post
// #define FN_Cvar_DirectSet_Post Cvar_DirectSet_Post
// #define FN_ForceUnmodified_Post ForceUnmodified_Post
// #define FN_GetPlayerStats_Post GetPlayerStats_Post
// #define FN_AddServerCommand_Post AddServerCommand_Post
// #define FN_Voice_GetClientListening_Post Voice_GetClientListening_Post
// #define FN_Voice_SetClientListening_Post Voice_SetClientListening_Post
// #define FN_GetPlayerAuthId_Post GetPlayerAuthId_Post
// #define FN_OnFreeEntPrivateData OnFreeEntPrivateData
// #define FN_GameShutdown GameShutdown
// #define FN_ShouldCollide ShouldCollide
// #define FN_OnFreeEntPrivateData_Post OnFreeEntPrivateData_Post
// #define FN_GameShutdown_Post GameShutdown_Post
// #define FN_ShouldCollide_Post ShouldCollide_Post
#endif // USE_METAMOD
#endif // __MODULECONFIG_H__

40
dlls/BB/pdata.h Normal file
View File

@ -0,0 +1,40 @@
// prevent double include
#ifndef __PDATA_H__
#define __PDATA_H__
#include <extdll.h>
#include "amxxmodule.h"
#if defined __linux__
#define EXTRAOFFSET 5 // offsets 5 higher in Linux builds
#else
#define EXTRAOFFSET 0 // no change in Windows builds
#endif // defined __linux__
inline edict_t* MF_GetEntityEdict( long& EntID )
{
if( (EntID > 0) && (EntID <= (gpGlobals->maxClients) ) )
return MF_GetPlayerEdict( EntID );
return NULL;
}
template <typename ValueType>
inline void SetPData( long& targetid, long offset, ValueType value, bool reset = false )
{
edict_t* target = MF_GetEntityEdict( targetid );
if(target == NULL) return;
*((ValueType *)target->pvPrivateData + offset + EXTRAOFFSET) = value;
if(reset) UpdateBBHud( targetid );
};
template <typename ValueType>
inline ValueType GetPData( long& targetid, long offset, ValueType value )
{
edict_t* target = MF_GetEntityEdict( targetid );
if(target == NULL) return NULL;
return *((ValueType *)target->pvPrivateData + offset + EXTRAOFFSET);
}
#endif

48
dlls/MemHack/MemConst.h Normal file
View File

@ -0,0 +1,48 @@
#ifndef __MEMCONST_H__
#define __MEMCONST_H__
#ifdef __linux__
#include <sys/mman.h>
#endif
#include "amxxmodule.h"
// Define memory address type
#ifdef __amd64__
typedef uint64_t maddress;
#else
typedef uint32_t maddress;
#endif
// Number of bytes for different data types
#define BYTE_BYTES 1
#define WORD_BYTES 2
#define DWORD_BYTES 4
#define QWORD_BYTES 8
#define FLOAT_BYTES 4
// Return codes for MemoryProtect
#define MP_FAIL -1
#define MP_OK 0
// Memory protection constants
#ifdef __linux__
#define MPROT_CODE PROT_READ|PROT_EXEC
#define MPROT_DATA PROT_READ|PROT_WRITE
#define MPROT_RODATA PROT_READ
#define MPROT_CODE_EDIT PROT_READ|PROT_WRITE|PROT_EXEC
#define MPROT_RODATA_EDIT PROT_READ|PROT_WRITE
#else
#define MPROT_CODE PAGE_EXECUTE_READ
#define MPROT_DATA PAGE_READWRITE
#define MPROT_RODATA PAGE_READONLY
#define MPROT_CODE_EDIT PAGE_EXECUTE_READWRITE
#define MPROT_RODATA_EDIT PAGE_READWRITE
#endif
// Memory area types
#define MEMTYPE_CODE 0 // Code (usually .text segment, requires mprotect or VirtualProtect)
#define MEMTYPE_DATA 1 // Data (usually .data segment, writable by default)
#define MEMTYPE_RODATA 2 // Read-Only Data (usually .rodata on Linux, .rdata on Windows)
#endif // #ifndef __MEMHACK_H__

16
dlls/MemHack/MemHack.cpp Normal file
View File

@ -0,0 +1,16 @@
#include "MemMisc.h"
extern AMX_NATIVE_INFO read_natives[];
extern AMX_NATIVE_INFO write_natives[];
extern AMX_NATIVE_INFO misc_natives[];
void OnAmxxAttach()
{
// Get Base Addresses for dll and engine; exit if unavailable.
if(GetBaseAddresses() == false) return MF_LogError(NULL,AMX_ERR_MEMACCESS,"Unable to get base address of game or mod .dll!");
// Add natives if base is found.
MF_AddNatives(read_natives);
MF_AddNatives(write_natives);
MF_AddNatives(misc_natives);
}

BIN
dlls/MemHack/MemHack.ncb Normal file

Binary file not shown.

19
dlls/MemHack/MemHack.sln Normal file
View File

@ -0,0 +1,19 @@
Microsoft Visual Studio Solution File, Format Version 9.00
# Visual C++ Express 2005
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "memhack", "MemHack.vcproj", "{B0190B77-FE9B-495F-8D7E-74D458EBE635}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{B0190B77-FE9B-495F-8D7E-74D458EBE635}.Debug|Win32.ActiveCfg = Debug|Win32
{B0190B77-FE9B-495F-8D7E-74D458EBE635}.Debug|Win32.Build.0 = Debug|Win32
{B0190B77-FE9B-495F-8D7E-74D458EBE635}.Release|Win32.ActiveCfg = Release|Win32
{B0190B77-FE9B-495F-8D7E-74D458EBE635}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

254
dlls/MemHack/MemHack.vcproj Normal file
View File

@ -0,0 +1,254 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="memhack"
ProjectGUID="{B0190B77-FE9B-495F-8D7E-74D458EBE635}"
Keyword="Win32Proj"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="Debug"
IntermediateDirectory="Debug"
ConfigurationType="2"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="&quot;C:\Program Files\Steam\hlsdk\Multiplayer Source\metamod\metamod-1.17.3\metamod&quot;;&quot;C:\Program Files\Steam\hlsdk\Multiplayer Source\common&quot;;&quot;C:\Program Files\Steam\hlsdk\Multiplayer Source\engine&quot;;&quot;C:\Program Files\Steam\hlsdk\Multiplayer Source\dlls&quot;;&quot;C:\Program Files\Steam\hlsdk\Multiplayer Source\pm_shared&quot;"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;MEMHACK_EXPORTS"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
StructMemberAlignment="3"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/memhack_amxx.dll"
LinkIncremental="2"
GenerateDebugInformation="true"
ProgramDatabaseFile="$(OutDir)/memhack.pdb"
SubSystem="2"
ImportLibrary="$(OutDir)/memhack.lib"
TargetMachine="1"
/>
<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="Release|Win32"
OutputDirectory="Release"
IntermediateDirectory="Release"
ConfigurationType="2"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="&quot;C:\Program Files\Steam\hlsdk\Multiplayer Source\metamod\metamod-1.17.3\metamod&quot;;&quot;C:\Program Files\Steam\hlsdk\Multiplayer Source\common&quot;;&quot;C:\Program Files\Steam\hlsdk\Multiplayer Source\engine&quot;;&quot;C:\Program Files\Steam\hlsdk\Multiplayer Source\dlls&quot;;&quot;C:\Program Files\Steam\hlsdk\Multiplayer Source\pm_shared&quot;"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;MEMHACK_EXPORTS"
RuntimeLibrary="0"
StructMemberAlignment="3"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="0"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/memhack_amxx.dll"
LinkIncremental="1"
GenerateDebugInformation="false"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
OptimizeForWindows98="1"
ImportLibrary="$(OutDir)/memhack.lib"
TargetMachine="1"
/>
<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;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\amxxmodule.cpp"
>
</File>
<File
RelativePath=".\MemHack.cpp"
>
</File>
<File
RelativePath=".\MemMisc.cpp"
>
</File>
<File
RelativePath=".\MemMiscNatives.cpp"
>
</File>
<File
RelativePath=".\MemRead.cpp"
>
</File>
<File
RelativePath=".\MemReadNatives.cpp"
>
</File>
<File
RelativePath=".\MemWrite.cpp"
>
</File>
<File
RelativePath=".\MemWriteNatives.cpp"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath=".\amxxmodule.h"
>
</File>
<File
RelativePath=".\MemConst.h"
>
</File>
<File
RelativePath=".\MemMisc.h"
>
</File>
<File
RelativePath=".\MemRead.h"
>
</File>
<File
RelativePath=".\MemWrite.h"
>
</File>
<File
RelativePath=".\moduleconfig.h"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

111
dlls/MemHack/MemMisc.cpp Normal file
View File

@ -0,0 +1,111 @@
#include "MemConst.h"
// Game memory addresses
maddress gameDllAddress = NULL;
maddress gameEngAddress = NULL;
bool GetBaseAddress(void *pAddr, maddress &pBaseAddr/*, size_t *memLength*/)
{
#ifdef WIN32
MEMORY_BASIC_INFORMATION mem;
if (!VirtualQuery(pAddr, &mem, sizeof(mem)))
return false;
pBaseAddr = (maddress)mem.AllocationBase;
IMAGE_DOS_HEADER *dos = (IMAGE_DOS_HEADER *)(mem.AllocationBase);
IMAGE_NT_HEADERS *pe = reinterpret_cast<IMAGE_NT_HEADERS*>( (unsigned long)dos + (unsigned long)dos->e_lfanew );
if (pe->Signature != IMAGE_NT_SIGNATURE)
return false;
//if (memLength)
//*memLength = (size_t)(pe->OptionalHeader.SizeOfImage);
return true;
#else
Dl_info info;
struct stat buf;
if (!dladdr(pAddr, &info))
return false;
if (!info.dli_fbase || !info.dli_fname)
return false;
if (stat(info.dli_fname, &buf) != 0)
return false;
if (pBaseAddr)
*pBaseAddr = (unsigned char *)info.dli_fbase;
//if (memLength)
//*memLength = buf.st_size;
return true;
#endif
}
/* Wrapper for mprotect and VirtualProtect */
int MemoryProtect(void *addr, size_t len, unsigned long newProt, unsigned long *oldProt, char memType) {
int retVal;
#ifdef __linux__
maddress alignAddr = (maddress)addr - ((maddress)addr % pageSize);
retVal = mprotect((void*)alignAddr, pageSize, newProt);
// Linux's mprotect doesn't get the old protection flags, so we have to fake it
switch (memType) {
case MEMTYPE_CODE:
*oldProt = MPROT_CODE;
break;
case MEMTYPE_RODATA:
*oldProt = MPROT_RODATA;
break;
default:
*oldProt = MPROT_CODE;
break;
}
#else
retVal = VirtualProtect(addr, len, newProt, oldProt);
// This will match the Windows return value with the Linux ones, done for consistency
if (retVal == 0) {
retVal = -1;
} else {
retVal = 0;
}
#endif
return retVal;
}
// Linux won't work till I fix it for MEMTYPE_DATA
#ifdef __linux__
// Data section stuff
maddress dataSectionStart;
maddress dataSectionOffset;
int pageSize = sysconf(_SC_PAGESIZE);
#endif
/* Gets real memory address */
maddress GetRealMemoryAddress(maddress baseaddress, maddress address, char memType)
{
if(baseaddress == NULL) return address;
maddress realAddress = address;
switch (memType)
{
case MEMTYPE_CODE: case MEMTYPE_RODATA:
realAddress = baseaddress + address;
break;
case MEMTYPE_DATA:
// Linux's data segment is in a not so simple place in memory
#ifdef __linux__
realAddress = dataSectionStart + (address - dataSectionOffset);
#else
realAddress = baseaddress + address;
#endif
break;
}
return realAddress;
}

38
dlls/MemHack/MemMisc.h Normal file
View File

@ -0,0 +1,38 @@
#ifndef __MEMMISC_H__
#define __MEMMISC_H__
#include "MemConst.h"
#define SAMPLE_DLLFUNC reinterpret_cast<void*>(gpGamedllFuncs->dllapi_table->pfnThink)
#define SAMPLE_ENGFUNC reinterpret_cast<void*>(g_engfuncs.pfnChangeLevel)
extern maddress gameDllAddress;
extern maddress gameEngAddress;
inline maddress PickBaseAddress(long num)
{
if(num == 0) return gameDllAddress;
else if(num == 1) return gameEngAddress;
return NULL;
}
extern int MemoryProtect(void *addr, size_t len, unsigned long newProt, unsigned long *oldProt, char memType = MEMTYPE_CODE);
extern maddress GetRealMemoryAddress(maddress baseaddress,maddress address, char memType);
extern bool GetBaseAddress(void *pAddr, maddress &pBaseAddr);
inline bool GetBaseAddresses( void )
{
bool success = false;
success = GetBaseAddress(SAMPLE_DLLFUNC, gameDllAddress);
if(success == false) return false;
success = GetBaseAddress(SAMPLE_ENGFUNC, gameEngAddress);
if(success == false) return false;
return true;
}
#endif

View File

@ -0,0 +1,33 @@
#include "MemMisc.h"
#define NATIVE_MISC_ADDRESS params[1]
#define NATIVE_MISC_BASEADDRESS PickBaseAddress(params[2])
#define NATIVE_MISC_FLAGS params[3]
static cell AMX_NATIVE_CALL memhack_get_base(AMX *amx, cell *params)
{
cell *success = MF_GetAmxAddr(amx, params[2]);
maddress BaseAddr = NULL;
bool is_success = GetBaseAddress((void*)(params[1]), BaseAddr);
*success = is_success;
return cell(BaseAddr);
}
static cell AMX_NATIVE_CALL memhack_get_realaddr(AMX *amx, cell *params)
{
return (cell)GetRealMemoryAddress(NATIVE_MISC_ADDRESS,NATIVE_MISC_BASEADDRESS,NATIVE_MISC_FLAGS);
}
static cell AMX_NATIVE_CALL memhack_return_addr(AMX *amx, cell *params)
{
return (cell)PickBaseAddress(params[1]);
}
AMX_NATIVE_INFO misc_natives[] = {
{ "memhack_get_base", memhack_get_base },
{ "memhack_get_realaddr", memhack_get_realaddr },
{ "memhack_return_addr", memhack_return_addr },
{ NULL, NULL }
};

56
dlls/MemHack/MemRead.cpp Normal file
View File

@ -0,0 +1,56 @@
#include "MemMisc.h"
/* Functions that read different data types in memory */
template <typename Type>
Type UTIL_ReadMemory(maddress BaseAddress, maddress StartAddress, char MemType, Type returnType)
{
maddress EndAddress = GetRealMemoryAddress(BaseAddress, StartAddress, MemType);
return *(Type*)EndAddress;
}
char UTIL_ReadMemory_Byte(maddress BaseAddress, maddress address, char memType)
{
return UTIL_ReadMemory( BaseAddress, address, memType, char(NULL));
}
short UTIL_ReadMemory_Word(maddress BaseAddress, maddress address, char memType)
{
return UTIL_ReadMemory( BaseAddress, address, memType, short(NULL));
}
int32_t UTIL_ReadMemory_Dword(maddress BaseAddress, maddress address, char memType)
{
return UTIL_ReadMemory( BaseAddress, address, memType, int32_t(NULL));
}
long long UTIL_ReadMemory_Qword(maddress BaseAddress, maddress address, char memType)
{
return UTIL_ReadMemory( BaseAddress, address, memType, (long long)(NULL));
}
float UTIL_ReadMemory_Float(maddress BaseAddress, maddress address, char memType)
{
return UTIL_ReadMemory( BaseAddress, address, memType, float(NULL));
}
unsigned char UTIL_ReadMemory_UnsignedByte(maddress BaseAddress, maddress address, char memType)
{
return UTIL_ReadMemory( BaseAddress, address, memType, (unsigned char)(NULL));
}
unsigned short UTIL_ReadMemory_UnsignedWord(maddress BaseAddress, maddress address, char memType)
{
return UTIL_ReadMemory( BaseAddress, address, memType, (unsigned short)(NULL));
}
uint32_t UTIL_ReadMemory_UnsignedDword(maddress BaseAddress, maddress address, char memType)
{
return UTIL_ReadMemory( BaseAddress, address, memType, uint32_t(NULL));
}
maddress UTIL_ReadMemory_Pointer(maddress BaseAddress, maddress address, char memType)
{
return UTIL_ReadMemory( BaseAddress, address, memType, maddress(NULL));
}

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